Dev release 3 update

pull/476/head
sfeakes 2025-10-04 17:18:06 -05:00
parent cc4ec9f2dd
commit 8b5bacf68b
38 changed files with 2174 additions and 2162 deletions

View File

@ -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

View File

@ -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.

Binary file not shown.

Binary file not shown.

0
release/aqualinkd.c Normal file
View File

View File

@ -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=<USER>
#mqtt_passwd<PASWORD>
#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
#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

Binary file not shown.

Binary file not shown.

View File

@ -12,15 +12,15 @@
#include "aq_scheduler.h"
/* Below can also be called from serialadapter.c */
void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmask_t from)
void processLEDstate(struct aqualinkdata *aqdata, unsigned char *packet, logmask_t from)
{
int i = 0;
int byte;
int bit;
if (memcmp(aq_data->raw_status, packet + 4, AQ_PSTLEN) != 0) {
aq_data->updated = true;
if (memcmp(aqdata->raw_status, packet + 4, AQ_PSTLEN) != 0) {
SET_DIRTY(aqdata->is_dirty);
LOG(from,LOG_DEBUG, "Processing LEDs status CHANGED\n");
} else {
LOG(from,LOG_DEBUG, "Processing LEDs status\n");
@ -28,7 +28,7 @@ void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmas
// But for the moment, we don't need to speed up anything.
}
memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN);
memcpy(aqdata->raw_status, packet + 4, AQ_PSTLEN);
//debuglogPacket(ALLB_LOG, );
@ -37,53 +37,64 @@ void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmas
{
for (bit = 0; bit < 8; bit += 2)
{
if (((aq_data->raw_status[byte] >> (bit + 1)) & 1) == 1)
aq_data->aqualinkleds[i].state = FLASH;
else if (((aq_data->raw_status[byte] >> bit) & 1) == 1)
aq_data->aqualinkleds[i].state = ON;
else
aq_data->aqualinkleds[i].state = OFF;
if (((aqdata->raw_status[byte] >> (bit + 1)) & 1) == 1){
//aqdata->aqualinkleds[i].state = FLASH;
SET_IF_CHANGED(aqdata->aqualinkleds[i].state, FLASH, aqdata->is_dirty);
} else if (((aqdata->raw_status[byte] >> bit) & 1) == 1){
//aqdata->aqualinkleds[i].state = ON;
SET_IF_CHANGED(aqdata->aqualinkleds[i].state, ON, aqdata->is_dirty);
}else{
//aqdata->aqualinkleds[i].state = OFF;
SET_IF_CHANGED(aqdata->aqualinkleds[i].state, OFF, aqdata->is_dirty);
}
//LOG(from,LOG_DEBUG,"Led %d state %d",i+1,aq_data->aqualinkleds[i].state);
//LOG(from,LOG_DEBUG,"Led %d state %d",i+1,aqdata->aqualinkleds[i].state);
i++;
}
}
// Reset enabled state for heaters, as they take 2 led states
if (aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[POOL_HTR_LED_INDEX].state == ON)
aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE;
if (aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[POOL_HTR_LED_INDEX].state == ON){
//aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE;
SET_IF_CHANGED(aqdata->aqualinkleds[POOL_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty);
}
if (aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SPA_HTR_LED_INDEX].state == ON)
aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE;
if (aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[SPA_HTR_LED_INDEX].state == ON){
//aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE;
SET_IF_CHANGED(aqdata->aqualinkleds[SPA_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty);
}
if (aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON)
aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE;
if (aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON){
//aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE;
SET_IF_CHANGED(aqdata->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state, ENABLE, aqdata->is_dirty);
}
/*
for (i=0; i < TOTAL_BUTTONS; i++) {
LOG(from,LOG_NOTICE, "%s = %d", aq_data->aqbuttons[i].name, aq_data->aqualinkleds[i].state);
LOG(from,LOG_NOTICE, "%s = %d", aqdata->aqbuttons[i].name, aqdata->aqualinkleds[i].state);
}
*/
#ifdef CLIGHT_PANEL_FIX // Use state from RSSD protocol for color light if it's on.
for (int i=0; i < aq_data->num_lights; i++) {
if ( aq_data->lights[i].RSSDstate == ON && aq_data->lights[i].button->led->state != ON ) {
aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate;
//LOG(from,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aq_data->lights[i].button->label);
for (int i=0; i < aqdata->num_lights; i++) {
if ( aqdata->lights[i].RSSDstate == ON && aqdata->lights[i].button->led->state != ON ) {
aqdata->lights[i].button->led->state = aqdata->lights[i].RSSDstate;
SET_IF_CHANGED(aqdata->lights[i].button->led->state, aqdata->lights[i].RSSDstate, aqdata->is_dirty);
//LOG(from,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aqdata->lights[i].button->label);
}
// Below is for aqualinkd programmable light, set color mode to last if something else turns it on or off.
if (aq_data->lights[i].lightType == LC_PROGRAMABLE && ! in_light_programming_mode(aq_data)) {
if (aq_data->lights[i].button->led->state == OFF && aq_data->lights[i].currentValue != 0) {
set_currentlight_value(&aq_data->lights[i], 0);
if (aqdata->lights[i].lightType == LC_PROGRAMABLE && ! in_light_programming_mode(aqdata)) {
if (aqdata->lights[i].button->led->state == OFF && aqdata->lights[i].currentValue != 0) {
set_currentlight_value(&aqdata->lights[i], 0);
//LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE 0 ******\n");
} else if (aq_data->lights[i].button->led->state == ON && aq_data->lights[i].currentValue == 0 && aq_data->lights[i].lastValue != 0) {
set_currentlight_value(&aq_data->lights[i], aq_data->lights[i].lastValue);
//LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE %d ******\n",aq_data->lights[i].lastValue);
} else if (aqdata->lights[i].button->led->state == ON && aqdata->lights[i].currentValue == 0 && aqdata->lights[i].lastValue != 0) {
set_currentlight_value(&aqdata->lights[i], aqdata->lights[i].lastValue);
//LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE %d ******\n",aqdata->lights[i].lastValue);
}
}
}
#endif
}
void setUnits(char *msg, struct aqualinkdata *aq_data)
void setUnits(char *msg, struct aqualinkdata *aqdata)
{
char buf[AQ_MSGLEN*3];
@ -92,14 +103,18 @@ void setUnits(char *msg, struct aqualinkdata *aq_data)
//ascii(buf, msg);
LOG(ALLB_LOG,LOG_DEBUG, "Getting temp units from message '%s', looking at '%c'\n", buf, buf[strlen(buf) - 1]);
if (msg[strlen(msg) - 1] == 'F')
aq_data->temp_units = FAHRENHEIT;
else if (msg[strlen(msg) - 1] == 'C')
aq_data->temp_units = CELSIUS;
else
aq_data->temp_units = UNKNOWN;
if (msg[strlen(msg) - 1] == 'F') {
//aqdata->temp_units = FAHRENHEIT;
SET_IF_CHANGED(aqdata->temp_units, FAHRENHEIT, aqdata->is_dirty);
} else if (msg[strlen(msg) - 1] == 'C') {
//aqdata->temp_units = CELSIUS;
SET_IF_CHANGED(aqdata->temp_units, CELSIUS, aqdata->is_dirty);
} else {
//aqdata->temp_units = UNKNOWN;
SET_IF_CHANGED(aqdata->temp_units, UNKNOWN, aqdata->is_dirty);
}
LOG(ALLB_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aq_data->temp_units);
LOG(ALLB_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aqdata->temp_units);
}
// Defined as int16_t so 16 bits to mask
@ -118,7 +133,7 @@ void setUnits(char *msg, struct aqualinkdata *aq_data)
#define MSG_LOOP_SPA_TEMP (1 << 12)
int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data)
int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aqdata)
{
char *sp;
int i;
@ -147,11 +162,12 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data)
// Only need to start at Aux B5->B8 (12-15)
// Loop over only aqdata->aqbuttons[13] to aqdata->aqbuttons[16]
for (i = aq_data->rs16_vbutton_start; i <= aq_data->rs16_vbutton_end; i++) {
for (i = aqdata->rs16_vbutton_start; i <= aqdata->rs16_vbutton_end; i++) {
//TOTAL_BUTTONS
if ( stristr(msg, aq_data->aqbuttons[i].label) != NULL) {
aq_data->aqbuttons[i].led->state = state;
LOG(ALLB_LOG,LOG_INFO, "Set %s to %d\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state);
if ( stristr(msg, aqdata->aqbuttons[i].label) != NULL) {
//aqdata->aqbuttons[i].led->state = state;
SET_IF_CHANGED(aqdata->aqbuttons[i].led->state, state, aqdata->is_dirty);
LOG(ALLB_LOG,LOG_INFO, "Set %s to %d\n", aqdata->aqbuttons[i].label, aqdata->aqbuttons[i].led->state);
// Return true should be the result, but in the if we want to continue to display message
//return true;
if (i == 13)
@ -164,7 +180,7 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data)
return MSG_RS16BUTTON;
else
{
LOG(ALLB_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state, i);
LOG(ALLB_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", aqdata->aqbuttons[i].label, aqdata->aqbuttons[i].led->state, i);
return false;
}
@ -175,17 +191,17 @@ int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data)
}
void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset);
void _processMessage(char *message, struct aqualinkdata *aqdata, bool reset);
void processMessage(char *message, struct aqualinkdata *aq_data)
void processMessage(char *message, struct aqualinkdata *aqdata)
{
_processMessage(message, aq_data, false);
_processMessage(message, aqdata, false);
}
void processMessageReset(struct aqualinkdata *aq_data)
void processMessageReset(struct aqualinkdata *aqdata)
{
_processMessage(NULL, aq_data, true);
_processMessage(NULL, aqdata, true);
}
void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
void _processMessage(char *message, struct aqualinkdata *aqdata, bool reset)
{
char *msg;
static bool _initWithRS = false;
@ -203,7 +219,7 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
//msg = stripwhitespace(message);
//strcpy(aq_data->last_message, msg);
//strcpy(aqdata->last_message, msg);
//LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
@ -215,91 +231,92 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
//if (stristr(msg, "JANDY AquaLinkRS") != NULL) {
if (!reset) {
msg = stripwhitespace(message);
strcpy(aq_data->last_message, msg);
strcpy(aqdata->last_message, msg);
LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
// Just set this to off, it will re-set since it'll be the only message we get if on
aq_data->service_mode_state = OFF;
aqdata->service_mode_state = OFF;
} else {
//aq_data->display_message = NULL;
aq_data->last_display_message[0] = ' ';
aq_data->last_display_message[1] = '\0';
//aqdata->display_message = NULL;
//aqdata->last_display_message[0] = ' ';
//aqdata->last_display_message[1] = '\0';
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, "", aqdata->is_dirty);
// Anything that wasn't on during the last set of messages, turn off
if ((msg_loop & MSG_FREEZE) != MSG_FREEZE) {
if (aq_data->frz_protect_state != default_frz_protect_state) {
if (aqdata->frz_protect_state != default_frz_protect_state) {
LOG(ALLB_LOG,LOG_INFO, "Freeze protect turned off\n");
event_happened_set_device_state(AQS_FRZ_PROTECT_OFF, aq_data);
event_happened_set_device_state(AQS_FRZ_PROTECT_OFF, aqdata);
// Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule
}
aq_data->frz_protect_state = default_frz_protect_state;
SET_IF_CHANGED(aqdata->frz_protect_state, default_frz_protect_state, aqdata->is_dirty);
}
if ((msg_loop & MSG_SERVICE) != MSG_SERVICE &&
(msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) {
aq_data->service_mode_state = OFF; // IF we get this message then Service / Timeout is off
aqdata->service_mode_state = OFF; // IF we get this message then Service / Timeout is off
}
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aq_data->swg_led_state != LED_S_UNKNOWN) {
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aqdata->swg_led_state != LED_S_UNKNOWN) {
// No Additional SWG devices messages like "no flow"
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF )
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_OFF);
if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->aqbuttons[PUMP_INDEX].led->state == OFF )
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_OFF);
else
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_ON);
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_ON);
}
// If no AQUAPURE message, either (no SWG, it's set 0, or it's off).
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->swg_led_state != LED_S_UNKNOWN ) {
if (aq_data->swg_percent != 0 || aq_data->swg_led_state == ON) {
if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->swg_led_state != LED_S_UNKNOWN ) {
if (aqdata->swg_percent != 0 || aqdata->swg_led_state == ON) {
// Something is wrong here. Let's check pump, if on set SWG to 0, if off turn SWE off
if ( aq_data->aqbuttons[PUMP_INDEX].led->state == OFF) {
if ( aqdata->aqbuttons[PUMP_INDEX].led->state == OFF) {
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
setSWGoff(aq_data);
setSWGoff(aqdata);
} else {
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n");
changeSWGpercent(aq_data, 0);
changeSWGpercent(aqdata, 0);
}
} else if (isIAQT_ENABLED == false && isONET_ENABLED == false && READ_RSDEV_SWG == false ) {
//We have no other way to read SWG %=0, so turn SWG on with pump
if ( aq_data->aqbuttons[PUMP_INDEX].led->state == ON) {
if ( aqdata->aqbuttons[PUMP_INDEX].led->state == ON) {
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
//changeSWGpercent(aq_data, 0);
setSWGenabled(aq_data);
//changeSWGpercent(aqdata, 0);
setSWGenabled(aqdata);
}
}
// NSF Need something to catch startup when SWG=0 so we set it to enabeled.
// when other ways/protocols to detect SWG=0 are turned off.
}
if ((msg_loop & MSG_LOOP_POOL_TEMP) != MSG_LOOP_POOL_TEMP && aq_data->pool_temp != TEMP_UNKNOWN ) {
aq_data->pool_temp = TEMP_UNKNOWN;
if ((msg_loop & MSG_LOOP_POOL_TEMP) != MSG_LOOP_POOL_TEMP && aqdata->pool_temp != TEMP_UNKNOWN ) {
SET_IF_CHANGED(aqdata->pool_temp, TEMP_UNKNOWN, aqdata->is_dirty);
}
if ((msg_loop & MSG_LOOP_SPA_TEMP) != MSG_LOOP_SPA_TEMP && aq_data->spa_temp != TEMP_UNKNOWN ) {
aq_data->spa_temp = TEMP_UNKNOWN;
if ((msg_loop & MSG_LOOP_SPA_TEMP) != MSG_LOOP_SPA_TEMP && aqdata->spa_temp != TEMP_UNKNOWN ) {
SET_IF_CHANGED(aqdata->spa_temp, TEMP_UNKNOWN, aqdata->is_dirty);
}
/*
// AQUAPURE=0 we never get that message on ALLBUTTON so don't turn off unless filter pump if off
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF ) {
//aq_data->ar_swg_status = SWG_STATUS_OFF;
setSWGoff(aq_data);
if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->aqbuttons[PUMP_INDEX].led->state == OFF ) {
//aqdata->ar_swg_status = SWG_STATUS_OFF;
setSWGoff(aqdata);
}
*/
if ((msg_loop & MSG_BOOST) != MSG_BOOST) {
if (aq_data->boost == true || boostInLastLoop == true) {
if (aqdata->boost == true || boostInLastLoop == true) {
LOG(ALLB_LOG,LOG_INFO, "Boost turned off\n");
event_happened_set_device_state(AQS_BOOST_OFF, aq_data);
event_happened_set_device_state(AQS_BOOST_OFF, aqdata);
// Add code to check Pump if to turn it on (was scheduled) ie time now is inbetween ON / OFF schedule
}
aq_data->boost = false;
aq_data->boost_msg[0] = '\0';
aq_data->boost_duration = 0;
SET_IF_CHANGED(aqdata->boost, false, aqdata->is_dirty);
aqdata->boost_msg[0] = '\0';
SET_IF_CHANGED(aqdata->boost_duration, 0, aqdata->is_dirty);
boostInLastLoop = false;
//if (aq_data->swg_percent >= 101)
// aq_data->swg_percent = 0;
//if (aqdata->swg_percent >= 101)
// aqdata->swg_percent = 0;
}
if ((msg_loop & MSG_BATTERY_LOW) != MSG_BATTERY_LOW)
aq_data->battery = OK;
SET_IF_CHANGED(aqdata->battery, OK, aqdata->is_dirty);
//if ( _aqconfig_.rs_panel_size >= 16) {
@ -307,13 +324,13 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
if ( PANEL_SIZE() >= 16 ) {
//printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE());
if ((msg_loop & MSG_RS13BUTTON) != MSG_RS13BUTTON)
aq_data->aqbuttons[13].led->state = OFF;
SET_IF_CHANGED(aqdata->aqbuttons[13].led->state, OFF, aqdata->is_dirty);
if ((msg_loop & MSG_RS14BUTTON) != MSG_RS14BUTTON)
aq_data->aqbuttons[14].led->state = OFF;
SET_IF_CHANGED(aqdata->aqbuttons[14].led->state, OFF, aqdata->is_dirty);
if ((msg_loop & MSG_RS15BUTTON) != MSG_RS15BUTTON)
aq_data->aqbuttons[15].led->state = OFF;
SET_IF_CHANGED(aqdata->aqbuttons[15].led->state, OFF, aqdata->is_dirty);
if ((msg_loop & MSG_RS16BUTTON) != MSG_RS16BUTTON)
aq_data->aqbuttons[16].led->state = OFF;
SET_IF_CHANGED(aqdata->aqbuttons[16].led->state, OFF, aqdata->is_dirty);
}
msg_loop = 0;
@ -322,66 +339,67 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
if (stristr(msg, LNG_MSG_BATTERY_LOW) != NULL)
{
aq_data->battery = LOW;
SET_IF_CHANGED(aqdata->battery, LOW, aqdata->is_dirty);
msg_loop |= MSG_BATTERY_LOW;
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI
//strcpy(aqdata->last_display_message, msg); // Also display the message on web UI
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
}
else if (stristr(msg, LNG_MSG_POOL_TEMP_SET) != NULL)
{
//LOG(ALLB_LOG,LOG_DEBUG, "**************** pool htr long message: %s", &message[20]);
aq_data->pool_htr_set_point = atoi(message + 20);
SET_IF_CHANGED(aqdata->pool_htr_set_point, atoi(message + 20), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
else if (stristr(msg, LNG_MSG_SPA_TEMP_SET) != NULL)
{
//LOG(ALLB_LOG,LOG_DEBUG, "spa htr long message: %s", &message[19]);
aq_data->spa_htr_set_point = atoi(message + 19);
SET_IF_CHANGED(aqdata->spa_htr_set_point, atoi(message + 19), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_SET) != NULL)
{
//LOG(ALLB_LOG,LOG_DEBUG, "frz protect long message: %s", &message[28]);
aq_data->frz_protect_set_point = atoi(message + 28);
aq_data->frz_protect_state = ENABLE;
SET_IF_CHANGED(aqdata->frz_protect_set_point, atoi(message + 28), aqdata->is_dirty);
SET_IF_CHANGED(aqdata->frz_protect_state, ENABLE, aqdata->is_dirty);
default_frz_protect_state = ENABLE;
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
else if (strncasecmp(msg, MSG_AIR_TEMP, MSG_AIR_TEMP_LEN) == 0)
{
aq_data->air_temp = atoi(msg + MSG_AIR_TEMP_LEN);
SET_IF_CHANGED(aqdata->air_temp, atoi(msg + MSG_AIR_TEMP_LEN), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
else if (strncasecmp(msg, MSG_POOL_TEMP, MSG_POOL_TEMP_LEN) == 0)
{
msg_loop |= MSG_LOOP_POOL_TEMP;
aq_data->pool_temp = atoi(msg + MSG_POOL_TEMP_LEN);
SET_IF_CHANGED(aqdata->pool_temp, atoi(msg + MSG_POOL_TEMP_LEN), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
else if (strncasecmp(msg, MSG_SPA_TEMP, MSG_SPA_TEMP_LEN) == 0)
{
msg_loop |= MSG_LOOP_SPA_TEMP;
aq_data->spa_temp = atoi(msg + MSG_SPA_TEMP_LEN);
SET_IF_CHANGED(aqdata->spa_temp, atoi(msg + MSG_SPA_TEMP_LEN), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
}
// NSF If get water temp rather than pool or spa in some cases, then we are in Pool OR Spa ONLY mode
else if (strncasecmp(msg, MSG_WATER_TEMP, MSG_WATER_TEMP_LEN) == 0)
{
aq_data->pool_temp = atoi(msg + MSG_WATER_TEMP_LEN);
aq_data->spa_temp = atoi(msg + MSG_WATER_TEMP_LEN);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
SET_IF_CHANGED(aqdata->pool_temp, atoi(msg + MSG_WATER_TEMP_LEN), aqdata->is_dirty);
SET_IF_CHANGED(aqdata->spa_temp, atoi(msg + MSG_WATER_TEMP_LEN), aqdata->is_dirty);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
if (isSINGLE_DEV_PANEL != true)
{
@ -391,10 +409,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
}
else if (stristr(msg, LNG_MSG_WATER_TEMP1_SET) != NULL)
{
aq_data->pool_htr_set_point = atoi(message + 28);
SET_IF_CHANGED(aqdata->pool_htr_set_point, atoi(message + 28), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
if (isSINGLE_DEV_PANEL != true)
{
@ -404,10 +422,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
}
else if (stristr(msg, LNG_MSG_WATER_TEMP2_SET) != NULL)
{
aq_data->spa_htr_set_point = atoi(message + 27);
SET_IF_CHANGED(aqdata->spa_htr_set_point, atoi(message + 27), aqdata->is_dirty);
if (aq_data->temp_units == UNKNOWN)
setUnits(msg, aq_data);
if (aqdata->temp_units == UNKNOWN)
setUnits(msg, aqdata);
if (isSINGLE_DEV_PANEL != true)
{
@ -417,31 +435,32 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
}
else if (stristr(msg, LNG_MSG_SERVICE_ACTIVE) != NULL)
{
if (aq_data->service_mode_state == OFF)
if (aqdata->service_mode_state == OFF)
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n");
aq_data->service_mode_state = ON;
SET_IF_CHANGED(aqdata->service_mode_state, ON, aqdata->is_dirty);
msg_loop |= MSG_SERVICE;
//service_msg_count = 0;
}
else if (stristr(msg, LNG_MSG_TIMEOUT_ACTIVE) != NULL)
{
if (aq_data->service_mode_state == OFF)
if (aqdata->service_mode_state == OFF)
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n");
aq_data->service_mode_state = FLASH;
SET_IF_CHANGED(aqdata->service_mode_state, FLASH, aqdata->is_dirty);
msg_loop |= MSG_TIMEOUT;
//service_msg_count = 0;
}
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_ACTIVATED) != NULL)
{
msg_loop |= MSG_FREEZE;
//aq_data->frz_protect_state = default_frz_protect_state;
aq_data->frz_protect_state = ON;
//aqdata->frz_protect_state = default_frz_protect_state;
SET_IF_CHANGED(aqdata->frz_protect_state, ON, aqdata->is_dirty);
//freeze_msg_count = 0;
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI
//strcpy(aqdata->last_display_message, msg); // Also display the message on web UI
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
}
else if (ENABLE_CHILLER && (stristr(msg,"Chiller") != NULL || stristr(msg,"Heat Pump") != NULL)) {
processHeatPumpDisplayMessage(msg, aq_data); // This doesn;t exist yet
processHeatPumpDisplayMessage(msg, aqdata); // This doesn;t exist yet
}
/* // Not sure when to do with these for the moment, so no need to compile in the test.
@ -452,27 +471,29 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
*/
else if (msg[2] == '/' && msg[5] == '/' && msg[8] == ' ')
{ // date in format '08/29/16 MON'
strcpy(aq_data->date, msg);
//strcpy(aqdata->date, msg);
SET_IF_CHANGED_STRCPY(aqdata->date, msg, aqdata->is_dirty);
}
else if (stristr(msg, MSG_SWG_PCT) != NULL)
{
if (strncasecmp(msg, MSG_SWG_PCT, MSG_SWG_PCT_LEN) == 0 && strncasecmp(msg, "AQUAPURE HRS", 12) != 0) {
changeSWGpercent(aq_data, atoi(msg + MSG_SWG_PCT_LEN));
changeSWGpercent(aqdata, atoi(msg + MSG_SWG_PCT_LEN));
}
else if (strncasecmp(msg, "AQUAPURE HRS", 12) != 0 && strncasecmp(msg, "SET AQUAPURE", 12) != 0)
{
if (strcasestr(msg, MSG_SWG_NO_FLOW) != NULL)
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_NO_FLOW);
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_NO_FLOW);
else if (strcasestr(msg, MSG_SWG_LOW_SALT) != NULL)
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_LOW_SALT);
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_LOW_SALT);
else if (strcasestr(msg, MSG_SWG_HIGH_SALT) != NULL)
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_HI_SALT);
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_HI_SALT);
else if (strcasestr(msg, MSG_SWG_FAULT) != NULL)
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_GENFAULT);
//setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_CHECK_PCB);
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_GENFAULT);
//setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_CHECK_PCB);
// Any of these messages want to display.
strcpy(aq_data->last_display_message, msg);
//strcpy(aqdata->last_display_message, msg);
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
msg_loop |= MSG_SWG_DEVICE;
}
@ -480,32 +501,33 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
}
else if (strncasecmp(msg, MSG_SWG_PPM, MSG_SWG_PPM_LEN) == 0)
{
aq_data->swg_ppm = atoi(msg + MSG_SWG_PPM_LEN);
SET_IF_CHANGED( aqdata->swg_ppm, atoi(msg + MSG_SWG_PPM_LEN), aqdata->is_dirty);
msg_loop |= MSG_SWG;
}
else if ((msg[1] == ':' || msg[2] == ':') && msg[strlen(msg) - 1] == 'M')
{ // time in format '9:45 AM'
strcpy(aq_data->time, msg);
//strcpy(aqdata->time, msg);
SET_IF_CHANGED_STRCPY(aqdata->time, msg, aqdata->is_dirty);
// Setting time takes a long time, so don't try until we have all other programmed data.
if (_initWithRS == true && strlen(aq_data->date) > 1 && checkAqualinkTime() != true)
if (_initWithRS == true && strlen(aqdata->date) > 1 && checkAqualinkTime() != true)
{
LOG(ALLB_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", aq_data->time, aq_data->date);
aq_programmer(AQ_SET_TIME, NULL, aq_data);
LOG(ALLB_LOG,LOG_NOTICE, "Time is NOT accurate '%s %s', re-setting on controller!\n", aqdata->time, aqdata->date);
aq_programmer(AQ_SET_TIME, NULL, aqdata);
}
else if (_initWithRS == false || _aqconfig_.sync_panel_time == false)
{
LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", aq_data->time, aq_data->date);
LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", aqdata->time, aqdata->date);
}
else if (_initWithRS == true)
{
LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", aq_data->time, aq_data->date);
LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", aqdata->time, aqdata->date);
}
// If we get a time message before REV, the controller didn't see us as we started too quickly.
/* Don't need to check this anymore with the check for probe before startup.
if (_gotREV == false)
{
LOG(ALLB_LOG,LOG_NOTICE, "Getting control panel information\n", msg);
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, aq_data);
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, aqdata);
_gotREV = true; // Force it to true just incase we don't understand the model#
}
*/
@ -513,19 +535,20 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
else if (strstr(msg, " REV ") != NULL || strstr(msg, " REV. ") != NULL)
{ // '8157 REV MMM'
// A master firmware revision message.
strcpy(aq_data->version, msg);
rsm_get_revision(aq_data->revision, aq_data->version, strlen(aq_data->version));
setPanelInformationFromPanelMsg(aq_data, msg, PANEL_CPU | PANEL_REV, ALLBUTTON);
//setBoardCPURevision(aq_data, aq_data->version, strlen(aq_data->version), ALLB_LOG);
//strcpy(aqdata->version, msg);
SET_IF_CHANGED_STRCPY(aqdata->version, msg, aqdata->is_dirty);
rsm_get_revision(aqdata->revision, aqdata->version, strlen(aqdata->version));
setPanelInformationFromPanelMsg(aqdata, msg, PANEL_CPU | PANEL_REV, ALLBUTTON);
//setBoardCPURevision(aqdata, aqdata->version, strlen(aqdata->version), ALLB_LOG);
//_gotREV = true;
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel version %s\n", aq_data->version);
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel revision %s\n", aq_data->revision);
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel version %s\n", aqdata->version);
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel revision %s\n", aqdata->revision);
if (_initWithRS == false)
{
//LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n");
queueGetProgramData(ALLBUTTON, aq_data);
event_happened_set_device_state(AQS_POWER_ON, aq_data);
//queueGetExtendedProgramData(ALLBUTTON, aq_data, _aqconfig_.use_panel_aux_labels);
queueGetProgramData(ALLBUTTON, aqdata);
event_happened_set_device_state(AQS_POWER_ON, aqdata);
//queueGetExtendedProgramData(ALLBUTTON, aqdata, _aqconfig_.use_panel_aux_labels);
_initWithRS = true;
}
}
@ -535,8 +558,8 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
}
else if (_aqconfig_.override_freeze_protect == TRUE && strncasecmp(msg, "Press Enter* to override Freeze Protection with", 47) == 0)
{
//send_cmd(KEY_ENTER, aq_data);
//aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, aq_data);
//send_cmd(KEY_ENTER, aqdata);
//aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, aqdata);
aq_send_allb_cmd(KEY_ENTER);
}
// Process any button states (fake LED) for RS12 and above keypads
@ -544,14 +567,15 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
//else if ( _aqconfig_.rs_panel_size >= 16 && (rs16 = RS16_endswithLEDstate(msg)) != 0 )
else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg, aq_data)) != 0 )
else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg, aqdata)) != 0 )
{
msg_loop |= rs16;
// Do nothing, just stop other else if statments executing
// make sure we also display the message.
// Note we only get ON messages here, Off messages will not be sent if something else turned it off
// use the Onetouch or iAqua equiptment page for off.
strcpy(aq_data->last_display_message, msg);
//strcpy(aqdata->last_display_message, msg);
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
}
else if (((msg[4] == ':') || (msg[6] == ':')) && (strncasecmp(msg, "AUX", 3) == 0) )
@ -570,64 +594,67 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
labelid = labelid + 1;
// Aux1: on panel = Button 3 in aqualinkd (button 2 in array)
if (strncasecmp(msg+ni+3, "No Label", 8) != 0) {
aq_data->aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2));
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label);
aqdata->aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2));
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", aqdata->aqbuttons[labelid].name, aqdata->aqbuttons[labelid].label);
} else {
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label);
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", aqdata->aqbuttons[labelid].name, aqdata->aqbuttons[labelid].label);
}
//aq_data->aqbuttons[labelid + 1].label = cleanalloc(msg + 5);
//aqdata->aqbuttons[labelid + 1].label = cleanalloc(msg + 5);
}
}
// BOOST POOL 23:59 REMAINING
else if ( (strncasecmp(msg, "BOOST POOL", 10) == 0) && (strcasestr(msg, "REMAINING") != NULL) ) {
// Ignore messages if in programming mode. We get one of these turning off for some strange reason.
if (in_programming_mode(aq_data) == false) {
if (in_programming_mode(aqdata) == false) {
if (aq_data->boost == false || boostInLastLoop == false) {
event_happened_set_device_state(AQS_BOOST_ON, aq_data);
if (aqdata->boost == false || boostInLastLoop == false) {
event_happened_set_device_state(AQS_BOOST_ON, aqdata);
}
snprintf(aq_data->boost_msg, 6, "%s", &msg[11]);
aq_data->boost_duration = rsm_HHMM2min(aq_data->boost_msg);
aq_data->boost = true;
snprintf(aqdata->boost_msg, 6, "%s", &msg[11]);
aqdata->boost_duration = rsm_HHMM2min(aqdata->boost_msg);
SET_IF_CHANGED(aqdata->boost, true, aqdata->is_dirty);
msg_loop |= MSG_BOOST;
msg_loop |= MSG_SWG;
boostInLastLoop = true;
//convert_boost_to_duration(aq_data->boost_msg)
//if (aq_data->ar_swg_status != SWG_STATUS_ON) {aq_data->ar_swg_status = SWG_STATUS_ON;}
if (aq_data->swg_percent != 101) {changeSWGpercent(aq_data, 101);}
//convert_boost_to_duration(aqdata->boost_msg)
//if (aqdata->ar_swg_status != SWG_STATUS_ON) {aqdata->ar_swg_status = SWG_STATUS_ON;}
if (aqdata->swg_percent != 101) {changeSWGpercent(aqdata, 101);}
//boost_msg_count = 0;
//if (aq_data->active_thread.thread_id == 0)
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI if not in programming mode
//if (aqdata->active_thread.thread_id == 0)
//strcpy(aqdata->last_display_message, msg); // Also display the message on web UI if not in programming mode
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
}
}
else
{
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg);
//aq_data->display_message = msg;
//if (in_programming_mode(aq_data) == false && aq_data->simulate_panel == false &&
if (in_programming_mode(aq_data) == false &&
//aqdata->display_message = msg;
//if (in_programming_mode(aqdata) == false && aqdata->simulate_panel == false &&
if (in_programming_mode(aqdata) == false &&
stristr(msg, "JANDY AquaLinkRS") == NULL &&
//stristr(msg, "PUMP O") == NULL &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
strncasecmp(msg, "PUMP O", 6) != 0 &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
stristr(msg, "MAINTAIN") == NULL && // Catch 'MAINTAIN TEMP IS OFF'
stristr(msg, "Heat Pump") == NULL && // Stop Heatpump on / off messages spam the UI.
stristr(msg, "0 PSI") == NULL /* // Catch some erronious message on test harness
stristr(msg, "CLEANER O") == NULL &&
stristr(msg, "SPA O") == NULL &&
stristr(msg, "AUX") == NULL*/
)
{ // Catch all AUX1 AUX5 messages
//aq_data->display_last_message = true;
strcpy(aq_data->last_display_message, msg);
//rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
//aqdata->display_last_message = true;
//strcpy(aqdata->last_display_message, msg);
SET_IF_CHANGED_STRCPY(aqdata->last_display_message, msg, aqdata->is_dirty);
//rsm_strncpy(aqdata->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
}
}
// Send every message if we are in simulate panel mode
//if (aq_data->simulate_panel)
// strcpy(aq_data->last_display_message, msg);
//rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
//ascii(aq_data->last_display_message, msg);
//if (aqdata->simulate_panel)
// strcpy(aqdata->last_display_message, msg);
//rsm_strncpy(aqdata->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
//ascii(aqdata->last_display_message, msg);
//LOG(ALLB_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop);
@ -636,10 +663,10 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
//printf ("Message kicking\n");
kick_aq_program_thread(aq_data, ALLBUTTON);
kick_aq_program_thread(aqdata, ALLBUTTON);
}
bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aqdata)
{
bool rtn = false;
//static unsigned char last_packet[AQ_MAXPKTLEN];
@ -658,15 +685,15 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
else
{
memcpy(last_packet, packet, length);
aq_data->last_packet_type = packet[PKT_CMD];
aqdata->last_packet_type = packet[PKT_CMD];
rtn = true;
}
*/
aq_data->last_packet_type = packet[PKT_CMD];
aqdata->last_packet_type = packet[PKT_CMD];
if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(aq_data) )
if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(aqdata) )
{
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length);
return false;
@ -682,7 +709,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
processing_long_msg = 0;
//LOG(ALLB_LOG,LOG_ERR, "RS failed to receive complete long message, received '%s'\n",message);
//LOG(ALLB_LOG,LOG_DEBUG, "RS didn't finished receiving of MSG_LONG '%s'\n",message);
processMessage(message, aq_data);
processMessage(message, aqdata);
}
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length);
@ -696,34 +723,34 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
//LOG(ALLB_LOG,LOG_DEBUG, "RS Received STATUS length %d.\n", length);
//debuglogPacket(ALLB_LOG, packet, length, true, true);
//memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN);
//processLEDstate(aq_data);
processLEDstate(aq_data, packet, ALLB_LOG);
//memcpy(aqdata->raw_status, packet + 4, AQ_PSTLEN);
//processLEDstate(aqdata);
processLEDstate(aqdata, packet, ALLB_LOG);
/* NSF Take this out, and use the ALLButton loop cycle to determin if we get spa/pool temp
messages. Works better for dual equiptment when both pool & spa pumps and dual temp sensors */
/*
if (aq_data->aqbuttons[PUMP_INDEX].led->state == OFF)
if (aqdata->aqbuttons[PUMP_INDEX].led->state == OFF)
{
aq_data->pool_temp = TEMP_UNKNOWN;
aq_data->spa_temp = TEMP_UNKNOWN;
//aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
aqdata->pool_temp = TEMP_UNKNOWN;
aqdata->spa_temp = TEMP_UNKNOWN;
//aqdata->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
}
else if (aq_data->aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true)
else if (aqdata->aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true)
{
//aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
aq_data->spa_temp = TEMP_UNKNOWN;
//aqdata->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
aqdata->spa_temp = TEMP_UNKNOWN;
}
else if (aq_data->aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true)
else if (aqdata->aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true)
{
aq_data->pool_temp = TEMP_UNKNOWN;
aqdata->pool_temp = TEMP_UNKNOWN;
}
*/
// COLOR MODE programming relies on state changes, so let any threads know
//if (aq_data->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) {
if ( in_light_programming_mode(aq_data) ) {
kick_aq_program_thread(aq_data, ALLBUTTON);
//if (aqdata->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) {
if ( in_light_programming_mode(aqdata) ) {
kick_aq_program_thread(aqdata, ALLBUTTON);
}
break;
case CMD_MSG:
@ -747,7 +774,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
//printf("RSM Long message index %d doesn't match buffer %d\n",index,processing_long_msg);
}
#ifdef PROCESS_INCOMPLETE_MESSAGES
kick_aq_program_thread(aq_data, ALLBUTTON);
kick_aq_program_thread(aqdata, ALLBUTTON);
#endif
}
@ -755,10 +782,10 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
//printf("RSM process message '%s'\n",message);
// MOVED FROM LINE 701 see if less errors
//kick_aq_program_thread(aq_data, ALLBUTTON);
//kick_aq_program_thread(aqdata, ALLBUTTON);
LOG(ALLB_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message);
processMessage(message, aq_data); // This will kick thread
processMessage(message, aqdata); // This will kick thread
}
}
@ -770,7 +797,7 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
break;
case CMD_MSG_LOOP_ST:
LOG(ALLB_LOG,LOG_INFO, "RS Received message loop start\n");
processMessageReset(aq_data);
processMessageReset(aqdata);
rtn = false;
break;
default:

