diff --git a/Makefile b/Makefile index 0c229d79..520e64c3 100755 --- a/Makefile +++ b/Makefile @@ -146,8 +146,10 @@ SL_OBJ_DIR := $(OBJ_DIR)/slog OBJ_DIR_ARMHF := $(OBJ_DIR)/armhf OBJ_DIR_ARM64 := $(OBJ_DIR)/arm64 +OBJ_DIR_AMD64 := $(OBJ_DIR)/amd64 SL_OBJ_DIR_ARMHF := $(OBJ_DIR_ARMHF)/slog SL_OBJ_DIR_ARM64 := $(OBJ_DIR_ARM64)/slog +SL_OBJ_DIR_AMD64 := $(OBJ_DIR_AMD64)/slog # Object files OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(SRCS)) @@ -156,8 +158,11 @@ SL_OBJ_FILES := $(patsubst %.c,$(SL_OBJ_DIR)/%.o,$(SL_SRC)) OBJ_FILES_ARMHF := $(patsubst %.c,$(OBJ_DIR_ARMHF)/%.o,$(SRCS)) OBJ_FILES_ARM64 := $(patsubst %.c,$(OBJ_DIR_ARM64)/%.o,$(SRCS)) +OBJ_FILES_AMD64 := $(patsubst %.c,$(OBJ_DIR_AMD64)/%.o,$(SRCS)) + SL_OBJ_FILES_ARMHF := $(patsubst %.c,$(SL_OBJ_DIR_ARMHF)/%.o,$(SL_SRC)) SL_OBJ_FILES_ARM64 := $(patsubst %.c,$(SL_OBJ_DIR_ARM64)/%.o,$(SL_SRC)) +SL_OBJ_FILES_AMD64 := $(patsubst %.c,$(SL_OBJ_DIR_AMD64)/%.o,$(SL_SRC)) #MG_OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(MG_SRC)) # define the executable file @@ -167,21 +172,30 @@ DEBG = ./release/aqualinkd-debug MAIN_ARM64 = ./release/aqualinkd-arm64 MAIN_ARMHF = ./release/aqualinkd-armhf +MAIN_AMD64 = ./release/aqualinkd-amd64 SLOG_ARM64 = ./release/serial_logger-arm64 SLOG_ARMHF = ./release/serial_logger-armhf +SLOG_AMD64 = ./release/serial_logger-amd64 + #LOGR = ./release/log_reader #PLAY = ./release/aqualinkd-player + # Rules with no targets .PHONY: clean clean-buildfiles buildrelease release install +# Default target +.DEFAULT_GOAL := all + +# Before the below works, you need to build the aqualinkd-releasebin docker for compiling. +# sudo docker build -f Dockerfile.releaseBinaries -t aqualinkd-releasebin . release: sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make buildrelease $(info Binaries for release have been built) -# This is run inside container Dockerfile.releaseBinariies -buildrelease: clean armhf arm64 +# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin) +buildrelease: clean armhf arm64 $(shell cd release && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger) @@ -220,6 +234,12 @@ arm64: $(MAIN_ARM64) $(SLOG_ARM64) $(info $(MAIN_ARM64) has been compiled) $(info $(SLOG_ARM64) has been compiled) +# amd64 +amd64: CC := $(CC_AMD64) +amd64: $(MAIN_AMD64) $(SLOG_AMD64) + $(info $(MAIN_AMD64) has been compiled) + $(info $(SLOG_AMD64) has been compiled) + #debug, Just change compile flags and call MAIN debug: CFLAGS = $(DFLAGS) debug: $(MAIN) $(SLOG) @@ -253,6 +273,11 @@ $(OBJ_DIR_ARM64)/%.o: %.c | $(OBJ_DIR_ARM64) $(SL_OBJ_DIR_ARM64)/%.o: %.c | $(SL_OBJ_DIR_ARM64) $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< +$(OBJ_DIR_AMD64)/%.o: %.c | $(OBJ_DIR_AMD64) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(SL_OBJ_DIR_AMD64)/%.o: %.c | $(SL_OBJ_DIR_AMD64) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< # Rules to link $(MAIN): $(OBJ_FILES) @@ -262,6 +287,9 @@ $(MAIN_ARM64): $(OBJ_FILES_ARM64) $(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS) $(MAIN_ARMHF): $(OBJ_FILES_ARMHF) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS) + +$(MAIN_AMD64): $(OBJ_FILES_AMD64) $(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS) $(DEBG): $(DBG_OBJ_FILES) @@ -279,6 +307,9 @@ $(SLOG_ARM64): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER $(SLOG_ARM64): $(SL_OBJ_FILES_ARM64) $(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS) +$(SLOG_AMD64): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER +$(SLOG_AMD64): $(SL_OBJ_FILES_AMD64) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ $^ $(LIBS) # Rules to make object directories. $(OBJ_DIR): @@ -302,14 +333,19 @@ $(OBJ_DIR_ARM64): $(SL_OBJ_DIR_ARM64): $(MKDIR) $(call FixPath,$@) +$(OBJ_DIR_AMD64): + $(MKDIR) $(call FixPath,$@) + +$(SL_OBJ_DIR_AMD64): + $(MKDIR) $(call FixPath,$@) # Clean rules clean: clean-buildfiles $(RM) *.o *~ $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(DEBG) - $(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_ARM64) $(MAIN_ARMHF) $(SLOG) $(SLOG_ARM64) $(SLOG_ARMHF) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) $(DEBG) + $(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_ARM64) $(MAIN_ARMHF) $(MAIN_AMD64) $(SLOG) $(SLOG_ARM64) $(SLOG_ARMHF) $(SLOG_AMD64) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) $(DEBG) clean-buildfiles: - $(RM) $(wildcard *.o) $(wildcard *~) $(OBJ_FILES) $(DBG_OBJ_FILES) $(SL_OBJ_FILES) $(OBJ_FILES_ARMHF) $(OBJ_FILES_ARM64) $(SL_OBJ_FILES_ARMHF) $(SL_OBJ_FILES_ARM64) + $(RM) $(wildcard *.o) $(wildcard *~) $(OBJ_FILES) $(DBG_OBJ_FILES) $(SL_OBJ_FILES) $(OBJ_FILES_ARMHF) $(OBJ_FILES_ARM64) $(OBJ_FILES_AMD64) $(SL_OBJ_FILES_ARMHF) $(SL_OBJ_FILES_ARM64) $(SL_OBJ_FILES_AMD64) diff --git a/README.md b/README.md index 740d7493..4c05979d 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,15 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control # Call for Help. * The only Jandy devices I have not decoded yet are LX heater & Chemical Feeder. If you have either of these devices and are willing to post some logs, please let me know, or post in the [Discussions area](https://github.com/sfeakes/AqualinkD/discussions) +# (Comming) Updates in Release 2.3.7 +* Fix for Pentair VSP losing connection & bouncing SWG to 0 and back. +* Added more VSP data (Mode, Status, Pressure Curve, both RPM & GPM) for all Pentair Pumps (VS/VF/VSF). +* Few updates to HomeAssistant integration. +* Updates to serial_logger. +* Few updates to AQmanager UI. + * Will display both RPM & GPM for VSP (space providing) + * Fix freeze protect button in UI not showing enabled. + # Update in Release 2.3.6 * No functionality changes * Build & Docker changes diff --git a/aq_mqtt.h b/aq_mqtt.h index 4ea8a150..5379a357 100644 --- a/aq_mqtt.h +++ b/aq_mqtt.h @@ -50,6 +50,9 @@ #define PUMP_RPM_TOPIC "/RPM" #define PUMP_GPM_TOPIC "/GPM" #define PUMP_WATTS_TOPIC "/Watts" +#define PUMP_MODE_TOPIC "/Mode" +#define PUMP_STATUS_TOPIC "/Status" +#define PUMP_PPC_TOPIC "/PPC" /* #define AIR_TEMPERATURE "Air" #define POOL_TEMPERATURE "Pool_Water" diff --git a/aq_panel.c b/aq_panel.c index 633911f5..6021857f 100644 --- a/aq_panel.c +++ b/aq_panel.c @@ -52,7 +52,7 @@ void changePanelToMode_Only() { void changePanelToExtendedIDProgramming() { _aqconfig_.paneltype_mask |= RSP_EXT_PROG; - LOG(AQUA_LOG,LOG_NOTICE, "AqualinkD is using use %s mode for programming (where supported)\n",isONET_ENABLED?"ONETOUCH":"IAQ TOUCH"); + LOG(PANL_LOG,LOG_NOTICE, "AqualinkD is using use %s mode for programming (where supported)\n",isONET_ENABLED?"ONETOUCH":"IAQ TOUCH"); } void addPanelRSserialAdapterInterface() { @@ -83,7 +83,7 @@ int PANEL_SIZE() { else if ((_aqconfig_.paneltype_mask & RSP_16) == RSP_16) return 16; - LOG(AQUA_LOG,LOG_ERR, "Internal error, panel size not set, using 8\n"); + LOG(PANL_LOG,LOG_ERR, "Internal error, panel size not set, using 8\n"); return 8; } //bool setPanel(const char *str); @@ -133,7 +133,7 @@ int setSizeMask(int size) int rtn_size = 0; if ( size > TOTAL_BUTTONS) { - LOG(AQUA_LOG,LOG_ERR, "Panel size is either invalid or too large for compiled parameters, ignoring %d using %d\n",size, TOTAL_BUTTONS); + LOG(PANL_LOG,LOG_ERR, "Panel size is either invalid or too large for compiled parameters, ignoring %d using %d\n",size, TOTAL_BUTTONS); rtn_size = TOTAL_BUTTONS; } @@ -160,7 +160,7 @@ int setSizeMask(int size) _aqconfig_.paneltype_mask |= RSP_16; break; default: - LOG(AQUA_LOG,LOG_ERR, "Didn't understand panel size, '%d' setting to size to 8\n",size); + LOG(PANL_LOG,LOG_ERR, "Didn't understand panel size, '%d' setting to size to 8\n",size); _aqconfig_.paneltype_mask |= RSP_8; rtn_size = 8; break; @@ -176,7 +176,7 @@ void setPanel(struct aqualinkdata *aqdata, bool rs, int size, bool combo, bool d { #ifndef AQ_PDA if (!rs) { - LOG(AQUA_LOG,LOG_ERR, "Can't use PDA mode, AqualinkD has not been compiled with PDA Enabled\n"); + LOG(PANL_LOG,LOG_ERR, "Can't use PDA mode, AqualinkD has not been compiled with PDA Enabled\n"); rs = true; } #endif @@ -228,7 +228,7 @@ void setPanelByName(struct aqualinkdata *aqdata, const char *str) else // Account for PDA-8 size = atoi(&str[4]); } else { - LOG(AQUA_LOG,LOG_ERR, "Didn't understand panel type, '%.2s' from '%s' setting to size to RS-8\n",str,str); + LOG(PANL_LOG,LOG_ERR, "Didn't understand panel type, '%.2s' from '%s' setting to size to RS-8\n",str,str); rs = true; size = 8; } @@ -245,7 +245,7 @@ void setPanelByName(struct aqualinkdata *aqdata, const char *str) } else if (str[i+1] == 'D' || str[i+1] == 'd') { dual = true; } else { - LOG(AQUA_LOG,LOG_ERR, "Didn't understand panel type, '%s' from '%s' setting to Combo\n",&str[i+1],str); + LOG(PANL_LOG,LOG_ERR, "Didn't understand panel type, '%s' from '%s' setting to Combo\n",&str[i+1],str); combo = true; } @@ -503,9 +503,84 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo #endif } +const char* getRequestName(request_source source) +{ + switch(source) { + case NET_MQTT: + return "MQTT"; + break; + case NET_API: + return "API"; + break; + case NET_WS: + return "WebSocket"; + break; + case NET_DZMQTT: + return "Domoticz"; + break; + case NET_TIMER: + return "Timer"; + break; + } + static char buf[25]; + sprintf(buf, "Unknown %d", source); + return buf; +} +const char* getActionName(action_type type) +{ + switch (type) { + case ON_OFF: + return "OnOff"; + break; + case NO_ACTION: + return "No Action"; + break; + case POOL_HTR_SETOINT: + return "Pool Heater Setpoint"; + break; + case SPA_HTR_SETOINT: + return "Spa Heater Setpoint"; + break; + case FREEZE_SETPOINT: + return "Freeze Protect Setpoint"; + break; + case SWG_SETPOINT: + return "SWG Percent"; + break; + case SWG_BOOST: + return "SWG Boost"; + break; + case PUMP_RPM: + return "VSP RPM/GPM"; + break; + case PUMP_VSPROGRAM: + return "VSP Program"; + break; + case POOL_HTR_INCREMENT: + return "Pool Heater Increment"; + break; + case SPA_HTR_INCREMENT: + return "Spa Heater Increment"; + break; + case TIMER: + return "Timer"; + break; + case LIGHT_MODE: + return "Light Mode"; + break; + case DATE_TIME: + return "Date Time"; + break; + } + + static char buf[25]; + sprintf(buf, "Unknown %d", type); + return buf; +} + //void create_PDA_on_off_request(aqkey *button, bool isON); //bool create_panel_request(struct aqualinkdata *aqdata, netRequest requester, int buttonIndex, int value, bool timer); //void create_program_request(struct aqualinkdata *aqdata, netRequest requester, action_type type, int value, int id); // id is only valid for PUMP RPM @@ -519,10 +594,10 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON) if ((button->led->state == OFF && isON == false) || (isON > 0 && (button->led->state == ON || button->led->state == FLASH || button->led->state == ENABLE))) { - LOG(AQUA_LOG, LOG_INFO, "received '%s' for '%s', already '%s', Ignoring\n", (isON == false ? "OFF" : "ON"), button->name, (isON == false ? "OFF" : "ON")); + LOG(PANL_LOG, LOG_INFO, "received '%s' for '%s', already '%s', Ignoring\n", (isON == false ? "OFF" : "ON"), button->name, (isON == false ? "OFF" : "ON")); //return false; } else { - LOG(AQUA_LOG, LOG_INFO, "received '%s' for '%s', turning '%s'\n", (isON == false ? "OFF" : "ON"), button->name, (isON == false ? "OFF" : "ON")); + LOG(PANL_LOG, LOG_INFO, "received '%s' for '%s', turning '%s'\n", (isON == false ? "OFF" : "ON"), button->name, (isON == false ? "OFF" : "ON")); #ifdef AQ_PDA if (isPDA_PANEL) { if (button->special_mask & PROGRAM_LIGHT && isPDA_IAQT) { @@ -570,16 +645,16 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON) bool programDeviceValue(struct aqualinkdata *aqdata, action_type type, int value, int id, bool expectMultiple) // id is only valid for PUMP RPM { if (aqdata->unactioned.type != NO_ACTION && type != aqdata->unactioned.type) - LOG(AQUA_LOG,LOG_ERR, "about to overwrite unactioned panel program\n"); + LOG(PANL_LOG,LOG_ERR, "about to overwrite unactioned panel program\n"); if (type == POOL_HTR_SETOINT || type == SPA_HTR_SETOINT || type == FREEZE_SETPOINT || type == SWG_SETPOINT ) { aqdata->unactioned.value = setpoint_check(type, value, aqdata); if (value != aqdata->unactioned.value) - LOG(AQUA_LOG,LOG_NOTICE, "requested setpoint value %d is invalid, change to %d\n", value, aqdata->unactioned.value); + LOG(PANL_LOG,LOG_NOTICE, "requested setpoint value %d is invalid, change to %d\n", value, aqdata->unactioned.value); } else if (type == PUMP_RPM) { aqdata->unactioned.value = value; } else if (type == PUMP_VSPROGRAM) { - LOG(AQUA_LOG,LOG_ERR, "requested Pump vsp program is not implimented yet\n", value, aqdata->unactioned.value); + LOG(PANL_LOG,LOG_ERR, "requested Pump vsp program is not implimented yet\n", value, aqdata->unactioned.value); } else { // SWG_BOOST & PUMP_RPM & SETPOINT incrment aqdata->unactioned.value = value; @@ -604,7 +679,7 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button) clight_detail *light = NULL; #ifdef AQ_PDA if (isPDA_PANEL && !isPDA_IAQT) { - LOG(AQUA_LOG,LOG_ERR, "Light mode control not supported in PDA mode\n"); + LOG(PANL_LOG,LOG_ERR, "Light mode control not supported in PDA mode\n"); return; } #endif @@ -617,7 +692,7 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button) } if (light == NULL) { - LOG(AQUA_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button); + LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button); return; } @@ -647,20 +722,26 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button) //bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int deviceIndex, int value, int subIndex, bool fromMQTT) bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int deviceIndex, int value, request_source source) { - LOG(AQUA_LOG,LOG_INFO, "Device request type %d for deviceindex %d of value %d from %d\n",type,deviceIndex, value, source); + LOG(PANL_LOG,LOG_INFO, "Device request type '%s' for deviceindex %d '%s' of value %d from '%s'\n", + getActionName(type), + deviceIndex,aqdata->aqbuttons[deviceIndex].label, + value, + getRequestName(source)); switch (type) { case ON_OFF: //setDeviceState(&aqdata->aqbuttons[deviceIndex], value<=0?false:true, deviceIndex ); setDeviceState(aqdata, deviceIndex, value<=0?false:true ); // Clear timer if off request and timer is active if (value<=0 && (aqdata->aqbuttons[deviceIndex].special_mask & TIMER_ACTIVE) == TIMER_ACTIVE ) { - clear_timer(aqdata, &aqdata->aqbuttons[deviceIndex]); + //clear_timer(aqdata, &aqdata->aqbuttons[deviceIndex]); + clear_timer(aqdata, deviceIndex); } break; case TIMER: //setDeviceState(&aqdata->aqbuttons[deviceIndex], true); setDeviceState(aqdata, deviceIndex, true); - start_timer(aqdata, &aqdata->aqbuttons[deviceIndex], value); + //start_timer(aqdata, &aqdata->aqbuttons[deviceIndex], deviceIndex, value); + start_timer(aqdata, deviceIndex, value); break; case LIGHT_MODE: programDeviceLightMode(aqdata, value, deviceIndex); @@ -680,7 +761,7 @@ bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int dev aq_programmer(AQ_SET_TIME, NULL, aqdata); break; default: - LOG(AQUA_LOG,LOG_ERR, "Unknown device request type %d for deviceindex %d\n",type,deviceIndex); + LOG(PANL_LOG,LOG_ERR, "Unknown device request type %d for deviceindex %d\n",type,deviceIndex); break; } diff --git a/aq_programmer.c b/aq_programmer.c index 63cc1287..fa01a58b 100644 --- a/aq_programmer.c +++ b/aq_programmer.c @@ -502,46 +502,21 @@ bool in_swg_programming_mode(struct aqualinkdata *aq_data) bool in_ot_programming_mode(struct aqualinkdata *aq_data) { - //( type != AQ_SET_PUMP_RPM || type != AQ_SET_OT_MACRO )) { - - if ( ( aq_data->active_thread.thread_id != 0 ) && - ( aq_data->active_thread.ptype == AQ_SET_ONETOUCH_PUMP_RPM || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_MACRO || - aq_data->active_thread.ptype == AQ_GET_ONETOUCH_SETPOINTS || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_TIME || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SWG_PERCENT || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_BOOST || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_POOL_HEATER_TEMP || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SPA_HEATER_TEMP || - aq_data->active_thread.ptype == AQ_SET_ONETOUCH_FREEZEPROTECT) - ) { - return true; + if ( aq_data->active_thread.thread_id != 0 && + aq_data->active_thread.ptype >= AQP_ONETOUCH_MIN && + aq_data->active_thread.ptype <= AQP_ONETOUCH_MAX) { + return true; } - return false; } bool in_iaqt_programming_mode(struct aqualinkdata *aq_data) { - //( type != AQ_SET_PUMP_RPM || type != AQ_SET_OT_MACRO )) { - - if ( ( aq_data->active_thread.thread_id != 0 ) && - ( aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_PUMP_RPM || - aq_data->active_thread.ptype == AQ_GET_IAQTOUCH_VSP_ASSIGNMENT || - aq_data->active_thread.ptype == AQ_GET_IAQTOUCH_SETPOINTS || - aq_data->active_thread.ptype == AQ_GET_IAQTOUCH_AUX_LABELS || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_PERCENT || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SWG_BOOST || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_POOL_HEATER_TEMP || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SPA_HEATER_TEMP || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_SET_TIME || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_DEVICE_ON_OFF || - aq_data->active_thread.ptype == AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE) - ) { - return true; + if ( aq_data->active_thread.thread_id != 0 && + aq_data->active_thread.ptype >= AQP_IAQTOUCH_MIN && + aq_data->active_thread.ptype <= AQP_IAQTOUCH_MAX) { + return true; } - return false; } @@ -1193,7 +1168,7 @@ bool setAqualinkNumericField(struct aqualinkdata *aq_data, char *value_label, in } bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label, int value, int increment) { - LOG(PROG_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); + LOG(ALLB_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); //char leading[10]; // description of the field (POOL, SPA, FRZ) int current_val=-1; // integer value of the current set point //char trailing[10]; // the degrees and scale @@ -1205,15 +1180,15 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label do { if (waitForMessage(aq_data, searchBuf, 4) != true) { - LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); + LOG(ALLB_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } -//LOG(PROG_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); +//LOG(ALLB_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); //sscanf(aq_data->last_message, "%s %d%s", leading, ¤t_val, trailing); //sscanf(aq_data->last_message, "%*[^0123456789]%d", ¤t_val); sscanf(&aq_data->last_message[val_len], "%*[^0123456789]%d", ¤t_val); - LOG(PROG_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); + LOG(ALLB_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { // Increment the field. @@ -1232,7 +1207,7 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label } if (i++ >= 100) { - LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', to '%d'\n",value_label,value); + LOG(ALLB_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', to '%d'\n",value_label,value); send_cmd(KEY_ENTER); break; } @@ -1245,7 +1220,7 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aq_data, char *value_label, int value) { // Works for everything but not SWG - LOG(PROG_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); + LOG(ALLB_LOG, LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); char leading[10]; // description of the field (POOL, SPA, FRZ) int current_val; // integer value of the current set point char trailing[10]; // the degrees and scale @@ -1256,13 +1231,13 @@ bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aq_data, char *value_l do { if (waitForMessage(aq_data, searchBuf, 3) != true) { - LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); + LOG(ALLB_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } -//LOG(PROG_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); +//LOG(ALLB_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); sscanf(aq_data->last_message, "%s %d%s", leading, ¤t_val, trailing); - LOG(PROG_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); + LOG(ALLB_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { // Increment the field. @@ -1337,10 +1312,10 @@ STOP BOOST POOL } #endif - LOG(PROG_LOG, LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); + LOG(ALLB_LOG, LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); if ( select_menu_item(aq_data, "BOOST POOL") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select BOOST POOL menu\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1360,16 +1335,16 @@ STOP BOOST POOL // This is a really bad hack, message sequence is out for boost for some reason, so as soon as we see stop message, force enter key. //_pgm_command = KEY_ENTER; send_cmd(KEY_ENTER); - LOG(PROG_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); + LOG(ALLB_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); //waitfor_queue2empty(); break; } else { - LOG(PROG_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for 'STOP BOOST POOL' received message '%s'\n",i,wait_messages,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for 'STOP BOOST POOL' received message '%s'\n",i,wait_messages,aq_data->last_message); delay(200); if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) { //_pgm_command = KEY_ENTER; send_cmd(KEY_ENTER); - LOG(PROG_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); + LOG(ALLB_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); break; } send_cmd(KEY_RIGHT); @@ -1389,7 +1364,7 @@ STOP BOOST POOL send_cmd(KEY_RIGHT); waitfor_queue2empty(); if ( select_sub_menu_item(aq_data, "STOP BOOST POOL") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select STOP BOOST POOL menu\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select STOP BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1425,11 +1400,11 @@ void *set_aqualink_SWG( void *ptr ) } #endif - //LOG(PROG_LOG, LOG_NOTICE, "programming SWG percent to %d\n", val); + //LOG(ALLB_LOG, LOG_NOTICE, "programming SWG percent to %d\n", val); if ( select_menu_item(aq_data, "SET AQUAPURE") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET AQUAPURE menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET AQUAPURE menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1438,8 +1413,8 @@ void *set_aqualink_SWG( void *ptr ) // If spa is on, set SWG for spa, if not set SWG for pool if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) { if (select_sub_menu_item(aq_data, "SET SPA SP") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu for SPA\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu for SPA\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1447,8 +1422,8 @@ void *set_aqualink_SWG( void *ptr ) setAqualinkNumericField_new(aq_data, "SPA SP", val, 5); } else { if (select_sub_menu_item(aq_data, "SET POOL SP") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1461,7 +1436,7 @@ void *set_aqualink_SWG( void *ptr ) /* if (select_sub_menu_item(aq_data, "SET POOL SP") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); cancel_menu(aq_data); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1505,16 +1480,16 @@ void *get_aqualink_aux_labels( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "AUX LABELS") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select AUX LABELS menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select AUX LABELS menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1545,7 +1520,7 @@ void *set_aqualink_light_colormode( void *ptr ) bool use_current_mode = false; if (btn < 0 || btn >= aq_data->total_buttons ) { - LOG(PROG_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); + LOG(ALLB_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -1553,20 +1528,20 @@ void *set_aqualink_light_colormode( void *ptr ) aqkey *button = &aq_data->aqbuttons[btn]; unsigned char code = button->code; - //LOG(PROG_LOG, LOG_NOTICE, "Light Programming #: %d, on button: %s, color light type: %d\n", val, button->label, typ); + //LOG(ALLB_LOG, LOG_NOTICE, "Light Programming #: %d, on button: %s, color light type: %d\n", val, button->label, typ); if (val <= 0) { use_current_mode = true; - LOG(PROG_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, using current mode\n", val, button->label, typ); + LOG(ALLB_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, using current mode\n", val, button->label, typ); } else { mode_name = light_mode_name(typ, val-1, ALLBUTTON); use_current_mode = false; if (mode_name == NULL) { - LOG(PROG_LOG, LOG_ERR, "Light Programming #: %d, on button: %s, color light type: %d, couldn't find mode name '%s'\n", val, button->label, typ, mode_name); + LOG(ALLB_LOG, LOG_ERR, "Light Programming #: %d, on button: %s, color light type: %d, couldn't find mode name '%s'\n", val, button->label, typ, mode_name); cleanAndTerminateThread(threadCtrl); return ptr; } else { - LOG(PROG_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, name '%s'\n", val, button->label, typ, mode_name); + LOG(ALLB_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, name '%s'\n", val, button->label, typ, mode_name); } } /* @@ -1581,11 +1556,11 @@ void *set_aqualink_light_colormode( void *ptr ) */ // Needs to start programming sequence with light off if ( button->led->state == ON ) { - LOG(PROG_LOG, LOG_INFO, "Light Programming Initial state on, turning off\n"); + LOG(ALLB_LOG, LOG_INFO, "Light Programming Initial state on, turning off\n"); send_cmd(code); waitfor_queue2empty(); if ( !waitForMessage(threadCtrl->aq_data, "OFF", 5)) // Message like 'Aux3 Off' - LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive OFF message\n"); + LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive OFF message\n"); } // Now turn on and wait for the message "color mode name<>*" @@ -1595,20 +1570,20 @@ void *set_aqualink_light_colormode( void *ptr ) int waitCounter=12; do{ - LOG(PROG_LOG, LOG_INFO,"Light program wait for message\n"); + LOG(ALLB_LOG, LOG_INFO,"Light program wait for message\n"); if ( !waitForMessage(threadCtrl->aq_data, "~*", waitCounter)) - LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive color light mode message\n"); + LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive color light mode message\n"); // Wait for less messages after first try. We get a lot of repeat messages before the one we need. waitCounter = 3; if (use_current_mode) { - LOG(PROG_LOG, LOG_INFO, "Light Programming using color mode %s\n",aq_data->last_message); + LOG(ALLB_LOG, LOG_INFO, "Light Programming using color mode %s\n",aq_data->last_message); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; } else if (strncasecmp(aq_data->last_message, mode_name, strlen(mode_name)) == 0) { - LOG(PROG_LOG, LOG_INFO, "Light Programming found color mode %s\n",mode_name); + LOG(ALLB_LOG, LOG_INFO, "Light Programming found color mode %s\n",mode_name); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; @@ -1624,7 +1599,7 @@ void *set_aqualink_light_colormode( void *ptr ) } while (i <= LIGHT_COLOR_OPTIONS); if (i == LIGHT_COLOR_OPTIONS) { - LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive color light mode message for '%s'\n",use_current_mode?"light program":mode_name); + LOG(ALLB_LOG, LOG_ERR, "Light Programming didn't receive color light mode message for '%s'\n",use_current_mode?"light program":mode_name); } cleanAndTerminateThread(threadCtrl); @@ -1651,7 +1626,7 @@ void *set_aqualink_light_programmode( void *ptr ) float pmode = atof(&buf[20]); if (btn < 0 || btn >= aq_data->total_buttons ) { - LOG(PROG_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); + LOG(ALLB_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -1659,7 +1634,7 @@ void *set_aqualink_light_programmode( void *ptr ) aqkey *button = &aq_data->aqbuttons[btn]; unsigned char code = button->code; - LOG(PROG_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, with pause mode: %f (initial on=%d, initial off=%d)\n", val, button->label, pmode, iOn, iOff); + LOG(ALLB_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, with pause mode: %f (initial on=%d, initial off=%d)\n", val, button->label, pmode, iOn, iOff); // Simply turn the light off if value is 0 if (val <= 0) { @@ -1674,23 +1649,23 @@ void *set_aqualink_light_programmode( void *ptr ) // Needs to start programming sequence with light on, if off we need to turn on for 15 seconds // before we can send the next off. if ( button->led->state != ON ) { - LOG(PROG_LOG, LOG_INFO, "Light Programming Initial state off, turning on for %d seconds\n",iOn); + LOG(ALLB_LOG, LOG_INFO, "Light Programming Initial state off, turning on for %d seconds\n",iOn); send_cmd(code); delay(iOn * seconds); } - LOG(PROG_LOG, LOG_INFO, "Light Programming turn off for %d seconds\n",iOff); + LOG(ALLB_LOG, LOG_INFO, "Light Programming turn off for %d seconds\n",iOff); // Now need to turn off for between 11 and 14 seconds to reset light. send_cmd(code); delay(iOff * seconds); // Now light is reset, pulse the appropiate number of times to advance program. - LOG(PROG_LOG, LOG_INFO, "Light Programming button pulsing on/off %d times\n", val); + LOG(ALLB_LOG, LOG_INFO, "Light Programming button pulsing on/off %d times\n", val); // Program light in safe mode (slowley), or quick mode if (pmode > 0) { for (i = 1; i < (val * 2); i++) { - LOG(PROG_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, i % 2 == 0 ? "Off" : "On", val); + LOG(ALLB_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, i % 2 == 0 ? "Off" : "On", val); send_cmd(code); waitfor_queue2empty(); delay(pmode * seconds); // 0.3 works, but using 0.4 to be safe @@ -1698,16 +1673,16 @@ void *set_aqualink_light_programmode( void *ptr ) } else { for (i = 1; i < val; i++) { const int dt = 0.5; // Time to wait after receiving conformation of light on/off - LOG(PROG_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "ON", val); + LOG(ALLB_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "ON", val); send_cmd(code); waitForButtonState(aq_data, button, ON, 2); delay(dt * seconds); - LOG(PROG_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "OFF", val); + LOG(ALLB_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "OFF", val); send_cmd(code); waitForButtonState(aq_data, button, OFF, 2); delay(dt * seconds); } - LOG(PROG_LOG, LOG_INFO, "Finished - Light Programming button press number %d - %s of %d\n", i, "ON", val); + LOG(ALLB_LOG, LOG_INFO, "Finished - Light Programming button press number %d - %s of %d\n", i, "ON", val); send_cmd(code); waitfor_queue2empty(); } @@ -1754,12 +1729,12 @@ void *set_aqualink_pool_heater_temps( void *ptr ) menu_name = "SET POOL TEMP"; } - LOG(PROG_LOG, LOG_DEBUG, "Setting pool heater setpoint to %d\n", val); + LOG(ALLB_LOG, LOG_DEBUG, "Setting pool heater setpoint to %d\n", val); //setAqualinkTemp(aq_data, "SET TEMP", "SET POOL TEMP", NULL, "POOL", val); if ( select_menu_item(aq_data, "SET TEMP") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1767,8 +1742,8 @@ void *set_aqualink_pool_heater_temps( void *ptr ) //if (select_sub_menu_item(aq_data, "SET POOL TEMP") != true) { if (select_sub_menu_item(aq_data, menu_name) != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET POOL TEMP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET POOL TEMP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1831,12 +1806,12 @@ void *set_aqualink_spa_heater_temps( void *ptr ) menu_name = "SET SPA TEMP"; } - LOG(PROG_LOG, LOG_DEBUG, "Setting spa heater setpoint to %d\n", val); + LOG(ALLB_LOG, LOG_DEBUG, "Setting spa heater setpoint to %d\n", val); //setAqualinkTemp(aq_data, "SET TEMP", "SET SPA TEMP", NULL, "SPA", val); if ( select_menu_item(aq_data, "SET TEMP") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1844,8 +1819,8 @@ void *set_aqualink_spa_heater_temps( void *ptr ) //if (select_sub_menu_item(aq_data, "SET SPA TEMP") != true) { if (select_sub_menu_item(aq_data, menu_name) != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET SPA TEMP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET SPA TEMP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1891,7 +1866,7 @@ void *set_aqualink_freeze_heater_temps( void *ptr ) */ val = setpoint_check(FREEZE_SETPOINT, val, aq_data); - LOG(PROG_LOG, LOG_DEBUG, "Setting sfreeze protection to %d\n", val); + LOG(ALLB_LOG, LOG_DEBUG, "Setting sfreeze protection to %d\n", val); #ifdef AQ_PDA if (isPDA_PANEL) { @@ -1902,24 +1877,24 @@ void *set_aqualink_freeze_heater_temps( void *ptr ) #endif //setAqualinkTemp(aq_data, "SYSTEM SETUP", "FRZ PROTECT", "TEMP SETTING", "FRZ", val); if ( select_menu_item(aq_data, "SYSTEM SETUP") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SYSTEM SETUP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SYSTEM SETUP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "TEMP SETTING") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select TEMP SETTING menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select TEMP SETTING menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1941,7 +1916,7 @@ void *set_aqualink_time( void *ptr ) struct aqualinkdata *aq_data = threadCtrl->aq_data; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_TIME); - //LOG(PROG_LOG, LOG_NOTICE, "Setting time on aqualink\n"); + //LOG(ALLB_LOG, LOG_NOTICE, "Setting time on aqualink\n"); #ifdef AQ_PDA if (isPDA_PANEL) { @@ -1971,11 +1946,11 @@ void *set_aqualink_time( void *ptr ) sprintf(hour, "HOUR %d PM", result->tm_hour - 12); - LOG(PROG_LOG, LOG_DEBUG, "Setting time to %d/%d/%d %d:%d\n", result->tm_mon + 1, result->tm_mday, result->tm_year + 1900, result->tm_hour + 1, result->tm_min); + LOG(ALLB_LOG, LOG_DEBUG, "Setting time to %d/%d/%d %d:%d\n", result->tm_mon + 1, result->tm_mday, result->tm_year + 1900, result->tm_hour + 1, result->tm_min); if ( select_menu_item(aq_data, "SET TIME") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select SET TIME menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select SET TIME menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -2005,16 +1980,16 @@ void *get_aqualink_diag_model( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_DIAGNOSTICS_MODEL); if ( select_menu_item(aq_data, "SYSTEM SETUP") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select HELP menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select HELP menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "DIAGNOSTICS") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select DIAGNOSTICS menu\n"); - LOG(PROG_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); + LOG(ALLB_LOG, LOG_WARNING, "Could not select DIAGNOSTICS menu\n"); + LOG(ALLB_LOG, LOG_ERR, "%s failed\n", ptypeName( aq_data->active_thread.ptype ) ); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -2030,18 +2005,18 @@ void *get_aqualink_diag_model( void *ptr ) void *get_aqualink_pool_spa_heater_temps( void *ptr ) { -//LOG(PROG_LOG, LOG_DEBUG, "Could not select TEMP SET menu\n"); +//LOG(ALLB_LOG, LOG_DEBUG, "Could not select TEMP SET menu\n"); struct programmingThreadCtrl *threadCtrl; threadCtrl = (struct programmingThreadCtrl *) ptr; struct aqualinkdata *aq_data = threadCtrl->aq_data; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_POOL_SPA_HEATER_TEMPS); - //LOG(PROG_LOG, LOG_NOTICE, "Getting pool & spa heat setpoints from aqualink\n"); + //LOG(ALLB_LOG, LOG_NOTICE, "Getting pool & spa heat setpoints from aqualink\n"); #ifdef AQ_PDA if (isPDA_PANEL) { if (!get_PDA_aqualink_pool_spa_heater_temps(aq_data)) { - LOG(PROG_LOG, LOG_ERR, "Error Getting PDA pool & spa heater setpoints\n"); + LOG(ALLB_LOG, LOG_ERR, "Error Getting PDA pool & spa heater setpoints\n"); } cleanAndTerminateThread(threadCtrl); return ptr; @@ -2049,16 +2024,16 @@ void *get_aqualink_pool_spa_heater_temps( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); - LOG(PROG_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(ALLB_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "TEMP SET") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select TEMP SET menu\n"); - LOG(PROG_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select TEMP SET menu\n"); + LOG(ALLB_LOG, LOG_ERR, "Can't get heater setpoints from Control Panel\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -2082,12 +2057,12 @@ void *get_freeze_protect_temp( void *ptr ) struct aqualinkdata *aq_data = threadCtrl->aq_data; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_FREEZE_PROTECT_TEMP); - //LOG(PROG_LOG, LOG_NOTICE, "Getting freeze protection setpoints\n"); + //LOG(ALLB_LOG, LOG_NOTICE, "Getting freeze protection setpoints\n"); #ifdef AQ_PDA if (isPDA_PANEL) { if (! get_PDA_freeze_protect_temp(aq_data)) { - LOG(PROG_LOG, LOG_ERR, "Error Getting PDA freeze protection setpoints\n"); + LOG(ALLB_LOG, LOG_ERR, "Error Getting PDA freeze protection setpoints\n"); } cleanAndTerminateThread(threadCtrl); return ptr; @@ -2095,16 +2070,16 @@ void *get_freeze_protect_temp( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); - LOG(PROG_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(ALLB_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { - LOG(PROG_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); - LOG(PROG_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); + LOG(ALLB_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); + LOG(ALLB_LOG, LOG_ERR, "Can't get freeze setpoints from Control Panel\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -2125,7 +2100,7 @@ bool get_aqualink_program_for_button(struct aqualinkdata *aq_data, unsigned char if (! waitForMessage(aq_data, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", rtnStringsWait)) return false; - LOG(PROG_LOG, LOG_DEBUG, "Send key '%d'\n",cmd); + LOG(ALLB_LOG, LOG_DEBUG, "Send key '%d'\n",cmd); send_cmd(cmd); return waitForEitherMessage(aq_data, "NOT SET", "TURNS ON", rtnStringsWait); } @@ -2140,14 +2115,14 @@ void *get_aqualink_programs( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_PROGRAMS); if ( select_menu_item(aq_data, "REVIEW") != true ) { - //LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); + //LOG(ALLB_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "PROGRAMS") != true) { - //LOG(PROG_LOG, LOG_WARNING, "Could not select PROGRAMS menu\n"); + //LOG(ALLB_LOG, LOG_WARNING, "Could not select PROGRAMS menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -2156,22 +2131,22 @@ void *get_aqualink_programs( void *ptr ) unsigned int i; for (i=0; i < strlen(keys); i++) { - //LOG(PROG_LOG, LOG_DEBUG, "**** START program for key in loop %d\n",i); + //LOG(ALLB_LOG, LOG_DEBUG, "**** START program for key in loop %d\n",i); if (! get_aqualink_program_for_button(aq_data, keys[i])) { - //LOG(PROG_LOG, LOG_DEBUG, "**** Didn't find program for key in loop %d\n",i); + //LOG(ALLB_LOG, LOG_DEBUG, "**** Didn't find program for key in loop %d\n",i); //cancel_menu(aq_data); cleanAndTerminateThread(threadCtrl); return ptr; } - //LOG(PROG_LOG, LOG_DEBUG, "**** Found program for key in loop %d\n",i); + //LOG(ALLB_LOG, LOG_DEBUG, "**** Found program for key in loop %d\n",i); } if (waitForMessage(aq_data, "SELECT DEVICE TO REVIEW or PRESS ENTER TO END", 6)) { - //LOG(PROG_LOG, LOG_DEBUG, "Send key ENTER\n"); + //LOG(ALLB_LOG, LOG_DEBUG, "Send key ENTER\n"); send_cmd(KEY_ENTER); } else { - //LOG(PROG_LOG, LOG_DEBUG, "Send CANCEL\n"); + //LOG(ALLB_LOG, LOG_DEBUG, "Send CANCEL\n"); cancel_menu(); } @@ -2186,7 +2161,7 @@ void *get_aqualink_programs( void *ptr ) void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) { push_aq_cmd(cmd); - LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", cmd); + LOG(ALLB_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", cmd); } */ @@ -2197,9 +2172,9 @@ void _waitfor_queue2empty(bool longwait) int i=0; if (_pgm_command != NUL) { - LOG(PROG_LOG, LOG_DEBUG, "Waiting for queue to empty\n"); + LOG(ALLB_LOG, LOG_DEBUG, "Waiting for queue to empty\n"); } else { - LOG(PROG_LOG, LOG_DEBUG, "Queue empty!\n"); + LOG(ALLB_LOG, LOG_DEBUG, "Queue empty!\n"); return; } @@ -2211,7 +2186,7 @@ void _waitfor_queue2empty(bool longwait) //while ( (_pgm_command != NUL) && ( i++ < (30*(longwait?2:1) ) ) ) { while ( (_pgm_command != NUL) && ( i++ < (50*(longwait?2:1) ) ) ) { //sleep(1); // NSF Change to smaller time. - //LOG(PROG_LOG, LOG_DEBUG, "******** QUEUE IS FULL ******** delay\n"); + //LOG(ALLB_LOG, LOG_DEBUG, "******** QUEUE IS FULL ******** delay\n"); delay(50); } */ @@ -2224,9 +2199,9 @@ void _waitfor_queue2empty(bool longwait) } } #endif - LOG(PROG_LOG, LOG_WARNING, "Send command Queue did not empty, timeout\n"); + LOG(ALLB_LOG, LOG_WARNING, "Send command Queue did not empty, timeout\n"); } else { - LOG(PROG_LOG, LOG_DEBUG, "Queue now empty!\n"); + LOG(ALLB_LOG, LOG_DEBUG, "Queue now empty!\n"); } } @@ -2247,12 +2222,12 @@ void send_cmd(unsigned char cmd) _pgm_command = cmd; //delay(200); - LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller (programming)\n", _pgm_command); + LOG(ALLB_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller (programming)\n", _pgm_command); } void force_queue_delete() { if (_pgm_command != NUL) - LOG(PROG_LOG, LOG_INFO, "Really bad coding, don't use this in release\n"); + LOG(ALLB_LOG, LOG_INFO, "Really bad coding, don't use this in release\n"); _pgm_command = NUL; } @@ -2270,7 +2245,7 @@ void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) aq_data->aq_command = cmd; //delay(200); - LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", aq_data->aq_command); + LOG(ALLB_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", aq_data->aq_command); } */ @@ -2285,7 +2260,7 @@ void cancel_menu() bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived) { - //LOG(PROG_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); + //LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); waitfor_queue2empty(); // MAke sure the last command was sent int i=0; pthread_mutex_lock(&aq_data->active_thread.thread_mutex); @@ -2309,12 +2284,12 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me while( ++i <= numMessageReceived) { - LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' OR '%s' received message1 '%s'\n",i,numMessageReceived,message1,message2,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' OR '%s' received message1 '%s'\n",i,numMessageReceived,message1,message2,aq_data->last_message); if (message1 != NULL) { ptr = stristr(aq_data->last_message, msgS1); if (ptr != NULL) { // match - LOG(PROG_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS1); + LOG(ALLB_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS1); if (msgS1 == message1) // match & don't care if first char break; else if (ptr == aq_data->last_message) // match & do care if first char @@ -2324,7 +2299,7 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me if (message2 != NULL) { ptr = stristr(aq_data->last_message, msgS2); if (ptr != NULL) { // match - LOG(PROG_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS2); + LOG(ALLB_LOG, LOG_DEBUG, "String MATCH '%s'\n", msgS2); if (msgS2 == message2) // match & don't care if first char break; else if (ptr == aq_data->last_message) // match & do care if first char @@ -2332,19 +2307,19 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me } } - //LOG(PROG_LOG, LOG_DEBUG, "looking for '%s' received message1 '%s'\n",message1,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message1 '%s'\n",message1,aq_data->last_message); pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message1 '%s'\n",i,numMessageReceived,message1,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message1 '%s'\n",i,numMessageReceived,message1,aq_data->last_message); } pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); if (message1 != NULL && message2 != NULL && ptr == NULL) { //logmessage1(LOG_ERR, "Could not select MENU of Aqualink control panel\n"); - LOG(PROG_LOG, LOG_ERR, "Did not find '%s'\n",message1); + LOG(ALLB_LOG, LOG_ERR, "Did not find '%s'\n",message1); return false; } - LOG(PROG_LOG, LOG_DEBUG, "Found message1 '%s' or '%s' in '%s'\n",message1,message2,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Found message1 '%s' or '%s' in '%s'\n",message1,message2,aq_data->last_message); return true; } @@ -2353,7 +2328,7 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived) { - LOG(PROG_LOG, LOG_DEBUG, "waitForMessage %s %d\n",message,numMessageReceived); + LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d\n",message,numMessageReceived); // NSF Need to come back to this, as it stops on test enviornment but not real panel, so must be speed related. //waitfor_queue2empty(); // MAke sure the last command was sent @@ -2372,14 +2347,14 @@ bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageR while( ++i <= numMessageReceived) { if (message != NULL) - LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aq_data->last_message); else - LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d waiting for next message, last message received '%s'\n",i,numMessageReceived,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d waiting for next message, last message received '%s'\n",i,numMessageReceived,aq_data->last_message); if (message != NULL) { ptr = stristr(aq_data->last_message, msgS); if (ptr != NULL) { // match - LOG(PROG_LOG, LOG_DEBUG, "String MATCH\n"); + LOG(ALLB_LOG, LOG_DEBUG, "String MATCH\n"); if (msgS == message) // match & don't care if first char break; else if (ptr == aq_data->last_message) // match & do care if first char @@ -2387,23 +2362,23 @@ bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageR } } - //LOG(PROG_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); - //LOG(PROG_LOG, LOG_DEBUG, "*** pthread_cond_wait() sleep\n"); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "*** pthread_cond_wait() sleep\n"); pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(PROG_LOG, LOG_DEBUG, "*** pthread_cond_wait() wake\n"); - //LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "*** pthread_cond_wait() wake\n"); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); } pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); if (message != NULL && ptr == NULL) { - //LOG(PROG_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); - LOG(PROG_LOG, LOG_DEBUG, "did not find '%s'\n",message); + //LOG(ALLB_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); + LOG(ALLB_LOG, LOG_DEBUG, "did not find '%s'\n",message); return false; } else if (message != NULL) - LOG(PROG_LOG, LOG_DEBUG, "found message '%s' in '%s'\n",message,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "found message '%s' in '%s'\n",message,aq_data->last_message); else - LOG(PROG_LOG, LOG_DEBUG, "waited for %d message(s)\n",numMessageReceived); + LOG(ALLB_LOG, LOG_DEBUG, "waited for %d message(s)\n",numMessageReceived); return true; } @@ -2467,7 +2442,7 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) while( (stristr(aq_data->last_message, item_string) == NULL) && ( i++ < wait_messages) ) { - LOG(PROG_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for '%s' received message '%s'\n",i,wait_messages,item_string,aq_data->last_message); + LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d looking for '%s' received message '%s'\n",i,wait_messages,item_string,aq_data->last_message); send_cmd(KEY_RIGHT); waitfor_queue2empty(); // ADDED BACK MAY 2023 setting time warked better //waitForMessage(aq_data, NULL, 1); @@ -2475,11 +2450,11 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) } if (stristr(aq_data->last_message, item_string) == NULL) { - LOG(PROG_LOG, LOG_ERR, "Could not find menu item '%s'\n",item_string); + LOG(ALLB_LOG, LOG_ERR, "Could not find menu item '%s'\n",item_string); return false; } - LOG(PROG_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d FOUND menu item '%s', sending ENTER command\n",i,wait_messages, item_string); + LOG(ALLB_LOG, LOG_DEBUG, "Find item in Menu: loop %d of %d FOUND menu item '%s', sending ENTER command\n",i,wait_messages, item_string); // Enter the mode specified by the argument. @@ -2499,32 +2474,32 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate state, int numMessageReceived) { - //LOG(PROG_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); + //LOG(ALLB_LOG, LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); int i=0; pthread_mutex_lock(&aq_data->active_thread.thread_mutex); while( ++i <= numMessageReceived) { - LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for state change to '%d' for '%s' \n",i,numMessageReceived,button->led->state,button->name); + LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for state change to '%d' for '%s' \n",i,numMessageReceived,button->led->state,button->name); if (button->led->state == state) { - LOG(PROG_LOG, LOG_INFO, "Button State =%d for %s\n",state,button->name); + LOG(ALLB_LOG, LOG_INFO, "Button State =%d for %s\n",state,button->name); break; } - //LOG(PROG_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "looking for '%s' received message '%s'\n",message,aq_data->last_message); pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //LOG(PROG_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(ALLB_LOG, LOG_DEBUG, "loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); } pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); if (numMessageReceived >= i) { - //LOG(PROG_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); - LOG(PROG_LOG, LOG_DEBUG, "did not find state '%d' for '%s'\n",button->led->state,button->name); + //LOG(ALLB_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); + LOG(ALLB_LOG, LOG_DEBUG, "did not find state '%d' for '%s'\n",button->led->state,button->name); return false; } - LOG(PROG_LOG, LOG_DEBUG, "found state '%d' for '%s'\n",button->led->state,button->name); + LOG(ALLB_LOG, LOG_DEBUG, "found state '%d' for '%s'\n",button->led->state,button->name); return true; } diff --git a/aq_programmer.h b/aq_programmer.h index 65ebb543..26430335 100644 --- a/aq_programmer.h +++ b/aq_programmer.h @@ -52,15 +52,20 @@ typedef enum { AQ_GET_PROGRAMS, AQ_SET_LIGHTPROGRAM_MODE, AQ_SET_LIGHTCOLOR_MODE, - AQ_PDA_INIT, AQ_SET_SWG_PERCENT, AQ_PDA_DEVICE_STATUS, AQ_PDA_DEVICE_ON_OFF, AQ_GET_AUX_LABELS, - AQ_PDA_WAKE_INIT, AQ_SET_BOOST, AQ_SET_PUMP_RPM, AQ_SET_PUMP_VS_PROGRAM, + // ******** Delimiter make sure to change MAX/MIN below + // NSF Need to add Specific ALL Button ones here + // ******** Delimiter make sure to change MAX/MIN below + // NSF Need to add ALL Specific PDA ones here + AQ_PDA_INIT, + AQ_PDA_WAKE_INIT, + // ******** Delimiter make sure to change MAX/MIN below AQ_SET_ONETOUCH_PUMP_RPM, AQ_SET_ONETOUCH_MACRO, AQ_GET_ONETOUCH_SETPOINTS, @@ -71,6 +76,7 @@ typedef enum { AQ_SET_ONETOUCH_TIME, AQ_SET_ONETOUCH_BOOST, AQ_SET_ONETOUCH_SWG_PERCENT, + // ******** Delimiter make sure to change MAX/MIN below AQ_SET_IAQTOUCH_PUMP_RPM, AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM, AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, @@ -85,13 +91,33 @@ typedef enum { AQ_SET_IAQTOUCH_SET_TIME, AQ_SET_IAQTOUCH_DEVICE_ON_OFF, AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE, + // ******** Delimiter make sure to change MAX/MIN below AQ_GET_RSSADAPTER_SETPOINTS, AQ_SET_RSSADAPTER_POOL_HEATER_TEMP, AQ_SET_RSSADAPTER_SPA_HEATER_TEMP, AQ_ADD_RSSADAPTER_POOL_HEATER_TEMP, - AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP + AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP, + // ******** Delimiter make sure to change MAX/MIN below } program_type; +#define AQP_GENERIC_MIN AQ_GET_POOL_SPA_HEATER_TEMPS +#define AQP_GENERIC_MAX AQ_SET_PUMP_VS_PROGRAM + +#define AQP_ALLBUTTON_MIN AQP_NULL +#define AQP_ALLBUTTONL_MAX AQP_NULL + +#define AQP_PDA_MIN AQ_PDA_INIT +#define AQP_PDA_MAX AQ_PDA_WAKE_INIT + +#define AQP_ONETOUCH_MIN AQ_SET_ONETOUCH_PUMP_RPM +#define AQP_ONETOUCH_MAX AQ_SET_ONETOUCH_SWG_PERCENT + +#define AQP_IAQTOUCH_MIN AQ_SET_IAQTOUCH_PUMP_RPM +#define AQP_IAQTOUCH_MAX AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE + +#define AQP_RSSADAPTER_MIN AQ_GET_RSSADAPTER_SETPOINTS +#define AQP_RSSADAPTER_MAX AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP + struct programmingThreadCtrl { pthread_t thread_id; diff --git a/aq_serial.c b/aq_serial.c index 503757bf..def0cbbb 100644 --- a/aq_serial.c +++ b/aq_serial.c @@ -46,6 +46,9 @@ ioctl(fd, TIOCSSERIAL, &serial); */ +// Default to send command with leading NUL, this changes that +//#define SEND_CMD_WITH_TRAILING_NUL + //#define BLOCKING_MODE static bool _blocking_mode = false; @@ -60,7 +63,45 @@ void send_packet(int fd, unsigned char *packet, int length); -const char* get_packet_type(unsigned char* packet , int length) +const char* get_pentair_packet_type(unsigned char* packet , int length) +{ + static char buf[15]; + + if (length <= 0 ) + return ""; + + switch (packet[PEN_PKT_CMD]) { + case PEN_CMD_SPEED: + if (packet[PEN_PKT_DEST]== PEN_DEV_MASTER) + return "VSP SetSpeed rtn"; + else + return "VSP SetSpeed"; + break; + case PEN_CMD_REMOTECTL: + if (packet[PEN_PKT_DEST]== PEN_DEV_MASTER) + return "VSP RemoteCtl rtn"; + else + return "VSP RemoteCtl"; + break; + case PEN_CMD_POWER: + if (packet[PEN_PKT_DEST]== PEN_DEV_MASTER) + return "VSP SetPower rtn"; + else + return "VSP SetPower"; + break; + case PEN_CMD_STATUS: + if (packet[PEN_PKT_DEST]== PEN_DEV_MASTER) + return "VSP Status"; + else + return "VSP GetStatus"; + break; + default: + sprintf(buf, "Unknown '0x%02hhx'", packet[PEN_PKT_CMD]); + return buf; + break; + } +} +const char* get_jandy_packet_type(unsigned char* packet , int length) { static char buf[15]; @@ -191,6 +232,16 @@ const char* get_packet_type(unsigned char* packet , int length) } } +const char* get_packet_type(unsigned char* packet , int length) +{ + if (getProtocolType(packet)==PENTAIR) { + return get_pentair_packet_type(packet, length); + } + + return get_jandy_packet_type(packet, length); +} + + // Generate and return checksum of packet. int generate_checksum(unsigned char* packet, int length) { @@ -424,9 +475,6 @@ int unlock_port(int fd) // https://www.cmrr.umn.edu/~strupp/serial.html#2_5_2 // http://unixwiz.net/techtips/termios-vmin-vtime.html -//#define OLD_SERIAL_INIT -#ifndef OLD_SERIAL_INIT - // Unless AQ_RS_EXTRA_OPTS is defined, blocking will always be true int _init_serial_port(const char* tty, bool blocking, bool readahead) @@ -513,60 +561,7 @@ int _init_serial_port(const char* tty, bool blocking, bool readahead) return fd; } -#else //OLD_SERIAL_INIT -int _init_serial_port(const char* tty, bool blocking, bool readahead) // readahead ignored in this implimentation -{ - - long BAUD = B9600; - long DATABITS = CS8; - long STOPBITS = 0; - long PARITYON = 0; - long PARITY = 0; - - struct termios newtio; //place for old and new port settings for serial port - - _blocking_mode = blocking; - - //int fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK); - int fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY); - if (fd < 0) { - LOG(RSSD_LOG,LOG_ERR, "Unable to open port: %s\n", tty); - return -1; - } - - LOG(RSSD_LOG,LOG_DEBUG, "Openeded serial port %s\n",tty); - - if (_blocking_mode) { - // http://unixwiz.net/techtips/termios-vmin-vtime.html - // Not designed behaviour, but it's what we need. - fcntl(fd, F_SETFL, 0); - newtio.c_cc[VMIN]= 1; - //newtio.c_cc[VTIME]= 0; // This will wait indefinatly. (not the best if panel / rs485 adapter is down) - newtio.c_cc[VTIME]= 50; // (1 to 255) 1 = 0.1 sec, 255 = 25.5 sec - LOG(RSSD_LOG,LOG_INFO, "Set serial port %s to blocking mode\n",tty); - } else { - int flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK | O_NDELAY); - newtio.c_cc[VMIN]= 0; - newtio.c_cc[VTIME]= 1; // This should be 0 if we have readahead before write - LOG(RSSD_LOG,LOG_INFO, "Set serial port %s to non blocking mode\n",tty); - } - - tcgetattr(fd, &_oldtio); // save current port settings - // set new port settings for canonical input processing - newtio.c_cflag = BAUD | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD; - newtio.c_iflag = IGNPAR; - newtio.c_lflag = 0; // ICANON; - newtio.c_oflag = 0; - - tcflush(fd, TCIFLUSH); - tcsetattr(fd, TCSANOW, &newtio); - - LOG(RSSD_LOG,LOG_DEBUG, "Set serial port %s io attributes\n",tty); - return fd; -} -#endif void close_blocking_serial_port() @@ -656,13 +651,15 @@ void send_pentair_command(int fd, unsigned char *packet_buffer, int size) packet[++i] = NUL; // Checksum packet[++i] = NUL; // Checksum generate_pentair_checksum(&packet[1], i); - packet[++i] = NUL; + //packet[++i] = NUL; //logPacket(packet, i); - send_packet(fd,packet,i); + send_packet(fd,packet,++i); } +#ifndef SEND_CMD_WITH_TRAILING_NUL + void send_jandy_command(int fd, unsigned char *packet_buffer, int size) { unsigned char packet[AQ_MAXPKTLEN]; @@ -677,6 +674,26 @@ void send_jandy_command(int fd, unsigned char *packet_buffer, int size) packet[i] = packet_buffer[i-3]; } + packet[++i] = DLE; + packet[++i] = ETX; + + packet[i-2] = generate_checksum(packet, i+1); + + send_packet(fd,packet,++i); +} +#else +void send_jandy_command(int fd, unsigned char *packet_buffer, int size) +{ + unsigned char packet[AQ_MAXPKTLEN]; + int i=0; + + packet[0] = DLE; + packet[1] = STX; + + for (i=2; i-2 < size; i++) { + packet[i] = packet_buffer[i-2]; + } + packet[++i] = DLE; packet[++i] = ETX; packet[++i] = NUL; @@ -685,7 +702,7 @@ void send_jandy_command(int fd, unsigned char *packet_buffer, int size) send_packet(fd,packet,++i); } - +#endif /* unsigned char tp[] = {PCOL_PENTAIR, 0x07, 0x0F, 0x10, 0x08, 0x0D, 0x55, 0x55, 0x5B, 0x2A, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00}; send_command(0, tp, 19); @@ -793,7 +810,8 @@ void send_packet(int fd, unsigned char *packet, int length) // MAYBE Change this back to debug serial LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial write %d bytes\n",length-2); //LOG(RSSD_LOG,LOG_DEBUG, "Serial write %d bytes, type 0x%02hhx cmd 0x%02hhx\n",length-2,packet[5],packet[6]); - logPacketWrite(&packet[1], length-2); + if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL) + logPacketWrite(&packet[1], length-2); /* if (getLogLevel(PDA_LOG) == LOG_DEBUG) { char buff[1024]; @@ -814,39 +832,74 @@ void send_packet(int fd, unsigned char *packet, int length) tcdrain(fd); // Make sure buffer has been sent. //if (_aqconfig_.frame_delay > 0) { +#ifndef SERIAL_LOGGER + if (_aqconfig_.frame_delay > 0) { timespec_subtract(&elapsed_time, &now, &last_serial_read_time); - LOG(RSSD_LOG, LOG_DEBUG, "Time from recv to %s send is %ld.%09ld sec\n", - (_blocking_mode?"blocking":"non-blocking"), elapsed_time.tv_sec, - elapsed_time.tv_nsec); + LOG(RSTM_LOG, LOG_DEBUG, "Time from recv to %s send is %.3f sec\n", + (_blocking_mode?"blocking":"non-blocking"), + roundf3(timespec2float(&elapsed_time))); + } +#endif //} } +#ifndef SEND_CMD_WITH_TRAILING_NUL void _send_ack(int fd, unsigned char ack_type, unsigned char command) { - const int length = 11; + //const int length = 11; + int length = 10; // Default null ack with checksum generated, don't mess with it, just over right unsigned char ackPacket[] = { NUL, DLE, STX, DEV_MASTER, CMD_ACK, NUL, NUL, 0x13, DLE, ETX, NUL }; + //unsigned char ackPacket[] = { NUL, DLE, STX, DEV_MASTER, CMD_ACK, NUL, NUL, 0x13, DLE, ETX }; + + // To overcome Pentair VSP bug in Jandy control panel, we need to NOT send trailing NUL on + // a normal ACK, but sent the trailing NUL on in ack with command. + // Always send trailing NUL causes VSP to loose connection + // Never sending trailing NUL causes come commands to be missed. // Update the packet and checksum if command argument is not NUL. if(command != NUL || ack_type != NUL) { //ackPacket[5] = 0x00 normal, 0x03 some pause, 0x01 some pause ending (0x01 = Screen Busy (also return from logn message)) ackPacket[5] = ack_type; ackPacket[6] = command; - ackPacket[7] = generate_checksum(ackPacket, length-1); + ackPacket[7] = generate_checksum(ackPacket, length); if (command == DLE) { // We shuld probably also check the ack type as well, just for future proofing. // 0x10(DLE) that's not part of the headder or footer needs to be escaped AFTER with NUL, so shif everyting uo one ackPacket[8] = ackPacket[7]; // move the caculated checksum ackPacket[7] = NUL; // escape the DLE ackPacket[9] = DLE; // add new end sequence - ackPacket[10] = ETX; // add new end sequence + ackPacket[10] = ETX; // add new end sequence + length = 11; } } + send_packet(fd, ackPacket, length); +} +#else +void _send_ack(int fd, unsigned char ack_type, unsigned char command) +{ + //const int length = 11; + int length = 9; + // Default null ack with checksum generated, don't mess with it, just over right + unsigned char ackPacket[] = { DLE, STX, DEV_MASTER, CMD_ACK, NUL, NUL, 0x13, DLE, ETX, NUL }; - //printf("***Send ACK (%s) ***\n",(ack_type==ACK_NORMAL?"Normal":(ack_type==ACK_SCREEN_BUSY?"ScreenBusy":"ScreenBusyDisplay")) ); - + if(command != NUL || ack_type != NUL) { + //ackPacket[5] = 0x00 normal, 0x03 some pause, 0x01 some pause ending (0x01 = Screen Busy (also return from logn message)) + ackPacket[4] = ack_type; + ackPacket[5] = command; + ackPacket[6] = generate_checksum(ackPacket, length); + if (command == DLE) { // We shuld probably also check the ack type as well, just for future proofing. + // 0x10(DLE) that's not part of the headder or footer needs to be escaped AFTER with NUL, so shif everyting uo one + ackPacket[7] = ackPacket[7]; // move the caculated checksum + ackPacket[6] = NUL; // escape the DLE + ackPacket[8] = DLE; // add new end sequence + ackPacket[9] = ETX; // add new end sequence + length = 10; + } + } send_packet(fd, ackPacket, length); } +#endif // SEND_CMD_WITH_TRAILING_NUL void send_ack(int fd, unsigned char command) { @@ -885,6 +938,8 @@ int get_packet(int fd, unsigned char* packet) //bool lastByteDLE = false; int PentairPreCnt = 0; int PentairDataCnt = -1; + struct timespec packet_elapsed; + struct timespec packet_end_time; memset(packet, 0, AQ_MAXPKTLEN); @@ -1053,7 +1108,19 @@ int get_packet(int fd, unsigned char* packet) } //if (_aqconfig_.frame_delay > 0) { - clock_gettime(CLOCK_REALTIME, &last_serial_read_time); + + if (_aqconfig_.frame_delay > 0 || getLogLevel(RSTM_LOG) >= LOG_DEBUG) { + clock_gettime(CLOCK_REALTIME, &packet_end_time); + if (getLogLevel(RSTM_LOG) >= LOG_DEBUG) { + timespec_subtract(&packet_elapsed, &packet_end_time, &last_serial_read_time); + LOG(RSTM_LOG, LOG_DEBUG, "Time between packets (%.3f sec)\n", roundf3(timespec2float(&packet_elapsed)) ); + } + if (_aqconfig_.frame_delay > 0) { + memcpy(&last_serial_read_time, &packet_end_time, sizeof(struct timespec)); + } + } + + //clock_gettime(CLOCK_REALTIME, &last_serial_read_time); //} LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index); if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL) diff --git a/aq_serial.h b/aq_serial.h index 8b639d43..a2bac42c 100644 --- a/aq_serial.h +++ b/aq_serial.h @@ -62,16 +62,30 @@ #define PP3 0xFF #define PP4 0xA5 -#define PEN_CMD_STATUS 0x07 +#define PEN_DEV_MASTER 0x10 + +#define PEN_CMD_SPEED 0x01 +#define PEN_CMD_REMOTECTL 0x04 +#define PEN_CMD_POWER 0x06 +#define PEN_CMD_STATUS 0x07 + + #define PEN_PKT_FROM 6 #define PEN_PKT_DEST 5 #define PEN_PKT_CMD 7 -#define PEN_HI_B_RPM 14 -#define PEN_LO_B_RPM 15 -#define PEN_HI_B_WAT 12 -#define PEN_LO_B_WAT 13 +// Pentair VSP +#define PEN_MODE 10 +#define PEN_DRIVE_STATE 11 +#define PEN_HI_B_WAT 12 +#define PEN_LO_B_WAT 13 +#define PEN_HI_B_RPM 14 +#define PEN_LO_B_RPM 15 +#define PEN_FLOW 16 +#define PEN_PPC 17 // Pump pressure curve +#define PEN_HI_B_STATUS 20 // The current status value of the pump. following values: ok, filterWarning, overCurrent, priming, systemBlocked, generalAlarm, powerOutage, overCurrent2, overVoltage, commLost +#define PEN_LO_B_STATUS 21 // END Pentair #define AQ_MINPKTLEN 5 diff --git a/aq_timer.c b/aq_timer.c index 6e5757ba..9f1db6e0 100644 --- a/aq_timer.c +++ b/aq_timer.c @@ -16,6 +16,7 @@ struct timerthread { pthread_mutex_t thread_mutex; pthread_cond_t thread_cond; aqkey *button; + int deviceIndex; struct aqualinkdata *aq_data; int duration_min; struct timespec timeout; @@ -56,9 +57,10 @@ int get_timer_left(aqkey *button) return 0; } -void clear_timer(struct aqualinkdata *aq_data, aqkey *button) +void clear_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex) { - struct timerthread *t_ptr = find_timerthread(button); + //struct timerthread *t_ptr = find_timerthread(button); + struct timerthread *t_ptr = find_timerthread(&aq_data->aqbuttons[deviceIndex]); if (t_ptr != NULL) { LOG(TIMR_LOG, LOG_INFO, "Clearing timer for '%s'\n",t_ptr->button->name); @@ -67,8 +69,9 @@ void clear_timer(struct aqualinkdata *aq_data, aqkey *button) } } -void start_timer(struct aqualinkdata *aq_data, aqkey *button, int duration) +void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex, int duration) { + aqkey *button = &aq_data->aqbuttons[deviceIndex]; struct timerthread *t_ptr = find_timerthread(button); if (t_ptr != NULL) { @@ -77,23 +80,11 @@ void start_timer(struct aqualinkdata *aq_data, aqkey *button, int duration) pthread_cond_broadcast(&t_ptr->thread_cond); return; } - /* - struct timerthread *t_ptr; - - if (_timerthread_ll != NULL) { - for (t_ptr = _timerthread_ll; t_ptr != NULL; t_ptr = t_ptr->next) { - if (t_ptr->button == button) { - LOG(TIMR_LOG, LOG_INFO, "already active for '%s', resetting\n",t_ptr->button->name); - t_ptr->duration_min = duration; - pthread_cond_broadcast(&t_ptr->thread_cond); - return; - } - } - }*/ struct timerthread *tmthread = calloc(1, sizeof(struct timerthread)); tmthread->aq_data = aq_data; tmthread->button = button; + tmthread->deviceIndex = deviceIndex; tmthread->thread_id = 0; tmthread->duration_min = duration; tmthread->next = NULL; @@ -147,7 +138,8 @@ void *timer_worker( void *ptr ) } else { // crap way to do this, need to use net_service logic in teh future, but should never actually get here LOG(TIMR_LOG, LOG_NOTICE, "turning on '%s'\n",tmthread->button->name); - aq_send_cmd(tmthread->button->code); + //aq_send_cmd(tmthread->button->code); + panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); } } @@ -173,13 +165,16 @@ void *timer_worker( void *ptr ) LOG(TIMR_LOG, LOG_NOTICE, "End timer for '%s'\n",tmthread->button->name); if (tmthread->button->led->state != OFF) { - LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name); + LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name); +/* #ifdef AQ_PDA if (isPDA_PANEL) create_PDA_on_off_request(tmthread->button, false); else #endif aq_send_cmd(tmthread->button->code); +*/ + panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); } else { LOG(TIMR_LOG, LOG_INFO, "Timer waking '%s' is already off\n",tmthread->button->name); } diff --git a/aq_timer.h b/aq_timer.h index 0dd5630b..90b75888 100644 --- a/aq_timer.h +++ b/aq_timer.h @@ -4,9 +4,9 @@ #include "aqualink.h" -void start_timer(struct aqualinkdata *aq_data, aqkey *button, int duration); +void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex, int duration); int get_timer_left(aqkey *button); -void clear_timer(struct aqualinkdata *aq_data, aqkey *button); +void clear_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceIndex); // Not best place for this, but leave it here so all requests are in net services, this is forward decleration of function in net_services.c #ifdef AQ_PDA void create_PDA_on_off_request(aqkey *button, bool isON); diff --git a/aqualink.h b/aqualink.h index b0508f7d..f63e3287 100644 --- a/aqualink.h +++ b/aqualink.h @@ -167,6 +167,11 @@ typedef struct pumpd protocolType prclType; aqkey *button; //bool updated; + // Other VSP values read directly from RS485 + int mode; // 0 local control, 1 remote control + //int driveState; // Haven't figured out what this is yet + int status; + int pressureCurve; } pump_detail; // color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite) @@ -185,7 +190,9 @@ typedef enum { NET_MQTT=0, NET_API, NET_WS, - NET_DZMQTT} request_source; + NET_DZMQTT, + NET_TIMER // Not used yet, need to change aq_timer.c +} request_source; typedef struct clightd { diff --git a/aqualinkd.c b/aqualinkd.c index 0d57192f..de048e5d 100644 --- a/aqualinkd.c +++ b/aqualinkd.c @@ -385,6 +385,7 @@ void _processMessage(char *message, bool reset) //static int swg_msg_count = 0; //static int boost_msg_count = 0; static int16_t msg_loop = 0; + static aqledstate default_frz_protect_state = OFF; // NSF replace message with msg #ifdef AQ_RS16 int16_t rs16; @@ -392,7 +393,7 @@ void _processMessage(char *message, bool reset) //msg = stripwhitespace(message); //strcpy(_aqualink_data.last_message, msg); - //LOG(AQRS_LOG,LOG_INFO, "RS Message :- '%s'\n", msg); + //LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg); @@ -404,7 +405,7 @@ void _processMessage(char *message, bool reset) if (!reset) { msg = stripwhitespace(message); strcpy(_aqualink_data.last_message, msg); - LOG(AQRS_LOG,LOG_INFO, "RS Message :- '%s'\n", 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 _aqualink_data.service_mode_state = OFF; } else { @@ -414,7 +415,7 @@ void _processMessage(char *message, bool reset) // Anything that wasn't on during the last set of messages, turn off if ((msg_loop & MSG_FREEZE) != MSG_FREEZE) - _aqualink_data.frz_protect_state = OFF; + _aqualink_data.frz_protect_state = default_frz_protect_state; if ((msg_loop & MSG_SERVICE) != MSG_SERVICE && (msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) { @@ -434,16 +435,16 @@ void _processMessage(char *message, bool reset) if (_aqualink_data.swg_percent != 0 || _aqualink_data.swg_led_state == ON) { // Something is wrong here. Let's check pump, if on set SWG to 0, if off turn SWE off if ( _aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF) { - LOG(AQRS_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); + LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); setSWGoff(&_aqualink_data); } else { - LOG(AQRS_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n"); + LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n"); changeSWGpercent(&_aqualink_data, 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 ( _aqualink_data.aqbuttons[PUMP_INDEX].led->state == ON) { - LOG(AQRS_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); + LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n"); //changeSWGpercent(&_aqualink_data, 0); setSWGenabled(&_aqualink_data); } @@ -515,6 +516,7 @@ void _processMessage(char *message, bool reset) //LOG(AQUA_LOG,LOG_DEBUG, "frz protect long message: %s", &message[28]); _aqualink_data.frz_protect_set_point = atoi(message + 28); _aqualink_data.frz_protect_state = ENABLE; + default_frz_protect_state = ENABLE; if (_aqualink_data.temp_units == UNKNOWN) setUnits(msg); @@ -551,7 +553,7 @@ void _processMessage(char *message, bool reset) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } else if (stristr(msg, LNG_MSG_WATER_TEMP1_SET) != NULL) @@ -564,7 +566,7 @@ void _processMessage(char *message, bool reset) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } else if (stristr(msg, LNG_MSG_WATER_TEMP2_SET) != NULL) @@ -577,13 +579,13 @@ void _processMessage(char *message, bool reset) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } else if (stristr(msg, LNG_MSG_SERVICE_ACTIVE) != NULL) { if (_aqualink_data.service_mode_state == OFF) - LOG(AQRS_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n"); + LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n"); _aqualink_data.service_mode_state = ON; msg_loop |= MSG_SERVICE; //service_msg_count = 0; @@ -591,7 +593,7 @@ void _processMessage(char *message, bool reset) else if (stristr(msg, LNG_MSG_TIMEOUT_ACTIVE) != NULL) { if (_aqualink_data.service_mode_state == OFF) - LOG(AQRS_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n"); + LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n"); _aqualink_data.service_mode_state = FLASH; msg_loop |= MSG_TIMEOUT; //service_msg_count = 0; @@ -648,16 +650,16 @@ void _processMessage(char *message, bool reset) // Setting time takes a long time, so don't try until we have all other programmed data. if (_initWithRS == true && strlen(_aqualink_data.date) > 1 && checkAqualinkTime() != true) { - LOG(AQRS_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", _aqualink_data.time, _aqualink_data.date); + LOG(ALLB_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); } else if (_initWithRS == false || _aqconfig_.sync_panel_time == false) { - LOG(AQRS_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", _aqualink_data.time, _aqualink_data.date); + LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", _aqualink_data.time, _aqualink_data.date); } else if (_initWithRS == true) { - LOG(AQRS_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", _aqualink_data.time, _aqualink_data.date); + LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", _aqualink_data.time, _aqualink_data.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. @@ -675,8 +677,8 @@ void _processMessage(char *message, bool reset) strcpy(_aqualink_data.version, msg); rsm_get_revision(_aqualink_data.revision, _aqualink_data.version, strlen(_aqualink_data.version)); //_gotREV = true; - LOG(AQRS_LOG,LOG_NOTICE, "Control Panel version %s\n", _aqualink_data.version); - LOG(AQRS_LOG,LOG_NOTICE, "Control Panel revision %s\n", _aqualink_data.revision); + LOG(ALLB_LOG,LOG_NOTICE, "Control Panel version %s\n", _aqualink_data.version); + LOG(ALLB_LOG,LOG_NOTICE, "Control Panel revision %s\n", _aqualink_data.revision); if (_initWithRS == false) { //LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n"); @@ -687,7 +689,7 @@ void _processMessage(char *message, bool reset) } else if (stristr(msg, " TURNS ON") != NULL) { - LOG(AQRS_LOG,LOG_NOTICE, "Program data '%s'\n", msg); + LOG(ALLB_LOG,LOG_NOTICE, "Program data '%s'\n", msg); } else if (_aqconfig_.override_freeze_protect == TRUE && strncasecmp(msg, "Press Enter* to override Freeze Protection with", 47) == 0) { @@ -727,9 +729,9 @@ void _processMessage(char *message, bool reset) // Aux1: on panel = Button 3 in aqualinkd (button 2 in array) if (strncasecmp(msg+ni+3, "No Label", 8) != 0) { _aqualink_data.aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2)); - LOG(AQRS_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label); + LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label); } else { - LOG(AQRS_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label); + LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label); } //_aqualink_data.aqbuttons[labelid + 1].label = cleanalloc(msg + 5); } @@ -753,7 +755,7 @@ void _processMessage(char *message, bool reset) } else { - LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg); + LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg); //_aqualink_data.display_message = msg; //if (in_programming_mode(&_aqualink_data) == false && _aqualink_data.simulate_panel == false && if (in_programming_mode(&_aqualink_data) == false && @@ -780,7 +782,7 @@ void _processMessage(char *message, bool reset) //ascii(_aqualink_data.last_display_message, msg); - //LOG(AQRS_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop); + //LOG(ALLB_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop); // We processed the next message, kick any threads waiting on the message. //printf ("Message kicking\n"); @@ -797,12 +799,14 @@ bool process_packet(unsigned char *packet, int length) static char message[AQ_MSGLONGLEN + 1]; static int processing_long_msg = 0; + LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "process_packer()\n", length); + // Check packet against last check if different. // Should only use the checksum, not whole packet since it's status messages. /* if ( packet[PKT_CMD] == CMD_STATUS && (memcmp(packet, last_packet, length) == 0)) { - LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length); + LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length); return rtn; } else @@ -827,7 +831,7 @@ bool process_packet(unsigned char *packet, int length) if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(&_aqualink_data) ) { - LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length); + LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length); return false; } else @@ -844,15 +848,15 @@ bool process_packet(unsigned char *packet, int length) processMessage(message); } - LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length); + LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length); switch (packet[PKT_CMD]) { case CMD_ACK: - //LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "RS Received ACK length %d.\n", length); + //LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received ACK length %d.\n", length); break; case CMD_STATUS: - //LOG(AQRS_LOG,LOG_DEBUG_SERIAL, "RS Received STATUS length %d.\n", length); + //LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received STATUS length %d.\n", length); memcpy(_aqualink_data.raw_status, packet + 4, AQ_PSTLEN); processLEDstate(); if (_aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF) @@ -887,14 +891,14 @@ bool process_packet(unsigned char *packet, int length) //strncpy(message, (char *)packet + PKT_DATA + 1, AQ_MSGLEN); rsm_strncpy(message, packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN); processing_long_msg = index; - //LOG(AQRS_LOG,LOG_ERR, "Message %s\n",message); + //LOG(ALLB_LOG,LOG_ERR, "Message %s\n",message); } else { //strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (char *)packet + PKT_DATA + 1, AQ_MSGLEN); //rsm_strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN); rsm_strncpy(&message[( (index-1) * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN); - //LOG(AQRS_LOG,LOG_ERR, "Long Message %s\n",message); + //LOG(ALLB_LOG,LOG_ERR, "Long Message %s\n",message); if (++processing_long_msg != index) { - LOG(AQRS_LOG,LOG_DEBUG, "Long message index %d doesn't match buffer %d\n",index,processing_long_msg); + LOG(ALLB_LOG,LOG_DEBUG, "Long message index %d doesn't match buffer %d\n",index,processing_long_msg); //printf("RSM Long message index %d doesn't match buffer %d\n",index,processing_long_msg); } #ifdef PROCESS_INCOMPLETE_MESSAGES @@ -908,24 +912,24 @@ bool process_packet(unsigned char *packet, int length) // MOVED FROM LINE 701 see if less errors //kick_aq_program_thread(&_aqualink_data, ALLBUTTON); - LOG(AQRS_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message); + LOG(ALLB_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message); processMessage(message); // This will kick thread } } break; case CMD_PROBE: - LOG(AQRS_LOG,LOG_DEBUG, "RS Received PROBE length %d.\n", length); + LOG(ALLB_LOG,LOG_DEBUG, "RS Received PROBE length %d.\n", length); //LOG(AQUA_LOG,LOG_INFO, "Synch'ing with Aqualink master device...\n"); rtn = false; break; case CMD_MSG_LOOP_ST: - LOG(AQRS_LOG,LOG_INFO, "RS Received message loop start\n"); + LOG(ALLB_LOG,LOG_INFO, "RS Received message loop start\n"); processMessageReset(); rtn = false; break; default: - LOG(AQRS_LOG,LOG_INFO, "RS Received unknown packet, 0x%02hhx\n", packet[PKT_CMD]); + LOG(ALLB_LOG,LOG_INFO, "RS Received unknown packet, 0x%02hhx\n", packet[PKT_CMD]); rtn = false; break; } @@ -1091,7 +1095,7 @@ int main(int argc, char *argv[]) // Any debug logging masks //addDebugLogMask(IAQT_LOG); //addDebugLogMask(ONET_LOG); - //addDebugLogMask(AQRS_LOG); + //addDebugLogMask(ALLB_LOG); //addDebugLogMask(PDA_LOG); //addDebugLogMask(NET_LOG); //addDebugLogMask(AQUA_LOG); @@ -1559,6 +1563,10 @@ void main_loop() _aqualink_data.pumps[i].rpm = TEMP_UNKNOWN; _aqualink_data.pumps[i].gpm = TEMP_UNKNOWN; _aqualink_data.pumps[i].watts = TEMP_UNKNOWN; + _aqualink_data.pumps[i].mode = TEMP_UNKNOWN; + //_aqualink_data.pumps[i].driveState = TEMP_UNKNOWN; + _aqualink_data.pumps[i].status = TEMP_UNKNOWN; + _aqualink_data.pumps[i].pressureCurve = TEMP_UNKNOWN; } if (_aqconfig_.force_swg == true) { @@ -1900,7 +1908,7 @@ void main_loop() { if (getLogLevel(AQUA_LOG) >= LOG_DEBUG) { LOG(AQUA_LOG,LOG_DEBUG, "RS received packet of type %s length %d\n", get_packet_type(packet_buffer, packet_length), packet_length); - logPacketRead(packet_buffer, packet_length); + //logPacketRead(packet_buffer, packet_length); } _aqualink_data.updated = process_packet(packet_buffer, packet_length); diff --git a/devices_jandy.c b/devices_jandy.c index 27d967f2..df3c3c0b 100644 --- a/devices_jandy.c +++ b/devices_jandy.c @@ -45,7 +45,7 @@ bool processJandyPacket(unsigned char *packet_buffer, int packet_length, struct { if (interestedInNextAck == DRS_SWG) { - rtn = processPacketFromSWG(packet_buffer, packet_length, aqdata); + rtn = processPacketFromSWG(packet_buffer, packet_length, aqdata, previous_packet_to); } else if (interestedInNextAck == DRS_EPUMP) { @@ -71,11 +71,11 @@ bool processJandyPacket(unsigned char *packet_buffer, int packet_length, struct { if (interestedInNextAck == DRS_SWG && aqdata->ar_swg_device_status != SWG_STATUS_OFF) { // SWG Offline - processMissingAckPacketFromSWG(previous_packet_to, aqdata); + processMissingAckPacketFromSWG(previous_packet_to, aqdata, previous_packet_to); } else if (interestedInNextAck == DRS_EPUMP) { // ePump offline - processMissingAckPacketFromJandyPump(previous_packet_to, aqdata); + processMissingAckPacketFromJandyPump(previous_packet_to, aqdata, previous_packet_to); } interestedInNextAck = DRS_NONE; previous_packet_to = NUL; @@ -177,10 +177,20 @@ bool processPacketToSWG(unsigned char *packet, int packet_length, struct aqualin return changedAnything; } -bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqualinkdata *aqdata) { +unsigned char _SWG_ID = NUL; + +bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqualinkdata *aqdata, const unsigned char previous_packet_to) { bool changedAnything = false; _swg_noreply_cnt = 0; + // Capture the SWG ID. We could have more than one, but for the moment AqualinkD only supports one so we'll pick the first one. + if (_SWG_ID == NUL) { + _SWG_ID = previous_packet_to; + } else if (_SWG_ID != NUL && _SWG_ID != previous_packet_to) { + LOG(DJAN_LOG, LOG_WARNING, "We have two SWG, AqualinkD only supports one. using ID 0x%02hhx, ignoring 0x%02hhx\n", _SWG_ID, previous_packet_to); + return changedAnything; + } + // Only log if we are jandy debug move and not serial (otherwise it'll print twice) if (getLogLevel(DJAN_LOG) == LOG_DEBUG && getLogLevel(RSSD_LOG) < LOG_DEBUG ) { char buff[1024]; @@ -211,11 +221,16 @@ bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqual return changedAnything; } -void processMissingAckPacketFromSWG(unsigned char destination, struct aqualinkdata *aqdata) +void processMissingAckPacketFromSWG(unsigned char destination, struct aqualinkdata *aqdata, const unsigned char previous_packet_to) { // SWG_STATUS_UNKNOWN means we have never seen anything from SWG, so leave as is. // IAQTOUCH & ONETOUCH give us AQUAPURE=0 but ALLBUTTON doesn't, so only turn off if we are not in extra device mode. // NSF Need to check that we actually use 0 from IAQTOUCH & ONETOUCH + if (_SWG_ID != previous_packet_to) { + //LOG(DJAN_LOG, LOG_DEBUG, "Ignoring SWG no reply from 0x%02hhx\n", previous_packet_to); + return; + } + if ( aqdata->ar_swg_device_status != SWG_STATUS_UNKNOWN && isIAQT_ENABLED == false && isONET_ENABLED == false ) { if ( _swg_noreply_cnt < 3 ) { @@ -250,9 +265,9 @@ void setSWGdeviceStatus(struct aqualinkdata *aqdata, emulation_type requester, u } */ // If we are reading state directly from RS458, then ignore everything else. - if ( READ_RSDEV_SWG && requester != JANDY_DEVICE ) { - return; - } + //if ( READ_RSDEV_SWG && requester != JANDY_DEVICE ) { + // return; + //} if ((aqdata->ar_swg_device_status == status) || (last_status == status)) { //LOG(DJAN_LOG, LOG_DEBUG, "Set SWG device state to '0x%02hhx', request from %d\n", aqdata->ar_swg_device_status, requester); @@ -614,7 +629,7 @@ bool processPacketFromJandyPump(unsigned char *packet_buffer, int packet_length, return false; } -void processMissingAckPacketFromJandyPump(unsigned char destination, struct aqualinkdata *aqdata) +void processMissingAckPacketFromJandyPump(unsigned char destination, struct aqualinkdata *aqdata, const unsigned char previous_packet_to) { // Do nothing for the moment. return; diff --git a/devices_jandy.h b/devices_jandy.h index aaf427ed..44b97487 100644 --- a/devices_jandy.h +++ b/devices_jandy.h @@ -8,11 +8,11 @@ bool processJandyPacket(unsigned char *packet_buffer, int packet_length, struct aqualinkdata *aqdata); bool processPacketToSWG(unsigned char *packet, int packet_length, struct aqualinkdata *aqdata, int swg_zero_ignore); -bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqualinkdata *aqdata); +bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqualinkdata *aqdata, const unsigned char previous_packet_to); bool processPacketToJandyPump(unsigned char *packet_buffer, int packet_length, struct aqualinkdata *aqdata); bool processPacketFromJandyPump(unsigned char *packet_buffer, int packet_length, struct aqualinkdata *aqdata, const unsigned char previous_packet_to); -void processMissingAckPacketFromSWG(unsigned char destination, struct aqualinkdata *aqdata); -void processMissingAckPacketFromJandyPump(unsigned char destination, struct aqualinkdata *aqdata); +void processMissingAckPacketFromSWG(unsigned char destination, struct aqualinkdata *aqdata, const unsigned char previous_packet_to); +void processMissingAckPacketFromJandyPump(unsigned char destination, struct aqualinkdata *aqdata, const unsigned char previous_packet_to); bool processPacketFromJandyJXiHeater(unsigned char *packet_buffer, int packet_length, struct aqualinkdata *aqdata, const unsigned char previous_packet_to ); bool processPacketToJandyJXiHeater(unsigned char *packet_buffer, int packet_length, struct aqualinkdata *aqdata); diff --git a/devices_pentair.c b/devices_pentair.c index 4ab5e21a..e3f6570c 100644 --- a/devices_pentair.c +++ b/devices_pentair.c @@ -44,6 +44,7 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual //static int pumpIndex = 1; + // Status from pump if ( packet[PEN_PKT_CMD] == PEN_CMD_STATUS && packet[PEN_PKT_FROM] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_FROM] <= PENTAIR_DEC_PUMP_MAX ){ // We have Pentair Pump packet, let's see if it's configured. //printf("PUMP\n"); @@ -51,28 +52,92 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual for (i = 0; i < MAX_PUMPS; i++) { if ( aqdata->pumps[i].prclType == PENTAIR && aqdata->pumps[i].pumpID == packet[PEN_PKT_FROM] ) { // We found the pump. - LOG(DPEN_LOG, LOG_INFO, "Pentair Pump Status message = RPM %d | WATTS %d\n", + LOG(DPEN_LOG, LOG_INFO, "Pentair Pump 0x%02hhx Status message = RPM %d | WATTS %d | GPM %d | Mode %d | DriveState %d | Status %d | PresureCurve %d\n", + packet[PEN_PKT_FROM], (packet[PEN_HI_B_RPM] * 256) + packet[PEN_LO_B_RPM], - (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT]); + (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT], + packet[PEN_FLOW], + packet[PEN_MODE], + packet[PEN_DRIVE_STATE], + (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]; + //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]; changedAnything = true; break; } - if (changedAnything != true) - LOG(DPEN_LOG, LOG_NOTICE, "Pentair Pump found at ID 0x%02hhx with RPM %d | WATTS %d, but not configured, information ignored!\n", + if (changedAnything != true) { + LOG(DPEN_LOG, LOG_NOTICE, "Pentair Pump found at ID 0x%02hhx values RPM %d | WATTS %d | PGM %d | Mode %d | DriveState %d | Status %d | PresureCurve %d\n", packet[PEN_PKT_FROM], (packet[PEN_HI_B_RPM] * 256) + packet[PEN_LO_B_RPM], - (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT]); + (packet[PEN_HI_B_WAT] * 256) + packet[PEN_LO_B_WAT], + packet[PEN_FLOW], + packet[PEN_MODE], + packet[PEN_DRIVE_STATE], + (packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS], + packet[PEN_PPC]); + } } // } + // Set RPM/GPM to pump + else if (packet[PEN_PKT_CMD] == PEN_CMD_SPEED && packet[PEN_PKT_DEST] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEC_PUMP_MAX) { + + //(msg.extractPayloadByte(2) & 32) >> 5 === 0 ? 'RPM' : 'GPM'; + + bool isRPM = (packet[11] & 32) >> 5 == 0?true:false; + + if (isRPM) { + LOG(DPEN_LOG, LOG_INFO,"Pentair Pump 0x%02hhx request to set RPM to %d\n",packet[PEN_PKT_DEST], (packet[11] * 256) + packet[12]); + } else { + LOG(DPEN_LOG, LOG_INFO,"Pentair Pump 0x%02hhx request to set GPM to %d\n",packet[PEN_PKT_DEST],packet[11]); + } + } + // Set power to pump + else if (packet[PEN_PKT_CMD] == PEN_CMD_POWER && packet[PEN_PKT_DEST] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEC_PUMP_MAX) { + if (packet[9] == 0x0A) { + LOG(DPEN_LOG, LOG_INFO,"Pentair Pump 0x%02hhx request set power ON\n"); + } else { + LOG(DPEN_LOG, LOG_INFO,"Pentair Pump 0x%02hhx request set power OFF\n"); + } + } return changedAnything; } - +/* + VSP Pump Status. + + (packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS]; + + // Below was pulled from another project. 0 doesn;t seem to be accurate. + [0, { name: 'off', desc: 'Off' }], // When the pump is disconnected or has no power then we simply report off as the status. This is not the recommended wiring + // for a VS/VF pump as is should be powered at all times. When it is, the status will always report a value > 0. + [1, { name: 'ok', desc: 'Ok' }], // Status is always reported when the pump is not wired to a relay regardless of whether it is on or not + // as is should be if this is a VS / VF pump. However if it is wired to a relay most often filter, the pump will report status + // 0 if it is not running. Essentially this is no error but it is not a status either. + [2, { name: 'filter', desc: 'Filter warning' }], + [3, { name: 'overcurrent', desc: 'Overcurrent condition' }], + [4, { name: 'priming', desc: 'Priming' }], + [5, { name: 'blocked', desc: 'System blocked' }], + [6, { name: 'general', desc: 'General alarm' }], + [7, { name: 'overtemp', desc: 'Overtemp condition' }], + [8, { name: 'power', dec: 'Power outage' }], + [9, { name: 'overcurrent2', desc: 'Overcurrent condition 2' }], + [10, { name: 'overvoltage', desc: 'Overvoltage condition' }], + [11, { name: 'error11', desc: 'Unspecified Error 11' }], + [12, { name: 'error12', desc: 'Unspecified Error 12' }], + [13, { name: 'error13', desc: 'Unspecified Error 13' }], + [14, { name: 'error14', desc: 'Unspecified Error 14' }], + [15, { name: 'error15', desc: 'Unspecified Error 15' }], + [16, { name: 'commfailure', desc: 'Communication failure' }] +*/ diff --git a/docker/buildx.sh b/docker/buildx.sh old mode 100644 new mode 100755 index 4bf8438a..fb8755b4 --- a/docker/buildx.sh +++ b/docker/buildx.sh @@ -5,11 +5,15 @@ IMAGE=aqualinkd +DOCKER_HUB_NAME="docker.io/sfeakes" +LATEST_TAG="" + if [ $# -eq 0 ] then # Below is safer, but not supported on all platforms. #VERSION=$(curl --silent "https://api.github.com/repos/sfeakes/AqualinkD/releases/latest" | grep -Po '"tag_name": "[^0-9|v|V]*\K.*?(?=")') VERSION=$(curl --silent "https://api.github.com/repos/sfeakes/AqualinkD/releases/latest" | grep "tag_name" | awk -F'"' '$0=$4') + LATEST_TAG="-t ${DOCKER_HUB_NAME}/${IMAGE}:latest" else VERSION=$1 fi @@ -37,10 +41,23 @@ if ! curl --output /dev/null --silent --location --head --fail "$URL"; then fi fi +# Check we are building a version not already on docker hub + +DOCKER_TAGS=$(wget -q -O - "https://hub.docker.com/v2/namespaces/sfeakes/repositories/aqualinkd/tags" | grep -o '"name": *"[^"]*' | grep -o '[^"]*$') + +if echo $DOCKER_TAGS | grep -q $VERSION; then + echo "AqualinkD version $VERSION already exists on docker.io, are you sure you want to overide" + read -p "Are you sure? " -n 1 -r + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit + fi +fi + echo "Building Docker container for $IMAGE using branch $VERSION" docker buildx build --platform=linux/amd64,linux/arm64 \ --file Dockerfile.buildx \ - -t docker.io/sfeakes/${IMAGE}:${VERSION} \ - -t docker.io/sfeakes/${IMAGE}:latest \ + -t ${DOCKER_HUB_NAME}/${IMAGE}:${VERSION} \ + $LATEST_TAG \ --build-arg AQUALINKD_VERSION=${VERSION} \ --push . \ No newline at end of file diff --git a/hassio.c b/hassio.c index 93a5186f..0a14cd24 100644 --- a/hassio.c +++ b/hassio.c @@ -267,10 +267,12 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect LOG(NET_LOG,LOG_INFO, "MQTT: Publishing discover messages to '%s'\n", _aqconfig_.mqtt_hass_discover_topic); for (i=0; i < aqdata->total_buttons; i++) - { // Heaters - if ( (strcmp(BTN_POOL_HTR,aqdata->aqbuttons[i].name) == 0 && (_aqconfig_.force_ps_setpoints || aqdata->pool_htr_set_point != TEMP_UNKNOWN)) || - (strcmp(BTN_SPA_HTR,aqdata->aqbuttons[i].name)==0 && (_aqconfig_.force_ps_setpoints || aqdata->spa_htr_set_point != TEMP_UNKNOWN)) ) { - sprintf(msg,HASSIO_CLIMATE_DISCOVER, + { + if (strcmp("NONE",aqdata->aqbuttons[i].label) != 0 ) { + // Heaters + if ( (strcmp(BTN_POOL_HTR,aqdata->aqbuttons[i].name) == 0 && (_aqconfig_.force_ps_setpoints || aqdata->pool_htr_set_point != TEMP_UNKNOWN)) || + (strcmp(BTN_SPA_HTR,aqdata->aqbuttons[i].name)==0 && (_aqconfig_.force_ps_setpoints || aqdata->spa_htr_set_point != TEMP_UNKNOWN)) ) { + sprintf(msg,HASSIO_CLIMATE_DISCOVER, _aqconfig_.mqtt_aq_topic, aqdata->aqbuttons[i].name, aqdata->aqbuttons[i].label, @@ -280,12 +282,12 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name, _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name, _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name); - sprintf(topic, "%s/climate/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name); - send_mqtt(nc, topic, msg); - } else if (strcmp("NONE",aqdata->aqbuttons[i].label) != 0 ) { + sprintf(topic, "%s/climate/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name); + send_mqtt(nc, topic, msg); + } else { // Switches //sprintf(msg,"{\"type\": \"switch\",\"unique_id\": \"%s\",\"name\": \"%s\",\"state_topic\": \"aqualinkd/%s\",\"command_topic\": \"aqualinkd/%s/set\",\"json_attributes_topic\": \"aqualinkd/%s/delay\",\"json_attributes_topic\": \"aqualinkd/%s/delay\",\"json_attributes_template\": \"{{ {'delay': value|int} | tojson }}\",\"payload_on\": \"1\",\"payload_off\": \"0\",\"qos\": 1,\"retain\": false}" , - sprintf(msg, HASSIO_SWITCH_DISCOVER, + sprintf(msg, HASSIO_SWITCH_DISCOVER, _aqconfig_.mqtt_aq_topic, aqdata->aqbuttons[i].name, aqdata->aqbuttons[i].label, @@ -293,8 +295,9 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name, _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name, _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name); - sprintf(topic, "%s/switch/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name); - send_mqtt(nc, topic, msg); + sprintf(topic, "%s/switch/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name); + send_mqtt(nc, topic, msg); + } } } diff --git a/iaqtouch_aq_programmer.c b/iaqtouch_aq_programmer.c index 86bff4a6..3ab3541c 100644 --- a/iaqtouch_aq_programmer.c +++ b/iaqtouch_aq_programmer.c @@ -881,7 +881,7 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(IAQT_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } } @@ -898,7 +898,7 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(IAQT_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } } @@ -938,12 +938,23 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) button = iaqtFindButtonByLabel("Degrees"); if (button != NULL) { - LOG(IAQT_LOG,LOG_NOTICE, "Temperature units are '%s'\n",button->name); - if (*button->name[8] == 'C') { + if (rsm_strmatch(*button->name, "Degrees F") == 0) { + LOG(IAQT_LOG,LOG_NOTICE, "Temperature unit message is '%s' set to degC\n",button->name); aq_data->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; } + + + /* + 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; + } else { + aq_data->temp_units = FAHRENHEIT; + } + */ } } diff --git a/json_messages.c b/json_messages.c index dd77ae08..dad166fd 100644 --- a/json_messages.c +++ b/json_messages.c @@ -513,7 +513,7 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int length += sprintf(buffer+length, ",\"debugmasks\":["); length += logmaskjsonobject(AQUA_LOG, buffer+length); length += logmaskjsonobject(NET_LOG, buffer+length); - length += logmaskjsonobject(AQRS_LOG, buffer+length); + length += logmaskjsonobject(ALLB_LOG, buffer+length); length += logmaskjsonobject(ONET_LOG, buffer+length); length += logmaskjsonobject(IAQT_LOG, buffer+length); length += logmaskjsonobject(PDA_LOG, buffer+length); @@ -522,9 +522,10 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int length += logmaskjsonobject(DPEN_LOG, buffer+length); length += logmaskjsonobject(RSSD_LOG, buffer+length); length += logmaskjsonobject(PROG_LOG, buffer+length); - length += logmaskjsonobject(DBGT_LOG, buffer+length); - length += logmaskjsonobject(TIMR_LOG, buffer+length); + length += logmaskjsonobject(SCHD_LOG, buffer+length); + length += logmaskjsonobject(RSTM_LOG, buffer+length); length += logmaskjsonobject(SIM_LOG, buffer+length); + // DBGT_LOG is a compile time only, so don;t include if (buffer[length-1] == ',') length--; length += sprintf(buffer+length, "]"); diff --git a/net_services.c b/net_services.c index f770dfa8..b0964170 100644 --- a/net_services.c +++ b/net_services.c @@ -920,6 +920,18 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc) //send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_WATTS_TOPIC, _aqualink_data->pumps[i].watts); send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_WATTS_TOPIC, _aqualink_data->pumps[i].watts); } + if (_aqualink_data->pumps[i].mode != TEMP_UNKNOWN && _aqualink_data->pumps[i].mode != _last_mqtt_aqualinkdata.pumps[i].mode) { + _last_mqtt_aqualinkdata.pumps[i].mode = _aqualink_data->pumps[i].mode; + send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_MODE_TOPIC, _aqualink_data->pumps[i].mode); + } + if (_aqualink_data->pumps[i].status != TEMP_UNKNOWN && _aqualink_data->pumps[i].status != _last_mqtt_aqualinkdata.pumps[i].status) { + _last_mqtt_aqualinkdata.pumps[i].status = _aqualink_data->pumps[i].status; + send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_STATUS_TOPIC, _aqualink_data->pumps[i].status); + } + if (_aqualink_data->pumps[i].pressureCurve != TEMP_UNKNOWN && _aqualink_data->pumps[i].pressureCurve != _last_mqtt_aqualinkdata.pumps[i].pressureCurve) { + _last_mqtt_aqualinkdata.pumps[i].pressureCurve = _aqualink_data->pumps[i].pressureCurve; + send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_PPC_TOPIC, _aqualink_data->pumps[i].pressureCurve); + } } } @@ -1923,9 +1935,13 @@ void reset_last_mqtt_status() _last_mqtt_aqualinkdata.heater_err_status = NUL; // 0x00 for (i=0; i < _aqualink_data->num_pumps; i++) { - _last_mqtt_aqualinkdata.pumps[i].gpm = -1; - _last_mqtt_aqualinkdata.pumps[i].rpm = -1; - _last_mqtt_aqualinkdata.pumps[i].watts = -1; + _last_mqtt_aqualinkdata.pumps[i].gpm = TEMP_UNKNOWN; + _last_mqtt_aqualinkdata.pumps[i].rpm = TEMP_UNKNOWN; + _last_mqtt_aqualinkdata.pumps[i].watts = TEMP_UNKNOWN; + _last_mqtt_aqualinkdata.pumps[i].mode = TEMP_UNKNOWN; + _last_mqtt_aqualinkdata.pumps[i].status = TEMP_UNKNOWN; + _last_mqtt_aqualinkdata.pumps[i].pressureCurve = TEMP_UNKNOWN; + //_last_mqtt_aqualinkdata.pumps[i].driveState = TEMP_UNKNOWN; } } diff --git a/onetouch.c b/onetouch.c index f25ff269..a84010f3 100644 --- a/onetouch.c +++ b/onetouch.c @@ -257,7 +257,7 @@ bool log_heater_setpoints(struct aqualinkdata *aq_data) if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(ONET_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } if (rsm_strcmp(_menu[3], "Temp2") == 0 ) diff --git a/packetLogger.c b/packetLogger.c index 13a736c9..474f88a2 100644 --- a/packetLogger.c +++ b/packetLogger.c @@ -110,8 +110,9 @@ void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, b if ( is_read && _aqconfig_.RSSD_LOG_filter != packet_buffer[PKT_DEST]) { return; } - } else if (!is_read && _lastReadFrom != _aqconfig_.RSSD_LOG_filter) // Must be write + } else if (!is_read && _lastReadFrom != _aqconfig_.RSSD_LOG_filter) { // Must be write return; + } /* if ( is_read && _aqconfig_.RSSD_LOG_filter != packet_buffer[PKT_DEST]) { return; @@ -146,14 +147,22 @@ int _beautifyPacket(char *buff, unsigned char *packet_buffer, int packet_length, { int i = 0; int cnt = 0; - + protocolType ptype = getProtocolType(packet_buffer); + + cnt = sprintf(buff, "%s %s packet %sTo 0x%02hhx of type %16.16s | HEX: ", + (is_read?"Read ":"Write"), + (ptype==PENTAIR?"Pentair":"Jandy "), + (error?"BAD PACKET ":""), + packet_buffer[(ptype==JANDY?PKT_DEST:PEN_PKT_DEST)], + get_packet_type(packet_buffer, packet_length)); +/* if (getProtocolType(packet_buffer)==PENTAIR) { // Listing Jandy below if redundant. need to clean this up. cnt = sprintf(buff, "%5.5s %s%8.8s Packet | HEX: ",(is_read?"Read":"Write"),(error?"BAD PACKET ":""),getProtocolType(packet_buffer)==PENTAIR?"Pentair":"Jandy"); } else { cnt = sprintf(buff, "%5.5s %sTo 0x%02hhx of type %16.16s | HEX: ",(is_read?"Read":"Write"),(error?"BAD PACKET ":""), packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length)); } - +*/ for (i = 0; i < packet_length; i++) cnt += sprintf(buff + cnt, "0x%02hhx|", packet_buffer[i]); diff --git a/pda.c b/pda.c index e72539e9..052706cf 100644 --- a/pda.c +++ b/pda.c @@ -252,7 +252,7 @@ void process_pda_packet_msg_long_time(const char *msg) if (checkAqualinkTime() != true) { - LOG(AQRS_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", _aqualink_data->time, _aqualink_data->date); + 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); } } @@ -336,7 +336,7 @@ void setSingleDeviceMode() if (isSINGLE_DEV_PANEL != true) { changePanelToMode_Only(); - LOG(AQRS_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); + LOG(PDA_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n"); } } diff --git a/release/aqualinkd-arm64 b/release/aqualinkd-arm64 index 6308cdc8..60719e3a 100755 Binary files a/release/aqualinkd-arm64 and b/release/aqualinkd-arm64 differ diff --git a/release/aqualinkd-armhf b/release/aqualinkd-armhf index ee73300d..e0ed678f 100755 Binary files a/release/aqualinkd-armhf and b/release/aqualinkd-armhf differ diff --git a/release/aqualinkd.conf b/release/aqualinkd.conf index 6152b603..508fce6e 100755 --- a/release/aqualinkd.conf +++ b/release/aqualinkd.conf @@ -138,7 +138,12 @@ report_zero_pool_temp = no # Log any packets from this device. #serial_debug_filter = 0x00 -# Not documented. These are experimental. Will change how RS485 / Serial works, Only use if asked to for problem solving purposes. +# Will change how RS485 / Serial works, Only use if asked to for problem solving purposes. +# Delay between RS485 frame (set or packets that make up a command), reply too quickly can +# cause slow panels (like PDA only) issues, reply too slowly and the control panel will think we are +# dead. +# ~40 and we will be replying too slowley, so keep below that. +# 10~20 is about what most device reply in. But 0-4 works well. rs485_frame_delay = 4 # Get rid of the startup warning message about no low latency. BETTER option is to buy a better adapter. @@ -212,10 +217,11 @@ use_panel_aux_labels=no # Simply change these to your setup, valid options for wach button are :- # None of these are mandatory unless you have PDA or RS16 panel, then _label is mandatory # button_??_label=Filter Pump - + @@ -730,6 +753,10 @@ AqualinkD version: + + Latest version: + + Panel version: @@ -753,11 +780,17 @@
Log to file --> -
- - - #lines -
+ + + + + +
+ + + #lines +
@@ -777,7 +810,7 @@ - + diff --git a/web/controller.html b/web/controller.html index 8a57d4d2..33534908 100644 --- a/web/controller.html +++ b/web/controller.html @@ -19,6 +19,8 @@ --tile-width: 100px; --tile_icon-height: 35px; --tile_name-height: 32px; + --tile_name-charlimit: 12; + --tile_name-height1line: 17px; --tile_status-height: 15px; --tile_grid-gap: 10px; --tile_name-lineheight: 1.2; @@ -299,6 +301,11 @@ /*background-color: green;*/ line-height: var(--tile_name-lineheight); } + .tile_name_1line { + height: var(--tile_name-height1line); + /*background-color: green;*/ + line-height: var(--tile_name-lineheight); + } .tile_status { color: var(--tile_status_text); @@ -633,8 +640,7 @@ document.getElementById('vspswitch_options').classList.remove("hide"); document.getElementById('timer_options').classList.remove("hide"); document.getElementById('scheduler_options').classList.remove("hide"); - //document.getElementById('simulator_options').classList.remove("hide"); - document.getElementById('simulator_iframe').classList.remove("hide"); + //document.getElementById('simulator_iframe').classList.remove("hide"); setColors(); load_background(); showTileOptions(false); @@ -722,6 +728,8 @@ document.documentElement.style.setProperty('--tile-width', '125px'); document.documentElement.style.setProperty('--tile_icon-height', '45px'); document.documentElement.style.setProperty('--tile_name-height', '42px'); + document.documentElement.style.setProperty('--tile_name-height1line', '27px'); + document.documentElement.style.setProperty('--tile_name-charlimit', '15'); document.documentElement.style.setProperty('--tile_status-height', '15px'); document.documentElement.style.setProperty('--tile_grid-gap', '20px'); document.documentElement.style.setProperty('--tile_name-lineheight', '1.4'); @@ -842,6 +850,7 @@ function add_tile(id, name, status, type, subtype, off_imgurl, on_imgurl) { var height = getComputedStyle(document.documentElement).getPropertyValue('--tile_icon-height'); + var div = document.createElement('div'); div.setAttribute('class', 'tile'); div.setAttribute('id', id); @@ -882,13 +891,25 @@ valdiv.textContent = '--'; subdiv.appendChild(valdiv); } */ - subdiv = document.createElement('div'); - subdiv.setAttribute('class', 'tile_name'); - subdiv.setAttribute('id', id + '_name'); - subdiv.textContent = name; - div.appendChild(subdiv); + title_subdiv = document.createElement('div'); + title_subdiv.setAttribute('class', 'tile_name'); + title_subdiv.setAttribute('id', id + '_name'); + title_subdiv.textContent = name; + div.appendChild(title_subdiv); // Value and Thermostat are the same, but value is read only and no state if (type != "value") { + // Add extra status line to VSP if we can + if (subtype == "switch_vsp") { + var title1linechatlimit = getComputedStyle(document.documentElement).getPropertyValue('--tile_name-charlimit'); + if ( name.length <= title1linechatlimit ) { + subdiv = document.createElement('div'); + subdiv.setAttribute('class', 'tile_status'); + subdiv.setAttribute('id', id + '_status_line2'); + div.appendChild(subdiv); + title_subdiv.classList.add("tile_name_1line"); + title_subdiv.classList.remove("tile_name"); + } + } subdiv = document.createElement('div'); subdiv.setAttribute('class', 'tile_status'); subdiv.setAttribute('id', id + '_status'); @@ -1014,6 +1035,15 @@ } } catch(exception) {} } + function setTileOnTextLine2(id, text) { + try { + if (document.getElementById(id).getAttribute('status') == 'on') { + document.getElementById(id + '_status_line2').innerHTML = text; + } else { + //console.log("Tile "+id+" status is '"+document.getElementById(id).getAttribute('status')+"' not setting text to '"+text+"'"); + } + } catch(exception) {} + } function setThermostatTile(id, value, sp_value) { setTileValue(id, value); @@ -1137,6 +1167,8 @@ try { document.getElementById(id + '_status').innerHTML = text; + // Clear line 2 status if we have it. + document.getElementById(id + '_status_line2').innerHTML = ""; } catch (e) {} var tile_icon = document.getElementById(id + '_tile_icon_value'); type = tile.getAttribute('type'); @@ -1222,15 +1254,22 @@ document.getElementById(object.id).setAttribute('setpoint', 0); } else { if (object.Pump_Type == "vfPump") { - if (_show_vsp_gpm == true) + if (_show_vsp_gpm == true) { setTileOnText(object.id, 'GPM:'+object.Pump_GPM); - else + setTileOnTextLine2(object.id, 'RPM:'+object.Pump_RPM); + } else { setTileOnText(object.id, 'RPM:'+object.Pump_RPM); - + setTileOnTextLine2(object.id, 'GPM:'+object.Pump_GPM); + } document.getElementById(object.id).setAttribute('setpoint', object.Pump_GPM); } else { setTileOnText(object.id, 'RPM:'+object.Pump_RPM); document.getElementById(object.id).setAttribute('setpoint', object.Pump_RPM); + if (object.Pump_GPM > 0) { + setTileOnTextLine2(object.id, 'GPM:'+object.Pump_GPM); + } else { + setTileOnTextLine2(object.id, ""); + } } } } @@ -1262,7 +1301,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_program') { active_option = document.getElementById('pswitch_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1270,7 +1309,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg') { active_option = document.getElementById('swg_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1278,7 +1317,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_freeze') { active_option = document.getElementById('swg_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1286,7 +1325,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_vsp') { active_option = document.getElementById('vspswitch_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1294,7 +1333,7 @@ document.getElementById('swg_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_timer') { active_option = document.getElementById('timer_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1302,7 +1341,7 @@ document.getElementById('swg_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; } else if (id != null && document.getElementById(id).getAttribute('type') == 'scheduler') { active_option = document.getElementById('scheduler_options'); document.getElementById('thermostat_options').style.display = 'none'; @@ -1310,8 +1349,8 @@ document.getElementById('swg_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; - } else if (id != null && document.getElementById(id).getAttribute('type') == 'simulator') { + //document.getElementById('simulator_iframe').style.display = 'none'; + } /*else if (id != null && document.getElementById(id).getAttribute('type') == 'simulator') { active_option = document.getElementById('simulator_iframe'); document.getElementById('thermostat_options').style.display = 'none'; document.getElementById('pswitch_options').style.display = 'none'; @@ -1319,7 +1358,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - } + }*/ active_option.style.display = 'flex'; /* @@ -1354,7 +1393,7 @@ document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none'; - document.getElementById('simulator_iframe').style.display = 'none'; + //document.getElementById('simulator_iframe').style.display = 'none'; document.getElementById('wrapper').classList.remove("opaque"); return; } @@ -1408,8 +1447,8 @@ } else if (type == 'scheduler') { title = document.getElementById("scheduler_options_title"); close_button = document.getElementById("scheduler_options_close"); - } else if (type == 'simulator') { - close_button = document.getElementById("simulator_iframe_close"); + //} else if (type == 'simulator') { + // close_button = document.getElementById("simulator_iframe_close"); } else { slider = document.getElementById("option_slider_range"); slider_output = document.getElementById("option_slider_text_value"); @@ -2188,15 +2227,22 @@ } else { //setTileOnText(object.id, 'RPM:'+object.Pump_RPM); if (data["Pump_"+i].Pump_Type == "vfPump") { - if (_show_vsp_gpm == true) + if (_show_vsp_gpm == true) { setTileOnText(data["Pump_"+i].id, 'GPM:'+data["Pump_"+i].GPM); - else + setTileOnTextLine2(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM); + } else { setTileOnText(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM); - + setTileOnTextLine2(data["Pump_"+i].id, 'GPM:'+data["Pump_"+i].GPM); + } document.getElementById(data["Pump_"+i].id).setAttribute('setpoint', data["Pump_"+i].GPM); } else { document.getElementById(data["Pump_"+i].id).setAttribute('setpoint', data["Pump_"+i].RPM); setTileOnText(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM); + if (data["Pump_"+i].GPM > 0) { + setTileOnTextLine2(data["Pump_"+i].id, 'GPM:'+data["Pump_"+i].GPM); + } else { + setTileOnTextLine2(data["Pump_"+i].id, ""); + } } } /* @@ -2468,7 +2514,7 @@ } } */ - + @@ -2480,7 +2526,6 @@