2017-12-30 20:12:01 +00:00
/*
* Copyright ( c ) 2017 Shaun Feakes - All rights reserved
*
* You may use redistribute and / or modify this code under the terms of
* the GNU General Public License version 2 as published by the
* Free Software Foundation . For the terms of this license ,
* see < http : //www.gnu.org/licenses/>.
*
* You are free to use this software under the terms of the GNU General
* Public License , but WITHOUT ANY WARRANTY ; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details .
*
* https : //github.com/sfeakes/aqualinkd
*/
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <getopt.h>
# include <string.h>
# include <sys/time.h>
# include <syslog.h>
# include "mongoose.h"
# include "aqualink.h"
# include "config.h"
# include "aq_programmer.h"
# include "utils.h"
# include "net_services.h"
# include "json_messages.h"
# include "domoticz.h"
# include "aq_mqtt.h"
2020-06-06 16:36:04 +00:00
# include "devices_jandy.h"
2023-05-14 21:35:13 +00:00
# include "web_config.h"
2020-07-26 19:28:58 +00:00
# include "debug_timer.h"
2020-08-28 19:12:38 +00:00
# include "serialadapter.h"
2023-05-14 21:35:13 +00:00
# include "aq_timer.h"
# include "aq_scheduler.h"
2017-12-30 20:12:01 +00:00
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
# include "pda.h"
# endif
2020-07-26 19:28:58 +00:00
/*
# if defined AQ_DEBUG || defined AQ_TM_DEBUG
2020-07-18 16:37:19 +00:00
# include "timespec_subtract.h"
2020-07-26 19:28:58 +00:00
//#define AQ_TM_DEBUG
2020-07-18 16:37:19 +00:00
# endif
2020-07-26 19:28:58 +00:00
*/
2017-12-30 20:12:01 +00:00
2020-06-01 00:35:17 +00:00
//static struct aqconfig *_aqconfig_;
2017-12-30 20:12:01 +00:00
static struct aqualinkdata * _aqualink_data ;
2020-07-26 19:28:58 +00:00
//static char *_web_root;
2017-12-30 20:12:01 +00:00
static int _mqtt_exit_flag = false ;
2020-07-18 16:37:19 +00:00
2017-12-30 20:12:01 +00:00
2020-06-20 16:09:54 +00:00
// Will remove this once we deprecate V1 API's
2023-05-14 21:35:13 +00:00
# ifdef INCLUDE_V1_API
2020-06-20 16:09:54 +00:00
void OLD_action_web_request ( struct mg_connection * nc , struct http_message * http_msg ) ;
void OLD_action_websocket_request ( struct mg_connection * nc , struct websocket_message * wm ) ;
2023-05-14 21:35:13 +00:00
# endif
2017-12-30 20:12:01 +00:00
# ifndef MG_DISABLE_MQTT
void start_mqtt ( struct mg_mgr * mgr ) ;
static struct aqualinkdata _last_mqtt_aqualinkdata ;
void mqtt_broadcast_aqualinkstate ( struct mg_connection * nc ) ;
# endif
2020-07-18 16:37:19 +00:00
void reset_last_mqtt_status ( ) ;
2017-12-30 20:12:01 +00:00
static sig_atomic_t s_signal_received = 0 ;
//static const char *s_http_port = "8080";
2020-07-18 16:37:19 +00:00
static struct mg_serve_http_opts _http_server_opts ;
2017-12-30 20:12:01 +00:00
2020-07-26 19:28:58 +00:00
static void net_signal_handler ( int sig_num ) {
if ( ! _aqconfig_ . thread_netservices ) {
signal ( sig_num , net_signal_handler ) ; // Reinstantiate signal handler to aqualinkd.c
s_signal_received = sig_num ;
} else {
intHandler ( sig_num ) ; // Force signal handler to aqualinkd.c
}
2017-12-30 20:12:01 +00:00
}
static int is_websocket ( const struct mg_connection * nc ) {
2023-05-14 21:35:13 +00:00
//return nc->flags & MG_F_IS_WEBSOCKET && !(nc->flags & MG_F_USER_2); // WS only, not WS simulator
return nc - > flags & MG_F_IS_WEBSOCKET ;
2020-06-01 00:35:17 +00:00
}
2023-05-14 21:35:13 +00:00
static void set_websocket_simulator ( struct mg_connection * nc ) {
2020-06-01 00:35:17 +00:00
nc - > flags | = MG_F_USER_2 ;
}
2023-05-14 21:35:13 +00:00
static int is_websocket_simulator ( const struct mg_connection * nc ) {
2020-06-01 00:35:17 +00:00
return nc - > flags & MG_F_USER_2 ;
2017-12-30 20:12:01 +00:00
}
2023-05-14 21:35:13 +00:00
2017-12-30 20:12:01 +00:00
static int is_mqtt ( const struct mg_connection * nc ) {
return nc - > flags & MG_F_USER_1 ;
}
static void set_mqtt ( struct mg_connection * nc ) {
nc - > flags | = MG_F_USER_1 ;
}
static void ws_send ( struct mg_connection * nc , char * msg )
{
int size = strlen ( msg ) ;
mg_send_websocket_frame ( nc , WEBSOCKET_OP_TEXT , msg , size ) ;
2023-05-16 16:17:42 +00:00
//LOG(NET_LOG,LOG_DEBUG, "WS: Sent %d characters '%s'\n",size, msg);
2017-12-30 20:12:01 +00:00
}
2020-07-26 19:28:58 +00:00
void _broadcast_aqualinkstate_error ( struct mg_connection * nc , char * msg )
2017-12-30 20:12:01 +00:00
{
struct mg_connection * c ;
char data [ JSON_STATUS_SIZE ] ;
build_aqualink_error_status_JSON ( data , JSON_STATUS_SIZE , msg ) ;
for ( c = mg_next ( nc - > mgr , NULL ) ; c ! = NULL ; c = mg_next ( nc - > mgr , c ) ) {
if ( is_websocket ( c ) )
ws_send ( c , data ) ;
}
// Maybe enhacment in future to sent error messages to MQTT
}
2020-07-26 19:28:58 +00:00
void _broadcast_aqualinkstate ( struct mg_connection * nc )
2017-12-30 20:12:01 +00:00
{
static int mqtt_count = 0 ;
struct mg_connection * c ;
char data [ JSON_STATUS_SIZE ] ;
2020-07-26 19:28:58 +00:00
# ifdef AQ_TM_DEBUG
int tid ;
# endif
DEBUG_TIMER_START ( & tid ) ;
2017-12-30 20:12:01 +00:00
build_aqualink_status_JSON ( _aqualink_data , data , JSON_STATUS_SIZE ) ;
2020-07-18 16:37:19 +00:00
# ifdef AQ_MEMCMP
if ( memcmp ( _aqualink_data , & _last_mqtt_aqualinkdata , sizeof ( struct aqualinkdata ) ) = = 0 ) {
LOG ( NET_LOG , LOG_NOTICE , " **********Structure buffs the same, ignoring request************ \n " ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_CLEAR ( & tid ) ;
2020-07-18 16:37:19 +00:00
return ;
}
# endif
2017-12-30 20:12:01 +00:00
# ifndef MG_DISABLE_MQTT
if ( _mqtt_exit_flag = = true ) {
mqtt_count + + ;
if ( mqtt_count > = 10 ) {
start_mqtt ( nc - > mgr ) ;
mqtt_count = 0 ;
}
}
# endif
for ( c = mg_next ( nc - > mgr , NULL ) ; c ! = NULL ; c = mg_next ( nc - > mgr , c ) ) {
if ( is_websocket ( c ) )
ws_send ( c , data ) ;
# ifndef MG_DISABLE_MQTT
else if ( is_mqtt ( c ) )
mqtt_broadcast_aqualinkstate ( c ) ;
# endif
}
2020-07-18 16:37:19 +00:00
# ifdef AQ_MEMCMP
memcpy ( & _last_mqtt_aqualinkdata , _aqualink_data , sizeof ( struct aqualinkdata ) ) ;
# endif
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " broadcast_aqualinkstate() completed, took " ) ;
2017-12-30 20:12:01 +00:00
return ;
}
2020-08-28 19:12:38 +00:00
void send_mqtt ( struct mg_connection * nc , const char * toppic , const char * message )
2017-12-30 20:12:01 +00:00
{
static uint16_t msg_id = 0 ;
2018-03-05 23:52:42 +00:00
if ( toppic = = NULL )
return ;
2017-12-30 20:12:01 +00:00
if ( msg_id > = 65535 ) { msg_id = 1 ; } else { msg_id + + ; }
//mg_mqtt_publish(nc, toppic, msg_id, MG_MQTT_QOS(0), message, strlen(message));
mg_mqtt_publish ( nc , toppic , msg_id , MG_MQTT_RETAIN | MG_MQTT_QOS ( 1 ) , message , strlen ( message ) ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Published id=%d: %s %s \n " , msg_id , toppic , message ) ;
2017-12-30 20:12:01 +00:00
}
2017-12-31 16:37:08 +00:00
void send_domoticz_mqtt_state_msg ( struct mg_connection * nc , int idx , int value )
2017-12-30 20:12:01 +00:00
{
if ( idx < = 0 )
return ;
char mqtt_msg [ JSON_MQTT_MSG_SIZE ] ;
build_mqtt_status_JSON ( mqtt_msg , JSON_MQTT_MSG_SIZE , idx , value , TEMP_UNKNOWN ) ;
2020-06-01 00:35:17 +00:00
send_mqtt ( nc , _aqconfig_ . mqtt_dz_pub_topic , mqtt_msg ) ;
2017-12-30 20:12:01 +00:00
}
2017-12-31 16:37:08 +00:00
void send_domoticz_mqtt_temp_msg ( struct mg_connection * nc , int idx , int value )
2017-12-30 20:12:01 +00:00
{
if ( idx < = 0 )
return ;
char mqtt_msg [ JSON_MQTT_MSG_SIZE ] ;
2020-06-01 00:35:17 +00:00
build_mqtt_status_JSON ( mqtt_msg , JSON_MQTT_MSG_SIZE , idx , 0 , ( _aqualink_data - > temp_units = = FAHRENHEIT & & _aqconfig_ . convert_dz_temp ) ? roundf ( degFtoC ( value ) ) : value ) ;
send_mqtt ( nc , _aqconfig_ . mqtt_dz_pub_topic , mqtt_msg ) ;
2017-12-30 20:12:01 +00:00
}
2018-03-12 20:49:21 +00:00
void send_domoticz_mqtt_numeric_msg ( struct mg_connection * nc , int idx , int value )
{
if ( idx < = 0 )
return ;
char mqtt_msg [ JSON_MQTT_MSG_SIZE ] ;
build_mqtt_status_JSON ( mqtt_msg , JSON_MQTT_MSG_SIZE , idx , 0 , value ) ;
2020-06-01 00:35:17 +00:00
send_mqtt ( nc , _aqconfig_ . mqtt_dz_pub_topic , mqtt_msg ) ;
2018-03-12 20:49:21 +00:00
}
2018-06-06 00:18:44 +00:00
void send_domoticz_mqtt_status_message ( struct mg_connection * nc , int idx , int value , char * svalue ) {
if ( idx < = 0 )
return ;
char mqtt_msg [ JSON_MQTT_MSG_SIZE ] ;
build_mqtt_status_message_JSON ( mqtt_msg , JSON_MQTT_MSG_SIZE , idx , value , svalue ) ;
2020-06-01 00:35:17 +00:00
send_mqtt ( nc , _aqconfig_ . mqtt_dz_pub_topic , mqtt_msg ) ;
2018-06-06 00:18:44 +00:00
}
2017-12-30 20:12:01 +00:00
void send_mqtt_state_msg ( struct mg_connection * nc , char * dev_name , aqledstate state )
{
static char mqtt_pub_topic [ 250 ] ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s/delay " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2019-02-10 23:13:18 +00:00
send_mqtt ( nc , mqtt_pub_topic , ( state = = FLASH ? MQTT_ON : MQTT_OFF ) ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , ( state = = OFF ? MQTT_OFF : MQTT_ON ) ) ;
2017-12-30 20:12:01 +00:00
}
2018-07-15 19:36:19 +00:00
2023-05-16 16:17:42 +00:00
void send_mqtt_timer_duration_msg ( struct mg_connection * nc , char * dev_name , aqkey * button )
{
static char mqtt_pub_topic [ 250 ] ;
sprintf ( mqtt_pub_topic , " %s/%s/timer/duration " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
if ( ( button - > special_mask & TIMER_ACTIVE ) = = TIMER_ACTIVE ) {
char val [ 10 ] ;
sprintf ( val , " %d " , get_timer_left ( button ) ) ;
send_mqtt ( nc , mqtt_pub_topic , val ) ;
} else {
send_mqtt ( nc , mqtt_pub_topic , " 0 " ) ;
}
}
2023-05-14 21:35:13 +00:00
void send_mqtt_timer_state_msg ( struct mg_connection * nc , char * dev_name , aqkey * button )
{
static char mqtt_pub_topic [ 250 ] ;
sprintf ( mqtt_pub_topic , " %s/%s/timer " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
send_mqtt ( nc , mqtt_pub_topic , ( ( ( button - > special_mask & TIMER_ACTIVE ) = = TIMER_ACTIVE ) & & ( button - > led - > state ! = OFF ) ) ? MQTT_ON : MQTT_OFF ) ;
2023-05-16 16:17:42 +00:00
send_mqtt_timer_duration_msg ( nc , dev_name , button ) ;
2023-05-14 21:35:13 +00:00
}
2019-06-08 19:34:47 +00:00
//void send_mqtt_aux_msg(struct mg_connection *nc, char *root_topic, int dev_index, char *dev_topic, int value)
void send_mqtt_aux_msg ( struct mg_connection * nc , char * dev_name , char * dev_topic , int value )
2019-05-31 23:08:45 +00:00
{
static char mqtt_pub_topic [ 250 ] ;
static char msg [ 10 ] ;
sprintf ( msg , " %d " , value ) ;
2020-06-01 00:35:17 +00:00
//sprintf(mqtt_pub_topic, "%s/%s%d%s",_aqconfig_.mqtt_aq_topic, root_topic, dev_index, dev_topic);
sprintf ( mqtt_pub_topic , " %s/%s%s " , _aqconfig_ . mqtt_aq_topic , dev_name , dev_topic ) ;
2019-05-31 23:08:45 +00:00
send_mqtt ( nc , mqtt_pub_topic , msg ) ;
}
2020-07-18 16:37:19 +00:00
void send_mqtt_led_state_msg ( struct mg_connection * nc , char * dev_name , aqledstate state , char * onS , char * offS )
2018-07-15 19:36:19 +00:00
{
2018-09-02 21:45:24 +00:00
2018-07-15 19:36:19 +00:00
static char mqtt_pub_topic [ 250 ] ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-07-15 19:36:19 +00:00
2020-07-18 16:37:19 +00:00
if ( state = = ENABLE ) {
send_mqtt ( nc , mqtt_pub_topic , offS ) ;
sprintf ( mqtt_pub_topic , " %s/%s%s " , _aqconfig_ . mqtt_aq_topic , dev_name , ENABELED_SUBT ) ;
send_mqtt ( nc , mqtt_pub_topic , onS ) ;
} else {
send_mqtt ( nc , mqtt_pub_topic , ( state = = OFF ? offS : onS ) ) ;
sprintf ( mqtt_pub_topic , " %s/%s%s " , _aqconfig_ . mqtt_aq_topic , dev_name , ENABELED_SUBT ) ;
send_mqtt ( nc , mqtt_pub_topic , ( state = = OFF ? offS : onS ) ) ;
}
}
void send_mqtt_swg_state_msg ( struct mg_connection * nc , char * dev_name , aqledstate state )
{
//send_mqtt_led_state_msg(nc, dev_name, state, SWG_ON, SWG_OFF);
send_mqtt_led_state_msg ( nc , dev_name , state , " 2 " , " 0 " ) ;
}
void send_mqtt_heater_state_msg ( struct mg_connection * nc , char * dev_name , aqledstate state )
{
send_mqtt_led_state_msg ( nc , dev_name , state , MQTT_ON , MQTT_OFF ) ;
/*
static char mqtt_pub_topic [ 250 ] ;
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-07-15 19:36:19 +00:00
if ( state = = ENABLE ) {
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , MQTT_OFF ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s%s " , _aqconfig_ . mqtt_aq_topic , dev_name , ENABELED_SUBT ) ;
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , MQTT_ON ) ;
2018-07-15 19:36:19 +00:00
} else {
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , ( state = = OFF ? MQTT_OFF : MQTT_ON ) ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s%s " , _aqconfig_ . mqtt_aq_topic , dev_name , ENABELED_SUBT ) ;
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , ( state = = OFF ? MQTT_OFF : MQTT_ON ) ) ;
2018-07-15 19:36:19 +00:00
}
2020-07-18 16:37:19 +00:00
*/
2018-07-15 19:36:19 +00:00
}
2020-07-18 16:37:19 +00:00
2018-07-15 19:36:19 +00:00
// NSF need to change this function to the _new once finished.
2017-12-30 20:12:01 +00:00
void send_mqtt_temp_msg ( struct mg_connection * nc , char * dev_name , long value )
{
static char mqtt_pub_topic [ 250 ] ;
2019-05-18 00:48:20 +00:00
static char degC [ 10 ] ;
2023-05-14 21:35:13 +00:00
// Use "not CELS" over "equal FAHR" so we default to FAHR for unknown units
//sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_mqtt_temp)?degFtoC(value):value );
sprintf ( degC , " %.2f " , ( _aqualink_data - > temp_units ! = CELSIUS & & _aqconfig_ . convert_mqtt_temp ) ? degFtoC ( value ) : value ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2017-12-30 20:12:01 +00:00
send_mqtt ( nc , mqtt_pub_topic , degC ) ;
}
2018-07-15 19:36:19 +00:00
/*
void send_mqtt_temp_msg_new ( struct mg_connection * nc , char * dev_name , long value )
{
static char mqtt_pub_topic [ 250 ] ;
static char degC [ 5 ] ;
// NSF remove false below once we have finished.
2020-06-01 00:35:17 +00:00
sprintf ( degC , " %.2f " , ( false & & _aqualink_data - > temp_units = = FAHRENHEIT & & _aqconfig_ . convert_mqtt_temp ) ? degFtoC ( value ) : value ) ;
2018-07-15 19:36:19 +00:00
//sprintf(degC, "%d", value );
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-07-15 19:36:19 +00:00
send_mqtt ( nc , mqtt_pub_topic , degC ) ;
}
*/
2017-12-30 20:12:01 +00:00
void send_mqtt_setpoint_msg ( struct mg_connection * nc , char * dev_name , long value )
{
static char mqtt_pub_topic [ 250 ] ;
2019-05-18 00:48:20 +00:00
static char degC [ 10 ] ;
2023-05-14 21:35:13 +00:00
// Use "not CELS" over "equal FAHR" so we default to FAHR for unknown units
//sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_mqtt_temp)?degFtoC(value):value );
sprintf ( degC , " %.2f " , ( _aqualink_data - > temp_units ! = CELSIUS & & _aqconfig_ . convert_mqtt_temp ) ? degFtoC ( value ) : value ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s/setpoint " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2017-12-30 20:12:01 +00:00
send_mqtt ( nc , mqtt_pub_topic , degC ) ;
}
2018-03-12 20:49:21 +00:00
void send_mqtt_numeric_msg ( struct mg_connection * nc , char * dev_name , int value )
{
static char mqtt_pub_topic [ 250 ] ;
static char msg [ 10 ] ;
sprintf ( msg , " %d " , value ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-03-12 20:49:21 +00:00
send_mqtt ( nc , mqtt_pub_topic , msg ) ;
}
2018-06-06 00:18:44 +00:00
void send_mqtt_float_msg ( struct mg_connection * nc , char * dev_name , float value ) {
static char mqtt_pub_topic [ 250 ] ;
static char msg [ 10 ] ;
2019-06-05 16:41:38 +00:00
sprintf ( msg , " %.2f " , value ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-06-06 00:18:44 +00:00
send_mqtt ( nc , mqtt_pub_topic , msg ) ;
}
2018-07-15 23:36:59 +00:00
2018-06-06 00:18:44 +00:00
void send_mqtt_int_msg ( struct mg_connection * nc , char * dev_name , int value ) {
2018-07-15 23:36:59 +00:00
send_mqtt_numeric_msg ( nc , dev_name , value ) ;
/*
2018-06-06 00:18:44 +00:00
static char mqtt_pub_topic [ 250 ] ;
static char msg [ 10 ] ;
sprintf ( msg , " %d " , value ) ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-06-06 00:18:44 +00:00
send_mqtt ( nc , mqtt_pub_topic , msg ) ;
2018-07-15 23:36:59 +00:00
*/
}
2020-08-28 19:12:38 +00:00
void send_mqtt_string_msg ( struct mg_connection * nc , const char * dev_name , const char * msg ) {
2018-07-15 23:36:59 +00:00
static char mqtt_pub_topic [ 250 ] ;
2020-06-01 00:35:17 +00:00
sprintf ( mqtt_pub_topic , " %s/%s " , _aqconfig_ . mqtt_aq_topic , dev_name ) ;
2018-07-15 23:36:59 +00:00
send_mqtt ( nc , mqtt_pub_topic , msg ) ;
2018-06-06 00:18:44 +00:00
}
2017-12-30 20:12:01 +00:00
void mqtt_broadcast_aqualinkstate ( struct mg_connection * nc )
{
2018-06-06 00:18:44 +00:00
static int cnt = 0 ;
2020-07-18 16:37:19 +00:00
int i ;
2023-05-14 21:35:13 +00:00
const char * status ;
2018-06-06 00:18:44 +00:00
2020-07-18 16:37:19 +00:00
if ( _aqconfig_ . mqtt_timed_update ) {
if ( cnt > 300 ) { // 100 = about every 2 minutes.
reset_last_mqtt_status ( ) ;
cnt = 0 ;
} else {
cnt + + ;
}
2018-06-06 00:18:44 +00:00
}
2020-07-18 16:37:19 +00:00
2017-12-30 20:12:01 +00:00
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_INFO, "mqtt_broadcast_aqualinkstate: START\n");
2017-12-30 20:12:01 +00:00
2019-03-01 15:22:03 +00:00
if ( _aqualink_data - > service_mode_state ! = _last_mqtt_aqualinkdata . service_mode_state ) {
_last_mqtt_aqualinkdata . service_mode_state = _aqualink_data - > service_mode_state ;
2019-10-18 13:52:20 +00:00
send_mqtt_string_msg ( nc , SERVICE_MODE_TOPIC , _aqualink_data - > service_mode_state = = OFF ? MQTT_OFF : ( _aqualink_data - > service_mode_state = = FLASH ? MQTT_FLASH : MQTT_ON ) ) ;
2019-03-01 15:22:03 +00:00
}
2023-05-14 21:35:13 +00:00
// Only send to display messag topic if not in simulator mode
//if (!_aqualink_data->simulate_panel) {
status = getAqualinkDStatusMessage ( _aqualink_data ) ;
if ( strcmp ( status , _last_mqtt_aqualinkdata . last_display_message ) ! = 0 ) {
strcpy ( _last_mqtt_aqualinkdata . last_display_message , status ) ;
send_mqtt_string_msg ( nc , DISPLAY_MSG_TOPIC , status ) ;
}
//}
2020-08-28 19:12:38 +00:00
2017-12-30 20:12:01 +00:00
if ( _aqualink_data - > air_temp ! = TEMP_UNKNOWN & & _aqualink_data - > air_temp ! = _last_mqtt_aqualinkdata . air_temp ) {
_last_mqtt_aqualinkdata . air_temp = _aqualink_data - > air_temp ;
send_mqtt_temp_msg ( nc , AIR_TEMP_TOPIC , _aqualink_data - > air_temp ) ;
2018-07-15 19:36:19 +00:00
//send_mqtt_temp_msg_new(nc, AIR_TEMPERATURE_TOPIC, _aqualink_data->air_temp);
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_temp_msg ( nc , _aqconfig_ . dzidx_air_temp , _aqualink_data - > air_temp ) ;
2017-12-30 20:12:01 +00:00
}
2019-03-01 15:45:59 +00:00
2019-01-18 03:38:25 +00:00
if ( _aqualink_data - > pool_temp ! = _last_mqtt_aqualinkdata . pool_temp ) {
2020-06-01 00:35:17 +00:00
if ( _aqualink_data - > pool_temp = = TEMP_UNKNOWN & & _aqconfig_ . report_zero_pool_temp ) {
2019-01-18 03:38:25 +00:00
_last_mqtt_aqualinkdata . pool_temp = TEMP_UNKNOWN ;
2023-05-14 21:35:13 +00:00
send_mqtt_temp_msg ( nc , POOL_TEMP_TOPIC , 0 ) ;
} if ( _aqualink_data - > pool_temp = = TEMP_UNKNOWN & & ! _aqconfig_ . report_zero_pool_temp ) {
// Don't post anything in this case, ie leave last posted value alone
2019-01-18 03:38:25 +00:00
} else if ( _aqualink_data - > pool_temp ! = TEMP_UNKNOWN ) {
_last_mqtt_aqualinkdata . pool_temp = _aqualink_data - > pool_temp ;
send_mqtt_temp_msg ( nc , POOL_TEMP_TOPIC , _aqualink_data - > pool_temp ) ;
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_temp_msg ( nc , _aqconfig_ . dzidx_pool_water_temp , _aqualink_data - > pool_temp ) ;
2019-01-18 03:38:25 +00:00
// IF spa is off, report pool water temp to Domoticz.
if ( _aqualink_data - > spa_temp = = TEMP_UNKNOWN )
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_temp_msg ( nc , _aqconfig_ . dzidx_spa_water_temp , _aqualink_data - > pool_temp ) ;
2019-01-18 03:38:25 +00:00
}
}
2018-07-15 23:36:59 +00:00
2018-07-20 17:29:13 +00:00
if ( _aqualink_data - > spa_temp ! = _last_mqtt_aqualinkdata . spa_temp ) {
2020-06-01 00:35:17 +00:00
if ( _aqualink_data - > spa_temp = = TEMP_UNKNOWN & & _aqconfig_ . report_zero_spa_temp ) {
2018-07-20 17:29:13 +00:00
_last_mqtt_aqualinkdata . spa_temp = TEMP_UNKNOWN ;
2023-05-14 21:35:13 +00:00
send_mqtt_temp_msg ( nc , SPA_TEMP_TOPIC , 0 ) ;
} if ( _aqualink_data - > spa_temp = = TEMP_UNKNOWN & & ! _aqconfig_ . report_zero_spa_temp & & _aqualink_data - > pool_temp ! = TEMP_UNKNOWN ) {
// Use Pool Temp as spa temp
if ( _last_mqtt_aqualinkdata . spa_temp ! = _aqualink_data - > pool_temp ) {
_last_mqtt_aqualinkdata . spa_temp = _aqualink_data - > pool_temp ;
send_mqtt_temp_msg ( nc , SPA_TEMP_TOPIC , _aqualink_data - > pool_temp ) ;
}
2018-11-28 23:21:07 +00:00
} else if ( _aqualink_data - > spa_temp ! = TEMP_UNKNOWN ) {
2018-07-20 17:29:13 +00:00
_last_mqtt_aqualinkdata . spa_temp = _aqualink_data - > spa_temp ;
send_mqtt_temp_msg ( nc , SPA_TEMP_TOPIC , _aqualink_data - > spa_temp ) ;
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_temp_msg ( nc , _aqconfig_ . dzidx_spa_water_temp , _aqualink_data - > spa_temp ) ;
2018-07-20 17:29:13 +00:00
}
}
2017-12-30 20:12:01 +00:00
if ( _aqualink_data - > pool_htr_set_point ! = TEMP_UNKNOWN & & _aqualink_data - > pool_htr_set_point ! = _last_mqtt_aqualinkdata . pool_htr_set_point ) {
_last_mqtt_aqualinkdata . pool_htr_set_point = _aqualink_data - > pool_htr_set_point ;
send_mqtt_setpoint_msg ( nc , BTN_POOL_HTR , _aqualink_data - > pool_htr_set_point ) ;
}
2018-07-15 19:36:19 +00:00
2017-12-30 20:12:01 +00:00
if ( _aqualink_data - > spa_htr_set_point ! = TEMP_UNKNOWN & & _aqualink_data - > spa_htr_set_point ! = _last_mqtt_aqualinkdata . spa_htr_set_point ) {
_last_mqtt_aqualinkdata . spa_htr_set_point = _aqualink_data - > spa_htr_set_point ;
send_mqtt_setpoint_msg ( nc , BTN_SPA_HTR , _aqualink_data - > spa_htr_set_point ) ;
}
2020-07-18 16:37:19 +00:00
2017-12-30 20:12:01 +00:00
if ( _aqualink_data - > frz_protect_set_point ! = TEMP_UNKNOWN & & _aqualink_data - > frz_protect_set_point ! = _last_mqtt_aqualinkdata . frz_protect_set_point ) {
_last_mqtt_aqualinkdata . frz_protect_set_point = _aqualink_data - > frz_protect_set_point ;
send_mqtt_setpoint_msg ( nc , FREEZE_PROTECT , _aqualink_data - > frz_protect_set_point ) ;
2020-07-18 16:37:19 +00:00
send_mqtt_string_msg ( nc , FREEZE_PROTECT_ENABELED , MQTT_ON ) ;
// Duplicate of below if statment. NSF come back and check if necessary for startup.
2019-01-24 02:32:22 +00:00
send_mqtt_string_msg ( nc , FREEZE_PROTECT , _aqualink_data - > frz_protect_state = = ON ? MQTT_ON : MQTT_OFF ) ;
_last_mqtt_aqualinkdata . frz_protect_state = _aqualink_data - > frz_protect_state ;
2017-12-30 20:12:01 +00:00
}
2018-07-15 23:36:59 +00:00
2019-01-21 00:27:59 +00:00
if ( _aqualink_data - > frz_protect_state ! = _last_mqtt_aqualinkdata . frz_protect_state ) {
_last_mqtt_aqualinkdata . frz_protect_state = _aqualink_data - > frz_protect_state ;
2020-07-18 16:37:19 +00:00
send_mqtt_string_msg ( nc , FREEZE_PROTECT , _aqualink_data - > frz_protect_state = = ON ? MQTT_ON : MQTT_OFF ) ;
//send_mqtt_string_msg(nc, FREEZE_PROTECT_ENABELED, MQTT_ON);
2019-01-21 00:27:59 +00:00
}
2019-01-24 02:32:22 +00:00
if ( _aqualink_data - > battery ! = _last_mqtt_aqualinkdata . battery ) {
_last_mqtt_aqualinkdata . battery = _aqualink_data - > battery ;
send_mqtt_string_msg ( nc , BATTERY_STATE , _aqualink_data - > battery = = OK ? MQTT_ON : MQTT_OFF ) ;
}
2020-06-06 16:36:04 +00:00
if ( _aqualink_data - > ph ! = TEMP_UNKNOWN & & _aqualink_data - > ph ! = _last_mqtt_aqualinkdata . ph ) {
_last_mqtt_aqualinkdata . ph = _aqualink_data - > ph ;
send_mqtt_float_msg ( nc , CHEM_PH_TOPIC , _aqualink_data - > ph ) ;
send_mqtt_float_msg ( nc , CHRM_PH_F_TOPIC , roundf ( degFtoC ( _aqualink_data - > ph ) ) ) ;
}
if ( _aqualink_data - > orp ! = TEMP_UNKNOWN & & _aqualink_data - > orp ! = _last_mqtt_aqualinkdata . orp ) {
_last_mqtt_aqualinkdata . orp = _aqualink_data - > orp ;
send_mqtt_numeric_msg ( nc , CHEM_ORP_TOPIC , _aqualink_data - > orp ) ;
send_mqtt_float_msg ( nc , CHRM_ORP_F_TOPIC , roundf ( degFtoC ( _aqualink_data - > orp ) ) ) ;
}
2019-10-18 16:53:49 +00:00
2020-07-18 16:37:19 +00:00
// Salt Water Generator
if ( _aqualink_data - > swg_led_state ! = LED_S_UNKNOWN ) {
2019-01-24 02:32:22 +00:00
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_DEBUG, "Sending MQTT SWG MEssages\n");
2019-10-18 16:53:49 +00:00
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > swg_led_state ! = _last_mqtt_aqualinkdata . swg_led_state ) {
send_mqtt_swg_state_msg ( nc , SWG_TOPIC , _aqualink_data - > swg_led_state ) ;
_last_mqtt_aqualinkdata . swg_led_state = _aqualink_data - > swg_led_state ;
}
2019-10-18 16:53:49 +00:00
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > swg_percent ! = TEMP_UNKNOWN & & ( _aqualink_data - > swg_percent ! = _last_mqtt_aqualinkdata . swg_percent ) ) {
2018-06-06 00:18:44 +00:00
_last_mqtt_aqualinkdata . swg_percent = _aqualink_data - > swg_percent ;
send_mqtt_numeric_msg ( nc , SWG_PERCENT_TOPIC , _aqualink_data - > swg_percent ) ;
send_mqtt_float_msg ( nc , SWG_PERCENT_F_TOPIC , roundf ( degFtoC ( _aqualink_data - > swg_percent ) ) ) ;
2018-09-12 21:04:09 +00:00
send_mqtt_float_msg ( nc , SWG_SETPOINT_TOPIC , roundf ( degFtoC ( _aqualink_data - > swg_percent ) ) ) ;
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_numeric_msg ( nc , _aqconfig_ . dzidx_swg_percent , _aqualink_data - > swg_percent ) ;
2018-06-06 00:18:44 +00:00
}
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > swg_ppm ! = TEMP_UNKNOWN & & ( _aqualink_data - > swg_ppm ! = _last_mqtt_aqualinkdata . swg_ppm ) ) {
2018-06-06 00:18:44 +00:00
_last_mqtt_aqualinkdata . swg_ppm = _aqualink_data - > swg_ppm ;
send_mqtt_numeric_msg ( nc , SWG_PPM_TOPIC , _aqualink_data - > swg_ppm ) ;
2019-08-23 23:14:14 +00:00
send_mqtt_float_msg ( nc , SWG_PPM_F_TOPIC , roundf ( degFtoC ( _aqualink_data - > swg_ppm ) ) ) ;
2020-06-01 00:35:17 +00:00
send_domoticz_mqtt_numeric_msg ( nc , _aqconfig_ . dzidx_swg_ppm , _aqualink_data - > swg_ppm ) ;
2018-06-06 00:18:44 +00:00
}
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > boost ! = _last_mqtt_aqualinkdata . boost ) {
send_mqtt_int_msg ( nc , SWG_BOOST_TOPIC , _aqualink_data - > boost ) ;
_last_mqtt_aqualinkdata . boost = _aqualink_data - > boost ;
}
} else {
//LOG(NET_LOG,LOG_DEBUG, "SWG status unknown\n");
2018-03-12 20:49:21 +00:00
}
2019-10-13 15:07:14 +00:00
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > ar_swg_device_status ! = SWG_STATUS_UNKNOWN ) {
//LOG(NET_LOG,LOG_DEBUG, "Sending MQTT SWG Extended %d\n",_aqualink_data->ar_swg_device_status);
if ( _aqualink_data - > ar_swg_device_status ! = _last_mqtt_aqualinkdata . ar_swg_device_status ) {
char message [ 30 ] ;
int status ;
int dzalert ;
get_swg_status_mqtt ( _aqualink_data , message , & status , & dzalert ) ;
send_domoticz_mqtt_status_message ( nc , _aqconfig_ . dzidx_swg_status , dzalert , & message [ 9 ] ) ;
2017-12-30 20:12:01 +00:00
2020-07-18 16:37:19 +00:00
send_mqtt_int_msg ( nc , SWG_EXTENDED_TOPIC , ( int ) _aqualink_data - > ar_swg_device_status ) ;
_last_mqtt_aqualinkdata . ar_swg_device_status = _aqualink_data - > ar_swg_device_status ;
//LOG(NET_LOG,LOG_DEBUG, "SWG Extended sending cur=%d sent=%d\n",_aqualink_data->ar_swg_device_status,_last_mqtt_aqualinkdata.ar_swg_device_status);
} else {
//LOG(NET_LOG,LOG_DEBUG, "SWG Extended already sent cur=%d sent=%d\n",_aqualink_data->ar_swg_device_status,_last_mqtt_aqualinkdata.ar_swg_device_status);
}
} else {
//LOG(NET_LOG,LOG_DEBUG, "SWG Extended unknown\n");
}
// LOG(NET_LOG,LOG_INFO, "mqtt_broadcast_aqualinkstate: START LEDs\n");
// if (time(NULL) % 2) {} <-- use to determin odd/even second in time to make state flash on enabled.
2017-12-30 20:12:01 +00:00
2018-08-02 00:47:55 +00:00
// Loop over LED's and send any changes.
2020-06-20 16:09:54 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
2020-07-18 16:37:19 +00:00
if ( _last_mqtt_aqualinkdata . aqualinkleds [ i ] . state ! = _aqualink_data - > aqbuttons [ i ] . led - > state ) {
2018-08-02 00:47:55 +00:00
_last_mqtt_aqualinkdata . aqualinkleds [ i ] . state = _aqualink_data - > aqbuttons [ i ] . led - > state ;
if ( _aqualink_data - > aqbuttons [ i ] . code = = KEY_POOL_HTR | | _aqualink_data - > aqbuttons [ i ] . code = = KEY_SPA_HTR ) {
send_mqtt_heater_state_msg ( nc , _aqualink_data - > aqbuttons [ i ] . name , _aqualink_data - > aqbuttons [ i ] . led - > state ) ;
} else {
send_mqtt_state_msg ( nc , _aqualink_data - > aqbuttons [ i ] . name , _aqualink_data - > aqbuttons [ i ] . led - > state ) ;
}
2023-05-14 21:35:13 +00:00
send_mqtt_timer_state_msg ( nc , _aqualink_data - > aqbuttons [ i ] . name , & _aqualink_data - > aqbuttons [ i ] ) ;
2023-05-16 16:17:42 +00:00
if ( _aqualink_data - > aqbuttons [ i ] . dz_idx ! = DZ_NULL_IDX ) {
2018-08-02 00:47:55 +00:00
send_domoticz_mqtt_state_msg ( nc , _aqualink_data - > aqbuttons [ i ] . dz_idx , ( _aqualink_data - > aqbuttons [ i ] . led - > state = = OFF ? DZ_OFF : DZ_ON ) ) ;
2023-05-16 16:17:42 +00:00
}
} else if ( ( _aqualink_data - > aqbuttons [ i ] . special_mask & TIMER_ACTIVE ) = = TIMER_ACTIVE ) {
//send_mqtt_timer_duration_msg(nc, _aqualink_data->aqbuttons[i].name, &_aqualink_data->aqbuttons[i]);
// send_mqtt_timer_state_msg will call send_mqtt_timer_duration_msg so no need to do it here.
// Have to use send_mqtt_timer_state_msg due to a timer being set on a device that's already on, (ir no state change so above code does't get hit)
send_mqtt_timer_state_msg ( nc , _aqualink_data - > aqbuttons [ i ] . name , & _aqualink_data - > aqbuttons [ i ] ) ;
2018-08-02 00:47:55 +00:00
}
}
2019-05-31 23:08:45 +00:00
// Loop over Pumps
2020-06-01 00:35:17 +00:00
for ( i = 0 ; i < _aqualink_data - > num_pumps ; i + + ) {
2019-05-31 23:08:45 +00:00
//_aqualink_data->pumps[i].rpm = TEMP_UNKNOWN;
//_aqualink_data->pumps[i].gph = TEMP_UNKNOWN;
//_aqualink_data->pumps[i].watts = TEMP_UNKNOWN;
if ( _aqualink_data - > pumps [ i ] . rpm ! = TEMP_UNKNOWN & & _aqualink_data - > pumps [ i ] . rpm ! = _last_mqtt_aqualinkdata . pumps [ i ] . rpm ) {
_last_mqtt_aqualinkdata . pumps [ i ] . rpm = _aqualink_data - > pumps [ i ] . rpm ;
2019-06-08 19:34:47 +00:00
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_RPM_TOPIC, _aqualink_data->pumps[i].rpm);
send_mqtt_aux_msg ( nc , _aqualink_data - > pumps [ i ] . button - > name , PUMP_RPM_TOPIC , _aqualink_data - > pumps [ i ] . rpm ) ;
2019-05-31 23:08:45 +00:00
}
2020-06-01 00:35:17 +00:00
if ( _aqualink_data - > pumps [ i ] . gpm ! = TEMP_UNKNOWN & & _aqualink_data - > pumps [ i ] . gpm ! = _last_mqtt_aqualinkdata . pumps [ i ] . gpm ) {
_last_mqtt_aqualinkdata . pumps [ i ] . gpm = _aqualink_data - > pumps [ i ] . gpm ;
2019-06-08 19:34:47 +00:00
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_GPH_TOPIC, _aqualink_data->pumps[i].gph);
2020-06-01 00:35:17 +00:00
send_mqtt_aux_msg ( nc , _aqualink_data - > pumps [ i ] . button - > name , PUMP_GPM_TOPIC , _aqualink_data - > pumps [ i ] . gpm ) ;
2019-05-31 23:08:45 +00:00
}
if ( _aqualink_data - > pumps [ i ] . watts ! = TEMP_UNKNOWN & & _aqualink_data - > pumps [ i ] . watts ! = _last_mqtt_aqualinkdata . pumps [ i ] . watts ) {
_last_mqtt_aqualinkdata . pumps [ i ] . watts = _aqualink_data - > pumps [ i ] . watts ;
2019-06-08 19:34:47 +00:00
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_WATTS_TOPIC, _aqualink_data->pumps[i].watts);
send_mqtt_aux_msg ( nc , _aqualink_data - > pumps [ i ] . button - > name , PUMP_WATTS_TOPIC , _aqualink_data - > pumps [ i ] . watts ) ;
2019-05-31 23:08:45 +00:00
}
}
2017-12-30 20:12:01 +00:00
}
//
2023-05-14 21:35:13 +00:00
/*
2019-08-18 20:54:10 +00:00
void set_light_mode ( char * value , int button )
2017-12-30 20:12:01 +00:00
{
2020-06-06 16:36:04 +00:00
int i ;
clight_detail * light = NULL ;
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL ) {
LOG ( NET_LOG , LOG_ERR , " Light mode control not supported in PDA mode \n " ) ;
2018-09-02 21:45:24 +00:00
return ;
}
2020-06-20 16:09:54 +00:00
# endif
2020-06-06 16:36:04 +00:00
for ( i = 0 ; i < _aqualink_data - > num_lights ; i + + ) {
if ( & _aqualink_data - > aqbuttons [ button ] = = _aqualink_data - > lights [ i ] . button ) {
// Found the programmable light
light = & _aqualink_data - > lights [ i ] ;
break ;
}
}
if ( light = = NULL ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " Light mode control not configured for button %d \n " , button ) ;
2019-08-18 20:54:10 +00:00
return ;
}
2018-09-02 21:45:24 +00:00
2018-07-15 19:36:19 +00:00
char buf [ LIGHT_MODE_BUFER ] ;
2020-06-06 16:36:04 +00:00
if ( light - > lightType = = LC_PROGRAMABLE ) {
2017-12-30 20:12:01 +00:00
// 5 below is light index, need to look this up so it's not hard coded.
2020-06-06 16:36:04 +00:00
sprintf ( buf , " %-5s%-5d%-5d%-5d%.2f " , value ,
2019-08-18 20:54:10 +00:00
button ,
2020-06-01 00:35:17 +00:00
_aqconfig_ . light_programming_initial_on ,
_aqconfig_ . light_programming_initial_off ,
_aqconfig_ . light_programming_mode ) ;
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_NOTICE, "WEB: requset light mode %s\n", buf);
2020-06-06 16:36:04 +00:00
aq_programmer ( AQ_SET_LIGHTPROGRAM_MODE , buf , _aqualink_data ) ;
} else {
sprintf ( buf , " %-5s%-5d%-5d " , value , button , light - > lightType ) ;
aq_programmer ( AQ_SET_LIGHTCOLOR_MODE , buf , _aqualink_data ) ;
}
2017-12-30 20:12:01 +00:00
}
2023-05-14 21:35:13 +00:00
*/
2017-12-30 20:12:01 +00:00
2023-05-14 21:35:13 +00:00
typedef enum { uActioned , uBad , uDevices , uStatus , uHomebridge , uDynamicconf , uDebugStatus , uDebugDownload , uSimulator , uSchedules , uSetSchedules } uriAtype ;
//typedef enum {NET_MQTT=0, NET_API, NET_WS, DZ_MQTT} netRequest;
const char actionName [ ] [ 5 ] = { " MQTT " , " API " , " WS " , " DZ " } ;
2020-07-18 16:37:19 +00:00
# define BAD_SETPOINT "No device for setpoint found"
# define NO_PLIGHT_DEVICE "No programable light found"
# define NO_VSP_SUPPORT "Pump VS programs not supported yet"
# define PUMP_NOT_FOUND "No matching Pump found"
# define NO_DEVICE "No matching Device found"
# define INVALID_VALUE "Invalid value"
# define NOCHANGE_IGNORING "No change, device is already in that state"
# define UNKNOWN_REQUEST "Didn't understand request"
2023-05-14 21:35:13 +00:00
/*
void create_program_request ( request_source requester , action_type type , int value , int id ) // id is only valid for PUMP RPM
2020-07-18 16:37:19 +00:00
{
2023-05-14 21:35:13 +00:00
//panel_device_request(struct aqualinkdata *aqdata, action_type type, int deviceIndex, int value, int subIndex, request_source source);
//panel_device_request(_aqualink_data, type, id, value, requester);
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > unactioned . type ! = NO_ACTION & & type ! = _aqualink_data - > unactioned . type )
LOG ( NET_LOG , LOG_ERR , " %s: About to overwrite unactioned panel program \n " , actionName [ requester ] ) ;
if ( type = = POOL_HTR_SETOINT | | type = = SPA_HTR_SETOINT | | type = = FREEZE_SETPOINT | | type = = SWG_SETPOINT ) {
_aqualink_data - > unactioned . value = setpoint_check ( type , value , _aqualink_data ) ;
if ( value ! = _aqualink_data - > unactioned . value )
LOG ( NET_LOG , LOG_NOTICE , " %s: requested setpoint value %d is invalid, change to %d \n " , actionName [ requester ] , value , _aqualink_data - > unactioned . value ) ;
} else if ( type = = PUMP_RPM ) {
//_aqualink_data->unactioned.value = RPM_check(_aqualink_data->pumps[id].pumpType , value, _aqualink_data);
_aqualink_data - > unactioned . value = value ;
//if (value != _aqualink_data->unactioned.value)
// LOG(NET_LOG,LOG_NOTICE, "%s: requested Pump value %d is invalid, change to %d\n",actionName[requester], value, _aqualink_data->unactioned.value);
} else if ( type = = PUMP_VSPROGRAM ) {
//_aqualink_data->unactioned.value = value;
//if (value != _aqualink_data->unactioned.value)
LOG ( NET_LOG , LOG_ERR , " %s: requested Pump vsp program is not implimented yet \n " , actionName [ requester ] , value , _aqualink_data - > unactioned . value ) ;
} else {
// SWG_BOOST & PUMP_RPM
_aqualink_data - > unactioned . value = value ;
2020-06-20 16:09:54 +00:00
}
2020-07-18 16:37:19 +00:00
_aqualink_data - > unactioned . type = type ;
_aqualink_data - > unactioned . id = id ; // This is only valid for pump.
2020-07-26 19:28:58 +00:00
if ( requester = = NET_MQTT ) // We can get multiple MQTT requests from some, so this will wait for last one to come in.
2020-07-18 16:37:19 +00:00
time ( & _aqualink_data - > unactioned . requested ) ;
else
_aqualink_data - > unactioned . requested = 0 ;
2020-06-20 16:09:54 +00:00
}
2023-05-14 21:35:13 +00:00
*/
2020-06-20 16:09:54 +00:00
2023-05-14 21:35:13 +00:00
# ifdef AQ_PDA
void create_PDA_on_off_request ( aqkey * button , bool isON )
{
int i ;
char msg [ PTHREAD_ARG ] ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( _aqualink_data - > aqbuttons [ i ] . code = = button - > code ) {
sprintf ( msg , " %-5d%-5d " , i , ( isON ? ON : OFF ) ) ;
aq_programmer ( AQ_PDA_DEVICE_ON_OFF , msg , _aqualink_data ) ;
break ;
}
}
}
# endif
/*
bool create_panel_request ( request_source requester , int buttonIndex , int value , bool timer ) {
//if (timer)
// return panel_device_request(_aqualink_data, TIMER, buttonIndex, value, requester);
//else
// return panel_device_request(_aqualink_data, ON_OFF, buttonIndex, value, requester);
// if value = 0 is OFF,
// if value = 1 is ON if (timer = false).
// if value > 0 (timer should be true, and vaue is duration).
if ( ( _aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = = OFF & & value = = 0 ) | |
( value > 0 & & ( _aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = = ON | | _aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = = FLASH | |
_aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = = ENABLE ) ) ) {
LOG ( NET_LOG , LOG_INFO , " %s: received '%s' for '%s', already '%s', Ignoring \n " , actionName [ requester ] , ( value = = 0 ? " OFF " : " ON " ) , _aqualink_data - > aqbuttons [ buttonIndex ] . name , ( value = = 0 ? " OFF " : " ON " ) ) ;
//return false;
} else {
LOG ( NET_LOG , LOG_INFO , " %s: received '%s' for '%s', turning '%s' \n " , actionName [ requester ] , ( value = = 0 ? " OFF " : " ON " ) , _aqualink_data - > aqbuttons [ buttonIndex ] . name , ( value = = 0 ? " OFF " : " ON " ) ) ;
# ifdef AQ_PDA
if ( isPDA_PANEL ) {
char msg [ PTHREAD_ARG ] ;
sprintf ( msg , " %-5d%-5d " , buttonIndex , ( value = = 0 ? OFF : ON ) ) ;
aq_programmer ( AQ_PDA_DEVICE_ON_OFF , msg , _aqualink_data ) ;
} else
# endif
{
// Check for panel programmable light. if so simple ON isn't going to work well
// Could also add "light mode" check, as this is only valid for panel configured light not aqualinkd configured light.
if ( ( _aqualink_data - > aqbuttons [ buttonIndex ] . special_mask & PROGRAM_LIGHT ) = = PROGRAM_LIGHT & & _aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = = OFF ) {
// OK Programable light, and no light mode selected. Now let's work out best way to turn it on. serial_adapter protocol will to it without questions,
// all other will require programmig.
if ( isRSSA_ENABLED ) {
set_aqualink_rssadapter_aux_state ( buttonIndex , true ) ;
} else {
set_light_mode ( " 0 " , buttonIndex ) ; // 0 means use current light mode
}
} else {
aq_send_cmd ( _aqualink_data - > aqbuttons [ buttonIndex ] . code ) ;
}
// Pre set device to state, next status will correct if state didn't take, but this will stop multiple ON messages setting on/off
# ifdef PRESTATE_ONOFF
if ( ( _aqualink_data - > aqbuttons [ buttonIndex ] . code = = KEY_POOL_HTR | | _aqualink_data - > aqbuttons [ buttonIndex ] . code = = KEY_SPA_HTR | |
_aqualink_data - > aqbuttons [ buttonIndex ] . code = = KEY_SOLAR_HTR ) & &
value > 0 ) {
_aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = ENABLE ; // if heater and set to on, set pre-status to enable.
//_aqualink_data->updated = true;
} else if ( isRSSA_ENABLED | | ( ( _aqualink_data - > aqbuttons [ buttonIndex ] . special_mask & PROGRAM_LIGHT ) ! = PROGRAM_LIGHT ) ) {
_aqualink_data - > aqbuttons [ buttonIndex ] . led - > state = ( value = = 0 ? OFF : ON ) ; // as long as it's not programmable light , pre-set to on/off
//_aqualink_data->updated = true;
}
# endif
}
}
// If it's a timer, start the timer
if ( timer ) {
start_timer ( _aqualink_data , & _aqualink_data - > aqbuttons [ buttonIndex ] , value ) ;
}
return true ;
}
*/
2020-06-20 16:09:54 +00:00
2020-07-18 16:37:19 +00:00
//uriAtype action_URI(char *from, const char *URI, int uri_length, float value, bool convertTemp) {
//uriAtype action_URI(netRequest from, const char *URI, int uri_length, float value, bool convertTemp) {
2023-05-14 21:35:13 +00:00
uriAtype action_URI ( request_source from , const char * URI , int uri_length , float value , bool convertTemp , char * * rtnmsg ) {
2020-06-20 16:09:54 +00:00
/* Example URI ()
* Note URI is NOT terminated
* devices
* status
* Freeze / setpoint / set
* Filter_Pump / set
* Pool_Heater / setpoint / set
* Pool_Heater / set
* SWG / Percent_f / set
* Filter_Pump / RPM / set
* Pump_1 / RPM / set
* Pool Light / color / set
2023-05-16 22:27:45 +00:00
* Pool Light / program / set
2020-06-20 16:09:54 +00:00
*/
uriAtype rtn = uBad ;
bool found = false ;
int i ;
char * ri1 = ( char * ) URI ;
char * ri2 = NULL ;
char * ri3 = NULL ;
2020-08-28 19:12:38 +00:00
LOG ( NET_LOG , LOG_DEBUG , " %s: URI Request '%.*s': value %.2f \n " , actionName [ from ] , uri_length , URI , value ) ;
2020-06-20 16:09:54 +00:00
// Split up the URI into parts.
for ( i = 1 ; i < uri_length ; i + + ) {
if ( URI [ i ] = = ' / ' ) {
if ( ri2 = = NULL ) {
ri2 = ( char * ) & URI [ + + i ] ;
} else if ( ri3 = = NULL ) {
ri3 = ( char * ) & URI [ + + i ] ;
break ;
2018-09-23 21:54:15 +00:00
}
2020-06-20 16:09:54 +00:00
}
}
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_NOTICE, "URI Request: %.*s, %.*s, %.*s | %f\n", uri_length, ri1, uri_length - (ri2 - ri1), ri2, uri_length - (ri3 - ri1), ri3, value);
2020-06-20 16:09:54 +00:00
if ( strncmp ( ri1 , " devices " , 7 ) = = 0 ) {
return uDevices ;
} else if ( strncmp ( ri1 , " status " , 6 ) = = 0 ) {
return uStatus ;
} else if ( strncmp ( ri1 , " homebridge " , 10 ) = = 0 ) {
return uHomebridge ;
} else if ( strncmp ( ri1 , " dynamicconfig " , 13 ) = = 0 ) {
return uDynamicconf ;
2023-05-14 21:35:13 +00:00
} else if ( strncmp ( ri1 , " schedules/set " , 13 ) = = 0 ) {
return uSetSchedules ;
} else if ( strncmp ( ri1 , " schedules " , 9 ) = = 0 ) {
return uSchedules ;
} else if ( strncmp ( ri1 , " simulator " , 9 ) = = 0 & & from = = NET_WS ) { // Only valid from websocket.
return uSimulator ;
} else if ( strncmp ( ri1 , " rawcommand " , 10 ) = = 0 & & from = = NET_WS ) { // Only valid from websocket.
aq_send_cmd ( ( unsigned char ) value ) ;
return uActioned ;
2020-07-18 16:37:19 +00:00
} else if ( strncmp ( ri1 , " debug " , 5 ) = = 0 ) {
if ( ri2 ! = NULL & & strncmp ( ri2 , " start " , 5 ) = = 0 ) {
startInlineDebug ( ) ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " stop " , 4 ) = = 0 ) {
stopInlineDebug ( ) ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " serialstart " , 11 ) = = 0 ) {
startInlineSerialDebug ( ) ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " serialstop " , 10 ) = = 0 ) {
stopInlineDebug ( ) ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " clean " , 5 ) = = 0 ) {
cleanInlineDebug ( ) ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " download " , 8 ) = = 0 ) {
return uDebugDownload ;
} else if ( ri2 ! = NULL & & strncmp ( ri2 , " stop " , 4 ) = = 0 ) {
}
return uDebugStatus ;
2020-08-28 19:12:38 +00:00
// couple of debug items for testing
} else if ( strncmp ( ri1 , " set_date_time " , 13 ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//aq_programmer(AQ_SET_TIME, NULL, _aqualink_data);
panel_device_request ( _aqualink_data , DATE_TIME , 0 , 0 , from ) ;
2020-08-28 19:12:38 +00:00
return uActioned ;
} else if ( strncmp ( ri1 , " startup_program " , 15 ) = = 0 ) {
if ( isRS_PANEL )
queueGetProgramData ( ALLBUTTON , _aqualink_data ) ;
if ( isRSSA_ENABLED )
queueGetProgramData ( RSSADAPTER , _aqualink_data ) ;
# ifdef AQ_ONETOUCH
if ( isONET_ENABLED )
queueGetProgramData ( ONETOUCH , _aqualink_data ) ;
# endif
# ifdef AQ_IAQTOUCH
if ( isIAQT_ENABLED )
queueGetProgramData ( IAQTOUCH , _aqualink_data ) ;
# endif
# ifdef AQ_PDA
if ( isPDA_PANEL )
queueGetProgramData ( AQUAPDA , _aqualink_data ) ;
# endif
return uActioned ;
// Action a setpoint message
} else if ( ri3 ! = NULL & & ( strncasecmp ( ri2 , " setpoint " , 8 ) = = 0 ) & & ( strncasecmp ( ri3 , " increment " , 9 ) = = 0 ) ) {
if ( ! isRSSA_ENABLED ) {
LOG ( NET_LOG , LOG_WARNING , " %s: ignoring %.*s setpoint increment only valid when RS Serial adapter protocol is enabeled \n " , actionName [ from ] , uri_length , URI ) ;
* rtnmsg = BAD_SETPOINT ;
return uBad ;
}
int val = round ( value ) ;
if ( strncmp ( ri1 , BTN_POOL_HTR , strlen ( BTN_POOL_HTR ) ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, POOL_HTR_INCREMENT, val, 0);
panel_device_request ( _aqualink_data , POOL_HTR_INCREMENT , 0 , val , from ) ;
2020-08-28 19:12:38 +00:00
} else if ( strncmp ( ri1 , BTN_SPA_HTR , strlen ( BTN_SPA_HTR ) ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, SPA_HTR_INCREMENT, val, 0);
panel_device_request ( _aqualink_data , SPA_HTR_INCREMENT , 0 , val , from ) ;
2020-08-28 19:12:38 +00:00
} else {
LOG ( NET_LOG , LOG_WARNING , " %s: ignoring %.*s setpoint add only valid for pool & spa \n " , actionName [ from ] , uri_length , URI ) ;
* rtnmsg = BAD_SETPOINT ;
return uBad ;
}
rtn = uActioned ;
2020-06-20 16:09:54 +00:00
} else if ( ri3 ! = NULL & & ( strncasecmp ( ri2 , " setpoint " , 8 ) = = 0 ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) {
int val = convertTemp ? round ( degCtoF ( value ) ) : round ( value ) ;
if ( strncmp ( ri1 , BTN_POOL_HTR , strlen ( BTN_POOL_HTR ) ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, POOL_HTR_SETOINT, val, 0);
panel_device_request ( _aqualink_data , POOL_HTR_SETOINT , 0 , val , from ) ;
2020-06-20 16:09:54 +00:00
} else if ( strncmp ( ri1 , BTN_SPA_HTR , strlen ( BTN_SPA_HTR ) ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, SPA_HTR_SETOINT, val, 0);
panel_device_request ( _aqualink_data , SPA_HTR_SETOINT , 0 , val , from ) ;
2020-06-20 16:09:54 +00:00
} else if ( strncmp ( ri1 , FREEZE_PROTECT , strlen ( FREEZE_PROTECT ) ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, FREEZE_SETPOINT, val, 0);
panel_device_request ( _aqualink_data , FREEZE_SETPOINT , 0 , val , from ) ;
2020-06-20 16:09:54 +00:00
} else if ( strncmp ( ri1 , " SWG " , 3 ) = = 0 ) { // If we get SWG percent as setpoint message it's from homebridge so use the convert
//int val = round(degCtoF(value));
//int val = convertTemp? round(degCtoF(value)) : round(value);
2023-05-14 21:35:13 +00:00
//create_program_request(from, SWG_SETPOINT, val, 0);
panel_device_request ( _aqualink_data , SWG_SETPOINT , 0 , val , from ) ;
2020-06-20 16:09:54 +00:00
} else {
// Not sure what the setpoint is, ignore.
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " %s: ignoring %.*s don't recognise button setpoint \n " , actionName [ from ] , uri_length , URI ) ;
* rtnmsg = BAD_SETPOINT ;
2020-06-20 16:09:54 +00:00
return uBad ;
}
rtn = uActioned ;
2020-08-28 19:12:38 +00:00
/* Moved into create_program_request()
2020-07-26 19:28:58 +00:00
if ( from = = NET_MQTT ) // We can get multiple MQTT requests for
2020-07-18 16:37:19 +00:00
time ( & _aqualink_data - > unactioned . requested ) ;
else
_aqualink_data - > unactioned . requested = 0 ;
2020-08-28 19:12:38 +00:00
*/
2020-06-20 16:09:54 +00:00
// Action a SWG Percent message
} else if ( ( ri3 ! = NULL & & ( strncmp ( ri1 , " SWG " , 3 ) = = 0 ) & & ( strncasecmp ( ri2 , " Percent " , 7 ) = = 0 ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) ) {
int val ;
if ( ( strncmp ( ri2 , " Percent_f " , 9 ) = = 0 ) ) {
val = _aqualink_data - > unactioned . value = round ( degCtoF ( value ) ) ;
} else {
val = _aqualink_data - > unactioned . value = round ( value ) ;
}
2023-05-14 21:35:13 +00:00
//create_program_request(from, SWG_SETPOINT, val, 0);
panel_device_request ( _aqualink_data , SWG_SETPOINT , 0 , val , from ) ;
2020-06-20 16:09:54 +00:00
rtn = uActioned ;
// Action a SWG boost message
} else if ( ( ri3 ! = NULL & & ( strncmp ( ri1 , " SWG " , 3 ) = = 0 ) & & ( strncasecmp ( ri2 , " Boost " , 5 ) = = 0 ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) ) {
2023-05-14 21:35:13 +00:00
//create_program_request(from, SWG_BOOST, round(value), 0);
panel_device_request ( _aqualink_data , SWG_BOOST , 0 , round ( value ) , from ) ;
if ( _aqualink_data - > swg_led_state = = OFF )
rtn = uBad ; // Return bad so we repost a mqtt update
else
rtn = uActioned ;
2020-06-20 16:09:54 +00:00
// Action Light program.
} else if ( ( ri3 ! = NULL & & ( ( strncasecmp ( ri2 , " color " , 5 ) = = 0 ) | | ( strncasecmp ( ri2 , " program " , 7 ) = = 0 ) ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) ) {
found = false ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( strncmp ( ri1 , _aqualink_data - > aqbuttons [ i ] . name , strlen ( _aqualink_data - > aqbuttons [ i ] . name ) ) = = 0 | |
strncmp ( ri1 , _aqualink_data - > aqbuttons [ i ] . label , strlen ( _aqualink_data - > aqbuttons [ i ] . label ) ) = = 0 )
{
2023-05-14 21:35:13 +00:00
//char buf[5];
2020-06-20 16:09:54 +00:00
found = true ;
2023-05-14 21:35:13 +00:00
//sprintf(buf,"%.0f",value);
//set_light_mode(buf, i);
panel_device_request ( _aqualink_data , LIGHT_MODE , i , value , from ) ;
2020-06-20 16:09:54 +00:00
break ;
2019-08-25 20:57:51 +00:00
}
2020-06-20 16:09:54 +00:00
}
if ( ! found ) {
2020-07-18 16:37:19 +00:00
* rtnmsg = NO_PLIGHT_DEVICE ;
LOG ( NET_LOG , LOG_WARNING , " %s: Didn't find device that matched URI '%.*s' \n " , actionName [ from ] , uri_length , URI ) ;
2020-06-20 16:09:54 +00:00
rtn = uBad ;
}
// Action a pump RPM/GPM message
2020-07-18 16:37:19 +00:00
} else if ( ( ri3 ! = NULL & & ( ( strncasecmp ( ri2 , " RPM " , 3 ) = = 0 ) | | ( strncasecmp ( ri2 , " GPM " , 3 ) = = 0 ) | | ( strncasecmp ( ri2 , " VSP " , 3 ) = = 0 ) ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) ) {
2020-06-20 16:09:54 +00:00
found = false ;
// Is it a pump index or pump name
if ( strncmp ( ri1 , " Pump_ " , 5 ) = = 0 ) { // Pump by number
int pumpIndex = atoi ( ri1 + 5 ) ; // Check for 0
for ( i = 0 ; i < _aqualink_data - > num_pumps ; i + + ) {
if ( _aqualink_data - > pumps [ i ] . pumpIndex = = pumpIndex ) {
2020-07-18 16:37:19 +00:00
if ( ( strncasecmp ( ri2 , " VSP " , 3 ) = = 0 ) ) {
if ( isIAQT_ENABLED ) {
//LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d to program %d\n",actionName[from], pumpIndex+1, round(value));
//create_program_request(from, PUMP_VSPROGRAM, round(value), pumpIndex);
LOG ( NET_LOG , LOG_ERR , " Setting Pump VSP is not supported yet \n " ) ;
* rtnmsg = NO_VSP_SUPPORT ;
return uBad ;
} else {
LOG ( NET_LOG , LOG_ERR , " Setting Pump VSP only supported if iAqualinkTouch protocol en enabled \n " ) ;
* rtnmsg = NO_VSP_SUPPORT ;
return uBad ;
}
} else {
LOG ( NET_LOG , LOG_NOTICE , " %s: request to change pump %d %s to %d \n " , actionName [ from ] , pumpIndex + 1 , ( strncasecmp ( ri2 , " GPM " , 3 ) = = 0 ) ? " GPM " : " RPM " , round ( value ) ) ;
2023-05-14 21:35:13 +00:00
//create_program_request(from, PUMP_RPM, round(value), pumpIndex);
panel_device_request ( _aqualink_data , PUMP_RPM , pumpIndex , round ( value ) , from ) ;
2020-07-18 16:37:19 +00:00
}
//_aqualink_data->unactioned.type = PUMP_RPM;
//_aqualink_data->unactioned.value = round(value);
//_aqualink_data->unactioned.id = pumpIndex;
2020-06-01 00:35:17 +00:00
found = true ;
break ;
}
}
2020-06-20 16:09:54 +00:00
} else { // Pump by button name
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( strncmp ( ri1 , _aqualink_data - > aqbuttons [ i ] . name , strlen ( _aqualink_data - > aqbuttons [ i ] . name ) ) = = 0 ) {
int pi ;
for ( pi = 0 ; pi < _aqualink_data - > num_pumps ; pi + + ) {
if ( _aqualink_data - > pumps [ pi ] . button = = & _aqualink_data - > aqbuttons [ i ] ) {
2020-07-18 16:37:19 +00:00
if ( ( strncasecmp ( ri2 , " VSP " , 3 ) = = 0 ) ) {
if ( isIAQT_ENABLED ) {
//LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d to program %d\n",actionName[from], pi+1, round(value));
//create_program_request(from, PUMP_VSPROGRAM, round(value), _aqualink_data->pumps[pi].pumpIndex);
LOG ( NET_LOG , LOG_ERR , " Setting Pump VSP is not supported yet \n " ) ;
* rtnmsg = NO_VSP_SUPPORT ;
return uBad ;
} else {
LOG ( NET_LOG , LOG_ERR , " Setting Pump VSP only supported if iAqualinkTouch protocol en enabled \n " ) ;
* rtnmsg = NO_VSP_SUPPORT ;
return uBad ;
}
} else {
LOG ( NET_LOG , LOG_NOTICE , " %s: request to change pump %d %s to %d \n " , actionName [ from ] , pi + 1 , ( strncasecmp ( ri2 , " GPM " , 3 ) = = 0 ) ? " GPM " : " RPM " , round ( value ) ) ;
2023-05-14 21:35:13 +00:00
//create_program_request(from, PUMP_RPM, round(value), _aqualink_data->pumps[pi].pumpIndex);
panel_device_request ( _aqualink_data , PUMP_RPM , _aqualink_data - > pumps [ pi ] . pumpIndex , round ( value ) , from ) ;
2020-07-18 16:37:19 +00:00
}
//_aqualink_data->unactioned.type = PUMP_RPM;
//_aqualink_data->unactioned.value = round(value);
//_aqualink_data->unactioned.id = _aqualink_data->pumps[pi].pumpIndex;
2020-06-20 16:09:54 +00:00
found = true ;
break ;
}
}
}
}
}
if ( ! found ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " %s: Didn't find pump from message %.*s \n " , actionName [ from ] , uri_length , URI ) ;
* rtnmsg = PUMP_NOT_FOUND ;
2020-06-20 16:09:54 +00:00
rtn = uBad ;
2017-12-30 20:12:01 +00:00
} else {
2020-06-20 16:09:54 +00:00
rtn = uActioned ;
}
// Action a Turn on / off message
2023-05-14 21:35:13 +00:00
} else if ( ( ri2 ! = NULL & & ( strncasecmp ( ri2 , " set " , 3 ) = = 0 ) & & ( strncasecmp ( ri2 , " setpoint " , 8 ) ! = 0 ) ) | |
( ri2 ! = NULL & & ri3 ! = NULL & & ( strncasecmp ( ri2 , " timer " , 5 ) = = 0 ) & & ( strncasecmp ( ri3 , " set " , 3 ) = = 0 ) ) ) {
2020-06-20 16:09:54 +00:00
// Must be a switch on / off
rtn = uActioned ;
found = false ;
2023-05-14 21:35:13 +00:00
//bool istimer = false;
action_type atype = ON_OFF ;
//int timer=0;
if ( strncasecmp ( ri2 , " timer " , 5 ) = = 0 ) {
//istimer = true;
atype = TIMER ;
//timer = value; // Save off timer
//value = 1; // Make sure we turn device on if timer.
} else if ( value > 1 | | value < 0 ) {
LOG ( NET_LOG , LOG_WARNING , " %s: URI %s has invalid value %.2f \n " , actionName [ from ] , URI , value ) ;
* rtnmsg = INVALID_VALUE ;
rtn = uBad ;
return rtn ;
}
2020-06-20 16:09:54 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
2023-05-14 21:35:13 +00:00
// If Label = "Spa", "Spa_Heater" will turn on "Spa", so need to check '/' on label as next character
2020-06-20 16:09:54 +00:00
if ( strncmp ( ri1 , _aqualink_data - > aqbuttons [ i ] . name , strlen ( _aqualink_data - > aqbuttons [ i ] . name ) ) = = 0 | |
2023-05-14 21:35:13 +00:00
( strncmp ( ri1 , _aqualink_data - > aqbuttons [ i ] . label , strlen ( _aqualink_data - > aqbuttons [ i ] . label ) ) = = 0 & & ri1 [ strlen ( _aqualink_data - > aqbuttons [ i ] . label ) ] = = ' / ' ) )
2020-06-20 16:09:54 +00:00
{
found = true ;
2023-05-14 21:35:13 +00:00
//create_panel_request(from, i, value, istimer);
panel_device_request ( _aqualink_data , atype , i , value , from ) ;
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_INFO, "%s: MATCH %s to topic %.*s\n",from,_aqualink_data->aqbuttons[i].name,uri_length, URI);
2020-06-20 16:09:54 +00:00
// Message is either a 1 or 0 for on or off
//int status = atoi(msg->payload.p);
2023-05-14 21:35:13 +00:00
/*
2020-06-20 16:09:54 +00:00
if ( value > 1 | | value < 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " %s: URI %s has invalid value %.2f \n " , actionName [ from ] , URI , value ) ;
* rtnmsg = INVALID_VALUE ;
rtn = uBad ;
2020-06-20 16:09:54 +00:00
}
2023-05-14 21:35:13 +00:00
if ( timer > 0 ) {
create_panel_request ( from , i , timer , true ) ;
2020-06-20 16:09:54 +00:00
} else {
2023-05-14 21:35:13 +00:00
create_panel_request ( from , i , value , false ) ;
} */
2017-12-30 20:12:01 +00:00
}
}
2020-06-20 16:09:54 +00:00
if ( ! found ) {
2020-07-18 16:37:19 +00:00
* rtnmsg = NO_DEVICE ;
LOG ( NET_LOG , LOG_WARNING , " %s: Didn't find device that matched URI '%.*s' \n " , actionName [ from ] , uri_length , URI ) ;
2020-06-20 16:09:54 +00:00
rtn = uBad ;
}
2017-12-30 20:12:01 +00:00
} else {
2020-06-20 16:09:54 +00:00
// We don's care
2020-07-18 16:37:19 +00:00
* rtnmsg = UNKNOWN_REQUEST ;
LOG ( NET_LOG , LOG_WARNING , " %s: ignoring, unknown URI %.*s \n " , actionName [ from ] , uri_length , URI ) ;
2020-06-20 16:09:54 +00:00
rtn = uBad ;
2017-12-30 20:12:01 +00:00
}
2018-07-15 19:36:19 +00:00
2020-06-20 16:09:54 +00:00
return rtn ;
2017-12-30 20:12:01 +00:00
}
2020-07-26 19:28:58 +00:00
2017-12-30 20:12:01 +00:00
void action_mqtt_message ( struct mg_connection * nc , struct mg_mqtt_message * msg ) {
2020-07-18 16:37:19 +00:00
char * rtnmsg ;
2020-07-26 19:28:58 +00:00
# ifdef AQ_TM_DEBUG
int tid ;
# endif
2020-06-20 16:09:54 +00:00
//unsigned int i;
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_DEBUG, "MQTT: topic %.*s %.2f\n",msg->topic.len, msg->topic.p, atof(msg->payload.p));
2020-08-28 19:12:38 +00:00
// If message doesn't end in set or increment we don't care about it.
2023-05-14 21:35:13 +00:00
if ( strncmp ( & msg - > topic . p [ msg - > topic . len - 4 ] , " /set " , 4 ) ! = 0 & & strncmp ( & msg - > topic . p [ msg - > topic . len - 10 ] , " /increment " , 10 ) ! = 0 ) {
LOG ( NET_LOG , LOG_DEBUG , " MQTT: Ignore %.*s %.*s \n " , msg - > topic . len , msg - > topic . p , msg - > payload . len , msg - > payload . p ) ;
2018-09-23 14:17:58 +00:00
return ;
}
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " MQTT: topic %.*s %.*s \n " , msg - > topic . len , msg - > topic . p , msg - > payload . len , msg - > payload . p ) ;
2018-03-12 20:49:21 +00:00
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_START ( & tid ) ;
2018-03-12 20:49:21 +00:00
//Need to do this in a better manor, but for present it's ok.
static char tmp [ 20 ] ;
strncpy ( tmp , msg - > payload . p , msg - > payload . len ) ;
tmp [ msg - > payload . len ] = ' \0 ' ;
float value = atof ( tmp ) ;
2020-06-20 16:09:54 +00:00
//int val = _aqualink_data->unactioned.value = (_aqualink_data->temp_units != CELSIUS && _aqconfig_.convert_mqtt_temp) ? round(degCtoF(value)) : round(value);
bool convert = ( _aqualink_data - > temp_units ! = CELSIUS & & _aqconfig_ . convert_mqtt_temp ) ? true : false ;
int offset = strlen ( _aqconfig_ . mqtt_aq_topic ) + 1 ;
2023-05-14 21:35:13 +00:00
if ( action_URI ( NET_MQTT , & msg - > topic . p [ offset ] , msg - > topic . len - offset , value , convert , & rtnmsg ) = = uBad ) {
// Check if it was something that can't be changed, if so send back current state. Homekit thermostat for SWG and Freezeprotect.
if ( strncmp ( & msg - > topic . p [ offset ] , FREEZE_PROTECT , strlen ( FREEZE_PROTECT ) ) = = 0 ) {
if ( _aqualink_data - > frz_protect_set_point ! = TEMP_UNKNOWN ) {
send_mqtt_setpoint_msg ( nc , FREEZE_PROTECT , _aqualink_data - > frz_protect_set_point ) ;
send_mqtt_string_msg ( nc , FREEZE_PROTECT_ENABELED , MQTT_ON ) ;
} else {
send_mqtt_string_msg ( nc , FREEZE_PROTECT_ENABELED , MQTT_OFF ) ;
}
send_mqtt_string_msg ( nc , FREEZE_PROTECT , _aqualink_data - > frz_protect_state = = ON ? MQTT_ON : MQTT_OFF ) ;
} else if ( strncmp ( & msg - > topic . p [ offset ] , SWG_TOPIC , strlen ( SWG_TOPIC ) ) = = 0 ) {
if ( _aqualink_data - > swg_led_state ! = LED_S_UNKNOWN ) {
send_mqtt_swg_state_msg ( nc , SWG_TOPIC , _aqualink_data - > swg_led_state ) ;
send_mqtt_int_msg ( nc , SWG_BOOST_TOPIC , _aqualink_data - > boost ) ;
}
}
}
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_mqtt_message() completed, took " ) ;
2020-06-20 16:09:54 +00:00
}
2020-07-26 19:28:58 +00:00
2020-06-20 16:09:54 +00:00
float pass_mg_body ( struct mg_str * body ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Message body: \n '%.*s' \n " , body - > len , body - > p ) ;
2020-06-20 16:09:54 +00:00
// Quick n dirty pass value from either of below.
// value=1.5&arg2=val2
// {"value":"1.5"}
int i ;
2020-08-28 19:12:38 +00:00
char buf [ 10 ] ;
2020-06-20 16:09:54 +00:00
// NSF Really need to come back and clean this up
for ( i = 0 ; i < body - > len ; i + + ) {
if ( body - > p [ i ] = = ' = ' | | body - > p [ i ] = = ' : ' ) {
2020-08-28 19:12:38 +00:00
while ( ! isdigit ( ( unsigned char ) body - > p [ i ] ) & & body - > p [ i ] ! = ' - ' & & i < body - > len ) { i + + ; }
if ( i < body - > len ) {
// Need to copy to buffer so we can terminate correctly.
strncpy ( buf , & body - > p [ i ] , body - > len - i ) ;
buf [ body - > len - i ] = ' \0 ' ;
//return atof(&body->p[i]);
return atof ( buf ) ;
}
2017-12-30 20:12:01 +00:00
}
}
2020-08-28 19:12:38 +00:00
return TEMP_UNKNOWN ;
2020-06-20 16:09:54 +00:00
}
2017-12-30 20:12:01 +00:00
2020-06-20 16:09:54 +00:00
void action_web_request ( struct mg_connection * nc , struct http_message * http_msg ) {
2020-07-18 16:37:19 +00:00
char * msg = NULL ;
2020-06-20 16:09:54 +00:00
// struct http_message *http_msg = (struct http_message *)ev_data;
2020-07-26 19:28:58 +00:00
# ifdef AQ_TM_DEBUG
2020-07-18 16:37:19 +00:00
int tid ;
int tid2 ;
# endif
2020-07-26 19:28:58 +00:00
//DEBUG_TIMER_START(&tid);
2020-07-18 16:37:19 +00:00
if ( getLogLevel ( NET_LOG ) > = LOG_INFO ) { // Simply for log message, check we are at
2020-06-20 16:09:54 +00:00
// this log level before running all this
// junk
char * uri = ( char * ) malloc ( http_msg - > uri . len + http_msg - > query_string . len + 2 ) ;
strncpy ( uri , http_msg - > uri . p , http_msg - > uri . len + http_msg - > query_string . len + 1 ) ;
uri [ http_msg - > uri . len + http_msg - > query_string . len + 1 ] = ' \0 ' ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " URI request: '%s' \n " , uri ) ;
2020-06-20 16:09:54 +00:00
free ( uri ) ;
}
2020-07-26 19:28:58 +00:00
//DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request debug print crap took");
2020-06-20 16:09:54 +00:00
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_INFO, "Message request:\n'%.*s'\n", http_msg->message.len, http_msg->message.p);
2020-06-20 16:09:54 +00:00
// If we have a get request, pass it
2023-05-14 21:35:13 +00:00
if ( strncmp ( http_msg - > uri . p , " /api " , 4 ) ! = 0 ) {
if ( strstr ( http_msg - > method . p , " GET " ) & & http_msg - > query_string . len > 0 ) {
# ifdef INCLUDE_V1_API
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " WEB: Old stanza, using old method to action \n " ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_START ( & tid ) ;
2020-06-20 16:09:54 +00:00
OLD_action_web_request ( nc , http_msg ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_web_request() serve Old stanza took " ) ;
2023-05-14 21:35:13 +00:00
# else
LOG ( NET_LOG , LOG_ERR , " WEB: Old API stanza requested, ignoring client request \n " ) ;
# endif
2017-12-30 20:12:01 +00:00
} else {
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
mg_serve_http ( nc , http_msg , _http_server_opts ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_web_request() serve file took " ) ;
2017-12-30 20:12:01 +00:00
}
2020-06-20 16:09:54 +00:00
//} else if (strstr(http_msg->method.p, "PUT")) {
} else {
2023-05-14 21:35:13 +00:00
char buf [ JSON_BUFFER_SIZE ] ;
2020-07-26 19:28:58 +00:00
float value = 0 ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2020-06-20 16:09:54 +00:00
// If query string.
if ( http_msg - > query_string . len > 1 ) {
mg_get_http_var ( & http_msg - > query_string , " value " , buf , sizeof ( buf ) ) ;
value = atof ( buf ) ;
2020-07-18 16:37:19 +00:00
} else if ( http_msg - > body . len > 1 ) {
2020-06-20 16:09:54 +00:00
value = pass_mg_body ( & http_msg - > body ) ;
2020-06-01 00:35:17 +00:00
}
2020-06-20 16:09:54 +00:00
int len = mg_url_decode ( http_msg - > uri . p , http_msg - > uri . len , buf , 50 , 0 ) ;
2023-05-14 21:35:13 +00:00
if ( strncmp ( http_msg - > uri . p , " /api/ " , 4 ) = = 0 ) {
2020-07-18 16:37:19 +00:00
switch ( action_URI ( NET_API , & buf [ 5 ] , len - 5 , value , false , & msg ) ) {
2020-06-20 16:09:54 +00:00
case uActioned :
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
break ;
case uDevices :
{
char message [ JSON_BUFFER_SIZE ] ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid2 ) ;
2020-07-26 19:28:58 +00:00
int size = build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , false ) ;
DEBUG_TIMER_STOP ( tid2 , NET_LOG , " action_web_request() build_device_JSON took " ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , message , size ) ;
2017-12-30 20:12:01 +00:00
}
2020-06-20 16:09:54 +00:00
break ;
case uHomebridge :
{
char message [ JSON_BUFFER_SIZE ] ;
2020-07-26 19:28:58 +00:00
int size = build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , true ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , message , size ) ;
2020-06-20 16:09:54 +00:00
}
break ;
case uStatus :
{
char message [ JSON_BUFFER_SIZE ] ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid2 ) ;
2020-07-26 19:28:58 +00:00
int size = build_aqualink_status_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid2 , NET_LOG , " action_web_request() build_aqualink_status_JSON took " ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , message , size ) ;
2017-12-30 20:12:01 +00:00
}
2020-07-26 19:28:58 +00:00
break ;
2020-06-20 16:09:54 +00:00
case uDynamicconf :
{
char message [ JSON_BUFFER_SIZE ] ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid2 ) ;
2023-05-14 21:35:13 +00:00
int size = build_webconfig_js ( _aqualink_data , message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid2 , NET_LOG , " action_web_request() build_webconfig_js took " ) ;
mg_send_head ( nc , 200 , size , CONTENT_JS ) ;
mg_send ( nc , message , size ) ;
}
break ;
case uSchedules :
{
char message [ JSON_BUFFER_SIZE ] ;
DEBUG_TIMER_START ( & tid2 ) ;
int size = build_schedules_js ( message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid2 , NET_LOG , " action_web_request() build_schedules_js took " ) ;
mg_send_head ( nc , 200 , size , CONTENT_JS ) ;
mg_send ( nc , message , size ) ;
}
break ;
case uSetSchedules :
{
char message [ JSON_BUFFER_SIZE ] ;
DEBUG_TIMER_START ( & tid2 ) ;
//int size = save_schedules_js(_aqualink_data, &http_msg->body, message, JSON_BUFFER_SIZE);
int size = save_schedules_js ( ( char * ) & http_msg - > body , http_msg - > body . len , message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid2 , NET_LOG , " action_web_request() save_schedules_js took " ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , size , CONTENT_JS ) ;
mg_send ( nc , message , size ) ;
}
break ;
2020-07-18 16:37:19 +00:00
case uDebugStatus :
{
char message [ JSON_BUFFER_SIZE ] ;
int size = snprintf ( message , 80 , " { \" sLevel \" : \" %s \" , \" iLevel \" :%d, \" logReady \" : \" %s \" } \n " , elevel2text ( getLogLevel ( NET_LOG ) ) , getLogLevel ( NET_LOG ) , islogFileReady ( ) ? " true " : " false " ) ;
mg_send_head ( nc , 200 , size , CONTENT_JS ) ;
mg_send ( nc , message , size ) ;
}
break ;
case uDebugDownload :
mg_http_serve_file ( nc , http_msg , getInlineLogFName ( ) , mg_mk_str ( " text/plain " ) , mg_mk_str ( " " ) ) ;
break ;
2020-06-20 16:09:54 +00:00
case uBad :
default :
2020-07-18 16:37:19 +00:00
if ( msg = = NULL ) {
mg_send_head ( nc , 400 , strlen ( GET_RTN_UNKNOWN ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_UNKNOWN , strlen ( GET_RTN_UNKNOWN ) ) ;
} else {
mg_send_head ( nc , 400 , strlen ( msg ) , CONTENT_TEXT ) ;
mg_send ( nc , msg , strlen ( msg ) ) ;
}
2017-12-30 20:12:01 +00:00
break ;
}
2020-06-20 16:09:54 +00:00
} else {
mg_send_head ( nc , 200 , strlen ( GET_RTN_UNKNOWN ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_UNKNOWN , strlen ( GET_RTN_UNKNOWN ) ) ;
2017-12-30 20:12:01 +00:00
}
2023-05-14 21:35:13 +00:00
sprintf ( buf , " action_web_request() request '%.*s' took " , ( int ) http_msg - > uri . len , http_msg - > uri . p ) ;
2020-07-18 16:37:19 +00:00
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , buf ) ;
2017-12-30 20:12:01 +00:00
}
}
2020-06-20 16:09:54 +00:00
void action_websocket_request ( struct mg_connection * nc , struct websocket_message * wm ) {
char buffer [ 100 ] ;
struct JSONkvptr jsonkv ;
int i ;
char * uri = NULL ;
char * value = NULL ;
2020-07-18 16:37:19 +00:00
char * msg = NULL ;
2020-07-26 19:28:58 +00:00
# ifdef AQ_TM_DEBUG
2020-07-18 16:37:19 +00:00
int tid ;
# endif
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
// Any websocket request means UI is active, so don't let AqualinkD go to sleep if in PDA mode
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL )
2020-06-20 16:09:54 +00:00
pda_reset_sleep ( ) ;
# endif
strncpy ( buffer , ( char * ) wm - > data , wm - > size ) ;
buffer [ wm - > size ] = ' \0 ' ;
parseJSONrequest ( buffer , & jsonkv ) ;
for ( i = 0 ; i < 4 ; i + + ) {
if ( jsonkv . kv [ i ] . key ! = NULL )
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WS: Message - Key '%s' Value '%s' \n " , jsonkv . kv [ i ] . key , jsonkv . kv [ i ] . value ) ;
2020-06-20 16:09:54 +00:00
if ( jsonkv . kv [ i ] . key ! = NULL & & strncmp ( jsonkv . kv [ i ] . key , " uri " , 3 ) = = 0 )
uri = jsonkv . kv [ i ] . value ;
else if ( jsonkv . kv [ i ] . key ! = NULL & & strncmp ( jsonkv . kv [ i ] . key , " value " , 4 ) = = 0 )
value = jsonkv . kv [ i ] . value ;
}
if ( uri = = NULL ) {
2023-05-14 21:35:13 +00:00
# ifdef INCLUDE_V1_API
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " WS: Old stanza, using old method to action \n " ) ;
2020-06-20 16:09:54 +00:00
return OLD_action_websocket_request ( nc , wm ) ;
2023-05-14 21:35:13 +00:00
# else
LOG ( NET_LOG , LOG_ERR , " WEB: Old websocket stanza requested, ignoring client request \n " ) ;
return ;
# endif
2020-06-20 16:09:54 +00:00
}
2020-08-28 19:12:38 +00:00
switch ( action_URI ( NET_WS , uri , strlen ( uri ) , ( value ! = NULL ? atof ( value ) : TEMP_UNKNOWN ) , false , & msg ) ) {
2020-06-20 16:09:54 +00:00
case uActioned :
sprintf ( buffer , " { \" message \" : \" ok \" } " ) ;
ws_send ( nc , buffer ) ;
break ;
case uDevices :
{
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2020-06-20 16:09:54 +00:00
char message [ JSON_BUFFER_SIZE ] ;
build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , false ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_websocket_request() build_device_JSON took " ) ;
2020-06-20 16:09:54 +00:00
ws_send ( nc , message ) ;
}
break ;
case uStatus :
{
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2020-06-20 16:09:54 +00:00
char message [ JSON_BUFFER_SIZE ] ;
build_aqualink_status_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_websocket_request() build_aqualink_status_JSON took " ) ;
2020-06-20 16:09:54 +00:00
ws_send ( nc , message ) ;
}
break ;
2023-05-14 21:35:13 +00:00
case uSimulator :
{
LOG ( NET_LOG , LOG_DEBUG , " Started Simulator Mode \n " ) ;
set_websocket_simulator ( nc ) ;
_aqualink_data - > simulate_panel = true ;
DEBUG_TIMER_START ( & tid ) ;
char message [ JSON_BUFFER_SIZE ] ;
build_aqualink_status_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE ) ; // Should change this to simulator.
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_websocket_request() build_aqualink_status_JSON took " ) ;
ws_send ( nc , message ) ;
}
break ;
case uSchedules :
{
DEBUG_TIMER_START ( & tid ) ;
char message [ JSON_BUFFER_SIZE ] ;
build_schedules_js ( message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_websocket_request() build_schedules_js took " ) ;
ws_send ( nc , message ) ;
}
break ;
case uSetSchedules :
{
DEBUG_TIMER_START ( & tid ) ;
char message [ JSON_BUFFER_SIZE ] ;
save_schedules_js ( ( char * ) wm - > data , wm - > size , message , JSON_BUFFER_SIZE ) ;
DEBUG_TIMER_STOP ( tid , NET_LOG , " action_websocket_request() save_schedules_js took " ) ;
ws_send ( nc , message ) ;
}
2020-06-20 16:09:54 +00:00
case uBad :
default :
2020-07-18 16:37:19 +00:00
if ( msg = = NULL )
sprintf ( buffer , " { \" message \" : \" Bad request \" } " ) ;
else
sprintf ( buffer , " { \" message \" : \" %s \" } " , msg ) ;
2020-06-20 16:09:54 +00:00
ws_send ( nc , buffer ) ;
break ;
}
}
void action_domoticz_mqtt_message ( struct mg_connection * nc , struct mg_mqtt_message * msg ) {
int idx = - 1 ;
int nvalue = - 1 ;
int i ;
char svalue [ DZ_SVALUE_LEN + 1 ] ;
2017-12-30 20:12:01 +00:00
2020-08-28 19:12:38 +00:00
if ( parseJSONmqttrequest ( msg - > payload . p , msg - > payload . len , & idx , & nvalue , svalue ) & & idx > 0 ) {
2020-06-20 16:09:54 +00:00
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
2017-12-30 20:12:01 +00:00
if ( _aqualink_data - > aqbuttons [ i ] . dz_idx = = idx ) {
2020-08-28 19:12:38 +00:00
LOG ( NET_LOG , LOG_DEBUG , " MQTT: DZ: Received message IDX=%d nValue=%d sValue=%s \n " , idx , nvalue , svalue ) ;
2017-12-30 20:12:01 +00:00
//NSF, should try to simplify this if statment, but not easy since AQ ON and DZ ON are different, and AQ has other states.
if ( ( _aqualink_data - > aqbuttons [ i ] . led - > state = = OFF & & nvalue = = DZ_OFF ) | |
( nvalue = = DZ_ON & & ( _aqualink_data - > aqbuttons [ i ] . led - > state = = ON | |
_aqualink_data - > aqbuttons [ i ] . led - > state = = FLASH | |
_aqualink_data - > aqbuttons [ i ] . led - > state = = ENABLE ) ) ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: DZ: received '%s' for '%s', already '%s', Ignoring \n " , ( nvalue = = DZ_OFF ? " OFF " : " ON " ) , _aqualink_data - > aqbuttons [ i ] . name , ( nvalue = = DZ_OFF ? " OFF " : " ON " ) ) ;
2017-12-30 20:12:01 +00:00
} else {
// NSF Below if needs to check that the button pressed is actually a light. Add this later
2020-06-06 16:36:04 +00:00
if ( _aqualink_data - > active_thread . ptype = = AQ_SET_LIGHTPROGRAM_MODE ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " MQTT: DZ: received '%s' for '%s', IGNORING as we are programming light mode \n " , ( nvalue = = DZ_OFF ? " OFF " : " ON " ) , _aqualink_data - > aqbuttons [ i ] . name ) ;
2017-12-30 20:12:01 +00:00
} else {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: DZ: received '%s' for '%s', turning '%s' \n " , ( nvalue = = DZ_OFF ? " OFF " : " ON " ) , _aqualink_data - > aqbuttons [ i ] . name , ( nvalue = = DZ_OFF ? " OFF " : " ON " ) ) ;
2023-05-14 21:35:13 +00:00
//create_panel_request(NET_DZMQTT, i, (nvalue == DZ_OFF?0:1), false);
panel_device_request ( _aqualink_data , ON_OFF , i , ( nvalue = = DZ_OFF ? 0 : 1 ) , NET_DZMQTT ) ;
/*
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL ) {
2018-09-02 21:45:24 +00:00
char msg [ PTHREAD_ARG ] ;
sprintf ( msg , " %-5d%-5d " , i , ( nvalue = = DZ_OFF ? OFF : ON ) ) ;
aq_programmer ( AQ_PDA_DEVICE_ON_OFF , msg , _aqualink_data ) ;
2020-06-20 16:09:54 +00:00
} else
# endif
{
aq_send_cmd ( _aqualink_data - > aqbuttons [ i ] . code ) ;
2018-09-02 21:45:24 +00:00
}
2023-05-14 21:35:13 +00:00
*/
2017-12-30 20:12:01 +00:00
}
}
break ; // no need to continue in for loop, we found button.
}
}
}
// NSF Need to check idx against ours and decide if we are interested in it.
}
2020-07-18 16:37:19 +00:00
2017-12-30 20:12:01 +00:00
static void ev_handler ( struct mg_connection * nc , int ev , void * ev_data ) {
struct mg_mqtt_message * mqtt_msg ;
struct http_message * http_msg ;
struct websocket_message * ws_msg ;
2018-09-07 16:49:17 +00:00
char aq_topic [ 30 ] ;
2020-07-26 19:28:58 +00:00
# ifdef AQ_TM_DEBUG
2020-07-18 16:37:19 +00:00
int tid ;
# endif
2017-12-30 20:12:01 +00:00
//static double last_control_time;
2020-07-18 16:37:19 +00:00
// LOG(NET_LOG,LOG_DEBUG, "Event\n");
2017-12-30 20:12:01 +00:00
switch ( ev ) {
case MG_EV_HTTP_REQUEST :
//nc->user_data = WEB;
http_msg = ( struct http_message * ) ev_data ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2017-12-30 20:12:01 +00:00
action_web_request ( nc , http_msg ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " WEB Request action_web_request() took " ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " Served WEB request \n " ) ;
2017-12-30 20:12:01 +00:00
break ;
case MG_EV_WEBSOCKET_HANDSHAKE_DONE :
//nc->user_data = WS;
2019-05-31 23:08:45 +00:00
_aqualink_data - > open_websockets + + ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " ++ Websocket joined \n " ) ;
2017-12-30 20:12:01 +00:00
break ;
case MG_EV_WEBSOCKET_FRAME :
ws_msg = ( struct websocket_message * ) ev_data ;
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2017-12-30 20:12:01 +00:00
action_websocket_request ( nc , ws_msg ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " Websocket Request action_websocket_request() took " ) ;
2017-12-30 20:12:01 +00:00
break ;
case MG_EV_CLOSE :
if ( is_websocket ( nc ) ) {
2019-05-31 23:08:45 +00:00
_aqualink_data - > open_websockets - - ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " -- Websocket left \n " ) ;
2023-05-14 21:35:13 +00:00
// Need something below to detect is_websocket_simulator() and turn off aq_data.simulate_panel
if ( is_websocket_simulator ( nc ) ) {
_aqualink_data - > simulate_panel = false ;
LOG ( NET_LOG , LOG_DEBUG , " Stoped Simulator Mode \n " ) ;
}
2017-12-30 20:12:01 +00:00
} else if ( is_mqtt ( nc ) ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " MQTT Connection closed \n " ) ;
2017-12-30 20:12:01 +00:00
_mqtt_exit_flag = true ;
}
break ;
case MG_EV_CONNECT : {
//nc->user_data = MQTT;
//nc->flags |= MG_F_USER_1; // NFS Need to readup on this
set_mqtt ( nc ) ;
_mqtt_exit_flag = false ;
//char *MQTT_id = "AQUALINK_MQTT_TEST_ID";
struct mg_send_mqtt_handshake_opts opts ;
memset ( & opts , 0 , sizeof ( opts ) ) ;
2020-06-01 00:35:17 +00:00
opts . user_name = _aqconfig_ . mqtt_user ;
opts . password = _aqconfig_ . mqtt_passwd ;
2017-12-30 20:12:01 +00:00
opts . keep_alive = 5 ;
opts . flags | = MG_MQTT_CLEAN_SESSION ; // NFS Need to readup on this
2018-09-07 16:49:17 +00:00
2020-06-01 00:35:17 +00:00
snprintf ( aq_topic , 24 , " %s/%s " , _aqconfig_ . mqtt_aq_topic , MQTT_LWM_TOPIC ) ;
2018-09-07 16:49:17 +00:00
opts . will_topic = aq_topic ;
opts . will_message = MQTT_OFF ;
2017-12-30 20:12:01 +00:00
mg_set_protocol_mqtt ( nc ) ;
2020-06-01 00:35:17 +00:00
mg_send_mqtt_handshake_opt ( nc , _aqconfig_ . mqtt_ID , opts ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscribing mqtt with id of: %s \n " , _aqconfig_ . mqtt_ID ) ;
2017-12-30 20:12:01 +00:00
//last_control_time = mg_time();
} break ;
case MG_EV_MQTT_CONNACK :
{
struct mg_mqtt_topic_expression topics [ 2 ] ;
2018-09-07 16:49:17 +00:00
2017-12-30 20:12:01 +00:00
int qos = 0 ; // can't be bothered with ack, so set to 0
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " MQTT: Connection acknowledged \n " ) ;
2017-12-30 20:12:01 +00:00
mqtt_msg = ( struct mg_mqtt_message * ) ev_data ;
if ( mqtt_msg - > connack_ret_code ! = MG_EV_MQTT_CONNACK_ACCEPTED ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " Got mqtt connection error: %d \n " , mqtt_msg - > connack_ret_code ) ;
2017-12-30 20:12:01 +00:00
_mqtt_exit_flag = true ;
}
2020-06-01 00:35:17 +00:00
snprintf ( aq_topic , 29 , " %s/# " , _aqconfig_ . mqtt_aq_topic ) ;
if ( _aqconfig_ . mqtt_aq_topic ! = NULL & & _aqconfig_ . mqtt_dz_sub_topic ! = NULL ) {
2017-12-30 20:12:01 +00:00
topics [ 0 ] . topic = aq_topic ;
topics [ 0 ] . qos = qos ;
2020-06-01 00:35:17 +00:00
topics [ 1 ] . topic = _aqconfig_ . mqtt_dz_sub_topic ;
2017-12-30 20:12:01 +00:00
topics [ 1 ] . qos = qos ;
mg_mqtt_subscribe ( nc , topics , 2 , 42 ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscribing to '%s' \n " , aq_topic ) ;
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscribing to '%s' \n " , _aqconfig_ . mqtt_dz_sub_topic ) ;
2017-12-30 20:12:01 +00:00
}
2020-06-01 00:35:17 +00:00
else if ( _aqconfig_ . mqtt_aq_topic ! = NULL ) {
2017-12-30 20:12:01 +00:00
topics [ 0 ] . topic = aq_topic ;
topics [ 0 ] . qos = qos ;
mg_mqtt_subscribe ( nc , topics , 1 , 42 ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscribing to '%s' \n " , aq_topic ) ;
2017-12-30 20:12:01 +00:00
}
2020-06-01 00:35:17 +00:00
else if ( _aqconfig_ . mqtt_dz_sub_topic ! = NULL ) {
topics [ 0 ] . topic = _aqconfig_ . mqtt_dz_sub_topic ; ;
2017-12-30 20:12:01 +00:00
topics [ 0 ] . qos = qos ;
mg_mqtt_subscribe ( nc , topics , 1 , 42 ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscribing to '%s' \n " , _aqconfig_ . mqtt_dz_sub_topic ) ;
2017-12-30 20:12:01 +00:00
}
}
break ;
case MG_EV_MQTT_PUBACK :
mqtt_msg = ( struct mg_mqtt_message * ) ev_data ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " MQTT: Message publishing acknowledged (msg_id: %d) \n " , mqtt_msg - > message_id ) ;
2017-12-30 20:12:01 +00:00
break ;
case MG_EV_MQTT_SUBACK :
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " MQTT: Subscription(s) acknowledged \n " ) ;
2020-06-01 00:35:17 +00:00
snprintf ( aq_topic , 24 , " %s/%s " , _aqconfig_ . mqtt_aq_topic , MQTT_LWM_TOPIC ) ;
2018-09-07 16:49:17 +00:00
send_mqtt ( nc , aq_topic , MQTT_ON ) ;
2017-12-30 20:12:01 +00:00
break ;
case MG_EV_MQTT_PUBLISH :
mqtt_msg = ( struct mg_mqtt_message * ) ev_data ;
if ( mqtt_msg - > message_id ! = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " MQTT: received (msg_id: %d), looks like my own message, ignoring \n " , mqtt_msg - > message_id ) ;
2017-12-30 20:12:01 +00:00
}
// NSF Need to change strlen to a global so it's not executed every time we check a topic
2023-05-14 21:35:13 +00:00
if ( _aqconfig_ . mqtt_aq_topic ! = NULL & & strncmp ( mqtt_msg - > topic . p , _aqconfig_ . mqtt_aq_topic , strlen ( _aqconfig_ . mqtt_aq_topic ) ) = = 0 )
2020-06-01 00:35:17 +00:00
{
2020-07-18 16:37:19 +00:00
DEBUG_TIMER_START ( & tid ) ;
2017-12-30 20:12:01 +00:00
action_mqtt_message ( nc , mqtt_msg ) ;
2020-07-26 19:28:58 +00:00
DEBUG_TIMER_STOP ( tid , NET_LOG , " MQTT Request action_mqtt_message() took " ) ;
2017-12-30 20:12:01 +00:00
}
2023-05-14 21:35:13 +00:00
if ( _aqconfig_ . mqtt_dz_sub_topic ! = NULL & & strncmp ( mqtt_msg - > topic . p , _aqconfig_ . mqtt_dz_sub_topic , strlen ( _aqconfig_ . mqtt_dz_sub_topic ) ) = = 0 ) {
2017-12-30 20:12:01 +00:00
action_domoticz_mqtt_message ( nc , mqtt_msg ) ;
}
break ;
}
2020-07-18 16:37:19 +00:00
}
void reset_last_mqtt_status ( )
{
int i ;
memset ( & _last_mqtt_aqualinkdata , 0 , sizeof ( _last_mqtt_aqualinkdata ) ) ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
_last_mqtt_aqualinkdata . aqualinkleds [ i ] . state = LED_S_UNKNOWN ;
2017-12-30 20:12:01 +00:00
}
2020-07-18 16:37:19 +00:00
_last_mqtt_aqualinkdata . ar_swg_device_status = SWG_STATUS_UNKNOWN ;
_last_mqtt_aqualinkdata . swg_led_state = LED_S_UNKNOWN ;
2023-05-14 21:35:13 +00:00
_last_mqtt_aqualinkdata . air_temp = TEMP_REFRESH ;
_last_mqtt_aqualinkdata . pool_temp = TEMP_REFRESH ;
_last_mqtt_aqualinkdata . spa_temp = TEMP_REFRESH ;
2020-07-18 16:37:19 +00:00
//_last_mqtt_aqualinkdata.sw .ar_swg_device_status = SWG_STATUS_UNKNOWN;
_last_mqtt_aqualinkdata . battery = - 1 ;
_last_mqtt_aqualinkdata . frz_protect_state = - 1 ;
_last_mqtt_aqualinkdata . boost = - 1 ;
_last_mqtt_aqualinkdata . service_mode_state = - 1 ;
2017-12-30 20:12:01 +00:00
}
void start_mqtt ( struct mg_mgr * mgr ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " Starting MQTT client to %s \n " , _aqconfig_ . mqtt_server ) ;
2020-06-01 00:35:17 +00:00
if ( _aqconfig_ . mqtt_server = = NULL | |
( _aqconfig_ . mqtt_aq_topic = = NULL & & _aqconfig_ . mqtt_dz_pub_topic = = NULL & & _aqconfig_ . mqtt_dz_sub_topic = = NULL ) )
2018-03-05 23:52:42 +00:00
return ;
2020-06-01 00:35:17 +00:00
if ( mg_connect ( mgr , _aqconfig_ . mqtt_server , ev_handler ) = = NULL ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " Failed to create MQTT listener to %s \n " , _aqconfig_ . mqtt_server ) ;
2017-12-30 20:12:01 +00:00
} else {
2020-07-26 19:28:58 +00:00
//int i;
2020-07-18 16:37:19 +00:00
# ifdef AQ_MEMCMP
memset ( & _last_mqtt_aqualinkdata , 0 , sizeof ( struct aqualinkdata ) ) ;
# endif
reset_last_mqtt_status ( ) ;
2017-12-30 20:12:01 +00:00
_mqtt_exit_flag = false ; // set here to stop multiple connects, if it fails truley fails it will get set to false.
}
}
//bool start_web_server(struct mg_mgr *mgr, struct aqualinkdata *aqdata, char *port, char* web_root) {
2020-06-01 00:35:17 +00:00
//bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata, struct aqconfig *aqconfig) {
2020-07-26 19:28:58 +00:00
bool _start_net_services ( struct mg_mgr * mgr , struct aqualinkdata * aqdata ) {
2017-12-30 20:12:01 +00:00
struct mg_connection * nc ;
_aqualink_data = aqdata ;
2020-06-01 00:35:17 +00:00
//_aqconfig_ = aqconfig;
2017-12-30 20:12:01 +00:00
2020-07-26 19:28:58 +00:00
signal ( SIGTERM , net_signal_handler ) ;
signal ( SIGINT , net_signal_handler ) ;
2017-12-30 20:12:01 +00:00
setvbuf ( stdout , NULL , _IOLBF , 0 ) ;
setvbuf ( stderr , NULL , _IOLBF , 0 ) ;
mg_mgr_init ( mgr , NULL ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " Starting web server on port %s \n " , _aqconfig_ . socket_port ) ;
2020-06-01 00:35:17 +00:00
nc = mg_bind ( mgr , _aqconfig_ . socket_port , ev_handler ) ;
2017-12-30 20:12:01 +00:00
if ( nc = = NULL ) {
2020-08-30 17:36:58 +00:00
LOG ( NET_LOG , LOG_ERR , " Failed to create listener on port %s \n " , _aqconfig_ . socket_port ) ;
2017-12-30 20:12:01 +00:00
return false ;
}
// Set up HTTP server parameters
mg_set_protocol_http_websocket ( nc ) ;
2020-07-18 16:37:19 +00:00
// Set default web options
//struct mg_serve_http_opts opts;
//memset(&opts, 0, sizeof(opts)); // Reset all options to defaults
//opts.document_root = _web_root; // Serve files from the current directory
//opts.extra_headers = "Cache-Control: public, max-age=604800, immutable";
memset ( & _http_server_opts , 0 , sizeof ( _http_server_opts ) ) ; // Reset all options to defaults
_http_server_opts . document_root = _aqconfig_ . web_directory ; // Serve current directory
_http_server_opts . enable_directory_listing = " yes " ;
//_http_server_opts.extra_headers = "Cache-Control: public, max-age=604800, immutable";
_http_server_opts . extra_headers = " Cache-Control: public,max-age=31536000,immutable " ; // Let's be as agressive on browser caching.
2017-12-30 20:12:01 +00:00
# ifndef MG_DISABLE_MQTT
// Start MQTT
start_mqtt ( mgr ) ;
# endif
2018-07-20 17:29:13 +00:00
2017-12-30 20:12:01 +00:00
return true ;
}
2020-06-20 16:09:54 +00:00
2020-07-26 19:28:58 +00:00
/**********************************************************************************************
* Thread Net Services
*
*/
pthread_t _net_thread_id ;
bool _keepNetServicesRunning = true ;
//volatile bool _broadcast = false; // This is redundent when most the fully threadded rather than option.
void * net_services_thread ( void * ptr )
{
struct aqualinkdata * aqdata = ( struct aqualinkdata * ) ptr ;
struct mg_mgr mgr ;
2020-08-30 17:36:58 +00:00
if ( ! _start_net_services ( & mgr , aqdata ) ) {
//LOG(NET_LOG,LOG_ERR, "Failed to start network services\n");
// Not the best way to do this (have thread exit process), but forks for the moment.
_keepNetServicesRunning = false ;
LOG ( AQUA_LOG , LOG_ERR , " Can not start webserver on port %s. \n " , _aqconfig_ . socket_port ) ;
exit ( EXIT_FAILURE ) ;
goto f_end ;
}
2020-07-26 19:28:58 +00:00
while ( _keepNetServicesRunning = = true )
{
//poll_net_services(&mgr, 10);
mg_mgr_poll ( & mgr , 100 ) ;
if ( aqdata - > updated = = true /*|| _broadcast == true*/ ) {
2020-08-28 19:12:38 +00:00
//LOG(NET_LOG,LOG_DEBUG, "********** Broadcast ************\n");
2020-07-26 19:28:58 +00:00
_broadcast_aqualinkstate ( mgr . active_connections ) ;
aqdata - > updated = false ;
//_broadcast = false;
}
}
2020-08-30 17:36:58 +00:00
f_end :
2020-07-26 19:28:58 +00:00
LOG ( NET_LOG , LOG_NOTICE , " Stopping network services thread \n " ) ;
mg_mgr_free ( & mgr ) ;
pthread_exit ( 0 ) ;
}
bool start_net_services ( struct mg_mgr * mgr , struct aqualinkdata * aqdata )
{
if ( ! _aqconfig_ . thread_netservices ) {
return _start_net_services ( mgr , aqdata ) ;
}
LOG ( NET_LOG , LOG_NOTICE , " Starting network services thread \n " ) ;
if ( pthread_create ( & _net_thread_id , NULL , net_services_thread , ( void * ) aqdata ) < 0 ) {
LOG ( NET_LOG , LOG_ERR , " could not create network thread \n " ) ;
return false ;
}
pthread_detach ( _net_thread_id ) ;
return true ;
}
time_t poll_net_services ( struct mg_mgr * mgr , int timeout_ms )
{
if ( timeout_ms < 0 )
timeout_ms = 0 ;
if ( ! _aqconfig_ . thread_netservices ) {
return mg_mgr_poll ( mgr , timeout_ms ) ;
}
if ( timeout_ms > 5 )
delay ( 5 ) ;
else if ( timeout_ms > 0 )
delay ( timeout_ms ) ;
//LOG(NET_LOG,LOG_NOTICE, "Poll network services\n");
return 0 ;
}
void broadcast_aqualinkstate ( struct mg_connection * nc )
{
if ( ! _aqconfig_ . thread_netservices ) {
_broadcast_aqualinkstate ( nc ) ;
_aqualink_data - > updated = false ;
return ;
}
//_broadcast = true;
//LOG(NET_LOG,LOG_NOTICE, "Broadcast status to network\n");
}
void broadcast_aqualinkstate_error ( struct mg_connection * nc , char * msg )
{
if ( ! _aqconfig_ . thread_netservices ) {
return _broadcast_aqualinkstate_error ( nc , msg ) ;
}
LOG ( NET_LOG , LOG_NOTICE , " Broadcast error to network \n " ) ;
}
void stop_net_services ( struct mg_mgr * mgr ) {
if ( ! _aqconfig_ . thread_netservices ) {
mg_mgr_free ( mgr ) ;
return ;
}
_keepNetServicesRunning = false ;
return ;
}
2020-06-20 16:09:54 +00:00
2023-05-14 21:35:13 +00:00
# ifdef INCLUDE_V1_API
2020-06-20 16:09:54 +00:00
/* OLD Functions to be deprecated */
2023-05-14 21:35:13 +00:00
int getTempforMeteohub ( char * buffer )
{
int length = 0 ;
if ( _aqualink_data - > air_temp ! = TEMP_UNKNOWN )
length + = sprintf ( buffer + length , " t0 %d \n " , ( int ) degFtoC ( _aqualink_data - > air_temp ) * 10 ) ;
else
length + = sprintf ( buffer + length , " t0 \n " ) ;
if ( _aqualink_data - > pool_temp ! = TEMP_UNKNOWN )
length + = sprintf ( buffer + length , " t1 %d \n " , ( int ) degFtoC ( _aqualink_data - > pool_temp ) * 10 ) ;
else
length + = sprintf ( buffer + length , " t1 \n " ) ;
return strlen ( buffer ) ;
}
2020-06-20 16:09:54 +00:00
/* Leave the old API / web function intact until we deprecate */
void OLD_action_web_request ( struct mg_connection * nc , struct http_message * http_msg ) {
// struct http_message *http_msg = (struct http_message *)ev_data;
2020-07-18 16:37:19 +00:00
if ( getLogLevel ( NET_LOG ) > = LOG_WARNING ) { // Simply for log message, check we are at
2020-06-20 16:09:54 +00:00
// this log level before running all this
// junk
char * uri = ( char * ) malloc ( http_msg - > uri . len + http_msg - > query_string . len + 2 ) ;
strncpy ( uri , http_msg - > uri . p , http_msg - > uri . len + http_msg - > query_string . len + 1 ) ;
uri [ http_msg - > uri . len + http_msg - > query_string . len + 1 ] = ' \0 ' ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_WARNING , " URI request: '%s' \n " , uri ) ;
2020-06-20 16:09:54 +00:00
free ( uri ) ;
}
// If we have a get request, pass it
if ( strstr ( http_msg - > method . p , " GET " ) & & http_msg - > query_string . len > 0 ) {
char command [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " command " , command , sizeof ( command ) ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: Message command='%s' \n " , command ) ;
2020-06-20 16:09:54 +00:00
if ( strcmp ( command , " dynamic_config " ) = = 0 ) {
char data [ JSON_BUFFER_SIZE ] ;
int size = build_color_lights_js ( _aqualink_data , data , JSON_BUFFER_SIZE ) ;
mg_send_head ( nc , 200 , size , CONTENT_JS ) ;
mg_send ( nc , data , size ) ;
} else
// if (strstr(http_msg->query_string.p, "command=status")) {
if ( strcmp ( command , " status " ) = = 0 ) {
char data [ JSON_STATUS_SIZE ] ;
int size = build_aqualink_status_JSON ( _aqualink_data , data , JSON_STATUS_SIZE ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , data , size ) ;
//} else if (strstr(http_msg->query_string.p, "command=mhstatus")) {
} else if ( strcmp ( command , " mhstatus " ) = = 0 ) {
char data [ 20 ] ;
int size = getTempforMeteohub ( data ) ;
mg_send_head ( nc , 200 , size , CONTENT_TEXT ) ;
mg_send ( nc , data , size ) ;
} else if ( strcmp ( command , " poollightmode " ) = = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " WEB: poollightmode taken out for update (forgot to put it back) \n " ) ;
2020-06-20 16:09:54 +00:00
/*
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
//aq_programmer(AQ_SET_COLORMODE, value, _aqualink_data);
set_light_mode ( value , _aqconfig_ . light_programming_button_pool ) ;
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
*/
} else if ( strcmp ( command , " spalightmode " ) = = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " WEB: spalightmode taken out for update (forgot to put it back) \n " ) ;
2020-06-20 16:09:54 +00:00
/*
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
//aq_programmer(AQ_SET_COLORMODE, value, _aqualink_data);
set_light_mode ( value , _aqconfig_ . light_programming_button_spa ) ;
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
*/
} else if ( strcmp ( command , " diag " ) = = 0 ) {
aq_programmer ( AQ_GET_DIAGNOSTICS_MODEL , NULL , _aqualink_data ) ;
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
} else if ( strcmp ( command , " swg_percent " ) = = 0 ) {
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
aq_programmer ( AQ_SET_SWG_PERCENT , value , _aqualink_data ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Web: request to set SWG to %s \n " , value ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
} else if ( strcmp ( command , " pool_htr_set_pnt " ) = = 0 ) {
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
aq_programmer ( AQ_SET_POOL_HEATER_TEMP , value , _aqualink_data ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Web: request to set Pool heater to %s \n " , value ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
} else if ( strcmp ( command , " spa_htr_set_pnt " ) = = 0 ) {
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
aq_programmer ( AQ_SET_SPA_HEATER_TEMP , value , _aqualink_data ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Web: request to set Spa heater to %s \n " , value ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
} else if ( strcmp ( command , " frz_protect_set_pnt " ) = = 0 ) {
char value [ 20 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
aq_programmer ( AQ_SET_FRZ_PROTECTION_TEMP , value , _aqualink_data ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Web: request to set Freeze protect to %s \n " , value ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
2020-07-18 16:37:19 +00:00
/*
2020-06-20 16:09:54 +00:00
} else if ( strcmp ( command , " extended_device_prg " ) = = 0 ) {
char value [ 20 ] ;
char message [ JSON_LABEL_SIZE ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
bool prg = request2bool ( value ) ;
if ( prg & & ! onetouch_enabled ( ) )
prg = false ; // Ignore request if onetouch is not enabeled
set_extended_device_id_programming ( prg ) ;
sprintf ( message , " { \" extended_device_prg \" : \" %s \" } " , bool2text ( prg ) ) ;
mg_send_head ( nc , 200 , strlen ( message ) , CONTENT_JSON ) ;
mg_send ( nc , message , strlen ( message ) ) ;
2020-07-18 16:37:19 +00:00
*/
2020-06-20 16:09:54 +00:00
} else if ( strcmp ( command , " devices " ) = = 0 ) {
char message [ JSON_BUFFER_SIZE ] ;
int size = build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , false ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , message , size ) ;
} else if ( strcmp ( command , " homebridge " ) = = 0 ) {
char message [ JSON_BUFFER_SIZE ] ;
int size = build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , true ) ;
mg_send_head ( nc , 200 , size , CONTENT_JSON ) ;
mg_send ( nc , message , size ) ;
} else if ( strcmp ( command , " setconfigprm " ) = = 0 ) {
char value [ 20 ] ;
char param [ 30 ] ;
char * webrtn ;
mg_get_http_var ( & http_msg - > query_string , " param " , param , sizeof ( param ) ) ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
if ( setConfigValue ( _aqualink_data , param , value ) ) {
webrtn = GET_RTN_OK ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " Web: request to config %s to %s \n " , param , value ) ;
2020-06-20 16:09:54 +00:00
} else {
webrtn = GET_RTN_ERROR ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " Web: request to config %s to %s failed \n " , param , value ) ;
2020-06-20 16:09:54 +00:00
}
mg_send_head ( nc , 200 , strlen ( webrtn ) , CONTENT_TEXT ) ;
mg_send ( nc , webrtn , strlen ( webrtn ) ) ;
} else if ( strcmp ( command , " writeconfig " ) = = 0 ) {
if ( writeCfg ( _aqualink_data ) ) {
mg_send_head ( nc , 200 , strlen ( GET_RTN_OK ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_OK , strlen ( GET_RTN_OK ) ) ;
} else {
mg_send_head ( nc , 200 , strlen ( GET_RTN_ERROR ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_ERROR , strlen ( GET_RTN_ERROR ) ) ;
}
} else if ( strcmp ( command , " debug " ) = = 0 ) {
char value [ 80 ] ;
char * rtn ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
if ( strcmp ( value , " start " ) = = 0 ) {
startInlineDebug ( ) ;
rtn = GET_RTN_OK ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: Started inline debug mode \n " ) ;
2020-06-20 16:09:54 +00:00
} else if ( strcmp ( value , " stop " ) = = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: Stoped inline debug mode \n " ) ;
2020-06-20 16:09:54 +00:00
stopInlineDebug ( ) ;
rtn = GET_RTN_OK ;
} else if ( strcmp ( value , " serialstart " ) = = 0 ) {
startInlineSerialDebug ( ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: Started inline debug mode \n " ) ;
2020-06-20 16:09:54 +00:00
rtn = GET_RTN_OK ;
} else if ( strcmp ( value , " serialstop " ) = = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: Stoped inline debug mode \n " ) ;
2020-06-20 16:09:54 +00:00
stopInlineDebug ( ) ;
rtn = GET_RTN_OK ;
} else if ( strcmp ( value , " status " ) = = 0 ) {
2020-07-18 16:37:19 +00:00
snprintf ( value , 80 , " { \" sLevel \" : \" %s \" , \" iLevel \" :%d, \" logReady \" : \" %s \" } \n " , elevel2text ( getLogLevel ( NET_LOG ) ) , getLogLevel ( NET_LOG ) , islogFileReady ( ) ? " true " : " false " ) ;
2020-06-20 16:09:54 +00:00
mg_send_head ( nc , 200 , strlen ( value ) , " Content-Type: text/json " ) ;
mg_send ( nc , value , strlen ( value ) ) ;
return ;
//rtn = value;
} else if ( strcmp ( value , " clean " ) = = 0 ) {
cleanInlineDebug ( ) ;
rtn = GET_RTN_OK ;
} else if ( strcmp ( value , " download " ) = = 0 ) {
mg_http_serve_file ( nc , http_msg , getInlineLogFName ( ) , mg_mk_str ( " text/plain " ) , mg_mk_str ( " " ) ) ;
return ;
} else {
rtn = GET_RTN_UNKNOWN ;
}
mg_send_head ( nc , 200 , strlen ( rtn ) , CONTENT_TEXT ) ;
mg_send ( nc , rtn , strlen ( rtn ) ) ;
} else if ( strncmp ( command , " Pump_ " , 5 ) = = 0 ) {
// Set Pump RPM
bool found = false ;
int pumpIndex = atoi ( command + 5 ) ; // Check for 0
char value [ 10 ] ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
int rpm = atoi ( value ) ;
// Check for pumpIndex = 0 (BAD) and check RPM Value
//printf("******** ADD CHECK FOR PUMP & RPM HERE ********\n");
int pi ;
for ( pi = 0 ; pi < _aqualink_data - > num_pumps ; pi + + ) {
if ( _aqualink_data - > pumps [ pi ] . pumpIndex = = pumpIndex ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " WEB: request to change pump %d to %d \n " , pumpIndex + 1 , round ( rpm ) ) ;
2020-06-20 16:09:54 +00:00
_aqualink_data - > unactioned . type = PUMP_RPM ;
_aqualink_data - > unactioned . value = round ( rpm ) ;
_aqualink_data - > unactioned . id = pumpIndex ;
found = true ;
break ;
}
}
if ( ! found )
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_ERR , " WEB: Didn't find pump %d from command %s \n " , pumpIndex , command ) ;
2020-06-20 16:09:54 +00:00
} else {
int i ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( strcmp ( command , _aqualink_data - > aqbuttons [ i ] . name ) = = 0 ) {
char value [ 20 ] ;
char * rtn ;
mg_get_http_var ( & http_msg - > query_string , " value " , value , sizeof ( value ) ) ;
2020-07-18 16:37:19 +00:00
// LOG(NET_LOG,LOG_INFO, "Web Message command='%s'\n",command);
2020-06-20 16:09:54 +00:00
// aq_programmer(AQ_SEND_CMD, (char
// *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: Message request '%s' change state to '%s' \n " , command , value ) ;
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL ) {
2020-06-20 16:09:54 +00:00
char msg [ PTHREAD_ARG ] ;
sprintf ( msg , " %-5d%-5d " , i , ( strcmp ( value , " on " ) = = 0 ) ? ON : OFF ) ;
//printf("******* '%s' ********\n",msg);
aq_programmer ( AQ_PDA_DEVICE_ON_OFF , msg , _aqualink_data ) ;
rtn = GET_RTN_OK ;
}
else
# endif
if ( strcmp ( value , " on " ) = = 0 ) {
if ( _aqualink_data - > aqbuttons [ i ] . led - > state = = OFF | | _aqualink_data - > aqbuttons [ i ] . led - > state = = FLASH ) {
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
aq_send_cmd ( _aqualink_data - > aqbuttons [ i ] . code ) ;
rtn = GET_RTN_OK ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: turn ON '%s' changed state to '%s' \n " , command , value ) ;
2020-06-20 16:09:54 +00:00
} else {
rtn = GET_RTN_NOT_CHANGED ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: '%s' is already on '%s', current state %d \n " , command , value , _aqualink_data - > aqbuttons [ i ] . led - > state ) ;
2020-06-20 16:09:54 +00:00
}
} else if ( strcmp ( value , " off " ) = = 0 ) {
if ( _aqualink_data - > aqbuttons [ i ] . led - > state = = ON | |
_aqualink_data - > aqbuttons [ i ] . led - > state = = ENABLE | |
_aqualink_data - > aqbuttons [ i ] . led - > state = = FLASH ) {
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
aq_send_cmd ( _aqualink_data - > aqbuttons [ i ] . code ) ;
rtn = GET_RTN_OK ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: turn Off '%s' changed state to '%s' \n " , command , value ) ;
2020-06-20 16:09:54 +00:00
} else {
rtn = GET_RTN_NOT_CHANGED ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: '%s' is already off '%s', current state %d \n " , command , value , _aqualink_data - > aqbuttons [ i ] . led - > state ) ;
2020-06-20 16:09:54 +00:00
}
} else { // Blind switch
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
aq_send_cmd ( _aqualink_data - > aqbuttons [ i ] . code ) ;
rtn = GET_RTN_OK ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WEB: '%s' blindly changed state \n " , command , value ) ;
2020-06-20 16:09:54 +00:00
}
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WEB: On=%d, Off=%d, Enable=%d, Flash=%d \n " , ON , OFF , ENABLE , FLASH ) ;
2020-06-20 16:09:54 +00:00
// NSF change OK and 2 below to a constant
mg_send_head ( nc , 200 , strlen ( rtn ) , CONTENT_TEXT ) ;
mg_send ( nc , rtn , strlen ( rtn ) ) ;
// NSF place check we found command here
}
}
}
// If we get here, got a bad query
mg_send_head ( nc , 200 , strlen ( GET_RTN_UNKNOWN ) , CONTENT_TEXT ) ;
mg_send ( nc , GET_RTN_UNKNOWN , strlen ( GET_RTN_UNKNOWN ) ) ;
} else {
2020-07-26 19:28:58 +00:00
//struct mg_serve_http_opts opts;
2020-07-18 16:37:19 +00:00
//memset(&opts, 0, sizeof(opts)); // Reset all options to defaults
//opts.document_root = _web_root; // Serve files from the current directory
// LOG(NET_LOG,LOG_DEBUG, "Doc root=%s\n",opts.document_root);
mg_serve_http ( nc , http_msg , _http_server_opts ) ;
2020-06-20 16:09:54 +00:00
}
}
void OLD_action_websocket_request ( struct mg_connection * nc , struct websocket_message * wm ) {
char buffer [ 100 ] ;
struct JSONwebrequest request ;
# ifdef AQ_PDA
// Any websocket request means UI is active, so don't let AqualinkD go to sleep if in PDA mode
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL )
2020-06-20 16:09:54 +00:00
pda_reset_sleep ( ) ;
# endif
strncpy ( buffer , ( char * ) wm - > data , wm - > size ) ;
buffer [ wm - > size ] = ' \0 ' ;
2020-07-18 16:37:19 +00:00
// LOG(NET_LOG,LOG_DEBUG, "buffer '%s'\n", buffer);
2020-06-20 16:09:54 +00:00
parseJSONwebrequest ( buffer , & request ) ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WS: Message - Key '%s' Value '%s' | Key2 '%s' Value2 '%s' \n " , request . first . key , request . first . value , request . second . key ,
2020-06-20 16:09:54 +00:00
request . second . value ) ;
/*
if ( strcmp ( request . first . key , " raw " ) = = 0 | | strcmp ( request . first . key , " simulator " ) = = 0 )
_aqualink_data - > simulate_panel = true ;
else
_aqualink_data - > simulate_panel = false ;
*/
if ( strcmp ( request . first . key , " raw " ) = = 0 ) {
_aqualink_data - > simulate_panel = true ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " WS: Send raw command to controller %s \n " , request . first . value ) ;
2020-06-20 16:09:54 +00:00
unsigned int n ;
sscanf ( request . first . value , " 0x%2x " , & n ) ;
//aq_programmer(AQ_SEND_CMD, (char *)&n, NULL);
aq_send_cmd ( ( unsigned char ) n ) ;
//char message[JSON_LABEL_SIZE*10];
//build_device_JSON(_aqualink_data, _aqconfig_.light_programming_button, message, JSON_LABEL_SIZE*10);
//ws_send(nc, message);
} else if ( strcmp ( request . first . key , " mode " ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//if (strcmp(request.first.value, "onetouchraw") == 0) {
// set_websocket_RSraw(nc);
// }
2020-06-20 16:09:54 +00:00
} else if ( strcmp ( request . first . key , " command " ) = = 0 ) {
_aqualink_data - > simulate_panel = false ;
if ( strcmp ( request . first . value , " GET_AUX_LABELS " ) = = 0 ) {
char labels [ JSON_LABEL_SIZE ] ;
build_aux_labels_JSON ( _aqualink_data , labels , JSON_LABEL_SIZE ) ;
ws_send ( nc , labels ) ;
} else if ( strcmp ( request . first . value , " GET_DEVICES " ) = = 0 ) {
char message [ JSON_BUFFER_SIZE ] ;
build_device_JSON ( _aqualink_data , message , JSON_BUFFER_SIZE , false ) ;
ws_send ( nc , message ) ;
} else if ( strcmp ( request . first . value , " simulator " ) = = 0 ) {
_aqualink_data - > simulate_panel = true ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WS: Set Simulator mode \n " ) ;
2020-06-20 16:09:54 +00:00
char labels [ JSON_LABEL_SIZE ] ;
build_aux_labels_JSON ( _aqualink_data , labels , JSON_LABEL_SIZE ) ;
ws_send ( nc , labels ) ;
} else if ( strcmp ( request . first . value , SWG_BOOST_TOPIC ) = = 0 ) {
2020-07-18 16:37:19 +00:00
//LOG(NET_LOG,LOG_INFO, "Boost\n");
2020-06-20 16:09:54 +00:00
if ( request . second . value ! = NULL )
_aqualink_data - > unactioned . value = request2bool ( request . second . value ) ;
else
_aqualink_data - > unactioned . value = ! _aqualink_data - > boost ;
_aqualink_data - > unactioned . type = SWG_BOOST ;
} else { // Search for value in command list
int i ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( strcmp ( request . first . value , _aqualink_data - > aqbuttons [ i ] . name ) = = 0 ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WS: button '%s' pressed \n " , _aqualink_data - > aqbuttons [ i ] . name ) ;
2020-06-20 16:09:54 +00:00
# ifdef AQ_PDA
2020-07-18 16:37:19 +00:00
if ( isPDA_PANEL ) {
2020-06-20 16:09:54 +00:00
char msg [ PTHREAD_ARG ] ;
sprintf ( msg , " %-5d%-5d " , i , ( _aqualink_data - > aqbuttons [ i ] . led - > state ! = OFF ) ? OFF : ON ) ;
aq_programmer ( AQ_PDA_DEVICE_ON_OFF , msg , _aqualink_data ) ;
} else
# endif
{
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WS: request 0x%02hhx to be sent to controller \n " , _aqualink_data - > aqbuttons [ i ] . code ) ;
2020-06-20 16:09:54 +00:00
aq_send_cmd ( _aqualink_data - > aqbuttons [ i ] . code ) ;
}
break ;
// NSF place check we found command here
}
}
}
} else if ( strcmp ( request . first . key , " parameter " ) = = 0 ) {
_aqualink_data - > simulate_panel = false ;
if ( strcmp ( request . first . value , " FRZ_PROTECT " ) = = 0 | | strcmp ( request . first . value , FREEZE_PROTECT ) = = 0 ) {
aq_programmer ( AQ_SET_FRZ_PROTECTION_TEMP , request . second . value , _aqualink_data ) ;
} else if ( strcmp ( request . first . value , " POOL_HTR " ) = = 0 | | strcmp ( request . first . value , BTN_POOL_HTR ) = = 0 ) {
aq_programmer ( AQ_SET_POOL_HEATER_TEMP , request . second . value , _aqualink_data ) ;
} else if ( strcmp ( request . first . value , " SPA_HTR " ) = = 0 | | strcmp ( request . first . value , BTN_SPA_HTR ) = = 0 ) {
aq_programmer ( AQ_SET_SPA_HEATER_TEMP , request . second . value , _aqualink_data ) ;
} else if ( strcmp ( request . first . value , SWG_TOPIC ) = = 0 ) {
//aq_programmer(AQ_SET_SWG_PERCENT, request.second.value, _aqualink_data);
int value = setpoint_check ( SWG_SETPOINT , atoi ( request . second . value ) , _aqualink_data ) ;
2020-07-18 16:37:19 +00:00
if ( _aqualink_data - > ar_swg_device_status = = SWG_STATUS_OFF ) {
2020-06-20 16:09:54 +00:00
// SWG is off, can't set %, so delay the set until it's on.
_aqualink_data - > swg_delayed_percent = value ;
} else {
aq_programmer ( AQ_SET_SWG_PERCENT , request . second . value , _aqualink_data ) ;
_aqualink_data - > swg_percent = value ; // Set the value as if it's already been set, just incase it's 0 as we won't get that message, or will update next time
}
//} else if (strcmp(request.first.value, "POOL_LIGHT_MODE") == 0) {
// set_light_mode(request.second.value, _aqconfig_.light_programming_button_pool);
} else if ( strcmp ( request . first . value , " LIGHT_MODE " ) = = 0 ) {
// second is mode & third is button_id
int i ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
// NSF I could pull the text here for the real light color name. 4th value in json
if ( strcmp ( request . third . value , _aqualink_data - > aqbuttons [ i ] . name ) = = 0 ) {
2023-05-14 21:35:13 +00:00
//set_light_mode(request.second.value, i);
panel_device_request ( _aqualink_data , LIGHT_MODE , i , request . second . value , NET_API ) ;
2020-06-20 16:09:54 +00:00
break ;
}
}
//set_light_mode(request.second.value, 0);
} else {
int i ;
bool found = false ;
for ( i = 0 ; i < _aqualink_data - > total_buttons ; i + + ) {
if ( strcmp ( request . first . value , _aqualink_data - > aqbuttons [ i ] . name ) = = 0 ) {
int pi ;
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_INFO , " WS: button parameter request '%s' '%s' \n " , _aqualink_data - > aqbuttons [ i ] . name , request . second . value ) ;
2020-06-20 16:09:54 +00:00
for ( pi = 0 ; pi < _aqualink_data - > num_pumps ; pi + + ) {
if ( _aqualink_data - > pumps [ pi ] . button = = & _aqualink_data - > aqbuttons [ i ] ) {
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_NOTICE , " WS: request to change pump %d %s to %s \n " , pi + 1 , _aqualink_data - > aqbuttons [ i ] . name , request . second . value ) ;
2020-06-20 16:09:54 +00:00
_aqualink_data - > unactioned . type = PUMP_RPM ;
_aqualink_data - > unactioned . value = atoi ( request . second . value ) ;
_aqualink_data - > unactioned . id = _aqualink_data - > pumps [ pi ] . pumpIndex ;
found = true ;
break ;
}
}
}
}
if ( ! found )
2020-07-18 16:37:19 +00:00
LOG ( NET_LOG , LOG_DEBUG , " WS: Unknown parameter %s \n " , request . first . value ) ;
2020-06-20 16:09:54 +00:00
}
}
2020-09-06 20:43:54 +00:00
}
2023-05-14 21:35:13 +00:00
# endif // INCLUDE_V1_API