File diff suppressed because it is too large Load Diff

View File

@ -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 {

View File

@ -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);
}

View File

@ -171,7 +171,7 @@ struct programmingThreadCtrl {
//void *thread_args;
struct programmerArgs pArgs;
char thread_args[PTHREAD_ARG];
struct aqualinkdata *aq_data;
struct aqualinkdata *aqdata;
};

View File

@ -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;

View File

@ -39,7 +39,7 @@
#include <sys/select.h>
#define SERIAL_READ_TIMEOUT_SEC 1;
#define SERIAL_READ_TIMEOUT_SEC 2;
static int _RS485_fds = -1;

View File

@ -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);
}

View File

@ -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;

View File

@ -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");

279
source/auto_configure.c Normal file
View File

@ -0,0 +1,279 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#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;
}

9
source/auto_configure.h Normal file
View File

@ -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_

View File

@ -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

View File

@ -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);

View File

@ -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));
}
*/
}

View File

@ -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);
}
}

View File

@ -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 <IAQ_STATUS_PAGE_LINES; i++ ) {
/*
//LOG(IAQT_LOG,LOG_NOTICE, "Passing message %.2d| %s\n",i,_deviceStatus[i]);
if (rsm_strcmp(_deviceStatus[i],"Intelliflo VS") == 0 ||
rsm_strcmp(_deviceStatus[i],"Intelliflo VF") == 0 ||
rsm_strcmp(_deviceStatus[i],"Jandy ePUMP") == 0 ||
rsm_strcmp(_deviceStatus[i],"ePump AC") == 0)
{
int pump_index = rsm_atoi(&_deviceStatus[i][14]);
if (pump_index <= 0)
pump_index = rsm_atoi(&_deviceStatus[i][10]); // ePump AC seems to display index in different position
for (pi=0; pi < aq_data->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<length; i++) {
@ -1203,11 +1006,11 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd
//iaqt_queue_cmd(KEY_IAQTCH_HELP);
//iaqt_queue_cmd(KEY_IAQTCH_HOME);
queueGetProgramData(IAQTOUCH, aq_data);
queueGetProgramData(IAQTOUCH, aqdata);
gotInit = true;
}
//aq_programmer(AQ_SET_IAQTOUCH_SET_TIME, NULL, aq_data);
//aq_programmer(AQ_SET_IAQTOUCH_SET_TIME, NULL, aqdata);
}
/*
NEED TO ALTERNATE SEND KEY_IAQTCH_HOMEP_KEY08 KEY and KEY_IAQTCH_STATUS BELOW FOR PDA
@ -1244,7 +1047,7 @@ if not programming && poll packet {
So why did I update this to sit on devices page???????????
RS16 should also probably sit on devices page.
}*/
if (in_programming_mode(aq_data) == false) {
if (in_programming_mode(aqdata) == false) {
//LOG(IAQT_LOG,LOG_DEBUG, "Poll counter = %d\n",_pollCnt);
if (_currentPage == IAQ_PAGE_HOME) {
@ -1252,7 +1055,7 @@ if not programming && poll packet {
_pollCnt = 0;
}
//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) ) {
// 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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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])
{

View File

@ -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");
}

View File

@ -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");

File diff suppressed because it is too large Load Diff

View File

@ -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.
*/

View File

@ -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_

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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)"