From 8b5bacf68be59385bcca996904e4cbb35cb93083 Mon Sep 17 00:00:00 2001 From: sfeakes Date: Sat, 4 Oct 2025 17:18:06 -0500 Subject: [PATCH] Dev release 3 update --- Makefile | 28 +- README.md | 11 +- release/aqualinkd-arm64 | Bin 754536 -> 763272 bytes release/aqualinkd-armhf | Bin 731356 -> 740012 bytes release/aqualinkd.c | 0 release/aqualinkd.conf | 32 +- release/serial_logger-arm64 | Bin 77112 -> 77152 bytes release/serial_logger-armhf | Bin 63164 -> 63196 bytes source/allbutton.c | 441 +++++++++++++++------------- source/allbutton_aq_programmer.c | 424 +++++++++++++-------------- source/aq_panel.c | 69 ++++- source/aq_programmer.c | 207 ++++++------- source/aq_programmer.h | 2 +- source/aq_scheduler.c | 44 +-- source/aq_serial.c | 2 +- source/aq_timer.c | 20 +- source/aqualink.h | 84 +++++- source/aqualinkd.c | 330 +++++---------------- source/auto_configure.c | 279 ++++++++++++++++++ source/auto_configure.h | 9 + source/color_lights.c | 15 +- source/color_lights.h | 2 +- source/devices_jandy.c | 111 ++----- source/devices_pentair.c | 16 +- source/iaqtouch.c | 447 ++++++++-------------------- source/iaqtouch_aq_programmer.c | 338 ++++++++++----------- source/iaqualink.c | 86 +++--- source/json_messages.c | 78 ++--- source/net_services.c | 37 +-- source/onetouch.c | 288 +++++++++--------- source/onetouch_aq_programmer.c | 206 ++++++------- source/pda.c | 111 +++---- source/pda_aq_programmer.c | 488 +++++++++++++++---------------- source/rs_msg_utils.c | 12 + source/rs_msg_utils.h | 2 + source/sensors.c | 18 +- source/serialadapter.c | 97 +++--- source/version.h | 2 +- 38 files changed, 2174 insertions(+), 2162 deletions(-) create mode 100644 release/aqualinkd.c create mode 100644 source/auto_configure.c create mode 100644 source/auto_configure.h 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 bfaa48edf89be0440fded9205bdd67d95faa67a1..31eb8586e0c3692878ddcefc6075f211b46fcb27 100755 GIT binary patch delta 285350 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 w#>{J*A(H1r1eBfx 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 z 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%0Dh+p652BnI{TC**_5HQU7- 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 Tg|C1uJbb^Dn+iX;3+Mj_Mh6F7 diff --git a/release/aqualinkd-armhf b/release/aqualinkd-armhf index 585925aef94444f65442d5795316a8a838b0ec10..119d5fbf0682d29a9208e68c984a4146b322043d 100755 GIT binary patch delta 233948 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 z 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

+c<~yv;fxkLcWh9ZXGN)<@h+AG`lzf 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ð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%0ABH73yoMdsN@ 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 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 ee5ea25a4e6efde6a8e5ebbf51afb00d5ba97c85..23c72f59f6dc4fdc7d41cabf884e7c00ebbc4620 100755 GIT binary patch delta 11457 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 delta 11551 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 diff --git a/release/serial_logger-armhf b/release/serial_logger-armhf index 4acc471ba9754f7997044968af705e2c4671b9f2..0a75ef29c40566c4dcf44224869f9bd6c6fbf9a0 100755 GIT binary patch delta 10221 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 delta 10303 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, 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