diff --git a/Makefile b/Makefile index a738add..71c72ae 100755 --- a/Makefile +++ b/Makefile @@ -11,17 +11,9 @@ # Valid flags for AQ_FLAGS #AQ_RS16 = true AQ_PDA = true -#AQ_ONETOUCH = true -#AQ_IAQTOUCH = true AQ_MANAGER = true -#AQ_DOMOTICZ = true -#AQ_RS_EXTRA_OPTS = false #AQ_CONTAINER = false // this is for compiling for containers -#AQ_MEMCMP = true // Not implimented correctly yet. - -# Turn off threadded net services -AQ_NO_THREAD_NETSERVICE = false # define the C compiler(s) to use CC = gcc @@ -30,31 +22,21 @@ CC_ARMHF = arm-linux-gnueabihf-gcc CC_AMD64 = x86_64-linux-gnu-gcc #LIBS := -lpthread -lm -#LIBS := -l pthread -l m -#LIBS := -l pthread -l m -static # Take out -static, just for dev # from documentation -lrt would be needed for glibc 2.17 & prior (debug clock realtime messages), but seems to be needed for armhf 2.24 LIBS := -lpthread -lm -lrt # Standard compile flags GCCFLAGS = -Wall -O3 #GCCFLAGS = -Wall -O3 -Wunused-macros -#GCCFLAGS = -O3 #GCCFLAGS = -Wall -O3 -Wextra -#GCCFLAGS = -Wl,--gc-sections,--print-gc-sections #GCCFLAGS = -Wall -O3 -ffunction-sections -fdata-sections # Standard debug flags DGCCFLAGS = -Wall -O0 -g # Aqualink Debug flags -#DBGFLAGS = -g -O0 -Wall -fsanitize=address -D AQ_DEBUG -D AQ_TM_DEBUG DBGFLAGS = -g -O0 -Wall -D AQ_DEBUG -D AQ_TM_DEBUG -# Mongoose flags -#MGFLAGS = -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH -D MG_DISABLE_MD5 -D MG_DISABLE_JSON_RPC -# Mongoose 6.18 flags -#MGFLAGS = -D MG_ENABLE_HTTP_SSI=0 -D MG_ENABLE_DIRECTORY_LISTING=0 -D MG_ENABLE_HTTP_CGI=0 - # Mongoose 7.19 flags #MGFLAGS = -D MG_TLS=2 #(2=MG_TLS_OPENSSL. 3=MG_TLS_BUILTIN) --or-- -DMG_TLS=MG_TLS_BUILTIN MGFLAGS = -D MG_TLS=3 -D MG_ENABLE_SSI=0 @@ -89,7 +71,7 @@ endif SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c allbutton.c allbutton_aq_programmer.c net_services.c net_interface.c json_messages.c rs_msg_utils.c\ onetouch.c onetouch_aq_programmer.c iaqtouch.c iaqtouch_aq_programmer.c iaqualink.c\ devices_jandy.c packetLogger.c devices_pentair.c color_lights.c serialadapter.c aq_timer.c aq_scheduler.c web_config.c\ - serial_logger.c mongoose.c mqtt_discovery.c simulator.c sensors.c aq_systemutils.c timespec_subtract.c + serial_logger.c mongoose.c mqtt_discovery.c simulator.c sensors.c aq_systemutils.c timespec_subtract.c auto_configure.c AQ_FLAGS = @@ -99,14 +81,6 @@ ifeq ($(AQ_PDA), true) AQ_FLAGS := $(AQ_FLAGS) -D AQ_PDA endif -ifeq ($(AQ_MEMCMP), true) - AQ_FLAGS := $(AQ_FLAGS) -D AQ_MEMCMP -endif - -#ifeq ($(AQ_DOMOTICZ), true) -# AQ_FLAGS := $(AQ_FLAGS) -D AQ_DOMOTICZ -#endif - ifeq ($(AQ_MANAGER), true) AQ_FLAGS := $(AQ_FLAGS) -D AQ_MANAGER LIBS := $(LIBS) -lsystemd diff --git a/README.md b/README.md index 6a76db5..b3b973b 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ NEED TO FIX FOR THIS RELEASE. * Serial optimization for AqualinkD HAT. * upgraded network library ( HTTP(S), MQTT(S), WS ) * Added support for HTTPS and MQTTS +* Optimized updates to MQTT and WebUI (only update when absolutely necessary) * Added options to force upgrades in aqmanager. (add ?upgrade or ?devupgrade to url to enable upgrade button) * MQTT Discovery for all supporting hubs (HomeAssistant Domoticz Hubitat OpenHAB etc) * Moved Domoticz support over to MQTT autodiscovery. @@ -149,17 +150,17 @@ NEED TO FIX FOR THIS RELEASE. * UI code cleanup. * Included program advance to AqualinkD programmable light mode. (lot quicker for lights that remember state) * Changed caching of HTTP server. (Better for UI config updates) +* Autoconfigure will now get panel size/type for panels that support PC-Dock interface. +* Autoconfigure will *try* to work for PDA panels. +* Added example script to generate HTTPS certificates. (./extras/generate-certs.sh) +* Cleaned up exit & errors when running as daemon and docker. * Need to finish off :- * HAT serial optimizations broke some USB serial adapters - * Reading TruSense. (Jandy protocols working, need to finish off read_RS485_TruSense support) * Finish off assigning light mode & functionality to a vbutton (for Jandy Infinite water color support ) * cleanup rs_msg_utils.c - * -D AQ_MANAGER. reset default to on, not off - * With aqmanager is packet_logger still valid? (maybe for raw, but it's not been used in years) - * Get panel size and clean up the ap_panel code around config size/type and reported size/type * WebUI Config in aqmanager. - + * Move all programming threads over to using struct programmerArgs. # Updates in 2.6.11 (Sept 14 2025) * Cleaned up exit codes. diff --git a/release/aqualinkd-arm64 b/release/aqualinkd-arm64 index bfaa48e..31eb858 100755 Binary files a/release/aqualinkd-arm64 and b/release/aqualinkd-arm64 differ diff --git a/release/aqualinkd-armhf b/release/aqualinkd-armhf index 585925a..119d5fb 100755 Binary files a/release/aqualinkd-armhf and b/release/aqualinkd-armhf differ diff --git a/release/aqualinkd.c b/release/aqualinkd.c new file mode 100644 index 0000000..e69de29 diff --git a/release/aqualinkd.conf b/release/aqualinkd.conf index b14cd1b..f1f5dd0 100755 --- a/release/aqualinkd.conf +++ b/release/aqualinkd.conf @@ -2,12 +2,16 @@ # -# The socket port that the daemon listens to +# The web address aqualinkd daemon listens to. # If you change this from 80, remember to update aqualink.service.avahi -socket_port=80 +# Unless you are familiar with how these work, leave it alone. +listen_address=http://0.0.0.0:80 # The serial port the daemon access to read the Aqualink RS8 serial_port=/dev/ttyUSB0 +# Other common options are below +#serial_port=/dev/ttyS2 +#serial_port=/dev/serial0 # The log level. [DEBUG_DERIAL, DEBUG, INFO, NOTICE, WARNING, ERROR] # Pick the highest level, and all levels below will be sent to syslog. @@ -72,6 +76,17 @@ device_id=0xFF # If using 0x30 to 0x33 for extended_device_id, then enable below if you want to use virtual buttons #enable_iaqualink=yes + +# MQTT options +#mqtt_address=mqtt://host-or-ip.local:1883 +#mqtt_user= +#mqtt_passwd +#mqtt_aq_topic=aqualinkd +#mqtt_discovery_topic=discovery +#mqtt_discovery_use_mac=YES +#mqtt_timed_update=YES +#mqtt_convert_temp_to_c=YES + # Read information from these devices directly from the RS485 bus as well as control panel. This will # give you quicker updates and more information. # swg = Salt Water Generator @@ -87,7 +102,8 @@ device_id=0xFF #read_RS485_vsfPump = yes #read_RS485_JXi = yes #read_RS485_LX = yes -#read_RS485_Chem = yes +#read_RS485_ChemLink = yes +#read_RS485_TruSense = yes #read_RS485_iAqualink = yes #read_RS485_HeatPump = yes @@ -298,8 +314,8 @@ report_zero_pool_temp = yes # These will depend a lot on the board & OS you are running. # the "factor" is the number the sensor is multiplied by to get an accurate result. example below is (millidegrees Celsius to Celsius) -# Poll tile in seconds -#sensor_poll_time=30 +# Poll time in seconds +#sensor_poll_time=5 #sensor_01_path = /sys/class/thermal/thermal_zone0/temp #sensor_01_label = CPU @@ -315,6 +331,8 @@ report_zero_pool_temp = yes # Linux load average #sensor_03_path = /proc/loadavg #sensor_03_label = CPU load -#sensor_03_factor = 100 #sensor_03_uom = % -#sensor_03_regexp = ([0-9|\.]*)\s \ No newline at end of file +#sensor_03_regexp = ([0-9|\.]*)\s +# Sesnor factor needs to be divide by #cores of CPU. So 1 core = 100, 4 core CPU = 25. Pi Zero=1 core, Pi Zero2=4 core +#sensor_03_factor = 100 +#sensor_03_factor = 25 \ No newline at end of file diff --git a/release/serial_logger-arm64 b/release/serial_logger-arm64 index ee5ea25..23c72f5 100755 Binary files a/release/serial_logger-arm64 and b/release/serial_logger-arm64 differ diff --git a/release/serial_logger-armhf b/release/serial_logger-armhf index 4acc471..0a75ef2 100755 Binary files a/release/serial_logger-armhf and b/release/serial_logger-armhf differ diff --git a/source/allbutton.c b/source/allbutton.c index a268215..333b0fa 100644 --- a/source/allbutton.c +++ b/source/allbutton.c @@ -12,15 +12,15 @@ #include "aq_scheduler.h" /* Below can also be called from serialadapter.c */ -void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmask_t from) +void processLEDstate(struct aqualinkdata *aqdata, unsigned char *packet, logmask_t from) { int i = 0; int byte; int bit; - if (memcmp(aq_data->raw_status, packet + 4, AQ_PSTLEN) != 0) { - aq_data->updated = true; + if (memcmp(aqdata->raw_status, packet + 4, AQ_PSTLEN) != 0) { + SET_DIRTY(aqdata->is_dirty); LOG(from,LOG_DEBUG, "Processing LEDs status CHANGED\n"); } else { LOG(from,LOG_DEBUG, "Processing LEDs status\n"); @@ -28,7 +28,7 @@ void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmas // But for the moment, we don't need to speed up anything. } - memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN); + memcpy(aqdata->raw_status, packet + 4, AQ_PSTLEN); //debuglogPacket(ALLB_LOG, ); @@ -37,53 +37,64 @@ void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmas { for (bit = 0; bit < 8; bit += 2) { - if (((aq_data->raw_status[byte] >> (bit + 1)) & 1) == 1) - aq_data->aqualinkleds[i].state = FLASH; - else if (((aq_data->raw_status[byte] >> bit) & 1) == 1) - aq_data->aqualinkleds[i].state = ON; - else - aq_data->aqualinkleds[i].state = OFF; + if (((aqdata->raw_status[byte] >> (bit + 1)) & 1) == 1){ + //aqdata->aqualinkleds[i].state = FLASH; + SET_IF_CHANGED(aqdata->aqualinkleds[i].state, FLASH, aqdata->is_dirty); + } else if (((aqdata->raw_status[byte] >> bit) & 1) == 1){ + //aqdata->aqualinkleds[i].state = ON; + SET_IF_CHANGED(aqdata->aqualinkleds[i].state, ON, aqdata->is_dirty); + }else{ + //aqdata->aqualinkleds[i].state = OFF; + SET_IF_CHANGED(aqdata->aqualinkleds[i].state, OFF, aqdata->is_dirty); + } - //LOG(from,LOG_DEBUG,"Led %d state %d",i+1,aq_data->aqualinkleds[i].state); + //LOG(from,LOG_DEBUG,"Led %d state %d",i+1,aqdata->aqualinkleds[i].state); i++; } } // Reset enabled state for heaters, as they take 2 led states - if (aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[POOL_HTR_LED_INDEX].state == ON) - aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE; + if (aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[POOL_HTR_LED_INDEX].state == ON){ + //aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE; + SET_IF_CHANGED(aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty); + } - if (aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SPA_HTR_LED_INDEX].state == ON) - aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE; + if (aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[SPA_HTR_LED_INDEX].state == ON){ + //aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE; + SET_IF_CHANGED(aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty); + } - if (aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON) - aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE; + if (aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON){ + //aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE; + SET_IF_CHANGED(aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty); + } /* for (i=0; i < TOTAL_BUTTONS; i++) { - LOG(from,LOG_NOTICE, "%s = %d", aq_data->aqbuttons[i].name, aq_data->aqualinkleds[i].state); + LOG(from,LOG_NOTICE, "%s = %d", aqdata->aqbuttons[i].name, aqdata->aqualinkleds[i].state); } */ #ifdef CLIGHT_PANEL_FIX // Use state from RSSD protocol for color light if it's on. - for (int i=0; i < aq_data->num_lights; i++) { - if ( aq_data->lights[i].RSSDstate == ON && aq_data->lights[i].button->led->state != ON ) { - aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate; - //LOG(from,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aq_data->lights[i].button->label); + for (int i=0; i < aqdata->num_lights; i++) { + if ( aqdata->lights[i].RSSDstate == ON && aqdata->lights[i].button->led->state != ON ) { + aqdata->lights[i].button->led->state = aqdata->lights[i].RSSDstate; + SET_IF_CHANGED(aqdata->lights[i].button->led->state, aqdata->lights[i].RSSDstate, aqdata->is_dirty); + //LOG(from,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aqdata->lights[i].button->label); } // Below is for aqualinkd programmable light, set color mode to last if something else turns it on or off. - if (aq_data->lights[i].lightType == LC_PROGRAMABLE && ! in_light_programming_mode(aq_data)) { - if (aq_data->lights[i].button->led->state == OFF && aq_data->lights[i].currentValue != 0) { - set_currentlight_value(&aq_data->lights[i], 0); + if (aqdata->lights[i].lightType == LC_PROGRAMABLE && ! in_light_programming_mode(aqdata)) { + if (aqdata->lights[i].button->led->state == OFF && aqdata->lights[i].currentValue != 0) { + set_currentlight_value(&aqdata->lights[i], 0); //LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE 0 ******\n"); - } else if (aq_data->lights[i].button->led->state == ON && aq_data->lights[i].currentValue == 0 && aq_data->lights[i].lastValue != 0) { - set_currentlight_value(&aq_data->lights[i], aq_data->lights[i].lastValue); - //LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE %d ******\n",aq_data->lights[i].lastValue); + } else if (aqdata->lights[i].button->led->state == ON && aqdata->lights[i].currentValue == 0 && aqdata->lights[i].lastValue != 0) { + set_currentlight_value(&aqdata->lights[i], aqdata->lights[i].lastValue); + //LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE %d ******\n",aqdata->lights[i].lastValue); } } } #endif } -void setUnits(char *msg, struct aqualinkdata *aq_data) +void setUnits(char *msg, struct aqualinkdata *aqdata) { char buf[AQ_MSGLEN*3]; @@ -92,14 +103,18 @@ void setUnits(char *msg, struct aqualinkdata *aq_data) //ascii(buf, msg); LOG(ALLB_LOG,LOG_DEBUG, "Getting temp units from message '%s', looking at '%c'\n", buf, buf[strlen(buf) - 1]); - if (msg[strlen(msg) - 1] == 'F') - aq_data->temp_units = FAHRENHEIT; - else if (msg[strlen(msg) - 1] == 'C') - aq_data->temp_units = CELSIUS; - else - aq_data->temp_units = UNKNOWN; + if (msg[strlen(msg) - 1] == 'F') { + //aqdata->temp_units = FAHRENHEIT; + SET_IF_CHANGED(aqdata->temp_units, FAHRENHEIT, aqdata->is_dirty); + } else if (msg[strlen(msg) - 1] == 'C') { + //aqdata->temp_units = CELSIUS; + SET_IF_CHANGED(aqdata->temp_units, CELSIUS, aqdata->is_dirty); + } else { + //aqdata->temp_units = UNKNOWN; + SET_IF_CHANGED(aqdata->temp_units, UNKNOWN, aqdata->is_dirty); + } - LOG(ALLB_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aq_data->temp_units); + LOG(ALLB_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aqdata->temp_units); } // Defined as int16_t so 16 bits to mask @@ -118,7 +133,7 @@ void setUnits(char *msg, struct aqualinkdata *aq_data) #define MSG_LOOP_SPA_TEMP (1 << 12) -int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data) +int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aqdata) { char *sp; int i; @@ -147,11 +162,12 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data) // Only need to start at Aux B5->B8 (12-15) // Loop over only aqdata->aqbuttons[13] to aqdata->aqbuttons[16] - for (i = aq_data->rs16_vbutton_start; i <= aq_data->rs16_vbutton_end; i++) { + for (i = aqdata->rs16_vbutton_start; i <= aqdata->rs16_vbutton_end; i++) { //TOTAL_BUTTONS - if ( stristr(msg, aq_data->aqbuttons[i].label) != NULL) { - aq_data->aqbuttons[i].led->state = state; - LOG(ALLB_LOG,LOG_INFO, "Set %s to %d\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state); + if ( stristr(msg, aqdata->aqbuttons[i].label) != NULL) { + //aqdata->aqbuttons[i].led->state = state; + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, state, aqdata->is_dirty); + LOG(ALLB_LOG,LOG_INFO, "Set %s to %d\n", aqdata->aqbuttons[i].label, aqdata->aqbuttons[i].led->state); // Return true should be the result, but in the if we want to continue to display message //return true; if (i == 13) @@ -164,7 +180,7 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data) return MSG_RS16BUTTON; else { - LOG(ALLB_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state, i); + LOG(ALLB_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", aqdata->aqbuttons[i].label, aqdata->aqbuttons[i].led->state, i); return false; } @@ -175,17 +191,17 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data) } -void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset); +void _processMessage(char *message, struct aqualinkdata *aqdata, bool reset); -void processMessage(char *message, struct aqualinkdata *aq_data) +void processMessage(char *message, struct aqualinkdata *aqdata) { - _processMessage(message, aq_data, false); + _processMessage(message, aqdata, false); } -void processMessageReset(struct aqualinkdata *aq_data) +void processMessageReset(struct aqualinkdata *aqdata) { - _processMessage(NULL, aq_data, true); + _processMessage(NULL, aqdata, true); } -void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) +void _processMessage(char *message, struct aqualinkdata *aqdata, bool reset) { char *msg; static bool _initWithRS = false; @@ -203,7 +219,7 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) //msg = stripwhitespace(message); - //strcpy(aq_data->last_message, msg); + //strcpy(aqdata->last_message, msg); //LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg); @@ -215,91 +231,92 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) //if (stristr(msg, "JANDY AquaLinkRS") != NULL) { if (!reset) { msg = stripwhitespace(message); - strcpy(aq_data->last_message, msg); + strcpy(aqdata->last_message, msg); LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg); // Just set this to off, it will re-set since it'll be the only message we get if on - aq_data->service_mode_state = OFF; + aqdata->service_mode_state = OFF; } else { - //aq_data->display_message = NULL; - aq_data->last_display_message[0] = ' '; - aq_data->last_display_message[1] = '\0'; + //aqdata->display_message = NULL; + //aqdata->last_display_message[0] = ' '; + //aqdata->last_display_message[1] = '\0'; + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, "", aqdata->is_dirty); // Anything that wasn't on during the last set of messages, turn off if ((msg_loop & MSG_FREEZE) != MSG_FREEZE) { - if (aq_data->frz_protect_state != default_frz_protect_state) { + if (aqdata->frz_protect_state != default_frz_protect_state) { LOG(ALLB_LOG,LOG_INFO, "Freeze protect turned off\n"); - event_happened_set_device_state(AQS_FRZ_PROTECT_OFF, aq_data); + event_happened_set_device_state(AQS_FRZ_PROTECT_OFF, aqdata); // Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule } - aq_data->frz_protect_state = default_frz_protect_state; + SET_IF_CHANGED(aqdata->frz_protect_state, default_frz_protect_state, aqdata->is_dirty); } if ((msg_loop & MSG_SERVICE) != MSG_SERVICE && (msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) { - aq_data->service_mode_state = OFF; // IF we get this message then Service / Timeout is off + aqdata->service_mode_state = OFF; // IF we get this message then Service / Timeout is off } - if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aq_data->swg_led_state != LED_S_UNKNOWN) { + if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aqdata->swg_led_state != LED_S_UNKNOWN) { // No Additional SWG devices messages like "no flow" - if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF ) - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_OFF); + if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->aqbuttons[PUMP_INDEX].led->state == OFF ) + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_OFF); else - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_ON); + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_ON); } // If no AQUAPURE message, either (no SWG, it's set 0, or it's off). - if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->swg_led_state != LED_S_UNKNOWN ) { - if (aq_data->swg_percent != 0 || aq_data->swg_led_state == ON) { + if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->swg_led_state != LED_S_UNKNOWN ) { + if (aqdata->swg_percent != 0 || aqdata->swg_led_state == ON) { // Something is wrong here. Let's check pump, if on set SWG to 0, if off turn SWE off - if ( aq_data->aqbuttons[PUMP_INDEX].led->state == OFF) { + if ( aqdata->aqbuttons[PUMP_INDEX].led->state == OFF) { LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); - setSWGoff(aq_data); + setSWGoff(aqdata); } else { LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n"); - changeSWGpercent(aq_data, 0); + changeSWGpercent(aqdata, 0); } } else if (isIAQT_ENABLED == false && isONET_ENABLED == false && READ_RSDEV_SWG == false ) { //We have no other way to read SWG %=0, so turn SWG on with pump - if ( aq_data->aqbuttons[PUMP_INDEX].led->state == ON) { + if ( aqdata->aqbuttons[PUMP_INDEX].led->state == ON) { LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); - //changeSWGpercent(aq_data, 0); - setSWGenabled(aq_data); + //changeSWGpercent(aqdata, 0); + setSWGenabled(aqdata); } } // NSF Need something to catch startup when SWG=0 so we set it to enabeled. // when other ways/protocols to detect SWG=0 are turned off. } - if ((msg_loop & MSG_LOOP_POOL_TEMP) != MSG_LOOP_POOL_TEMP && aq_data->pool_temp != TEMP_UNKNOWN ) { - aq_data->pool_temp = TEMP_UNKNOWN; + if ((msg_loop & MSG_LOOP_POOL_TEMP) != MSG_LOOP_POOL_TEMP && aqdata->pool_temp != TEMP_UNKNOWN ) { + SET_IF_CHANGED(aqdata->pool_temp, TEMP_UNKNOWN, aqdata->is_dirty); } - if ((msg_loop & MSG_LOOP_SPA_TEMP) != MSG_LOOP_SPA_TEMP && aq_data->spa_temp != TEMP_UNKNOWN ) { - aq_data->spa_temp = TEMP_UNKNOWN; + if ((msg_loop & MSG_LOOP_SPA_TEMP) != MSG_LOOP_SPA_TEMP && aqdata->spa_temp != TEMP_UNKNOWN ) { + SET_IF_CHANGED(aqdata->spa_temp, TEMP_UNKNOWN, aqdata->is_dirty); } /* // AQUAPURE=0 we never get that message on ALLBUTTON so don't turn off unless filter pump if off - if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF ) { - //aq_data->ar_swg_status = SWG_STATUS_OFF; - setSWGoff(aq_data); + if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->aqbuttons[PUMP_INDEX].led->state == OFF ) { + //aqdata->ar_swg_status = SWG_STATUS_OFF; + setSWGoff(aqdata); } */ if ((msg_loop & MSG_BOOST) != MSG_BOOST) { - if (aq_data->boost == true || boostInLastLoop == true) { + if (aqdata->boost == true || boostInLastLoop == true) { LOG(ALLB_LOG,LOG_INFO, "Boost turned off\n"); - event_happened_set_device_state(AQS_BOOST_OFF, aq_data); + event_happened_set_device_state(AQS_BOOST_OFF, aqdata); // Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule } - aq_data->boost = false; - aq_data->boost_msg[0] = '\0'; - aq_data->boost_duration = 0; + SET_IF_CHANGED(aqdata->boost, false, aqdata->is_dirty); + aqdata->boost_msg[0] = '\0'; + SET_IF_CHANGED(aqdata->boost_duration, 0, aqdata->is_dirty); boostInLastLoop = false; - //if (aq_data->swg_percent >= 101) - // aq_data->swg_percent = 0; + //if (aqdata->swg_percent >= 101) + // aqdata->swg_percent = 0; } if ((msg_loop & MSG_BATTERY_LOW) != MSG_BATTERY_LOW) - aq_data->battery = OK; + SET_IF_CHANGED(aqdata->battery, OK, aqdata->is_dirty); //if ( _aqconfig_.rs_panel_size >= 16) { @@ -307,13 +324,13 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) if ( PANEL_SIZE() >= 16 ) { //printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE()); if ((msg_loop & MSG_RS13BUTTON) != MSG_RS13BUTTON) - aq_data->aqbuttons[13].led->state = OFF; + SET_IF_CHANGED(aqdata->aqbuttons[13].led->state, OFF, aqdata->is_dirty); if ((msg_loop & MSG_RS14BUTTON) != MSG_RS14BUTTON) - aq_data->aqbuttons[14].led->state = OFF; + SET_IF_CHANGED(aqdata->aqbuttons[14].led->state, OFF, aqdata->is_dirty); if ((msg_loop & MSG_RS15BUTTON) != MSG_RS15BUTTON) - aq_data->aqbuttons[15].led->state = OFF; + SET_IF_CHANGED(aqdata->aqbuttons[15].led->state, OFF, aqdata->is_dirty); if ((msg_loop & MSG_RS16BUTTON) != MSG_RS16BUTTON) - aq_data->aqbuttons[16].led->state = OFF; + SET_IF_CHANGED(aqdata->aqbuttons[16].led->state, OFF, aqdata->is_dirty); } msg_loop = 0; @@ -322,66 +339,67 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) if (stristr(msg, LNG_MSG_BATTERY_LOW) != NULL) { - aq_data->battery = LOW; + SET_IF_CHANGED(aqdata->battery, LOW, aqdata->is_dirty); msg_loop |= MSG_BATTERY_LOW; - strcpy(aq_data->last_display_message, msg); // Also display the message on web UI + //strcpy(aqdata->last_display_message, msg); // Also display the message on web UI + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); } else if (stristr(msg, LNG_MSG_POOL_TEMP_SET) != NULL) { //LOG(ALLB_LOG,LOG_DEBUG, "**************** pool htr long message: %s", &message[20]); - aq_data->pool_htr_set_point = atoi(message + 20); + SET_IF_CHANGED(aqdata->pool_htr_set_point, atoi(message + 20), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } else if (stristr(msg, LNG_MSG_SPA_TEMP_SET) != NULL) { //LOG(ALLB_LOG,LOG_DEBUG, "spa htr long message: %s", &message[19]); - aq_data->spa_htr_set_point = atoi(message + 19); + SET_IF_CHANGED(aqdata->spa_htr_set_point, atoi(message + 19), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_SET) != NULL) { //LOG(ALLB_LOG,LOG_DEBUG, "frz protect long message: %s", &message[28]); - aq_data->frz_protect_set_point = atoi(message + 28); - aq_data->frz_protect_state = ENABLE; + SET_IF_CHANGED(aqdata->frz_protect_set_point, atoi(message + 28), aqdata->is_dirty); + SET_IF_CHANGED(aqdata->frz_protect_state, ENABLE, aqdata->is_dirty); default_frz_protect_state = ENABLE; - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } else if (strncasecmp(msg, MSG_AIR_TEMP, MSG_AIR_TEMP_LEN) == 0) { - aq_data->air_temp = atoi(msg + MSG_AIR_TEMP_LEN); + SET_IF_CHANGED(aqdata->air_temp, atoi(msg + MSG_AIR_TEMP_LEN), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } else if (strncasecmp(msg, MSG_POOL_TEMP, MSG_POOL_TEMP_LEN) == 0) { msg_loop |= MSG_LOOP_POOL_TEMP; - aq_data->pool_temp = atoi(msg + MSG_POOL_TEMP_LEN); + SET_IF_CHANGED(aqdata->pool_temp, atoi(msg + MSG_POOL_TEMP_LEN), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } else if (strncasecmp(msg, MSG_SPA_TEMP, MSG_SPA_TEMP_LEN) == 0) { msg_loop |= MSG_LOOP_SPA_TEMP; - aq_data->spa_temp = atoi(msg + MSG_SPA_TEMP_LEN); + SET_IF_CHANGED(aqdata->spa_temp, atoi(msg + MSG_SPA_TEMP_LEN), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); } // NSF If get water temp rather than pool or spa in some cases, then we are in Pool OR Spa ONLY mode else if (strncasecmp(msg, MSG_WATER_TEMP, MSG_WATER_TEMP_LEN) == 0) { - aq_data->pool_temp = atoi(msg + MSG_WATER_TEMP_LEN); - aq_data->spa_temp = atoi(msg + MSG_WATER_TEMP_LEN); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + SET_IF_CHANGED(aqdata->pool_temp, atoi(msg + MSG_WATER_TEMP_LEN), aqdata->is_dirty); + SET_IF_CHANGED(aqdata->spa_temp, atoi(msg + MSG_WATER_TEMP_LEN), aqdata->is_dirty); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); if (isSINGLE_DEV_PANEL != true) { @@ -391,10 +409,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) } else if (stristr(msg, LNG_MSG_WATER_TEMP1_SET) != NULL) { - aq_data->pool_htr_set_point = atoi(message + 28); + SET_IF_CHANGED(aqdata->pool_htr_set_point, atoi(message + 28), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); if (isSINGLE_DEV_PANEL != true) { @@ -404,10 +422,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) } else if (stristr(msg, LNG_MSG_WATER_TEMP2_SET) != NULL) { - aq_data->spa_htr_set_point = atoi(message + 27); + SET_IF_CHANGED(aqdata->spa_htr_set_point, atoi(message + 27), aqdata->is_dirty); - if (aq_data->temp_units == UNKNOWN) - setUnits(msg, aq_data); + if (aqdata->temp_units == UNKNOWN) + setUnits(msg, aqdata); if (isSINGLE_DEV_PANEL != true) { @@ -417,31 +435,32 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) } else if (stristr(msg, LNG_MSG_SERVICE_ACTIVE) != NULL) { - if (aq_data->service_mode_state == OFF) + if (aqdata->service_mode_state == OFF) LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n"); - aq_data->service_mode_state = ON; + SET_IF_CHANGED(aqdata->service_mode_state, ON, aqdata->is_dirty); msg_loop |= MSG_SERVICE; //service_msg_count = 0; } else if (stristr(msg, LNG_MSG_TIMEOUT_ACTIVE) != NULL) { - if (aq_data->service_mode_state == OFF) + if (aqdata->service_mode_state == OFF) LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n"); - aq_data->service_mode_state = FLASH; + SET_IF_CHANGED(aqdata->service_mode_state, FLASH, aqdata->is_dirty); msg_loop |= MSG_TIMEOUT; //service_msg_count = 0; } else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_ACTIVATED) != NULL) { msg_loop |= MSG_FREEZE; - //aq_data->frz_protect_state = default_frz_protect_state; - aq_data->frz_protect_state = ON; + //aqdata->frz_protect_state = default_frz_protect_state; + SET_IF_CHANGED(aqdata->frz_protect_state, ON, aqdata->is_dirty); //freeze_msg_count = 0; - strcpy(aq_data->last_display_message, msg); // Also display the message on web UI + //strcpy(aqdata->last_display_message, msg); // Also display the message on web UI + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); } else if (ENABLE_CHILLER && (stristr(msg,"Chiller") != NULL || stristr(msg,"Heat Pump") != NULL)) { - processHeatPumpDisplayMessage(msg, aq_data); // This doesn;t exist yet + processHeatPumpDisplayMessage(msg, aqdata); // This doesn;t exist yet } /* // Not sure when to do with these for the moment, so no need to compile in the test. @@ -452,27 +471,29 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) */ else if (msg[2] == '/' && msg[5] == '/' && msg[8] == ' ') { // date in format '08/29/16 MON' - strcpy(aq_data->date, msg); + //strcpy(aqdata->date, msg); + SET_IF_CHANGED_STRCPY(aqdata->date, msg, aqdata->is_dirty); } else if (stristr(msg, MSG_SWG_PCT) != NULL) { if (strncasecmp(msg, MSG_SWG_PCT, MSG_SWG_PCT_LEN) == 0 && strncasecmp(msg, "AQUAPURE HRS", 12) != 0) { - changeSWGpercent(aq_data, atoi(msg + MSG_SWG_PCT_LEN)); + changeSWGpercent(aqdata, atoi(msg + MSG_SWG_PCT_LEN)); } else if (strncasecmp(msg, "AQUAPURE HRS", 12) != 0 && strncasecmp(msg, "SET AQUAPURE", 12) != 0) { if (strcasestr(msg, MSG_SWG_NO_FLOW) != NULL) - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_NO_FLOW); + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_NO_FLOW); else if (strcasestr(msg, MSG_SWG_LOW_SALT) != NULL) - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_LOW_SALT); + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_LOW_SALT); else if (strcasestr(msg, MSG_SWG_HIGH_SALT) != NULL) - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_HI_SALT); + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_HI_SALT); else if (strcasestr(msg, MSG_SWG_FAULT) != NULL) - setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_GENFAULT); - //setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_CHECK_PCB); + setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_GENFAULT); + //setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_CHECK_PCB); // Any of these messages want to display. - strcpy(aq_data->last_display_message, msg); + //strcpy(aqdata->last_display_message, msg); + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); msg_loop |= MSG_SWG_DEVICE; } @@ -480,32 +501,33 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) } else if (strncasecmp(msg, MSG_SWG_PPM, MSG_SWG_PPM_LEN) == 0) { - aq_data->swg_ppm = atoi(msg + MSG_SWG_PPM_LEN); + SET_IF_CHANGED( aqdata->swg_ppm, atoi(msg + MSG_SWG_PPM_LEN), aqdata->is_dirty); msg_loop |= MSG_SWG; } else if ((msg[1] == ':' || msg[2] == ':') && msg[strlen(msg) - 1] == 'M') { // time in format '9:45 AM' - strcpy(aq_data->time, msg); + //strcpy(aqdata->time, msg); + SET_IF_CHANGED_STRCPY(aqdata->time, msg, aqdata->is_dirty); // Setting time takes a long time, so don't try until we have all other programmed data. - if (_initWithRS == true && strlen(aq_data->date) > 1 && checkAqualinkTime() != true) + if (_initWithRS == true && strlen(aqdata->date) > 1 && checkAqualinkTime() != true) { - LOG(ALLB_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", aq_data->time, aq_data->date); - aq_programmer(AQ_SET_TIME, NULL, aq_data); + LOG(ALLB_LOG,LOG_NOTICE, "Time is NOT accurate '%s %s', re-setting on controller!\n", aqdata->time, aqdata->date); + aq_programmer(AQ_SET_TIME, NULL, aqdata); } else if (_initWithRS == false || _aqconfig_.sync_panel_time == false) { - LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", aq_data->time, aq_data->date); + LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", aqdata->time, aqdata->date); } else if (_initWithRS == true) { - LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", aq_data->time, aq_data->date); + LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", aqdata->time, aqdata->date); } // If we get a time message before REV, the controller didn't see us as we started too quickly. /* Don't need to check this anymore with the check for probe before startup. if (_gotREV == false) { LOG(ALLB_LOG,LOG_NOTICE, "Getting control panel information\n", msg); - aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, aq_data); + aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, aqdata); _gotREV = true; // Force it to true just incase we don't understand the model# } */ @@ -513,19 +535,20 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) else if (strstr(msg, " REV ") != NULL || strstr(msg, " REV. ") != NULL) { // '8157 REV MMM' // A master firmware revision message. - strcpy(aq_data->version, msg); - rsm_get_revision(aq_data->revision, aq_data->version, strlen(aq_data->version)); - setPanelInformationFromPanelMsg(aq_data, msg, PANEL_CPU | PANEL_REV, ALLBUTTON); - //setBoardCPURevision(aq_data, aq_data->version, strlen(aq_data->version), ALLB_LOG); + //strcpy(aqdata->version, msg); + SET_IF_CHANGED_STRCPY(aqdata->version, msg, aqdata->is_dirty); + rsm_get_revision(aqdata->revision, aqdata->version, strlen(aqdata->version)); + setPanelInformationFromPanelMsg(aqdata, msg, PANEL_CPU | PANEL_REV, ALLBUTTON); + //setBoardCPURevision(aqdata, aqdata->version, strlen(aqdata->version), ALLB_LOG); //_gotREV = true; - LOG(ALLB_LOG,LOG_DEBUG, "Control Panel version %s\n", aq_data->version); - LOG(ALLB_LOG,LOG_DEBUG, "Control Panel revision %s\n", aq_data->revision); + LOG(ALLB_LOG,LOG_DEBUG, "Control Panel version %s\n", aqdata->version); + LOG(ALLB_LOG,LOG_DEBUG, "Control Panel revision %s\n", aqdata->revision); if (_initWithRS == false) { //LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n"); - queueGetProgramData(ALLBUTTON, aq_data); - event_happened_set_device_state(AQS_POWER_ON, aq_data); - //queueGetExtendedProgramData(ALLBUTTON, aq_data, _aqconfig_.use_panel_aux_labels); + queueGetProgramData(ALLBUTTON, aqdata); + event_happened_set_device_state(AQS_POWER_ON, aqdata); + //queueGetExtendedProgramData(ALLBUTTON, aqdata, _aqconfig_.use_panel_aux_labels); _initWithRS = true; } } @@ -535,8 +558,8 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) } else if (_aqconfig_.override_freeze_protect == TRUE && strncasecmp(msg, "Press Enter* to override Freeze Protection with", 47) == 0) { - //send_cmd(KEY_ENTER, aq_data); - //aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, aq_data); + //send_cmd(KEY_ENTER, aqdata); + //aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, aqdata); aq_send_allb_cmd(KEY_ENTER); } // Process any button states (fake LED) for RS12 and above keypads @@ -544,14 +567,15 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) //else if ( _aqconfig_.rs_panel_size >= 16 && (rs16 = RS16_endswithLEDstate(msg)) != 0 ) - else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg, aq_data)) != 0 ) + else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg, aqdata)) != 0 ) { msg_loop |= rs16; // Do nothing, just stop other else if statments executing // make sure we also display the message. // Note we only get ON messages here, Off messages will not be sent if something else turned it off // use the Onetouch or iAqua equiptment page for off. - strcpy(aq_data->last_display_message, msg); + //strcpy(aqdata->last_display_message, msg); + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); } else if (((msg[4] == ':') || (msg[6] == ':')) && (strncasecmp(msg, "AUX", 3) == 0) ) @@ -570,64 +594,67 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) labelid = labelid + 1; // Aux1: on panel = Button 3 in aqualinkd (button 2 in array) if (strncasecmp(msg+ni+3, "No Label", 8) != 0) { - aq_data->aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2)); - LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label); + aqdata->aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2)); + LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", aqdata->aqbuttons[labelid].name, aqdata->aqbuttons[labelid].label); } else { - LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label); + LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", aqdata->aqbuttons[labelid].name, aqdata->aqbuttons[labelid].label); } - //aq_data->aqbuttons[labelid + 1].label = cleanalloc(msg + 5); + //aqdata->aqbuttons[labelid + 1].label = cleanalloc(msg + 5); } } // BOOST POOL 23:59 REMAINING else if ( (strncasecmp(msg, "BOOST POOL", 10) == 0) && (strcasestr(msg, "REMAINING") != NULL) ) { // Ignore messages if in programming mode. We get one of these turning off for some strange reason. - if (in_programming_mode(aq_data) == false) { + if (in_programming_mode(aqdata) == false) { - if (aq_data->boost == false || boostInLastLoop == false) { - event_happened_set_device_state(AQS_BOOST_ON, aq_data); + if (aqdata->boost == false || boostInLastLoop == false) { + event_happened_set_device_state(AQS_BOOST_ON, aqdata); } - snprintf(aq_data->boost_msg, 6, "%s", &msg[11]); - aq_data->boost_duration = rsm_HHMM2min(aq_data->boost_msg); - aq_data->boost = true; + snprintf(aqdata->boost_msg, 6, "%s", &msg[11]); + aqdata->boost_duration = rsm_HHMM2min(aqdata->boost_msg); + SET_IF_CHANGED(aqdata->boost, true, aqdata->is_dirty); msg_loop |= MSG_BOOST; msg_loop |= MSG_SWG; boostInLastLoop = true; - //convert_boost_to_duration(aq_data->boost_msg) - //if (aq_data->ar_swg_status != SWG_STATUS_ON) {aq_data->ar_swg_status = SWG_STATUS_ON;} - if (aq_data->swg_percent != 101) {changeSWGpercent(aq_data, 101);} + //convert_boost_to_duration(aqdata->boost_msg) + //if (aqdata->ar_swg_status != SWG_STATUS_ON) {aqdata->ar_swg_status = SWG_STATUS_ON;} + if (aqdata->swg_percent != 101) {changeSWGpercent(aqdata, 101);} //boost_msg_count = 0; - //if (aq_data->active_thread.thread_id == 0) - strcpy(aq_data->last_display_message, msg); // Also display the message on web UI if not in programming mode + //if (aqdata->active_thread.thread_id == 0) + //strcpy(aqdata->last_display_message, msg); // Also display the message on web UI if not in programming mode + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); } } else { LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg); - //aq_data->display_message = msg; - //if (in_programming_mode(aq_data) == false && aq_data->simulate_panel == false && - if (in_programming_mode(aq_data) == false && + //aqdata->display_message = msg; + //if (in_programming_mode(aqdata) == false && aqdata->simulate_panel == false && + if (in_programming_mode(aqdata) == false && stristr(msg, "JANDY AquaLinkRS") == NULL && //stristr(msg, "PUMP O") == NULL &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON' strncasecmp(msg, "PUMP O", 6) != 0 &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON' stristr(msg, "MAINTAIN") == NULL && // Catch 'MAINTAIN TEMP IS OFF' + stristr(msg, "Heat Pump") == NULL && // Stop Heatpump on / off messages spam the UI. stristr(msg, "0 PSI") == NULL /* // Catch some erronious message on test harness stristr(msg, "CLEANER O") == NULL && stristr(msg, "SPA O") == NULL && stristr(msg, "AUX") == NULL*/ ) { // Catch all AUX1 AUX5 messages - //aq_data->display_last_message = true; - strcpy(aq_data->last_display_message, msg); - //rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN); + //aqdata->display_last_message = true; + //strcpy(aqdata->last_display_message, msg); + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty); + //rsm_strncpy(aqdata->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN); } } // Send every message if we are in simulate panel mode - //if (aq_data->simulate_panel) - // strcpy(aq_data->last_display_message, msg); - //rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN); - //ascii(aq_data->last_display_message, msg); + //if (aqdata->simulate_panel) + // strcpy(aqdata->last_display_message, msg); + //rsm_strncpy(aqdata->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN); + //ascii(aqdata->last_display_message, msg); //LOG(ALLB_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop); @@ -636,10 +663,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset) //printf ("Message kicking\n"); - kick_aq_program_thread(aq_data, ALLBUTTON); + kick_aq_program_thread(aqdata, ALLBUTTON); } -bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) +bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata) { bool rtn = false; //static unsigned char last_packet[AQ_MAXPKTLEN]; @@ -658,15 +685,15 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink else { memcpy(last_packet, packet, length); - aq_data->last_packet_type = packet[PKT_CMD]; + aqdata->last_packet_type = packet[PKT_CMD]; rtn = true; } */ - aq_data->last_packet_type = packet[PKT_CMD]; + aqdata->last_packet_type = packet[PKT_CMD]; - if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(aq_data) ) + if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(aqdata) ) { LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length); return false; @@ -682,7 +709,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink processing_long_msg = 0; //LOG(ALLB_LOG,LOG_ERR, "RS failed to receive complete long message, received '%s'\n",message); //LOG(ALLB_LOG,LOG_DEBUG, "RS didn't finished receiving of MSG_LONG '%s'\n",message); - processMessage(message, aq_data); + processMessage(message, aqdata); } LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length); @@ -696,34 +723,34 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink //LOG(ALLB_LOG,LOG_DEBUG, "RS Received STATUS length %d.\n", length); //debuglogPacket(ALLB_LOG, packet, length, true, true); - //memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN); - //processLEDstate(aq_data); - processLEDstate(aq_data, packet, ALLB_LOG); + //memcpy(aqdata->raw_status, packet + 4, AQ_PSTLEN); + //processLEDstate(aqdata); + processLEDstate(aqdata, packet, ALLB_LOG); /* NSF Take this out, and use the ALLButton loop cycle to determin if we get spa/pool temp messages. Works better for dual equiptment when both pool & spa pumps and dual temp sensors */ /* - if (aq_data->aqbuttons[PUMP_INDEX].led->state == OFF) + if (aqdata->aqbuttons[PUMP_INDEX].led->state == OFF) { - aq_data->pool_temp = TEMP_UNKNOWN; - aq_data->spa_temp = TEMP_UNKNOWN; - //aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN; + aqdata->pool_temp = TEMP_UNKNOWN; + aqdata->spa_temp = TEMP_UNKNOWN; + //aqdata->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN; } - else if (aq_data->aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true) + else if (aqdata->aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true) { - //aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN; - aq_data->spa_temp = TEMP_UNKNOWN; + //aqdata->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN; + aqdata->spa_temp = TEMP_UNKNOWN; } - else if (aq_data->aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true) + else if (aqdata->aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true) { - aq_data->pool_temp = TEMP_UNKNOWN; + aqdata->pool_temp = TEMP_UNKNOWN; } */ // COLOR MODE programming relies on state changes, so let any threads know - //if (aq_data->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) { - if ( in_light_programming_mode(aq_data) ) { - kick_aq_program_thread(aq_data, ALLBUTTON); + //if (aqdata->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) { + if ( in_light_programming_mode(aqdata) ) { + kick_aq_program_thread(aqdata, ALLBUTTON); } break; case CMD_MSG: @@ -747,7 +774,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink //printf("RSM Long message index %d doesn't match buffer %d\n",index,processing_long_msg); } #ifdef PROCESS_INCOMPLETE_MESSAGES - kick_aq_program_thread(aq_data, ALLBUTTON); + kick_aq_program_thread(aqdata, ALLBUTTON); #endif } @@ -755,10 +782,10 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink //printf("RSM process message '%s'\n",message); // MOVED FROM LINE 701 see if less errors - //kick_aq_program_thread(aq_data, ALLBUTTON); + //kick_aq_program_thread(aqdata, ALLBUTTON); LOG(ALLB_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message); - processMessage(message, aq_data); // This will kick thread + processMessage(message, aqdata); // This will kick thread } } @@ -770,7 +797,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink break; case CMD_MSG_LOOP_ST: LOG(ALLB_LOG,LOG_INFO, "RS Received message loop start\n"); - processMessageReset(aq_data); + processMessageReset(aqdata); rtn = false; break; default: diff --git a/source/allbutton_aq_programmer.c b/source/allbutton_aq_programmer.c index c36146b..36b0318 100644 --- a/source/allbutton_aq_programmer.c +++ b/source/allbutton_aq_programmer.c @@ -15,12 +15,12 @@ -bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate state, int numMessageReceived); -bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived); -bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived); +bool waitForButtonState(struct aqualinkdata *aqdata, aqkey* button, aqledstate state, int numMessageReceived); +bool waitForMessage(struct aqualinkdata *aqdata, char* message, int numMessageReceived); +bool waitForEitherMessage(struct aqualinkdata *aqdata, char* message1, char* message2, int numMessageReceived); -bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string); -bool select_menu_item(struct aqualinkdata *aq_data, char* item_string); +bool select_sub_menu_item(struct aqualinkdata *aqdata, char* item_string); +bool select_menu_item(struct aqualinkdata *aqdata, char* item_string); void send_cmd(unsigned char cmd); void cancel_menu(); @@ -70,12 +70,12 @@ int get_allb_queue_length() -unsigned char pop_allb_cmd(struct aqualinkdata *aq_data) +unsigned char pop_allb_cmd(struct aqualinkdata *aqdata) { unsigned char cmd = NUL; if ( _expectNextMessage > 0 && - (aq_data->last_packet_type == CMD_MSG || aq_data->last_packet_type == CMD_MSG_LONG || aq_data->last_packet_type == CMD_MSG_LOOP_ST)) + (aqdata->last_packet_type == CMD_MSG || aqdata->last_packet_type == CMD_MSG_LONG || aqdata->last_packet_type == CMD_MSG_LOOP_ST)) { _expectNextMessage=0; } else if (_expectNextMessage > 3) { @@ -90,9 +90,9 @@ unsigned char pop_allb_cmd(struct aqualinkdata *aq_data) // Only send commands on status messages and is we are not in programming mode. // In programming move, we don't use the queue. // Are we in programming mode and it's not ONETOUCH programming mode - if (in_programming_mode(aq_data) && ( in_ot_programming_mode(aq_data) == false && in_iaqt_programming_mode(aq_data) == false )) { - //if (aq_data->active_thread.thread_id != 0) { - if ( _allb_pgm_command != NUL && aq_data->last_packet_type == CMD_STATUS) { + if (in_programming_mode(aqdata) && ( in_ot_programming_mode(aqdata) == false && in_iaqt_programming_mode(aqdata) == false )) { + //if (aqdata->active_thread.thread_id != 0) { + if ( _allb_pgm_command != NUL && aqdata->last_packet_type == CMD_STATUS) { cmd = _allb_pgm_command; _allb_pgm_command = NUL; LOG(ALLB_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' (programming)\n", cmd); @@ -101,7 +101,7 @@ unsigned char pop_allb_cmd(struct aqualinkdata *aq_data) } else { LOG(ALLB_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' empty queue (programming)\n", cmd); } - } else if (_allb_stack_place > 0 && aq_data->last_packet_type == CMD_STATUS ) { + } else if (_allb_stack_place > 0 && aqdata->last_packet_type == CMD_STATUS ) { cmd = _allb_commands[0]; _allb_stack_place--; LOG(ALLB_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); @@ -111,7 +111,7 @@ unsigned char pop_allb_cmd(struct aqualinkdata *aq_data) LOG(ALLB_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); } -//printf("RSM sending cmd '0x%02hhx' in reply to '0x%02hhx'\n",cmd,aq_data->last_packet_type); +//printf("RSM sending cmd '0x%02hhx' in reply to '0x%02hhx'\n",cmd,aqdata->last_packet_type); if (cmd == KEY_ENTER || cmd == KEY_RIGHT || cmd == KEY_LEFT || cmd == KEY_MENU ) { //KEY_CANCEL KEY_HOLD KEY_OVERRIDE _expectNextMessage=1; @@ -123,12 +123,12 @@ unsigned char pop_allb_cmd(struct aqualinkdata *aq_data) -bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label, int value, int increment); -bool setAqualinkNumericField(struct aqualinkdata *aq_data, char *value_label, int value) +bool setAqualinkNumericField_new(struct aqualinkdata *aqdata, char *value_label, int value, int increment); +bool setAqualinkNumericField(struct aqualinkdata *aqdata, char *value_label, int value) { - return setAqualinkNumericField_new(aq_data, value_label, value, 1); + return setAqualinkNumericField_new(aqdata, value_label, value, 1); } -bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label, int value, int increment) +bool setAqualinkNumericField_new(struct aqualinkdata *aqdata, char *value_label, int value, int increment) { LOG(ALLB_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); //char leading[10]; // description of the field (POOL, SPA, FRZ) @@ -141,15 +141,15 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label int i=0; do { - if (waitForMessage(aq_data, searchBuf, 4) != true) { + if (waitForMessage(aqdata, searchBuf, 4) != true) { LOG(ALLB_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } //LOG(ALLB_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); - //sscanf(aq_data->last_message, "%s %d%s", leading, ¤t_val, trailing); - //sscanf(aq_data->last_message, "%*[^0123456789]%d", ¤t_val); - sscanf(&aq_data->last_message[val_len], "%*[^0123456789]%d", ¤t_val); + //sscanf(aqdata->last_message, "%s %d%s", leading, ¤t_val, trailing); + //sscanf(aqdata->last_message, "%*[^0123456789]%d", ¤t_val); + sscanf(&aqdata->last_message[val_len], "%*[^0123456789]%d", ¤t_val); LOG(ALLB_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { @@ -180,7 +180,7 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label -bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aq_data, char *value_label, int value) +bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aqdata, char *value_label, int value) { // Works for everything but not SWG LOG(ALLB_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); char leading[10]; // description of the field (POOL, SPA, FRZ) @@ -192,13 +192,13 @@ bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aq_data, char *value_l do { - if (waitForMessage(aq_data, searchBuf, 3) != true) { + if (waitForMessage(aqdata, searchBuf, 3) != true) { LOG(ALLB_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } //LOG(ALLB_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); - sscanf(aq_data->last_message, "%s %d%s", leading, ¤t_val, trailing); + sscanf(aqdata->last_message, "%s %d%s", leading, ¤t_val, trailing); LOG(ALLB_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { @@ -225,11 +225,11 @@ void *threadded_send_cmd( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SEND_CMD); - send_cmd( (unsigned char)*threadCtrl->thread_args, aq_data); + send_cmd( (unsigned char)*threadCtrl->thread_args, aqdata); cleanAndTerminateThread(threadCtrl); @@ -241,7 +241,7 @@ void *set_allbutton_boost( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_BOOST); /* @@ -268,7 +268,7 @@ STOP BOOST POOL LOG(ALLB_LOG, LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); - if ( select_menu_item(aq_data, "BOOST POOL") != true ) { + if ( select_menu_item(aqdata, "BOOST POOL") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); @@ -276,7 +276,7 @@ STOP BOOST POOL } if (val==true) { - waitForMessage(threadCtrl->aq_data, "TO START BOOST POOL", 5); + waitForMessage(threadCtrl->aqdata, "TO START BOOST POOL", 5); send_cmd(KEY_ENTER); longwaitfor_queue2empty(); } else { @@ -284,8 +284,8 @@ STOP BOOST POOL int i=0; while( i++ < wait_messages) { - waitForMessage(aq_data, "STOP BOOST POOL", 1); - if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) { + waitForMessage(aqdata, "STOP BOOST POOL", 1); + if (stristr(aqdata->last_message, "STOP BOOST POOL") != NULL) { // This is a really bad hack, message sequence is out for boost for some reason, so as soon as we see stop message, force enter key. //_allb_pgm_command = KEY_ENTER; send_cmd(KEY_ENTER); @@ -293,9 +293,9 @@ STOP BOOST POOL //waitfor_queue2empty(); break; } else { - LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for 'STOP BOOST POOL' received message '%s'\n",i,wait_messages,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for 'STOP BOOST POOL' received message '%s'\n",i,wait_messages,aqdata->last_message); delay(200); - if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) { + if (stristr(aqdata->last_message, "STOP BOOST POOL") != NULL) { //_allb_pgm_command = KEY_ENTER; send_cmd(KEY_ENTER); LOG(ALLB_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); @@ -307,17 +307,17 @@ STOP BOOST POOL //printf("FINISHED WAIT\n"); } //waitfor_queue2empty(); - //waitForMessage(aq_data, NULL, 1); + //waitForMessage(aqdata, NULL, 1); } if (i < wait_messages) { // Takes ages to see bost is off from menu, to set it here. - setSWGboost(aq_data, false); + setSWGboost(aqdata, false); } /* // Extra message overcome. send_cmd(KEY_RIGHT); waitfor_queue2empty(); - if ( select_sub_menu_item(aq_data, "STOP BOOST POOL") != true ) { + if ( select_sub_menu_item(aqdata, "STOP BOOST POOL") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select STOP BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); @@ -326,7 +326,7 @@ STOP BOOST POOL //send_cmd(KEY_ENTER); } - waitForMessage(aq_data,NULL, 1); + waitForMessage(aqdata,NULL, 1); cleanAndTerminateThread(threadCtrl); @@ -339,67 +339,67 @@ void *set_allbutton_SWG( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_SWG_PERCENT); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SWG_SETPOINT, val, aq_data); + val = setpoint_check(SWG_SETPOINT, val, aqdata); //LOG(ALLB_LOG, LOG_NOTICE, "programming SWG percent to %d\n", val); - if ( select_menu_item(aq_data, "SET AQUAPURE") != true ) { + if ( select_menu_item(aqdata, "SET AQUAPURE") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET AQUAPURE menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } // If spa is on, set SWG for spa, if not set SWG for pool - if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) { - if (select_sub_menu_item(aq_data, "SET SPA SP") != true) { + if (aqdata->aqbuttons[SPA_INDEX].led->state != OFF) { + if (select_sub_menu_item(aqdata, "SET SPA SP") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu for SPA\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - setAqualinkNumericField_new(aq_data, "SPA SP", val, 5); + setAqualinkNumericField_new(aqdata, "SPA SP", val, 5); } else { - if (select_sub_menu_item(aq_data, "SET POOL SP") != true) { + if (select_sub_menu_item(aqdata, "SET POOL SP") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - setAqualinkNumericField_new(aq_data, "POOL SP", val, 5); + setAqualinkNumericField_new(aqdata, "POOL SP", val, 5); } // Let everyone know we set SWG, if it failed we will update on next message, unless it's 0. - setSWGpercent(aq_data, val); // Don't use chageSWGpercent as we are in programming mode. + setSWGpercent(aqdata, val); // Don't use chageSWGpercent as we are in programming mode. /* - if (select_sub_menu_item(aq_data, "SET POOL SP") != true) { + if (select_sub_menu_item(aqdata, "SET POOL SP") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); - cancel_menu(aq_data); + cancel_menu(aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } - setAqualinkNumericField_new(aq_data, "POOL SP", val, 5); + setAqualinkNumericField_new(aqdata, "POOL SP", val, 5); */ // usually miss this message, not sure why, but wait anyway to make sure programming has ended // NSF have see the below message RS Message :- // 'Pool set to 20%' // 'POOL SP IS SET TO 20%' - waitForMessage(threadCtrl->aq_data, "SET TO", 1); - //waitForMessage(threadCtrl->aq_data, "POOL SP IS SET TO", 1); + waitForMessage(threadCtrl->aqdata, "SET TO", 1); + //waitForMessage(threadCtrl->aqdata, "POOL SP IS SET TO", 1); // Since we read % directly from RS message, wait for another few messages that way // We won't registed a SWG bounce, since we already told clients SWG was at new % before programming started - waitForMessage(threadCtrl->aq_data, NULL, 1); + waitForMessage(threadCtrl->aqdata, NULL, 1); cleanAndTerminateThread(threadCtrl); @@ -413,27 +413,27 @@ void *get_allbutton_aux_labels( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_AUX_LABELS); - if ( select_menu_item(aq_data, "REVIEW") != true ) { + if ( select_menu_item(aqdata, "REVIEW") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - if (select_sub_menu_item(aq_data, "AUX LABELS") != true) { + if (select_sub_menu_item(aqdata, "AUX LABELS") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select AUX LABELS menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - waitForMessage(aq_data, NULL, 5); // Receive 5 messages + waitForMessage(aqdata, NULL, 5); // Receive 5 messages cleanAndTerminateThread(threadCtrl); @@ -446,7 +446,7 @@ void *set_allbutton_light_colormode( void *ptr ) int i; struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_LIGHTCOLOR_MODE); @@ -457,13 +457,13 @@ void *set_allbutton_light_colormode( void *ptr ) int typ = atoi(&buf[10]); bool use_current_mode = false; - if (btn < 0 || btn >= aq_data->total_buttons ) { + if (btn < 0 || btn >= aqdata->total_buttons ) { LOG(ALLB_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } - aqkey *button = &aq_data->aqbuttons[btn]; + aqkey *button = &aqdata->aqbuttons[btn]; unsigned char code = button->code; //LOG(ALLB_LOG, LOG_NOTICE, "Light Programming #: %d, on button: %s, color light type: %d\n", val, button->label, typ); @@ -497,7 +497,7 @@ void *set_allbutton_light_colormode( void *ptr ) LOG(ALLB_LOG, LOG_INFO, "Light Programming Initial state on, turning off\n"); send_cmd(code); waitfor_queue2empty(); - if ( !waitForMessage(threadCtrl->aq_data, "OFF", 5)) // Message like 'Aux3 Off' + if ( !waitForMessage(threadCtrl->aqdata, "OFF", 5)) // Message like 'Aux3 Off' LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive OFF message\n"); } @@ -509,18 +509,18 @@ void *set_allbutton_light_colormode( void *ptr ) do{ LOG(ALLB_LOG, LOG_INFO,"Light program wait for message\n"); - if ( !waitForMessage(threadCtrl->aq_data, "~*", waitCounter)) + if ( !waitForMessage(threadCtrl->aqdata, "~*", waitCounter)) LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive color light mode message\n"); // Wait for less messages after first try. We get a lot of repeat messages before the one we need. waitCounter = 3; if (use_current_mode) { - LOG(ALLB_LOG, LOG_INFO, "Light Programming using color mode %s\n",aq_data->last_message); + LOG(ALLB_LOG, LOG_INFO, "Light Programming using color mode %s\n",aqdata->last_message); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; - } else if (strncasecmp(aq_data->last_message, mode_name, strlen(mode_name)) == 0) { + } else if (strncasecmp(aqdata->last_message, mode_name, strlen(mode_name)) == 0) { LOG(ALLB_LOG, LOG_INFO, "Light Programming found color mode %s\n",mode_name); send_cmd(KEY_ENTER); waitfor_queue2empty(); @@ -531,7 +531,7 @@ void *set_allbutton_light_colormode( void *ptr ) waitfor_queue2empty(); // Just clear current message before waiting for next, since the test in the do can't distinguish // as both messages end in "~*" - waitForMessage(threadCtrl->aq_data, NULL, 1); + waitForMessage(threadCtrl->aqdata, NULL, 1); i++; } while (i <= LIGHT_COLOR_OPTIONS); @@ -540,7 +540,7 @@ void *set_allbutton_light_colormode( void *ptr ) LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive color light mode message for '%s'\n",use_current_mode?"light program":mode_name); } else { // Set before we are called. - //updateButtonLightProgram(aq_data, val, btn); + //updateButtonLightProgram(aqdata, val, btn); } cleanAndTerminateThread(threadCtrl); @@ -555,7 +555,7 @@ void *set_allbutton_light_programmode( void *ptr ) int i; struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_LIGHTPROGRAM_MODE); @@ -570,13 +570,13 @@ void *set_allbutton_light_programmode( void *ptr ) bool useProgAdvance = _aqconfig_.light_programming_advance_mode; - if (btn < 0 || btn >= aq_data->total_buttons ) { + if (btn < 0 || btn >= aqdata->total_buttons ) { LOG(ALLB_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } - aqkey *button = &aq_data->aqbuttons[btn]; + aqkey *button = &aqdata->aqbuttons[btn]; unsigned char code = button->code; // Simply turn the light off if value is 0 @@ -649,12 +649,12 @@ void *set_allbutton_light_programmode( void *ptr ) waitfor_queue2empty(); LOG(ALLB_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "ON", val); send_cmd(code); - waitForButtonState(aq_data, button, ON, 2); + waitForButtonState(aqdata, button, ON, 2); delay(dt * seconds); waitfor_queue2empty(); LOG(ALLB_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "OFF", val); send_cmd(code); - waitForButtonState(aq_data, button, OFF, 2); + waitForButtonState(aqdata, button, OFF, 2); delay(dt * seconds); } LOG(ALLB_LOG, LOG_INFO, "Finished - Light Programming button press number %d - %s of %d\n", i, "ON", val); @@ -662,13 +662,13 @@ void *set_allbutton_light_programmode( void *ptr ) //waitfor_queue2empty(); longwaitfor_queue2empty(); } - //waitForButtonState(aq_data, &aq_data->aqbuttons[btn], ON, 2); + //waitForButtonState(aqdata, &aqdata->aqbuttons[btn], ON, 2); // set before we are called - //updateButtonLightProgram(aq_data, val, btn); + //updateButtonLightProgram(aqdata, val, btn); // Save value if needed - updateLightProgram(aq_data, final_mode, (clight_detail *)button->special_mask_ptr ); + updateLightProgram(aqdata, final_mode, (clight_detail *)button->special_mask_ptr ); cleanAndTerminateThread(threadCtrl); @@ -681,7 +681,7 @@ void *set_allbutton_light_dimmer( void *ptr ) int i; struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_LIGHTDIMMER); @@ -693,13 +693,13 @@ void *set_allbutton_light_dimmer( void *ptr ) int typ = atoi(&buf[10]); bool use_current_mode = false; - if (btn < 0 || btn >= aq_data->total_buttons ) { + if (btn < 0 || btn >= aqdata->total_buttons ) { LOG(ALLB_LOG, LOG_ERR, "Can't program light dimmer on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } - aqkey *button = &aq_data->aqbuttons[btn]; + aqkey *button = &aqdata->aqbuttons[btn]; unsigned char code = button->code; */ @@ -747,7 +747,7 @@ void *set_allbutton_light_dimmer( void *ptr ) LOG(ALLB_LOG, LOG_INFO, "Light Programming Initial state on, turning off\n"); send_cmd(button->code); waitfor_queue2empty(); - if ( !waitForMessage(threadCtrl->aq_data, "OFF", 5)) // Message like 'Aux3 Off' + if ( !waitForMessage(threadCtrl->aqdata, "OFF", 5)) // Message like 'Aux3 Off' LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive OFF message\n"); } @@ -760,7 +760,7 @@ void *set_allbutton_light_dimmer( void *ptr ) do{ LOG(ALLB_LOG, LOG_INFO,"Light program wait for message\n"); - if ( !waitForMessage(threadCtrl->aq_data, "~*", waitCounter)) + if ( !waitForMessage(threadCtrl->aqdata, "~*", waitCounter)) LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive light mode message\n"); // Wait for less messages after first try. We get a lot of repeat messages before the one we need. @@ -768,22 +768,22 @@ void *set_allbutton_light_dimmer( void *ptr ) if (useDefaultIfValid) { // If 0 in last message then it's NOT valid and we will change to 100% (5 char =0, 6 char=%) - if (aq_data->last_message[0] == '0' && aq_data->last_message[1] == '%' ) { + if (aqdata->last_message[0] == '0' && aqdata->last_message[1] == '%' ) { //printf("******** Light stuck ************\n"); LOG(ALLB_LOG, LOG_WARNING, "Light Programming detected Jandy panel light%% bug, re-setting to %d%%\n",val * 25); useDefaultIfValid=false; } else { - // printf("******** Light good ************ '%c' '%c'\n",aq_data->last_message[0],aq_data->last_message[1]); + // printf("******** Light good ************ '%c' '%c'\n",aqdata->last_message[0],aqdata->last_message[1]); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; } } else if (use_current_mode) { - LOG(ALLB_LOG, LOG_INFO, "Light Programming using mode %s\n",aq_data->last_message); + LOG(ALLB_LOG, LOG_INFO, "Light Programming using mode %s\n",aqdata->last_message); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; - } else if (strncasecmp(aq_data->last_message, mode_name, strlen(mode_name)) == 0) { + } else if (strncasecmp(aqdata->last_message, mode_name, strlen(mode_name)) == 0) { LOG(ALLB_LOG, LOG_INFO, "Light Programming found mode %s\n",mode_name); send_cmd(KEY_ENTER); waitfor_queue2empty(); @@ -794,7 +794,7 @@ void *set_allbutton_light_dimmer( void *ptr ) waitfor_queue2empty(); // Just clear current message before waiting for next, since the test in the do can't distinguish // as both messages end in "~*" - waitForMessage(threadCtrl->aq_data, NULL, 1); + waitForMessage(threadCtrl->aqdata, NULL, 1); i++; } while (i <= 8); @@ -805,9 +805,9 @@ void *set_allbutton_light_dimmer( void *ptr ) // update status before we are exit. if (light->lightType == LC_DIMMER2 ) { // value or Dimmer2 is the actual %, while Dimmer & colorlight is an index into an array - updateLightProgram(aq_data, val * 25, light); + updateLightProgram(aqdata, val * 25, light); } else { - updateLightProgram(aq_data, val, light); + updateLightProgram(aqdata, val, light); } } @@ -826,7 +826,7 @@ void *set_allbutton_pool_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *name; char *menu_name; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_POOL_HEATER_TEMP); @@ -842,7 +842,7 @@ void *set_allbutton_pool_heater_temps( void *ptr ) val = MEATER_MIN; } */ - val = setpoint_check(POOL_HTR_SETPOINT, val, aq_data); + val = setpoint_check(POOL_HTR_SETPOINT, val, aqdata); // NSF IF in TEMP1 / TEMP2 mode, we need C range of 1 to 40 is 2 to 40 for TEMP1, 1 to 39 TEMP2 if (isSINGLE_DEV_PANEL){ @@ -854,20 +854,20 @@ void *set_allbutton_pool_heater_temps( void *ptr ) } LOG(ALLB_LOG, LOG_DEBUG, "Setting pool heater setpoint to %d\n", val); - //setAqualinkTemp(aq_data, "SET TEMP", "SET POOL TEMP", NULL, "POOL", val); + //setAqualinkTemp(aqdata, "SET TEMP", "SET POOL TEMP", NULL, "POOL", val); - if ( select_menu_item(aq_data, "SET TEMP") != true ) { + if ( select_menu_item(aqdata, "SET TEMP") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - //if (select_sub_menu_item(aq_data, "SET POOL TEMP") != true) { - if (select_sub_menu_item(aq_data, menu_name) != true) { + //if (select_sub_menu_item(aqdata, "SET POOL TEMP") != true) { + if (select_sub_menu_item(aqdata, menu_name) != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET POOL TEMP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -877,18 +877,18 @@ void *set_allbutton_pool_heater_temps( void *ptr ) // Need to get pass this message 'TEMP1 MUST BE SET HIGHER THAN TEMP2' // and get this message 'TEMP1 20�C ~*' // Before going to numeric field. - waitForMessage(threadCtrl->aq_data, "MUST BE SET", 5); + waitForMessage(threadCtrl->aqdata, "MUST BE SET", 5); send_cmd(KEY_LEFT); - while (stristr(aq_data->last_message, "MUST BE SET") != NULL) { + while (stristr(aqdata->last_message, "MUST BE SET") != NULL) { delay(500); } } - //setAqualinkNumericField(aq_data, "POOL", val); - setAqualinkNumericField(aq_data, name, val); + //setAqualinkNumericField(aqdata, "POOL", val); + setAqualinkNumericField(aqdata, name, val); // usually miss this message, not sure why, but wait anyway to make sure programming has ended - waitForMessage(threadCtrl->aq_data, "POOL TEMP IS SET TO", 1); + waitForMessage(threadCtrl->aqdata, "POOL TEMP IS SET TO", 1); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -898,7 +898,7 @@ void *set_allbutton_spa_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_SPA_HEATER_TEMP); @@ -911,7 +911,7 @@ void *set_allbutton_spa_heater_temps( void *ptr ) } else if ( val < MEATER_MIN) { val = MEATER_MIN; }*/ - val = setpoint_check(SPA_HTR_SETPOINT, val, aq_data); + val = setpoint_check(SPA_HTR_SETPOINT, val, aqdata); // NSF IF in TEMP1 / TEMP2 mode, we need C range of 1 to 40 is 2 to 40 for TEMP1, 1 to 39 TEMP2 @@ -925,19 +925,19 @@ void *set_allbutton_spa_heater_temps( void *ptr ) LOG(ALLB_LOG, LOG_DEBUG, "Setting spa heater setpoint to %d\n", val); - //setAqualinkTemp(aq_data, "SET TEMP", "SET SPA TEMP", NULL, "SPA", val); - if ( select_menu_item(aq_data, "SET TEMP") != true ) { + //setAqualinkTemp(aqdata, "SET TEMP", "SET SPA TEMP", NULL, "SPA", val); + if ( select_menu_item(aqdata, "SET TEMP") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - //if (select_sub_menu_item(aq_data, "SET SPA TEMP") != true) { - if (select_sub_menu_item(aq_data, menu_name) != true) { + //if (select_sub_menu_item(aqdata, "SET SPA TEMP") != true) { + if (select_sub_menu_item(aqdata, menu_name) != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET SPA TEMP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -947,18 +947,18 @@ void *set_allbutton_spa_heater_temps( void *ptr ) // Need to get pass this message 'TEMP2 MUST BE SET LOWER THAN TEMP1' // and get this message 'TEMP2 20�C ~*' // Before going to numeric field. - waitForMessage(threadCtrl->aq_data, "MUST BE SET", 5); + waitForMessage(threadCtrl->aqdata, "MUST BE SET", 5); send_cmd(KEY_LEFT); - while (stristr(aq_data->last_message, "MUST BE SET") != NULL) { + while (stristr(aqdata->last_message, "MUST BE SET") != NULL) { delay(500); } } - //setAqualinkNumericField(aq_data, "SPA", val); - setAqualinkNumericField(aq_data, name, val); + //setAqualinkNumericField(aqdata, "SPA", val); + setAqualinkNumericField(aqdata, name, val); // usually miss this message, not sure why, but wait anyway to make sure programming has ended - waitForMessage(threadCtrl->aq_data, "SPA TEMP IS SET TO", 1); + waitForMessage(threadCtrl->aqdata, "SPA TEMP IS SET TO", 1); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -969,7 +969,7 @@ void *set_allbutton_freeze_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_FRZ_PROTECTION_TEMP); @@ -981,38 +981,38 @@ void *set_allbutton_freeze_heater_temps( void *ptr ) val = FREEZE_PT_MIN; } */ - val = setpoint_check(FREEZE_SETPOINT, val, aq_data); + val = setpoint_check(FREEZE_SETPOINT, val, aqdata); LOG(ALLB_LOG, LOG_DEBUG, "Setting sfreeze protection to %d\n", val); - //setAqualinkTemp(aq_data, "SYSTEM SETUP", "FRZ PROTECT", "TEMP SETTING", "FRZ", val); - if ( select_menu_item(aq_data, "SYSTEM SETUP") != true ) { + //setAqualinkTemp(aqdata, "SYSTEM SETUP", "FRZ PROTECT", "TEMP SETTING", "FRZ", val); + if ( select_menu_item(aqdata, "SYSTEM SETUP") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SYSTEM SETUP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { + if (select_sub_menu_item(aqdata, "FRZ PROTECT") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - if (select_sub_menu_item(aq_data, "TEMP SETTING") != true) { + if (select_sub_menu_item(aqdata, "TEMP SETTING") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select TEMP SETTING menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - setAqualinkNumericField(aq_data, "FRZ", val); + setAqualinkNumericField(aqdata, "FRZ", val); - waitForMessage(threadCtrl->aq_data, "FREEZE PROTECTION IS SET TO", 3); + waitForMessage(threadCtrl->aqdata, "FREEZE PROTECTION IS SET TO", 3); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -1023,7 +1023,7 @@ void *set_allbutton_time( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_TIME); //LOG(ALLB_LOG, LOG_NOTICE, "Setting time on aqualink\n"); @@ -1050,20 +1050,20 @@ void *set_allbutton_time( void *ptr ) LOG(ALLB_LOG, LOG_DEBUG, "Setting time to %d/%d/%d %d:%d\n", result->tm_mon + 1, result->tm_mday, result->tm_year + 1900, result->tm_hour + 1, result->tm_min); - if ( select_menu_item(aq_data, "SET TIME") != true ) { + if ( select_menu_item(aqdata, "SET TIME") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TIME menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - setAqualinkNumericField(aq_data, "YEAR", result->tm_year + 1900); - setAqualinkNumericField(aq_data, "MONTH", result->tm_mon + 1); - setAqualinkNumericField(aq_data, "DAY", result->tm_mday); - //setAqualinkNumericFieldExtra(aq_data, "HOUR", 11, "PM"); - select_sub_menu_item(aq_data, hour); // This will keep looping until it finds the right message - setAqualinkNumericField(aq_data, "MINUTE", result->tm_min); + setAqualinkNumericField(aqdata, "YEAR", result->tm_year + 1900); + setAqualinkNumericField(aqdata, "MONTH", result->tm_mon + 1); + setAqualinkNumericField(aqdata, "DAY", result->tm_mday); + //setAqualinkNumericFieldExtra(aqdata, "HOUR", 11, "PM"); + select_sub_menu_item(aqdata, hour); // This will keep looping until it finds the right message + setAqualinkNumericField(aqdata, "MINUTE", result->tm_min); send_cmd(KEY_ENTER); @@ -1077,27 +1077,27 @@ void *get_allbutton_diag_model( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_DIAGNOSTICS_MODEL); - if ( select_menu_item(aq_data, "SYSTEM SETUP") != true ) { + if ( select_menu_item(aqdata, "SYSTEM SETUP") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select HELP menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - if (select_sub_menu_item(aq_data, "DIAGNOSTICS") != true) { + if (select_sub_menu_item(aqdata, "DIAGNOSTICS") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select DIAGNOSTICS menu\n"); - LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aqdata->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - waitForMessage(aq_data, NULL, 8); // Receive 8 messages + waitForMessage(aqdata, NULL, 8); // Receive 8 messages //8157 REV MMM | BATTERY OK | Cal: -27 0 6 | CONTROL PANEL #1 | CONTROL PANEL #3 | WATER SENSOR OK | AIR SENSOR OK | SOLAR SENSOR OPENED cleanAndTerminateThread(threadCtrl); @@ -1110,12 +1110,12 @@ void *get_allbutton_pool_spa_heater_temps( void *ptr ) //LOG(ALLB_LOG, LOG_DEBUG, "Could not select TEMP SET menu\n"); struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_POOL_SPA_HEATER_TEMPS); //LOG(ALLB_LOG, LOG_NOTICE, "Getting pool & spa heat setpoints from aqualink\n"); - if ( select_menu_item(aq_data, "REVIEW") != true ) { + if ( select_menu_item(aqdata, "REVIEW") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); LOG(ALLB_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); cancel_menu(); @@ -1123,7 +1123,7 @@ void *get_allbutton_pool_spa_heater_temps( void *ptr ) return ptr; } - if (select_sub_menu_item(aq_data, "TEMP SET") != true) { + if (select_sub_menu_item(aqdata, "TEMP SET") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select TEMP SET menu\n"); LOG(ALLB_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); cancel_menu(); @@ -1133,9 +1133,9 @@ void *get_allbutton_pool_spa_heater_temps( void *ptr ) // Should receive 'POOL TEMP IS SET TO xx' then 'SPA TEMP IS SET TO xx' then 'MAINTAIN TEMP IS (OFF|ON)' // wait for the last message - waitForMessage(threadCtrl->aq_data, "MAINTAIN TEMP IS", 5); + waitForMessage(threadCtrl->aqdata, "MAINTAIN TEMP IS", 5); - //cancel_menu(threadCtrl->aq_data); + //cancel_menu(threadCtrl->aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -1146,12 +1146,12 @@ void *get_allbutton_freeze_protect_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_FREEZE_PROTECT_TEMP); //LOG(ALLB_LOG, LOG_NOTICE, "Getting freeze protection setpoints\n"); - if ( select_menu_item(aq_data, "REVIEW") != true ) { + if ( select_menu_item(aqdata, "REVIEW") != true ) { LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); LOG(ALLB_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); cancel_menu(); @@ -1159,7 +1159,7 @@ void *get_allbutton_freeze_protect_temp( void *ptr ) return ptr; } - if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { + if (select_sub_menu_item(aqdata, "FRZ PROTECT") != true) { LOG(ALLB_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); LOG(ALLB_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); cancel_menu(); @@ -1167,43 +1167,43 @@ void *get_allbutton_freeze_protect_temp( void *ptr ) return ptr; } - waitForMessage(aq_data, "FREEZE PROTECTION IS SET TO", 6); // Changed from 3 to wait for multiple items to be listed - //cancel_menu(aq_data); + waitForMessage(aqdata, "FREEZE PROTECTION IS SET TO", 6); // Changed from 3 to wait for multiple items to be listed + //cancel_menu(aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed return ptr; } -bool get_aqualink_program_for_button(struct aqualinkdata *aq_data, unsigned char cmd) +bool get_aqualink_program_for_button(struct aqualinkdata *aqdata, unsigned char cmd) { int rtnStringsWait = 7; - if (! waitForMessage(aq_data, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", rtnStringsWait)) + if (! waitForMessage(aqdata, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", rtnStringsWait)) return false; LOG(ALLB_LOG, LOG_DEBUG, "Send key '%d'\n",cmd); send_cmd(cmd); - return waitForEitherMessage(aq_data, "NOT SET", "TURNS ON", rtnStringsWait); + return waitForEitherMessage(aqdata, "NOT SET", "TURNS ON", rtnStringsWait); } void *get_allbutton_programs( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char keys[10] = {KEY_PUMP, KEY_SPA, KEY_AUX1, KEY_AUX2, KEY_AUX3, KEY_AUX4, KEY_AUX5}; // KEY_AUX6 & KEY_AUX7 kill programming mode waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_PROGRAMS); - if ( select_menu_item(aq_data, "REVIEW") != true ) { + if ( select_menu_item(aqdata, "REVIEW") != true ) { //LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } - if (select_sub_menu_item(aq_data, "PROGRAMS") != true) { + if (select_sub_menu_item(aqdata, "PROGRAMS") != true) { //LOG(ALLB_LOG, LOG_WARNING, "Could not select PROGRAMS menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); @@ -1214,9 +1214,9 @@ void *get_allbutton_programs( void *ptr ) for (i=0; i < strlen(keys); i++) { //LOG(ALLB_LOG, LOG_DEBUG, "**** START program for key in loop %d\n",i); - if (! get_aqualink_program_for_button(aq_data, keys[i])) { + if (! get_aqualink_program_for_button(aqdata, keys[i])) { //LOG(ALLB_LOG, LOG_DEBUG, "**** Didn't find program for key in loop %d\n",i); - //cancel_menu(aq_data); + //cancel_menu(aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -1224,7 +1224,7 @@ void *get_allbutton_programs( void *ptr ) } - if (waitForMessage(aq_data, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", 6)) { + if (waitForMessage(aqdata, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", 6)) { //LOG(ALLB_LOG, LOG_DEBUG, "Send key ENTER\n"); send_cmd(KEY_ENTER); } else { @@ -1232,7 +1232,7 @@ void *get_allbutton_programs( void *ptr ) cancel_menu(); } - //cancel_menu(aq_data); + //cancel_menu(aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -1240,7 +1240,7 @@ void *get_allbutton_programs( void *ptr ) } /* -void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) +void send_cmd(unsigned char cmd, struct aqualinkdata *aqdata) { push_aq_cmd(cmd); LOG(ALLB_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", cmd); @@ -1309,12 +1309,12 @@ void cancel_menu() * added functionality, if start of string is ^ use that as must start with in comparison */ -bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived) +bool waitForEitherMessage(struct aqualinkdata *aqdata, char* message1, char* message2, int numMessageReceived) { //LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); waitfor_queue2empty(); // MAke sure the last command was sent int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); char* msgS1 = ""; char* msgS2 = ""; char* ptr = NULL; @@ -1335,56 +1335,56 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me while( ++i <= numMessageReceived) { - LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' OR '%s' received message1 '%s'\n",i,numMessageReceived,message1,message2,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' OR '%s' received message1 '%s'\n",i,numMessageReceived,message1,message2,aqdata->last_message); if (message1 != NULL) { - ptr = stristr(aq_data->last_message, msgS1); + ptr = stristr(aqdata->last_message, msgS1); if (ptr != NULL) { // match LOG(ALLB_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS1); if (msgS1 == message1) // match & don't care if first char break; - else if (ptr == aq_data->last_message) // match & do care if first char + else if (ptr == aqdata->last_message) // match & do care if first char break; } } if (message2 != NULL) { - ptr = stristr(aq_data->last_message, msgS2); + ptr = stristr(aqdata->last_message, msgS2); if (ptr != NULL) { // match LOG(ALLB_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS2); if (msgS2 == message2) // match & don't care if first char break; - else if (ptr == aq_data->last_message) // match & do care if first char + else if (ptr == aqdata->last_message) // match & do care if first char break; } } - //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message1 '%s'\n",message1,aq_data->last_message); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message1 '%s'\n",i,numMessageReceived,message1,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message1 '%s'\n",message1,aqdata->last_message); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message1 '%s'\n",i,numMessageReceived,message1,aqdata->last_message); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (message1 != NULL && message2 != NULL && ptr == NULL) { //logmessage1(LOG_ERR, "Could not select MENU of Aqualink control panel\n"); LOG(ALLB_LOG, LOG_ERR, "Did not find '%s'\n",message1); return false; } - LOG(ALLB_LOG, LOG_DEBUG, "Found message1 '%s' or '%s' in '%s'\n",message1,message2,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Found message1 '%s' or '%s' in '%s'\n",message1,message2,aqdata->last_message); return true; } -bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived) +bool waitForMessage(struct aqualinkdata *aqdata, char* message, int numMessageReceived) { LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d\n",message,numMessageReceived); // NSF Need to come back to this, as it stops on test enviornment but not real panel, so must be speed related. //waitfor_queue2empty(); // MAke sure the last command was sent int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); char* msgS; char* ptr = NULL; @@ -1398,43 +1398,43 @@ bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageR while( ++i <= numMessageReceived) { if (message != NULL) - LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aqdata->last_message); else - LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d waiting for next message, last message received '%s'\n",i,numMessageReceived,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d waiting for next message, last message received '%s'\n",i,numMessageReceived,aqdata->last_message); if (message != NULL) { - ptr = stristr(aq_data->last_message, msgS); + ptr = stristr(aqdata->last_message, msgS); if (ptr != NULL) { // match LOG(ALLB_LOG, LOG_DEBUG, "String MATCH\n"); if (msgS == message) // match & don't care if first char break; - else if (ptr == aq_data->last_message) // match & do care if first char + else if (ptr == aqdata->last_message) // match & do care if first char break; } } - //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aqdata->last_message); //LOG(ALLB_LOG, LOG_DEBUG, "*** pthread_cond_wait() sleep\n"); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); //LOG(ALLB_LOG, LOG_DEBUG, "*** pthread_cond_wait() wake\n"); - //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aqdata->last_message); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (message != NULL && ptr == NULL) { //LOG(ALLB_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); LOG(ALLB_LOG, LOG_DEBUG, "did not find '%s'\n",message); return false; } else if (message != NULL) - LOG(ALLB_LOG, LOG_DEBUG, "found message '%s' in '%s'\n",message,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "found message '%s' in '%s'\n",message,aqdata->last_message); else LOG(ALLB_LOG, LOG_DEBUG, "waited for %d message(s)\n",numMessageReceived); return true; } -bool select_menu_item(struct aqualinkdata *aq_data, char* item_string) +bool select_menu_item(struct aqualinkdata *aqdata, char* item_string) { char* expectedMsg = "PRESS ENTER* TO SELECT"; //char* expectedMsg = "PROGRAM"; @@ -1445,7 +1445,7 @@ bool select_menu_item(struct aqualinkdata *aq_data, char* item_string) while (found == false && tries <= 3) { send_cmd(KEY_MENU); - found = waitForMessage(aq_data, expectedMsg, wait_messages); + found = waitForMessage(aqdata, expectedMsg, wait_messages); tries++; } @@ -1453,54 +1453,54 @@ bool select_menu_item(struct aqualinkdata *aq_data, char* item_string) return false; // NSF This isn't needed and seems to cause issue on some controllers. - //send_cmd(KEY_ENTER, aq_data); - //waitForMessage(aq_data, NULL, 1); + //send_cmd(KEY_ENTER, aqdata); + //waitForMessage(aqdata, NULL, 1); - return select_sub_menu_item(aq_data, item_string); + return select_sub_menu_item(aqdata, item_string); } /* -bool select_menu_item(struct aqualinkdata *aq_data, char* item_string) +bool select_menu_item(struct aqualinkdata *aqdata, char* item_string) { char* expectedMsg = "PRESS ENTER* TO SELECT"; int wait_messages = 6; //int i=0; // Select the MENU and wait to get the RS8 respond. - send_cmd(KEY_MENU, aq_data); + send_cmd(KEY_MENU, aqdata); - if (waitForMessage(aq_data, expectedMsg, wait_messages) == false) + if (waitForMessage(aqdata, expectedMsg, wait_messages) == false) return false; - send_cmd(KEY_ENTER, aq_data); - waitForMessage(aq_data, NULL, 1); + send_cmd(KEY_ENTER, aqdata); + waitForMessage(aqdata, NULL, 1); // Blindly wait for next message - //sendCmdWaitForReturn(aq_data, KEY_ENTER); + //sendCmdWaitForReturn(aqdata, KEY_ENTER); // Can't determin the first response //delay(500); - return select_sub_menu_item(aq_data, item_string); + return select_sub_menu_item(aqdata, item_string); } */ -//bool select_sub_menu_item(char* item_string, struct aqualinkdata *aq_data) -bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) +//bool select_sub_menu_item(char* item_string, struct aqualinkdata *aqdata) +bool select_sub_menu_item(struct aqualinkdata *aqdata, char* item_string) { int wait_messages = 28; int i=0; waitfor_queue2empty(); - while( (stristr(aq_data->last_message, item_string) == NULL) && ( i++ < wait_messages) ) + while( (stristr(aqdata->last_message, item_string) == NULL) && ( i++ < wait_messages) ) { - LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for '%s' received message '%s'\n",i,wait_messages,item_string,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for '%s' received message '%s'\n",i,wait_messages,item_string,aqdata->last_message); send_cmd(KEY_RIGHT); waitfor_queue2empty(); // ADDED BACK MAY 2023 setting time warked better - //waitForMessage(aq_data, NULL, 1); - waitForMessage(aq_data, item_string, 1); + //waitForMessage(aqdata, NULL, 1); + waitForMessage(aqdata, item_string, 1); } - if (stristr(aq_data->last_message, item_string) == NULL) { + if (stristr(aqdata->last_message, item_string) == NULL) { LOG(ALLB_LOG, LOG_ERR, "Could not find menu item '%s'\n",item_string); return false; } @@ -1512,10 +1512,10 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) send_cmd(KEY_ENTER); - waitForMessage(aq_data, NULL, 1); + waitForMessage(aqdata, NULL, 1); - //sendCmdWaitForReturn(aq_data, KEY_ENTER); + //sendCmdWaitForReturn(aqdata, KEY_ENTER); return true; @@ -1523,11 +1523,11 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) // NSF Need to test this, then use it for the color change mode. -bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate state, int numMessageReceived) +bool waitForButtonState(struct aqualinkdata *aqdata, aqkey* button, aqledstate state, int numMessageReceived) { //LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { @@ -1538,12 +1538,12 @@ bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate break; } - //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aqdata->last_message); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aqdata->last_message); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (numMessageReceived >= i) { //LOG(ALLB_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); diff --git a/source/aq_panel.c b/source/aq_panel.c index 9fde941..5bcb5bc 100644 --- a/source/aq_panel.c +++ b/source/aq_panel.c @@ -116,6 +116,13 @@ const char* find_rev_chars(const char *str, int length, int *out_len) { while (isalpha(str[*out_len]) || isdigit(str[*out_len]) || str[*out_len] == '.') *out_len+=1; *out_len = *out_len - i; return str + i; + } else if ( str[i] == 'P' && str[i+1] == 'D' && str[i+2] == 'A' && str[i+3] == ':') { + i=i+4; + while (str[i] == ':' || str[i] == ' ') i++; + *out_len=i; + while (isdigit(str[*out_len]) || str[*out_len] == '.') *out_len+=1; + *out_len = *out_len - i; + return str + i; } } @@ -179,24 +186,41 @@ pull board CPU, revision & panel string from strings like 'CPU p/n: B0029221' '. RS-6 Combo' '. PD-8 Only' + + ' PDA-PS4 Combo ' + ' PPD: PDA 1.2 ' + + PDA: 7.1.0 + PDA-P4 Only */ + uint8_t setPanelInformationFromPanelMsg(struct aqualinkdata *aqdata, const char *input, uint8_t type, emulation_type source) { - const char *rev_pos = NULL; + //const char *rev_pos = NULL; + char *rev_pos = NULL; uint8_t rtn = 0; //printf("Calculate panel from %s\n",input); //const char *rev_pos = strstr(input, "REV"); // Find the position of "REV" const char *sp; int length = 0; + LOG(PANL_LOG, LOG_DEBUG, "Decoding string '%s'\n",input); + if (isMASK_SET(type, PANEL_REV)) { if (aqdata->panel_rev[0] == '\0') { - if ( (rev_pos = strstr(input, "REV")) != NULL) { // Find the position of "REV" - length = 0; - sp = find_rev_chars(rev_pos, strlen(input) - (rev_pos - input), &length); - if (length>0 && sp != NULL) { + // RS panels use REV Yg, some newer PDA panels use PDA: 7.x.x + if ( (rev_pos = strstr(input, "REV")) == NULL) { // Find the position of "REV" + rev_pos = strstr(input, "PDA"); // Find the position of "PDA:" + _aqconfig_.paneltype_mask |= RSP_PDA; // Set PDA type so we don't confuse versions + _aqconfig_.paneltype_mask &= ~RSP_RS; + } + if ( rev_pos != NULL) { // If found Find the position of "REV" + length = 0; + sp = find_rev_chars(rev_pos, strlen(input) - (rev_pos - input), &length); + + if (length>0 && sp != NULL) { strncpy(aqdata->panel_rev, sp, length); aqdata->panel_rev[length] = '\0'; setMASK(rtn, PANEL_REV); @@ -209,12 +233,12 @@ uint8_t setPanelInformationFromPanelMsg(struct aqualinkdata *aqdata, const char } else { checkPanelConfig(aqdata); } - } else { - //printf("Failed to find REV, length\n"); - } - } else { - //printf("Failed to find REV, null\n"); - } + } else { + //printf("Failed to find rev or version #\n"); + } + } else { + //printf("Failed to find REV string, null\n"); + } } else { // Already set } @@ -253,14 +277,24 @@ uint8_t setPanelInformationFromPanelMsg(struct aqualinkdata *aqdata, const char break; } } + + if ( sp != NULL && *sp == 'P' ){ + // If PDA make sure to search for - as we can get 'PDA: 7.1.0' and 'PDA-P4 Only' (need to ignore version) + if ( strstr(input, "-") == NULL ) {sp = NULL;} + } + if (sp != NULL) { - // Strip trailing whitespace + // Strip trailing whitespace for(length=strlen(sp)-1; isspace(sp[length]); length--); length++; strncpy(aqdata->panel_string, sp, length); aqdata->panel_string[length] = '\0'; setMASK(rtn,PANEL_STRING); LOG(PANL_LOG, LOG_NOTICE, "Panel %s from %s\n",aqdata->panel_string,getJandyDeviceName(source)); + if (source == SIM_NONE) { + // We pass SIM_NONE when we are in auto_config mode,so re-set the actual panel size + setPanelByName(aqdata, aqdata->panel_string); + } } else { // ERROR not in string. } @@ -277,7 +311,11 @@ uint16_t setPanelSupport(struct aqualinkdata *aqdata) { if (! isalpha(aqdata->panel_rev[0])) { - LOG(PANL_LOG,LOG_WARNING, "Panel revision is not understood '%s', please report this issue", aqdata->panel_rev); + if (isPDA_PANEL) { + LOG(PANL_LOG,LOG_NOTICE, "PDA Panel revision '%s' unknown support options\n", aqdata->panel_rev); + } else { + LOG(PANL_LOG,LOG_WARNING, "Panel revision is not understood '%s', please report this issue\n", aqdata->panel_rev); + } } // Rev >= F Dimmer. But need serial protocol so set to I @@ -623,10 +661,13 @@ void setPanelByName(struct aqualinkdata *aqdata, const char *str) size = atoi(&str[3]); } else if (str[0] == 'P' && str[1] == 'D') { // PDA Panel rs = false; + //printf("Char at 0=%c 1=%c 2=%c 3=%c 4=%c 5=%d 6=%c\n", str[0], str[1], str[2], str[3], str[4], str[5], str[6]); if (str[2] == '-' || str[2] == ' ') // Account for PD-8 size = atoi(&str[3]); - if (str[3] == '-' && str[4] == 'P') // PDA-PS6 Combo + else if (str[3] == '-' && str[4] == 'P' && str[5] == 'S') // PDA-PS4 Combo size = atoi(&str[6]); + else if (str[3] == '-' && str[4] == 'P') // PDA-P6 Only + size = atoi(&str[5]); else // Account for PDA-8 size = atoi(&str[4]); } else { diff --git a/source/aq_programmer.c b/source/aq_programmer.c index 128f655..91f544b 100644 --- a/source/aq_programmer.c +++ b/source/aq_programmer.c @@ -48,7 +48,7 @@ #include "timespec_subtract.h" #endif -void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride); +void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aqdata, bool allowOveride); // Lookup table for programming function to protocal we will use for programming panel @@ -245,7 +245,7 @@ int setpoint_check(int type, int value, struct aqualinkdata *aqdata) Figure out the fastest way in get all needed startup data depending on what protocols are available and what's just called us */ -void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data) +void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aqdata) { LOG(PROG_LOG, LOG_INFO, "Initial setup call from %s with RSSA=%s ONETouch=%s IAQTouch=%s ExtendedProgramming=%s\n", (source_type == ALLBUTTON)?"AllButton":((source_type == RSSADAPTER)?"RSSA":((source_type == ONETOUCH)?"OneTouch":((source_type == IAQTOUCH)?"IAQTouch":"PDA"))), @@ -258,78 +258,78 @@ void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_dat if (isRSSA_ENABLED && isEXTP_ENABLED == true) { // serial adapter enabled and extended programming if (source_type == RSSADAPTER) { - _aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aq_data, false); + _aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aqdata, false); } else if (source_type == ONETOUCH && isEXTP_ENABLED) { - //_aq_programmer(AQ_GET_ONETOUCH_FREEZEPROTECT, NULL, aq_data, false); // Add back and remove below once tested and working - //_aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aq_data, false); + //_aq_programmer(AQ_GET_ONETOUCH_FREEZEPROTECT, NULL, aqdata, false); // Add back and remove below once tested and working + //_aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aqdata, false); } else if (source_type == IAQTOUCH && isEXTP_ENABLED) { - //_aq_programmer(AQ_GET_IAQTOUCH_FREEZEPROTECT, NULL, aq_data, false); // Add back and remove below once tested and working - //_aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data, false); // This get's freeze & heaters, we should just get freeze if isRSSA_ENABLED + //_aq_programmer(AQ_GET_IAQTOUCH_FREEZEPROTECT, NULL, aqdata, false); // Add back and remove below once tested and working + //_aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aqdata, false); // This get's freeze & heaters, we should just get freeze if isRSSA_ENABLED if (ENABLE_CHILLER) { // Need to get setpoints for chiller. - _aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data, false); + _aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aqdata, false); } } else if (source_type == ALLBUTTON) { - _aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data, false); // This is still quicker that IAQ or ONE Touch protocols at the moment. + _aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aqdata, false); // This is still quicker that IAQ or ONE Touch protocols at the moment. if (_aqconfig_.use_panel_aux_labels) { - _aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false); + _aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata, false); } } } else if (isRSSA_ENABLED && isEXTP_ENABLED == false) { // serial adapter enabled with no extended programming if (source_type == RSSADAPTER) { - _aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aq_data, false); + _aq_programmer(AQ_GET_RSSADAPTER_SETPOINTS, NULL, aqdata, false); } else if (source_type == ALLBUTTON) { - _aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data, false); + _aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aqdata, false); if (_aqconfig_.use_panel_aux_labels) { - _aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false); + _aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata, false); } } } else if (!isRSSA_ENABLED && isEXTP_ENABLED && isONET_ENABLED) { // One touch extended and no serial adapter if (source_type == ONETOUCH) { - _aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aq_data, false); + _aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aqdata, false); } else if (source_type == ALLBUTTON) { if (_aqconfig_.use_panel_aux_labels) { - _aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false); + _aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata, false); } } } else if (!isRSSA_ENABLED && isEXTP_ENABLED && isIAQT_ENABLED) { // IAQ touch extended and no serial adapter if (source_type == IAQTOUCH) { - _aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data, false); + _aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aqdata, false); } else if (source_type == ALLBUTTON) { if (_aqconfig_.use_panel_aux_labels) { - _aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data, false); + _aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata, false); } } #ifdef AQ_PDA } else if ( isPDA_PANEL && source_type == AQUAPDA) { - aq_programmer(AQ_PDA_INIT, NULL, aq_data); + aq_programmer(AQ_PDA_INIT, NULL, aqdata); } else if ( isPDA_PANEL && source_type == IAQTOUCH) { - //aq_programmer(AQ_PDA_INIT, NULL, aq_data); + //aq_programmer(AQ_PDA_INIT, NULL, aqdata); if (_aqconfig_.use_panel_aux_labels) { - aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data); + aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata); } - aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data); + aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aqdata); #endif } else { // Must be all button only - aq_programmer(AQ_GET_POOL_SPA_HEATER_TEMPS, NULL, aq_data); - aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data); + aq_programmer(AQ_GET_POOL_SPA_HEATER_TEMPS, NULL, aqdata); + aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aqdata); if (_aqconfig_.use_panel_aux_labels) { - aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data); + aq_programmer(AQ_GET_AUX_LABELS, NULL, aqdata); } } } -bool in_light_programming_mode(struct aqualinkdata *aq_data) +bool in_light_programming_mode(struct aqualinkdata *aqdata) { - if ( ( aq_data->active_thread.thread_id != 0 ) && - ( aq_data->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE || - aq_data->active_thread.ptype == AQ_SET_LIGHTCOLOR_MODE || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE) + if ( ( aqdata->active_thread.thread_id != 0 ) && + ( aqdata->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE || + aqdata->active_thread.ptype == AQ_SET_LIGHTCOLOR_MODE || + aqdata->active_thread.ptype == AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE) ) { return true; } @@ -337,15 +337,15 @@ bool in_light_programming_mode(struct aqualinkdata *aq_data) return false; } -bool in_swg_programming_mode(struct aqualinkdata *aq_data) +bool in_swg_programming_mode(struct aqualinkdata *aqdata) { - if ( ( aq_data->active_thread.thread_id != 0 ) && - ( aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SWG_PERCENT || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_PERCENT || - aq_data->active_thread.ptype == AQ_SET_SWG_PERCENT || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_BOOST || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_BOOST || - aq_data->active_thread.ptype == AQ_SET_BOOST) + if ( ( aqdata->active_thread.thread_id != 0 ) && + ( aqdata->active_thread.ptype == AQ_SET_ONETOUCH_SWG_PERCENT || + aqdata->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_PERCENT || + aqdata->active_thread.ptype == AQ_SET_SWG_PERCENT || + aqdata->active_thread.ptype == AQ_SET_ONETOUCH_BOOST || + aqdata->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_BOOST || + aqdata->active_thread.ptype == AQ_SET_BOOST) ) { return true; } @@ -353,31 +353,31 @@ bool in_swg_programming_mode(struct aqualinkdata *aq_data) return false; } -bool in_ot_programming_mode(struct aqualinkdata *aq_data) +bool in_ot_programming_mode(struct aqualinkdata *aqdata) { - if ( aq_data->active_thread.thread_id != 0 && - aq_data->active_thread.ptype >= AQP_ONETOUCH_MIN && - aq_data->active_thread.ptype <= AQP_ONETOUCH_MAX) { + if ( aqdata->active_thread.thread_id != 0 && + aqdata->active_thread.ptype >= AQP_ONETOUCH_MIN && + aqdata->active_thread.ptype <= AQP_ONETOUCH_MAX) { return true; } return false; } -bool in_iaqt_programming_mode(struct aqualinkdata *aq_data) +bool in_iaqt_programming_mode(struct aqualinkdata *aqdata) { - if ( aq_data->active_thread.thread_id != 0 && - aq_data->active_thread.ptype >= AQP_IAQTOUCH_MIN && - aq_data->active_thread.ptype <= AQP_IAQTOUCH_MAX) { + if ( aqdata->active_thread.thread_id != 0 && + aqdata->active_thread.ptype >= AQP_IAQTOUCH_MIN && + aqdata->active_thread.ptype <= AQP_IAQTOUCH_MAX) { return true; } return false; } -bool in_allb_programming_mode(struct aqualinkdata *aq_data) +bool in_allb_programming_mode(struct aqualinkdata *aqdata) { - if ( aq_data->active_thread.thread_id != 0 && - aq_data->active_thread.ptype >= AQP_ALLBUTTON_MIN && - aq_data->active_thread.ptype <= AQP_ALLBUTTONL_MAX) { + if ( aqdata->active_thread.thread_id != 0 && + aqdata->active_thread.ptype >= AQP_ALLBUTTON_MIN && + aqdata->active_thread.ptype <= AQP_ALLBUTTONL_MAX) { return true; } return false; @@ -406,66 +406,66 @@ emulation_type get_programming_mode(program_type type) return SIM_NONE; } -emulation_type get_current_programming_mode(struct aqualinkdata *aq_data) +emulation_type get_current_programming_mode(struct aqualinkdata *aqdata) { - if ( !in_programming_mode(aq_data) ) { + if ( !in_programming_mode(aqdata) ) { return SIM_NONE; } - return get_programming_mode(aq_data->active_thread.ptype); + return get_programming_mode(aqdata->active_thread.ptype); } -bool in_programming_mode(struct aqualinkdata *aq_data) +bool in_programming_mode(struct aqualinkdata *aqdata) { - if ( aq_data->active_thread.thread_id != 0 ) { + if ( aqdata->active_thread.thread_id != 0 ) { return true; } return false; } -void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_type) +void kick_aq_program_thread(struct aqualinkdata *aqdata, emulation_type source_type) { - if ( aq_data->active_thread.thread_id != 0 ) { - if ( (source_type == ONETOUCH) && in_ot_programming_mode(aq_data)) + if ( aqdata->active_thread.thread_id != 0 ) { + if ( (source_type == ONETOUCH) && in_ot_programming_mode(aqdata)) { - LOG(ONET_LOG, LOG_DEBUG, "Kicking OneTouch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); - pthread_cond_broadcast(&aq_data->active_thread.thread_cond); + LOG(ONET_LOG, LOG_DEBUG, "Kicking OneTouch thread %d,%p\n",aqdata->active_thread.ptype, aqdata->active_thread.thread_id); + pthread_cond_broadcast(&aqdata->active_thread.thread_cond); } - else if (source_type == IAQTOUCH && in_iaqt_programming_mode(aq_data)) { - LOG(IAQT_LOG, LOG_DEBUG, "Kicking IAQ Touch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); - pthread_cond_broadcast(&aq_data->active_thread.thread_cond); + else if (source_type == IAQTOUCH && in_iaqt_programming_mode(aqdata)) { + LOG(IAQT_LOG, LOG_DEBUG, "Kicking IAQ Touch thread %d,%p\n",aqdata->active_thread.ptype, aqdata->active_thread.thread_id); + pthread_cond_broadcast(&aqdata->active_thread.thread_cond); } - else if (source_type == ALLBUTTON && !in_ot_programming_mode(aq_data) && !in_iaqt_programming_mode(aq_data)) { - LOG(PROG_LOG, LOG_DEBUG, "Kicking RS Allbutton thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message); - pthread_cond_broadcast(&aq_data->active_thread.thread_cond); + else if (source_type == ALLBUTTON && !in_ot_programming_mode(aqdata) && !in_iaqt_programming_mode(aqdata)) { + LOG(PROG_LOG, LOG_DEBUG, "Kicking RS Allbutton thread %d,%p message '%s'\n",aqdata->active_thread.ptype, aqdata->active_thread.thread_id,aqdata->last_message); + pthread_cond_broadcast(&aqdata->active_thread.thread_cond); } #ifdef AQ_PDA - else if (source_type == AQUAPDA && !in_ot_programming_mode(aq_data)) { - LOG(PDA_LOG, LOG_DEBUG, "Kicking PDA thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); - pthread_cond_broadcast(&aq_data->active_thread.thread_cond); + else if (source_type == AQUAPDA && !in_ot_programming_mode(aqdata)) { + LOG(PDA_LOG, LOG_DEBUG, "Kicking PDA thread %d,%p\n",aqdata->active_thread.ptype, aqdata->active_thread.thread_id); + pthread_cond_broadcast(&aqdata->active_thread.thread_cond); } #endif } } -void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, int alt_value, struct aqualinkdata *aq_data, bool allowOveride); +void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, int alt_value, struct aqualinkdata *aqdata, bool allowOveride); -void aq_program(program_type r_type, aqkey *button, int value, int alt_value, struct aqualinkdata *aq_data){ - _aq_programmer_(r_type, NULL, button, value, alt_value, aq_data, true); +void aq_program(program_type r_type, aqkey *button, int value, int alt_value, struct aqualinkdata *aqdata){ + _aq_programmer_(r_type, NULL, button, value, alt_value, aqdata, true); } -void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data){ - _aq_programmer(r_type, args, aq_data, true); +void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aqdata){ + _aq_programmer(r_type, args, aqdata, true); } -void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride) +void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aqdata, bool allowOveride) { - _aq_programmer_(r_type, args, NULL, -1, -1, aq_data, allowOveride); + _aq_programmer_(r_type, args, NULL, -1, -1, aqdata, allowOveride); } -void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, int alt_value, struct aqualinkdata *aq_data, bool allowOveride) +void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, int alt_value, struct aqualinkdata *aqdata, bool allowOveride) { struct programmingThreadCtrl *programmingthread = malloc(sizeof(struct programmingThreadCtrl)); @@ -654,7 +654,7 @@ void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, LOG(PROG_LOG, LOG_NOTICE, "Starting programming thread '%s'\n",ptypeName(type)); - programmingthread->aq_data = aq_data; + programmingthread->aqdata = aqdata; programmingthread->thread_id = 0; //programmingthread->thread_args = args; if (args != NULL /*&& type != AQ_SEND_CMD*/) @@ -671,19 +671,19 @@ void _aq_programmer_(program_type r_type, char *args, aqkey *button, int value, return; // No need to create this as thread. break; case AQ_SET_RSSADAPTER_POOL_HEATER_TEMP: - set_aqualink_rssadapter_pool_setpoint(args, aq_data); + set_aqualink_rssadapter_pool_setpoint(args, aqdata); return; // No need to create this as thread. break; case AQ_SET_RSSADAPTER_SPA_HEATER_TEMP: - set_aqualink_rssadapter_spa_setpoint(args, aq_data); + set_aqualink_rssadapter_spa_setpoint(args, aqdata); return; // No need to create this as thread. break; case AQ_ADD_RSSADAPTER_POOL_HEATER_TEMP: - increase_aqualink_rssadapter_pool_setpoint(args, aq_data); + increase_aqualink_rssadapter_pool_setpoint(args, aqdata); return; // No need to create this as thread. break; case AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP: - increase_aqualink_rssadapter_spa_setpoint(args, aq_data); + increase_aqualink_rssadapter_spa_setpoint(args, aqdata); return; // No need to create this as thread. break; case AQ_SET_IAQLINK_POOL_HEATER_TEMP: @@ -735,63 +735,64 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr pthread_exit(0); } */ - while ( (threadCtrl->aq_data->active_thread.thread_id != 0) && ( i++ <= tries) ) { - //LOG(PROG_LOG, LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id); + while ( (threadCtrl->aqdata->active_thread.thread_id != 0) && ( i++ <= tries) ) { + //LOG(PROG_LOG, LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aqdata->active_thread.thread_id); LOG(PROG_LOG, LOG_DEBUG, "Thread %p (%s) sleeping, waiting for thread %p (%s) to finish\n", &threadCtrl->thread_id, ptypeName(type), - threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype)); + threadCtrl->aqdata->active_thread.thread_id, ptypeName(threadCtrl->aqdata->active_thread.ptype)); sleep(waitTime); } if (i >= tries) { //LOG(PROG_LOG, LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id); LOG(PROG_LOG, LOG_ERR, "Thread (%s) %p timeout waiting for thread (%s) %p to finish\n", - ptypeName(type), &threadCtrl->thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype), - threadCtrl->aq_data->active_thread.thread_id); + ptypeName(type), &threadCtrl->thread_id, ptypeName(threadCtrl->aqdata->active_thread.ptype), + threadCtrl->aqdata->active_thread.thread_id); free(threadCtrl); pthread_exit(0); } // Clear out any messages to the UI. - threadCtrl->aq_data->last_display_message[0] = '\0'; - threadCtrl->aq_data->active_thread.thread_id = &threadCtrl->thread_id; - threadCtrl->aq_data->active_thread.ptype = type; + threadCtrl->aqdata->last_display_message[0] = '\0'; + threadCtrl->aqdata->active_thread.thread_id = &threadCtrl->thread_id; + threadCtrl->aqdata->active_thread.ptype = type; #ifdef AQ_DEBUG - clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->start_active_time); + clock_gettime(CLOCK_REALTIME, &threadCtrl->aqdata->start_active_time); #endif - LOG(PROG_LOG, LOG_INFO, "Programming: %s, %d\n", ptypeName(threadCtrl->aq_data->active_thread.ptype), threadCtrl->aq_data->active_thread.ptype); + LOG(PROG_LOG, LOG_INFO, "Programming: %s, %d\n", ptypeName(threadCtrl->aqdata->active_thread.ptype), threadCtrl->aqdata->active_thread.ptype); LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p is active (%s)\n", - threadCtrl->aq_data->active_thread.ptype, - threadCtrl->aq_data->active_thread.thread_id, - ptypeName(threadCtrl->aq_data->active_thread.ptype)); + threadCtrl->aqdata->active_thread.ptype, + threadCtrl->aqdata->active_thread.thread_id, + ptypeName(threadCtrl->aqdata->active_thread.ptype)); } void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl) { //waitfor_queue2empty(); #ifndef AQ_DEBUG - LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aq_data->active_thread.ptype)); + LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aqdata->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aqdata->active_thread.ptype)); #else struct timespec elapsed; - clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->last_active_time); - timespec_subtract(&elapsed, &threadCtrl->aq_data->last_active_time, &threadCtrl->aq_data->start_active_time); + clock_gettime(CLOCK_REALTIME, &threadCtrl->aqdata->last_active_time); + timespec_subtract(&elapsed, &threadCtrl->aqdata->last_active_time, &threadCtrl->aqdata->start_active_time); LOG(PROG_LOG, LOG_NOTICE, "Thread %d,%p (%s) finished in %d.%03ld sec\n", - threadCtrl->aq_data->active_thread.ptype, - threadCtrl->aq_data->active_thread.thread_id, - ptypeName(threadCtrl->aq_data->active_thread.ptype), + threadCtrl->aqdata->active_thread.ptype, + threadCtrl->aqdata->active_thread.thread_id, + ptypeName(threadCtrl->aqdata->active_thread.ptype), elapsed.tv_sec, elapsed.tv_nsec / 1000000L); #endif // Quick delay to allow for last message to be sent. delay(500); - threadCtrl->aq_data->active_thread.thread_id = 0; - threadCtrl->aq_data->active_thread.ptype = AQP_NULL; + threadCtrl->aqdata->active_thread.thread_id = 0; + threadCtrl->aqdata->active_thread.ptype = AQP_NULL; threadCtrl->thread_id = 0; // Force update, change display message - threadCtrl->aq_data->updated = true; + //threadCtrl->aqdata->is_dirty = true; + SET_DIRTY(threadCtrl->aqdata->is_dirty); free(threadCtrl); pthread_exit(0); } diff --git a/source/aq_programmer.h b/source/aq_programmer.h index fc01e36..3a109f2 100644 --- a/source/aq_programmer.h +++ b/source/aq_programmer.h @@ -171,7 +171,7 @@ struct programmingThreadCtrl { //void *thread_args; struct programmerArgs pArgs; char thread_args[PTHREAD_ARG]; - struct aqualinkdata *aq_data; + struct aqualinkdata *aqdata; }; diff --git a/source/aq_scheduler.c b/source/aq_scheduler.c index 5ec7fd2..7a869ab 100644 --- a/source/aq_scheduler.c +++ b/source/aq_scheduler.c @@ -321,7 +321,7 @@ void get_cron_pump_times() } -bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata *aq_data) +bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata *aqdata) { if (! isAQS_START_PUMP_EVENT_ENABLED) { LOG(SCHD_LOG,LOG_DEBUG, "Event scheduler is not enabled\n"); @@ -356,50 +356,50 @@ bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata // Check event type. switch(type){ case AQS_POWER_ON: - if (scheduledOn && isAQS_POWER_ON_ENABED && aq_data->aqbuttons[0].led->state == OFF) { + if (scheduledOn && isAQS_POWER_ON_ENABED && aqdata->aqbuttons[0].led->state == OFF) { LOG(SCHD_LOG,LOG_INFO, "Powered on, schedule is set for pump running and pump is off, turning pump on\n"); - panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER); + panel_device_request(aqdata, ON_OFF, 0, true, NET_TIMER); } else { //LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule is not set and/or pump is already on, leaving\n"); - LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_POWER_ON_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On")); + LOG(SCHD_LOG,LOG_DEBUG, "Powered on, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_POWER_ON_ENABED?"":"not "),(scheduledOn?"":" not"), (aqdata->aqbuttons[0].led->state ==OFF?"Off":"On")); } break; case AQS_FRZ_PROTECT_OFF: - if (scheduledOn && isAQS_FRZ_PROTECT_OFF_ENABED && aq_data->aqbuttons[0].led->state == OFF) { + if (scheduledOn && isAQS_FRZ_PROTECT_OFF_ENABED && aqdata->aqbuttons[0].led->state == OFF) { LOG(SCHD_LOG,LOG_INFO, "Freeze Protect off, schedule is set for pump running and pump is off, turning pump on\n"); - panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER); + panel_device_request(aqdata, ON_OFF, 0, true, NET_TIMER); } else { //LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule is not set and/or pump is already on, leaving\n"); - LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_FRZ_PROTECT_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On")); + LOG(SCHD_LOG,LOG_DEBUG, "Freeze Protect off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_FRZ_PROTECT_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aqdata->aqbuttons[0].led->state ==OFF?"Off":"On")); } break; case AQS_BOOST_OFF: - if (scheduledOn && isAQS_BOOST_OFF_ENABED && aq_data->aqbuttons[0].led->state == OFF) { + if (scheduledOn && isAQS_BOOST_OFF_ENABED && aqdata->aqbuttons[0].led->state == OFF) { LOG(SCHD_LOG,LOG_INFO, "Boost off, schedule is set for pump running and pump is off, turning pump on\n"); - panel_device_request(aq_data, ON_OFF, 0, true, NET_TIMER); + panel_device_request(aqdata, ON_OFF, 0, true, NET_TIMER); } else { //LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule is not set and/or pump is already on, leaving\n"); - LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_BOOST_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On")); + LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_BOOST_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aqdata->aqbuttons[0].led->state ==OFF?"Off":"On")); } - if (aq_data->boost_linked_device != AQ_UNKNOWN && aq_data->boost_linked_device <= aq_data->total_buttons && aq_data->boost_linked_device >= 0) { - //aq_data->aqbuttons[aq_data->boost_linked_device].code - if (aq_data->aqbuttons[aq_data->boost_linked_device].led->state == OFF) { - panel_device_request(aq_data, ON_OFF, aq_data->boost_linked_device, false, NET_TIMER); - LOG(SCHD_LOG,LOG_INFO, "Boost off, Turing %s off\n",aq_data->aqbuttons[aq_data->boost_linked_device].label); + if (aqdata->boost_linked_device != AQ_UNKNOWN && aqdata->boost_linked_device <= aqdata->total_buttons && aqdata->boost_linked_device >= 0) { + //aqdata->aqbuttons[aqdata->boost_linked_device].code + if (aqdata->aqbuttons[aqdata->boost_linked_device].led->state == OFF) { + panel_device_request(aqdata, ON_OFF, aqdata->boost_linked_device, false, NET_TIMER); + LOG(SCHD_LOG,LOG_INFO, "Boost off, Turing %s off\n",aqdata->aqbuttons[aqdata->boost_linked_device].label); } else { - LOG(SCHD_LOG,LOG_INFO, "Boost off, %s is already off\n",aq_data->aqbuttons[aq_data->boost_linked_device].label); + LOG(SCHD_LOG,LOG_INFO, "Boost off, %s is already off\n",aqdata->aqbuttons[aqdata->boost_linked_device].label); } } break; case AQS_BOOST_ON: - if (aq_data->boost_linked_device != AQ_UNKNOWN && aq_data->boost_linked_device <= aq_data->total_buttons && aq_data->boost_linked_device >= 0) { - //aq_data->aqbuttons[aq_data->boost_linked_device].code - if (aq_data->aqbuttons[aq_data->boost_linked_device].led->state == OFF) { - panel_device_request(aq_data, ON_OFF, aq_data->boost_linked_device, true, NET_TIMER); - LOG(SCHD_LOG,LOG_INFO, "Boost on, Turing %s on\n",aq_data->aqbuttons[aq_data->boost_linked_device].label); + if (aqdata->boost_linked_device != AQ_UNKNOWN && aqdata->boost_linked_device <= aqdata->total_buttons && aqdata->boost_linked_device >= 0) { + //aqdata->aqbuttons[aqdata->boost_linked_device].code + if (aqdata->aqbuttons[aqdata->boost_linked_device].led->state == OFF) { + panel_device_request(aqdata, ON_OFF, aqdata->boost_linked_device, true, NET_TIMER); + LOG(SCHD_LOG,LOG_INFO, "Boost on, Turing %s on\n",aqdata->aqbuttons[aqdata->boost_linked_device].label); } else { - LOG(SCHD_LOG,LOG_INFO, "Boost on, %s is already on\n",aq_data->aqbuttons[aq_data->boost_linked_device].label); + LOG(SCHD_LOG,LOG_INFO, "Boost on, %s is already on\n",aqdata->aqbuttons[aqdata->boost_linked_device].label); } } break; diff --git a/source/aq_serial.c b/source/aq_serial.c index 0481029..9ad0c46 100644 --- a/source/aq_serial.c +++ b/source/aq_serial.c @@ -39,7 +39,7 @@ #include -#define SERIAL_READ_TIMEOUT_SEC 1; +#define SERIAL_READ_TIMEOUT_SEC 2; static int _RS485_fds = -1; diff --git a/source/aq_timer.c b/source/aq_timer.c index 162c4cf..6747828 100644 --- a/source/aq_timer.c +++ b/source/aq_timer.c @@ -17,7 +17,7 @@ struct timerthread { pthread_cond_t thread_cond; aqkey *button; int deviceIndex; - struct aqualinkdata *aq_data; + struct aqualinkdata *aqdata; int duration_min; struct timespec timeout; time_t started_at; @@ -57,10 +57,10 @@ int get_timer_left(aqkey *button) return 0; } -void clear_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex) +void clear_timer(struct aqualinkdata *aqdata, /*aqkey *button,*/ int deviceIndex) { //struct timerthread *t_ptr = find_timerthread(button); - struct timerthread *t_ptr = find_timerthread(&aq_data->aqbuttons[deviceIndex]); + struct timerthread *t_ptr = find_timerthread(&aqdata->aqbuttons[deviceIndex]); if (t_ptr != NULL) { LOG(TIMR_LOG, LOG_INFO, "Clearing timer for '%s'\n",t_ptr->button->name); @@ -69,9 +69,9 @@ void clear_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceInde } } -void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex, int duration) +void start_timer(struct aqualinkdata *aqdata, /*aqkey *button,*/ int deviceIndex, int duration) { - aqkey *button = &aq_data->aqbuttons[deviceIndex]; + aqkey *button = &aqdata->aqbuttons[deviceIndex]; struct timerthread *t_ptr = find_timerthread(button); if (t_ptr != NULL) { @@ -82,7 +82,7 @@ void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceInde } struct timerthread *tmthread = calloc(1, sizeof(struct timerthread)); - tmthread->aq_data = aq_data; + tmthread->aqdata = aqdata; tmthread->button = button; tmthread->deviceIndex = deviceIndex; tmthread->thread_id = 0; @@ -137,11 +137,11 @@ void *timer_worker( void *ptr ) // device should be on, but check, ignore for PDA as that may not have been turned on yet if (!isPDA_PANEL && tmthread->button->led->state == OFF) { - if ((tmthread->button->special_mask & PROGRAM_LIGHT) == PROGRAM_LIGHT && in_light_programming_mode(tmthread->aq_data)) { + if ((tmthread->button->special_mask & PROGRAM_LIGHT) == PROGRAM_LIGHT && in_light_programming_mode(tmthread->aqdata)) { LOG(TIMR_LOG, LOG_NOTICE, "Not turning on '%s' as programmer is\n",tmthread->button->name); } else { LOG(TIMR_LOG, LOG_NOTICE, "turning on '%s'\n",tmthread->button->name); - panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); + panel_device_request(tmthread->aqdata, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); } } */ @@ -151,7 +151,7 @@ void *timer_worker( void *ptr ) delay(WAIT_TIME_BEFORE_ON_CHECK); if (cnt++ == 5 && !isPDA_PANEL) { LOG(TIMR_LOG, LOG_NOTICE, "turning on '%s'\n",tmthread->button->name); - panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, true, NET_TIMER); + panel_device_request(tmthread->aqdata, ON_OFF, tmthread->deviceIndex, true, NET_TIMER); } else if (cnt == 10) { LOG(TIMR_LOG, LOG_ERR, "button state never turned on'%s'\n",tmthread->button->name); break; @@ -189,7 +189,7 @@ void *timer_worker( void *ptr ) if (tmthread->duration_min != 0 && tmthread->button->led->state != OFF) { LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name); - panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); + panel_device_request(tmthread->aqdata, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); } else if (tmthread->button->led->state == OFF) { LOG(TIMR_LOG, LOG_INFO, "Timer waking '%s' is already off\n",tmthread->button->name); } diff --git a/source/aqualink.h b/source/aqualink.h index a4edff5..58cca99 100644 --- a/source/aqualink.h +++ b/source/aqualink.h @@ -329,6 +329,85 @@ typedef struct clightd #include "aq_panel.h" + +/** + * SET_IF_CHANGED: Updates a variable and sets a flag if the value has changed. + * + * @src: The variable to be updated (can be a struct member). + * @val: The new value. + * @flag: A boolean flag to set to true if a change occurs. + * + * This macro uses GCC extensions for type safety and to prevent + * double-evaluation of the `val` argument. + */ +//#define DEBUG_SET_IF_CHANGED +#ifndef DEBUG_SET_IF_CHANGED + +#define SET_IF_CHANGED(src, val, flag) \ + ({ \ + typeof(src) __new_val = (val); \ + if ((src) != __new_val) { \ + (src) = __new_val; \ + (flag) = true; \ + } \ + }) + +#define SET_IF_CHANGED_STRCPY(src, val, flag) \ + ({ \ + const char *__new_val = (val); \ + if (strncmp((src), __new_val, sizeof(src)) != 0) { \ + strncpy((src), __new_val, sizeof(src)); \ + (src)[sizeof(src) - 1] = '\0'; \ + (flag) = true; \ + } \ + }) + +#define SET_DIRTY(flag) ((flag) = true) +#define CLEAR_DIRTY(flag) ((flag) = false) + +#else + +#define SET_IF_CHANGED(src, val, flag) \ + ({ \ + typeof(src) __old_val = (src); \ + typeof(src) __new_val = (val); \ + if (__old_val != __new_val) { \ + (src) = __new_val; \ + (flag) = true; \ + printf("[%s:%d] Changed %s: %d -> %d\n", __FILE__, __LINE__, #src, (int)__old_val, (int)__new_val); \ + } \ + }) + +#define SET_IF_CHANGED_STRCPY(src, val, flag) \ + ({ \ + const char *__new_val = (val); \ + if (strncmp((src), __new_val, sizeof(src)) != 0) { \ + printf("[%s:%d] Changed %s: \"%s\" -> \"%s\"\n", __FILE__, __LINE__, #src, (src), __new_val); \ + strncpy((src), __new_val, sizeof(src)); \ + (src)[sizeof(src) - 1] = '\0'; \ + (flag) = true; \ + } \ + }) + +#define SET_DIRTY(flag) \ + do { \ + if (!(flag)) { \ + (flag) = true;\ + printf("[%s:%d] Set dirty flag\n", __FILE__, __LINE__); \ + } \ + } while(0) + +#define CLEAR_DIRTY(flag) \ + do { \ + if ((flag)) { \ + (flag) = false;\ + printf("[%s:%d] Clear dirty flag\n", __FILE__, __LINE__); \ + } \ + } while(0) + +#endif // DEBUG_SET_IF_CHANGED + + struct aqualinkdata { //panel_status panelstatus; @@ -382,7 +461,7 @@ struct aqualinkdata float ph; int orp; - // Below this line is not state related. (Future just do a mem compare for change) + // Below this line is not state related. //aqkey *orderedbuttons[TOTAL_BUTTONS]; // Future to reduce RS4,6,8,12,16 & spa buttons //unsigned short total_ordered_buttons; unsigned char last_packet_type; @@ -403,7 +482,8 @@ struct aqualinkdata struct action unactioned; unsigned char raw_status[AQ_PSTLEN]; // Multiple threads update this value. - volatile bool updated; + //volatile bool updated; + volatile bool is_dirty; char self[AQ_MSGLEN*2]; int num_sensors; diff --git a/source/aqualinkd.c b/source/aqualinkd.c index 416b6e6..d6a4c8a 100644 --- a/source/aqualinkd.c +++ b/source/aqualinkd.c @@ -58,6 +58,7 @@ #include "aq_scheduler.h" #include "json_messages.h" #include "aq_systemutils.h" +#include "auto_configure.h" #ifdef AQ_MANAGER #include "serial_logger.h" @@ -95,6 +96,13 @@ bool _cmdln_nostartupcheck = false; #define AddAQDstatusMask(mask) (_aqualink_data.status_mask |= mask) #define RemoveAQDstatusMask(mask) (_aqualink_data.status_mask &= ~mask) +// Keep running on all errors (we can) if we are in a container or demonized +#if defined(AQ_CONTAINER) + #define SHOULD_KEEP_RUNNING() (true) +#else + #define SHOULD_KEEP_RUNNING() (_aqconfig_.deamonize) +#endif + void main_loop(); int startup(char *self, char *cfgFile); @@ -415,12 +423,6 @@ int main(int argc, char *argv[]) #endif char defaultCfg[] = "./aqualinkd.conf"; char *cfgFile; - -//printf ("TIMER = %d\n",TIMR_LOG); - -#ifdef AQ_MEMCMP - memset(&_aqualink_data, 0, sizeof (struct aqualinkdata)); -#endif _aqualink_data.num_pumps = 0; _aqualink_data.num_lights = 0; @@ -542,7 +544,8 @@ int startup(char *self, char *cfgFile) AddAQDstatusMask(CHECKING_CONFIG); AddAQDstatusMask(NOT_CONNECTED); - _aqualink_data.updated = true; + + SET_DIRTY(_aqualink_data.is_dirty); //_aqualink_data.chiller_button == NULL; // HATE having this here, but needs to be null before config. //sd_journal_print(LOG_NOTICE, "Starting %s v%s !\n", AQUALINKD_NAME, AQUALINKD_VERSION); @@ -594,7 +597,7 @@ int startup(char *self, char *cfgFile) //return EXIT_FAILURE; } } else if (isPDA_PANEL) { - if ( (_aqconfig_.device_id >= 0x60 && _aqconfig_.device_id <= 0x63) || _aqconfig_.device_id == 0x33 ) { + if ( (_aqconfig_.device_id >= 0x60 && _aqconfig_.device_id <= 0x63) || _aqconfig_.device_id == 0x33 || _aqconfig_.device_id == 0xFF) { if ( _aqconfig_.device_id == 0x33 ) { LOG(AQUA_LOG,LOG_NOTICE, "Enabeling iAqualink protocol.\n"); _aqconfig_.enable_iaqualink = true; @@ -602,11 +605,11 @@ int startup(char *self, char *cfgFile) // We are good } else { LOG(AQUA_LOG,LOG_ERR, "Device ID 0x%02hhx does not match PDA panel, please check config!\n", _aqconfig_.device_id); - return EXIT_FAILURE; + if ( !SHOULD_KEEP_RUNNING() ) {return EXIT_FAILURE;} } } else { LOG(AQUA_LOG,LOG_ERR, "Error unknown panel type, please check config!\n"); - return EXIT_FAILURE; + if (!SHOULD_KEEP_RUNNING()) {return EXIT_FAILURE;} } if (_aqconfig_.rssa_device_id != 0x00) { @@ -614,7 +617,7 @@ int startup(char *self, char *cfgFile) // We are good } else { LOG(AQUA_LOG,LOG_ERR, "RSSA Device ID 0x%02hhx does not match RS panel, please check config!\n", _aqconfig_.rssa_device_id); - return EXIT_FAILURE; + if (!SHOULD_KEEP_RUNNING()) {return EXIT_FAILURE;} } } @@ -626,7 +629,7 @@ int startup(char *self, char *cfgFile) // We are good } else { LOG(AQUA_LOG,LOG_ERR, "Extended Device ID 0x%02hhx does not match OneTouch or AqualinkTouch ID, please check config!\n", _aqconfig_.extended_device_id); - return EXIT_FAILURE; + if (!SHOULD_KEEP_RUNNING()) {return EXIT_FAILURE;} } } @@ -728,185 +731,8 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"Unknown Emulation type Processed packet in"); break; } - -/* -#ifdef AQ_TM_DEBUG - static struct timespec now; - static struct timespec elapsed; - clock_gettime(CLOCK_REALTIME, &now); - timespec_subtract(&elapsed, &now, &_rs_packet_readitme); - LOG(AQUA_LOG,LOG_NOTICE, "Emulation type %d. Processed packet in %d.%02ld sec (%08ld ns)\n",source, elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); -#endif -*/ - } -#define MAX_AUTO_PACKETS 1200 - -bool auto_configure(unsigned char* packet, int rs_fd) { - // Loop over PROBE packets and store any we can use, - // once we see the 2nd probe of any ID we fave stored, then the loop is complete, - // set ID's and exit true, exit falce to get called again. -/* - unsigned char _goodID[] = {0x0a, 0x0b, 0x08, 0x09}; - unsigned char _goodPDAID[] = {0x60, 0x61, 0x62, 0x63}; // PDA Panel only supports one PDA. - unsigned char _goodONETID[] = {0x40, 0x41, 0x42, 0x43}; - unsigned char _goodIAQTID[] = {0x30, 0x31, 0x32, 0x33}; - unsigned char _goodRSSAID[] = {0x48, 0x49}; // Know there are only 2 good RS SA id's, guess 0x49 is the second. -*/ - - static unsigned char firstprobe = 0x00; - static unsigned char lastID = 0x00; - static bool seen_iAqualink2 = false; - static bool ignore_AqualinkTouch = false; - static bool ignore_OneTouch = false; - static int foundIDs = 0; - static int packetsReceived=0; - - static bool gotRev = false; - static unsigned char gettingRevID = 0xFF; - - static int loopsCompleted=0; - //static char message[AQ_MSGLONGLEN + 1]; - - if (++packetsReceived >= MAX_AUTO_PACKETS ) { - LOG(AQUA_LOG,LOG_ERR, "Received %d packets, and didn't get a full probe cycle, stoping Auto Configure!\n",packetsReceived); - return true; - } - - if ( packet[PKT_CMD] == CMD_PROBE ) { - LOG(AQUA_LOG,LOG_INFO, "Got Probe on ID 0x%02hhx\n",packet[PKT_DEST]); - //printf(" *** Got Probe on ID 0x%02hhx\n",packet[PKT_DEST]); - if ( packet[PKT_DEST] >= 0x08 && packet[PKT_DEST] <= 0x0B && gotRev == false && gettingRevID == 0xFF) { - // Try replying to get panel rev - gettingRevID = packet[PKT_DEST]; - caculate_ack_packet(rs_fd, packet, ALLBUTTON); - return false; // We don't want to store this ID since we use it for getting REV and is won't go back to probe when AqualinkD starts - } - } else if (packet[PKT_DEST] == gettingRevID) { - if ( packet[PKT_CMD] == CMD_MSG ) { - if ( rsm_strnstr((char *)&packet[5], " REV", AQ_MSGLEN) != NULL ) { - // We need to get the rev to cater for panel rev I & k (maybe others) that send AqualinkTouch probe messages - // then they don't support that protocol. - LOG(AQUA_LOG,LOG_DEBUG, "Got %15s from ID 0x%02hhx\n",(char *)&packet[5],packet[PKT_DEST]); - gotRev = true; - gettingRevID = 0xFF; - setPanelInformationFromPanelMsg(&_aqualink_data, (char *)&packet[5], PANEL_CPU | PANEL_REV, SIM_NONE); - if ( !isMASKSET(_aqualink_data.panel_support_options, RSP_SUP_AQLT)) { - LOG(AQUA_LOG,LOG_NOTICE, "Ignoring AqualinkTouch probes due to panel rev\n"); - ignore_AqualinkTouch = true; - if ( _aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33 ) { - _aqconfig_.extended_device_id = 0x00; - _aqconfig_.enable_iaqualink = false; - _aqconfig_.read_RS485_devmask &= ~ READ_RS485_IAQUALNK; - //firstprobe = 0x00; - foundIDs--; - } - } - if ( !isMASKSET(_aqualink_data.panel_support_options, RSP_SUP_ONET)) { - LOG(AQUA_LOG,LOG_NOTICE, "Ignoring OneTouch probes due to panel rev\n"); - ignore_OneTouch = true; - if ( _aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43 ) { - _aqconfig_.extended_device_id = 0x00; - //_aqconfig_.enable_iaqualink = false; - //_aqconfig_.read_RS485_devmask &= ~ READ_RS485_IAQUALNK; - //firstprobe = 0x00; - foundIDs--; - } - } - } - } - caculate_ack_packet(rs_fd, packet, ALLBUTTON); - } - - if (lastID != 0x00 && packet[PKT_DEST] == DEV_MASTER ) { // Can't use got a reply to the late probe. - lastID = 0x00; - } else if (lastID != 0x00 && packet[PKT_DEST] != DEV_MASTER) { - // We can use last ID. - // Save the first good ID. - if (firstprobe == 0x00 && lastID != 0x60) { - // NOTE IF can't use 0x60 (or PDA ID's) for probe, as they are way too often. - //printf("*** First Probe 0x%02hhx\n",lastID); - firstprobe = lastID; - _aqconfig_.device_id = 0x00; - _aqconfig_.rssa_device_id = 0x00; - _aqconfig_.extended_device_id = 0x00; - _aqconfig_.extended_device_id_programming = false; - AddAQDstatusMask(AUTOCONFIGURE_ID); - _aqualink_data.updated = true; - //AddAQDstatusMask(AUTOCONFIGURE_PANEL); // Not implimented yet. - } - - - if ( (lastID >= 0x08 && lastID <= 0x0B) && - (_aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) ) { - _aqconfig_.device_id = lastID; - LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused device ID 0x%02hhx\n",lastID); - foundIDs++; - } else if ( (lastID >= 0x48 && lastID <= 0x49) && - (_aqconfig_.rssa_device_id == 0x00 || _aqconfig_.rssa_device_id == 0xFF) ) { - _aqconfig_.rssa_device_id = lastID; - LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused RSSA ID 0x%02hhx\n",lastID); - foundIDs++; - } else if ( (lastID >= 0x40 && lastID <= 0x43) && ignore_OneTouch == false && - (_aqconfig_.extended_device_id == 0x00 || _aqconfig_.extended_device_id == 0xFF) ) { - _aqconfig_.extended_device_id = lastID; - _aqconfig_.extended_device_id_programming = true; - // Don't increase foundIDs as we prefer not to use this one. - LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused extended ID 0x%02hhx\n",lastID); - } else if ( (lastID >= 0x30 && lastID <= 0x33) && ignore_AqualinkTouch == false && - (_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33)) { //Overide if it's been set to Touch or not set. - _aqconfig_.extended_device_id = lastID; - _aqconfig_.extended_device_id_programming = true; - if (!seen_iAqualink2) { - _aqconfig_.enable_iaqualink = true; - _aqconfig_.read_RS485_devmask &= ~ READ_RS485_IAQUALNK; // Remove this mask, as no need since we enabled iaqualink - } - LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused extended ID 0x%02hhx\n",lastID); - foundIDs++; - } - // Now reset ID - lastID = 0x00; - - return false; - } - - if (packet[PKT_DEST] == firstprobe && packet[PKT_CMD] == CMD_PROBE) { - loopsCompleted++; - //LOG(AQUA_LOG,LOG_DEBUG, "***** Loop %d *****\n",loopsCompleted); - } - - //if ( foundIDs >= 3 || (packet[PKT_DEST] == firstprobe && packet[PKT_CMD] == CMD_PROBE) ) { - if ( (foundIDs >= 3 && gotRev) || loopsCompleted == 2 ) { - // We should have seen one complete probe cycle my now. - LOG(AQUA_LOG,LOG_NOTICE, "Finished Autoconfigure using device_id=0x%02hhx rssa_device_id=0x%02hhx extended_device_id=0x%02hhx (%s iAqualink2/3)\n", - _aqconfig_.device_id,_aqconfig_.rssa_device_id,_aqconfig_.extended_device_id, _aqconfig_.enable_iaqualink?"Enable":"Disable"); - RemoveAQDstatusMask(AUTOCONFIGURE_ID); - _aqualink_data.updated = true; - return true; // we can exit finally. - } - - if ( (packet[PKT_CMD] == CMD_PROBE) && ( - (packet[PKT_DEST] >= 0x08 && packet[PKT_DEST] <= 0x0B) || - //(packet[PKT_DEST] >= 0x60 && packet[PKT_DEST] <= 0x63) || - (packet[PKT_DEST] >= 0x40 && packet[PKT_DEST] <= 0x43) || - (packet[PKT_DEST] >= 0x30 && packet[PKT_DEST] <= 0x33) || - (packet[PKT_DEST] >= 0x48 && packet[PKT_DEST] <= 0x49) )) - { - lastID = packet[PKT_DEST]; // Store the valid ID. - } else if (lastID != 0x00 && packet[PKT_CMD] != CMD_PROBE && - (packet[PKT_DEST] >= 0xA0 && packet[PKT_DEST] <= 0xA3) ) // we get a packet to iAqualink2/3 make sure to turn off - { // Saw a iAqualink2/3 device, so can't use ID, but set to read device info. - // LOG Nessage as such - _aqconfig_.extended_device_id2 = 0x00; - _aqconfig_.enable_iaqualink = false; - _aqconfig_.read_RS485_devmask |= READ_RS485_IAQUALNK; - seen_iAqualink2 = true; - LOG(AQUA_LOG,LOG_NOTICE, "Saw inuse iAqualink2/3 ID 0x%02hhx, turning off AqualinkD on that ID\n",lastID); - } - - return false; -} unsigned char find_unused_address(unsigned char* packet) { static int ID[4] = {0,0,0,0}; // 0=0x08, 1=0x09, 2=0x0A, 3=0x0B @@ -953,7 +779,7 @@ void main_loop() //_aqualink_data.panel_rev = NULL; //_aqualink_data.panel_cpu = NULL; //_aqualink_data.panel_string = NULL; - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); sprintf(_aqualink_data.last_display_message, "%s", "Connecting to Control Panel"); _aqualink_data.is_display_message_programming = false; //_aqualink_data.simulate_panel = false; @@ -1056,7 +882,7 @@ void main_loop() LOG(AQUA_LOG,LOG_ERR, "Bad serial port: %s\n", _aqconfig_.serial_port); AddAQDstatusMask(ERROR_SERIAL); } - +/* #ifdef AQ_PDA if (isPDA_PANEL) { init_pda(&_aqualink_data); @@ -1068,11 +894,11 @@ void main_loop() } } #endif - +*/ // Set probes to true for any device we are not searching for. RemoveAQDstatusMask(CHECKING_CONFIG); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); if (_aqconfig_.rssa_device_id == 0x00) got_probe_rssa = true; @@ -1090,12 +916,12 @@ void main_loop() auto_config_complete = false; //_aqualink_data.panelstatus = LOOKING_IDS; AddAQDstatusMask(AUTOCONFIGURE_ID); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); } else { LOG(AQUA_LOG,LOG_NOTICE, "Waiting for Control Panel probe\n"); //_aqualink_data.panelstatus = CONECTING; AddAQDstatusMask(CONNECTING); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); } i=0; @@ -1104,23 +930,25 @@ void main_loop() { if (blank_read == blank_read_reconnect / 2) { LOG(AQUA_LOG,LOG_ERR, "Nothing read on '%s', are you sure that's right?\n",_aqconfig_.serial_port); -//#ifdef AQ_CONTAINER // Reset blank reads here, we want to ignore TTY errors in container to keep it running blank_read = 1; -//#endif if (_aqconfig_.device_id == 0x00) { blank_read = 1; // if device id=0x00 it's code for don't exit } - _aqualink_data.updated = true; // Make sure to show erros if ui is up + SET_DIRTY(_aqualink_data.is_dirty); // Make sure to show erros if ui is up } else if (blank_read == blank_read_reconnect*2 ) { - LOG(AQUA_LOG,LOG_ERR, "I'm done, exiting, please check '%s'\n",_aqconfig_.serial_port); - stopPacketLogger(); - close_serial_port(rs_fd); - stop_net_services(); - stop_sensors_thread(); - exit_code=EXIT_FAILURE; - _keepRunning=false; - return; + if (SHOULD_KEEP_RUNNING()){ + LOG(AQUA_LOG,LOG_ERR, "You are wasting my time, please check '%s'\n",_aqconfig_.serial_port); + } else { + LOG(AQUA_LOG,LOG_ERR, "I'm done, exiting, please check '%s'\n",_aqconfig_.serial_port); + stopPacketLogger(); + close_serial_port(rs_fd); + stop_net_services(); + stop_sensors_thread(); + exit_code=EXIT_FAILURE; + _keepRunning=false; + return; + } } /* if (_aqconfig_.log_raw_RS_bytes) @@ -1132,9 +960,9 @@ void main_loop() if (packet_length > 0 && auto_config_complete == false) { blank_read = 0; - auto_config_complete = auto_configure(packet_buffer, rs_fd); + auto_config_complete = auto_configure(&_aqualink_data, packet_buffer, packet_length, rs_fd); AddAQDstatusMask(AUTOCONFIGURE_ID); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); if (auto_config_complete) { //if (_aqconfig_.device_id != 0x00) got_probe = true; @@ -1148,7 +976,7 @@ void main_loop() if (packet_length > 0 && _aqconfig_.device_id == 0x00) { blank_read = 0; AddAQDstatusMask(AUTOCONFIGURE_ID); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); _aqconfig_.device_id = find_unused_address(packet_buffer); continue; } @@ -1204,12 +1032,16 @@ void main_loop() LOG(AQUA_LOG,LOG_ERR, "No probe on device_id '0x%02hhx', Can't start! (please check config)\n",_aqconfig_.device_id); i=0; } else { - LOG(AQUA_LOG,LOG_ERR, "No probe on device_id '0x%02hhx', giving up! (please check config)\n",_aqconfig_.device_id); - stopPacketLogger(); - close_serial_port(rs_fd); - stop_net_services(); - stop_sensors_thread(); - return; + if (SHOULD_KEEP_RUNNING()){ + LOG(AQUA_LOG,LOG_ERR, "You are wasting my time, please check config line 'device_id = 0x%02hhx'\n",_aqconfig_.device_id); + } else { + LOG(AQUA_LOG,LOG_ERR, "No probe on device_id '0x%02hhx', giving up! (please check config)\n",_aqconfig_.device_id); + stopPacketLogger(); + close_serial_port(rs_fd); + stop_net_services(); + stop_sensors_thread(); + return; + } } } if(!got_probe_rssa) { @@ -1231,7 +1063,7 @@ void main_loop() RemoveAQDstatusMask(AUTOCONFIGURE_ID); RemoveAQDstatusMask(NOT_CONNECTED); AddAQDstatusMask(CONNECTING); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); //At this point we should have correct ID and seen probes on those ID's. // Setup the panel @@ -1240,9 +1072,21 @@ void main_loop() //_aqualink_data.panelstatus = NO_IDS_ERROR; RemoveAQDstatusMask(CONNECTING); // Not sure if we should remove this AddAQDstatusMask(ERROR_NO_DEVICE_ID); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); } +#ifdef AQ_PDA + if (isPDA_PANEL) { + init_pda(&_aqualink_data); + if (_aqconfig_.extended_device_id != 0x00) + { + LOG(AQUA_LOG,LOG_ERR, "Aqualink daemon can't use extended_device_id in PDA mode, ignoring value '0x%02hhx' from cfg\n",_aqconfig_.extended_device_id); + _aqconfig_.extended_device_id = 0x00; + _aqconfig_.extended_device_id_programming = false; + } + } +#endif + if (_aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x49) { addPanelRSserialAdapterInterface(); } @@ -1256,7 +1100,7 @@ void main_loop() // We can only get panel size info from extended ID if (_aqconfig_.extended_device_id != 0x00) { RemoveAQDstatusMask(AUTOCONFIGURE_PANEL); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); } if (_aqconfig_.extended_device_id_programming == true && (isONET_ENABLED || isIAQT_ENABLED) ) @@ -1301,7 +1145,7 @@ void main_loop() LOG(AQUA_LOG,LOG_ERR, "Bad serial port '%s', are you sure that's right?\n",_aqconfig_.serial_port); sprintf(_aqualink_data.last_display_message, CONNECTION_ERROR); //LOG(AQUA_LOG,LOG_ERR, "Serial port error, Aqualink daemon waiting to connect to master device...\n"); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); AddAQDstatusMask(ERROR_SERIAL); //broadcast_aqualinkstate_error(CONNECTION_ERROR); broadcast_aqualinkstate_error(getAqualinkDStatusMessage(&_aqualink_data)); @@ -1312,7 +1156,7 @@ void main_loop() { sprintf(_aqualink_data.last_display_message, CONNECTION_ERROR); LOG(AQUA_LOG,LOG_ERR, "Aqualink daemon looks like serial error, resetting.\n"); - _aqualink_data.updated = true; + SET_DIRTY(_aqualink_data.is_dirty); AddAQDstatusMask(ERROR_SERIAL); //broadcast_aqualinkstate_error(CONNECTION_ERROR); broadcast_aqualinkstate_error(getAqualinkDStatusMessage(&_aqualink_data)); @@ -1370,7 +1214,7 @@ void main_loop() RemoveAQDstatusMask(ERROR_SERIAL); RemoveAQDstatusMask(CONNECTING); AddAQDstatusMask(CONNECTED); - _aqualink_data.updated = true; + //_aqualink_data.is_dirty = true; DEBUG_TIMER_START(&_rs_packet_timer); blank_read = 0; @@ -1414,27 +1258,27 @@ void main_loop() AddAQDstatusMask(CONNECTED); switch(getJandyDeviceType(packet_buffer[PKT_DEST])){ case ALLBUTTON: - _aqualink_data.updated = process_allbutton_packet(packet_buffer, packet_length, &_aqualink_data); + process_allbutton_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, ALLBUTTON); break; case RSSADAPTER: - _aqualink_data.updated = process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data); + process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, RSSADAPTER); break; case IAQTOUCH: - _aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data); + process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH); break; case ONETOUCH: - _aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data); + process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH); break; case AQUAPDA: - _aqualink_data.updated = process_pda_packet(packet_buffer, packet_length); + process_pda_packet(packet_buffer, packet_length); caculate_ack_packet(rs_fd, packet_buffer, AQUAPDA); break; case IAQUALNK: - _aqualink_data.updated = process_iaqualink_packet(packet_buffer, packet_length, &_aqualink_data); + process_iaqualink_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, IAQUALNK); break; default: @@ -1451,11 +1295,11 @@ void main_loop() { if (getProtocolType(packet_buffer) == JANDY) { - _aqualink_data.updated = processJandyPacket(packet_buffer, packet_length, &_aqualink_data); + processJandyPacket(packet_buffer, packet_length, &_aqualink_data); } // Process Pentair Device Packed (pentair have to & from in message, so no need to) else if (getProtocolType(packet_buffer) == PENTAIR && READ_RSDEV_vsfPUMP) { - _aqualink_data.updated = processPentairPacket(packet_buffer, packet_length, &_aqualink_data); + processPentairPacket(packet_buffer, packet_length, &_aqualink_data); // In the future probably add code to catch device offline (ie missing reply message) } DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"Processed (readonly) packet in"); @@ -1475,17 +1319,7 @@ void main_loop() } } - /* - if ( _aqualink_data.num_sensors > 0 && ++loopnum >= 200 ) { - loopnum=0; - for (int i=0; i < _aqualink_data.num_sensors; i++) { - if (read_sensor(&_aqualink_data.sensors[i]) ) { - _aqualink_data.updated = true; - } - } - } - */ - + //tcdrain(rs_fd); // Make sure buffer has been sent. //delay(10); } @@ -1506,21 +1340,7 @@ void main_loop() close_serial_port(rs_fd); // Clear webbrowser //mg_mgr_free(&mgr); -/* - if (! _restart) { - // NSF need to run through config memory and clean up. - LOG(AQUA_LOG,LOG_NOTICE, "Exit!\n"); - //exit(EXIT_FAILURE); - exit(exit_code); - } else { - LOG(AQUA_LOG,LOG_WARNING, "Waiting for process to fininish!\n"); - delay(5 * 1000); - LOG(AQUA_LOG,LOG_WARNING, "Restarting!\n"); - _keepRunning = true; - _restart = false; - startup(_self, _cfgFile); - } -*/ + #ifdef SELF_RESTART if (! _restart) { LOG(AQUA_LOG,LOG_WARNING, "Waiting for process to fininish!\n"); diff --git a/source/auto_configure.c b/source/auto_configure.c new file mode 100644 index 0000000..5d7e55c --- /dev/null +++ b/source/auto_configure.c @@ -0,0 +1,279 @@ +#include +#include +#include +#include + +#include "aqualink.h" +#include "aq_serial.h" +#include "auto_configure.h" +#include "utils.h" +#include "config.h" +#include "rs_msg_utils.h" + + +#define MAX_AUTO_PACKETS 1200 + + +char *_getPanelInfoAllB(int rs_fd, unsigned char *packet_buffer) +{ + static unsigned char allbID = 0x00; + static bool found=false; + + if (found) + return NULL; + + if (packet_buffer[PKT_CMD] == CMD_PROBE) { + if (allbID == 0x00) { + allbID = packet_buffer[PKT_DEST]; + send_ack(rs_fd, 0x00); + } + } else if ( allbID == packet_buffer[PKT_DEST] ) { + if ( packet_buffer[PKT_CMD] == CMD_MSG ) { + char *ptr; + if ( (ptr = rsm_strnstr((char *)&packet_buffer[5], " REV", AQ_MSGLEN)) != NULL ) { + found=true; + return ptr+1; + } + } + send_ack(rs_fd, 0x00); + } + + return NULL; +} + +void *_getPanelInfoPCdock(int rs_fd, unsigned char *packet_buffer) +{ + static unsigned char getPanelRev[] = {0x00,0x14,0x01}; + static unsigned char getPanelType[] = {0x00,0x14,0x02}; + static int msgcnt=0; + static int found=0; + static unsigned char pcdID = 0x00; + + if (found >= 2) + return NULL; + + if (packet_buffer[PKT_CMD] == CMD_PROBE) { + if (msgcnt == 0) { + pcdID = packet_buffer[PKT_DEST]; + send_ack(rs_fd, 0x00); + } else if (msgcnt == 1 && pcdID == packet_buffer[PKT_DEST]) + send_jandy_command(rs_fd, getPanelRev, 3); + else if (msgcnt == 2 && pcdID == packet_buffer[PKT_DEST]) + send_jandy_command(rs_fd, getPanelType, 3); + msgcnt++; + } else if (packet_buffer[PKT_CMD] == CMD_MSG && pcdID == packet_buffer[PKT_DEST]) { + send_ack(rs_fd, 0x00); + if (msgcnt == 2) { + found++; + return (char *)&packet_buffer[5]; + } else if (msgcnt == 3) { + found++; + return (char *)&packet_buffer[5]; + } + } + + return NULL; + +} + + +bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int packet_length, int rs_fd) { + // Loop over PROBE packets and store any we can use, + // once we see the 2nd probe of any ID we fave stored, then the loop is complete, + // set ID's and exit true, exit falce to get called again. +/* + unsigned char _goodID[] = {0x0a, 0x0b, 0x08, 0x09}; + unsigned char _goodPDAID[] = {0x60, 0x61, 0x62, 0x63}; // PDA Panel only supports one PDA. + unsigned char _goodONETID[] = {0x40, 0x41, 0x42, 0x43}; + unsigned char _goodIAQTID[] = {0x30, 0x31, 0x32, 0x33}; + unsigned char _goodRSSAID[] = {0x48, 0x49}; // Know there are only 2 good RS SA id's, guess 0x49 is the second. +*/ + + static unsigned char firstprobe = 0x00; + static unsigned char lastID = 0x00; + static unsigned char PDA_ID = 0x00; + static bool seen_iAqualink2 = false; + static int foundIDs = 0; + static int packetsReceived=0; + static bool done=false; + static bool gotRev = false; + static bool gotPsize = false; + static int loopsCompleted=0; + static unsigned char passMessageAllB = 0xFF; + static unsigned char passMessagePCdock = 0xFF; + + char *msg_ptr; + + if (++packetsReceived >= MAX_AUTO_PACKETS ) { + LOG(AQUA_LOG,LOG_ERR, "Received %d packets, and didn't get a full probe cycle, stoping Auto Configure!\n",packetsReceived); + //return true; + done=true; + goto checkIDs; + } + + if (packet[PKT_DEST] == passMessageAllB && gotRev == false) { + if ( (msg_ptr = _getPanelInfoAllB(rs_fd, packet)) != NULL) { + uint8_t sets = setPanelInformationFromPanelMsg(aqdata, msg_ptr, PANEL_CPU | PANEL_REV, SIM_NONE); + if (isMASK_SET(sets, PANEL_REV)) + gotRev = true; + return false; + } + } else if (packet[PKT_DEST] == passMessagePCdock && (gotRev == false || gotPsize == false) ) { + if ( (msg_ptr = _getPanelInfoPCdock(rs_fd, packet)) != NULL) { + uint8_t sets = setPanelInformationFromPanelMsg(aqdata, msg_ptr, PANEL_REV | PANEL_STRING, SIM_NONE); + if (isMASK_SET(sets, PANEL_REV)) + gotRev = true; + if (isMASK_SET(sets, PANEL_STRING)) + gotPsize = true; + return false; + } + } else if ( packet[PKT_CMD] == CMD_PROBE ) { + if ( packet[PKT_DEST] >= 0x08 && packet[PKT_DEST] <= 0x0B && gotRev == false && passMessageAllB == 0xFF) { + _getPanelInfoAllB(rs_fd, packet); + passMessageAllB = packet[PKT_DEST]; + LOG(AQUA_LOG, LOG_NOTICE, "Using id=0x%02hhx to probe panel for information\n",packet[PKT_DEST]); + return false; + } else if ( packet[PKT_DEST] == 0x58 && (gotRev == false || gotPsize == false) && passMessagePCdock == 0xFF) { + _getPanelInfoPCdock(rs_fd, packet); + passMessagePCdock = packet[PKT_DEST]; + LOG(AQUA_LOG, LOG_NOTICE, "Using id=0x%02hhx to probe panel for information\n",packet[PKT_DEST]); + return false; + } + } + + // PDA might be active, so capture PDA ID ignoring if it's free or not. + if ( (packet[PKT_DEST] >= 0x60 && packet[PKT_DEST] <= 0x63) && PDA_ID == 0x00) { + LOG(AQUA_LOG,LOG_NOTICE, "Found valid PDA ID 0x%02hhx\n",packet[PKT_DEST]); + PDA_ID = packet[PKT_DEST]; + } + + if (lastID != 0x00 && packet[PKT_DEST] == DEV_MASTER ) { // Can't use got a reply to the last probe. + lastID = 0x00; + } else if (lastID != 0x00 && packet[PKT_DEST] != DEV_MASTER) { + // We can use last ID. + // Save the first good ID. + if (firstprobe == 0x00 && lastID != 0x60) { + // NOTE IF can't use 0x60 (or PDA ID's) for probe, as they are way too often. + //printf("*** First Probe 0x%02hhx\n",lastID); + firstprobe = lastID; + _aqconfig_.device_id = 0x00; + _aqconfig_.rssa_device_id = 0x00; + _aqconfig_.extended_device_id = 0x00; + _aqconfig_.extended_device_id_programming = false; + //AddAQDstatusMask(AUTOCONFIGURE_ID); + setMASK(aqdata->status_mask, AUTOCONFIGURE_ID); + SET_DIRTY(aqdata->is_dirty); + //AddAQDstatusMask(AUTOCONFIGURE_PANEL); // Not implimented yet. + } + + + if ( (lastID >= 0x08 && lastID <= 0x0B) && + (_aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) ) { + _aqconfig_.device_id = lastID; + LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused device ID 0x%02hhx\n",lastID); + foundIDs++; + } else if ( (lastID >= 0x48 && lastID <= 0x49) && + (_aqconfig_.rssa_device_id == 0x00 || _aqconfig_.rssa_device_id == 0xFF) ) { + _aqconfig_.rssa_device_id = lastID; + LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused RSSA ID 0x%02hhx\n",lastID); + foundIDs++; + } else if ( (lastID >= 0x40 && lastID <= 0x43) && + (_aqconfig_.extended_device_id == 0x00 || _aqconfig_.extended_device_id == 0xFF) ) { + _aqconfig_.extended_device_id = lastID; + _aqconfig_.extended_device_id_programming = true; + // Don't increase foundIDs as we prefer not to use this one. + LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused extended ID 0x%02hhx\n",lastID); + } else if ( (lastID >= 0x30 && lastID <= 0x33) && + (_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33)) { //Overide if it's been set to Touch or not set. + _aqconfig_.extended_device_id = lastID; + _aqconfig_.extended_device_id_programming = true; + if (!seen_iAqualink2) { + _aqconfig_.enable_iaqualink = true; + _aqconfig_.read_RS485_devmask &= ~ READ_RS485_IAQUALNK; // Remove this mask, as no need since we enabled iaqualink + } + LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused extended ID 0x%02hhx\n",lastID); + foundIDs++; + } + + // Now reset ID + lastID = 0x00; + + return false; + } + + if (packet[PKT_DEST] == firstprobe && packet[PKT_CMD] == CMD_PROBE) { + loopsCompleted++; + } + + if ( (foundIDs >= 3 && gotRev && gotPsize) || loopsCompleted >= 2 ) { + done=true; + goto checkIDs; + } + + if ( (packet[PKT_CMD] == CMD_PROBE) && ( + (packet[PKT_DEST] >= 0x08 && packet[PKT_DEST] <= 0x0B) || + //(packet[PKT_DEST] >= 0x60 && packet[PKT_DEST] <= 0x63) || + (packet[PKT_DEST] >= 0x40 && packet[PKT_DEST] <= 0x43) || + (packet[PKT_DEST] >= 0x30 && packet[PKT_DEST] <= 0x33) || + (packet[PKT_DEST] >= 0x48 && packet[PKT_DEST] <= 0x49) )) + { + lastID = packet[PKT_DEST]; // Store the valid ID. + } + else if (packet[PKT_DEST] >= 0xa0 && packet[PKT_DEST] <= 0xa3 && seen_iAqualink2 == false ) // we get a packet to iAqualink2/3 make sure to turn off, + { // Saw a iAqualink2/3 device, so can't use ID, but set to read device info. + // NSF This is not a good way to check, will probably be false positive if you are using iAqualink2 and hit restart. + _aqconfig_.extended_device_id2 = 0x00; + _aqconfig_.enable_iaqualink = false; + _aqconfig_.read_RS485_devmask |= READ_RS485_IAQUALNK; + seen_iAqualink2 = true; + LOG(AQUA_LOG,LOG_NOTICE, "Saw inuse iAqualink2/3 ID 0x%02hhx, turning off AqualinkD on that ID\n",packet[PKT_DEST]); + } + + if (!done) + return false; + + + checkIDs: + + //printf("Total loops = %d, Found ID's = %d, using ID 0x%02hhx\n",loopsCompleted,foundIDs,firstprobe); + + if (isPDA_PANEL || (PDA_ID != 0x00 && _aqconfig_.device_id == 0x00) ) { + LOG(AQUA_LOG,LOG_WARNING, "Autoconfigure set to PDA panel - Using most basic mode, may want to re-configure later\n"); + _aqconfig_.device_id = PDA_ID; + _aqconfig_.extended_device_id = 0x00; + _aqconfig_.rssa_device_id = 0x00; + _aqconfig_.enable_iaqualink = false; + _aqconfig_.extended_device_id_programming = false; + if (!isPDA_PANEL) { + _aqconfig_.paneltype_mask |= RSP_PDA; + _aqconfig_.paneltype_mask &= ~RSP_RS; + } + } + + if (gotRev) { + if ( !isMASKSET(aqdata->panel_support_options, RSP_SUP_AQLT)) { + LOG(AQUA_LOG,LOG_NOTICE, "Ignoring AqualinkTouch probes due to panel rev\n"); + if ( _aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33 ) { + _aqconfig_.extended_device_id = 0x00; + _aqconfig_.enable_iaqualink = false; + _aqconfig_.read_RS485_devmask &= ~ READ_RS485_IAQUALNK; + foundIDs--; + } + } + + if ( !isMASKSET(aqdata->panel_support_options, RSP_SUP_ONET)) { + LOG(AQUA_LOG,LOG_NOTICE, "Ignoring OneTouch probes due to panel rev\n"); + if ( _aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43 ) { + _aqconfig_.extended_device_id = 0x00; + foundIDs--; + } + } + } + + LOG(AQUA_LOG,LOG_NOTICE, "Finished Autoconfigure using device_id=0x%02hhx rssa_device_id=0x%02hhx extended_device_id=0x%02hhx (%s iAqualink2/3)\n", + _aqconfig_.device_id,_aqconfig_.rssa_device_id,_aqconfig_.extended_device_id, _aqconfig_.enable_iaqualink?"Enable":"Disable"); + removeMASK(aqdata->status_mask, AUTOCONFIGURE_ID); + SET_DIRTY(aqdata->is_dirty); + + return true; +} \ No newline at end of file diff --git a/source/auto_configure.h b/source/auto_configure.h new file mode 100644 index 0000000..0e4796c --- /dev/null +++ b/source/auto_configure.h @@ -0,0 +1,9 @@ +#ifndef AUTO_CONFIGURE_H_ +#define AUTO_CONFIGURE_H_ + + +bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int packet_length, int rs_fd); + + + +#endif //AUTO_CONFIGURE_H_ \ No newline at end of file diff --git a/source/color_lights.c b/source/color_lights.c index b0801e8..d74e0f7 100644 --- a/source/color_lights.c +++ b/source/color_lights.c @@ -310,23 +310,28 @@ bool isShowMode(const char *mode) return false; } -void set_currentlight_value(clight_detail *light, int index) + +// NSF need to use the SET_IF_CHANGED macro here, so come back and change function parameters. +bool set_currentlight_value(clight_detail *light, int index) { + bool rtn=false; // Dimmer 2 has different values (range 1 to 100) if (light->lightType == LC_DIMMER2) { if (index < 0 || index > 100) - light->currentValue = 0; + SET_IF_CHANGED(light->currentValue, 0, rtn); else - light->currentValue = index; + SET_IF_CHANGED(light->currentValue, index, rtn); } else { // We want to leave the last color, so if 0 don't do anything, but set to 0 if bad value if (index <= 0 || index > LIGHT_COLOR_OPTIONS) { - light->currentValue = 0; + SET_IF_CHANGED(light->currentValue, 0, rtn); } else if (index > 0 && index < LIGHT_COLOR_OPTIONS) { - light->currentValue = index; + SET_IF_CHANGED(light->currentValue, index, rtn); //light->lastValue = index; } } + + return rtn; } // Used for dynamic config JS diff --git a/source/color_lights.h b/source/color_lights.h index b1842cd..edfdcd9 100644 --- a/source/color_lights.h +++ b/source/color_lights.h @@ -34,7 +34,7 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size); int build_color_light_jsonarray(int index, char* buffer, int size); void clear_aqualinkd_light_modes(); -void set_currentlight_value(clight_detail *light, int index); +bool set_currentlight_value(clight_detail *light, int index); bool set_aqualinkd_light_mode_name(char *name, int index, bool isShow); const char *get_aqualinkd_light_mode_name(int index, bool *isShow); diff --git a/source/devices_jandy.c b/source/devices_jandy.c index 0f65b8c..6b6f8f7 100644 --- a/source/devices_jandy.c +++ b/source/devices_jandy.c @@ -227,40 +227,18 @@ bool processPacketToSWG(unsigned char *packet, int packet_length, struct aqualin // In service or timeout mode SWG set % message is very strange. AR %% | HEX: 0x10|0x02|0x50|0x11|0xff|0x72|0x10|0x03| // Not really sure what to do with this, just ignore 0xff / 255 for the moment. (if statment above) - // SWG can get ~10 messages to set to 0 then go back again for some reason, so don't go to 0 until 10 messages are received - /* - if (swg_zero_cnt < swg_zero_ignore && packet[4] == 0x00) { - LOG(DJAN_LOG, LOG_DEBUG, "Ignoring SWG set to %d due to packet packet count %d <= %d from control panel to SWG 0x%02hhx 0x%02hhx\n", (int)packet[4], - swg_zero_cnt, swg_zero_ignore, packet[4], packet[5]); - swg_zero_cnt++; - } else if (swg_zero_cnt >= swg_zero_ignore && packet[4] == 0x00) { if (aqdata->swg_percent != (int)packet[4]) { //aqdata->swg_percent = (int)packet[4]; setSWGpercent(aqdata, (int)packet[4]); changedAnything = true; - aqdata->updated = true; - LOG(DJAN_LOG, LOG_DEBUG, "Set SWG %% to %d from reading control panel RS485 packet sent to SWG\n", aqdata->swg_percent); - } - // LOG(DJAN_LOG, LOG_DEBUG, "SWG set to %d due to packet packet count %d <= %d from control panel to SWG 0x%02hhx 0x%02hhx\n", - // (int)packet[4],swg_zero_cnt,SWG_ZERO_IGNORE_COUNT,packet[4],packet[5]); swg_zero_cnt++; - } else {*/ - //swg_zero_cnt = 0; - if (aqdata->swg_percent != (int)packet[4]) { - //aqdata->swg_percent = (int)packet[4]; - setSWGpercent(aqdata, (int)packet[4]); - changedAnything = true; - aqdata->updated = true; + SET_DIRTY(aqdata->is_dirty); LOG(DJAN_LOG, LOG_INFO, "Set SWG %% to %d from control panel to SWG\n", aqdata->swg_percent); } - // LOG(DJAN_LOG, LOG_DEBUG, "SWG set to %d due to packet from control panel to SWG 0x%02hhx 0x%02hhx\n", - // aqdata.swg_percent,packet[4],packet[5]); - /*}*/ - if (aqdata->swg_percent > 100) - aqdata->boost = true; + SET_IF_CHANGED(aqdata->boost, true, aqdata->is_dirty); else - aqdata->boost = false; + SET_IF_CHANGED(aqdata->boost, false, aqdata->is_dirty); } return changedAnything; } @@ -294,7 +272,7 @@ bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqual aqdata->swg_ppm = packet[4] * 100; LOG(DJAN_LOG, LOG_INFO, "Received SWG PPM %d from SWG packet\n", aqdata->swg_ppm); changedAnything = true; - aqdata->updated = true; + SET_DIRTY(aqdata->is_dirty); } // logMessage(LOG_DEBUG, "Read SWG PPM %d from ID 0x%02hhx\n", aqdata.swg_ppm, SWG_DEV_ID); } @@ -385,13 +363,13 @@ void setSWGdeviceStatus(struct aqualinkdata *aqdata, emulation_type requester, u case SWG_STATUS_LOW_TEMP: case SWG_STATUS_CHECK_PCB: case SWG_STATUS_GENFAULT: - aqdata->ar_swg_device_status = status; - aqdata->swg_led_state = isSWGDeviceErrorState(status)?ENABLE:ON; + SET_IF_CHANGED(aqdata->ar_swg_device_status, status, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_led_state, (isSWGDeviceErrorState(status)?ENABLE:ON), aqdata->is_dirty); break; case SWG_STATUS_OFF: // THIS IS OUR OFF STATUS, NOT AQUAPURE case SWG_STATUS_TURNING_OFF: - aqdata->ar_swg_device_status = status; - aqdata->swg_led_state = OFF; + SET_IF_CHANGED(aqdata->ar_swg_device_status, status, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_led_state, OFF, aqdata->is_dirty); break; default: LOG(DJAN_LOG, LOG_WARNING, "Ignoring set SWG device to state '0x%02hhx', state is unknown\n", status); @@ -423,13 +401,13 @@ bool updateSWG(struct aqualinkdata *aqdata, emulation_type requester, aqledstate bool setSWGboost(struct aqualinkdata *aqdata, bool on) { if (!on) { - aqdata->boost = false; - aqdata->boost_msg[0] = '\0'; - aqdata->swg_percent = 0; + SET_IF_CHANGED(aqdata->boost, false, aqdata->is_dirty); + SET_IF_CHANGED_STRCPY(aqdata->boost_msg, "", aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_percent, 0, aqdata->is_dirty); } else { - aqdata->boost = true; - aqdata->swg_percent = 101; - aqdata->swg_led_state = ON; + SET_IF_CHANGED(aqdata->boost, true, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_percent, 101, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_led_state, ON, aqdata->is_dirty); } return true; @@ -448,43 +426,40 @@ bool changeSWGpercent(struct aqualinkdata *aqdata, int percent) { } void setSWGoff(struct aqualinkdata *aqdata) { - if (aqdata->ar_swg_device_status != SWG_STATUS_OFF || aqdata->swg_led_state != OFF) - aqdata->updated = true; - aqdata->ar_swg_device_status = SWG_STATUS_OFF; - aqdata->swg_led_state = OFF; + SET_IF_CHANGED(aqdata->ar_swg_device_status, SWG_STATUS_OFF, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->swg_led_state, OFF, aqdata->is_dirty); LOG(DJAN_LOG, LOG_DEBUG, "Set SWG to off\n"); } void setSWGenabled(struct aqualinkdata *aqdata) { if (aqdata->swg_led_state != ENABLE) { - aqdata->updated = true; - aqdata->swg_led_state = ENABLE; + SET_IF_CHANGED(aqdata->swg_led_state, ENABLE, aqdata->is_dirty); LOG(DJAN_LOG, LOG_DEBUG, "Set SWG to Enable\n"); } + //SET_IF_CHANGED(aqdata->swg_led_state, ENABLE, aqdata->is_dirty); } // force a Change SWG percent. void setSWGpercent(struct aqualinkdata *aqdata, int percent) { - aqdata->swg_percent = percent; - aqdata->updated = true; + SET_IF_CHANGED(aqdata->swg_percent, percent, aqdata->is_dirty); if (aqdata->swg_percent > 0) { //LOG(DJAN_LOG, LOG_DEBUG, "swg_led_state=%d, swg_led_state=%d, isSWGDeviceErrorState=%d, ar_swg_device_status=%d\n",aqdata->swg_led_state, aqdata->swg_led_state, isSWGDeviceErrorState(aqdata->ar_swg_device_status),aqdata->ar_swg_device_status); if (aqdata->swg_led_state == OFF || (aqdata->swg_led_state == ENABLE && ! isSWGDeviceErrorState(aqdata->ar_swg_device_status)) ) // Don't change ENABLE / FLASH - aqdata->swg_led_state = ON; + SET_IF_CHANGED(aqdata->swg_led_state, ON, aqdata->is_dirty); if (aqdata->ar_swg_device_status == SWG_STATUS_UNKNOWN) - aqdata->ar_swg_device_status = SWG_STATUS_ON; + SET_IF_CHANGED(aqdata->ar_swg_device_status, SWG_STATUS_ON, aqdata->is_dirty); } if ( aqdata->swg_percent == 0 ) { if (aqdata->swg_led_state == ON) - aqdata->swg_led_state = ENABLE; // Don't change OFF + SET_IF_CHANGED(aqdata->swg_led_state, ENABLE, aqdata->is_dirty); // Don't change OFF if (aqdata->ar_swg_device_status == SWG_STATUS_UNKNOWN) - aqdata->ar_swg_device_status = SWG_STATUS_ON; // Maybe this should be off + SET_IF_CHANGED(aqdata->ar_swg_device_status, SWG_STATUS_ON, aqdata->is_dirty); // Maybe this should be off } LOG(DJAN_LOG, LOG_DEBUG, "Set SWG %% to %d, LED=%d, FullStatus=0x%02hhx\n", aqdata->swg_percent, aqdata->swg_led_state, aqdata->ar_swg_device_status); @@ -638,7 +613,8 @@ bool processPacketFromJandyPump(unsigned char *packet_buffer, int packet_length, for (int i = 0; i < MAX_PUMPS; i++) { if ( aqdata->pumps[i].prclType == JANDY && aqdata->pumps[i].pumpID == previous_packet_to ) { LOG(DJAN_LOG, LOG_INFO, "Jandy Pump Status message = RPM %d\n",( (packet_buffer[EP_HI_B_RPM] * 256) + packet_buffer[EP_LO_B_RPM]) / 4 ); - aqdata->pumps[i].rpm = ( (packet_buffer[EP_HI_B_RPM] * 256) + packet_buffer[EP_LO_B_RPM] ) / 4; + //aqdata->pumps[i].rpm = ( (packet_buffer[EP_HI_B_RPM] * 256) + packet_buffer[EP_LO_B_RPM] ) / 4; + SET_IF_CHANGED(aqdata->pumps[i].rpm, ( (packet_buffer[EP_HI_B_RPM] * 256) + packet_buffer[EP_LO_B_RPM] ) / 4, aqdata->is_dirty); found=true; } } @@ -646,7 +622,8 @@ bool processPacketFromJandyPump(unsigned char *packet_buffer, int packet_length, for (int i = 0; i < MAX_PUMPS; i++) { if ( aqdata->pumps[i].prclType == JANDY && aqdata->pumps[i].pumpID == previous_packet_to ) { LOG(DJAN_LOG, LOG_INFO, "Jandy Pump Status message = WATTS %d\n", (packet_buffer[EP_HI_B_WAT] * 256) + packet_buffer[EP_LO_B_WAT]); - aqdata->pumps[i].watts = (packet_buffer[EP_HI_B_WAT] * 256) + packet_buffer[EP_LO_B_WAT]; + //aqdata->pumps[i].watts = (packet_buffer[EP_HI_B_WAT] * 256) + packet_buffer[EP_LO_B_WAT]; + SET_IF_CHANGED(aqdata->pumps[i].watts, (packet_buffer[EP_HI_B_WAT] * 256) + packet_buffer[EP_LO_B_WAT], aqdata->is_dirty); found=true; } } @@ -712,24 +689,24 @@ bool processPacketToJandyJXiHeater(unsigned char *packet_buffer, int packet_leng if (packet_buffer[5] != aqdata->pool_htr_set_point) { LOG(DJAN_LOG, LOG_INFO, "JXi pool setpoint %d, Pool heater sp %d (changing to LXi)\n", packet_buffer[5], aqdata->pool_htr_set_point); - aqdata->pool_htr_set_point = packet_buffer[5]; + SET_IF_CHANGED(aqdata->pool_htr_set_point, packet_buffer[5], aqdata->is_dirty); } if (packet_buffer[6] != aqdata->spa_htr_set_point) { LOG(DJAN_LOG, LOG_INFO, "JXi spa setpoint %d, Spa heater sp %d (changing to LXi)\n", packet_buffer[6], aqdata->spa_htr_set_point); - aqdata->spa_htr_set_point = packet_buffer[6]; + SET_IF_CHANGED(aqdata->spa_htr_set_point, packet_buffer[6], aqdata->is_dirty); } if (packet_buffer[7] != 0xff && packet_buffer[4] != 0x00) { if (packet_buffer[4] == 0x11 || packet_buffer[4] == 0x19) { if (aqdata->pool_temp != packet_buffer[7]) { LOG(DJAN_LOG, LOG_INFO, "JXi pool water temp %d, pool water temp %d (changing to LXi)\n", packet_buffer[7], aqdata->pool_temp); - aqdata->pool_temp = packet_buffer[7]; + SET_IF_CHANGED(aqdata->pool_temp, packet_buffer[7], aqdata->is_dirty); } } else if (packet_buffer[4] == 0x12 || packet_buffer[4] == 0x1a) { if (aqdata->spa_temp != packet_buffer[7]) { LOG(DJAN_LOG, LOG_INFO, "JXi spa water temp %d, spa water temp %d (changing to LXi)\n", packet_buffer[7], aqdata->spa_temp); - aqdata->spa_temp = packet_buffer[7]; + SET_IF_CHANGED(aqdata->spa_temp, packet_buffer[7], aqdata->is_dirty); } } } @@ -1202,10 +1179,7 @@ void updateHeatPumpLed(heatpumpstate state, aqledstate ledstate, struct aqualink if ( (ledstate == ENABLE && (from == HP_DISPLAY || from == HP_FROM_PANEL)) || ( (ledstate == ON || ledstate == OFF) && (from == HP_DISPLAY || from == HP_TO_PANEL) )) { - if ( ledstate != aqdata->chiller_button->led->state) { - aqdata->chiller_button->led->state = ledstate; - aqdata->updated = true; - } + SET_IF_CHANGED(aqdata->chiller_button->led->state, ledstate, aqdata->is_dirty); } if (state == HP_COOL) { @@ -1213,27 +1187,6 @@ void updateHeatPumpLed(heatpumpstate state, aqledstate ledstate, struct aqualink } else if (state == HP_HEAT) { ((altlabel_detail *)aqdata->chiller_button->special_mask_ptr)->in_alt_mode = false; } -/* - // If LED state is enable (that's a reqest), so only change if off. - // if froma displayed message, that's from ON to ENA, so set that one. - if ( !fromMessage && ledstate == ENABLE && aqdata->chiller_button->led->state == ON) { - //printf("**** Request from %s Heat Pump %s, currently %s, ignore!\n",fromMessage?"Display":"RS485",LED2text(ledstate),LED2text(aqdata->chiller_button->led->state) ); - return; - } - - if (aqdata->chiller_button->led->state != ledstate) { - //printf("**** Heat Pump Setting to %s, from %s!\n",LED2text(ledstate),LED2text(aqdata->chiller_button->led->state)); - aqdata->chiller_button->led->state = ledstate; - aqdata->updated = true; - if (state == HP_COOL) { - ((vbutton_detail *)aqdata->chiller_button->special_mask_ptr)->in_alt_mode = true; - } else if (state == HP_HEAT) { - ((vbutton_detail *)aqdata->chiller_button->special_mask_ptr)->in_alt_mode = false; - } - } else { - //printf("**** Heat Pump %s, already %s, ignore!\n",LED2text(ledstate),LED2text(aqdata->chiller_button->led->state)); - } - */ } diff --git a/source/devices_pentair.c b/source/devices_pentair.c index f09effa..64ba768 100644 --- a/source/devices_pentair.c +++ b/source/devices_pentair.c @@ -62,20 +62,20 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual (packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS], packet[PEN_PPC]); - aqdata->pumps[i].rpm = (packet[PEN_HI_B_RPM] * 256) + packet[PEN_LO_B_RPM]; - aqdata->pumps[i].watts = (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT]; - aqdata->pumps[i].gpm = packet[PEN_FLOW]; - aqdata->pumps[i].mode = packet[PEN_MODE]; + SET_IF_CHANGED(aqdata->pumps[i].rpm, (packet[PEN_HI_B_RPM] * 256) + packet[PEN_LO_B_RPM], aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].watts, (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT], aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].gpm, packet[PEN_FLOW], aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].mode, packet[PEN_MODE], aqdata->is_dirty); //aqdata->pumps[i].driveState = packet[PEN_DRIVE_STATE]; - aqdata->pumps[i].status = (packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS]; - aqdata->pumps[i].pressureCurve = packet[PEN_PPC]; + SET_IF_CHANGED(aqdata->pumps[i].status, (packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS], aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].pressureCurve, packet[PEN_PPC], aqdata->is_dirty); // This is for RS485 mode only (no info from OneTouch or iAqualinkTouch) if (!isONET_ENABLED && !isIAQT_ENABLED) { if ( /*aqdata->pumps[i].mode > 0 ||*/ aqdata->pumps[i].rpm > 0 || aqdata->pumps[i].gpm > 0 || aqdata->pumps[i].watts > 0) { - aqdata->pumps[i].pStatus = PS_OK; + SET_IF_CHANGED(aqdata->pumps[i].pStatus, PS_OK, aqdata->is_dirty); } else { - aqdata->pumps[i].pStatus = PS_OFF; + SET_IF_CHANGED(aqdata->pumps[i].pStatus, PS_OFF, aqdata->is_dirty); } } diff --git a/source/iaqtouch.c b/source/iaqtouch.c index c793aaf..ea251e7 100644 --- a/source/iaqtouch.c +++ b/source/iaqtouch.c @@ -37,12 +37,12 @@ void temp_debugprintExtraInfo(unsigned char *pk, int length); #ifdef ATOUCH_TEST void set_iaq_cansend(bool yes) {} -bool in_iaqt_programming_mode(struct aqualinkdata *aq_data) {return false;} +bool in_iaqt_programming_mode(struct aqualinkdata *aqdata) {return false;} bool iaqt_queue_cmd(unsigned char cmd) {} -bool in_programming_mode(struct aqualinkdata *aq_data){return false;} -void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data){} -void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_type){} -void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data){} +bool in_programming_mode(struct aqualinkdata *aqdata){return false;} +void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aqdata){} +void kick_aq_program_thread(struct aqualinkdata *aqdata, emulation_type source_type){} +void aq_programmer(program_type type, char *args, struct aqualinkdata *aqdata){} #endif unsigned char _button_keys[] = { KEY_IAQTCH_KEY01, @@ -308,68 +308,55 @@ int matchLabel2Button(const char* pageButtonName, aqkey *aqbutton, int ignorecha } // aqualinkd button found and updated, AQstart & AQend are index of aqualinkd button array -void updateAQButtonFromPageButton(struct aqualinkdata *aq_data, struct iaqt_page_button *pageButton, int AQstartIndex, int AQendIndex) +void updateAQButtonFromPageButton(struct aqualinkdata *aqdata, struct iaqt_page_button *pageButton, int AQstartIndex, int AQendIndex) { for (int i = AQstartIndex; i < AQendIndex; i++) { - //LOG(IAQT_LOG,LOG_DEBUG, "Button compare '%s' to '%s'\n",pageButton->name, aq_data->aqbuttons[i].label); + //LOG(IAQT_LOG,LOG_DEBUG, "Button compare '%s' to '%s'\n",pageButton->name, aqdata->aqbuttons[i].label); int rtn = -1; // If we are loading HOME page then simply button name is the label ie "Aux3" // If loading DEVICES? page then button name + status is "Aux3 OFF " /* if (_currentPageLoading == IAQ_PAGE_HOME) { - rtn = rsm_strmatch((const char *)pageButton->name, aq_data->aqbuttons[i].label); - if (rtn != 0 && isVBUTTON_ALTLABEL(aq_data->aqbuttons) ) { - rtn = rsm_strmatch((const char *)pageButton->name, ((vbutton_detail *)aq_data->aqbuttons[i].special_mask_ptr)->altlabel ); + rtn = rsm_strmatch((const char *)pageButton->name, aqdata->aqbuttons[i].label); + if (rtn != 0 && isVBUTTON_ALTLABEL(aqdata->aqbuttons) ) { + rtn = rsm_strmatch((const char *)pageButton->name, ((vbutton_detail *)aqdata->aqbuttons[i].special_mask_ptr)->altlabel ); if (rtn = 0 ) { - ((vbutton_detail *)aq_data->aqbuttons[i].special_mask_ptr)->in_alt_mode = true; + ((vbutton_detail *)aqdata->aqbuttons[i].special_mask_ptr)->in_alt_mode = true; } } } else { - rtn = rsm_strmatch_ignore((const char *)pageButton->name, aq_data->aqbuttons[i].label, 5); // 5 = 3 chars and 2 spaces ' OFF ' + rtn = rsm_strmatch_ignore((const char *)pageButton->name, aqdata->aqbuttons[i].label, 5); // 5 = 3 chars and 2 spaces ' OFF ' }*/ if (_currentPageLoading == IAQ_PAGE_HOME) { - rtn = matchLabel2Button((const char *)pageButton->name, &aq_data->aqbuttons[i], 0); + rtn = matchLabel2Button((const char *)pageButton->name, &aqdata->aqbuttons[i], 0); } else { - rtn = matchLabel2Button((const char *)pageButton->name, &aq_data->aqbuttons[i], 5); // 5 = 3 chars and 2 spaces ' OFF ' + rtn = matchLabel2Button((const char *)pageButton->name, &aqdata->aqbuttons[i], 5); // 5 = 3 chars and 2 spaces ' OFF ' } if (rtn == 0) { - LOG(IAQT_LOG,LOG_DEBUG, "Found Status for %s state 0x%02hhx\n", aq_data->aqbuttons[i].label, pageButton->state); + LOG(IAQT_LOG,LOG_DEBUG, "Found Status for %s state 0x%02hhx\n", aqdata->aqbuttons[i].label, pageButton->state); switch(pageButton->state) { case 0x00: - if (aq_data->aqbuttons[i].led->state != OFF) { - aq_data->aqbuttons[i].led->state = OFF; - aq_data->updated = true; - } + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, OFF, aqdata->is_dirty); break; case 0x01: - if (aq_data->aqbuttons[i].led->state != ON) { - aq_data->aqbuttons[i].led->state = ON; - aq_data->updated = true; - } + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, ON, aqdata->is_dirty); break; case 0x02: - if (aq_data->aqbuttons[i].led->state != FLASH) { - aq_data->aqbuttons[i].led->state = FLASH; - aq_data->updated = true; - } + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, FLASH, aqdata->is_dirty); break; case 0x03: - if (aq_data->aqbuttons[i].led->state != ENABLE) { - aq_data->aqbuttons[i].led->state = ENABLE; - aq_data->updated = true; - } + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, ENABLE, aqdata->is_dirty); break; default: // Dimmer light will have the % as the state. so 0x32=50% 0x4B=75% // So anything greater than 0 use as on if (pageButton->state > 0x00) { - aq_data->aqbuttons[i].led->state = ON; - aq_data->updated = true; + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, ON, aqdata->is_dirty); } //LOG(IAQT_LOG,LOG_NOTICE, "Unknown state 0x%02hhx for button %s\n",pageButton->state,pageButton->name); break; @@ -377,45 +364,9 @@ void updateAQButtonFromPageButton(struct aqualinkdata *aq_data, struct iaqt_page } } - - // Quick and dirty check for heat pump/chiller - // if we see Heat Pump then chiller is not enabled. - // if we see chiller then it is enabled. - // Not sure why button name changes from "Heat Pump" to "Chiller", need to figure this out. (might be pump) - // THIS NEEDS TO BE DELETED AND MAKE A HEAT_PUMP / CHILLER BUTTON - /* - int ignore = 5; - if (_currentPageLoading == IAQ_PAGE_HOME) - ignore = 0; - - if ( rsm_strmatch_ignore((const char *)pageButton->name, "Heat Pump", ignore) == 0 ) { - aq_data->chiller_state = OFF; - aq_data->chiller_mode = MD_HEATPUMP; - aq_data->updated = true; - //printf("********* Disable Chiller \n"); - } else if (rsm_strmatch_ignore((const char *)pageButton->name, "Chiller", ignore) == 0) { - switch(pageButton->state) { - case 0x00: - aq_data->chiller_state = OFF; - break; - case 0x01: - aq_data->chiller_state = ON; - break; - case 0x02: - aq_data->chiller_state = FLASH; - break; - case 0x03: - aq_data->chiller_state = ENABLE; - break; - } - aq_data->chiller_mode = MD_CHILLER; - aq_data->updated = true; - LOG(IAQT_LOG,LOG_DEBUG, "*** Found Status for %s state 0x%02hhx\n", "Chiller", pageButton->state); - }*/ - } -void processPageButton(unsigned char *message, int length, struct aqualinkdata *aq_data) +void processPageButton(unsigned char *message, int length, struct aqualinkdata *aqdata) { struct iaqt_page_button *button; int index = (int)message[PKT_IAQT_BUTINDX]; @@ -460,108 +411,20 @@ void processPageButton(unsigned char *message, int length, struct aqualinkdata * // This get's called or every device state change in PDA mode, since we page over all the devices. // So capture and update the device state if (isPDA_PANEL) { - updateAQButtonFromPageButton(aq_data,button,0,aq_data->total_buttons); + updateAQButtonFromPageButton(aqdata,button,0,aqdata->total_buttons); } else { if ( PANEL_SIZE() >= 16) { - updateAQButtonFromPageButton(aq_data,button,aq_data->rs16_vbutton_start,aq_data->rs16_vbutton_end + 1); + updateAQButtonFromPageButton(aqdata,button,aqdata->rs16_vbutton_start,aqdata->rs16_vbutton_end + 1); } if ( isVirtualButtonEnabled() ) { - updateAQButtonFromPageButton(aq_data,button,aq_data->virtual_button_start,aq_data->total_buttons); + updateAQButtonFromPageButton(aqdata,button,aqdata->virtual_button_start,aqdata->total_buttons); } } - -/* - // NSF Add virtual button support below. ( || aq_data->virtual_button_start > 0 ) - if (isPDA_PANEL || PANEL_SIZE() >= 16) { - int start = 0; - int end = aq_data->total_buttons; - -#ifdef AQ_RS16 - if (PANEL_SIZE() >= 16) { - start = aq_data->rs16_vbutton_start; - end = aq_data->rs16_vbutton_end + 1; // Using < in comparison and not <=, so +1 -//printf("************ CHECK RS16 BUTTONS ************\n"); - } -#endif - - for (int i = start; i < end; i++) - { - - int rtn=-1; - //LOG(IAQT_LOG,LOG_DEBUG, "Button compare '%s' to '%s'\n",button->name, aq_data->aqbuttons[i].label); - // If we are loading HOME page then simply button name is the label ie "Aux3" - // If loading DEVICES? page then button name + status is "Aux3 OFF " - - if (_currentPageLoading == IAQ_PAGE_HOME) - rtn = rsm_strmatch((const char *)button->name, aq_data->aqbuttons[i].label); - else - rtn = rsm_strmatch_ignore((const char *)button->name, aq_data->aqbuttons[i].label,5); // 5 = 3 chars and 2 spaces ' OFF ' - - if (rtn == 0) - { - LOG(IAQT_LOG,LOG_DEBUG, "*** Found Status for %s state 0x%02hhx\n", aq_data->aqbuttons[i].label, button->state); - switch(button->state) { - case 0x00: - if (aq_data->aqbuttons[i].led->state != OFF) { - aq_data->aqbuttons[i].led->state = OFF; - aq_data->updated = true; - } - break; - case 0x01: - if (aq_data->aqbuttons[i].led->state != ON) { - aq_data->aqbuttons[i].led->state = ON; - aq_data->updated = true; - } - break; - case 0x02: - if (aq_data->aqbuttons[i].led->state != FLASH) { - aq_data->aqbuttons[i].led->state = FLASH; - aq_data->updated = true; - } - break; - case 0x03: - if (aq_data->aqbuttons[i].led->state != ENABLE) { - aq_data->aqbuttons[i].led->state = ENABLE; - aq_data->updated = true; - } - break; - default: - LOG(IAQT_LOG,LOG_NOTICE, "Unknown state 0x%02hhx for button %s\n",button->state,button->name); - break; - } - } - } - } */ } -/* No need as we can see this in buttons -typedef enum iaqt_devices{ - DEVICE_RESET = (1 << 0), - DEVICE_CHILLER = (1 << 1) -}iaqt_devices; - -void iaqt_device_update(struct aqualinkdata *aq_data, iaqt_devices mask) { - - static uint8_t device_bitmask; - - if (mask == DEVICE_RESET) { - if ( (device_bitmask & DEVICE_CHILLER) == DEVICE_CHILLER ) { - aq_data->chiller_state = ON; - LOG(IAQT_LOG,LOG_INFO, "Saw Chiller in device status\n"); - } else { - aq_data->chiller_state = OFF; - } - - device_bitmask = 0; - return; - } - - device_bitmask |= mask; -} -*/ // Log if we saw a pump in a device page cycle. -void iaqt_pump_update(struct aqualinkdata *aq_data, int updated) { +void iaqt_pump_update(struct aqualinkdata *aqdata, int updated) { const int bitmask[MAX_PUMPS] = {1,2,4,8}; static unsigned char updates = '\0'; //int i; @@ -569,26 +432,25 @@ void iaqt_pump_update(struct aqualinkdata *aq_data, int updated) { if (updated == -1) { for(int i=0; i < MAX_PUMPS; i++) { if ((updates & bitmask[i]) != bitmask[i]) { - aq_data->pumps[i].rpm = PUMP_OFF_RPM; - aq_data->pumps[i].gpm = PUMP_OFF_GPM; - aq_data->pumps[i].watts = PUMP_OFF_WAT; - aq_data->pumps[i].pStatus = PS_OFF; + SET_IF_CHANGED(aqdata->pumps[i].rpm, PUMP_OFF_RPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].gpm, PUMP_OFF_GPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].watts, PUMP_OFF_WAT, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].pStatus, PS_OFF, aqdata->is_dirty); // If Virtual pump, turn it off as well. - if (i < aq_data->num_pumps && isVBUTTON(aq_data->pumps[i].button->special_mask) && aq_data->pumps[i].button->led->state == ON ) { - LOG(IAQT_LOG,LOG_DEBUG, "Turning off virtual button pump %d - \n",aq_data->pumps[i].pumpIndex,aq_data->pumps[i].button->label); - aq_data->pumps[i].button->led->state = OFF; + if (i < aqdata->num_pumps && isVBUTTON(aqdata->pumps[i].button->special_mask) && aqdata->pumps[i].button->led->state == ON ) { + LOG(IAQT_LOG,LOG_DEBUG, "Turning off virtual button pump %d - \n",aqdata->pumps[i].pumpIndex,aqdata->pumps[i].button->label); + SET_IF_CHANGED(aqdata->pumps[i].button->led->state, OFF, aqdata->is_dirty); } LOG(IAQT_LOG,LOG_DEBUG, "Clearing pump %d\n",i); - aq_data->updated =true; } } updates = '\0'; } else if (updated >=0 && updated < MAX_PUMPS) { updates |= bitmask[updated]; LOG(IAQT_LOG,LOG_DEBUG, "Got pump update message for pump %d\n",updated); - if (updated < aq_data->num_pumps && isVBUTTON(aq_data->pumps[updated].button->special_mask) && aq_data->pumps[updated].button->led->state == OFF) { - LOG(IAQT_LOG,LOG_DEBUG, "Turning on virtual button pump %d - %s\n",aq_data->pumps[updated].pumpIndex,aq_data->pumps[updated].button->label); - aq_data->pumps[updated].button->led->state = ON; + if (updated < aqdata->num_pumps && isVBUTTON(aqdata->pumps[updated].button->special_mask) && aqdata->pumps[updated].button->led->state == OFF) { + LOG(IAQT_LOG,LOG_DEBUG, "Turning on virtual button pump %d - %s\n",aqdata->pumps[updated].pumpIndex,aqdata->pumps[updated].button->label); + SET_IF_CHANGED(aqdata->pumps[updated].button->led->state, ON, aqdata->is_dirty); } } } @@ -608,7 +470,7 @@ Info: iAQ Touch: Status page 06| #1 AquaPure\ */ -pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char *name, int *pump_index) +pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aqdata, char *name, int *pump_index) { int i; pump_detail *pump = NULL; @@ -627,13 +489,13 @@ pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char } // Now loop over all the VSP pumps and check the name. - for (i = 0; i < aq_data->num_pumps; i++) + for (i = 0; i < aqdata->num_pumps; i++) { - if ((pi > 0 && aq_data->pumps[i].pumpIndex == pi) || - (rsm_strcmp(name, aq_data->pumps[i].pumpName) == 0)) + if ((pi > 0 && aqdata->pumps[i].pumpIndex == pi) || + (rsm_strcmp(name, aqdata->pumps[i].pumpName) == 0)) { *pump_index = i; - pump = &aq_data->pumps[i]; + pump = &aqdata->pumps[i]; } } @@ -647,12 +509,12 @@ pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char else if (pump->pumpType == PT_UNKNOWN) { if (rsm_strcmp(name, "Intelliflo VS") == 0) - pump->pumpType = VSPUMP; + SET_IF_CHANGED(pump->pumpType, VSPUMP, aqdata->is_dirty); else if (rsm_strcmp(name, "Intelliflo VF") == 0) - pump->pumpType = VFPUMP; + SET_IF_CHANGED(pump->pumpType, VFPUMP, aqdata->is_dirty); else if (rsm_strcmp(name, "Jandy ePUMP") == 0 || rsm_strcmp(name, "ePump AC") == 0) - pump->pumpType = EPUMP; + SET_IF_CHANGED(pump->pumpType, EPUMP, aqdata->is_dirty); } } @@ -664,7 +526,7 @@ pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char return pump; } -void passDeviceStatusPage(struct aqualinkdata *aq_data) +void passDeviceStatusPage(struct aqualinkdata *aqdata) { int i; int pi = -2; @@ -673,92 +535,50 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) //int pump_index = 0; for (i=0; i num_pumps; pi++) { - if (aq_data->pumps[pi].pumpIndex == pump_index) { - iaqt_pump_update(aq_data, pi); // Log that we saw a pump - pump = &aq_data->pumps[pi]; - aq_data->updated =true; - if (pump->pumpType == PT_UNKNOWN){ - if (rsm_strcmp(_deviceStatus[i],"Intelliflo VS") == 0) - pump->pumpType = VSPUMP; - else if (rsm_strcmp(_deviceStatus[i],"Intelliflo VF") == 0) - pump->pumpType = VFPUMP; - else if (rsm_strcmp(_deviceStatus[i],"Jandy ePUMP") == 0 || - rsm_strcmp(_deviceStatus[i],"ePump AC") == 0) - pump->pumpType = EPUMP; - - LOG(IAQT_LOG,LOG_DEBUG, "Pump %d set to type %s\n",pump->pumpIndex, (pump->pumpType==EPUMP?"Jandy ePUMP":(pump->pumpType==VFPUMP?"Intelliflo VF":"Intelliflo VS")) ); - } - } - } - if (pump == NULL) - LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump at index %d\n",_deviceStatus[i],pump_index); - - continue; - - } else*/ if (rsm_strcmp(_deviceStatus[i],"RPM:") == 0) { - pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi); + if (rsm_strcmp(_deviceStatus[i],"RPM:") == 0) { + pump = matchPump(IAQT_LOG, aqdata, _deviceStatus[i-1], &pi); if (pump != NULL) { - iaqt_pump_update(aq_data, pi); // Log that we saw a pump - pump->rpm = rsm_atoi(&_deviceStatus[i][9]); - pump->pStatus = PS_OK; - aq_data->updated = true; + iaqt_pump_update(aqdata, pi); // Log that we saw a pump + SET_IF_CHANGED(pump->rpm, rsm_atoi(&_deviceStatus[i][9]), aqdata->is_dirty); + SET_IF_CHANGED(pump->pStatus, PS_OK, aqdata->is_dirty); } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; } else if (rsm_strcmp(_deviceStatus[i],"GPM:") == 0) { if (pump != NULL) { - pump->gpm = rsm_atoi(&_deviceStatus[i][9]); - pump->pStatus = PS_OK; - aq_data->updated = true; + SET_IF_CHANGED(pump->gpm, rsm_atoi(&_deviceStatus[i][9]), aqdata->is_dirty); + SET_IF_CHANGED(pump->pStatus, PS_OK, aqdata->is_dirty); } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; } else if (rsm_strcmp(_deviceStatus[i],"Watts:") == 0) { if (pump != NULL) { - pump->watts = rsm_atoi(&_deviceStatus[i][9]); + SET_IF_CHANGED(pump->watts, rsm_atoi(&_deviceStatus[i][9]), aqdata->is_dirty); //pump->ppStatus = DON"T SET, WE GET WATTS IN PRIMING - aq_data->updated = true; } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; } else if (rsm_strcmp(_deviceStatus[i],"*** Priming ***") == 0) { - pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi); + pump = matchPump(IAQT_LOG, aqdata, _deviceStatus[i-1], &pi); if (pump != NULL) { - iaqt_pump_update(aq_data, pi); // Log that we saw a pump - //pump->rpm = PUMP_PRIMING; // NSF need to remove future - pump->pStatus = PS_PRIMING; - aq_data->updated = true; + iaqt_pump_update(aqdata, pi); // Log that we saw a pump + SET_IF_CHANGED(pump->pStatus, PS_PRIMING, aqdata->is_dirty); } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; } else if (rsm_strcmp(_deviceStatus[i],"(Offline)") == 0) { - pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi); + pump = matchPump(IAQT_LOG, aqdata, _deviceStatus[i-1], &pi); if (pump != NULL) { - iaqt_pump_update(aq_data, pi); // Log that we saw a pump - //pump->rpm = PUMP_OFFLINE; // NSF need to remove future - pump->pStatus = PS_OFFLINE; - aq_data->updated = true; + iaqt_pump_update(aqdata, pi); // Log that we saw a pump + SET_IF_CHANGED(pump->pStatus, PS_OFFLINE, aqdata->is_dirty); } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; } else if (rsm_strcmp(_deviceStatus[i],"(Priming Error)") == 0) { - pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi); + pump = matchPump(IAQT_LOG, aqdata, _deviceStatus[i-1], &pi); if (pump != NULL) { - iaqt_pump_update(aq_data, pi); // Log that we saw a pump - //pump->rpm = PUMP_ERROR; // NSF need to remove future - pump->pStatus = PS_ERROR; - aq_data->updated = true; + iaqt_pump_update(aqdata, pi); // Log that we saw a pump + SET_IF_CHANGED(pump->pStatus, PS_ERROR, aqdata->is_dirty); } else LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]); continue; @@ -774,18 +594,6 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) Info: = ORP 750/PH 7.0 */ // Use logic under TrueSense below to get ORP & PH i++; - /* - if (rsm_strcmp(_deviceStatus[i],"ORP") == 0) { - int orp = rsm_atoi(&_deviceStatus[i][4]); - char *indx = strchr(_deviceStatus[i], '/'); - float ph = rsm_atof(indx+3); - if (aq_data->ph != ph || aq_data->orp != orp) { - aq_data->ph = ph; - aq_data->orp = orp; - } - aq_data->updated = true; - LOG(IAQT_LOG,LOG_INFO, "Set Cemlink ORP = %d PH = %f from message '%s'\n",orp,ph,_deviceStatus[i]); - }*/ } /* TruSense is different format to chemlink above @@ -800,11 +608,10 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) int orp = rsm_atoi(oi+4); float ph = rsm_atof(pi+3); if (orp > 0 && ph > 0) { - if (aq_data->ph != ph || aq_data->orp != orp) { - aq_data->ph = ph; - aq_data->orp = orp; + if (aqdata->ph != ph || aqdata->orp != orp) { + SET_IF_CHANGED(aqdata->ph, ph, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->orp, orp, aqdata->is_dirty); } - aq_data->updated = true; LOG(IAQT_LOG,LOG_INFO, "Set Cem ORP = %d PH = %f from message '%s'\n",orp,ph,_deviceStatus[i]); } else { // Didn't understand message, not @@ -814,22 +621,20 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) } if (ENABLE_CHILLER && (rsm_strcmp(_deviceStatus[i],"Chiller") == 0 || rsm_strcmp(_deviceStatus[i],"Heat Pump") == 0 )) { - processHeatPumpDisplayMessage(_deviceStatus[i], aq_data); + processHeatPumpDisplayMessage(_deviceStatus[i], aqdata); } //#ifdef READ_SWG_FROM_EXTENDED_ID else if (isPDA_PANEL) { if (rsm_strcmp(_deviceStatus[i],"AQUAPURE") == 0) { - //aq_data->swg_percent = rsm_atoi(&_deviceStatus[i][9]); - if (changeSWGpercent(aq_data, rsm_atoi(&_deviceStatus[i][9]))) - LOG(IAQT_LOG,LOG_DEBUG, "Set swg %% to %d from message'%s'\n",aq_data->swg_percent,_deviceStatus[i]); + //aqdata->swg_percent = rsm_atoi(&_deviceStatus[i][9]); + if (changeSWGpercent(aqdata, rsm_atoi(&_deviceStatus[i][9]))) + LOG(IAQT_LOG,LOG_DEBUG, "Set swg %% to %d from message'%s'\n",aqdata->swg_percent,_deviceStatus[i]); } else if (rsm_strcmp(_deviceStatus[i],"salt") == 0) { - aq_data->swg_ppm = rsm_atoi(&_deviceStatus[i][5]); - aq_data->updated = true; - LOG(IAQT_LOG,LOG_DEBUG, "Set swg PPM to %d from message'%s'\n",aq_data->swg_ppm,_deviceStatus[i]); + SET_IF_CHANGED(aqdata->swg_ppm, rsm_atoi(&_deviceStatus[i][5]), aqdata->is_dirty); + LOG(IAQT_LOG,LOG_DEBUG, "Set swg PPM to %d from message'%s'\n",aqdata->swg_ppm,_deviceStatus[i]); } else if (rsm_strcmp(_deviceStatus[i],"Boost Pool") == 0) { - aq_data->boost = true; - aq_data->updated = true; + SET_IF_CHANGED(aqdata->boost, true, aqdata->is_dirty); // Let RS pickup time remaing message. } } @@ -849,7 +654,7 @@ void debugPrintButtons(struct iaqt_page_button buttons[]) //#define member_size(type, member) (sizeof( ((type*)0)->member )) -void processPage(struct aqualinkdata *aq_data) +void processPage(struct aqualinkdata *aqdata) { //static int _home_cnt = 0; int i; @@ -866,14 +671,14 @@ void processPage(struct aqualinkdata *aq_data) LOG(IAQT_LOG,LOG_INFO, "Status page %.2d| %s\n",i,_deviceStatus[i]); debugPrintButtons(_pageButtons); - passDeviceStatusPage(aq_data); + passDeviceStatusPage(aqdata); // If button 1 is type 0x02 then there is a next page. Since status page isn't used for programming, hit the next page button. if (_pageButtons[1].type == 0x02) { iaqt_queue_cmd(KEY_IAQTCH_KEY02); } else { - iaqt_pump_update(aq_data, -1); // Reset pumps. - //iaqt_device_update(aq_data,DEVICE_RESET); // Reset any devices we monitor. - if ( (isPDA_PANEL || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aq_data) ) { + iaqt_pump_update(aqdata, -1); // Reset pumps. + //iaqt_device_update(aqdata,DEVICE_RESET); // Reset any devices we monitor. + if ( (isPDA_PANEL || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aqdata) ) { iaqt_queue_cmd(KEY_IAQTCH_HOME); } } @@ -895,7 +700,7 @@ void processPage(struct aqualinkdata *aq_data) #ifndef NEW_POLL_CYCLE // If Button 15 has type 0x02 then we have previous, if 0x00 nothing (previous send code KEY_IAQTCH_PREV_PAGE) // If Button 16 has type 0x03 then we have next, if 0x00 nothing (next send code KEY_IAQTCH_NEXT_PAGE) - if ( (isPDA_PANEL || isVirtualButtonEnabled() || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aq_data) ) { + if ( (isPDA_PANEL || isVirtualButtonEnabled() || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aqdata) ) { if (_devicePageButtons[dp][16].type == 0x03) { iaqt_queue_cmd(KEY_IAQTCH_NEXT_PAGE); } else { @@ -933,22 +738,19 @@ void processPage(struct aqualinkdata *aq_data) if (isPDA_PANEL) { // Set temp if PDA panel if (rsm_strcmp(_homeStatus[5],"Air Temp") == 0) { - aq_data->air_temp = atoi(_homeStatus[1]); - LOG(IAQT_LOG,LOG_DEBUG, "Air Temp set to %d\n",aq_data->air_temp); - aq_data->updated = true; + SET_IF_CHANGED(aqdata->air_temp, atoi(_homeStatus[1]), aqdata->is_dirty); + LOG(IAQT_LOG,LOG_DEBUG, "Air Temp set to %d\n",aqdata->air_temp); } if (rsm_strcmp(_homeStatus[4],"Pool Temp") == 0) { - aq_data->pool_temp = atoi(_homeStatus[0]); - LOG(IAQT_LOG,LOG_DEBUG, "Pool Temp set to %d\n",aq_data->air_temp); - aq_data->updated = true; + SET_IF_CHANGED(aqdata->pool_temp, atoi(_homeStatus[0]), aqdata->is_dirty); + LOG(IAQT_LOG,LOG_DEBUG, "Pool Temp set to %d\n",aqdata->air_temp); } else if (rsm_strcmp(_homeStatus[4],"Spa Temp") == 0) { - aq_data->spa_temp = atoi(_homeStatus[0]); - LOG(IAQT_LOG,LOG_DEBUG, "Spa Temp set to %d\n",aq_data->spa_temp); - aq_data->updated = true; + SET_IF_CHANGED(aqdata->spa_temp, atoi(_homeStatus[0]), aqdata->is_dirty); + LOG(IAQT_LOG,LOG_DEBUG, "Spa Temp set to %d\n",aqdata->spa_temp); } } - //passHomePage(aq_data); + //passHomePage(aqdata); debugPrintButtons(_homeButtons); break; case IAQ_PAGE_SYSTEM_SETUP: @@ -975,17 +777,17 @@ void processPage(struct aqualinkdata *aq_data) Info: iAQ Touch: Table Messages 05| TL Rev: */ - setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[2], PANEL_STRING, IAQTOUCH); - setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[3], PANEL_REV, IAQTOUCH); - setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[4], PANEL_CPU, IAQTOUCH); + setPanelInformationFromPanelMsg(aqdata, (char *)_tableInformation[2], PANEL_STRING, IAQTOUCH); + setPanelInformationFromPanelMsg(aqdata, (char *)_tableInformation[3], PANEL_REV, IAQTOUCH); + setPanelInformationFromPanelMsg(aqdata, (char *)_tableInformation[4], PANEL_CPU, IAQTOUCH); if (isPDA_PANEL && ((char *)_tableInformation[03]) > 0) { - if ( rsm_get_revision(aq_data->revision,(char *)_tableInformation[3], sizeof(aq_data->revision) ) == TRUE) { - int len = rsm_get_boardcpu(aq_data->version, sizeof(aq_data->version), (char *)_tableInformation[4], IAQT_TABLE_MSGLEN ); - sprintf(aq_data->version+len, " REV %s",aq_data->revision); - LOG(IAQT_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision); - LOG(IAQT_LOG,LOG_NOTICE, "Control Panel version %s\n", aq_data->version); - aq_data->updated = true; + if ( rsm_get_revision(aqdata->revision,(char *)_tableInformation[3], sizeof(aqdata->revision) ) == TRUE) { + int len = rsm_get_boardcpu(aqdata->version, sizeof(aqdata->version), (char *)_tableInformation[4], IAQT_TABLE_MSGLEN ); + sprintf(aqdata->version+len, " REV %s",aqdata->revision); + LOG(IAQT_LOG,LOG_NOTICE, "Control Panel revision %s\n", aqdata->revision); + LOG(IAQT_LOG,LOG_NOTICE, "Control Panel version %s\n", aqdata->version); + SET_DIRTY(aqdata->is_dirty); } } @@ -1023,7 +825,7 @@ void reset_iaqTouchPollCounter() _pollCnt = 0; } -bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) +bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata) { static bool gotInit = false; //static int _pollCnt = 0; @@ -1060,12 +862,12 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd } LOG(IAQT_LOG,LOG_NOTICE, "Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d\n", - aq_data->aqbuttons[0].led->state==OFF?"Off":"On ", - aq_data->aqbuttons[1].led->state==OFF?"Off":"On ", - aq_data->swg_percent, - aq_data->pumps[0].rpm, - aq_data->pool_htr_set_point, - aq_data->spa_htr_set_point); + aqdata->aqbuttons[0].led->state==OFF?"Off":"On ", + aqdata->aqbuttons[1].led->state==OFF?"Off":"On ", + aqdata->swg_percent, + aqdata->pumps[0].rpm, + aqdata->pool_htr_set_point, + aqdata->spa_htr_set_point); } else if (packet[PKT_CMD] == 0x70){ debuglogPacket(IAQT_LOG, packet, length, true, true); } else if (packet[PKT_CMD] == 0x71){ @@ -1075,14 +877,15 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS || packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS || packet[PKT_CMD] == CMD_IAQ_AUX_STATUS) { - process_iaqualink_packet(packet, length, aq_data); + process_iaqualink_packet(packet, length, aqdata); } else if (packet[PKT_CMD] == CMD_IAQ_PAGE_START) { // Reset and messages on new page - aq_data->last_display_message[0] = ' '; - aq_data->last_display_message[1] = '\0'; - aq_data->is_display_message_programming = false; + //aqdata->last_display_message[0] = ' '; + //aqdata->last_display_message[1] = '\0'; + SET_IF_CHANGED_STRCPY( aqdata->last_display_message, "", aqdata->is_dirty); + SET_IF_CHANGED(aqdata->is_display_message_programming, false, aqdata->is_dirty); LOG(IAQT_LOG,LOG_DEBUG, "Turning IAQ SEND off\n"); set_iaq_cansend(false); _currentPageLoading = packet[PKT_IAQT_PAGTYPE]; @@ -1113,21 +916,21 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd //Hex |0x10|0x02|0x33|0x28|0x01|0x12|0x0b|0x0d|0x2a|0xc2|0x10|0x03| //Dec | 16| 2| 51| 40| 1| 18| 11| 13| 42| 194| 16| 3 //Ascii | | | 3| (| | | | | *| | | - snprintf(aq_data->date, sizeof(aq_data->date), "%02d/%02d/%02d", packet[4],packet[5],packet[6]); + snprintf(aqdata->date, sizeof(aqdata->date), "%02d/%02d/%02d", packet[4],packet[5],packet[6]); if (packet[7] <= 12) - snprintf(aq_data->time, sizeof(aq_data->date), "%d:%02d am", packet[7],packet[8]); + snprintf(aqdata->time, sizeof(aqdata->date), "%d:%02d am", packet[7],packet[8]); else - snprintf(aq_data->time, sizeof(aq_data->date), "%d:%02d pm", (packet[7] - 12),packet[8]); + snprintf(aqdata->time, sizeof(aqdata->date), "%d:%02d pm", (packet[7] - 12),packet[8]); } - processPage(aq_data); + processPage(aqdata); } else if (packet[PKT_CMD] == CMD_IAQ_TABLE_MSG) { processTableMessage(packet, length); } else if (packet[PKT_CMD] == CMD_IAQ_PAGE_MSG) { processPageMessage(packet, length); } else if (packet[PKT_CMD] == CMD_IAQ_PAGE_BUTTON) { - processPageButton(packet, length, aq_data); + processPageButton(packet, length, aqdata); // Second page on status doesn't send start & end, but button is message, so use that to kick off next page. if (_currentPage == IAQ_PAGE_STATUS) { /* Notice: Added Button 1 @@ -1137,7 +940,7 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd * SHOULD PROBABLY USE ABOVE TO CHECK. */ //if (packet[PKT_IAQT_BUTTYPE] == 0x02 ) - processPage(aq_data); + processPage(aqdata); } // if we get a button with 0x00 state on Light Page, that's the end of page. @@ -1147,7 +950,7 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd LOG(IAQT_LOG,LOG_DEBUG, "MANUAL PAGE END\n"); _currentPage = _currentPageLoading; //_currentPageLoading = NUL; - processPage(aq_data); + processPage(aqdata); set_iaq_cansend(true); // For programming mode fake_pageend = true; @@ -1168,12 +971,12 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd *sp = '\0'; } - strcpy(aq_data->last_display_message, message); // Also display the message on web UI + SET_IF_CHANGED_STRCPY(aqdata->last_display_message, message, aqdata->is_dirty); // Also display the message on web UI - if (in_programming_mode(aq_data)) { - aq_data->is_display_message_programming = true; + if (in_programming_mode(aqdata)) { + SET_IF_CHANGED(aqdata->is_display_message_programming, true, aqdata->is_dirty); } else { - aq_data->is_display_message_programming = false; + SET_IF_CHANGED(aqdata->is_display_message_programming, false, aqdata->is_dirty); } /* for(int i=0; i= 16) && !in_iaqt_programming_mode(aq_data) ) { + //if ( (isPDA_PANEL || isVirtualButtonEnabled() || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aqdata) ) { // Just sent Status Page request if none of the above are active //} // After we send devices page in above if statment, kick us through a loop of @@ -1290,7 +1093,7 @@ if not programming && poll packet { (_currentPage == IAQ_PAGE_DEVICES || _currentPage == IAQ_PAGE_DEVICES_REV_Yg) ) { iaqt_queue_cmd(KEY_IAQTCH_STATUS); // This will force us to go to status, then it'll jump back to devices, then force status again } - } else if (in_programming_mode(aq_data) == true) { + } else if (in_programming_mode(aqdata) == true) { // Set count to something close to max, so we will pull latest info once programming has finished. // This is good for VSP GPM programming as it takes number of seconds to register once finished programming. // -5 seems to be too quick for VSP/GPM so using 10 @@ -1300,14 +1103,14 @@ if not programming && poll packet { #else //LOG(IAQT_LOG,LOG_DEBUG, "poll count %d\n",_pollCnt); // Load status page every 50 messages - if (_pollCnt++ > FULL_STATUS_POLL_COUNT && in_programming_mode(aq_data) == false ) { + if (_pollCnt++ > FULL_STATUS_POLL_COUNT && in_programming_mode(aqdata) == false ) { if (isPDA_PANEL || PANEL_SIZE() >= 16) { iaqt_queue_cmd(KEY_IAQTCH_HOMEP_KEY08); } else { iaqt_queue_cmd(KEY_IAQTCH_STATUS); } gotStatus = false; // Reset if we got status page, for fix panel bug. - //aq_programmer(AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, NULL, aq_data); + //aq_programmer(AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, NULL, aqdata); _pollCnt = 0; } else if (gotStatus == false && _pollCnt > 3) { // Fix bug with control panel where after a few hours status page disapears and you need to hit menu. @@ -1323,7 +1126,7 @@ if not programming && poll packet { */ - } else if (in_programming_mode(aq_data) == true) { + } else if (in_programming_mode(aqdata) == true) { // Set count to something close to max, so we will pull latest info once programming has finished. // This is good for VSP GPM programming as it takes number of seconds to register once finished programming. // -5 seems to be too quick for VSP/GPM so using 10 @@ -1349,7 +1152,7 @@ if not programming && poll packet { //temp_debugprintExtraInfo(packet, length); - kick_aq_program_thread(aq_data, IAQTOUCH); + kick_aq_program_thread(aqdata, IAQTOUCH); return true; } diff --git a/source/iaqtouch_aq_programmer.c b/source/iaqtouch_aq_programmer.c index 2ac82f0..b743399 100644 --- a/source/iaqtouch_aq_programmer.c +++ b/source/iaqtouch_aq_programmer.c @@ -173,24 +173,24 @@ bool waitfor_iaqt_ctrl_queue2empty() return true; } /* -unsigned const char _waitfor_iaqt_nextPage(struct aqualinkdata *aq_data, int numMessageReceived) { +unsigned const char _waitfor_iaqt_nextPage(struct aqualinkdata *aqdata, int numMessageReceived) { waitfor_iaqt_queue2empty(); int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { //LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage (%d of %d)\n",i,numMessageReceived); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) break; } LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage finished in (%d of %d)\n",i,numMessageReceived); - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) return iaqtCurrentPage(); @@ -199,12 +199,12 @@ unsigned const char _waitfor_iaqt_nextPage(struct aqualinkdata *aq_data, int num } -unsigned const char shortwaitfor_iaqt_nextPage(struct aqualinkdata *aq_data) { - return _waitfor_iaqt_nextPage(aq_data, 3); +unsigned const char shortwaitfor_iaqt_nextPage(struct aqualinkdata *aqdata) { + return _waitfor_iaqt_nextPage(aqdata, 3); } */ -unsigned const char waitfor_iaqt_messages(struct aqualinkdata *aq_data, int numMessageReceived) { - //return _waitfor_iaqt_nextPage(aq_data, 30); +unsigned const char waitfor_iaqt_messages(struct aqualinkdata *aqdata, int numMessageReceived) { + //return _waitfor_iaqt_nextPage(aqdata, 30); waitfor_iaqt_queue2empty(); @@ -212,42 +212,42 @@ unsigned const char waitfor_iaqt_messages(struct aqualinkdata *aq_data, int numM LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_messages (%d of %d)\n",i,numMessageReceived); - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { //LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage (%d of %d)\n",i,numMessageReceived); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_messages finished in (%d of %d)\n",i,numMessageReceived); - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); return iaqtLastMsg(); } -unsigned const char waitfor_iaqt_nextPage(struct aqualinkdata *aq_data) { - //return _waitfor_iaqt_nextPage(aq_data, 30); +unsigned const char waitfor_iaqt_nextPage(struct aqualinkdata *aqdata) { + //return _waitfor_iaqt_nextPage(aqdata, 30); waitfor_iaqt_queue2empty(); int i=0; const int numMessageReceived = 30; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { //LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage (%d of %d)\n",i,numMessageReceived); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) break; } LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage finished in (%d of %d)\n",i,numMessageReceived); - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) return iaqtCurrentPage(); @@ -257,23 +257,23 @@ unsigned const char waitfor_iaqt_nextPage(struct aqualinkdata *aq_data) { -unsigned const char waitfor_iaqt_nextMessage(struct aqualinkdata *aq_data, const unsigned char msg_type) { +unsigned const char waitfor_iaqt_nextMessage(struct aqualinkdata *aqdata, const unsigned char msg_type) { waitfor_iaqt_queue2empty(); int i=0; const int numMessageReceived = 30; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextMessage 0x%02hhx (%d of %d)\n",msg_type,i,numMessageReceived); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); if( msg_type == NUL || iaqtLastMsg() == msg_type) break; } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); return iaqtLastMsg(); } @@ -341,14 +341,14 @@ bool queue_iaqt_control_command_str(iaqtControlCmdYype type, char *str) { -bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { +bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aqdata) { if (iaqtCurrentPage() == pageID) return true; // If we go to Other Status Page, do that so we can quit if (pageID == IAQ_PAGE_STATUS) { send_aqt_cmd(KEY_IAQTCH_STATUS); - unsigned char rtn = waitfor_iaqt_nextPage(aq_data); + unsigned char rtn = waitfor_iaqt_nextPage(aqdata); if (rtn != IAQ_PAGE_STATUS && rtn != IAQ_PAGE_STATUS2) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Status page\n"); return false; @@ -360,7 +360,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { if (pageID == IAQ_PAGE_HOME || pageID == IAQ_PAGE_DEVICES) { if (iaqtCurrentPage() != IAQ_PAGE_HOME) { send_aqt_cmd(KEY_IAQTCH_HOME); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_HOME) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_HOME) { //LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Home page\n"); // We reset to home page after every programming cycle and error really don't care, so don't throw the error. return false; @@ -370,7 +370,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { if (pageID == IAQ_PAGE_DEVICES) { send_aqt_cmd(KEY_IAQTCH_HOMEP_KEY08); - unsigned char page = waitfor_iaqt_nextPage(aq_data); + unsigned char page = waitfor_iaqt_nextPage(aqdata); if (page != IAQ_PAGE_DEVICES && page != IAQ_PAGE_DEVICES_REV_Yg) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Device page\n"); return false; @@ -381,7 +381,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { } else if (pageID == IAQ_PAGE_ONETOUCH) { send_aqt_cmd(KEY_IAQTCH_ONETOUCH); if (iaqtCurrentPage() != IAQ_PAGE_ONETOUCH) { - unsigned char page = waitfor_iaqt_nextPage(aq_data); + unsigned char page = waitfor_iaqt_nextPage(aqdata); if (page != IAQ_PAGE_ONETOUCH ) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find OneTouch page\n"); return false; @@ -394,7 +394,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { pageID == IAQ_PAGE_VSP_SETUP) { // All other pages require us to go to Menu page send_aqt_cmd(KEY_IAQTCH_MENU); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_MENU) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_MENU) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Menu page\n"); return false; } else @@ -404,7 +404,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { // So hit those first if (pageID == IAQ_PAGE_SET_TEMP) { send_aqt_cmd(KEY_IAQTCH_SET_TEMP); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_TEMP) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_TEMP) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Set Temp page\n"); return false; } @@ -414,7 +414,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { if (pageID == IAQ_PAGE_SET_TIME) { send_aqt_cmd(KEY_IAQTCH_SET_DATETIME); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_TIME) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_TIME) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Set Time page\n"); return false; } @@ -424,7 +424,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { if (pageID == IAQ_PAGE_SET_SWG) { send_aqt_cmd(KEY_IAQTCH_SET_ACQUAPURE); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_SWG) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_SWG) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Aquapure page\n"); return false; } @@ -434,7 +434,7 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { // All pages now require us to goto System Setup send_aqt_cmd(KEY_IAQTCH_SYSTEM_SETUP); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SYSTEM_SETUP) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SYSTEM_SETUP) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find System Setup page\n"); return false; } @@ -464,16 +464,16 @@ bool goto_iaqt_page(const unsigned char pageID, struct aqualinkdata *aq_data) { if (button == NULL) { //send_aqt_cmd(KEY_IAQTCH_NEXT_PAGE); // Try Next Page - //unsigned char page = waitfor_iaqt_nextPage(aq_data); + //unsigned char page = waitfor_iaqt_nextPage(aqdata); //LOG(IAQT_LOG, LOG_ERR, "PAGE RETURN IS 0x%02hhx\n",page); - //if (waitfor_iaqt_nextPage(aq_data) != pageID) { + //if (waitfor_iaqt_nextPage(aqdata) != pageID) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find '%s' button on page setup\n", menuText); return false; //} } // send_aqt_cmd(KEY_IAQTCH_KEY01); send_aqt_cmd(button->keycode); - if (waitfor_iaqt_nextPage(aq_data) != pageID) { + if (waitfor_iaqt_nextPage(aqdata) != pageID) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find %s page\n", menuText); return false; } else @@ -490,7 +490,7 @@ void *set_aqualink_iaqtouch_device_on_off( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; //char device_name[15]; struct iaqt_page_button *button; @@ -500,43 +500,43 @@ void *set_aqualink_iaqtouch_device_on_off( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_DEVICE_ON_OFF); - if (device > aq_data->total_buttons) { + if (device > aqdata->total_buttons) { LOG(IAQT_LOG,LOG_ERR, "(PDA mode) Device On/Off :- bad device number '%d'\n",device); cleanAndTerminateThread(threadCtrl); return ptr; } - LOG(IAQT_LOG,LOG_INFO, "PDA Device On/Off, device '%s', state %d\n",aq_data->aqbuttons[device].label,state); + LOG(IAQT_LOG,LOG_INFO, "PDA Device On/Off, device '%s', state %d\n",aqdata->aqbuttons[device].label,state); // See if it's on the current page - button = iaqtFindButtonByLabel(aq_data->aqbuttons[device].label); + button = iaqtFindButtonByLabel(aqdata->aqbuttons[device].label); - if (button == NULL && isVBUTTON_ALTLABEL(aq_data->aqbuttons[device].special_mask) ) { // Try alt button name - button = iaqtFindButtonByLabel(((altlabel_detail *)aq_data->aqbuttons[device].special_mask_ptr)->altlabel); + if (button == NULL && isVBUTTON_ALTLABEL(aqdata->aqbuttons[device].special_mask) ) { // Try alt button name + button = iaqtFindButtonByLabel(((altlabel_detail *)aqdata->aqbuttons[device].special_mask_ptr)->altlabel); } if (button == NULL) { // No luck, go to the device page - if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aqdata) == false ) goto f_end; - button = iaqtFindButtonByLabel(aq_data->aqbuttons[device].label); + button = iaqtFindButtonByLabel(aqdata->aqbuttons[device].label); - if (button == NULL && isVBUTTON_ALTLABEL(aq_data->aqbuttons[device].special_mask) ) { // Try alt button name - button = iaqtFindButtonByLabel(((altlabel_detail *)aq_data->aqbuttons[device].special_mask_ptr)->altlabel); + if (button == NULL && isVBUTTON_ALTLABEL(aqdata->aqbuttons[device].special_mask) ) { // Try alt button name + button = iaqtFindButtonByLabel(((altlabel_detail *)aqdata->aqbuttons[device].special_mask_ptr)->altlabel); } // If not found see if page has next if (button == NULL && iaqtFindButtonByIndex(16)->type == 0x03 ) { iaqt_queue_cmd(KEY_IAQTCH_NEXT_PAGE); - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); // This will fail, since not looking at device page 2 buttons - button = iaqtFindButtonByLabel(aq_data->aqbuttons[device].label); + button = iaqtFindButtonByLabel(aqdata->aqbuttons[device].label); } } if (button == NULL) { - LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find '%s' button on device list\n", aq_data->aqbuttons[device].label); + LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find '%s' button on device list\n", aqdata->aqbuttons[device].label); goto f_end; } @@ -549,9 +549,9 @@ void *set_aqualink_iaqtouch_device_on_off( void *ptr ) // Color light can be cleared with a home button, but won;t turn on. waitfor_iaqt_queue2empty(); - //waitfor_iaqt_messages(aq_data,1); + //waitfor_iaqt_messages(aqdata,1); - // OR maybe use waitfor_iaqt_messages(aq_data,1) + // OR maybe use waitfor_iaqt_messages(aqdata,1) // Turn spa on when pump off, ned to remove message "spa will turn on after safty delay", home doesn't clear. send_aqt_cmd(KEY_IAQTCH_HOME); @@ -559,7 +559,7 @@ void *set_aqualink_iaqtouch_device_on_off( void *ptr ) // Turn spa off need to read message if heater is on AND hit ok...... f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -572,7 +572,7 @@ void *set_aqualink_iaqtouch_onetouch_on_off( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; //char device_name[15]; struct iaqt_page_button *button; @@ -582,17 +582,17 @@ void *set_aqualink_iaqtouch_onetouch_on_off( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF); - LOG(IAQT_LOG,LOG_INFO, "OneTouch Device On/Off, device '%s', state %d\n",aq_data->aqbuttons[device].label,state); + LOG(IAQT_LOG,LOG_INFO, "OneTouch Device On/Off, device '%s', state %d\n",aqdata->aqbuttons[device].label,state); - if ( goto_iaqt_page(IAQ_PAGE_ONETOUCH, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_ONETOUCH, aqdata) == false ) goto f_end; // See if it's on the current page - button = iaqtFindButtonByLabel(aq_data->aqbuttons[device].label); + button = iaqtFindButtonByLabel(aqdata->aqbuttons[device].label); f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -605,7 +605,7 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; //char device_name[15]; struct iaqt_page_button *button; @@ -621,13 +621,13 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) //char *buf = (char*)threadCtrl->thread_args; - if (btn < 0 || btn >= aq_data->total_buttons ) { + if (btn < 0 || btn >= aqdata->total_buttons ) { LOG(IAQT_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } - aqkey *key = &aq_data->aqbuttons[btn]; + aqkey *key = &aqdata->aqbuttons[btn]; //unsigned char code = key->code; // We also need to cater for light being ON AND changing the color mode. we have extra OK to hit. @@ -655,7 +655,7 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) if (button == NULL) { // No luck, go to the device page - if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aqdata) == false ) goto f_end; button = iaqtFindButtonByLabel(key->label); @@ -663,7 +663,7 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) // If not found see if page has next if (button == NULL && iaqtFindButtonByIndex(16)->type == 0x03 ) { iaqt_queue_cmd(KEY_IAQTCH_NEXT_PAGE); - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); // This will fail, since not looking at device page 2 buttons button = iaqtFindButtonByLabel(key->label); } @@ -682,16 +682,16 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) // a) if off turn on and default to last color. // b) if on, turn off. (pain that we need to wait 5 seconds.) waitfor_iaqt_queue2empty(); - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); if (use_current_mode) { // Their is no message for this, so give one. - sprintf(aq_data->last_display_message, "Light will turn on in 5 seconds"); - aq_data->is_display_message_programming = true; - aq_data->updated = true; + sprintf(aqdata->last_display_message, "Light will turn on in 5 seconds"); + aqdata->is_display_message_programming = true; + SET_DIRTY(aqdata->is_dirty); } // Wait for next page maybe? // Below needs a timeout. - while (waitfor_iaqt_nextPage(aq_data) == IAQ_PAGE_COLOR_LIGHT); + while (waitfor_iaqt_nextPage(aqdata) == IAQ_PAGE_COLOR_LIGHT); goto f_end; } @@ -702,7 +702,7 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) send_aqt_cmd(KEY_IAQTCH_OK); } - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_COLOR_LIGHT) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_COLOR_LIGHT) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not color light page\n"); goto f_end; } @@ -715,14 +715,14 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr ) } //LOG(IAQT_LOG, LOG_ERR, "IAQ Touch WAIYING FOR 1 MESSAGES\n"); - //waitfor_iaqt_messages(aq_data, 1); + //waitfor_iaqt_messages(aqdata, 1); // Finally found the color. select it send_aqt_cmd(button->keycode); - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -734,7 +734,7 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; char VSPstr[20]; int structIndex; @@ -746,15 +746,15 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) int pumpIndex = atoi(&buf[0]); int pumpRPM = -1; //int pumpRPM = atoi(&buf[2]); - for (structIndex=0; structIndex < aq_data->num_pumps; structIndex++) { - if (aq_data->pumps[structIndex].pumpIndex == pumpIndex) { - pumpName = aq_data->pumps[structIndex].pumpName; - if (aq_data->pumps[structIndex].pumpType == PT_UNKNOWN) { + for (structIndex=0; structIndex < aqdata->num_pumps; structIndex++) { + if (aqdata->pumps[structIndex].pumpIndex == pumpIndex) { + pumpName = aqdata->pumps[structIndex].pumpName; + if (aqdata->pumps[structIndex].pumpType == PT_UNKNOWN) { LOG(IAQT_LOG,LOG_ERR, "Can't set Pump RPM/GPM until type is known\n"); cleanAndTerminateThread(threadCtrl); return ptr; } - pumpRPM = RPM_check(aq_data->pumps[structIndex].pumpType, atoi(&buf[2]), aq_data); + pumpRPM = RPM_check(aqdata->pumps[structIndex].pumpType, atoi(&buf[2]), aqdata); break; } } @@ -770,7 +770,7 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) LOG(IAQT_LOG,LOG_NOTICE, "IAQ Touch Set Pump %d to RPM %d\n",pumpIndex,pumpRPM); - if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aqdata) == false ) goto f_end; sprintf(VSPstr, "VSP%1d Spd ADJ",pumpIndex); @@ -787,7 +787,7 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) } send_aqt_cmd(button->keycode); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_VSP) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_VSP) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find %s page\n", VSPstr); goto f_end; } @@ -801,9 +801,9 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) LOG(IAQT_LOG, LOG_INFO, "IAQ Touch got to %s page\n", VSPstr); // We should get the device page back. - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); - //goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); + //goto_iaqt_page(IAQ_PAGE_STATUS, aqdata); /* // Send Devices button. send_aqt_cmd(KEY_IAQTCH_HOME); @@ -820,11 +820,11 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) // Go to status page on startup to read devices // This is too soon - //goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); - //waitfor_iaqt_nextPage(aq_data); + //goto_iaqt_page(IAQ_PAGE_STATUS, aqdata); + //waitfor_iaqt_nextPage(aqdata); f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -835,10 +835,10 @@ void *set_aqualink_iaqtouch_vsp_assignments( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_IAQTOUCH_VSP_ASSIGNMENT); - if ( goto_iaqt_page(IAQ_PAGE_VSP_SETUP, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_VSP_SETUP, aqdata) == false ) goto f_end; /* Info: Button 00| ePump | type=0xff | state=0x00 | unknown=0xff @@ -873,7 +873,7 @@ void *set_aqualink_iaqtouch_vsp_assignments( void *ptr ) * */ f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -887,28 +887,28 @@ void *get_aqualink_iaqtouch_freezeprotect( void *ptr ) struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_IAQTOUCH_FREEZEPROTECT); - if ( goto_iaqt_page(IAQ_PAGE_FREEZE_PROTECT, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_FREEZE_PROTECT, aqdata) == false ) goto f_end; // The Message at index 0 is the deg that freeze protect is set to. int frz = rsm_atoi(iaqtGetMessageLine(0)); if (frz >= 0) { - aq_data->frz_protect_set_point = frz; - aq_data->frz_protect_state = ON; + aqdata->frz_protect_set_point = frz; + aqdata->frz_protect_state = ON; LOG(IAQT_LOG,LOG_NOTICE, "IAQ Touch Freeze Protection setpoint %d\n",frz); } // Need to run over table messages and check ens with X for on off. // Go to status page on startup to read devices - goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); + goto_iaqt_page(IAQ_PAGE_STATUS, aqdata); f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -918,29 +918,29 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; struct iaqt_page_button *button; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_IAQTOUCH_SETPOINTS); // Get product info. send_aqt_cmd(KEY_IAQTCH_HELP); - waitfor_iaqt_nextPage(aq_data); + waitfor_iaqt_nextPage(aqdata); - if ( goto_iaqt_page(IAQ_PAGE_SET_TEMP, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_SET_TEMP, aqdata) == false ) goto f_end; // Button 0 is "Pool Heat 50" // Button 2 is "Spa Heat 100" button = iaqtFindButtonByLabel("Pool Heat"); if (button != NULL) { - aq_data->pool_htr_set_point = rsm_atoi((char *)&button->name + 9); - LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Pool heater setpoint %d\n",aq_data->pool_htr_set_point); + aqdata->pool_htr_set_point = rsm_atoi((char *)&button->name + 9); + LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Pool heater setpoint %d\n",aqdata->pool_htr_set_point); } else { button = iaqtFindButtonByLabel("Temp1"); if (button != NULL) { - aq_data->pool_htr_set_point = rsm_atoi((char *)&button->name + 5); - LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Temp1 setpoint %d\n",aq_data->pool_htr_set_point); + aqdata->pool_htr_set_point = rsm_atoi((char *)&button->name + 5); + LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Temp1 setpoint %d\n",aqdata->pool_htr_set_point); if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); @@ -951,13 +951,13 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) button = iaqtFindButtonByLabel("Spa Heat"); if (button != NULL) { - aq_data->spa_htr_set_point = rsm_atoi((char *)&button->name + 8); - LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Spa heater setpoint %d\n",aq_data->spa_htr_set_point); + aqdata->spa_htr_set_point = rsm_atoi((char *)&button->name + 8); + LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Spa heater setpoint %d\n",aqdata->spa_htr_set_point); } else { button = iaqtFindButtonByLabel("Temp2"); if (button != NULL) { - aq_data->spa_htr_set_point = rsm_atoi((char *)&button->name + 5); - LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Temp2 setpoint %d\n",aq_data->spa_htr_set_point); + aqdata->spa_htr_set_point = rsm_atoi((char *)&button->name + 5); + LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Temp2 setpoint %d\n",aqdata->spa_htr_set_point); if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); @@ -968,17 +968,17 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) button = iaqtFindButtonByLabel("Chiller"); if (button != NULL) { - aq_data->chiller_set_point = rsm_atoi((char *)&button->name + 8); - LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Chiller setpoint %d\n",aq_data->chiller_set_point); + aqdata->chiller_set_point = rsm_atoi((char *)&button->name + 8); + LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch got to Chiller setpoint %d\n",aqdata->chiller_set_point); } - if ( goto_iaqt_page(IAQ_PAGE_FREEZE_PROTECT, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_FREEZE_PROTECT, aqdata) == false ) goto f_end; // The Message at index 0 is the deg that freeze protect is set to. int frz = rsm_atoi(iaqtGetMessageLine(0)); if (frz >= 0) { - aq_data->frz_protect_set_point = frz; + aqdata->frz_protect_set_point = frz; LOG(IAQT_LOG,LOG_NOTICE, "IAQ Touch Freeze Protection setpoint %d\n",frz); } @@ -988,19 +988,19 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) // Only if in PDA mode send_aqt_cmd(KEY_IAQTCH_BACK); // Clear the feeze protect menu and go back to system setup - if ( waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SYSTEM_SETUP ) + if ( waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SYSTEM_SETUP ) { LOG(IAQT_LOG,LOG_ERR, "Couldn't get back to setup page, Temperature units unknown, default to DegF\n"); - aq_data->temp_units = FAHRENHEIT; + aqdata->temp_units = FAHRENHEIT; goto f_end; } send_aqt_cmd(KEY_IAQTCH_NEXT_PAGE_ALTERNATE); // Go to page 2 - if ( waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SYSTEM_SETUP2 ) + if ( waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SYSTEM_SETUP2 ) { LOG(IAQT_LOG,LOG_ERR, "Couldn't get back to setup page, Temperature units unknown, default to DegF\n"); - aq_data->temp_units = FAHRENHEIT; + aqdata->temp_units = FAHRENHEIT; goto f_end; } @@ -1010,19 +1010,19 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) LOG(IAQT_LOG,LOG_NOTICE, "Temperature units are '%s'\n",button->name); if (button->name[8] == 'C') { LOG(IAQT_LOG,LOG_NOTICE, "Temperature unit message is '%s' set to degC\n",button->name); - aq_data->temp_units = CELSIUS; + aqdata->temp_units = CELSIUS; } else { LOG(IAQT_LOG,LOG_NOTICE, "Temperature unit message is '%s' set to degF\n",button->name); - aq_data->temp_units = FAHRENHEIT; + aqdata->temp_units = FAHRENHEIT; } /* printf("************** DEG IS '%c'\n", (uintptr_t)button->name[8]); if ( (uintptr_t)button->name[8] == 'C') { // NSF THIS DOES NOT WORK, LEAVE COMPILER WARNING TO COME BACK AND FIX - aq_data->temp_units = CELSIUS; + aqdata->temp_units = CELSIUS; } else { - aq_data->temp_units = FAHRENHEIT; + aqdata->temp_units = FAHRENHEIT; } */ } @@ -1031,10 +1031,10 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) // Need to run over table messages and check ens with X for on off. // Go to status page on startup to read devices - goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); + goto_iaqt_page(IAQ_PAGE_STATUS, aqdata); f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -1046,12 +1046,12 @@ void *get_aqualink_iaqtouch_aux_labels( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; int i; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_IAQTOUCH_AUX_LABELS); - if ( goto_iaqt_page(IAQ_PAGE_LABEL_AUX, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_LABEL_AUX, aqdata) == false ) goto f_end; // Need to loop over messages. Tab 0x09 is next in each message @@ -1081,20 +1081,20 @@ void *get_aqualink_iaqtouch_aux_labels( void *ptr ) } f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } -bool set_aqualink_iaqtouch_aquapure( struct aqualinkdata *aq_data, bool boost, int val ) +bool set_aqualink_iaqtouch_aquapure( struct aqualinkdata *aqdata, bool boost, int val ) { struct iaqt_page_button *button; static unsigned char b_pool = NUL; static unsigned char b_spa = NUL; static unsigned char b_boost = NUL; - if ( goto_iaqt_page(IAQ_PAGE_SET_SWG, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_SET_SWG, aqdata) == false ) return false; // IF pool button not set, first time here, need to cache the buttons @@ -1120,7 +1120,7 @@ bool set_aqualink_iaqtouch_aquapure( struct aqualinkdata *aq_data, bool boost, i return false; } waitfor_iaqt_queue2empty(); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_QBOOST) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_QBOOST) { LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find Boost Start button on SWG page\n"); } if(val==true) @@ -1129,10 +1129,10 @@ bool set_aqualink_iaqtouch_aquapure( struct aqualinkdata *aq_data, bool boost, i button = iaqtFindButtonByLabel("Stop"); send_aqt_cmd(button->keycode); waitfor_iaqt_queue2empty(); - waitfor_iaqt_nextPage(aq_data); - aq_data->boost = val; + waitfor_iaqt_nextPage(aqdata); + aqdata->boost = val; } else { - if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) { + if (aqdata->aqbuttons[SPA_INDEX].led->state != OFF) { if (b_spa != NUL) send_aqt_cmd(b_spa); else { @@ -1151,14 +1151,14 @@ bool set_aqualink_iaqtouch_aquapure( struct aqualinkdata *aq_data, bool boost, i waitfor_iaqt_queue2empty(); queue_iaqt_control_command(0, val); waitfor_iaqt_ctrl_queue2empty(); - waitfor_iaqt_nextMessage(aq_data, CMD_IAQ_PAGE_BUTTON); + waitfor_iaqt_nextMessage(aqdata, CMD_IAQ_PAGE_BUTTON); } //LOG(IAQT_LOG, LOG_NOTICE, "IAQ Touch got to %s page\n", VSPstr); // We should get the device page back. - //waitfor_iaqt_nextPage(aq_data); + //waitfor_iaqt_nextPage(aqdata); - goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); + goto_iaqt_page(IAQ_PAGE_STATUS, aqdata); return true; } @@ -1168,16 +1168,16 @@ void *set_aqualink_iaqtouch_swg_percent( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_SWG_PERCENT); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SWG_SETPOINT, val, aq_data); + val = setpoint_check(SWG_SETPOINT, val, aqdata); - if (set_aqualink_iaqtouch_aquapure(aq_data, false, val)) - setSWGpercent(aq_data, val); + if (set_aqualink_iaqtouch_aquapure(aqdata, false, val)) + setSWGpercent(aqdata, val); - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1187,28 +1187,28 @@ void *set_aqualink_iaqtouch_swg_boost( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_SWG_BOOST); int val = atoi((char*)threadCtrl->thread_args); //logMessage(LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); - set_aqualink_iaqtouch_aquapure(aq_data, true, val); + set_aqualink_iaqtouch_aquapure(aqdata, true, val); - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } -bool set_aqualink_iaqtouch_heater_setpoint( struct aqualinkdata *aq_data, SP_TYPE type, int val) +bool set_aqualink_iaqtouch_heater_setpoint( struct aqualinkdata *aqdata, SP_TYPE type, int val) { struct iaqt_page_button *button; char *name; - if ( goto_iaqt_page(IAQ_PAGE_SET_TEMP, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_SET_TEMP, aqdata) == false ) return false; if (isCOMBO_PANEL) { @@ -1230,7 +1230,7 @@ bool set_aqualink_iaqtouch_heater_setpoint( struct aqualinkdata *aq_data, SP_TYP button = iaqtFindButtonByLabel(name); if (button == NULL) { - //aq_data->pool_htr_set_point = rsm_atoi((char *)&button->name + 9); + //aqdata->pool_htr_set_point = rsm_atoi((char *)&button->name + 9); LOG(IAQT_LOG,LOG_ERR, "IAQ Touch did not find heater setpoint '%s' on page\n",name); return false; } @@ -1241,21 +1241,21 @@ bool set_aqualink_iaqtouch_heater_setpoint( struct aqualinkdata *aq_data, SP_TYP queue_iaqt_control_command(0, val); waitfor_iaqt_ctrl_queue2empty(); - waitfor_iaqt_nextMessage(aq_data, CMD_IAQ_PAGE_BUTTON); + waitfor_iaqt_nextMessage(aqdata, CMD_IAQ_PAGE_BUTTON); button = iaqtFindButtonByLabel(name); if (button != NULL) { int value = 0; if (type == SP_POOL) { - aq_data->pool_htr_set_point = rsm_atoi((char *)&button->name + strlen(name)); - value = aq_data->pool_htr_set_point; + aqdata->pool_htr_set_point = rsm_atoi((char *)&button->name + strlen(name)); + value = aqdata->pool_htr_set_point; } else if (type == SP_SPA) { - aq_data->spa_htr_set_point = rsm_atoi((char *)&button->name + strlen(name)); - value = aq_data->spa_htr_set_point; + aqdata->spa_htr_set_point = rsm_atoi((char *)&button->name + strlen(name)); + value = aqdata->spa_htr_set_point; } else if (type == SP_CHILLER) { - aq_data->chiller_set_point = rsm_atoi((char *)&button->name + strlen(name)); - value = aq_data->chiller_set_point; + aqdata->chiller_set_point = rsm_atoi((char *)&button->name + strlen(name)); + value = aqdata->chiller_set_point; } LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch set %s heater setpoint to %d\n",name,value); } @@ -1267,16 +1267,16 @@ void *set_aqualink_iaqtouch_spa_heater_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_SPA_HEATER_TEMP); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SPA_HTR_SETPOINT, val, aq_data); + val = setpoint_check(SPA_HTR_SETPOINT, val, aqdata); - set_aqualink_iaqtouch_heater_setpoint(aq_data, SP_SPA, val); + set_aqualink_iaqtouch_heater_setpoint(aqdata, SP_SPA, val); - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1286,16 +1286,16 @@ void *set_aqualink_iaqtouch_pool_heater_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_POOL_HEATER_TEMP); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(POOL_HTR_SETPOINT, val, aq_data); + val = setpoint_check(POOL_HTR_SETPOINT, val, aqdata); - set_aqualink_iaqtouch_heater_setpoint(aq_data, SP_POOL, val); + set_aqualink_iaqtouch_heater_setpoint(aqdata, SP_POOL, val); - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1305,16 +1305,16 @@ void *set_aqualink_iaqtouch_chiller_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_POOL_HEATER_TEMP); int val = atoi((char*)threadCtrl->thread_args); - //val = setpoint_check(POOL_HTR_SETPOINT, val, aq_data); + //val = setpoint_check(POOL_HTR_SETPOINT, val, aqdata); - set_aqualink_iaqtouch_heater_setpoint(aq_data, SP_CHILLER, val); + set_aqualink_iaqtouch_heater_setpoint(aqdata, SP_CHILLER, val); - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1324,7 +1324,7 @@ void *set_aqualink_iaqtouch_pump_vs_program( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; char VSPstr[20]; int structIndex; @@ -1335,14 +1335,14 @@ void *set_aqualink_iaqtouch_pump_vs_program( void *ptr ) int pumpIndex = atoi(&buf[0]); //int pumpRPM = -1; int vspindex = atoi(&buf[2]); - for (structIndex=0; structIndex < aq_data->num_pumps; structIndex++) { - if (aq_data->pumps[structIndex].pumpIndex == pumpIndex) { - if (aq_data->pumps[structIndex].pumpType == PT_UNKNOWN) { + for (structIndex=0; structIndex < aqdata->num_pumps; structIndex++) { + if (aqdata->pumps[structIndex].pumpIndex == pumpIndex) { + if (aqdata->pumps[structIndex].pumpType == PT_UNKNOWN) { LOG(IAQT_LOG,LOG_ERR, "Can't set Pump RPM/GPM until type is known\n"); cleanAndTerminateThread(threadCtrl); return ptr; } - //pumpRPM = RPM_check(aq_data->pumps[structIndex].pumpType, atoi(&buf[2]), aq_data); + //pumpRPM = RPM_check(aqdata->pumps[structIndex].pumpType, atoi(&buf[2]), aqdata); break; } } @@ -1353,7 +1353,7 @@ void *set_aqualink_iaqtouch_pump_vs_program( void *ptr ) LOG(IAQT_LOG,LOG_NOTICE, "Set Pump %d to VSP Index %d\n",pumpIndex,vspindex); - if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aq_data) == false ) + if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aqdata) == false ) goto f_end; button = iaqtFindButtonByLabel(VSPstr); @@ -1363,7 +1363,7 @@ void *set_aqualink_iaqtouch_pump_vs_program( void *ptr ) } send_aqt_cmd(button->keycode); - if (waitfor_iaqt_nextPage(aq_data) != IAQ_PAGE_SET_VSP) { + if (waitfor_iaqt_nextPage(aqdata) != IAQ_PAGE_SET_VSP) { LOG(IAQT_LOG, LOG_ERR, "Did not find %s page\n", VSPstr); goto f_end; } @@ -1381,7 +1381,7 @@ void *set_aqualink_iaqtouch_pump_vs_program( void *ptr ) // Probably wait. f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1391,7 +1391,7 @@ void *set_aqualink_iaqtouch_time( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; struct iaqt_page_button *button; char buf[20]; //int len; @@ -1404,7 +1404,7 @@ void *set_aqualink_iaqtouch_time( void *ptr ) struct tm *result = localtime(&now); - if ( goto_iaqt_page(IAQ_PAGE_SET_TIME, aq_data) == false ) { + if ( goto_iaqt_page(IAQ_PAGE_SET_TIME, aqdata) == false ) { LOG(IAQT_LOG,LOG_ERR, "IAQ Touch didn't find set time page\n"); goto f_end; } @@ -1453,7 +1453,7 @@ void *set_aqualink_iaqtouch_time( void *ptr ) while ( rsm_strcmp(buf, iaqtGetMessageLine(2)) != 0 && i < 3) { send_aqt_cmd(0x13); waitfor_iaqt_queue2empty(); - waitfor_iaqt_nextMessage(aq_data, CMD_IAQ_PAGE_MSG); + waitfor_iaqt_nextMessage(aqdata, CMD_IAQ_PAGE_MSG); i++; } LOG(IAQT_LOG,LOG_DEBUG, "IAQ Touch AM/PM is now '%s'\n",iaqtGetMessageLine(2)); @@ -1469,7 +1469,7 @@ void *set_aqualink_iaqtouch_time( void *ptr ) f_end: - goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + goto_iaqt_page(IAQ_PAGE_HOME, aqdata); cleanAndTerminateThread(threadCtrl); return ptr; diff --git a/source/iaqualink.c b/source/iaqualink.c index cbdb556..0ea7742 100644 --- a/source/iaqualink.c +++ b/source/iaqualink.c @@ -316,17 +316,17 @@ void set_iaqualink_heater_setpoint(int value, SP_TYPE type) { _fullcmd[10] = 0x00; } -void iAqSetButtonState(struct aqualinkdata *aq_data, int index, const unsigned char byte) +void iAqSetButtonState(struct aqualinkdata *aqdata, int index, const unsigned char byte) { - if ( aq_data->aqbuttons[index].led->state != OFF && byte == 0x00) { - aq_data->aqbuttons[index].led->state = OFF; - LOG(IAQL_LOG, LOG_INFO, "Set %s off\n",aq_data->aqbuttons[index].label); - } else if ( aq_data->aqbuttons[index].led->state != ON && byte == 0x01) { - aq_data->aqbuttons[index].led->state = ON; - LOG(IAQL_LOG, LOG_INFO, "Set %s on\n",aq_data->aqbuttons[index].label); - } else if ( aq_data->aqbuttons[index].led->state != ENABLE && byte == 0x03) { - aq_data->aqbuttons[index].led->state = ENABLE; - LOG(IAQL_LOG, LOG_INFO, "Set %s enabled\n",aq_data->aqbuttons[index].label); + if ( aqdata->aqbuttons[index].led->state != OFF && byte == 0x00) { + SET_IF_CHANGED(aqdata->aqbuttons[index].led->state, OFF, aqdata->is_dirty); + LOG(IAQL_LOG, LOG_INFO, "Set %s off\n",aqdata->aqbuttons[index].label); + } else if ( aqdata->aqbuttons[index].led->state != ON && byte == 0x01) { + SET_IF_CHANGED(aqdata->aqbuttons[index].led->state, ON, aqdata->is_dirty); + LOG(IAQL_LOG, LOG_INFO, "Set %s on\n",aqdata->aqbuttons[index].label); + } else if ( aqdata->aqbuttons[index].led->state != ENABLE && byte == 0x03) { + SET_IF_CHANGED(aqdata->aqbuttons[index].led->state, ENABLE, aqdata->is_dirty); + LOG(IAQL_LOG, LOG_INFO, "Set %s enabled\n",aqdata->aqbuttons[index].label); } } @@ -336,7 +336,7 @@ void iAqSetButtonState(struct aqualinkdata *aq_data, int index, const unsigned c So good to catch in PDA mode when a physical iAqualink device is connected to PDA panel. packet has cmd of 0x70, 0x71, 0x72 */ -bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqualinkdata *aq_data) +bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqualinkdata *aqdata) { if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS) { @@ -430,15 +430,15 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu /* if (byteType == 0) { label = "Filter Pump "; - if (isPDA_PANEL) { iAqSetButtonState(aq_data, 0, byte); } + if (isPDA_PANEL) { iAqSetButtonState(aqdata, 0, byte); } } else if (byteType == 1) { label = "Pool Heater "; // 0x00 off 0x01=on&heating, 0x03=enabled - if (isPDA_PANEL) { iAqSetButtonState(aq_data, aq_data->pool_heater_index , byte); } + if (isPDA_PANEL) { iAqSetButtonState(aqdata, aqdata->pool_heater_index , byte); } } else if (byteType == 2) { label = "Spa "; } else if (byteType == 3) { label = "Spa Heater "; // 0x01=on&heating, 0x03=ena - if (isPDA_PANEL) { iAqSetButtonState(aq_data, aq_data->spa_heater_index , byte); } + if (isPDA_PANEL) { iAqSetButtonState(aqdata, aqdata->spa_heater_index , byte); } } else if (byteType == 6) { label = "Pool Htr setpoint"; } else if (byteType == 8 || byteType == 9) {// 8 usually, also get 9 & 14 (different spa/heater modes not sorted out yet. 14 sometimes blank as well) @@ -460,14 +460,14 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu LOG(IAQL_LOG, LOG_INFO, "%-17s = %3d | index=%d type=(%0.2d 0x%02hhx) value=0x%02hhx offset=%d\n", label, byte, i, byteType, byteType, byte, (offsetIndex + i)); } LOG(IAQL_LOG, LOG_INFO, "Status from other protocols Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d, WaterTemp=%d, AirTemp=%d\n", - aq_data->aqbuttons[0].led->state == OFF ? "Off" : "On ", - aq_data->aqbuttons[1].led->state == OFF ? "Off" : "On ", - aq_data->swg_percent, - aq_data->pumps[0].rpm, - aq_data->pool_htr_set_point, - aq_data->spa_htr_set_point, - (aq_data->aqbuttons[1].led->state == OFF ? aq_data->pool_temp : aq_data->spa_temp), - aq_data->air_temp); + aqdata->aqbuttons[0].led->state == OFF ? "Off" : "On ", + aqdata->aqbuttons[1].led->state == OFF ? "Off" : "On ", + aqdata->swg_percent, + aqdata->pumps[0].rpm, + aqdata->pool_htr_set_point, + aqdata->spa_htr_set_point, + (aqdata->aqbuttons[1].led->state == OFF ? aqdata->pool_temp : aqdata->spa_temp), + aqdata->air_temp); } else if (packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS) { @@ -491,16 +491,15 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu // Check against virtual onetouch buttons. // NSF This needs to check strlingth, ie "Spa Mode" vs "Spa" - if ( aq_data->virtual_button_start > 0 ) { - for (int bi=aq_data->virtual_button_start ; bi < aq_data->total_buttons ; bi++) { - //LOG(IAQL_LOG, LOG_INFO, "Check %s against %s\n",(char *)&packet[start + 2], aq_data->aqbuttons[bi].label); - if (rsm_strcmp((char *)&packet[start + 2], aq_data->aqbuttons[bi].label) == 0) { - //LOG(IAQL_LOG, LOG_INFO, "Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); + if ( aqdata->virtual_button_start > 0 ) { + for (int bi=aqdata->virtual_button_start ; bi < aqdata->total_buttons ; bi++) { + //LOG(IAQL_LOG, LOG_INFO, "Check %s against %s\n",(char *)&packet[start + 2], aqdata->aqbuttons[bi].label); + if (rsm_strcmp((char *)&packet[start + 2], aqdata->aqbuttons[bi].label) == 0) { + //LOG(IAQL_LOG, LOG_INFO, "Status for %s is %s\n",aqdata->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); // == means doesn;t match, RS 1=on 0=off / LED enum 1=off 0=on - if (aq_data->aqbuttons[bi].led->state == status) { - LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); - aq_data->aqbuttons[bi].led->state = (status == 0x00 ? OFF:ON); - aq_data->updated = true; + if (aqdata->aqbuttons[bi].led->state == status) { + LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aqdata->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); + SET_IF_CHANGED(aqdata->aqbuttons[bi].led->state, (status == 0x00 ? OFF:ON), aqdata->is_dirty); } } } @@ -525,14 +524,15 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu LOG(IAQL_LOG, LOG_INFO, "%-15.*s = %s | bit1=0x%02hhx bit2=0x%02hhx bit3=0x%02hhx bit4=0x%02hhx\n", labellen, &packet[labelstart], (packet[status] == 0x00 ? "Off" : "On "), packet[status], packet[status + 1], packet[status + 2], packet[status + 3]); } if (isPDA_PANEL) { - for (int bi=2 ; bi < aq_data->total_buttons ; bi++) { - if (rsm_strcmp((char *)&packet[labelstart], aq_data->aqbuttons[bi].label) == 0) { - if (aq_data->aqbuttons[bi].led->state == packet[status]) { - LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(packet[status] == 0x00 ? "Off" : "On ")); - aq_data->aqbuttons[bi].led->state = (packet[status] == 0x00 ? OFF:ON); - aq_data->updated = true; + for (int bi=2 ; bi < aqdata->total_buttons ; bi++) { + if (rsm_strcmp((char *)&packet[labelstart], aqdata->aqbuttons[bi].label) == 0) { + if (aqdata->aqbuttons[bi].led->state == packet[status]) { + LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aqdata->aqbuttons[bi].label,(packet[status] == 0x00 ? "Off" : "On ")); + //aqdata->aqbuttons[bi].led->state = (packet[status] == 0x00 ? OFF:ON); + SET_IF_CHANGED(aqdata->aqbuttons[bi].led->state, (packet[status] == 0x00 ? OFF:ON), aqdata->is_dirty); + //aqdata->is_dirty = true; } - //LOG(IAQL_LOG, LOG_INFO, "Match %s to %.*s state(aqd=%d pnl=%d)\n",aq_data->aqbuttons[bi].label, labellen, (char *)&packet[labelstart], aq_data->aqbuttons[bi].led->state, packet[status]); + //LOG(IAQL_LOG, LOG_INFO, "Match %s to %.*s state(aqd=%d pnl=%d)\n",aqdata->aqbuttons[bi].label, labellen, (char *)&packet[labelstart], aqdata->aqbuttons[bi].led->state, packet[status]); } } } @@ -544,7 +544,7 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu return true; } -bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) +bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata) { lastchecksum(packet, length); @@ -610,13 +610,13 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink //push_iaqualink_cmd(cmd_getTouchstatus, 2); //push_iaqualink_cmd(cmd_getAuxstatus, 2); /* - if (aq_data->swg_percent != cur_swg && cur_swg != 0) { + if (aqdata->swg_percent != cur_swg && cur_swg != 0) { LOG(IAQL_LOG, LOG_INFO,"*****************************************\n"); - LOG(IAQL_LOG, LOG_INFO,"********** SWG Changed to %d ************\n",aq_data->swg_percent); + LOG(IAQL_LOG, LOG_INFO,"********** SWG Changed to %d ************\n",aqdata->swg_percent); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n"); exit(0); } - cur_swg = aq_data->swg_percent; + cur_swg = aqdata->swg_percent; LOG(IAQL_LOG, LOG_INFO,"******* QUEUE SWG Comand of %d | 0x%02hhx *************\n",ID,ID); ID++;*/ @@ -627,7 +627,7 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink } else if (packet[PKT_DEST] == _aqconfig_.extended_device_id || (isPDA_PANEL && packet[PKT_DEST] == _aqconfig_.device_id) ) { - process_iAqualinkStatusPacket(packet, length, aq_data); + process_iAqualinkStatusPacket(packet, length, aqdata); } return true; diff --git a/source/json_messages.c b/source/json_messages.c index 6be0623..7195238 100644 --- a/source/json_messages.c +++ b/source/json_messages.c @@ -1286,7 +1286,7 @@ const char *pumpType2String(pump_type ptype) { } */ -int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_data) +int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aqdata) { memset(&buffer[0], 0, size); int length = 0; @@ -1312,7 +1312,7 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d } */ if ((result = snprintf(buffer+length, size-length, ",\"max_pumps\": \"%d\",\"max_lights\": \"%d\",\"max_sensors\": \"%d\",\"max_light_programs\": \"%d\",\"max_vbuttons\": \"%d\"", - MAX_PUMPS,MAX_LIGHTS,MAX_SENSORS,LIGHT_COLOR_OPTIONS-1, (TOTAL_BUTTONS - aq_data->virtual_button_start) )) < 0 || result >= size-length) { + MAX_PUMPS,MAX_LIGHTS,MAX_SENSORS,LIGHT_COLOR_OPTIONS-1, (TOTAL_BUTTONS - aqdata->virtual_button_start) )) < 0 || result >= size-length) { length += snprintf(buffer+length, size-length, "}"); return length; } else { @@ -1340,7 +1340,7 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d } } - for (i = 1; i <= aq_data->num_sensors; i++) + for (i = 1; i <= aqdata->num_sensors; i++) { length += sprintf(buffer+length, ",\"sensor_%.2d\":{ \"advanced\":\"yes\",",i ); // The next json_cfg_element() call will add a , at the beginning, so save the next char index so we can delete it later. @@ -1350,36 +1350,36 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d //fprintf(fp,"sensor_%.2d_label=%s\n",i+1,aqdata->sensors->label); //fprintf(fp,"sensor_%.2d_factor=%f\n",i+1,aqdata->sensors->factor); sprintf(buf,"sensor_%.2d_path", i); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->sensors[i-1].path, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->sensors[i-1].path, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) return length; else length += result; sprintf(buf,"sensor_%.2d_label", i); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->sensors[i-1].label, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->sensors[i-1].label, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) return length; else length += result; sprintf(buf,"sensor_%.2d_factor", i); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->sensors[i-1].factor, CFG_FLOAT, 0, NULL, CFG_GRP_ADVANCED)) <= 0) + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->sensors[i-1].factor, CFG_FLOAT, 0, NULL, CFG_GRP_ADVANCED)) <= 0) return length; else length += result; sprintf(buf,"sensor_%.2d_uom", i); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->sensors[i-1].uom, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->sensors[i-1].uom, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) return length; else length += result; - //(&aq_data->sensors[i-1].uom==NULL ? "" : &aq_data->sensors[i-1].uom) + //(&aqdata->sensors[i-1].uom==NULL ? "" : &aqdata->sensors[i-1].uom) /* // Need to escape / with /// for this to work, and fix the disply that will show // for //// // Don;t forget config.c, Line 2096, search comment // NSF When fixed the JSON & config editor, put these lines back. - if (&aq_data->sensors[i-1].regex != NULL) { + if (&aqdata->sensors[i-1].regex != NULL) { sprintf(buf,"sensor_%.2d_regex", i); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->sensors[i-1].regex, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->sensors[i-1].regex, CFG_STRING, 0, NULL, CFG_GRP_ADVANCED)) <= 0) return length; else length += result; @@ -1415,50 +1415,50 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d // All buttons - for (i = 0; i < aq_data->total_buttons; i++) + for (i = 0; i < aqdata->total_buttons; i++) { char prefix[30]; - if (isVBUTTON(aq_data->aqbuttons[i].special_mask)) { - sprintf(prefix,"virtual_button_%.2d",(i+1)-aq_data->virtual_button_start); + if (isVBUTTON(aqdata->aqbuttons[i].special_mask)) { + sprintf(prefix,"virtual_button_%.2d",(i+1)-aqdata->virtual_button_start); } else { sprintf(prefix,"button_%.2d",i+1); } //length += sprintf(buffer+length, ",\"%s\":{",prefix ); - length += sprintf(buffer+length, ",\"%s\":{ \"default\":\"%s\", ",prefix, aq_data->aqbuttons[i].name ); + length += sprintf(buffer+length, ",\"%s\":{ \"default\":\"%s\", ",prefix, aqdata->aqbuttons[i].name ); // The next json_cfg_element() call will add a , at the beginning, so save the next char index so we can delete it later. delectCharAt = length; sprintf(buf,"%s_label", prefix); - if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->aqbuttons[i].label, CFG_STRING, 0, NULL, 0)) <= 0) { + if ((result = json_cfg_element(buffer+length, size-length, buf, &aqdata->aqbuttons[i].label, CFG_STRING, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; - if (isVS_PUMP(aq_data->aqbuttons[i].special_mask)) + if (isVS_PUMP(aqdata->aqbuttons[i].special_mask)) { - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpIndex > 0) { + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpIndex > 0) { sprintf(buf,"%s_pumpIndex", prefix); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpIndex, CFG_INT, 0, NULL, 0)) <= 0) { + if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpIndex, CFG_INT, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; } - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpID != NUL) { + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpID != NUL) { sprintf(buf,"%s_pumpID", prefix); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpID, CFG_HEX, 0, NULL, 0)) <= 0) { + if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpID, CFG_HEX, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; } - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpName[0] != '\0') { + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpName[0] != '\0') { sprintf(buf,"%s_pumpName", prefix); - stringptr = ((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpName; + stringptr = ((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpName; if ((result = json_cfg_element(buffer+length, size-length, buf, &stringptr, CFG_STRING, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; @@ -1466,9 +1466,9 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d length += result; } - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType != PT_UNKNOWN) { + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType != PT_UNKNOWN) { sprintf(buf,"%s_pumpType", prefix); - stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType); + stringptr = pumpType2String(((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType); if ((result = json_cfg_element(buffer+length, size-length, buf, &stringptr, CFG_STRING, 0, "[\"\", \"JANDY ePUMP\",\"Pentair VS\",\"Pentair VF\"]", 0) ) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; @@ -1476,24 +1476,24 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d length += result; } - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed != PT_UNKNOWN && - ((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed != getPumpDefaultSpeed((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr, false) ) + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed != PT_UNKNOWN && + ((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed != getPumpDefaultSpeed((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr, false) ) { sprintf(buf,"%s_pumpMinSpeed", prefix); - stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->minSpeed, CFG_INT, 0, NULL, 0) ) <= 0) { + stringptr = pumpType2String(((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType); + if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->minSpeed, CFG_INT, 0, NULL, 0) ) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; } - if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed != PT_UNKNOWN && - ((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed != getPumpDefaultSpeed((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr, true) ) + if (((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed != PT_UNKNOWN && + ((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed != getPumpDefaultSpeed((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr, true) ) { sprintf(buf,"%s_pumpMaxSpeed", prefix); - stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->maxSpeed, CFG_INT, 0, NULL, 0) ) <= 0) { + stringptr = pumpType2String(((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->pumpType); + if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aqdata->aqbuttons[i].special_mask_ptr)->maxSpeed, CFG_INT, 0, NULL, 0) ) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else @@ -1502,26 +1502,26 @@ int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_d - } else if (isPLIGHT(aq_data->aqbuttons[i].special_mask)) { - if (((clight_detail *)aq_data->aqbuttons[i].special_mask_ptr)->lightType >= 0) { + } else if (isPLIGHT(aqdata->aqbuttons[i].special_mask)) { + if (((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType >= 0) { sprintf(buf,"%s_lightMode", prefix); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((clight_detail *)aq_data->aqbuttons[i].special_mask_ptr)->lightType, CFG_INT, 0, NULL, 0)) <= 0) { + if ((result = json_cfg_element(buffer+length, size-length, buf, &((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType, CFG_INT, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; } - } else if ( (isVBUTTON(aq_data->aqbuttons[i].special_mask) && aq_data->aqbuttons[i].rssd_code >= IAQ_ONETOUCH_1 && aq_data->aqbuttons[i].rssd_code <= IAQ_ONETOUCH_6 ) ) { + } else if ( (isVBUTTON(aqdata->aqbuttons[i].special_mask) && aqdata->aqbuttons[i].rssd_code >= IAQ_ONETOUCH_1 && aqdata->aqbuttons[i].rssd_code <= IAQ_ONETOUCH_6 ) ) { sprintf(buf,"%s_onetouchID", prefix); - int oID = (aq_data->aqbuttons[i].rssd_code - 15); + int oID = (aqdata->aqbuttons[i].rssd_code - 15); if ((result = json_cfg_element(buffer+length, size-length, buf, &oID, CFG_INT, 0, "[\"\", \"1\",\"2\",\"3\",\"4\",\"5\",\"6\"]", 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else length += result; - } else if ( isVBUTTON_ALTLABEL(aq_data->aqbuttons[i].special_mask)) { + } else if ( isVBUTTON_ALTLABEL(aqdata->aqbuttons[i].special_mask)) { sprintf(buf,"%s_altlabel", prefix); - if ((result = json_cfg_element(buffer+length, size-length, buf, &((altlabel_detail *)aq_data->aqbuttons[i].special_mask_ptr)->altlabel, CFG_STRING, 0, NULL, 0)) <= 0) { + if ((result = json_cfg_element(buffer+length, size-length, buf, &((altlabel_detail *)aqdata->aqbuttons[i].special_mask_ptr)->altlabel, CFG_STRING, 0, NULL, 0)) <= 0) { LOG(NET_LOG,LOG_ERR, "Config json buffer full in, result truncated! size=%d curently used=%d\n",size,length); return length; } else diff --git a/source/net_services.c b/source/net_services.c index 5899750..0a5e982 100644 --- a/source/net_services.c +++ b/source/net_services.c @@ -451,15 +451,6 @@ void _broadcast_aqualinkstate(struct mg_connection *nc) build_aqualink_status_JSON(_aqualink_data, data, JSON_STATUS_SIZE); - #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"); - DEBUG_TIMER_CLEAR(&tid); - return; - } - #endif - - if (_mqtt_exit_flag == true) { mqtt_count++; if (mqtt_count >= 10) { @@ -468,7 +459,6 @@ void _broadcast_aqualinkstate(struct mg_connection *nc) } } - for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) { //if (is_websocket(c) && !is_websocket_simulator(c)) // No need to broadcast status messages to simulator. if (is_websocket(c)) // All button simulator needs status messages @@ -478,10 +468,6 @@ void _broadcast_aqualinkstate(struct mg_connection *nc) } - #ifdef AQ_MEMCMP - memcpy(&_last_mqtt_aqualinkdata, _aqualink_data, sizeof(struct aqualinkdata)); - #endif - DEBUG_TIMER_STOP(tid, NET_LOG, "broadcast_aqualinkstate() completed, took "); return; @@ -2123,10 +2109,6 @@ void start_mqtt(struct mg_mgr *mgr) { LOG(NET_LOG,LOG_ERR, "Failed to create MQTT listener to %s\n", _aqconfig_.mqtt_server); } else { set_mqttconnecting(nc); - //int i; -#ifdef AQ_MEMCMP - memset(&_last_mqtt_aqualinkdata, 0, sizeof (struct aqualinkdata)); -#endif reset_last_mqtt_status(); _mqtt_exit_flag = false; // set here to stop multiple connects, if it fails truley fails it will get set to false. } @@ -2214,7 +2196,9 @@ void *net_services_thread( void *ptr ) { struct aqualinkdata *aqdata = (struct aqualinkdata *) ptr; int journald_fail = 0; - //struct mg_mgr mgr; +#ifdef DEBUG_SET_IF_CHANGED + uint noupdate=0; +#endif if (!_start_net_services(&_mgr, aqdata)) { //LOG(NET_LOG,LOG_ERR, "Failed to start network services\n"); @@ -2227,15 +2211,16 @@ void *net_services_thread( void *ptr ) while (_keepNetServicesRunning == true) { - //poll_net_services(&_mgr, 10); - // Shorten poll cycle when in simulator mode mg_mgr_poll(&_mgr, (_aqualink_data->simulator_active != SIM_NONE)?10:100); - //mg_mgr_poll(&_mgr, 100); - if (aqdata->updated == true /*|| _broadcast == true*/) { - //LOG(NET_LOG,LOG_DEBUG, "********** Broadcast ************\n"); + if (aqdata->is_dirty == true /*|| _broadcast == true*/) { _broadcast_aqualinkstate(_mgr.conns); - aqdata->updated = false; + CLEAR_DIRTY(aqdata->is_dirty); +#ifdef DEBUG_SET_IF_CHANGED + printf("NO updates for %d loops\n",noupdate), noupdate=0; + } else { + noupdate += (noupdate < UINT_MAX); +#endif } #ifdef AQ_MANAGER // NSF, need to stop and disable after 5 tries, this just keeps looping. @@ -2273,9 +2258,11 @@ f_end: pthread_exit(0); } +/* void broadcast_aqualinkstate() { _aqualink_data->updated = true; } +*/ void broadcast_aqualinkstate_error(const char *msg) { _broadcast_aqualinkstate_error(_mgr.conns, msg); } diff --git a/source/onetouch.c b/source/onetouch.c index 28f9ca3..d411385 100644 --- a/source/onetouch.c +++ b/source/onetouch.c @@ -44,11 +44,11 @@ bool _panel_version_P2 = false; // Older panels REV 0.1 and 0.2 void set_macro_status(); -void pump_update(struct aqualinkdata *aq_data, int updated); -bool log_heater_setpoints(struct aqualinkdata *aq_data); +void pump_update(struct aqualinkdata *aqdata, int updated); +bool log_heater_setpoints(struct aqualinkdata *aqdata); -void rs16led_update(struct aqualinkdata *aq_data, int updated); +void rs16led_update(struct aqualinkdata *aqdata, int updated); void print_onetouch_menu() @@ -118,19 +118,19 @@ int onetouch_menu_find_index(char *text) One Touch: OneTouch Menu Line 3 = Set Pool to: 20% One Touch: OneTouch Menu Line 4 = Set Spa to:100% */ -void log_programming_information(struct aqualinkdata *aq_data) +void log_programming_information(struct aqualinkdata *aqdata) { switch(get_onetouch_menu_type()){ case OTM_SET_AQUAPURE: - if (isCOMBO_PANEL && aq_data->aqbuttons[SPA_INDEX].led->state == ON) - setSWGpercent(aq_data, rsm_atoi(&_menu[4][13])); // use spa + if (isCOMBO_PANEL && aqdata->aqbuttons[SPA_INDEX].led->state == ON) + setSWGpercent(aqdata, rsm_atoi(&_menu[4][13])); // use spa else - setSWGpercent(aq_data, rsm_atoi(&_menu[3][13])); // use pool + setSWGpercent(aqdata, rsm_atoi(&_menu[3][13])); // use pool - LOG(ONET_LOG,LOG_INFO, "SWG Set to %d\n",aq_data->swg_percent); + LOG(ONET_LOG,LOG_INFO, "SWG Set to %d\n",aqdata->swg_percent); break; case OTM_SET_TEMP: - log_heater_setpoints(aq_data); + log_heater_setpoints(aqdata); break; default: // No need to do anything yet @@ -138,7 +138,7 @@ void log_programming_information(struct aqualinkdata *aq_data) } } -bool process_onetouch_menu_packet(struct aqualinkdata *aq_data, unsigned char* packet, int length) +bool process_onetouch_menu_packet(struct aqualinkdata *aqdata, unsigned char* packet, int length) { bool rtn = true; signed char first_line; @@ -148,7 +148,7 @@ bool process_onetouch_menu_packet(struct aqualinkdata *aq_data, unsigned char* p switch (packet[PKT_CMD]) { case CMD_PDA_CLEAR: - log_programming_information(aq_data); + log_programming_information(aqdata); _ot_hlightindex = -1; _ot_hlightcharindexstart = -1; _ot_hlightcharindexstart = -1; @@ -228,32 +228,32 @@ bool process_onetouch_menu_packet(struct aqualinkdata *aq_data, unsigned char* p } -void setUnits_ot(char *str, struct aqualinkdata *aq_data) +void setUnits_ot(char *str, struct aqualinkdata *aqdata) { // NSF This needs to use setUnits from aqualinkd.c - if (aq_data->temp_units == UNKNOWN) { + if (aqdata->temp_units == UNKNOWN) { if (str[15] == 'F') - aq_data->temp_units = FAHRENHEIT; + SET_IF_CHANGED(aqdata->temp_units, FAHRENHEIT, aqdata->is_dirty); else if (str[15] == 'C') - aq_data->temp_units = CELSIUS; + SET_IF_CHANGED(aqdata->temp_units, CELSIUS, aqdata->is_dirty); else - aq_data->temp_units = UNKNOWN; + SET_IF_CHANGED(aqdata->temp_units, UNKNOWN, aqdata->is_dirty); - LOG(ONET_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aq_data->temp_units); + LOG(ONET_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aqdata->temp_units); } } -bool log_heater_setpoints(struct aqualinkdata *aq_data) +bool log_heater_setpoints(struct aqualinkdata *aqdata) { bool rtn = false; if (rsm_strcmp(_menu[2], "Pool Heat") == 0) - aq_data->pool_htr_set_point = rsm_atoi(&_menu[2][10]); + SET_IF_CHANGED(aqdata->pool_htr_set_point, rsm_atoi(&_menu[2][10]), aqdata->is_dirty); if (rsm_strcmp(_menu[3], "Spa Heat") == 0 ) - aq_data->spa_htr_set_point = rsm_atoi(&_menu[3][9]); + SET_IF_CHANGED(aqdata->spa_htr_set_point, rsm_atoi(&_menu[3][9]), aqdata->is_dirty); else { if (rsm_strcmp(_menu[2], "Temp1") == 0) { - aq_data->pool_htr_set_point = rsm_atoi(&_menu[2][10]); + SET_IF_CHANGED(aqdata->pool_htr_set_point, rsm_atoi(&_menu[2][10]), aqdata->is_dirty); if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); @@ -261,14 +261,14 @@ bool log_heater_setpoints(struct aqualinkdata *aq_data) } } if (rsm_strcmp(_menu[3], "Temp2") == 0 ) - aq_data->spa_htr_set_point = rsm_atoi(&_menu[3][9]); + SET_IF_CHANGED(aqdata->spa_htr_set_point, rsm_atoi(&_menu[3][9]), aqdata->is_dirty); } - setUnits_ot(_menu[2], aq_data); + setUnits_ot(_menu[2], aqdata); - LOG(ONET_LOG,LOG_INFO, "POOL HEATER SETPOINT %d\n",aq_data->pool_htr_set_point); - LOG(ONET_LOG,LOG_INFO, "SPA HEATER SETPOINT %d\n",aq_data->spa_htr_set_point); - aq_data->updated = true; + LOG(ONET_LOG,LOG_INFO, "POOL HEATER SETPOINT %d\n",aqdata->pool_htr_set_point); + LOG(ONET_LOG,LOG_INFO, "SPA HEATER SETPOINT %d\n",aqdata->spa_htr_set_point); + //aqdata->is_dirty = true; return rtn; } @@ -287,45 +287,45 @@ One Touch: OneTouch Menu Line 9 = One Touch: OneTouch Menu Line 10 = One Touch: OneTouch Menu Line 11 = */ -bool log_panelversion(struct aqualinkdata *aq_data) +bool log_panelversion(struct aqualinkdata *aqdata) { char *end; static bool revTest=false; - setPanelInformationFromPanelMsg(aq_data, _menu[4], PANEL_CPU, ONETOUCH); - setPanelInformationFromPanelMsg(aq_data, _menu[5], PANEL_STRING, ONETOUCH); - setPanelInformationFromPanelMsg(aq_data, _menu[7], PANEL_REV, ONETOUCH); + setPanelInformationFromPanelMsg(aqdata, _menu[4], PANEL_CPU, ONETOUCH); + setPanelInformationFromPanelMsg(aqdata, _menu[5], PANEL_STRING, ONETOUCH); + setPanelInformationFromPanelMsg(aqdata, _menu[7], PANEL_REV, ONETOUCH); // It's already been set - if (strlen(aq_data->version) > 0) { + if (strlen(aqdata->version) > 0) { // If another protocol set the version, we need to check the rev. if (!revTest){ - //LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision); - if ( strcmp(aq_data->revision, "O.1") == 0 || strcmp(aq_data->revision, "O.2") == 0 ) { + //LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aqdata->revision); + if ( strcmp(aqdata->revision, "O.1") == 0 || strcmp(aqdata->revision, "O.2") == 0 ) { LOG(ONET_LOG,LOG_NOTICE, "Setting early version for OneTouch\n"); _panel_version_P2 = true; revTest = true; } - //LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision); + //LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aqdata->revision); } return false; } - strcpy(aq_data->version, trimwhitespace(_menu[4])); + strcpy(aqdata->version, trimwhitespace(_menu[4])); // Trim trailing space - end = aq_data->version + strlen(aq_data->version) - 1; - while(end > aq_data->version && isspace(*end)) end--; + end = aqdata->version + strlen(aqdata->version) - 1; + while(end > aqdata->version && isspace(*end)) end--; strcpy(end+2, trimwhitespace(_menu[7])); // Trim trailing space - end = aq_data->version + strlen(aq_data->version) - 1; - while(end > aq_data->version && isspace(*end)) end--; + end = aqdata->version + strlen(aqdata->version) - 1; + while(end > aqdata->version && isspace(*end)) end--; - rsm_get_revision(aq_data->revision, _menu[7], AQ_MSGLEN); - LOG(ONET_LOG,LOG_NOTICE, "Control Panel version %s\n", aq_data->version); - LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision); + rsm_get_revision(aqdata->revision, _menu[7], AQ_MSGLEN); + LOG(ONET_LOG,LOG_NOTICE, "Control Panel version %s\n", aqdata->version); + LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aqdata->revision); - if ( strcmp(aq_data->revision, "O.1") == 0 || strcmp(aq_data->revision, "O.2") == 0 ) { + if ( strcmp(aqdata->revision, "O.1") == 0 || strcmp(aqdata->revision, "O.2") == 0 ) { LOG(ONET_LOG,LOG_NOTICE, "Setting early version for OneTouch\n"); _panel_version_P2 = true; } @@ -335,28 +335,28 @@ bool log_panelversion(struct aqualinkdata *aq_data) // Write new null terminator *(end+1) = 0; - LOG(ONET_LOG,LOG_DEBUG, "**** '%s' ****\n",aq_data->version); + LOG(ONET_LOG,LOG_DEBUG, "**** '%s' ****\n",aqdata->version); return true; } //Info: OneTouch Menu Line 3 = Temp 38`F -bool log_freeze_setpoints(struct aqualinkdata *aq_data) +bool log_freeze_setpoints(struct aqualinkdata *aqdata) { bool rtn = false; if (rsm_strcmp(_menu[3], "Temp") == 0) - aq_data->frz_protect_set_point = rsm_atoi(&_menu[3][11]); + aqdata->frz_protect_set_point = rsm_atoi(&_menu[3][11]); - setUnits_ot(_menu[3], aq_data); + setUnits_ot(_menu[3], aqdata); - LOG(ONET_LOG,LOG_INFO, "FREEZE PROTECT SETPOINT %d\n",aq_data->frz_protect_set_point); + LOG(ONET_LOG,LOG_INFO, "FREEZE PROTECT SETPOINT %d\n",aqdata->frz_protect_set_point); return rtn; } /* -bool get_pumpinfo_from_menu_OLD(struct aqualinkdata *aq_data, int menuLineIdx) +bool get_pumpinfo_from_menu_OLD(struct aqualinkdata *aqdata, int menuLineIdx) { int rpm = 0; int watts = 0; @@ -392,30 +392,30 @@ bool get_pumpinfo_from_menu_OLD(struct aqualinkdata *aq_data, int menuLineIdx) LOG(ONET_LOG, LOG_DEBUG, "Found Pump '%s', Index %d, RPM %d, Watts %d, GPM %d\n", _menu[menuLineIdx], pump_index, rpm, watts, gpm); - for (int i = 0; i < aq_data->num_pumps; i++) + for (int i = 0; i < aqdata->num_pumps; i++) { - if (aq_data->pumps[i].pumpIndex == pump_index) + if (aqdata->pumps[i].pumpIndex == pump_index) { // printf("**** FOUND PUMP %d at index %d *****\n",pump_index,i); - // aq_data->pumps[i].updated = true; - pump_update(aq_data, i); - aq_data->pumps[i].rpm = rpm; - aq_data->pumps[i].watts = watts; - aq_data->pumps[i].gpm = gpm; - aq_data->pumps[i].pStatus = panelStatus; + // aqdata->pumps[i].updated = true; + pump_update(aqdata, i); + aqdata->pumps[i].rpm = rpm; + aqdata->pumps[i].watts = watts; + aqdata->pumps[i].gpm = gpm; + aqdata->pumps[i].pStatus = panelStatus; // LOG(ONET_LOG,LOG_INFO, "Matched OneTouch Pump to Index %d, RPM %d, Watts %d, GPM %d\n",i,rpm,watts,gpm); - LOG(ONET_LOG, LOG_INFO, "Matched Pump to '%s', Index %d, RPM %d, Watts %d, GPM %d\n", aq_data->pumps[i].button->name, i, rpm, watts, gpm); - if (aq_data->pumps[i].pumpType == PT_UNKNOWN) + LOG(ONET_LOG, LOG_INFO, "Matched Pump to '%s', Index %d, RPM %d, Watts %d, GPM %d\n", aqdata->pumps[i].button->name, i, rpm, watts, gpm); + if (aqdata->pumps[i].pumpType == PT_UNKNOWN) { if (rsm_strcmp(_menu[2], "Intelliflo VS") == 0) - aq_data->pumps[i].pumpType = VSPUMP; + aqdata->pumps[i].pumpType = VSPUMP; else if (rsm_strcmp(_menu[2], "Intelliflo VF") == 0) - aq_data->pumps[i].pumpType = VFPUMP; + aqdata->pumps[i].pumpType = VFPUMP; else if (rsm_strcmp(_menu[2], "Jandy ePUMP") == 0 || rsm_strcmp(_menu[2], "ePump AC") == 0) - aq_data->pumps[i].pumpType = EPUMP; + aqdata->pumps[i].pumpType = EPUMP; - LOG(ONET_LOG, LOG_INFO, "Pump index %d set PumpType to %d\n", i, aq_data->pumps[i].pumpType); + LOG(ONET_LOG, LOG_INFO, "Pump index %d set PumpType to %d\n", i, aqdata->pumps[i].pumpType); } return true; } @@ -425,7 +425,7 @@ bool get_pumpinfo_from_menu_OLD(struct aqualinkdata *aq_data, int menuLineIdx) } */ -bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx, int pump_number) +bool get_pumpinfo_from_menu(struct aqualinkdata *aqdata, int menuLineIdx, int pump_number) { int rpm = 0; int watts = 0; @@ -466,26 +466,26 @@ bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx, int p LOG(ONET_LOG, LOG_DEBUG, "Found Pump information '%s', RPM %d, Watts %d, GPM %d\n", _menu[menuLineIdx], rpm, watts, gpm); - for (int i=0; i < aq_data->num_pumps; i++) { - if (aq_data->pumps[i].pumpIndex == pump_number) { - LOG(ONET_LOG,LOG_INFO, "Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d\n",aq_data->pumps[i].button->name, i ,pump_number,rpm,watts,gpm); - pump_update(aq_data, i); - aq_data->pumps[i].rpm = rpm; - aq_data->pumps[i].watts = watts; - aq_data->pumps[i].gpm = gpm; - aq_data->pumps[i].pStatus = pStatus; - if (aq_data->pumps[i].pumpType == PT_UNKNOWN){ + for (int i=0; i < aqdata->num_pumps; i++) { + if (aqdata->pumps[i].pumpIndex == pump_number) { + LOG(ONET_LOG,LOG_INFO, "Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d\n",aqdata->pumps[i].button->name, i ,pump_number,rpm,watts,gpm); + pump_update(aqdata, i); + SET_IF_CHANGED(aqdata->pumps[i].rpm, rpm, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].watts, watts, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].gpm, gpm, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].pStatus, pStatus, aqdata->is_dirty); + if (aqdata->pumps[i].pumpType == PT_UNKNOWN){ if (rsm_strcmp(_menu[menuLineIdx],"Intelliflo VS") == 0) - aq_data->pumps[i].pumpType = VSPUMP; + SET_IF_CHANGED(aqdata->pumps[i].pumpType, VSPUMP, aqdata->is_dirty); else if (rsm_strcmp(_menu[menuLineIdx],"Intelliflo VF") == 0) - aq_data->pumps[i].pumpType = VFPUMP; + SET_IF_CHANGED(aqdata->pumps[i].pumpType, VFPUMP, aqdata->is_dirty); else if (rsm_strcmp(_menu[menuLineIdx],"Jandy ePUMP") == 0 || rsm_strcmp(_menu[menuLineIdx],"ePump AC") == 0) - aq_data->pumps[i].pumpType = EPUMP; + SET_IF_CHANGED(aqdata->pumps[i].pumpType, EPUMP, aqdata->is_dirty); - LOG(ONET_LOG, LOG_INFO, "Pump index %d set PumpType to %d\n", i, aq_data->pumps[i].pumpType); + LOG(ONET_LOG, LOG_INFO, "Pump index %d set PumpType to %d\n", i, aqdata->pumps[i].pumpType); } - return true; + return aqdata->is_dirty; } } LOG(ONET_LOG,LOG_WARNING, "Could not find config for Pump %s, Number %d, RPM %d, Watts %d, GPM %d\n",_menu[menuLineIdx],pump_number,rpm,watts,gpm); @@ -498,7 +498,7 @@ bool get_pumpinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx, int p Info: OneTouch Menu Line 2 = Chemlink 1 Info: OneTouch Menu Line 3 = ORP 750/PH 7.0 */ -bool get_chemlinkinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) +bool get_chemlinkinfo_from_menu(struct aqualinkdata *aqdata, int menuLineIdx) { if (rsm_strcmp(_menu[menuLineIdx + 1], "ORP") == 0) { @@ -506,11 +506,10 @@ bool get_chemlinkinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) char *indx = strchr(_menu[menuLineIdx + 1], '/'); float ph = atof(indx + 3); LOG(ONET_LOG, LOG_INFO, "Cemlink ORP = %d PH = %f\n", orp, ph); - if (aq_data->ph != ph || aq_data->orp != orp) + if (aqdata->ph != ph || aqdata->orp != orp) { - aq_data->ph = ph; - aq_data->orp = orp; - aq_data->updated = true; + SET_IF_CHANGED(aqdata->ph, ph, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->orp, orp, aqdata->is_dirty); return true; } return false; @@ -522,7 +521,7 @@ bool get_chemlinkinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) /* Get ORP and Ph from either chemlink or truesense ORP 750/PH 7.0 */ -bool get_chemsensors_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) +bool get_chemsensors_from_menu(struct aqualinkdata *aqdata, int menuLineIdx) { char *oi = rsm_strncasestr(_menu[menuLineIdx], "ORP", AQ_MSGLEN); char *pi = rsm_strncasestr(_menu[menuLineIdx], "PH", AQ_MSGLEN); @@ -530,13 +529,12 @@ bool get_chemsensors_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) int orp = rsm_atoi(oi+4); float ph = rsm_atof(pi+3); if (orp > 0 && ph > 0) { - if (aq_data->ph != ph || aq_data->orp != orp) { - aq_data->ph = ph; - aq_data->orp = orp; + if (aqdata->ph != ph || aqdata->orp != orp) { + SET_IF_CHANGED(aqdata->ph, ph, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->orp, orp, aqdata->is_dirty); + LOG(ONET_LOG,LOG_INFO, "Set Cem ORP = %d PH = %f from message '%s'\n",orp,ph,_menu[menuLineIdx]); + return true; } - aq_data->updated = true; - LOG(ONET_LOG,LOG_INFO, "Set Cem ORP = %d PH = %f from message '%s'\n",orp,ph,_menu[menuLineIdx]); - return true; } else { // Didn't understand message, not LOG(ONET_LOG,LOG_DEBUG, "Could not extract ORP & PH from message '%s'\n",_menu[menuLineIdx]); @@ -550,25 +548,25 @@ bool get_chemsensors_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) /* Info: OneTouch Menu Line 2 = AQUAPURE 60% Info: OneTouch Menu Line 3 = Salt 7600 PPM */ -bool get_aquapureinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) +bool get_aquapureinfo_from_menu(struct aqualinkdata *aqdata, int menuLineIdx) { bool rtn = false; #ifdef READ_SWG_FROM_EXTENDED_ID int swgp = atoi(&_menu[menuLineIdx][10]); - if (aq_data->swg_percent != swgp) + if (aqdata->swg_percent != swgp) { - changeSWGpercent(aq_data, swgp); + changeSWGpercent(aqdata, swgp); rtn = true; } if (rsm_strcmp(_menu[menuLineIdx+1], "Salt") == 0) { int ppm = atoi(&_menu[menuLineIdx+1][6]); - if (aq_data->swg_ppm != ppm) + if (aqdata->swg_ppm != ppm) { - aq_data->swg_ppm = ppm; + aqdata->swg_ppm = ppm; rtn = true; } LOG(ONET_LOG, LOG_INFO, "Aquapure SWG %d%, %d PPM\n", swgp, ppm); @@ -580,16 +578,16 @@ bool get_aquapureinfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) } -bool get_RS16buttoninfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) +bool get_RS16buttoninfo_from_menu(struct aqualinkdata *aqdata, int menuLineIdx) { - for (int i = aq_data->rs16_vbutton_start; i <= aq_data->rs16_vbutton_end; i++) + for (int i = aqdata->rs16_vbutton_start; i <= aqdata->rs16_vbutton_end; i++) { - if (rsm_strcmp(_menu[menuLineIdx], aq_data->aqbuttons[i].label) == 0) + if (rsm_strcmp(_menu[menuLineIdx], aqdata->aqbuttons[i].label) == 0) { // Matched must be on. - LOG(ONET_LOG, LOG_INFO, "RS16 equiptment status '%s' matched '%s'\n", _menu[menuLineIdx], aq_data->aqbuttons[i].label); - rs16led_update(aq_data, i); - aq_data->aqbuttons[i].led->state = ON; + LOG(ONET_LOG, LOG_INFO, "RS16 equiptment status '%s' matched '%s'\n", _menu[menuLineIdx], aqdata->aqbuttons[i].label); + rs16led_update(aqdata, i); + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, ON, aqdata->is_dirty); return true; } } @@ -613,7 +611,7 @@ bool get_RS16buttoninfo_from_menu(struct aqualinkdata *aq_data, int menuLineIdx) OneTouch Menu Line 10 = OneTouch Menu Line 11 = */ -bool log_qeuiptment_status_VP2(struct aqualinkdata *aq_data) +bool log_qeuiptment_status_VP2(struct aqualinkdata *aqdata) { bool rtn = false; char *cidx = NULL; @@ -627,24 +625,24 @@ bool log_qeuiptment_status_VP2(struct aqualinkdata *aq_data) rsm_strcmp(_menu[i], "Jandy ePUMP") == 0 || rsm_strcmp(_menu[i], "ePump AC") == 0) { - rtn = get_pumpinfo_from_menu(aq_data, i); + rtn = get_pumpinfo_from_menu(aqdata, i); }*/ if ( (cidx = rsm_charafterstr(_menu[i], "Intelliflo VS", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[i], "Intelliflo VF", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[i], "Jandy ePUMP", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[i], "ePump AC", AQ_MSGLEN)) != NULL) { - rtn = get_pumpinfo_from_menu(aq_data, i, rsm_atoi(cidx)); + rtn = get_pumpinfo_from_menu(aqdata, i, rsm_atoi(cidx)); } else if (rsm_strcmp(_menu[2],"AQUAPURE") == 0) { - rtn = get_aquapureinfo_from_menu(aq_data, i); + rtn = get_aquapureinfo_from_menu(aqdata, i); } else if (rsm_strcmp(_menu[i],"Chemlink") == 0) { - rtn = get_chemlinkinfo_from_menu(aq_data, i); + rtn = get_chemlinkinfo_from_menu(aqdata, i); } else if (rsm_strcmp(_menu[i],"ORP") == 0) { // On iaqtouch TruSence does not state "Chemlink", simply OR / PH values in different format. - rtn = get_chemsensors_from_menu(aq_data, i); + rtn = get_chemsensors_from_menu(aqdata, i); } else if (PANEL_SIZE() >= 16 ) { // Loop over RS 16 buttons. - get_RS16buttoninfo_from_menu(aq_data, i); + get_RS16buttoninfo_from_menu(aqdata, i); } } @@ -654,10 +652,10 @@ bool log_qeuiptment_status_VP2(struct aqualinkdata *aq_data) /* Newer panels have a page per device and specific lines with information */ -bool log_qeuiptment_status(struct aqualinkdata *aq_data) +bool log_qeuiptment_status(struct aqualinkdata *aqdata) { if (_panel_version_P2) - return log_qeuiptment_status_VP2(aq_data); + return log_qeuiptment_status_VP2(aqdata); bool rtn = false; char *cidx = NULL; @@ -666,25 +664,25 @@ bool log_qeuiptment_status(struct aqualinkdata *aq_data) rsm_strcmp(_menu[2],"Intelliflo VF") == 0 || rsm_strcmp(_menu[2],"Jandy ePUMP") == 0 || rsm_strcmp(_menu[2],"ePump AC") == 0) { - rtn = get_pumpinfo_from_menu(aq_data, 2); + rtn = get_pumpinfo_from_menu(aqdata, 2); } */ if ( (cidx = rsm_charafterstr(_menu[2], "Intelliflo VS", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[2], "Intelliflo VF", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[2], "Jandy ePUMP", AQ_MSGLEN)) != NULL || (cidx = rsm_charafterstr(_menu[2], "ePump AC", AQ_MSGLEN)) != NULL) { - rtn = get_pumpinfo_from_menu(aq_data, 2, rsm_atoi(cidx)); + rtn = get_pumpinfo_from_menu(aqdata, 2, rsm_atoi(cidx)); } else if (rsm_strcmp(_menu[2],"AQUAPURE") == 0) { - rtn = get_aquapureinfo_from_menu(aq_data, 2); + rtn = get_aquapureinfo_from_menu(aqdata, 2); } else if (rsm_strcmp(_menu[2],"Chemlink") == 0) { - rtn = get_chemlinkinfo_from_menu(aq_data, 2); + rtn = get_chemlinkinfo_from_menu(aqdata, 2); } else if (PANEL_SIZE() >= 16 ) { // This fails on RS4, comeback and find out why. // Run over devices that have no status LED's on RS12&16 panels. //else if ( 16 <= (int)PANEL_SIZE ) { int i; for (i=2; i <= ONETOUCH_LINES; i++) { - get_RS16buttoninfo_from_menu(aq_data, i); + get_RS16buttoninfo_from_menu(aqdata, i); } } @@ -724,7 +722,7 @@ ot_menu_type get_onetouch_menu_type() return OTM_UNKNOWN; } -void pump_update(struct aqualinkdata *aq_data, int updated) { +void pump_update(struct aqualinkdata *aqdata, int updated) { const int bitmask[MAX_PUMPS] = {1,2,4,8}; static unsigned char updates = '\0'; int i; @@ -732,10 +730,10 @@ void pump_update(struct aqualinkdata *aq_data, int updated) { if (updated == -1) { for(i=0; i < MAX_PUMPS; i++) { if ((updates & bitmask[i]) != bitmask[i]) { - aq_data->pumps[i].rpm = PUMP_OFF_RPM; - aq_data->pumps[i].gpm = PUMP_OFF_GPM; - aq_data->pumps[i].watts = PUMP_OFF_WAT; - aq_data->pumps[i].pStatus = PS_OFF; + SET_IF_CHANGED(aqdata->pumps[i].rpm, PUMP_OFF_RPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].gpm, PUMP_OFF_GPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].watts, PUMP_OFF_WAT, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].pStatus, PS_OFF, aqdata->is_dirty); } } updates = '\0'; @@ -745,7 +743,7 @@ void pump_update(struct aqualinkdata *aq_data, int updated) { } -void rs16led_update(struct aqualinkdata *aq_data, int updated) { +void rs16led_update(struct aqualinkdata *aqdata, int updated) { //LOG(ONET_LOG,LOG_INFO, "******* VLED check %d ******\n",updated); const int bitmask[4] = {1,2,4,8}; static unsigned char updates = '\0'; @@ -755,22 +753,22 @@ void rs16led_update(struct aqualinkdata *aq_data, int updated) { return; if (updated == -1) { - for(i=aq_data->rs16_vbutton_start; i <= aq_data->rs16_vbutton_start; i++) { - if ((updates & bitmask[i-aq_data->rs16_vbutton_start]) != bitmask[i-aq_data->rs16_vbutton_end]) { - aq_data->aqbuttons[i].led->state = OFF; + for(i=aqdata->rs16_vbutton_start; i <= aqdata->rs16_vbutton_start; i++) { + if ((updates & bitmask[i-aqdata->rs16_vbutton_start]) != bitmask[i-aqdata->rs16_vbutton_end]) { + SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, OFF, aqdata->is_dirty); //LOG(ONET_LOG,LOG_INFO, "******* Turning off VLED %d ******\n",i); } } updates = '\0'; - } else if (updated >= aq_data->rs16_vbutton_start && updated <= aq_data->rs16_vbutton_end) { - updates |= bitmask[updated - aq_data->rs16_vbutton_start]; + } else if (updated >= aqdata->rs16_vbutton_start && updated <= aqdata->rs16_vbutton_end) { + updates |= bitmask[updated - aqdata->rs16_vbutton_start]; //LOG(ONET_LOG,LOG_INFO, "******* Updated VLED status %d ******\n",updated); } } -bool new_menu(struct aqualinkdata *aq_data) +bool new_menu(struct aqualinkdata *aqdata) { static bool initRS = false; bool rtn = false; @@ -785,39 +783,39 @@ bool new_menu(struct aqualinkdata *aq_data) break; case OTM_EQUIPTMENT_STATUS: if (initRS == false) { - queueGetProgramData(ONETOUCH, aq_data); + queueGetProgramData(ONETOUCH, aqdata); initRS = true; } - rtn = log_qeuiptment_status(aq_data); + rtn = log_qeuiptment_status(aqdata); // Hit select to get to next menu ASAP. - if ( in_ot_programming_mode(aq_data) == false ) + if ( in_ot_programming_mode(aqdata) == false ) ot_queue_cmd(KEY_ONET_SELECT); break; case OTM_SET_TEMP: - rtn = log_heater_setpoints(aq_data); + rtn = log_heater_setpoints(aqdata); break; case OTM_FREEZE_PROTECT: - rtn = log_freeze_setpoints(aq_data); + rtn = log_freeze_setpoints(aqdata); break; case OTM_VERSION: - rtn = log_panelversion(aq_data); + rtn = log_panelversion(aqdata); LOG(ONET_LOG,LOG_DEBUG, "**** ONETOUCH INIT ****\n"); - queueGetProgramData(ONETOUCH, aq_data); + queueGetProgramData(ONETOUCH, aqdata); //set_aqualink_onetouch_pool_heater_temp() - //aq_programmer(AQ_SET_ONETOUCH_POOL_HEATER_TEMP, "95", aq_data); - //aq_programmer(AQ_SET_ONETOUCH_SPA_HEATER_TEMP, "94", aq_data); + //aq_programmer(AQ_SET_ONETOUCH_POOL_HEATER_TEMP, "95", aqdata); + //aq_programmer(AQ_SET_ONETOUCH_SPA_HEATER_TEMP, "94", aqdata); initRS = true; break; default: break; } - if (last_menu_type == OTM_EQUIPTMENT_STATUS && menu_type != OTM_EQUIPTMENT_STATUS && !in_ot_programming_mode(aq_data) ) { + if (last_menu_type == OTM_EQUIPTMENT_STATUS && menu_type != OTM_EQUIPTMENT_STATUS && !in_ot_programming_mode(aqdata) ) { // End of equiptment status chain of menus, reset any pump that wasn't listed in menus as long as we are not in programming mode - pump_update(aq_data, -1); + pump_update(aqdata, -1); if (PANEL_SIZE() >= 16) - rs16led_update(aq_data, -1); + rs16led_update(aqdata, -1); } @@ -872,7 +870,7 @@ void set_onetouch_lastmsg(unsigned char msgtype) _last_msg_type = msgtype; } -bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) +bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata) { static bool filling_menu = false; bool rtn = false; @@ -886,7 +884,7 @@ bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkd //LOG(ONET_LOG,LOG_DEBUG, "RS Received ONETOUCH 0x%02hhx\n", packet[PKT_CMD]); //debuglogPacket(packet, length); - process_onetouch_menu_packet(aq_data, packet, length); + process_onetouch_menu_packet(aqdata, packet, length); // Check for new menu. // Usually PDA_CLEAR bunch of CMD_MSG_LONG then a CMD_PDA_HIGHLIGHT or CMD_PDA_HIGHLIGHTCHARS @@ -900,7 +898,7 @@ bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkd ) { filling_menu = false; - rtn = new_menu(aq_data); + rtn = new_menu(aqdata); _last_kick_type = KICKT_MENU; } else { _last_kick_type = KICKT_CMD; @@ -913,7 +911,7 @@ bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkd /* //if (_last_msg_type == CMD_MSG_LONG && packet[PKT_CMD] != CMD_MSG_LONG) { if (_last_msg_type == CMD_MSG_LONG && ( packet[PKT_CMD] != CMD_MSG_LONG && packet[PKT_CMD] != CMD_PDA_HIGHLIGHTCHARS) ) { // CMD_PDA_SHIFTLINES - rtn = new_menu(aq_data); + rtn = new_menu(aqdata); _last_kick_type = KICKT_MENU; } else { _last_kick_type = KICKT_CMD; @@ -938,8 +936,8 @@ bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkd //debuglogPacket(packet, length); - //if ( in_ot_programming_mode(aq_data) == true ) - kick_aq_program_thread(aq_data, ONETOUCH); + //if ( in_ot_programming_mode(aqdata) == true ) + kick_aq_program_thread(aqdata, ONETOUCH); /* switch (packet[PKT_CMD]) { diff --git a/source/onetouch_aq_programmer.c b/source/onetouch_aq_programmer.c index 4e9ef2a..113dedf 100644 --- a/source/onetouch_aq_programmer.c +++ b/source/onetouch_aq_programmer.c @@ -83,12 +83,12 @@ void send_ot_cmd(unsigned char cmd) LOG(ONET_LOG,LOG_INFO, "OneTouch Queue send '0x%02hhx' to controller (programming)\n", _ot_pgm_command); } -bool waitForOT_MessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived) +bool waitForOT_MessageTypes(struct aqualinkdata *aqdata, unsigned char mtype1, unsigned char mtype2, int numMessageReceived) { //LOG(ONET_LOG,LOG_DEBUG, "waitForOT_MessageType 0x%02hhx || 0x%02hhx\n",mtype1,mtype2); int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { @@ -96,10 +96,10 @@ bool waitForOT_MessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, if (*last_onetouch_packet() == mtype1 || *last_onetouch_packet() == mtype2) break; - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (*last_onetouch_packet() != mtype1 && *last_onetouch_packet() != mtype2) { //LOG(ONET_LOG,LOG_ERR, "Could not select MENU of Aqualink control panel\n"); @@ -111,14 +111,14 @@ bool waitForOT_MessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, return true; } -bool waitForNextOT_Menu(struct aqualinkdata *aq_data) { - //waitForOT_MessageTypes(aq_data,CMD_PDA_CLEAR,CMD_PDA_0x04,10); - //return waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); +bool waitForNextOT_Menu(struct aqualinkdata *aqdata) { + //waitForOT_MessageTypes(aqdata,CMD_PDA_CLEAR,CMD_PDA_0x04,10); + //return waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); int i=0; const int numMessageReceived = 20; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= 20) { @@ -126,11 +126,11 @@ bool waitForNextOT_Menu(struct aqualinkdata *aq_data) { //if(thread_kick_type() == KICKT_MENU) break; - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); if(thread_kick_type() == KICKT_MENU) break; } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if(thread_kick_type() == KICKT_MENU) return true; @@ -138,7 +138,7 @@ bool waitForNextOT_Menu(struct aqualinkdata *aq_data) { return false; } -bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) +bool highlight_onetouch_menu_item(struct aqualinkdata *aqdata, char *item) { int i; int index; @@ -151,7 +151,7 @@ bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) for (i=0; i < cnt; i ++) { send_ot_cmd(KEY_ONET_DOWN); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,3); + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,3); if (rsm_strcmp(onetouch_menu_hlight(), item) == 0) { // We got here early, probably because blank menu item break; @@ -165,7 +165,7 @@ bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) for (i=0; i < cnt; i ++) { send_ot_cmd(KEY_ONET_DOWN); //waitfor_ot_queue2empty(); - //waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + //waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } } else { cnt = 11 - cnt; @@ -173,21 +173,21 @@ bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) for (i=0; i < cnt; i ++) { send_ot_cmd(KEY_ONET_UP); //waitfor_ot_queue2empty(); - //waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + //waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } }*/ // Not much quicker doing it this way that in the for loops above, may have to change back. //waitfor_ot_queue2empty(); - //waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + //waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } else { // Is their another page to search if (rsm_strcmp(onetouch_menu_line(10), "^^ More") == 0) { char first_item[AQ_MSGLEN+1]; do { send_ot_cmd(KEY_ONET_PAGE_DN); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); if (onetouch_menu_find_index(item) != -1) { - return highlight_onetouch_menu_item(aq_data, item); + return highlight_onetouch_menu_item(aqdata, item); } } while (strncpy(first_item, onetouch_menu_line(1), AQ_MSGLEN)); // Need to get menu item 1. @@ -206,18 +206,18 @@ bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) } } -bool select_onetouch_menu_item(struct aqualinkdata *aq_data, char *item) +bool select_onetouch_menu_item(struct aqualinkdata *aqdata, char *item) { - if (highlight_onetouch_menu_item(aq_data, item)) { + if (highlight_onetouch_menu_item(aqdata, item)) { send_ot_cmd(KEY_ONET_SELECT); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); return true; } return false; } -bool goto_onetouch_system_menu(struct aqualinkdata *aq_data) +bool goto_onetouch_system_menu(struct aqualinkdata *aqdata) { int i=0; @@ -228,7 +228,7 @@ bool goto_onetouch_system_menu(struct aqualinkdata *aq_data) while (get_onetouch_menu_type() != OTM_SYSTEM && get_onetouch_menu_type() != OTM_ONETOUCH && i < 5 ) { send_ot_cmd(KEY_ONET_BACK); waitfor_ot_queue2empty(); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); i++; } @@ -240,11 +240,11 @@ bool goto_onetouch_system_menu(struct aqualinkdata *aq_data) // Can only be one of 2 options in this menu, so if it's not the one we want, hit down first if ( rsm_strcmp(onetouch_menu_hlight(), "System") != 0) { send_ot_cmd(KEY_ONET_DOWN); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); //return false; } else { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer couldn't get to System menu\n"); @@ -262,7 +262,7 @@ bool goto_onetouch_system_menu(struct aqualinkdata *aq_data) return true; } -bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu) +bool goto_onetouch_menu(struct aqualinkdata *aqdata, ot_menu_type menu) { bool equErr = false; char *second_menu = false; @@ -270,7 +270,7 @@ bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu) LOG(ONET_LOG,LOG_DEBUG, "OneTouch device programmer request for menu %d\n",menu); - if ( ! goto_onetouch_system_menu(aq_data) ) { + if ( ! goto_onetouch_system_menu(aqdata) ) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get system menu\n"); return false; } @@ -313,7 +313,7 @@ bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu) return true; break; case OTM_EQUIPTMENT_ONOFF: - if ( select_onetouch_menu_item(aq_data, "Equipment ON/OFF") == false ) { + if ( select_onetouch_menu_item(aqdata, "Equipment ON/OFF") == false ) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer couldn't select 'Equipment ON/OFF' menu %d\n",menu); equErr = true; } @@ -325,14 +325,14 @@ bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu) case OTM_FREEZE_PROTECT: case OTM_BOOST: case OTM_SYSTEM_SETUP: - if ( select_onetouch_menu_item(aq_data, "Menu / Help") == false ) { + if ( select_onetouch_menu_item(aqdata, "Menu / Help") == false ) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer couldn't select menu %d\n",menu); break; } if (second_menu) - select_onetouch_menu_item(aq_data, second_menu); + select_onetouch_menu_item(aqdata, second_menu); if (third_menu) - select_onetouch_menu_item(aq_data, third_menu); + select_onetouch_menu_item(aqdata, third_menu); break; default: LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer doesn't know how to access menu %d\n",menu); @@ -346,7 +346,7 @@ bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu) // Need to wait a bit longer for set temp menu if single device (nag screen temp1 higher than temp2) if ( menu == OTM_SET_TEMP && get_onetouch_menu_type() != menu) { - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); } if (get_onetouch_menu_type() != menu) @@ -399,7 +399,7 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; char *buf = (char*)threadCtrl->thread_args; char VSPstr[20]; int i, structIndex; @@ -409,14 +409,14 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) int pumpIndex = atoi(&buf[0]); int pumpRPM = -1; //int pumpRPM = atoi(&buf[2]); - for (structIndex=0; structIndex < aq_data->num_pumps; structIndex++) { - if (aq_data->pumps[structIndex].pumpIndex == pumpIndex) { - if (aq_data->pumps[structIndex].pumpType == PT_UNKNOWN) { + for (structIndex=0; structIndex < aqdata->num_pumps; structIndex++) { + if (aqdata->pumps[structIndex].pumpIndex == pumpIndex) { + if (aqdata->pumps[structIndex].pumpType == PT_UNKNOWN) { LOG(ONET_LOG,LOG_ERR, "Can't set Pump RPM/GPM until type is known\n"); cleanAndTerminateThread(threadCtrl); return ptr; } - pumpRPM = RPM_check(aq_data->pumps[structIndex].pumpType, atoi(&buf[2]), aq_data); + pumpRPM = RPM_check(aqdata->pumps[structIndex].pumpType, atoi(&buf[2]), aqdata); break; } } @@ -427,7 +427,7 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) LOG(ONET_LOG,LOG_INFO, "OneTouch Set Pump %d to RPM %d\n",pumpIndex,pumpRPM); - if (! goto_onetouch_menu(aq_data, OTM_EQUIPTMENT_ONOFF) ){ + if (! goto_onetouch_menu(aqdata, OTM_EQUIPTMENT_ONOFF) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer didn't get Equiptment on/off menu\n"); } @@ -440,9 +440,9 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) waitfor_ot_queue2empty(); } send_ot_cmd(KEY_ONET_SELECT); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); */ - if ( select_onetouch_menu_item(aq_data, VSPstr) ) { + if ( select_onetouch_menu_item(aqdata, VSPstr) ) { if ( get_onetouch_menu_type() == OTM_SELECT_SPEED) { // Now fine menu item with X as last digit, and select that menu. //Pool X @@ -450,11 +450,11 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) if ( onetouch_menu_hlight()[15] != 'X' ) { send_ot_cmd(KEY_ONET_DOWN); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } else { send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForNextOT_Menu(aq_data); + waitForNextOT_Menu(aqdata); break; } } @@ -484,10 +484,10 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) RPM = rsm_atoi(&onetouch_menu_hlight()[7]); intPress(digitDiff(RPM, pumpRPM, 10)); // Get the new RPM. - aq_data->pumps[structIndex].rpm = rsm_atoi(&onetouch_menu_hlight()[7]); + aqdata->pumps[structIndex].rpm = rsm_atoi(&onetouch_menu_hlight()[7]); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_MSG_LONG,CMD_PDA_HIGHLIGHTCHARS,5); + waitForOT_MessageTypes(aqdata,CMD_MSG_LONG,CMD_PDA_HIGHLIGHTCHARS,5); //} else if (strstr(onetouch_menu_hlight(), "GPM") != NULL ) { } else if (rsm_strstr(onetouch_menu_hlight(), "GPM") != NULL ) { // GPM 130 max, GPM 15 min @@ -499,19 +499,19 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) } else if (GPM < pumpRPM) { send_ot_cmd(KEY_ONET_UP); } else { - aq_data->pumps[structIndex].gpm = rsm_atoi(&onetouch_menu_hlight()[8]);; + aqdata->pumps[structIndex].gpm = rsm_atoi(&onetouch_menu_hlight()[8]);; send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); break; } waitfor_ot_queue2empty(); // This really does slow it down, but we hit up.down once too ofter without it, need to fix. - //waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); - waitForOT_MessageTypes(aq_data,CMD_MSG_LONG,CMD_PDA_HIGHLIGHTCHARS,5); + //waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); + waitForOT_MessageTypes(aqdata,CMD_MSG_LONG,CMD_PDA_HIGHLIGHTCHARS,5); // Reset the pump GPM - //aq_data->pumps[structIndex].rpm = GPM; - //waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,5); - //waitForNextOT_Menu(aq_data); + //aqdata->pumps[structIndex].rpm = GPM; + //waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,5); + //waitForNextOT_Menu(aqdata); } } else { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer Not sure how to set '%s'\n",onetouch_menu_hlight()); @@ -529,7 +529,7 @@ void *set_aqualink_onetouch_pump_rpm( void *ptr ) //printf("**** GOT THIS FAR, NOW LET'S GO BACK ****\n"); - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_WARNING, "OneTouch device programmer didn't get back to System menu\n"); } @@ -559,7 +559,7 @@ void *set_aqualink_onetouch_macro( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - //struct aqualinkdata *aq_data = threadCtrl->aq_data; + //struct aqualinkdata *aqdata = threadCtrl->aqdata; //sprintf(msg, "%-5d%-5d",index, (strcmp(value, "on") == 0)?ON:OFF); // Use above to set @@ -583,21 +583,21 @@ void *get_aqualink_onetouch_freezeprotect( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_ONETOUCH_FREEZEPROTECT); LOG(ONET_LOG,LOG_DEBUG, "OneTouch get Freezeprotect\n"); - if ( !goto_onetouch_menu(aq_data, OTM_SET_TEMP) ){ + if ( !goto_onetouch_menu(aqdata, OTM_SET_TEMP) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get heater temp menu\n"); } - if ( !goto_onetouch_menu(aq_data, OTM_FREEZE_PROTECT) ){ + if ( !goto_onetouch_menu(aqdata, OTM_FREEZE_PROTECT) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get freeze protect menu\n"); } - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer didn't get back to System menu\n"); } @@ -613,21 +613,21 @@ void *get_aqualink_onetouch_setpoints( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_ONETOUCH_SETPOINTS); LOG(ONET_LOG,LOG_DEBUG, "OneTouch get heater temps\n"); - if ( !goto_onetouch_menu(aq_data, OTM_SET_TEMP) ){ + if ( !goto_onetouch_menu(aqdata, OTM_SET_TEMP) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get heater temp menu\n"); } - if ( !goto_onetouch_menu(aq_data, OTM_FREEZE_PROTECT) ){ + if ( !goto_onetouch_menu(aqdata, OTM_FREEZE_PROTECT) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get freeze protect menu\n"); } - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer didn't get back to System menu\n"); } @@ -637,7 +637,7 @@ void *get_aqualink_onetouch_setpoints( void *ptr ) return ptr; } -void set_aqualink_onetouch_heater_setpoint( struct aqualinkdata *aq_data, bool ispool, int val ) +void set_aqualink_onetouch_heater_setpoint( struct aqualinkdata *aqdata, bool ispool, int val ) { int cval; int diff; @@ -646,30 +646,30 @@ void set_aqualink_onetouch_heater_setpoint( struct aqualinkdata *aq_data, bool i //char *st; unsigned char direction; - if ( !goto_onetouch_menu(aq_data, OTM_SET_TEMP) ){ + if ( !goto_onetouch_menu(aqdata, OTM_SET_TEMP) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get heater temp menu\n"); } if(ispool){ if (isCOMBO_PANEL) { - if (!highlight_onetouch_menu_item(aq_data, "Pool Heat")) { + if (!highlight_onetouch_menu_item(aqdata, "Pool Heat")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get pool heater temp menu\n"); return; } } else { - if (!highlight_onetouch_menu_item(aq_data, "Temp1")) { + if (!highlight_onetouch_menu_item(aqdata, "Temp1")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get Temp1 temp menu\n"); return; } } } else { if (isCOMBO_PANEL) { - if (!highlight_onetouch_menu_item(aq_data, "Spa Heat")) { + if (!highlight_onetouch_menu_item(aqdata, "Spa Heat")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get spa heater temp menu\n"); return; } } else { - if (!highlight_onetouch_menu_item(aq_data, "Temp2")) { + if (!highlight_onetouch_menu_item(aqdata, "Temp2")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get Temp2 temp menu\n"); return; } @@ -678,7 +678,7 @@ void set_aqualink_onetouch_heater_setpoint( struct aqualinkdata *aq_data, bool i send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. { char *st = onetouch_menu_hlightchars(&len); @@ -721,15 +721,15 @@ void *set_aqualink_onetouch_pool_heater_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_POOL_HEATER_TEMP); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(POOL_HTR_SETPOINT, val, aq_data); + val = setpoint_check(POOL_HTR_SETPOINT, val, aqdata); LOG(ONET_LOG,LOG_DEBUG, "OneTouch set pool heater temp to %d\n", val); - set_aqualink_onetouch_heater_setpoint(aq_data, true, val); + set_aqualink_onetouch_heater_setpoint(aqdata, true, val); cleanAndTerminateThread(threadCtrl); @@ -741,15 +741,15 @@ void *set_aqualink_onetouch_spa_heater_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_SPA_HEATER_TEMP); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SPA_HTR_SETPOINT, val, aq_data); + val = setpoint_check(SPA_HTR_SETPOINT, val, aqdata); LOG(ONET_LOG,LOG_DEBUG, "OneTouch set spa heater temp to %d\n", val); - set_aqualink_onetouch_heater_setpoint(aq_data, false, val); + set_aqualink_onetouch_heater_setpoint(aqdata, false, val); cleanAndTerminateThread(threadCtrl); @@ -761,7 +761,7 @@ void *set_aqualink_onetouch_boost( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_BOOST); @@ -769,7 +769,7 @@ void *set_aqualink_onetouch_boost( void *ptr ) LOG(ONET_LOG,LOG_DEBUG, "OneTouch request set Boost to '%d'\n",val==true?"On":"Off"); - if ( !goto_onetouch_menu(aq_data, OTM_BOOST) ){ + if ( !goto_onetouch_menu(aqdata, OTM_BOOST) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get BOOST menu\n"); } else { if ( rsm_strcmp(onetouch_menu_hlight(), "Start") == 0 ) { @@ -783,11 +783,11 @@ void *set_aqualink_onetouch_boost( void *ptr ) } else if ( rsm_strcmp(onetouch_menu_hlight(), "Pause") == 0 ) { if (! val) { LOG(ONET_LOG,LOG_DEBUG, "OneTouch set Boost is ON, turning Off\n"); - highlight_onetouch_menu_item(aq_data, "Stop"); + highlight_onetouch_menu_item(aqdata, "Stop"); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); // Takes ages to see bost is off from menu, to set it here. - setSWGboost(aq_data, false); + setSWGboost(aqdata, false); } else { LOG(ONET_LOG,LOG_INFO, "OneTouch Boost is On, ignore request\n"); } @@ -796,7 +796,7 @@ void *set_aqualink_onetouch_boost( void *ptr ) } } - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_WARNING, "OneTouch device programmer didn't get back to System menu\n"); } @@ -810,7 +810,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; int cval; int diff; int i; @@ -819,11 +819,11 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_SWG_PERCENT); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SWG_SETPOINT, val, aq_data); + val = setpoint_check(SWG_SETPOINT, val, aqdata); LOG(ONET_LOG,LOG_DEBUG, "OneTouch set SWG Percent to %d\n",val); - if ( !goto_onetouch_menu(aq_data, OTM_SET_AQUAPURE) ){ + if ( !goto_onetouch_menu(aqdata, OTM_SET_AQUAPURE) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get Aquapure menu\n"); goto f_end; } @@ -833,13 +833,13 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) // Only have option for both on ComboPanel, and us if (isCOMBO_PANEL) { - if (aq_data->aqbuttons[SPA_INDEX].led->state == OFF) { - if (!highlight_onetouch_menu_item(aq_data, "Set Pool")) { + if (aqdata->aqbuttons[SPA_INDEX].led->state == OFF) { + if (!highlight_onetouch_menu_item(aqdata, "Set Pool")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get Pool swg percent\n"); goto f_end; } } else { - if (!highlight_onetouch_menu_item(aq_data, "Set Spa")) { + if (!highlight_onetouch_menu_item(aqdata, "Set Spa")) { LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get Spa swg percent\n"); goto f_end; } @@ -850,7 +850,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. { i=0; @@ -859,7 +859,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) while (len > 5 || (len < 0 && i < 5)) { LOG(ONET_LOG,LOG_DEBUG, "** OneTouch set SWG Percent highlighted waiting again\n"); delay(50); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,5); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,5); // CMD_PDA_0x04 is just a packer. st = onetouch_menu_hlightchars(&len); LOG(ONET_LOG,LOG_DEBUG, "** OneTouch set SWG Percent highlighted='%.*s' len=%d st=%s\n", len, st, len, st); i++; @@ -884,8 +884,8 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) } /* - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. - setSWGpercent(aq_data,atoi(onetouch_menu_hlightchars(&len))); + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + setSWGpercent(aqdata,atoi(onetouch_menu_hlightchars(&len))); */ send_ot_cmd(KEY_ONET_SELECT); @@ -894,7 +894,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) waitfor_ot_queue2empty(); f_end: - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_WARNING, "OneTouch device programmer didn't get back to System menu\n"); } @@ -906,7 +906,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) -bool set_numeric_value(struct aqualinkdata *aq_data, int val) { +bool set_numeric_value(struct aqualinkdata *aqdata, int val) { int len; int cval; int diff; @@ -931,7 +931,7 @@ bool set_numeric_value(struct aqualinkdata *aq_data, int val) { waitfor_ot_queue2empty(); } - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,5); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,5); // CMD_PDA_0x04 is just a packer. cval = atoi(onetouch_menu_hlightchars(&len)); if ( val != cval ) { LOG(ONET_LOG,LOG_ERR, "** OneTouch set value failed, val=%d cval=%d\n", val,cval); @@ -946,7 +946,7 @@ void *set_aqualink_onetouch_time( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_TIME); @@ -954,7 +954,7 @@ void *set_aqualink_onetouch_time( void *ptr ) LOG(ONET_LOG,LOG_DEBUG, "OneTouch set time\n"); - if ( !goto_onetouch_menu(aq_data, OTM_SET_TIME) ){ + if ( !goto_onetouch_menu(aqdata, OTM_SET_TIME) ){ LOG(ONET_LOG,LOG_ERR, "OneTouch device programmer failed to get time menu\n"); } else { @@ -988,40 +988,40 @@ void *set_aqualink_onetouch_time( void *ptr ) //Line 3 startchat 8 for year while ( (onetouch_menu_hlightindex() != 3) || (onetouch_menu_hlightcharindex() != 2) ) - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. printf("*** Setting month. line=%d, char=%d\n",onetouch_menu_hlightindex(), onetouch_menu_hlightcharindex()); - set_numeric_value(aq_data, (result->tm_mon + 1) ); + set_numeric_value(aqdata, (result->tm_mon + 1) ); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); while ( (onetouch_menu_hlightindex() != 3) || (onetouch_menu_hlightcharindex() != 5) ) - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. printf("*** Setting day. line=%d, char=%d\n",onetouch_menu_hlightindex(), onetouch_menu_hlightcharindex()); - set_numeric_value(aq_data, result->tm_mday ); + set_numeric_value(aqdata, result->tm_mday ); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); while ( (onetouch_menu_hlightindex() != 3) || (onetouch_menu_hlightcharindex() != 8) ) - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. printf("*** Setting year. line=%d, char=%d\n",onetouch_menu_hlightindex(), onetouch_menu_hlightcharindex()); - set_numeric_value(aq_data, result->tm_year % 100 ); + set_numeric_value(aqdata, result->tm_year % 100 ); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); // highlightline 4 char 3 or 4 for Hour // highlightline 4 char 5 or 6 for Min // highlightline 4 char 9 - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. // Need to check AM/PM here - set_numeric_value(aq_data, hour ); + set_numeric_value(aqdata, hour ); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); - waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. + waitForOT_MessageTypes(aqdata,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer. - set_numeric_value(aq_data, result->tm_min ); + set_numeric_value(aqdata, result->tm_min ); send_ot_cmd(KEY_ONET_SELECT); waitfor_ot_queue2empty(); @@ -1033,7 +1033,7 @@ void *set_aqualink_onetouch_time( void *ptr ) waitfor_ot_queue2empty(); } - if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){ + if (! goto_onetouch_menu(aqdata, OTM_SYSTEM) ){ LOG(ONET_LOG,LOG_WARNING, "OneTouch device programmer didn't get back to System menu\n"); } diff --git a/source/pda.c b/source/pda.c index 8b4c322..925c404 100644 --- a/source/pda.c +++ b/source/pda.c @@ -207,8 +207,7 @@ void equiptment_update_cycle(int eqID) { //for (i=0; i < _aqualink_data->total_buttons; i++) { // total_buttons - 2 because we don't get heaters in this cycle if ((update_equiptment_bitmask & (1 << (i))) != (1 << (i))) { if (_aqualink_data->aqbuttons[i].led->state != OFF) { - _aqualink_data->aqbuttons[i].led->state = OFF; - _aqualink_data->updated = true; + SET_IF_CHANGED(_aqualink_data->aqbuttons[i].led->state, OFF, _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "Turn off equipment id %d %s not seen in last cycle\n", i, _aqualink_data->aqbuttons[i].name); } //LOG(PDA_LOG,LOG_DEBUG, "Thick id %d %s total = %d\n", i, _aqualink_data->aqbuttons[i].name, _aqualink_data->total_buttons); @@ -218,7 +217,7 @@ void equiptment_update_cycle(int eqID) { if ((_aqualink_data->frz_protect_state == ON) && (! (update_equiptment_bitmask & (1 << PDA_FREEZE_PROTECT_INDEX)))) { LOG(PDA_LOG,LOG_DEBUG, "Turn off freeze protect not seen in last cycle\n"); - _aqualink_data->frz_protect_state = ENABLE; + SET_IF_CHANGED(_aqualink_data->frz_protect_state, ENABLE, _aqualink_data->is_dirty); } if ((_aqualink_data->boost) && @@ -259,30 +258,30 @@ void process_pda_packet_msg_long_temp(const char *msg) // 'AIR WATER' // In case of single device. if (_aqualink_data->temp_units == UNKNOWN && !in_programming_mode(_aqualink_data)) { LOG(PDA_LOG,LOG_NOTICE, "Forcing temperature units to FAHRENHEIT\n"); - _aqualink_data->temp_units = FAHRENHEIT; // Force FAHRENHEIT + SET_IF_CHANGED(_aqualink_data->temp_units, FAHRENHEIT, _aqualink_data->is_dirty); // Force FAHRENHEIT } if (stristr(pda_m_line(1), "AIR") != NULL) - _aqualink_data->air_temp = atoi(msg); + SET_IF_CHANGED(_aqualink_data->air_temp, atoi(msg), _aqualink_data->is_dirty); if (stristr(pda_m_line(1), "SPA") != NULL) { - _aqualink_data->spa_temp = atoi(msg + 4); - _aqualink_data->pool_temp = TEMP_UNKNOWN; + SET_IF_CHANGED(_aqualink_data->spa_temp, atoi(msg + 4), _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->pool_temp, TEMP_UNKNOWN, _aqualink_data->is_dirty); } else if (stristr(pda_m_line(1), "POOL") != NULL) { - _aqualink_data->pool_temp = atoi(msg + 7); - _aqualink_data->spa_temp = TEMP_UNKNOWN; + SET_IF_CHANGED(_aqualink_data->pool_temp, atoi(msg + 7), _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->spa_temp, TEMP_UNKNOWN, _aqualink_data->is_dirty); } else if (stristr(pda_m_line(1), "WATER") != NULL) { - _aqualink_data->pool_temp = atoi(msg + 7); - _aqualink_data->spa_temp = TEMP_UNKNOWN; + SET_IF_CHANGED(_aqualink_data->pool_temp, atoi(msg + 7), _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->spa_temp, TEMP_UNKNOWN, _aqualink_data->is_dirty); } else { - _aqualink_data->pool_temp = TEMP_UNKNOWN; - _aqualink_data->spa_temp = TEMP_UNKNOWN; + SET_IF_CHANGED(_aqualink_data->pool_temp, TEMP_UNKNOWN, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->spa_temp, TEMP_UNKNOWN, _aqualink_data->is_dirty); } // printf("Air Temp = %d | Water Temp = %d\n",atoi(msg),atoi(msg+7)); } @@ -310,7 +309,9 @@ void process_pda_packet_msg_long_time(const char *msg) { LOG(PDA_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", _aqualink_data->time, _aqualink_data->date); aq_programmer(AQ_SET_TIME, NULL, _aqualink_data); - } + } + + SET_DIRTY(_aqualink_data->is_dirty); } void process_pda_packet_msg_long_equipment_control(const char *msg) @@ -352,11 +353,11 @@ void process_pda_packet_msg_long_home(const char *msg) // If pool mode is on the filter pump is on but if it is off the filter pump might be on if spa mode is on. if (msg[AQ_MSGLEN - 1] == 'N') { - _aqualink_data->aqbuttons[PUMP_INDEX].led->state = ON; + SET_IF_CHANGED(_aqualink_data->aqbuttons[PUMP_INDEX].led->state, ON, _aqualink_data->is_dirty) ; } else if (msg[AQ_MSGLEN - 1] == '*') { - _aqualink_data->aqbuttons[PUMP_INDEX].led->state = FLASH; + SET_IF_CHANGED(_aqualink_data->aqbuttons[PUMP_INDEX].led->state, FLASH, _aqualink_data->is_dirty); } } else if (stristr(msg, "POOL HEATER") != NULL) @@ -368,17 +369,17 @@ void process_pda_packet_msg_long_home(const char *msg) // when SPA mode is on the filter may be on or pending if (msg[AQ_MSGLEN - 1] == 'N') { - _aqualink_data->aqbuttons[PUMP_INDEX].led->state = ON; - _aqualink_data->aqbuttons[SPA_INDEX].led->state = ON; + SET_IF_CHANGED(_aqualink_data->aqbuttons[PUMP_INDEX].led->state, ON, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->aqbuttons[SPA_INDEX].led->state, ON, _aqualink_data->is_dirty); } else if (msg[AQ_MSGLEN - 1] == '*') { - _aqualink_data->aqbuttons[PUMP_INDEX].led->state = FLASH; - _aqualink_data->aqbuttons[SPA_INDEX].led->state = ON; + SET_IF_CHANGED(_aqualink_data->aqbuttons[PUMP_INDEX].led->state, FLASH, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->aqbuttons[SPA_INDEX].led->state, ON, _aqualink_data->is_dirty); } else { - _aqualink_data->aqbuttons[SPA_INDEX].led->state = OFF; + SET_IF_CHANGED(_aqualink_data->aqbuttons[SPA_INDEX].led->state, OFF, _aqualink_data->is_dirty); } } else if (stristr(msg, "SPA HEATER") != NULL) @@ -426,10 +427,10 @@ void get_pda_temp_units(const char *msg) } if (msg[15] == 'F') { - _aqualink_data->temp_units = FAHRENHEIT; + SET_IF_CHANGED(_aqualink_data->temp_units, FAHRENHEIT, _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "Set temperature units to FAHRENHEIT\n"); } else if (msg[15] == 'C') { - _aqualink_data->temp_units = CELSIUS; + SET_IF_CHANGED(_aqualink_data->temp_units, CELSIUS, _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "Set temperature units to CELSIUS\n"); } else { LOG(PDA_LOG,LOG_DEBUG, "Unknown temperature units '%c'\n",msg[15]); @@ -442,27 +443,27 @@ void process_pda_packet_msg_long_set_temp(const char *msg) if (stristr(msg, "POOL HEAT") != NULL) { - _aqualink_data->pool_htr_set_point = atoi(msg + 10); + SET_IF_CHANGED(_aqualink_data->pool_htr_set_point, atoi(msg + 10), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "pool_htr_set_point = %d\n", _aqualink_data->pool_htr_set_point); get_pda_temp_units(msg); } else if (stristr(msg, "SPA HEAT") != NULL) { - _aqualink_data->spa_htr_set_point = atoi(msg + 10); + SET_IF_CHANGED(_aqualink_data->spa_htr_set_point, atoi(msg + 10), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "spa_htr_set_point = %d\n", _aqualink_data->spa_htr_set_point); get_pda_temp_units(msg); } else if (stristr(msg, "TEMP1") != NULL) { setSingleDeviceMode(); - _aqualink_data->pool_htr_set_point = atoi(msg + 10); + SET_IF_CHANGED(_aqualink_data->pool_htr_set_point, atoi(msg + 10), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "pool_htr_set_point = %d\n", _aqualink_data->pool_htr_set_point); get_pda_temp_units(msg); } else if (stristr(msg, "TEMP2") != NULL) { setSingleDeviceMode(); - _aqualink_data->spa_htr_set_point = atoi(msg + 10); + SET_IF_CHANGED(_aqualink_data->spa_htr_set_point, atoi(msg + 10), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "spa_htr_set_point = %d\n", _aqualink_data->spa_htr_set_point); get_pda_temp_units(msg); } @@ -474,11 +475,11 @@ void process_pda_packet_msg_long_spa_heat(const char *msg) { if (strncasecmp(msg, " ENABLED ", 16) == 0) { - _aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state = ENABLE; + SET_IF_CHANGED(_aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state, ENABLE, _aqualink_data->is_dirty); } else if (strncasecmp(msg, " SET TO", 8) == 0) { - _aqualink_data->spa_htr_set_point = atoi(msg + 8); + SET_IF_CHANGED(_aqualink_data->spa_htr_set_point, atoi(msg + 8), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "spa_htr_set_point = %d\n", _aqualink_data->spa_htr_set_point); } } @@ -487,11 +488,11 @@ void process_pda_packet_msg_long_pool_heat(const char *msg) { if (strncasecmp(msg, " ENABLED ", 16) == 0) { - _aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state = ENABLE; + SET_IF_CHANGED(_aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state, ENABLE, _aqualink_data->is_dirty); } else if (strncasecmp(msg, " SET TO", 8) == 0) { - _aqualink_data->pool_htr_set_point = atoi(msg + 8); + SET_IF_CHANGED(_aqualink_data->pool_htr_set_point, atoi(msg + 8), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "pool_htr_set_point = %d\n", _aqualink_data->pool_htr_set_point); } } @@ -500,7 +501,7 @@ void process_pda_packet_msg_long_freeze_protect(const char *msg) { if (strncasecmp(msg, "TEMP ", 10) == 0) { - _aqualink_data->frz_protect_set_point = atoi(msg + 10); + SET_IF_CHANGED(_aqualink_data->frz_protect_set_point, atoi(msg + 10), _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "frz_protect_set_point = %d\n", _aqualink_data->frz_protect_set_point); } } @@ -565,7 +566,7 @@ void process_pda_packet_msg_long_unknown(const char *msg) } } -void pda_pump_update(struct aqualinkdata *aq_data, int updated) { +void pda_pump_update(struct aqualinkdata *aqdata, int updated) { const int bitmask[MAX_PUMPS] = {1,2,4,8}; static unsigned char updates = '\0'; int i; @@ -573,10 +574,10 @@ void pda_pump_update(struct aqualinkdata *aq_data, int updated) { if (updated == -1) { for(i=0; i < MAX_PUMPS; i++) { if ((updates & bitmask[i]) != bitmask[i]) { - aq_data->pumps[i].rpm = PUMP_OFF_RPM; - aq_data->pumps[i].gpm = PUMP_OFF_GPM; - aq_data->pumps[i].watts = PUMP_OFF_WAT; - aq_data->pumps[i].pStatus = PS_OFF; + SET_IF_CHANGED(aqdata->pumps[i].rpm, PUMP_OFF_RPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].gpm, PUMP_OFF_GPM, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].watts, PUMP_OFF_WAT, aqdata->is_dirty); + SET_IF_CHANGED(aqdata->pumps[i].pStatus, PS_OFF, aqdata->is_dirty); } } updates = '\0'; @@ -661,18 +662,18 @@ void get_pda_pumpinfo_from_menu(int menuLineIdx, int pump_number) if (_aqualink_data->pumps[i].pumpIndex == pump_number) { LOG(PDA_LOG,LOG_DEBUG, "Pump label: %s Index: %d, Number: %d, RPM: %d, Watts: %d, GPM: %d\n",_aqualink_data->pumps[i].button->name, i ,pump_number,rpm,watts,gpm); pda_pump_update(_aqualink_data, i); - _aqualink_data->pumps[i].rpm = rpm; - _aqualink_data->pumps[i].watts = watts; - _aqualink_data->pumps[i].gpm = gpm; - _aqualink_data->pumps[i].pStatus = pStatus; + SET_IF_CHANGED(_aqualink_data->pumps[i].rpm, rpm, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->pumps[i].watts, watts, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->pumps[i].gpm, gpm, _aqualink_data->is_dirty); + SET_IF_CHANGED(_aqualink_data->pumps[i].pStatus, pStatus, _aqualink_data->is_dirty); if (_aqualink_data->pumps[i].pumpType == PT_UNKNOWN){ if (rsm_strcmp(pda_m_line(menuLineIdx),"Intelliflo VS") == 0) - _aqualink_data->pumps[i].pumpType = VSPUMP; + SET_IF_CHANGED(_aqualink_data->pumps[i].pumpType, VSPUMP, _aqualink_data->is_dirty); else if (rsm_strcmp(pda_m_line(menuLineIdx),"Intelliflo VF") == 0) - _aqualink_data->pumps[i].pumpType = VFPUMP; + SET_IF_CHANGED(_aqualink_data->pumps[i].pumpType, VFPUMP, _aqualink_data->is_dirty); else if (rsm_strcmp(pda_m_line(menuLineIdx),"Jandy ePUMP") == 0 || rsm_strcmp(pda_m_line(menuLineIdx),"ePump AC") == 0) - _aqualink_data->pumps[i].pumpType = EPUMP; + SET_IF_CHANGED(_aqualink_data->pumps[i].pumpType, EPUMP, _aqualink_data->is_dirty); LOG(PDA_LOG, LOG_DEBUG, "Pump index %d set PumpType to %d\n", i, _aqualink_data->pumps[i].pumpType); } @@ -697,9 +698,9 @@ void log_pump_information() { } /* // NSF This need to be used in the future and not process_pda_packet_msg_long_equiptment_status() else if (rsm_strcmp(pda_m_line(i),"AQUAPURE") == 0) { - rtn = get_aquapureinfo_from_menu(aq_data, i); + rtn = get_aquapureinfo_from_menu(aqdata, i); } else if (rsm_strcmp(pda_m_line(i),"Chemlink") == 0) { - rtn = get_chemlinkinfo_from_menu(aq_data, i); + rtn = get_chemlinkinfo_from_menu(aqdata, i); */ } } @@ -757,7 +758,7 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin } else if ((index = rsm_strncasestr(msg, "FREEZE PROTECT", AQ_MSGLEN)) != NULL) { - _aqualink_data->frz_protect_state = ON; + SET_IF_CHANGED(_aqualink_data->frz_protect_state, ON, _aqualink_data->is_dirty); equiptment_update_cycle(PDA_FREEZE_PROTECT_INDEX); LOG(PDA_LOG,LOG_DEBUG, "Freeze Protect is on\n"); } @@ -771,7 +772,7 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin //snprintf(_aqualink_data->boost_msg, sizeof(_aqualink_data->boost_msg), "%s", msg+2); //Message is ' 23:21 Remain', we only want time part snprintf(_aqualink_data->boost_msg, 6, "%s", msg); - _aqualink_data->boost_duration = rsm_HHMM2min(_aqualink_data->boost_msg); + SET_IF_CHANGED(_aqualink_data->boost_duration, rsm_HHMM2min(_aqualink_data->boost_msg), _aqualink_data->is_dirty); } else if ((index = rsm_strncasestr(msg, MSG_SWG_PCT, AQ_MSGLEN)) != NULL) { @@ -782,19 +783,19 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin } else if ((index = rsm_strncasestr(msg, MSG_SWG_PPM, AQ_MSGLEN)) != NULL) { - _aqualink_data->swg_ppm = atoi(index + strlen(MSG_SWG_PPM)); + SET_IF_CHANGED(_aqualink_data->swg_ppm, atoi(index + strlen(MSG_SWG_PPM)), _aqualink_data->is_dirty); //if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;} LOG(PDA_LOG,LOG_DEBUG, "SALT = %d\n", _aqualink_data->swg_ppm); } else if (rsm_strncmp(msg_line, "POOL HEAT ENA",AQ_MSGLEN) == 0) { - _aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state = ENABLE; + SET_IF_CHANGED(_aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state, ENABLE, _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "Pool Hearter is enabled\n"); //equiptment_update_cycle(_aqualink_data->pool_heater_index); } else if (rsm_strncmp(msg_line, "SPA HEAT ENA",AQ_MSGLEN) == 0) { - _aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state = ENABLE; + SET_IF_CHANGED(_aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state, ENABLE, _aqualink_data->is_dirty); LOG(PDA_LOG,LOG_DEBUG, "Spa Hearter is enabled\n"); //equiptment_update_cycle(_aqualink_data->spa_heater_index); } @@ -812,7 +813,7 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin // It's on (or delayed) if it's listed here. if (_aqualink_data->aqbuttons[i].led->state != FLASH) { - _aqualink_data->aqbuttons[i].led->state = ON; + SET_IF_CHANGED(_aqualink_data->aqbuttons[i].led->state, ON, _aqualink_data->is_dirty); } break; } @@ -878,7 +879,7 @@ void process_pda_freeze_protect_devices() LOG(PDA_LOG,LOG_DEBUG, "PDA freeze protect enabled by %s\n", pda_m_line(i)); if (_aqualink_data->frz_protect_state == OFF) { - _aqualink_data->frz_protect_state = ENABLE; + SET_IF_CHANGED(_aqualink_data->frz_protect_state, ENABLE, _aqualink_data->is_dirty); break; } } @@ -899,7 +900,6 @@ bool process_pda_packet(unsigned char *packet, int length) process_pda_menu_packet(packet, length, in_programming_mode(_aqualink_data)); - switch (packet[PKT_CMD]) { case CMD_ACK: @@ -913,7 +913,8 @@ bool process_pda_packet(unsigned char *packet, int length) case CMD_STATUS: //LOG(PDA_LOG,LOG_DEBUG, "**** PDA Menu type %d ****\n", pda_m_type()); - _aqualink_data->last_display_message[0] = '\0'; + //_aqualink_data->last_display_message[0] = '\0'; + SET_IF_CHANGED_STRCPY(_aqualink_data->last_display_message, "", _aqualink_data->is_dirty); if (equiptment_update_loop == false && pda_m_type() == PM_EQUIPTMENT_STATUS) { LOG(PDA_LOG,LOG_DEBUG, "**** PDA Start new Equiptment loop ****\n"); diff --git a/source/pda_aq_programmer.c b/source/pda_aq_programmer.c index 99198f7..c751f28 100644 --- a/source/pda_aq_programmer.c +++ b/source/pda_aq_programmer.c @@ -41,19 +41,19 @@ #include "timespec_subtract.h" #endif -bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex, int numMessageReceived); -bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived); -bool waitForPDAMessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived); -bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line); -bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu); -bool wait_pda_selected_item(struct aqualinkdata *aq_data); -bool waitForPDAnextMenu(struct aqualinkdata *aq_data); -bool loopover_devices(struct aqualinkdata *aq_data); -bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charlimit); -bool select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu); +bool waitForPDAMessageHighlight(struct aqualinkdata *aqdata, int highlighIndex, int numMessageReceived); +bool waitForPDAMessageType(struct aqualinkdata *aqdata, unsigned char mtype, int numMessageReceived); +bool waitForPDAMessageTypes(struct aqualinkdata *aqdata, unsigned char mtype1, unsigned char mtype2, int numMessageReceived); +bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aqdata, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line); +bool goto_pda_menu(struct aqualinkdata *aqdata, pda_menu_type menu); +bool wait_pda_selected_item(struct aqualinkdata *aqdata); +bool waitForPDAnextMenu(struct aqualinkdata *aqdata); +bool loopover_devices(struct aqualinkdata *aqdata); +bool find_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, int charlimit); +bool select_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, bool waitForNextMenu); -bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data); -bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data); +bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aqdata); +bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aqdata); static pda_type _PDA_Type; @@ -63,7 +63,7 @@ static pda_type _PDA_Type; /* Forcing all these to allbutton for the moment */ void waitfor_queue2empty(); void send_cmd(unsigned char cmd); -unsigned char pop_allb_cmd(struct aqualinkdata *aq_data); +unsigned char pop_allb_cmd(struct aqualinkdata *aqdata); int get_allb_queue_length(); void waitfor_pda_queue2empty() { @@ -72,8 +72,8 @@ void waitfor_pda_queue2empty() { void send_pda_cmd(unsigned char cmd) { send_cmd(cmd); } -unsigned char pop_pda_cmd(struct aqualinkdata *aq_data){ - return pop_allb_cmd(aq_data); +unsigned char pop_pda_cmd(struct aqualinkdata *aqdata){ + return pop_allb_cmd(aqdata); } int get_pda_queue_length(){ return get_allb_queue_length(); @@ -114,17 +114,17 @@ void send_pda_cmd(unsigned char cmd) { } } -unsigned char pop_pda_cmd(struct aqualinkdata *aq_data) +unsigned char pop_pda_cmd(struct aqualinkdata *aqdata) { unsigned char cmd = NUL; - if (_pda_command != NUL && aq_data->last_packet_type == CMD_STATUS) { + if (_pda_command != NUL && aqdata->last_packet_type == CMD_STATUS) { cmd = _pda_command; _pda_command = NUL; } /* // Only send commands on status messages - if (get_pda_queue_length() > 0 && aq_data->last_packet_type == CMD_STATUS) { + if (get_pda_queue_length() > 0 && aqdata->last_packet_type == CMD_STATUS) { cmd = _pda_cmd_queue[0]; _pda_cmdstack_place--; LOG(PDA_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); @@ -173,7 +173,7 @@ bool waitfor_pda_queue2empty() { //#define MAX_ACK_FOR_THREAD 200 // ~40 seconds (Init takes 30) #define MAX_ACK_FOR_THREAD 60 // ~12 seconds (testing, will stop every thread) // *** DELETE THIS WHEN PDA IS OUT OF BETA **** -void pda_programming_thread_check(struct aqualinkdata *aq_data) +void pda_programming_thread_check(struct aqualinkdata *aqdata) { static pthread_t thread_id = 0; static int ack_count = 0; @@ -183,34 +183,34 @@ void pda_programming_thread_check(struct aqualinkdata *aq_data) struct timespec elapsed; #endif // Check for long lasting threads - if (aq_data->active_thread.thread_id != 0) { - if (thread_id != *aq_data->active_thread.thread_id) { + if (aqdata->active_thread.thread_id != 0) { + if (thread_id != *aqdata->active_thread.thread_id) { printf ("**************** LAST POINTER SET %ld , %p ****************************\n",thread_id,&thread_id); - thread_id = *aq_data->active_thread.thread_id; + thread_id = *aqdata->active_thread.thread_id; #ifdef AQ_DEBUG clock_gettime(CLOCK_REALTIME, &start); #endif - printf ("**************** NEW POINTER SET %d, %ld %ld , %p %p ****************************\n",aq_data->active_thread.ptype,thread_id,*aq_data->active_thread.thread_id,&thread_id,aq_data->active_thread.thread_id); + printf ("**************** NEW POINTER SET %d, %ld %ld , %p %p ****************************\n",aqdata->active_thread.ptype,thread_id,*aqdata->active_thread.thread_id,&thread_id,aqdata->active_thread.thread_id); ack_count = 0; } else if (ack_count > MAX_ACK_FOR_THREAD) { #ifdef AQ_DEBUG clock_gettime(CLOCK_REALTIME, &now); timespec_subtract(&elapsed, &now, &start); LOG(PDA_LOG,LOG_ERR, "Thread %d,%p FAILED to finished in reasonable time, %d.%03ld sec, killing it.\n", - aq_data->active_thread.ptype, - aq_data->active_thread.thread_id, + aqdata->active_thread.ptype, + aqdata->active_thread.thread_id, elapsed.tv_sec, elapsed.tv_nsec / 1000000L); #else - LOG(PDA_LOG,LOG_ERR, "Thread %d,%p FAILED to finished in reasonable time, killing it!\n", aq_data->active_thread.ptype, aq_data->active_thread.thread_id) + LOG(PDA_LOG,LOG_ERR, "Thread %d,%p FAILED to finished in reasonable time, killing it!\n", aqdata->active_thread.ptype, aqdata->active_thread.thread_id) #endif - if (pthread_cancel(*aq_data->active_thread.thread_id) != 0) + if (pthread_cancel(*aqdata->active_thread.thread_id) != 0) LOG(PDA_LOG,LOG_ERR, "Thread kill failed\n"); else { } - aq_data->active_thread.thread_id = 0; - aq_data->active_thread.ptype = AQP_NULL; + aqdata->active_thread.thread_id = 0; + aqdata->active_thread.ptype = AQP_NULL; ack_count = 0; thread_id = 0; } else { @@ -223,12 +223,12 @@ void pda_programming_thread_check(struct aqualinkdata *aq_data) } */ -bool wait_pda_selected_item(struct aqualinkdata *aq_data) +bool wait_pda_selected_item(struct aqualinkdata *aqdata) { int i=0; while (pda_m_hlightindex() == -1 && i < 5){ - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,10); + waitForPDAMessageType(aqdata,CMD_PDA_HIGHLIGHT,10); i++; } @@ -238,17 +238,17 @@ bool wait_pda_selected_item(struct aqualinkdata *aq_data) return true; } -bool waitForPDAnextMenu(struct aqualinkdata *aq_data) { - if (!waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10)) +bool waitForPDAnextMenu(struct aqualinkdata *aqdata) { + if (!waitForPDAMessageType(aqdata,CMD_PDA_CLEAR,10)) return false; - return waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + return waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); } -bool loopover_devices(struct aqualinkdata *aq_data) { +bool loopover_devices(struct aqualinkdata *aqdata) { int i; int index = -1; - if (! goto_pda_menu(aq_data, PM_EQUIPTMENT_CONTROL)) { + if (! goto_pda_menu(aqdata, PM_EQUIPTMENT_CONTROL)) { LOG(PDA_LOG,LOG_ERR, "loopover_devices :- can't goto PM_EQUIPTMENT_CONTROL menu\n"); //cleanAndTerminateThread(threadCtrl); return false; @@ -257,8 +257,8 @@ bool loopover_devices(struct aqualinkdata *aq_data) { // Should look for message "ALL OFF", that's end of device list. for (i=0; i < 18 && (index = pda_find_m_index("ALL OFF")) == -1 ; i++) { send_pda_cmd(KEY_PDA_DOWN); - //waitForMessage(aq_data, NULL, 1); - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,8); + //waitForMessage(aqdata, NULL, 1); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,8); } if (index == -1) { LOG(PDA_LOG,LOG_ERR, "loopover_devices :- can't find ALL OFF\n"); @@ -272,7 +272,7 @@ bool loopover_devices(struct aqualinkdata *aq_data) { if charlimit is set, use case insensitive match and limit chars. if charlimit is -1, use VERY loose matching. */ -bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charlimit) { +bool find_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, int charlimit) { int i=pda_m_hlightindex(); int min_index = -1; int max_index = -1; @@ -298,9 +298,9 @@ bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charli send_pda_cmd(KEY_PDA_DOWN); //delay(500); //wait_for_empty_cmd_buffer(); - //waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,2); - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,8); - //waitForMessage(aq_data, NULL, 1); + //waitForPDAMessageType(aqdata,CMD_PDA_HIGHLIGHT,2); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,8); + //waitForMessage(aqdata, NULL, 1); index = (charlimit == 0)?pda_find_m_index(menuText):pda_find_m_index_case(menuText, charlimit); if (index >= 0) { i=pda_m_hlightindex(); @@ -424,28 +424,28 @@ bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charli } } } - return waitForPDAMessageHighlight(aq_data, bLookingForBoost?9:index, 10); + return waitForPDAMessageHighlight(aqdata, bLookingForBoost?9:index, 10); } -bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu, bool loose); +bool _select_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, bool waitForNextMenu, bool loose); -bool select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu){ - return _select_pda_menu_item(aq_data, menuText, waitForNextMenu, false); +bool select_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, bool waitForNextMenu){ + return _select_pda_menu_item(aqdata, menuText, waitForNextMenu, false); } -bool select_pda_menu_item_loose(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu){ - return _select_pda_menu_item(aq_data, menuText, waitForNextMenu, true); +bool select_pda_menu_item_loose(struct aqualinkdata *aqdata, char *menuText, bool waitForNextMenu){ + return _select_pda_menu_item(aqdata, menuText, waitForNextMenu, true); } -bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu, bool loose) { +bool _select_pda_menu_item(struct aqualinkdata *aqdata, char *menuText, bool waitForNextMenu, bool loose) { //int matchType = loose?-1:0; // NSF release 2.1.0 was this and it worked. Need to re-check why I did this. //int matchType = loose?-1:1; int matchType = loose?-1:strlen(menuText); // NSF Not way to check this. (release 2.2.0 introduced this with the line above) - if ( find_pda_menu_item(aq_data, menuText, matchType) ) { + if ( find_pda_menu_item(aqdata, menuText, matchType) ) { send_pda_cmd(KEY_PDA_SELECT); LOG(PDA_LOG,LOG_DEBUG, "PDA Device programmer selected menu item '%s'\n",menuText); if (waitForNextMenu) - return waitForPDAnextMenu(aq_data); + return waitForPDAnextMenu(aqdata); return true; } @@ -461,7 +461,7 @@ bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wa // and 6594 - AquaLink RS Control Panel Installation Manual // https://www.jandy.com/-/media/zodiac/global/downloads/0748-91071/6594.pdf -bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { +bool goto_pda_menu(struct aqualinkdata *aqdata, pda_menu_type menu) { bool ret = true; int cnt = 0; @@ -470,12 +470,12 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { if (pda_m_type() == PM_FW_VERSION) { LOG(PDA_LOG,LOG_DEBUG, "goto_pda_menu at FW version menu\n"); send_pda_cmd(KEY_PDA_BACK); - if (! waitForPDAnextMenu(aq_data)) { + if (! waitForPDAnextMenu(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Device programmer wait for next menu failed\n"); } } else if (pda_m_type() == PM_BUILDING_HOME) { LOG(PDA_LOG,LOG_DEBUG, "goto_pda_menu building home menu\n"); - waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,15); + waitForPDAMessageType(aqdata,CMD_PDA_HIGHLIGHT,15); } @@ -483,37 +483,37 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { switch (menu) { case PM_HOME: send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); break; case PM_EQUIPTMENT_CONTROL: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "EQUIPMENT ON/OFF", true); + ret = select_pda_menu_item(aqdata, "EQUIPMENT ON/OFF", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } break; case PM_PALM_OPTIONS: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "PALM OPTIONS", true); + ret = select_pda_menu_item(aqdata, "PALM OPTIONS", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } break; case PM_AUX_LABEL: if ( _PDA_Type == PDA) { if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "SYSTEM SETUP", true); + ret = select_pda_menu_item(aqdata, "SYSTEM SETUP", true); } else if (pda_m_type() == PM_SYSTEM_SETUP) { - ret = select_pda_menu_item(aq_data, "LABEL AUX", true); + ret = select_pda_menu_item(aqdata, "LABEL AUX", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } } else { LOG(PDA_LOG,LOG_ERR, "PDA in AquaPlalm mode, there is no SYSTEM SETUP / LABEL AUX menu\n"); @@ -522,12 +522,12 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { case PM_SYSTEM_SETUP: if ( _PDA_Type == PDA) { if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "SYSTEM SETUP", true); + ret = select_pda_menu_item(aqdata, "SYSTEM SETUP", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } } else { LOG(PDA_LOG,LOG_ERR, "PDA in AquaPlalm mode, there is no SYSTEM SETUP menu\n"); @@ -536,14 +536,14 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { case PM_FREEZE_PROTECT: if ( _PDA_Type == PDA) { if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "SYSTEM SETUP", true); + ret = select_pda_menu_item(aqdata, "SYSTEM SETUP", true); } else if (pda_m_type() == PM_SYSTEM_SETUP) { - ret = select_pda_menu_item(aq_data, "FREEZE PROTECT", true); + ret = select_pda_menu_item(aqdata, "FREEZE PROTECT", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } } else { LOG(PDA_LOG,LOG_ERR, "PDA in AquaPlalm mode, there is no SYSTEM SETUP / FREEZE PROTECT menu\n"); @@ -551,54 +551,54 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) { break; case PM_AQUAPURE: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "SET AquaPure", true); + ret = select_pda_menu_item(aqdata, "SET AquaPure", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } break; case PM_BOOST: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item_loose(aq_data, "BOOST", true); - //ret = select_pda_menu_item(aq_data, "BOOST", true); + ret = select_pda_menu_item_loose(aqdata, "BOOST", true); + //ret = select_pda_menu_item(aqdata, "BOOST", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } //printf("****MENU SELECT RETURN %d*****\n",ret); break; case PM_SET_TEMP: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { if (isCOMBO_PANEL) { - ret = select_pda_menu_item(aq_data, "SET TEMP", true); + ret = select_pda_menu_item(aqdata, "SET TEMP", true); } else { // Depending on control panel config, may get an extra menu asking to press any key LOG(PDA_LOG,LOG_DEBUG, "PDA in single device mode, \n"); - ret = select_pda_menu_item(aq_data, "SET TEMP", false); + ret = select_pda_menu_item(aqdata, "SET TEMP", false); // We could press enter here, but I can't test it, so just wait for message to dissapear. - ret = waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,25); - //waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10); - //waitForPDAMessageTypesOrMenu(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,20,"press ANY key",8); + ret = waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,25); + //waitForPDAMessageType(aqdata,CMD_PDA_CLEAR,10); + //waitForPDAMessageTypesOrMenu(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,20,"press ANY key",8); } } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } break; case PM_SET_TIME: if (pda_m_type() == PM_HOME) { - ret = select_pda_menu_item(aq_data, "MENU", true); + ret = select_pda_menu_item(aqdata, "MENU", true); } else if (pda_m_type() == PM_MAIN) { - ret = select_pda_menu_item(aq_data, "SET TIME", true); + ret = select_pda_menu_item(aqdata, "SET TIME", true); } else { send_pda_cmd(KEY_PDA_BACK); - ret = waitForPDAnextMenu(aq_data); + ret = waitForPDAnextMenu(aqdata); } break; default: @@ -621,7 +621,7 @@ void *set_aqualink_PDA_device_on_off( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //int i=0; //int found; char device_name[15]; @@ -632,77 +632,77 @@ void *set_aqualink_PDA_device_on_off( void *ptr ) unsigned int device = atoi(&buf[0]); unsigned int state = atoi(&buf[5]); - if (device > aq_data->total_buttons) { + if (device > aqdata->total_buttons) { LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off :- bad device number '%d'\n",device); cleanAndTerminateThread(threadCtrl); return ptr; } - LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, device '%s', state %d\n",aq_data->aqbuttons[device].label,state); + LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, device '%s', state %d\n",aqdata->aqbuttons[device].label,state); - if (! goto_pda_menu(aq_data, PM_EQUIPTMENT_CONTROL)) { + if (! goto_pda_menu(aqdata, PM_EQUIPTMENT_CONTROL)) { LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off :- can't find EQUIPTMENT CONTROL menu\n"); cleanAndTerminateThread(threadCtrl); return ptr; } // If single config (Spa OR pool) rather than (Spa AND pool) heater is TEMP1 and TEMP2 - if (isSINGLE_DEV_PANEL && device == aq_data->pool_heater_index) { // rename Heater and Spa + if (isSINGLE_DEV_PANEL && device == aqdata->pool_heater_index) { // rename Heater and Spa sprintf(device_name,"%-13s\n","TEMP1"); - } else if (isSINGLE_DEV_PANEL && device == aq_data->spa_heater_index) {// rename Heater and Spa + } else if (isSINGLE_DEV_PANEL && device == aqdata->spa_heater_index) {// rename Heater and Spa sprintf(device_name,"%-13s\n","TEMP2"); } else { //Pad name with spaces so something like "SPA" doesn't match "SPA BLOWER" - sprintf(device_name,"%-13s\n",aq_data->aqbuttons[device].label); + sprintf(device_name,"%-13s\n",aqdata->aqbuttons[device].label); } // NSF Added this since DEBUG hitting wrong command //waitfor_pda_queue2empty(); - if ( find_pda_menu_item(aq_data, device_name, 12) ) { // Remove 1 char to account for '100%' (4 chars not the usual 3) - if (aq_data->aqbuttons[device].led->state != state) { + if ( find_pda_menu_item(aqdata, device_name, 12) ) { // Remove 1 char to account for '100%' (4 chars not the usual 3) + if (aqdata->aqbuttons[device].led->state != state) { //printf("*** Select State ***\n"); - LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, found device '%s', changing state\n",aq_data->aqbuttons[device].label); + LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, found device '%s', changing state\n",aqdata->aqbuttons[device].label); force_queue_delete(); // NSF This is a bad thing to do. Need to fix this send_pda_cmd(KEY_PDA_SELECT); while (get_pda_queue_length() > 0) { delay(500); } // If you are turning on a heater there will be a sub menu to set temp - if ((state == ON) && ((device == aq_data->pool_heater_index) || (device == aq_data->spa_heater_index))) { - if (! waitForPDAnextMenu(aq_data)) { - LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - waitForPDAnextMenu\n", aq_data->aqbuttons[device].label); + if ((state == ON) && ((device == aqdata->pool_heater_index) || (device == aqdata->spa_heater_index))) { + if (! waitForPDAnextMenu(aqdata)) { + LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - waitForPDAnextMenu\n", aqdata->aqbuttons[device].label); } else { send_pda_cmd(KEY_PDA_SELECT); while (get_pda_queue_length() > 0) { delay(500); } - if (!waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,20)) { - LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - wait for CMD_PDA_HIGHLIGHT\n",aq_data->aqbuttons[device].label); + if (!waitForPDAMessageType(aqdata,CMD_PDA_HIGHLIGHT,20)) { + LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - wait for CMD_PDA_HIGHLIGHT\n",aqdata->aqbuttons[device].label); } } - } else if ( isPLIGHT(aq_data->aqbuttons[device].special_mask) ) { + } else if ( isPLIGHT(aqdata->aqbuttons[device].special_mask) ) { // THIS EXTRA ENTER IS ONLY FOR ON, NOT OFF // PDA Menu Line 0 = Set Color // for color light // PDA Menu Line 0 = Set // for dimmer light if ( state == ON ) { - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); if (strncasecmp(pda_m_line(0),"Set", 3) == 0) { - LOG(PDA_LOG,LOG_DEBUG, "PDA Device On/Off, '%s' is programmable light, but no mode using default\n",aq_data->aqbuttons[device].label); + LOG(PDA_LOG,LOG_DEBUG, "PDA Device On/Off, '%s' is programmable light, but no mode using default\n",aqdata->aqbuttons[device].label); send_pda_cmd(KEY_PDA_SELECT); } else { - LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: expected Set menu for programmable light '%s', not found\n",aq_data->aqbuttons[device].label); + LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: expected Set menu for programmable light '%s', not found\n",aqdata->aqbuttons[device].label); } } } else { // not turning on heater wait for line update // worst case spa when pool is running - if (!waitForPDAMessageType(aq_data,CMD_MSG_LONG,2)) { + if (!waitForPDAMessageType(aqdata,CMD_MSG_LONG,2)) { LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - wait for CMD_MSG_LONG\n", - aq_data->aqbuttons[device].label); + aqdata->aqbuttons[device].label); } } } else { - LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, found device '%s', not changing state, is same\n",aq_data->aqbuttons[device].label,state); + LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, found device '%s', not changing state, is same\n",aqdata->aqbuttons[device].label,state); } } else { - LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off, device '%s' not found\n",aq_data->aqbuttons[device].label); + LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off, device '%s' not found\n",aqdata->aqbuttons[device].label); } cleanAndTerminateThread(threadCtrl); @@ -717,7 +717,7 @@ void *set_aqualink_PDA_light_mode( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //int i=0; //int found; //char device_name[15]; @@ -731,13 +731,13 @@ void *set_aqualink_PDA_light_mode( void *ptr ) int typ = atoi(&buf[10]); bool use_current_mode = false; - if (btn < 0 || btn >= aq_data->total_buttons ) { + if (btn < 0 || btn >= aqdata->total_buttons ) { LOG(PDA_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } - aqkey *button = &aq_data->aqbuttons[btn]; + aqkey *button = &aqdata->aqbuttons[btn]; if ( ! isPLIGHT(button->special_mask) ) { @@ -768,17 +768,17 @@ void *set_aqualink_PDA_light_mode( void *ptr ) } } - if (! goto_pda_menu(aq_data, PM_EQUIPTMENT_CONTROL)) { + if (! goto_pda_menu(aqdata, PM_EQUIPTMENT_CONTROL)) { LOG(PDA_LOG,LOG_ERR, "PDA light Programming :- can't find EQUIPTMENT CONTROL menu\n"); cleanAndTerminateThread(threadCtrl); return ptr; } - if ( find_pda_menu_item(aq_data, button->label, 0) ) { // Remove 1 char to account for '100%' (4 chars not the usual 3) + if ( find_pda_menu_item(aqdata, button->label, 0) ) { // Remove 1 char to account for '100%' (4 chars not the usual 3) LOG(PDA_LOG,LOG_INFO, "PDA Light Programming, found device '%s', changing to '%s'\n",button->label,mode_name); force_queue_delete(); // NSF This is a bad thing to do. Need to fix this send_pda_cmd(KEY_PDA_SELECT); - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15); // if we get `PDA Menu Line 3 = Light will turn ` light is on and we need to press enter again. // if we get `PDA Menu Line 2 = Dimmer Power ` we need to cycle over 25%/50%/75%/100% // if we get `Menu Line 0 = Set Color` we can set color. @@ -787,10 +787,10 @@ void *set_aqualink_PDA_light_mode( void *ptr ) } else { if (strncasecmp(pda_m_line(3),"Light will turn", 15) == 0) { send_pda_cmd(KEY_PDA_SELECT); - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5); } if (use_current_mode && mode_name != NULL) { - if (find_pda_menu_item(aq_data,(char *)mode_name,strlen(mode_name))) { + if (find_pda_menu_item(aqdata,(char *)mode_name,strlen(mode_name))) { send_pda_cmd(KEY_PDA_SELECT); } else { LOG(PDA_LOG,LOG_ERR, "PDA Light Programming, could find mode '%s' for device '%s'\n",mode_name,button->label); @@ -812,14 +812,14 @@ void *get_aqualink_PDA_device_status( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //int i; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_DEVICE_STATUS); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); - if (! loopover_devices(aq_data)) { + if (! loopover_devices(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Device Status :- failed\n"); } @@ -833,7 +833,7 @@ void *set_aqualink_PDA_init( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //int i=0; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_INIT); @@ -855,19 +855,19 @@ void *set_aqualink_PDA_init( void *ptr ) char *ptr2 = pda_m_line(5); ptr1[AQ_MSGLEN+1] = '\0'; ptr2[AQ_MSGLEN+1] = '\0'; - //strcpy(aq_data->version, stripwhitespace(ptr)); - snprintf(aq_data->version, (AQ_MSGLEN*2)-1, "%s %s",stripwhitespace(ptr1),stripwhitespace(ptr2)); + //strcpy(aqdata->version, stripwhitespace(ptr)); + snprintf(aqdata->version, (AQ_MSGLEN*2)-1, "%s %s",stripwhitespace(ptr1),stripwhitespace(ptr2)); - //printf("****** Version '%s' ********\n",aq_data->version); - LOG(PDA_LOG,LOG_DEBUG, "PDA type=%d, version=%s\n", _PDA_Type, aq_data->version); + //printf("****** Version '%s' ********\n",aqdata->version); + LOG(PDA_LOG,LOG_DEBUG, "PDA type=%d, version=%s\n", _PDA_Type, aqdata->version); // don't wait for version menu to time out press back to get to home menu faster send_pda_cmd(KEY_PDA_BACK); - //if (! waitForPDAnextMenu(aq_data)) { // waitForPDAnextMenu waits for highlight chars, which we don't get on normal menu + //if (! waitForPDAnextMenu(aqdata)) { // waitForPDAnextMenu waits for highlight chars, which we don't get on normal menu - if (! waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10)) { + if (! waitForPDAMessageType(aqdata,CMD_PDA_CLEAR,10)) { LOG(PDA_LOG,LOG_ERR, "PDA Init :- wait for next menu failed\n"); } } @@ -876,23 +876,23 @@ void *set_aqualink_PDA_init( void *ptr ) } /* // Get status of all devices - if (! loopover_devices(aq_data)) { + if (! loopover_devices(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Init :- can't find menu\n"); } */ // Get heater setpoints - if (! _get_PDA_aqualink_pool_spa_heater_temps(aq_data)) { + if (! _get_PDA_aqualink_pool_spa_heater_temps(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Init :- Error getting heater setpoints\n"); } // Get freeze protect setpoint, AquaPalm doesn't have freeze protect in menu. - if (_PDA_Type != AQUAPALM && ! _get_PDA_freeze_protect_temp(aq_data)) { + if (_PDA_Type != AQUAPALM && ! _get_PDA_freeze_protect_temp(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Init :- Error getting freeze setpoints\n"); } pda_reset_sleep(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); @@ -905,7 +905,7 @@ void *set_aqualink_PDA_wakeinit( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //int i=0; // At this point, we should probably just exit if there is a thread already going as @@ -915,7 +915,7 @@ void *set_aqualink_PDA_wakeinit( void *ptr ) LOG(PDA_LOG,LOG_DEBUG, "PDA Wake Init\n"); // Get status of all devices - if (! loopover_devices(aq_data)) { + if (! loopover_devices(aqdata)) { LOG(PDA_LOG,LOG_ERR, "PDA Init :- can't find menu\n"); } @@ -926,29 +926,29 @@ void *set_aqualink_PDA_wakeinit( void *ptr ) } -bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data) { +bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aqdata) { if ( _PDA_Type == PDA) { - if (! goto_pda_menu(aq_data, PM_FREEZE_PROTECT)) { + if (! goto_pda_menu(aqdata, PM_FREEZE_PROTECT)) { return false; } /* select the freeze protect temp to see which devices are enabled by freeze protect */ send_pda_cmd(KEY_PDA_SELECT); - return waitForPDAnextMenu(aq_data); + return waitForPDAnextMenu(aqdata); } else { LOG(PDA_LOG,LOG_INFO, "In PDA AquaPalm mode, freezepoints not supported\n"); return false; } } -bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data) { +bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aqdata) { // Get heater setpoints - if (! goto_pda_menu(aq_data, PM_SET_TEMP)) { + if (! goto_pda_menu(aqdata, PM_SET_TEMP)) { LOG(PDA_LOG,LOG_ERR, "Could not get heater setpoints, trying again!\n"); // Going to try this twice. - if (! goto_pda_menu(aq_data, PM_SET_TEMP)) { + if (! goto_pda_menu(aqdata, PM_SET_TEMP)) { return false; } } @@ -960,10 +960,10 @@ void *get_PDA_aqualink_pool_spa_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_POOL_SPA_HEATER_TEMPS); - _get_PDA_aqualink_pool_spa_heater_temps(aq_data); + _get_PDA_aqualink_pool_spa_heater_temps(aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -972,33 +972,33 @@ void *get_PDA_freeze_protect_temp( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_FREEZE_PROTECT_TEMP); - _get_PDA_freeze_protect_temp(aq_data); + _get_PDA_freeze_protect_temp(aqdata); cleanAndTerminateThread(threadCtrl); return ptr; } -bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex, int numMessageReceived) +bool waitForPDAMessageHighlight(struct aqualinkdata *aqdata, int highlighIndex, int numMessageReceived) { LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageHighlight index %d\n",highlighIndex); if(pda_m_hlightindex() == highlighIndex) return true; int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { - LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageHighlight last = 0x%02hhx : index %d : (%d of %d)\n",aq_data->last_packet_type,pda_m_hlightindex(),i,numMessageReceived); + LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageHighlight last = 0x%02hhx : index %d : (%d of %d)\n",aqdata->last_packet_type,pda_m_hlightindex(),i,numMessageReceived); - if (aq_data->last_packet_type == CMD_PDA_HIGHLIGHT && pda_m_hlightindex() == highlighIndex) break; + if (aqdata->last_packet_type == CMD_PDA_HIGHLIGHT && pda_m_hlightindex() == highlighIndex) break; - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (pda_m_hlightindex() != highlighIndex) { //LOG(PDA_LOG,LOG_ERR, "Could not select MENU of Aqualink control panel\n"); @@ -1011,29 +1011,29 @@ bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex, } -bool _waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived, bool forceNext) +bool _waitForPDAMessageType(struct aqualinkdata *aqdata, unsigned char mtype, int numMessageReceived, bool forceNext) { LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx\n",mtype); int i=0; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); if (forceNext) { // Ignore current message type, and wait for next - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } while( ++i <= numMessageReceived) { - LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype,aq_data->last_packet_type,i,numMessageReceived); + LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype,aqdata->last_packet_type,i,numMessageReceived); - if (aq_data->last_packet_type == mtype) break; + if (aqdata->last_packet_type == mtype) break; - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); - if (aq_data->last_packet_type != mtype) { + if (aqdata->last_packet_type != mtype) { //LOG(PDA_LOG,LOG_ERR, "Could not select MENU of Aqualink control panel\n"); LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType: did not receive 0x%02hhx\n",mtype); return false; @@ -1043,24 +1043,24 @@ bool _waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, i return true; } -bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived){ - return _waitForPDAMessageType(aq_data, mtype, numMessageReceived, false); +bool waitForPDAMessageType(struct aqualinkdata *aqdata, unsigned char mtype, int numMessageReceived){ + return _waitForPDAMessageType(aqdata, mtype, numMessageReceived, false); } -bool waitForPDANextMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived){ - return _waitForPDAMessageType(aq_data, mtype, numMessageReceived, true); +bool waitForPDANextMessageType(struct aqualinkdata *aqdata, unsigned char mtype, int numMessageReceived){ + return _waitForPDAMessageType(aqdata, mtype, numMessageReceived, true); } // Wait for Message, hit return on particular menu. -bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line) +bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aqdata, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line) { LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypes 0x%02hhx or 0x%02hhx\n",mtype1,mtype2); int i=0; bool gotmenu = false; - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); while( ++i <= numMessageReceived) { @@ -1071,40 +1071,40 @@ bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mt LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypesOrMenu saw '%s' and line %d\n",text,line); } } - LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypes 0x%02hhx | 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype1,mtype2,aq_data->last_packet_type,i,numMessageReceived); + LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypes 0x%02hhx | 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype1,mtype2,aqdata->last_packet_type,i,numMessageReceived); - if (aq_data->last_packet_type == mtype1 || aq_data->last_packet_type == mtype2) break; + if (aqdata->last_packet_type == mtype1 || aqdata->last_packet_type == mtype2) break; - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); - if (aq_data->last_packet_type != mtype1 && aq_data->last_packet_type != mtype2) { + if (aqdata->last_packet_type != mtype1 && aqdata->last_packet_type != mtype2) { //LOG(PDA_LOG,LOG_ERR, "Could not select MENU of Aqualink control panel\n"); LOG(PDA_LOG,LOG_ERR, "waitForPDAMessageTypes: did not receive 0x%02hhx or 0x%02hhx\n",mtype1,mtype2); return false; } else - LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypes: received 0x%02hhx\n",aq_data->last_packet_type); + LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypes: received 0x%02hhx\n",aqdata->last_packet_type); return true; } -bool waitForPDAMessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived) +bool waitForPDAMessageTypes(struct aqualinkdata *aqdata, unsigned char mtype1, unsigned char mtype2, int numMessageReceived) { - return waitForPDAMessageTypesOrMenu(aq_data, mtype1, mtype2, numMessageReceived, NULL, 0); + return waitForPDAMessageTypesOrMenu(aqdata, mtype1, mtype2, numMessageReceived, NULL, 0); } /* Use -1 for cur_val if you want this to find the current value and change it. Use number for cur_val to increase / decrease from known start point */ -bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_val, char *select_label, int step) { +bool set_PDA_numeric_field_value(struct aqualinkdata *aqdata, int val, int cur_val, char *select_label, int step) { int i=0; LOG(PDA_LOG,LOG_DEBUG, "set_PDA_numeric_field_value %s from %d to %d step %d\n", select_label, cur_val, val, step); if (select_label != NULL) { - if ( ! select_pda_menu_item(aq_data, select_label, false) ) { + if ( ! select_pda_menu_item(aqdata, select_label, false) ) { return false; } } @@ -1116,7 +1116,7 @@ bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_ hghlight_chars = pda_m_hlightchars(&hlight_length); // NSF May need to take this out and there for the LOG entry after while while (hlight_length >= 15 || hlight_length <= 0) { delay(500); - waitForPDANextMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5); + waitForPDANextMessageType(aqdata,CMD_PDA_HIGHLIGHTCHARS,5); hghlight_chars = pda_m_hlightchars(&hlight_length); LOG(PDA_LOG,LOG_DEBUG, "Numeric selector, highlight chars '%.*s'\n",hlight_length , hghlight_chars); if (++i >= 20) { @@ -1149,64 +1149,64 @@ bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_ return true; } -//bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val) { +//bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aqdata, int val) { void *set_PDA_aqualink_SWG_setpoint(void *ptr) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_SWG_PERCENT); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SWG_SETPOINT, val, aq_data); + val = setpoint_check(SWG_SETPOINT, val, aqdata); - if (! goto_pda_menu(aq_data, PM_AQUAPURE)) { + if (! goto_pda_menu(aqdata, PM_AQUAPURE)) { LOG(PDA_LOG,LOG_ERR, "Error finding SWG setpoints menu\n"); cleanAndTerminateThread(threadCtrl); return ptr; } // wait for menu to display to capture current value with process_pda_packet_msg_long_SWG - waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS, 10); + waitForPDAMessageTypes(aqdata,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS, 10); /* if (pda_find_m_index("SET POOL") < 0) { // Single Setpoint Screen - set_PDA_numeric_field_value(aq_data, val, -1, NULL, 5); - } else*/ if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) { + set_PDA_numeric_field_value(aqdata, val, -1, NULL, 5); + } else*/ if (aqdata->aqbuttons[SPA_INDEX].led->state != OFF) { // Dual Setpoint Screen with SPA mode enabled - // :TODO: aq_data should have 2 swg_precent values and GUI should be updated to + // :TODO: aqdata should have 2 swg_precent values and GUI should be updated to // display and modify both values. - set_PDA_numeric_field_value(aq_data, val, -1, "SET SPA", 5); + set_PDA_numeric_field_value(aqdata, val, -1, "SET SPA", 5); } else { // Dual Setpoint Screen with SPA mode disabled - set_PDA_numeric_field_value(aq_data, val, -1, "SET POOL", 5); + set_PDA_numeric_field_value(aqdata, val, -1, "SET POOL", 5); } waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); return ptr; } -//bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val) +//bool set_PDA_aqualink_boost(struct aqualinkdata *aqdata, bool val) void *set_PDA_aqualink_boost(void *ptr) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_BOOST); int val = atoi((char*)threadCtrl->thread_args); - if (! goto_pda_menu(aq_data, PM_BOOST)) { + if (! goto_pda_menu(aqdata, PM_BOOST)) { LOG(PDA_LOG,LOG_ERR, "Error finding BOOST menu\n"); return false; } // Should be on the START menu item if (val == true) { // Turn on should just be enter - select_pda_menu_item_loose(aq_data, "START", false); + select_pda_menu_item_loose(aqdata, "START", false); } else { // PDA Line 0 = BOOST // PDA Line 1 = @@ -1219,36 +1219,36 @@ void *set_PDA_aqualink_boost(void *ptr) // PDA Line 8 = RESTART // PDA Line 9 = STOP - select_pda_menu_item_loose(aq_data, "STOP", false); + select_pda_menu_item_loose(aqdata, "STOP", false); } waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); return ptr; } -bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, bool isPool) { +bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aqdata, int val, bool isPool) { char label[10]; int cur_val; if ( isCOMBO_PANEL ) { if (isPool) { sprintf(label, "POOL HEAT"); - cur_val = aq_data->pool_htr_set_point; + cur_val = aqdata->pool_htr_set_point; } else { sprintf(label, "SPA HEAT"); - cur_val = aq_data->spa_htr_set_point; + cur_val = aqdata->spa_htr_set_point; } } else { if (isPool) { sprintf(label, "TEMP1"); - cur_val = aq_data->pool_htr_set_point; + cur_val = aqdata->pool_htr_set_point; } else { sprintf(label, "TEMP2"); - cur_val = aq_data->spa_htr_set_point; + cur_val = aqdata->spa_htr_set_point; } } @@ -1258,12 +1258,12 @@ bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, boo return true; } - if (! goto_pda_menu(aq_data, PM_SET_TEMP)) { + if (! goto_pda_menu(aqdata, PM_SET_TEMP)) { LOG(PDA_LOG,LOG_ERR, "Error finding heater setpoints menu\n"); return false; } - set_PDA_numeric_field_value(aq_data, val, cur_val, label, 1); + set_PDA_numeric_field_value(aqdata, val, cur_val, label, 1); return true; } @@ -1272,18 +1272,18 @@ void *set_aqualink_PDA_pool_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //char *name; //char *menu_name; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_POOL_HEATER_TEMPS); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(POOL_HTR_SETPOINT, val, aq_data); + val = setpoint_check(POOL_HTR_SETPOINT, val, aqdata); - set_PDA_aqualink_heater_setpoint(aq_data, val, true); + set_PDA_aqualink_heater_setpoint(aqdata, val, true); waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1292,66 +1292,66 @@ void *set_aqualink_PDA_spa_heater_temps( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; //char *name; //char *menu_name; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_SPA_HEATER_TEMPS); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(SPA_HTR_SETPOINT, val, aq_data); + val = setpoint_check(SPA_HTR_SETPOINT, val, aqdata); - set_PDA_aqualink_heater_setpoint(aq_data, val, false); + set_PDA_aqualink_heater_setpoint(aqdata, val, false); waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); return ptr; } -//bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int val) { +//bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aqdata, int val) { void *set_aqualink_PDA_freeze_protectsetpoint( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_FREEZE_PROTECT_TEMP); int val = atoi((char*)threadCtrl->thread_args); - val = setpoint_check(FREEZE_SETPOINT, val, aq_data); + val = setpoint_check(FREEZE_SETPOINT, val, aqdata); if (_PDA_Type != PDA) { LOG(PDA_LOG,LOG_INFO, "In PDA AquaPalm mode, freezepoints not supported\n"); //return false; - } else if (! goto_pda_menu(aq_data, PM_FREEZE_PROTECT)) { + } else if (! goto_pda_menu(aqdata, PM_FREEZE_PROTECT)) { LOG(PDA_LOG,LOG_ERR, "Error finding freeze protect setpoints menu\n"); //return false; - } else if (! set_PDA_numeric_field_value(aq_data, val, aq_data->frz_protect_set_point, NULL, 1)) { + } else if (! set_PDA_numeric_field_value(aqdata, val, aqdata->frz_protect_set_point, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set freeze protect temp value\n"); //return false; } else { - waitForPDAnextMenu(aq_data); + waitForPDAnextMenu(aqdata); } waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); cleanAndTerminateThread(threadCtrl); return ptr; } -//bool set_PDA_aqualink_time(struct aqualinkdata *aq_data) +//bool set_PDA_aqualink_time(struct aqualinkdata *aqdata) void *set_PDA_aqualink_time( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_TIME); - if (! goto_pda_menu(aq_data, PM_SET_TIME)) { + if (! goto_pda_menu(aqdata, PM_SET_TIME)) { LOG(PDA_LOG,LOG_ERR, "Error finding set time menu\n"); goto f_end; } @@ -1393,25 +1393,25 @@ Debug: PDA: PDA Menu Line 9 = to continue. asctime_r(&panel_tm,result)); // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x02|0x03|0x01|0x8c|0x10|0x03| - if (! set_PDA_numeric_field_value(aq_data, tm.tm_mon, panel_tm.tm_mon, NULL, 1)) { + if (! set_PDA_numeric_field_value(aqdata, tm.tm_mon, panel_tm.tm_mon, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set month\n"); // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x05|0x06|0x01|0x92|0x10|0x03| - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_mday, panel_tm.tm_mday, NULL, 1)) { + } else if (! set_PDA_numeric_field_value(aqdata, tm.tm_mday, panel_tm.tm_mday, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set day\n"); // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x02|0x08|0x09|0x01|0x98|0x10|0x03| - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_year, panel_tm.tm_year, NULL, 1)) { + } else if (! set_PDA_numeric_field_value(aqdata, tm.tm_year, panel_tm.tm_year, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set year\n"); // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x04|0x05|0x01|0x91|0x10|0x03| - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_hour, panel_tm.tm_hour, NULL, 1)) { + } else if (! set_PDA_numeric_field_value(aqdata, tm.tm_hour, panel_tm.tm_hour, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set hour\n"); // PDA HlightChars | HEX: 0x10|0x02|0x62|0x10|0x03|0x07|0x08|0x01|0x97|0x10|0x03| - } else if (! set_PDA_numeric_field_value(aq_data, tm.tm_min, panel_tm.tm_min, NULL, 1)) { + } else if (! set_PDA_numeric_field_value(aqdata, tm.tm_min, panel_tm.tm_min, NULL, 1)) { LOG(PDA_LOG,LOG_ERR, "Error failed to set min\n"); } - waitForPDAnextMenu(aq_data); + waitForPDAnextMenu(aqdata); waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); f_end: @@ -1420,13 +1420,13 @@ Debug: PDA: PDA Menu Line 9 = to continue. } // Test ine this. -//bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data) { +//bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aqdata) { void *get_PDA_aqualink_aux_labels( void *ptr ) { struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; #ifdef BETA_PDA_AUTOLABEL - struct aqualinkdata *aq_data = threadCtrl->aq_data; + struct aqualinkdata *aqdata = threadCtrl->aqdata; waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_AUX_LABELS); @@ -1435,22 +1435,22 @@ void *get_PDA_aqualink_aux_labels( void *ptr ) { LOG(PDA_LOG,LOG_INFO, "Finding PDA labels, (BETA ONLY)\n"); - if (! goto_pda_menu(aq_data, PM_AUX_LABEL)) { + if (! goto_pda_menu(aqdata, PM_AUX_LABEL)) { LOG(PDA_LOG,LOG_ERR, "Error finding aux label menu\n"); goto f_end; } for (i=1;i<8;i++) { sprintf(label, "AUX%d",i); - select_pda_menu_item(aq_data, label, true); + select_pda_menu_item(aqdata, label, true); send_pda_cmd(KEY_PDA_BACK); - waitForPDAnextMenu(aq_data); + waitForPDAnextMenu(aqdata); } // Read first page of devices and make some assumptions. waitfor_pda_queue2empty(); - goto_pda_menu(aq_data, PM_HOME); + goto_pda_menu(aqdata, PM_HOME); f_end: @@ -1463,12 +1463,12 @@ void *get_PDA_aqualink_aux_labels( void *ptr ) { } /* -bool waitForPDAMessage(struct aqualinkdata *aq_data, int numMessageReceived, unsigned char packettype) +bool waitForPDAMessage(struct aqualinkdata *aqdata, int numMessageReceived, unsigned char packettype) { LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessage %s %d\n",message,numMessageReceived); int i=0; - pthread_mutex_init(&aq_data->active_thread.thread_mutex, NULL); - pthread_mutex_lock(&aq_data->active_thread.thread_mutex); + pthread_mutex_init(&aqdata->active_thread.thread_mutex, NULL); + pthread_mutex_lock(&aqdata->active_thread.thread_mutex); char* msgS; char* ptr; @@ -1482,34 +1482,34 @@ bool waitForPDAMessage(struct aqualinkdata *aq_data, int numMessageReceived, uns while( ++i <= numMessageReceived) { if (message != NULL) - LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aqdata->last_message); else - LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d waiting for next message, received '%s'\n",i,numMessageReceived,aq_data->last_message); + LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d waiting for next message, received '%s'\n",i,numMessageReceived,aqdata->last_message); if (message != NULL) { - ptr = stristr(aq_data->last_message, msgS); + ptr = stristr(aqdata->last_message, msgS); if (ptr != NULL) { // match LOG(PDA_LOG,LOG_DEBUG, "Programming mode: String MATCH\n"); if (msgS == message) // match & don't care if first char break; - else if (ptr == aq_data->last_message) // match & do care if first char + else if (ptr == aqdata->last_message) // match & do care if first char break; } } - //LOG(PDA_LOG,LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aq_data->last_message); - pthread_cond_init(&aq_data->active_thread.thread_cond, NULL); - pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(PDA_LOG,LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aqdata->last_message); + pthread_cond_init(&aqdata->active_thread.thread_cond, NULL); + pthread_cond_wait(&aqdata->active_thread.thread_cond, &aqdata->active_thread.thread_mutex); + //LOG(PDA_LOG,LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aqdata->last_message); } - pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); + pthread_mutex_unlock(&aqdata->active_thread.thread_mutex); if (message != NULL && ptr == NULL) { //LOG(PDA_LOG,LOG_ERR, "Could not select MENU of Aqualink control panel\n"); LOG(PDA_LOG,LOG_DEBUG, "Programming mode: did not find '%s'\n",message); return false; } else if (message != NULL) - LOG(PDA_LOG,LOG_DEBUG, "Programming mode: found message '%s' in '%s'\n",message,aq_data->last_message); + LOG(PDA_LOG,LOG_DEBUG, "Programming mode: found message '%s' in '%s'\n",message,aqdata->last_message); return true; } diff --git a/source/rs_msg_utils.c b/source/rs_msg_utils.c index cc666bf..ab8f22d 100644 --- a/source/rs_msg_utils.c +++ b/source/rs_msg_utils.c @@ -198,6 +198,18 @@ bool rsm_isempy(const char *src, int length) } return true; } + +#include "aq_serial.h" +int rsm_countascii(const char *src) +{ + int i; + for(i=0; i < AQ_MSGLONGLEN; i++) { + if (src[i] < 32 || src[i] > 126) // 32 is space + break; + } + + return i; +} /* Can probably replace this with rsm_strncasestr in all code. */ diff --git a/source/rs_msg_utils.h b/source/rs_msg_utils.h index 71cb618..46b9da6 100644 --- a/source/rs_msg_utils.h +++ b/source/rs_msg_utils.h @@ -31,4 +31,6 @@ char *rsm_char_replace(char *replaced , char *search, char *find, char *replac char *rsm_nchar_replace(char *replaced, int replaced_len, char *search, char *find, char *replace); int rsm_HHMM2min(char *message); +int rsm_countascii(const char *src); + #endif //RS_MSG_UTILS_H_ diff --git a/source/sensors.c b/source/sensors.c index 84ce889..d345da4 100644 --- a/source/sensors.c +++ b/source/sensors.c @@ -39,7 +39,7 @@ struct sensorthread { pthread_t thread_id; pthread_mutex_t thread_mutex; pthread_cond_t thread_cond; - struct aqualinkdata *aq_data; + struct aqualinkdata *aqdata; struct timespec timeout; }; @@ -50,14 +50,16 @@ void *sensors_worker( void *ptr ); void stop_sensors_thread() { LOG(AQUA_LOG, LOG_INFO, "Stopping sensor thread\n"); - pthread_cond_broadcast(&_sthread->thread_cond); + if (_sthread != NULL) + pthread_cond_broadcast(&_sthread->thread_cond); + } -void start_sensors_thread(struct aqualinkdata *aq_data) { +void start_sensors_thread(struct aqualinkdata *aqdata) { _sthread = calloc(1, sizeof(struct sensorthread)); - _sthread->aq_data = aq_data; + _sthread->aqdata = aqdata; _sthread->thread_id = 0; if( pthread_create( &_sthread->thread_id , NULL , sensors_worker, (void*)_sthread) < 0) { @@ -87,10 +89,10 @@ void *sensors_worker( void *ptr ) break; } - for (int i=0; i < sthread->aq_data->num_sensors; i++) { - //LOG(AQUA_LOG, LOG_DEBUG, "Sensor thread reading %s\n",sthread->aq_data->sensors[i].label); - if (read_sensor(&sthread->aq_data->sensors[i]) ) { - sthread->aq_data->updated = true; + for (int i=0; i < sthread->aqdata->num_sensors; i++) { + //LOG(AQUA_LOG, LOG_DEBUG, "Sensor thread reading %s\n",sthread->aqdata->sensors[i].label); + if (read_sensor(&sthread->aqdata->sensors[i]) ) { + SET_DIRTY(sthread->aqdata->is_dirty); } } diff --git a/source/serialadapter.c b/source/serialadapter.c index 1d345f3..c05bb9f 100644 --- a/source/serialadapter.c +++ b/source/serialadapter.c @@ -35,10 +35,10 @@ unsigned char getAux15[] = {0x00,0x01,0x00,RS_SA_AUX15}; // processLEDstate exists in allbutton.c -//void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmask_t from); -void processRSSALEDstate(struct aqualinkdata *aq_data, unsigned char *packet) +//void processLEDstate(struct aqualinkdata *aqdata, unsigned char *packet, logmask_t from); +void processRSSALEDstate(struct aqualinkdata *aqdata, unsigned char *packet) { - processLEDstate(aq_data, packet, RSSA_LOG); + processLEDstate(aqdata, packet, RSSA_LOG); } @@ -225,12 +225,12 @@ void get_aqualink_rssadapter_button_status(aqkey *button) if (button->rssd_code != NUL) rssadapter_device_state(button->rssd_code, 0x00); } -void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aq_data) +void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aqdata) { - for (int i=0; i < aq_data->num_lights; i++) { - if (aq_data->lights[i].lightType != LC_PROGRAMABLE ) { + for (int i=0; i < aqdata->num_lights; i++) { + if (aqdata->lights[i].lightType != LC_PROGRAMABLE ) { // LC_PROGRAMABLE is aqualinkd to set, so works as normal button - rssadapter_device_state(aq_data->lights[i].button->rssd_code, 0x00); // 0x00 meand Get curent state + rssadapter_device_state(aqdata->lights[i].button->rssd_code, 0x00); // 0x00 meand Get curent state } } } @@ -247,7 +247,7 @@ void get_aqualink_rssadapter_setpoints() { } // Return true if we change the state. -bool setLEDstate( aqled *led, unsigned char state, struct aqualinkdata *aq_data) +bool setLEDstate( aqled *led, unsigned char state, struct aqualinkdata *aqdata) { if (state == 0x00) { if (led->state != OFF) { @@ -267,7 +267,7 @@ bool setLEDstate( aqled *led, unsigned char state, struct aqualinkdata *aq_data) return false; } -bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) { +bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata) { //RSSA_LOG bool rtn = false; static int cnt=-5; @@ -278,7 +278,7 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin //debuglogPacket(RSSA_LOG, packet, length, true); #ifdef CLIGHT_PANEL_FIX if ( (cnt % 10 == 0) || cnt == 0 ) { // NSF Change to 20 and 1 - get_aqualink_rssadapter_colorlight_statuses(aq_data); + get_aqualink_rssadapter_colorlight_statuses(aqdata); } #endif if (cnt == 0 || cnt >= 100) { @@ -287,7 +287,7 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin if (cnt == 0) { // The below inturn calls get_aqualink_rssadapter_setpoints() // But do it here as it's the first init, cnt=0 will only happen once - queueGetProgramData(RSSADAPTER, aq_data); + queueGetProgramData(RSSADAPTER, aqdata); } else { push_rssa_cmd(getPoolSP); @@ -309,14 +309,14 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin if (packet[PKT_CMD] == CMD_PROBE) { LOG(RSSA_LOG,LOG_DEBUG, "Probe received, will queue device update shortly\n"); - //queueGetProgramData(RSSADAPTER, aq_data); + //queueGetProgramData(RSSADAPTER, aqdata); cnt=-5; // Connection reset, so queue the status update } else if (packet[PKT_CMD] == CMD_STATUS) { // This is identical to allbutton status packet. //LOG(RSSA_LOG,LOG_DEBUG, "RS Received STATUS length %d.\n", length); //debuglogPacket(RSSA_LOG, packet, length, true, true); - processRSSALEDstate(aq_data, packet); + processRSSALEDstate(aqdata, packet); } else if (packet[PKT_CMD] == 0x13) { //beautifyPacket(buff, packet, length); //LOG(RSSA_LOG,LOG_DEBUG, "%s", buff); @@ -333,77 +333,77 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin } else if (packet[4] == RS_SA_UNITS) { if (packet[6] == 0x01) { LOG(RSSA_LOG,LOG_INFO,"Units are Deg C\n"); - aq_data->temp_units = CELSIUS; - rtn = true; + SET_IF_CHANGED(aqdata->temp_units, CELSIUS, aqdata->is_dirty); + rtn |= true; } else if (packet[6] == 0x00) { LOG(RSSA_LOG,LOG_INFO,"Units are Deg F\n"); - aq_data->temp_units = FAHRENHEIT; - rtn = true; + SET_IF_CHANGED(aqdata->temp_units, FAHRENHEIT, aqdata->is_dirty); + rtn |= true; } else { LOG(RSSA_LOG,LOG_ERR,"Units are Unknown\n"); } } else if (packet[4] == RS_SA_POOLSP) { LOG(RSSA_LOG,LOG_INFO,"Pool SP is %d\n", packet[6]); - aq_data->pool_htr_set_point = (int) packet[6]; - rtn = true; + SET_IF_CHANGED(aqdata->pool_htr_set_point, (int) packet[6], aqdata->is_dirty); + rtn |= true; } else if (packet[4] == RS_SA_SPASP) { LOG(RSSA_LOG,LOG_INFO,"Spa SP is %d\n", packet[6]); - aq_data->spa_htr_set_point = (int) packet[6]; - rtn = true; + SET_IF_CHANGED(aqdata->spa_htr_set_point, (int) packet[6], aqdata->is_dirty); + rtn |= true; } else if (packet[4] == RS_SA_POOLSP2) { LOG(RSSA_LOG,LOG_INFO,"Pool SP2 is %d\n", packet[6]); - aq_data->spa_htr_set_point = (int) packet[6]; - rtn = true; + SET_IF_CHANGED(aqdata->spa_htr_set_point, (int) packet[6], aqdata->is_dirty); + rtn |= true; } else if (packet[4] == 0x03 || packet[4] == 0x02) { // 03 reply from query state, 02 reply from set state // These are device status messages - for (int i=0; i < aq_data->num_lights; i++) { - if (aq_data->lights[i].lightType != LC_PROGRAMABLE && - aq_data->lights[i].button->rssd_code == packet[7] ) { + for (int i=0; i < aqdata->num_lights; i++) { + if (aqdata->lights[i].lightType != LC_PROGRAMABLE && + aqdata->lights[i].button->rssd_code == packet[7] ) { // CHANGE TO DEBUG BEFORE RELEASE - if (aq_data->lights[i].lightType == LC_DIMMER || aq_data->lights[i].lightType == LC_DIMMER2) { + if (aqdata->lights[i].lightType == LC_DIMMER || aqdata->lights[i].lightType == LC_DIMMER2) { LOG(RSSA_LOG,LOG_DEBUG,"DimmerLight '%s' is %s, rawvalue 0x%02hhx value '%d'%%\n", - aq_data->lights[i].button->label, + aqdata->lights[i].button->label, packet[6]==0x00?"OFF":"ON", packet[6], packet[6]==0x00?0:(packet[6] - RSSD_DIMMER_LIGHT_OFFSET)); }else{ LOG(RSSA_LOG,LOG_DEBUG,"ColorLight '%s' is %s 0x%02hhx value name '%s'\n", - aq_data->lights[i].button->label, + aqdata->lights[i].button->label, packet[6]==0x00?"OFF":"ON", packet[6], - packet[6]==0x00?"--":light_mode_name( aq_data->lights[i].lightType,(packet[6] - RSSD_COLOR_LIGHT_OFFSET), RSSADAPTER) ); + packet[6]==0x00?"--":light_mode_name( aqdata->lights[i].lightType,(packet[6] - RSSD_COLOR_LIGHT_OFFSET), RSSADAPTER) ); } - aq_data->lights[i].RSSDstate = (packet[6]==0x00?OFF:ON); + SET_IF_CHANGED(aqdata->lights[i].RSSDstate, (packet[6]==0x00?OFF:ON), aqdata->is_dirty); #ifdef CLIGHT_PANEL_FIX // Set LED to the correct state, but only print warning if light is on and panel states off. - if (aq_data->lights[i].RSSDstate == ON && aq_data->lights[i].button->led->state == OFF) { + if (aqdata->lights[i].RSSDstate == ON && aqdata->lights[i].button->led->state == OFF) { // 0x00 is off, 0x01 is usually on, but get 0x44 for color light 0x4e=gemstone, 0x41=vodo LOG(RSSA_LOG,LOG_DEBUG,"ColorLight '%s' is out of sync with panel, light is '%s', panel states '%s', Fixed Jany bug!\n", - aq_data->lights[i].button->label, + aqdata->lights[i].button->label, packet[6]==0x00?"OFF":"ON", - aq_data->lights[i].button->led->state==OFF?"OFF":"ON"); + aqdata->lights[i].button->led->state==OFF?"OFF":"ON"); } - aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate; + SET_IF_CHANGED(aqdata->lights[i].button->led->state, aqdata->lights[i].RSSDstate, aqdata->is_dirty); #endif - switch(aq_data->lights[i].lightType) { + switch(aqdata->lights[i].lightType) { case LC_DIMMER: - set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25); + rtn |= set_currentlight_value(&aqdata->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25); break; case LC_DIMMER2: - set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET)); + rtn |= set_currentlight_value(&aqdata->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET)); break; default: - set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET)); + rtn |= set_currentlight_value(&aqdata->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET)); break; } /* - if (aq_data->lights[i].lightType != LC_DIMMER ) { - set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET)); - } else if (aq_data->lights[i].lightType == LC_DIMMER) { - set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25); + if (aqdata->lights[i].lightType != LC_DIMMER ) { + set_currentlight_value(&aqdata->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET)); + } else if (aqdata->lights[i].lightType == LC_DIMMER) { + set_currentlight_value(&aqdata->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25); }*/ } } @@ -411,25 +411,24 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin if (packet[7] == RS_SA_AUX12) { LOG(RSSA_LOG,LOG_INFO,"AUX12 %d\n", packet[6]); - rtn = setLEDstate(aq_data->aqbuttons[13].led, packet[6], aq_data); + rtn |= setLEDstate(aqdata->aqbuttons[13].led, packet[6], aqdata); //_aqualink_data.aqbuttons[13].led->state = OFF; } else if (packet[7] == RS_SA_AUX13) { LOG(RSSA_LOG,LOG_INFO,"AUX13 %d\n", packet[6]); - rtn = setLEDstate(aq_data->aqbuttons[14].led, packet[6], aq_data); + rtn |= setLEDstate(aqdata->aqbuttons[14].led, packet[6], aqdata); } else if (packet[7] == RS_SA_AUX14) { LOG(RSSA_LOG,LOG_INFO,"AUX14 %d\n", packet[6]); - rtn = setLEDstate(aq_data->aqbuttons[15].led, packet[6], aq_data); + rtn |= setLEDstate(aqdata->aqbuttons[15].led, packet[6], aqdata); } else if (packet[7] == RS_SA_AUX15) { LOG(RSSA_LOG,LOG_INFO,"AUX15 %d\n", packet[6]); - rtn = setLEDstate(aq_data->aqbuttons[16].led, packet[6], aq_data); + rtn |= setLEDstate(aqdata->aqbuttons[16].led, packet[6], aqdata); } } } - if (rtn == true) - aq_data->updated = true; + if (rtn){SET_DIRTY(aqdata->is_dirty);} return rtn; } diff --git a/source/version.h b/source/version.h index 984e68d..060efac 100644 --- a/source/version.h +++ b/source/version.h @@ -4,5 +4,5 @@ #define AQUALINKD_SHORT_NAME "AqualinkD" // Use Magor . Minor . Patch -#define AQUALINKD_VERSION "3.0.0 (dev r5)" +#define AQUALINKD_VERSION "3.0.0 (dev r6)" \ No newline at end of file