diff --git a/Makefile b/Makefile index 14e031c..ed18865 100755 --- a/Makefile +++ b/Makefile @@ -1,45 +1,51 @@ # # Options +# +# make // standard everything +# make debug // Give standard binary just with debugging +# make aqdebug // Compile with extra aqualink debug information like timings +# make slog // Serial logger +# make // not documenting +# # Valid flags for AQ_FLAGS -#AQ_DEBUG = true AQ_RS16 = true AQ_PDA = true AQ_ONETOUCH = true AQ_IAQTOUCH = true #AQ_MEMCMP = true // Not implimented correctly yet. +# Get some system information +PI_OS_VERSION = $(shell cat /etc/os-release | grep VERSION= | cut -d\" -f2) +$(info OS: $(PI_OS_VERSION) ) +GLIBC_VERSION = $(shell ldd --version | grep ldd) +$(info GLIBC: $(GLIBC_VERSION) ) -# make EXFLAGS="-D BETA_PDA_AUTOLABEL" // Add compile flags -# # define the C compiler to use CC = gcc #LIBS := -lpthread -lm LIBS := -l pthread -l m -#LIBS := -lpthread -lwebsockets +#LIBS := -l pthread -l m -static # Take out -static, just for dev -# debug of not -#DBG = -g -O0 -fsanitize=address -#GCCFLAGS = -Wall -O3 - -# USe below to remove unused functions and global variables. -#LFLAGS = -Wl,--gc-sections,--print-gc-sections -#GCCFLAGS = -Wall -ffunction-sections -fdata-sections - -# define any compile-time flags +# Standard compile flags +GCCFLAGS = -Wall -O3 +#GCCFLAGS = -O3 #GCCFLAGS = -Wall -O3 -Wextra -#GCCFLAGS = -Wall -O3 -#GCCFLAGS = -Wall +#GCCFLAGS = -Wl,--gc-sections,--print-gc-sections +#GCCFLAGS = -Wall -O3 -ffunction-sections -fdata-sections -#CFLAGS = -Wall -g $(LIBS) -#CFLAGS = -Wall -g $(LIBS) -std=gnu11 -#CFLAGS = $(GCCFLAGS) $(DBG) $(AQ_FLAGS) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH -D MG_DISABLE_MD5 -D MG_DISABLE_JSON_RPC -CFLAGS = $(GCCFLAGS) $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH -D MG_DISABLE_MD5 -D MG_DISABLE_JSON_RPC +# Standard debug flags +DGCCFLAGS = -Wall -O0 -g +# Aqualink Debug flags +#DBGFLAGS = -g -O0 -Wall -fsanitize=address -D AQ_DEBUG -D AQ_TM_DEBUG +DBGFLAGS = -g -O0 -Wall -D AQ_DEBUG -D AQ_TM_DEBUG + +# Mongoose flags +MGFLAGS = -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH -D MG_DISABLE_MD5 -D MG_DISABLE_JSON_RPC -# Add inputs and outputs from these tool invocations to the build variables # define the C source files #SRCS = aqualinkd.c utils.c config.c aq_serial.c init_buttons.c aq_programmer.c net_services.c json_messages.c pda.c pda_menu.c \ @@ -47,41 +53,41 @@ CFLAGS = $(GCCFLAGS) $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_ SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c net_services.c json_messages.c rs_msg_utils.c\ devices_jandy.c packetLogger.c devices_pentair.c color_lights.c mongoose.c -DBG_SRC = timespec_subtract.c + +AQ_FLAGS = +# Add source and flags depending on protocols to support. ifeq ($(AQ_PDA), true) SRCS := $(SRCS) pda.c pda_menu.c pda_aq_programmer.c - CFLAGS := $(CFLAGS) -D AQ_PDA + AQ_FLAGS := $(AQ_FLAGS) -D AQ_PDA endif ifeq ($(AQ_ONETOUCH), true) SRCS := $(SRCS) onetouch.c onetouch_aq_programmer.c - CFLAGS := $(CFLAGS) -D AQ_ONETOUCH + AQ_FLAGS := $(AQ_FLAGS) -D AQ_ONETOUCH endif ifeq ($(AQ_IAQTOUCH), true) SRCS := $(SRCS) iaqtouch.c iaqtouch_aq_programmer.c - CFLAGS := $(CFLAGS) -D AQ_IAQTOUCH + AQ_FLAGS := $(AQ_FLAGS) -D AQ_IAQTOUCH endif ifeq ($(AQ_RS16), true) - CFLAGS := $(CFLAGS) -D AQ_RS16 + AQ_FLAGS := $(AQ_FLAGS) -D AQ_RS16 endif ifeq ($(AQ_MEMCMP), true) - CFLAGS := $(CFLAGS) -D AQ_MEMCMP + AQ_FLAGS := $(AQ_FLAGS) -D AQ_MEMCMP endif -ifeq ($(AQ_DEBUG), true) - DEBUG=true -endif - -# If run with `make DEBUG=true` add debug files and pass parameter for compile -ifeq ($(DEBUG), true) - SRCS := $(SRCS) $(DBG_SRC) - CFLAGS := -g -O0 $(CFLAGS) -D AQ_DEBUG -endif +# Put all flags together. +CFLAGS = $(GCCFLAGS) $(AQ_FLAGS) $(MGFLAGS) +DFLAGS = $(DGCCFLAGS) $(AQ_FLAGS) $(MGFLAGS) +DBG_CFLAGS = $(DBGFLAGS) $(AQ_FLAGS) $(MGFLAGS) +# Other sources. +#DBG_SRC = timespec_subtract.c debug_timer.c +DBG_SRC = debug_timer.c SL_SRC = serial_logger.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c LR_SRC = log_reader.c aq_serial.c utils.c packetLogger.c PL_EXSRC = aq_serial.c @@ -89,6 +95,7 @@ PL_EXOBJ = aq_serial_player.o PL_SRC := $(filter-out aq_serial.c, $(SRCS)) OBJS = $(SRCS:.c=.o) +DBG_OBJS = $(DBG_SRC:.c=.o) SL_OBJS = $(SL_SRC:.c=.o) LR_OBJS = $(LR_SRC:.c=.o) @@ -99,27 +106,45 @@ MAIN = ./release/aqualinkd SLOG = ./release/serial_logger LOGR = ./release/log_reader PLAY = ./release/aqualinkd-player +DEBG = ./release/aqualinkd-debug -all: $(MAIN) - @echo: $(MAIN) have been compiled +all: $(MAIN) + $(info $(MAIN) has been compiled) + +# debug, Just change compile flags and call MAIN +debug: CFLAGS = $(DFLAGS) +debug: $(MAIN) + $(info $(MAIN) has been compiled) $(MAIN): $(OBJS) - $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) + $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LIBS) + $(info $(MAIN) has been compiled) slog: $(SLOG) - @echo: $(SLOG) have been compiled + $(info $(SLOG) has been compiled) +$(SLOG): CFLAGS := $(CFLAGS) -D SERIAL_LOGGER $(SLOG): $(SL_OBJS) - $(CC) $(CFLAGS) $(INCLUDES) -o $(SLOG) $(SL_OBJS) -D SERIAL_LOGGER + $(CC) $(CFLAGS) $(INCLUDES) -o $(SLOG) $(SL_OBJS) + + +# Shouldn't need to use any of these options unless you're developing. + +aqdebug: $(DEBG) + $(info $(DEBG) has been compiled) + +$(DEBG): CFLAGS = $(DBG_CFLAGS) +$(DEBG): $(OBJS) $(DBG_OBJS) + $(CC) $(CFLAGS) $(INCLUDES) -o $(DEBG) $(OBJS) $(DBG_OBJS) $(DBGFLAGS) $(LIBS) logr: $(LOGR) - @echo: $(LOGR) have been compiled + $(info $(LOGR) has been compiled) $(LOGR): $(LR_OBJS) $(CC) $(CFLAGS) $(INCLUDES) -o $(LOGR) $(LR_OBJS) player: $(PLAY) - @echo: $(PLAY) have been compiled + $(info $(PLAY) has been compiled) $(PL_EXOBJ): $(PL_EXSRC) $(CC) $(CFLAGS) -D PLAYBACK_MODE $(INCLUDES) -c $(PL_EXSRC) -o $(PL_EXOBJ) @@ -127,6 +152,7 @@ $(PL_EXOBJ): $(PL_EXSRC) $(PLAY): $(PL_OBJS) $(PL_EXOBJ) $(CC) $(CFLAGS) $(INCLUDES) -o $(PLAY) $(PL_OBJS) $(PL_EXOBJ) +# Fog github publishing .PHONY: git git: clean $(MAIN) $(SLOG) ./release/git_version.sh @@ -141,8 +167,8 @@ git: clean $(MAIN) $(SLOG) .PHONY: clean clean: - $(RM) *.o *~ $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) - $(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) + $(RM) *.o *~ $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(DEBG) + $(RM) $(wildcard *.o) $(wildcard *~) $(MAIN) $(MAIN_U) $(PLAY) $(PL_EXOBJ) $(LOGR) $(PLAY) $(DEBG) depend: $(SRCS) makedepend $(INCLUDES) $^ diff --git a/README.md b/README.md index 0df29b0..e0c9347 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,18 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to * Allow selecting of pre-defined VSP programs * Timed based actions (undecided on cron & AqualinkD or use Jandy programs ) * Put back some form of Jandy panel simulator. (existing was removed in V2.2.0) -* RS Serial protocol. AqualinkD has all Jandy control protocols except RS Serial. +* Add RS Serial protocol. AqualinkD has all Jandy control protocols except RS Serial. * Update homekit-aqualinkd to use new API & features. +* Add light programming to Aqualink Touch protocol. -# Update in (Pre) Release 2.2.0b +# Update in (Pre) Release 2.2.0c +* Cleaned up Makefile (and adding debug timings). +* Changed loggin infrastructure. +* Added expermental options for Pi4. * 2.2.0a (had some issues with compiler optimisation), please don't use or compile yourself. -* Fixed RS-4 bug. -* Increased timeout for startup probe +* Fixed RS-4 panel bug. +* Fixed some AqualinkTouch programming issues. +* Increased timeout for startup probe. * This release WILL require you to make aqualinkd.conf changes. Make sure to read wiki section https://github.com/sfeakes/AqualinkD/wiki#Version_2 * Extensive work to reduce CPU cycles and unnesessary logic. * iAqualink Touch protocol supported for VSP & extended programming. diff --git a/aq_programmer.c b/aq_programmer.c index 9c6bcb7..1a8cab3 100644 --- a/aq_programmer.c +++ b/aq_programmer.c @@ -119,13 +119,13 @@ unsigned char pop_ot_cmd(unsigned char receive_type) */ bool push_aq_cmd(unsigned char cmd) { - //logMessage(LOG_DEBUG, "push_aq_cmd '0x%02hhx'\n", cmd); + //LOG(PROG_LOG, LOG_DEBUG, "push_aq_cmd '0x%02hhx'\n", cmd); if (_stack_place < MAX_STACK) { _commands[_stack_place] = cmd; _stack_place++; } else { - logMessage(LOG_ERR, "Command queue overflow, too many unsent commands to RS control panel\n"); + LOG(PROG_LOG, LOG_ERR, "Command queue overflow, too many unsent commands to RS control panel\n"); return false; } @@ -147,19 +147,19 @@ unsigned char pop_aq_cmd(struct aqualinkdata *aq_data) if ( _pgm_command != NUL && aq_data->last_packet_type == CMD_STATUS) { cmd = _pgm_command; _pgm_command = NUL; - logMessage(LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' (programming)\n", cmd); + LOG(PROG_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' (programming)\n", cmd); } else if (_pgm_command != NUL) { - logMessage(LOG_DEBUG_SERIAL, "RS Waiting to send cmd '0x%02hhx' (programming)\n", _pgm_command); + LOG(PROG_LOG, LOG_DEBUG_SERIAL, "RS Waiting to send cmd '0x%02hhx' (programming)\n", _pgm_command); } else { - logMessage(LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' empty queue (programming)\n", cmd); + LOG(PROG_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx' empty queue (programming)\n", cmd); } } else if (_stack_place > 0 && aq_data->last_packet_type == CMD_STATUS ) { cmd = _commands[0]; _stack_place--; - logMessage(LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); + LOG(PROG_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); memmove(&_commands[0], &_commands[1], sizeof(unsigned char) * _stack_place ) ; } else { - logMessage(LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); + LOG(PROG_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd); } //printf("RSM sending cmd '0x%02hhx' in reply to '0x%02hhx'\n",cmd,aq_data->last_packet_type); @@ -181,19 +181,19 @@ unsigned char pop_aq_cmd_OLD(struct aqualinkdata *aq_data) ( _pgm_command != NUL && (aq_data->last_packet_type == CMD_STATUS || aq_data->last_packet_type == CMD_MSG_LONG) )) { cmd = _pgm_command; _pgm_command = NUL; - logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx' (programming)\n", cmd); + LOG(PROG_LOG, LOG_DEBUG, "RS SEND cmd '0x%02hhx' (programming)\n", cmd); } else if (_pgm_command != NUL) { - logMessage(LOG_DEBUG, "RS Waiting to send cmd '0x%02hhx' (programming)\n", _pgm_command); + LOG(PROG_LOG, LOG_DEBUG, "RS Waiting to send cmd '0x%02hhx' (programming)\n", _pgm_command); } else { - logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx' empty queue (programming)\n", cmd); + LOG(PROG_LOG, LOG_DEBUG, "RS SEND cmd '0x%02hhx' empty queue (programming)\n", cmd); } } else if (_stack_place > 0 && aq_data->last_packet_type == CMD_STATUS ) { cmd = _commands[0]; _stack_place--; - logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx'\n", cmd); + LOG(PROG_LOG, LOG_DEBUG, "RS SEND cmd '0x%02hhx'\n", cmd); memmove(&_commands[0], &_commands[1], sizeof(unsigned char) * _stack_place ) ; } else { - logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx'\n", cmd); + LOG(PROG_LOG, LOG_DEBUG, "RS SEND cmd '0x%02hhx'\n", cmd); } //printf("RSM sending cmd '0x%02hhx' in reply to '0x%02hhx'\n",cmd,aq_data->last_packet_type); @@ -306,9 +306,9 @@ int setpoint_check(int type, int value, struct aqualinkdata *aqdata) } if (rtn != value) - logMessage(LOG_WARNING, "Setpoint of %d for %s is outside range, using %d\n",value,type_msg,rtn); + LOG(PROG_LOG, LOG_WARNING, "Setpoint of %d for %s is outside range, using %d\n",value,type_msg,rtn); //else - // logMessage(LOG_NOTICE, "Setting setpoint of %s to %d\n",type_msg,rtn); + // LOG(PROG_LOG, LOG_NOTICE, "Setting setpoint of %s to %d\n",type_msg,rtn); return rtn; } @@ -334,7 +334,7 @@ void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_dat aq_programmer(AQ_GET_IAQTOUCH_SETPOINTS, NULL, aq_data); if (_aqconfig_.use_panel_aux_labels) aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data); - //aq_programmer(AQ_GET_IAQTOUCH_AUX_LABELS, NULL, aq_data); + //aq_programmer(AQ_GET_IAQTOUCH_AUX_LABELS, NULL, aq_data); // This is not working yet #endif #ifdef AQ_PDA } else if ( source_type == AQUAPDA) { @@ -353,7 +353,7 @@ void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_dat void kick_aq_program_thread(struct aqualinkdata *aq_data) { if (aq_data->active_thread.thread_id != 0) { - logMessage(LOG_DEBUG, "Kicking thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Kicking thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message); pthread_cond_broadcast(&aq_data->active_thread.thread_cond); } } @@ -431,20 +431,20 @@ void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_ if ( aq_data->active_thread.thread_id != 0 ) { if ( (source_type == ONETOUCH) && in_ot_programming_mode(aq_data)) { - logMessage(LOG_DEBUG, "Kicking OneTouch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); + LOG(PROG_LOG, LOG_DEBUG, "Kicking OneTouch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); pthread_cond_broadcast(&aq_data->active_thread.thread_cond); } else if (source_type == ALLBUTTON && !in_ot_programming_mode(aq_data)) { - logMessage(LOG_DEBUG, "Kicking RS thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Kicking RS thread %d,%p message '%s'\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id,aq_data->last_message); pthread_cond_broadcast(&aq_data->active_thread.thread_cond); } else if (source_type == IAQTOUCH && in_iaqt_programming_mode(aq_data)) { - logMessage(LOG_DEBUG, "Kicking IAQ Touch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); + LOG(PROG_LOG, LOG_DEBUG, "Kicking IAQ Touch thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); pthread_cond_broadcast(&aq_data->active_thread.thread_cond); } #ifdef AQ_PDA else if (source_type == AQUAPDA && !in_ot_programming_mode(aq_data)) { - logMessage(LOG_DEBUG, "Kicking PDA thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); + LOG(PROG_LOG, LOG_DEBUG, "Kicking PDA thread %d,%p\n",aq_data->active_thread.ptype, aq_data->active_thread.thread_id); pthread_cond_broadcast(&aq_data->active_thread.thread_cond); } #endif @@ -455,6 +455,61 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data { struct programmingThreadCtrl *programmingthread = malloc(sizeof(struct programmingThreadCtrl)); + +/* + Seemed like a good idea to use lookuptable, but need to figure out a way to check program_type actually exists in array, + + //void* (*pf[])(void *ptr) = {get_freeze_protect_temp, get_freeze_protect_temp, get_freeze_protect_temp}; + //static const void * (*fun_lookup[])(void *ptr) = { + static void * (*function_lookup[])(void *ptr) = { + [AQ_GET_POOL_SPA_HEATER_TEMPS] = get_aqualink_pool_spa_heater_temps, + [AQ_GET_FREEZE_PROTECT_TEMP] = get_freeze_protect_temp, + [AQ_SET_TIME] = set_aqualink_time, + [AQ_SET_POOL_HEATER_TEMP] = set_aqualink_pool_heater_temps, + [AQ_SET_SPA_HEATER_TEMP] = set_aqualink_spa_heater_temps, + [AQ_SET_FRZ_PROTECTION_TEMP] = set_aqualink_freeze_heater_temps, + [AQ_GET_DIAGNOSTICS_MODEL] = get_aqualink_diag_model, + [AQ_GET_PROGRAMS] = get_aqualink_programs, + [AQ_SET_LIGHTPROGRAM_MODE] = set_aqualink_light_programmode, + [AQ_SET_LIGHTCOLOR_MODE] = set_aqualink_light_colormode, + [AQ_SET_SWG_PERCENT] = set_aqualink_SWG, + [AQ_GET_AUX_LABELS] = get_aqualink_aux_labels, + [AQ_SET_BOOST] = set_aqualink_boost, +#ifdef AQ_PDA + [AQ_PDA_INIT] = set_aqualink_PDA_init, + [AQ_PDA_DEVICE_STATUS] = get_aqualink_PDA_device_status, + [AQ_PDA_DEVICE_ON_OFF] = set_aqualink_PDA_device_on_off, + [AQ_PDA_WAKE_INIT] = set_aqualink_PDA_wakeinit, +#endif +#ifdef AQ_ONETOUCH + //[AQ_SET_PUMP_RPM] = , + //[AQ_SET_PUMP_VS_PROGRAM] = , + //[AQ_SET_ONETOUCH_MACRO] = , + [AQ_SET_ONETOUCH_PUMP_RPM] = set_aqualink_onetouch_pump_rpm, + [AQ_GET_ONETOUCH_SETPOINTS] = get_aqualink_onetouch_setpoints, + [AQ_SET_ONETOUCH_POOL_HEATER_TEMP] = set_aqualink_onetouch_pool_heater_temp, + [AQ_SET_ONETOUCH_SPA_HEATER_TEMP] = set_aqualink_onetouch_spa_heater_temp, + [AQ_SET_ONETOUCH_FREEZEPROTECT] = set_aqualink_onetouch_freezeprotect, + [AQ_SET_ONETOUCH_TIME] = set_aqualink_onetouch_time, + [AQ_SET_ONETOUCH_BOOST] = set_aqualink_onetouch_boost, + [AQ_SET_ONETOUCH_SWG_PERCENT] = set_aqualink_onetouch_swg_percent, +#endif +#ifdef AQ_IAQTOUCH + [AQ_SET_IAQTOUCH_PUMP_RPM] = set_aqualink_iaqtouch_pump_rpm, + [AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM] = set_aqualink_iaqtouch_pump_vs_program, + [AQ_GET_IAQTOUCH_VSP_ASSIGNMENT] = set_aqualink_iaqtouch_vsp_assignments, + [AQ_GET_IAQTOUCH_SETPOINTS] = get_aqualink_iaqtouch_setpoints, + [AQ_GET_IAQTOUCH_AUX_LABELS] = get_aqualink_iaqtouch_aux_labels, + [AQ_SET_IAQTOUCH_SWG_PERCENT] = set_aqualink_iaqtouch_swg_percent, + [AQ_SET_IAQTOUCH_SWG_BOOST] = set_aqualink_iaqtouch_swg_boost, + [AQ_SET_IAQTOUCH_POOL_HEATER_TEMP] = set_aqualink_iaqtouch_pool_heater_temp, + [AQ_SET_IAQTOUCH_SPA_HEATER_TEMP] = set_aqualink_iaqtouch_spa_heater_temp, + [AQ_SET_IAQTOUCH_SET_TIME] = set_aqualink_iaqtouch_time, +#endif + [AQ_SET_BOOST] = set_aqualink_boost + }; +*/ + program_type type = r_type; if (r_type == AQ_SET_PUMP_RPM) { @@ -463,14 +518,14 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data else if (isIAQT_ENABLED) type = AQ_SET_IAQTOUCH_PUMP_RPM; else { - logMessage(LOG_ERR, "Can only change pump RPM with an extended device id\n",type); + LOG(PROG_LOG, LOG_ERR, "Can only change pump RPM with an extended device id\n",type); return; } } else if (r_type == AQ_SET_PUMP_VS_PROGRAM) { if (isIAQT_ENABLED) type = AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM; else { - logMessage(LOG_ERR, "Can only change pump VS Program with an iAqualink Touch device id\n",type); + LOG(PROG_LOG, LOG_ERR, "Can only change pump VS Program with an iAqualink Touch device id\n",type); return; } } @@ -547,7 +602,7 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data type != AQ_GET_POOL_SPA_HEATER_TEMPS && type != AQ_SET_FRZ_PROTECTION_TEMP && type != AQ_SET_BOOST) { - logMessage(LOG_ERR, "Selected Programming mode '%d' not supported with PDA mode control panel\n",type); + LOG(PROG_LOG, LOG_ERR, "Selected Programming mode '%d' not supported with PDA mode control panel\n",type); return; } } @@ -562,150 +617,150 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data switch(type) { /* case AQ_SEND_CMD: - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller\n", &args[0]); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", &args[0]); unsigned char cmd = (unsigned char) &args[0]; if (cmd == NUL) { - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller (NEW)\n", cmd); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller (NEW)\n", cmd); push_aq_cmd( cmd ); } else { - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller (OLD)\n", cmd); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller (OLD)\n", cmd); push_aq_cmd((unsigned char)*args); }*/ - //logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller\n", (unsigned char)*args); + //LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", (unsigned char)*args); /* if(aq_data->active_thread.thread_id == 0) { // No need to thread a plane send if no active threads send_cmd( (unsigned char)*args, aq_data); } else if( pthread_create( &programmingthread->thread_id , NULL , threadded_send_cmd, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } */ //break; case AQ_GET_POOL_SPA_HEATER_TEMPS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_pool_spa_heater_temps, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_FREEZE_PROTECT_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , get_freeze_protect_temp, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_TIME: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_time, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_POOL_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_pool_heater_temps, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_SPA_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_spa_heater_temps, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_FRZ_PROTECTION_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_freeze_heater_temps, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_DIAGNOSTICS_MODEL: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_diag_model, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_PROGRAMS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_programs, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_LIGHTPROGRAM_MODE: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_light_programmode, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_LIGHTCOLOR_MODE: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_light_colormode, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_SWG_PERCENT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_SWG, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_AUX_LABELS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_aux_labels, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_BOOST: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_boost, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; #ifdef AQ_ONETOUCH case AQ_SET_ONETOUCH_PUMP_RPM: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_pump_rpm, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_ONETOUCH_SETPOINTS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_onetouch_setpoints, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_TIME: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_time, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_BOOST: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_boost, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_SWG_PERCENT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_swg_percent, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_POOL_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_pool_heater_temp, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_SPA_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_spa_heater_temp, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_ONETOUCH_FREEZEPROTECT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_onetouch_freezeprotect, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; @@ -713,101 +768,101 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data #ifdef AQ_IAQTOUCH case AQ_SET_IAQTOUCH_PUMP_RPM: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_pump_rpm, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_IAQTOUCH_VSP_ASSIGNMENT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_vsp_assignments, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_IAQTOUCH_SETPOINTS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_iaqtouch_setpoints, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_GET_IAQTOUCH_AUX_LABELS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_iaqtouch_aux_labels, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_SWG_PERCENT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_swg_percent, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_SWG_BOOST: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_swg_boost, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_POOL_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_pool_heater_temp, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_SPA_HEATER_TEMP: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_spa_heater_temp, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_SET_TIME: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_time, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_iaqtouch_pump_vs_program, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } #endif #ifdef AQ_PDA case AQ_PDA_INIT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_PDA_init, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_PDA_WAKE_INIT: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_PDA_wakeinit, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_PDA_DEVICE_STATUS: if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_PDA_device_status, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; case AQ_PDA_DEVICE_ON_OFF: if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_PDA_device_on_off, (void*)programmingthread) < 0) { - logMessage (LOG_ERR, "could not create thread\n"); + LOG(PROG_LOG, LOG_ERR, "could not create thread\n"); return; } break; #endif default: - logMessage (LOG_ERR, "Didn't understand programming mode type\n"); + LOG(PROG_LOG, LOG_ERR, "Didn't understand programming mode type\n"); break; } if ( programmingthread->thread_id != 0 ) { - //logMessage (LOG_DEBUG, "********* DID pthread_detach %d\n",programmingthread->thread_id); + //LOG(PROG_LOG, LOG_DEBUG, "********* DID pthread_detach %d\n",programmingthread->thread_id); pthread_detach(programmingthread->thread_id); } else { - //logMessage (LOG_DEBUG, "********* DID NOT pthread_detach\n"); + //LOG(PROG_LOG, LOG_DEBUG, "********* DID NOT pthread_detach\n"); } } @@ -821,26 +876,26 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr i = 0; while (get_aq_cmd_length() > 0 && ( i++ <= tries) ) { - logMessage (LOG_DEBUG, "Thread %p (%s) sleeping, waiting command queue to empty\n", &threadCtrl->thread_id, ptypeName(type)); + LOG(PROG_LOG, LOG_DEBUG, "Thread %p (%s) sleeping, waiting command queue to empty\n", &threadCtrl->thread_id, ptypeName(type)); sleep(waitTime); } if (i >= tries) { - logMessage (LOG_ERR, "Thread %p (%s) timeout waiting, ending\n",&threadCtrl->thread_id,ptypeName(type)); + LOG(PROG_LOG, LOG_ERR, "Thread %p (%s) timeout waiting, ending\n",&threadCtrl->thread_id,ptypeName(type)); free(threadCtrl); pthread_exit(0); } while ( (threadCtrl->aq_data->active_thread.thread_id != 0) && ( i++ <= tries) ) { - //logMessage (LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id); - logMessage (LOG_DEBUG, "Thread %p (%s) sleeping, waiting for thread %p (%s) to finish\n", + //LOG(PROG_LOG, LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id); + LOG(PROG_LOG, LOG_DEBUG, "Thread %p (%s) sleeping, waiting for thread %p (%s) to finish\n", &threadCtrl->thread_id, ptypeName(type), threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype)); sleep(waitTime); } if (i >= tries) { - //logMessage (LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id); - logMessage (LOG_ERR, "Thread %d,%p timeout waiting for thread %d,%p to finish\n", + //LOG(PROG_LOG, LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id); + LOG(PROG_LOG, LOG_ERR, "Thread %d,%p timeout waiting for thread %d,%p to finish\n", type, &threadCtrl->thread_id, threadCtrl->aq_data->active_thread.ptype, threadCtrl->aq_data->active_thread.thread_id); free(threadCtrl); @@ -856,9 +911,9 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->start_active_time); #endif - logMessage (LOG_NOTICE, "Programming: %s\n", ptypeName(threadCtrl->aq_data->active_thread.ptype)); + LOG(PROG_LOG, LOG_NOTICE, "Programming: %s, %d\n", ptypeName(threadCtrl->aq_data->active_thread.ptype), threadCtrl->aq_data->active_thread.ptype); - logMessage (LOG_DEBUG, "Thread %d,%p is active (%s)\n", + LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p is active (%s)\n", threadCtrl->aq_data->active_thread.ptype, threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype)); @@ -867,12 +922,12 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl) { #ifndef AQ_DEBUG - logMessage(LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aq_data->active_thread.ptype)); + LOG(PROG_LOG, LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aq_data->active_thread.ptype)); #else struct timespec elapsed; clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->last_active_time); timespec_subtract(&elapsed, &threadCtrl->aq_data->last_active_time, &threadCtrl->aq_data->start_active_time); - logMessage(LOG_NOTICE, "Thread %d,%p (%s) finished in %d.%03ld sec\n", + LOG(PROG_LOG, LOG_NOTICE, "Thread %d,%p (%s) finished in %d.%03ld sec\n", threadCtrl->aq_data->active_thread.ptype, threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype), @@ -895,7 +950,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) { - logMessage(LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); + LOG(PROG_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 @@ -907,15 +962,15 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label do { if (waitForMessage(aq_data, searchBuf, 4) != true) { - logMessage(LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); + LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } -//logMessage(LOG_DEBUG,"WAITING for kick value=%d\n",current_val); +//LOG(PROG_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); - logMessage(LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); + LOG(PROG_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { // Increment the field. @@ -934,7 +989,7 @@ bool setAqualinkNumericField_new(struct aqualinkdata *aq_data, char *value_label } if (i++ >= 100) { - logMessage(LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', to '%d'\n",value_label,value); + LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', to '%d'\n",value_label,value); break; } } while(value != current_val); @@ -944,7 +999,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 - logMessage(LOG_DEBUG,"Setting menu item '%s' to %d\n",value_label, value); + LOG(PROG_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 @@ -955,13 +1010,13 @@ bool OLD_setAqualinkNumericField_OLD(struct aqualinkdata *aq_data, char *value_l do { if (waitForMessage(aq_data, searchBuf, 3) != true) { - logMessage(LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); + LOG(PROG_LOG, LOG_WARNING, "AQ_Programmer Could not set numeric input '%s', not found\n",value_label); cancel_menu(); return false; } -//logMessage(LOG_DEBUG,"WAITING for kick value=%d\n",current_val); +//LOG(PROG_LOG, LOG_DEBUG,"WAITING for kick value=%d\n",current_val); sscanf(aq_data->last_message, "%s %d%s", leading, ¤t_val, trailing); - logMessage(LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); + LOG(PROG_LOG, LOG_DEBUG, "%s set to %d, looking for %d\n",value_label,current_val,value); if(value > current_val) { // Increment the field. @@ -1036,10 +1091,10 @@ STOP BOOST POOL } #endif - logMessage(LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); + LOG(PROG_LOG, LOG_DEBUG, "programming BOOST to %s\n", val==true?"On":"Off"); if ( select_menu_item(aq_data, "BOOST POOL") != true ) { - logMessage(LOG_WARNING, "Could not select BOOST POOL menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1059,16 +1114,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); - logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); + LOG(PROG_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); //waitfor_queue2empty(); break; } else { - logMessage(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(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); delay(200); if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) { //_pgm_command = KEY_ENTER; send_cmd(KEY_ENTER); - logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); + LOG(PROG_LOG, LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n"); break; } send_cmd(KEY_RIGHT); @@ -1088,7 +1143,7 @@ STOP BOOST POOL send_cmd(KEY_RIGHT); waitfor_queue2empty(); if ( select_sub_menu_item(aq_data, "STOP BOOST POOL") != true ) { - logMessage(LOG_WARNING, "Could not select STOP BOOST POOL menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select STOP BOOST POOL menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1125,10 +1180,10 @@ void *set_aqualink_SWG( void *ptr ) } #endif - //logMessage(LOG_NOTICE, "programming SWG percent to %d\n", val); + //LOG(PROG_LOG, LOG_NOTICE, "programming SWG percent to %d\n", val); if ( select_menu_item(aq_data, "SET AQUAPURE") != true ) { - logMessage(LOG_WARNING, "Could not select SET AQUAPURE menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET AQUAPURE menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1137,7 +1192,7 @@ 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) { - logMessage(LOG_WARNING, "Could not select SWG setpoint menu for SPA\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu for SPA\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1145,7 +1200,7 @@ 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) { - logMessage(LOG_WARNING, "Could not select SWG setpoint menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1158,7 +1213,7 @@ void *set_aqualink_SWG( void *ptr ) /* if (select_sub_menu_item(aq_data, "SET POOL SP") != true) { - logMessage(LOG_WARNING, "Could not select SWG setpoint menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SWG setpoint menu\n"); cancel_menu(aq_data); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1202,14 +1257,14 @@ void *get_aqualink_aux_labels( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - logMessage(LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "AUX LABELS") != true) { - logMessage(LOG_WARNING, "Could not select AUX LABELS menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select AUX LABELS menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1239,7 +1294,7 @@ void *set_aqualink_light_colormode( void *ptr ) int typ = atoi(&buf[10]); if (btn < 0 || btn >= aq_data->total_buttons ) { - logMessage(LOG_ERR, "Can't program light mode on button %d\n", btn); + LOG(PROG_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -1247,16 +1302,16 @@ void *set_aqualink_light_colormode( void *ptr ) aqkey *button = &aq_data->aqbuttons[btn]; unsigned char code = button->code; - //logMessage(LOG_NOTICE, "Light Programming #: %d, on button: %s, color light type: %d\n", val, button->label, typ); + //LOG(PROG_LOG, LOG_NOTICE, "Light Programming #: %d, on button: %s, color light type: %d\n", val, button->label, typ); mode_name = light_mode_name(typ, val-1); if (mode_name == NULL) { - logMessage(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(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); cleanAndTerminateThread(threadCtrl); return ptr; } else { - logMessage(LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, name '%s'\n", val, button->label, typ, mode_name); + LOG(PROG_LOG, LOG_INFO, "Light Programming #: %d, on button: %s, color light type: %d, name '%s'\n", val, button->label, typ, mode_name); } // Simply turn the light off if value is 0 @@ -1270,11 +1325,11 @@ void *set_aqualink_light_colormode( void *ptr ) // Needs to start programming sequence with light off if ( button->led->state == ON ) { - logMessage(LOG_INFO, "Light Programming Initial state on, turning off\n"); + LOG(PROG_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' - logMessage(LOG_ERR, "Light Programming didn't receive OFF message\n"); + LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive OFF message\n"); } // Now turn on and wait for the message "color mode name<>*" @@ -1284,10 +1339,10 @@ void *set_aqualink_light_colormode( void *ptr ) do{ if ( !waitForMessage(threadCtrl->aq_data, "~*", 3)) - logMessage(LOG_ERR, "Light Programming didn't receive color light mode message\n"); + LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive color light mode message\n"); if (strncasecmp(aq_data->last_message, mode_name, strlen(mode_name)) == 0) { - logMessage(LOG_INFO, "Light Programming found color mode %s\n",mode_name); + LOG(PROG_LOG, LOG_INFO, "Light Programming found color mode %s\n",mode_name); send_cmd(KEY_ENTER); waitfor_queue2empty(); break; @@ -1303,7 +1358,7 @@ void *set_aqualink_light_colormode( void *ptr ) } while (i <= LIGHT_COLOR_OPTIONS); if (i == LIGHT_COLOR_OPTIONS) { - logMessage(LOG_ERR, "Light Programming didn't receive color light mode message for '%s'\n",mode_name); + LOG(PROG_LOG, LOG_ERR, "Light Programming didn't receive color light mode message for '%s'\n",mode_name); } cleanAndTerminateThread(threadCtrl); @@ -1330,7 +1385,7 @@ void *set_aqualink_light_programmode( void *ptr ) float pmode = atof(&buf[20]); if (btn < 0 || btn >= aq_data->total_buttons ) { - logMessage(LOG_ERR, "Can't program light mode on button %d\n", btn); + LOG(PROG_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn); cleanAndTerminateThread(threadCtrl); return ptr; } @@ -1338,7 +1393,7 @@ void *set_aqualink_light_programmode( void *ptr ) aqkey *button = &aq_data->aqbuttons[btn]; unsigned char code = button->code; - logMessage(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(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); // Simply turn the light off if value is 0 if (val <= 0) { @@ -1353,37 +1408,37 @@ 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 ) { - logMessage(LOG_INFO, "Light Programming Initial state off, turning on for %d seconds\n",iOn); + LOG(PROG_LOG, LOG_INFO, "Light Programming Initial state off, turning on for %d seconds\n",iOn); send_cmd(code); delay(iOn * seconds); } - logMessage(LOG_INFO, "Light Programming turn off for %d seconds\n",iOff); + LOG(PROG_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. - logMessage(LOG_INFO, "Light Programming button pulsing on/off %d times\n", val); + LOG(PROG_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++) { - logMessage(LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, i % 2 == 0 ? "Off" : "On", val); + LOG(PROG_LOG, LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, i % 2 == 0 ? "Off" : "On", val); send_cmd(code); delay(pmode * seconds); // 0.3 works, but using 0.4 to be safe } } else { for (i = 1; i < val; i++) { - logMessage(LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "ON", val); + LOG(PROG_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); - logMessage(LOG_INFO, "Light Programming button press number %d - %s of %d\n", i, "OFF", val); + LOG(PROG_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); } - logMessage(LOG_INFO, "Finished - Light Programming button press number %d - %s of %d\n", i, "ON", val); + LOG(PROG_LOG, LOG_INFO, "Finished - Light Programming button press number %d - %s of %d\n", i, "ON", val); send_cmd(code); } //waitForButtonState(aq_data, &aq_data->aqbuttons[btn], ON, 2); @@ -1429,11 +1484,11 @@ void *set_aqualink_pool_heater_temps( void *ptr ) menu_name = "SET POOL TEMP"; } - logMessage(LOG_DEBUG, "Setting pool heater setpoint to %d\n", val); + LOG(PROG_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 ) { - logMessage(LOG_WARNING, "Could not select SET TEMP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1441,7 +1496,7 @@ 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) { - logMessage(LOG_WARNING, "Could not select SET POOL TEMP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET POOL TEMP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1504,11 +1559,11 @@ void *set_aqualink_spa_heater_temps( void *ptr ) menu_name = "SET SPA TEMP"; } - logMessage(LOG_DEBUG, "Setting spa heater setpoint to %d\n", val); + LOG(PROG_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 ) { - logMessage(LOG_WARNING, "Could not select SET TEMP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET TEMP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1516,7 +1571,7 @@ 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) { - logMessage(LOG_WARNING, "Could not select SET SPA TEMP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET SPA TEMP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1562,7 +1617,7 @@ void *set_aqualink_freeze_heater_temps( void *ptr ) */ val = setpoint_check(FREEZE_SETPOINT, val, aq_data); - logMessage(LOG_DEBUG, "Setting sfreeze protection to %d\n", val); + LOG(PROG_LOG, LOG_DEBUG, "Setting sfreeze protection to %d\n", val); #ifdef AQ_PDA if (isPDA_PANEL) { @@ -1573,21 +1628,21 @@ 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 ) { - logMessage(LOG_WARNING, "Could not select SYSTEM SETUP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SYSTEM SETUP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { - logMessage(LOG_WARNING, "Could not select FRZ PROTECT menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "TEMP SETTING") != true) { - logMessage(LOG_WARNING, "Could not select TEMP SETTING menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select TEMP SETTING menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1609,26 +1664,26 @@ void *set_aqualink_time( void *ptr ) struct aqualinkdata *aq_data = threadCtrl->aq_data; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_TIME); - //logMessage(LOG_NOTICE, "Setting time on aqualink\n"); + //LOG(PROG_LOG, LOG_NOTICE, "Setting time on aqualink\n"); time_t now = time(0); // get time now struct tm *result = localtime(&now); - char hour[11]; + char hour[20]; if (result->tm_hour == 0) sprintf(hour, "HOUR 12 AM"); else if (result->tm_hour < 11) - sprintf(hour, "HOUR %d AM", result->tm_hour); + sprintf(hour, "HOUR %.2d AM", result->tm_hour); else if (result->tm_hour == 12) sprintf(hour, "HOUR 12 PM"); else // Must be 13 or more - sprintf(hour, "HOUR %d PM", result->tm_hour - 12); + sprintf(hour, "HOUR %.2d PM", result->tm_hour - 12); - logMessage(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(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); if ( select_menu_item(aq_data, "SET TIME") != true ) { - logMessage(LOG_WARNING, "Could not select SET TIME menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select SET TIME menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1658,14 +1713,14 @@ void *get_aqualink_diag_model( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_DIAGNOSTICS_MODEL); if ( select_menu_item(aq_data, "SYSTEM SETUP") != true ) { - logMessage(LOG_WARNING, "Could not select HELP menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select HELP menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "DIAGNOSTICS") != true) { - logMessage(LOG_WARNING, "Could not select DIAGNOSTICS menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select DIAGNOSTICS menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1681,18 +1736,18 @@ void *get_aqualink_diag_model( void *ptr ) void *get_aqualink_pool_spa_heater_temps( void *ptr ) { -//logMessage(LOG_DEBUG, "Could not select TEMP SET menu\n"); +//LOG(PROG_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); - //logMessage(LOG_NOTICE, "Getting pool & spa heat setpoints from aqualink\n"); + //LOG(PROG_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)) { - logMessage(LOG_ERR, "Error Getting PDA pool & spa heater setpoints\n"); + LOG(PROG_LOG, LOG_ERR, "Error Getting PDA pool & spa heater setpoints\n"); } cleanAndTerminateThread(threadCtrl); return ptr; @@ -1700,14 +1755,14 @@ void *get_aqualink_pool_spa_heater_temps( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - logMessage(LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "TEMP SET") != true) { - logMessage(LOG_WARNING, "Could not select TEMP SET menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select TEMP SET menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1731,12 +1786,12 @@ void *get_freeze_protect_temp( void *ptr ) struct aqualinkdata *aq_data = threadCtrl->aq_data; waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_FREEZE_PROTECT_TEMP); - //logMessage(LOG_NOTICE, "Getting freeze protection setpoints\n"); + //LOG(PROG_LOG, LOG_NOTICE, "Getting freeze protection setpoints\n"); #ifdef AQ_PDA if (isPDA_PANEL) { if (! get_PDA_freeze_protect_temp(aq_data)) { - logMessage(LOG_ERR, "Error Getting PDA freeze protection setpoints\n"); + LOG(PROG_LOG, LOG_ERR, "Error Getting PDA freeze protection setpoints\n"); } cleanAndTerminateThread(threadCtrl); return ptr; @@ -1744,14 +1799,14 @@ void *get_freeze_protect_temp( void *ptr ) #endif if ( select_menu_item(aq_data, "REVIEW") != true ) { - logMessage(LOG_WARNING, "Could not select REVIEW menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "FRZ PROTECT") != true) { - logMessage(LOG_WARNING, "Could not select FRZ PROTECT menu\n"); + LOG(PROG_LOG, LOG_WARNING, "Could not select FRZ PROTECT menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1772,7 +1827,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; - logMessage(LOG_DEBUG, "Send key '%d'\n",cmd); + LOG(PROG_LOG, LOG_DEBUG, "Send key '%d'\n",cmd); send_cmd(cmd); return waitForEitherMessage(aq_data, "NOT SET", "TURNS ON", rtnStringsWait); } @@ -1787,14 +1842,14 @@ void *get_aqualink_programs( void *ptr ) waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_PROGRAMS); if ( select_menu_item(aq_data, "REVIEW") != true ) { - //logMessage(LOG_WARNING, "Could not select REVIEW menu\n"); + //LOG(PROG_LOG, LOG_WARNING, "Could not select REVIEW menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; } if (select_sub_menu_item(aq_data, "PROGRAMS") != true) { - //logMessage(LOG_WARNING, "Could not select PROGRAMS menu\n"); + //LOG(PROG_LOG, LOG_WARNING, "Could not select PROGRAMS menu\n"); cancel_menu(); cleanAndTerminateThread(threadCtrl); return ptr; @@ -1803,22 +1858,22 @@ void *get_aqualink_programs( void *ptr ) unsigned int i; for (i=0; i < strlen(keys); i++) { - //logMessage(LOG_DEBUG, "**** START program for key in loop %d\n",i); + //LOG(PROG_LOG, LOG_DEBUG, "**** START program for key in loop %d\n",i); if (! get_aqualink_program_for_button(aq_data, keys[i])) { - //logMessage(LOG_DEBUG, "**** Didn't find program for key in loop %d\n",i); + //LOG(PROG_LOG, LOG_DEBUG, "**** Didn't find program for key in loop %d\n",i); //cancel_menu(aq_data); cleanAndTerminateThread(threadCtrl); return ptr; } - //logMessage(LOG_DEBUG, "**** Found program for key in loop %d\n",i); + //LOG(PROG_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)) { - //logMessage(LOG_DEBUG, "Send key ENTER\n"); + //LOG(PROG_LOG, LOG_DEBUG, "Send key ENTER\n"); send_cmd(KEY_ENTER); } else { - //logMessage(LOG_DEBUG, "Send CANCEL\n"); + //LOG(PROG_LOG, LOG_DEBUG, "Send CANCEL\n"); cancel_menu(); } @@ -1833,7 +1888,7 @@ void *get_aqualink_programs( void *ptr ) void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) { push_aq_cmd(cmd); - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller\n", cmd); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", cmd); } */ @@ -1844,7 +1899,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. - //logMessage(LOG_DEBUG, "******** QUEUE IS FULL ******** delay\n"); + //LOG(PROG_LOG, LOG_DEBUG, "******** QUEUE IS FULL ******** delay\n"); delay(50); } @@ -1857,7 +1912,7 @@ void _waitfor_queue2empty(bool longwait) } } #endif - logMessage(LOG_WARNING, "Send command Queue did not empty, timeout\n"); + LOG(PROG_LOG, LOG_WARNING, "Send command Queue did not empty, timeout\n"); } } @@ -1878,7 +1933,7 @@ void send_cmd(unsigned char cmd) _pgm_command = cmd; //delay(200); - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller (programming)\n", _pgm_command); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller (programming)\n", _pgm_command); } /* @@ -1894,7 +1949,7 @@ void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data) aq_data->aq_command = cmd; //delay(200); - logMessage(LOG_INFO, "Queue send '0x%02hhx' to controller\n", aq_data->aq_command); + LOG(PROG_LOG, LOG_INFO, "Queue send '0x%02hhx' to controller\n", aq_data->aq_command); } */ @@ -1909,7 +1964,7 @@ void cancel_menu() bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived) { - //logMessage(LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); + //LOG(PROG_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); @@ -1933,12 +1988,12 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me while( ++i <= numMessageReceived) { - logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' OR '%s' received message1 '%s'\n",i,numMessageReceived,message1,message2,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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 - logMessage(LOG_DEBUG, "Programming mode: String MATCH '%s'\n", msgS1); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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 @@ -1948,7 +2003,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 - logMessage(LOG_DEBUG, "Programming mode: String MATCH '%s'\n", msgS2); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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 @@ -1956,19 +2011,19 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me } } - //logMessage(LOG_DEBUG, "Programming mode: looking for '%s' received message1 '%s'\n",message1,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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); - //logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message1 '%s'\n",i,numMessageReceived,message1,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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"); - logMessage(LOG_DEBUG, "Programming mode: did not find '%s'\n",message1); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: did not find '%s'\n",message1); return false; } - logMessage(LOG_DEBUG, "Programming mode: found message1 '%s' or '%s' in '%s'\n",message1,message2,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: found message1 '%s' or '%s' in '%s'\n",message1,message2,aq_data->last_message); return true; } @@ -1977,7 +2032,7 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived) { - logMessage(LOG_DEBUG, "waitForMessage %s %d\n",message,numMessageReceived); + LOG(PROG_LOG, LOG_DEBUG, "waitForMessage %s %d\n",message,numMessageReceived); waitfor_queue2empty(); // MAke sure the last command was sent int i=0; @@ -1995,14 +2050,14 @@ bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageR while( ++i <= numMessageReceived) { if (message != NULL) - logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s', last message received '%s'\n",i,numMessageReceived,message,aq_data->last_message); else - logMessage(LOG_DEBUG, "Programming mode: loop %d of %d waiting for next message, last message received '%s'\n",i,numMessageReceived,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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 - logMessage(LOG_DEBUG, "Programming mode: String MATCH\n"); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: String MATCH\n"); if (msgS == message) // match & don't care if first char break; else if (ptr == aq_data->last_message) // match & do care if first char @@ -2010,23 +2065,23 @@ bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageR } } - //logMessage(LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aq_data->last_message); - //logMessage(LOG_DEBUG, "*** pthread_cond_wait() sleep\n"); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "*** pthread_cond_wait() sleep\n"); pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); - //logMessage(LOG_DEBUG, "*** pthread_cond_wait() wake\n"); - //logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "*** pthread_cond_wait() wake\n"); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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) { - //logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n"); - logMessage(LOG_DEBUG, "Programming mode: did not find '%s'\n",message); + //LOG(PROG_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: did not find '%s'\n",message); return false; } else if (message != NULL) - logMessage(LOG_DEBUG, "Programming mode: found message '%s' in '%s'\n",message,aq_data->last_message); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: found message '%s' in '%s'\n",message,aq_data->last_message); else - logMessage(LOG_DEBUG, "Programming mode: waited for %d message(s)\n",numMessageReceived); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: waited for %d message(s)\n",numMessageReceived); return true; } @@ -2088,17 +2143,17 @@ bool select_sub_menu_item(struct aqualinkdata *aq_data, char* item_string) while( (stristr(aq_data->last_message, item_string) == NULL) && ( i++ < wait_messages) ) { - logMessage(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(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); send_cmd(KEY_RIGHT); waitForMessage(aq_data, NULL, 1); } if (stristr(aq_data->last_message, item_string) == NULL) { - //logMessage(LOG_ERR, "Could not select SUB_MENU of Aqualink control panel\n"); + //LOG(PROG_LOG, LOG_ERR, "Could not select SUB_MENU of Aqualink control panel\n"); return false; } - logMessage(LOG_DEBUG, "Find item in Menu: loop %d of %d FOUND menu item '%s', sending ENTER command\n",i,wait_messages, item_string); + 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); // Enter the mode specified by the argument. @@ -2118,32 +2173,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) { - //logMessage(LOG_DEBUG, "waitForMessage %s %d %d\n",message,numMessageReceived,cmd); + //LOG(PROG_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) { - logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for state change to '%d' for '%s' \n",i,numMessageReceived,button->led->state,button->name); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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) { - logMessage(LOG_INFO, "Programming mode: Button State =%d for %s\n",state,button->name); + LOG(PROG_LOG, LOG_INFO, "Programming mode: Button State =%d for %s\n",state,button->name); break; } - //logMessage(LOG_DEBUG, "Programming mode: looking for '%s' received message '%s'\n",message,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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); - //logMessage(LOG_DEBUG, "Programming mode: loop %d of %d looking for '%s' received message '%s'\n",i,numMessageReceived,message,aq_data->last_message); + //LOG(PROG_LOG, LOG_DEBUG, "Programming mode: 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) { - //logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n"); - logMessage(LOG_DEBUG, "Programming mode: did not find state '%d' for '%s'\n",button->led->state,button->name); + //LOG(PROG_LOG, LOG_ERR, "Could not select MENU of Aqualink control panel\n"); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: did not find state '%d' for '%s'\n",button->led->state,button->name); return false; } - logMessage(LOG_DEBUG, "Programming mode: found state '%d' for '%s'\n",button->led->state,button->name); + LOG(PROG_LOG, LOG_DEBUG, "Programming mode: found state '%d' for '%s'\n",button->led->state,button->name); return true; } @@ -2193,6 +2248,9 @@ const char *ptypeName(program_type type) case AQ_SET_PUMP_VS_PROGRAM: return "Set Pump VS Program"; break; + case AQ_GET_AUX_LABELS: + return "Get AUX labels"; + break; #ifdef AQ_ONETOUCH case AQ_SET_ONETOUCH_PUMP_RPM: return "Set OneTouch Pump RPM"; @@ -2264,9 +2322,6 @@ const char *ptypeName(program_type type) case AQ_PDA_DEVICE_ON_OFF: return "Switch PDA device on/off"; break; - case AQ_GET_AUX_LABELS: - return "Get AUX labels"; - break; case AQ_PDA_WAKE_INIT: return "PDA init after wake"; break; diff --git a/aq_programmer.h b/aq_programmer.h index 1744440..780fbad 100644 --- a/aq_programmer.h +++ b/aq_programmer.h @@ -74,6 +74,7 @@ typedef enum { AQ_SET_IAQTOUCH_SET_TIME } program_type; + struct programmingThreadCtrl { pthread_t thread_id; //void *thread_args; diff --git a/aq_serial.c b/aq_serial.c index eb8d140..941b85b 100644 --- a/aq_serial.c +++ b/aq_serial.c @@ -33,7 +33,10 @@ //#define USE_AQ_SERIAL_OLD +//#define BLOCKING_MODE +static bool _blocking_mode = false; +int _blocking_fds = -1; #ifndef USE_AQ_SERIAL_OLD // Substansial changes to core component, make sure we can role back easily @@ -306,8 +309,75 @@ Open and Initialize the serial communications port to the Aqualink RS8 device. Arg is tty or port designation string returns the file descriptor */ +//#define TXDEN_DUMMY_RS485_MODE + +#ifdef TXDEN_DUMMY_RS485_MODE + +#include +/* RS485 ioctls: */ +#define TIOCGRS485 0x542E +#define TIOCSRS485 0x542F + +int init_serial_port_Pi(const char* tty) +{ + struct serial_rs485 rs485conf = {0}; + + //int fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK); + int fd = open(tty, O_RDWR); + if (fd < 0) { + LOG(RSSD_LOG,LOG_ERR, "Unable to open port: %s\n", tty); + return -1; + } + + LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Openeded serial port %s\n",tty); + + if (ioctl (fd, TIOCGRS485, &rs485conf) < 0) { + LOG(RSSD_LOG,LOG_ERR, "Error reading ioctl port (%d): %s\n", errno, strerror( errno )); + return -1; + } + + LOG(RSSD_LOG,LOG_DEBUG, "Port currently RS485 mode is %s\n", (rs485conf.flags & SER_RS485_ENABLED) ? "set" : "NOT set"); + + /* Enable RS485 mode: */ + rs485conf.flags |= SER_RS485_ENABLED; + + /* Set logical level for RTS pin equal to 1 when sending: */ + rs485conf.flags |= SER_RS485_RTS_ON_SEND; + /* or, set logical level for RTS pin equal to 0 when sending: */ + //rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND); + + /* Set logical level for RTS pin equal to 1 after sending: */ + rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; + /* or, set logical level for RTS pin equal to 0 after sending: */ + //rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); + + /* Set this flag if you want to receive data even whilst sending data */ + //rs485conf.flags |= SER_RS485_RX_DURING_TX; + + if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { + LOG(RSSD_LOG,LOG_ERR, "Unable to set port to RS485 %s (%d): %s\n", tty, errno, strerror( errno )); + return -1; + } + + return fd; +} +#endif + +int _init_serial_port(const char* tty, bool blocking); + int init_serial_port(const char* tty) { + return _init_serial_port(tty, false); +} +int init_blocking_serial_port(const char* tty) +{ + _blocking_fds = _init_serial_port(tty, true); + return _blocking_fds; +} + +int _init_serial_port(const char* tty, bool blocking) +{ + long BAUD = B9600; long DATABITS = CS8; long STOPBITS = 0; @@ -316,6 +386,8 @@ int init_serial_port(const char* tty) 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) { @@ -323,13 +395,22 @@ int init_serial_port(const char* tty) return -1; } - LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Openeded serial port %s\n",tty); + LOG(RSSD_LOG,LOG_DEBUG, "Openeded serial port %s\n",tty); - 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; - LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Set serial port %s to non blocking mode\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; + LOG(RSSD_LOG,LOG_DEBUG, "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; + LOG(RSSD_LOG,LOG_DEBUG, "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 @@ -341,11 +422,20 @@ int init_serial_port(const char* tty) tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); - LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Set serial port %s io attributes\n",tty); + LOG(RSSD_LOG,LOG_DEBUG, "Set serial port %s io attributes\n",tty); return fd; } +void close_blocking_serial_port() +{ + if (_blocking_fds > 0) { + LOG(RSSD_LOG,LOG_INFO, "Forcing close of blocking serial port, ignore following read errors\n"); + close_serial_port(_blocking_fds); + } else { + LOG(RSSD_LOG,LOG_ERR, "Didn't find valid blocking serial port file descripter\n"); + } +} /* close tty port */ void close_serial_port(int fd) { @@ -355,11 +445,6 @@ void close_serial_port(int fd) } - - - - - // Send an ack packet to the Aqualink RS8 master device. // fd: the file descriptor of the serial port connected to the device // command: the command byte to send to the master device, NUL if no command @@ -530,35 +615,45 @@ void send_command(int fd, unsigned char *packet_buffer, int size) void send_packet(int fd, unsigned char *packet, int length) { - if (_aqconfig_.readahead_b4_write) { - unsigned char byte; - int r; - //int j=0; - do { - //j++; - r = read(fd, &byte, 1); - //printf("*** Peek Read %d 0x%02hhx ***\n",r,byte); - if (r==1 && byte != 0x00) { - LOG(RSSD_LOG,LOG_ERR, "SERIOUS ERROR on RS485, AqualinkD was too slow in replying to message! (please check OS for performance issues)\n"); - return; - } - } while (r==1 && byte==0x00); - } + if (_blocking_mode) { + write(fd, packet, length); + } else { + if (_aqconfig_.readahead_b4_write) { + unsigned char byte; + int bytesRead; + // int j=0; + do { + // j++; + bytesRead = read(fd, &byte, 1); + // printf("*** Peek Read %d 0x%02hhx ***\n",r,byte); + if (bytesRead == 1 && byte != 0x00) { + LOG(RSSD_LOG, LOG_ERR, "ERROR on RS485, AqualinkD was too slow in replying to message! (please check for performance issues)\n"); + do { // Just play catchup + bytesRead = read(fd, &byte, 1); + // if (bytesRead==1) { LOG(RSSD_LOG,LOG_ERR, "Error Cleanout read 0x%02hhx\n",byte); } + } while (bytesRead == 1); - int nwrite, i; - for (i=0; i= LOG_DEBUG) { - debuglogPacket(&packet[1], length-2); - } -#endif -*/ + return; + } + } while (bytesRead == 1 && byte == 0x00); + } + + int nwrite, i; + for (i = 0; i < length; i += nwrite) { + nwrite = write(fd, packet + i, length - i); + if (nwrite < 0) + LOG(RSSD_LOG, LOG_ERR, "write to serial port failed\n"); + } + } // _blockine_mode + + /* + #ifdef AQ_DEBUG + // Need to take this out for release + if ( getLogLevel(RSSD_LOG) >= LOG_DEBUG) { + debuglogPacket(&packet[1], length-2); + } + #endif + */ if ( getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL) { // Packet is padded with 0x00, so discard for logging LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial write %d bytes\n",length-2); @@ -634,6 +729,7 @@ int _get_packet(int fd, unsigned char* packet, bool rawlog) while (!endOfPacket) { bytesRead = read(fd, &byte, 1); +//printf("Read %d 0x%02hhx err=%d\n",bytesRead,byte,errno); //if (bytesRead < 0 && errno == EAGAIN && packetStarted == FALSE && lastByteDLE == FALSE) { if (bytesRead < 0 && errno == EAGAIN && jandyPacketStarted == false && diff --git a/aq_serial.h b/aq_serial.h index 3eef82a..3c71d6a 100644 --- a/aq_serial.h +++ b/aq_serial.h @@ -425,7 +425,9 @@ typedef enum { int init_serial_port(const char* tty); +int init_blocking_serial_port(const char* tty); void close_serial_port(int file_descriptor); +void close_blocking_serial_port(); //#ifdef AQ_PDA //void set_pda_mode(bool mode); //bool pda_mode(); diff --git a/aqualink.h b/aqualink.h index fa17c9a..7a10793 100644 --- a/aqualink.h +++ b/aqualink.h @@ -8,7 +8,7 @@ #include "aq_programmer.h" #include "aq_panel.h" -#define DEFAULT_MG_NET_WAIT 2 +#define DEFAULT_POLL_SPEED 2 #define TIME_CHECK_INTERVAL 3600 #define ACCEPTABLE_TIME_DIFF 120 @@ -19,6 +19,10 @@ #define MAX_ZERO_READ_BEFORE_RECONNECT 10000 // 2k normally +void intHandler(int dummy); + +// There are cases where SWG will read 80% in allbutton and 0% in onetouch/aqualinktouch, this will compile that in or our +//#define READ_SWG_FROM_EXTENDED_ID //#define TOTAL_BUTTONS 12 /* diff --git a/aqualinkd.c b/aqualinkd.c index 8c58d5d..07a5753 100644 --- a/aqualinkd.c +++ b/aqualinkd.c @@ -49,29 +49,41 @@ #include "iaqtouch_aq_programmer.h" #include "version.h" #include "rs_msg_utils.h" +#include "debug_timer.h" -#ifdef AQ_DEBUG +/* +#if defined AQ_DEBUG || defined AQ_TM_DEBUG #include "timespec_subtract.h" - //#define AQ_DEBUG_TIME_ACK #endif - +*/ //#define DEFAULT_CONFIG_FILE "./aqualinkd.conf" static volatile bool _keepRunning = true; //static struct aqconfig _aqconfig_; static struct aqualinkdata _aqualink_data; -#ifdef AQ_DEBUG_TIME_ACK - struct timespec _rs_packet_readitme; + +#ifdef AQ_TM_DEBUG + //struct timespec _rs_packet_readitme; + int _rs_packet_timer; #endif + void main_loop(); void intHandler(int dummy) { _keepRunning = false; - LOG(AQUA_LOG,LOG_NOTICE, "Stopping!"); - if (dummy){}// stop compile warnings + LOG(AQUA_LOG,LOG_NOTICE, "Stopping!\n"); + //if (dummy){}// stop compile warnings + + // In blocking mode, die as cleanly as possible. + if (_aqconfig_.rs_poll_speed < 0) { + stopPacketLogger(); + // This should force port to close and do somewhat gracefull exit. + close_blocking_serial_port(); + //exit(-1); + } } void processLEDstate() @@ -307,11 +319,11 @@ void _processMessage(char *message, bool reset) _aqualink_data.frz_protect_state = OFF; if ((msg_loop & MSG_SERVICE) != MSG_SERVICE && - (msg_loop & MSG_SERVICE) != MSG_TIMEOUT ) { + (msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) { _aqualink_data.service_mode_state = OFF; // IF we get this message then Service / Timeout is off } - if ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) { + if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && _aqualink_data.swg_led_state != LED_S_UNKNOWN) { // No Additional SWG devices messages like "no flow" if ((msg_loop & MSG_SWG) != MSG_SWG && _aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF ) setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_OFF); @@ -362,7 +374,7 @@ void _processMessage(char *message, bool reset) //if ( _aqconfig_.rs_panel_size >= 16) { //if ( (int)PANEL_SIZE >= 16) { // NSF No idea why this fails on RS-4, but it does. Come back and find out why if ( PANEL_SIZE() >= 16 ) { - printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE()); + //printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE()); if ((msg_loop & MSG_RS13BUTTON) != MSG_RS13BUTTON) _aqualink_data.aqbuttons[13].led->state = OFF; if ((msg_loop & MSG_RS14BUTTON) != MSG_RS14BUTTON) @@ -533,7 +545,11 @@ void _processMessage(char *message, bool reset) LOG(AQRS_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 + 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); + } + else if (_initWithRS == true) { LOG(AQRS_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", _aqualink_data.time, _aqualink_data.date); } @@ -911,6 +927,10 @@ int main(int argc, char *argv[]) _aqualink_data.num_pumps = 0; _aqualink_data.num_lights = 0; +#ifdef AQ_TM_DEBUG + addDebugLogMask(DBGT_LOG); + init_aqd_timer(); // Must clear timers. +#endif // Any debug logging masks //addDebugLogMask(IAQT_LOG); //addDebugLogMask(ONET_LOG); @@ -1002,8 +1022,8 @@ int main(int argc, char *argv[]) #if defined AQ_ONETOUCH || defined AQ_IAQTOUCH if (_aqconfig_.extended_device_id != 0x00) { - if (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33 || - _aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) { + if ( (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) || + (_aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) ) { // We are good } else { LOG(AQUA_LOG,LOG_ERR, "Extended Device ID 0x%02hhx does not match OneTouch or AqualinkTouch ID, please check config!\n", _aqconfig_.extended_device_id); @@ -1100,8 +1120,28 @@ int main(int argc, char *argv[]) if (_aqconfig_.readahead_b4_write == true) LOG(AQUA_LOG,LOG_NOTICE, "Serial Read Ahead Write = %s\n", bool2text(_aqconfig_.readahead_b4_write)); - if (_aqconfig_.net_poll_wait != DEFAULT_MG_NET_WAIT) - LOG(AQUA_LOG,LOG_NOTICE, "Network Poll Speed = %d\n", _aqconfig_.net_poll_wait); + if (_aqconfig_.rs_poll_speed != DEFAULT_POLL_SPEED) + LOG(AQUA_LOG,LOG_NOTICE, "RS Poll Speed = %d\n", _aqconfig_.rs_poll_speed); + + if (_aqconfig_.thread_netservices) + LOG(AQUA_LOG,LOG_NOTICE, "Thread Network Services = %s\n", bool2text(_aqconfig_.thread_netservices)); + + if (_aqconfig_.rs_poll_speed < 0 && !_aqconfig_.thread_netservices) { + LOG(AQUA_LOG,LOG_WARNING, "Negative RS Poll Speed is only valid when using Thread Network Services, resetting to %d\n",DEFAULT_POLL_SPEED); + _aqconfig_.rs_poll_speed = DEFAULT_POLL_SPEED; + } + if (_aqconfig_.rs_poll_speed < 0 && _aqconfig_.readahead_b4_write) { + LOG(AQUA_LOG,LOG_WARNING, "Serial Read Ahead Write is not valid when using Negative RS Poll Speed, turning Serial Read Ahead Write off\n"); + _aqconfig_.readahead_b4_write = false; + } + + if (_aqconfig_.rs_poll_speed < 0) { + LOG(AQUA_LOG,LOG_WARNING, "**************************************************************************************************\n"); + LOG(AQUA_LOG,LOG_WARNING, "* RS Poll Speed of %d is expermental, this put's USB in complete blocking mode *\n",_aqconfig_.rs_poll_speed); + LOG(AQUA_LOG,LOG_WARNING, "* if USB becomes unstable / connection to panel lost, AqualinkD may need to be killed manually *\n"); + LOG(AQUA_LOG,LOG_WARNING, "* eg:- sudo kill -9 *\n"); + LOG(AQUA_LOG,LOG_WARNING, "**************************************************************************************************\n"); + } //for (i = 0; i < TOTAL_BUTONS; i++) for (i = 0; i < _aqualink_data.total_buttons; i++) @@ -1162,10 +1202,12 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type switch (source) { case ALLBUTTON: send_extended_ack(rs_fd, (packet_buffer[PKT_CMD]==CMD_MSG_LONG?ACK_SCREEN_BUSY_SCROLL:ACK_NORMAL), pop_aq_cmd(&_aqualink_data)); + //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AllButton Emulation type Processed packet in"); break; #ifdef AQ_ONETOUCH case ONETOUCH: send_extended_ack(rs_fd, ACK_ONETOUCH, pop_ot_cmd(packet_buffer[PKT_CMD])); + //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"OneTouch Emulation type Processed packet in"); break; #endif #ifdef AQ_IAQTOUCH @@ -1178,6 +1220,7 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type send_jandy_command(rs_fd, cmd, size); rem_iaqt_control_cmd(cmd); } + //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AquaTouch Emulation type Processed packet in"); break; #endif #ifdef AQ_PDA @@ -1188,20 +1231,24 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type } else { send_extended_ack(rs_fd, ACK_PDA, pop_aq_cmd(&_aqualink_data)); } + //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"PDA Emulation type Processed packet in"); break; #endif default: LOG(AQUA_LOG,LOG_WARNING, "Can't caculate ACK, No idea what packet this source packet was for!\n"); + //DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"Unknown Emulation type Processed packet in"); break; } -#ifdef AQ_DEBUG_TIME_ACK +/* +#ifdef AQ_TM_DEBUG static struct timespec now; static struct timespec elapsed; clock_gettime(CLOCK_REALTIME, &now); timespec_subtract(&elapsed, &now, &_rs_packet_readitme); - LOG(AQUA_LOG,LOG_NOTICE, "Packet processed in %d.%02ld sec (%08ld ns)\n", elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); + LOG(AQUA_LOG,LOG_NOTICE, "Emulation type %d. Processed packet in %d.%02ld sec (%08ld ns)\n",source, elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); #endif +*/ } /* @@ -1364,9 +1411,18 @@ void main_loop() signal(SIGINT, intHandler); signal(SIGTERM, intHandler); + signal(SIGQUIT, intHandler); int blank_read = 0; - rs_fd = init_serial_port(_aqconfig_.serial_port); + if (_aqconfig_.rs_poll_speed < 0) + rs_fd = init_blocking_serial_port(_aqconfig_.serial_port); + else + rs_fd = init_serial_port(_aqconfig_.serial_port); + + if (rs_fd == -1) { + LOG(AQUA_LOG,LOG_ERR, "Error Aqualink setting serial port: %s\n", _aqconfig_.serial_port); + exit(EXIT_FAILURE); + } LOG(AQUA_LOG,LOG_NOTICE, "Listening to Aqualink RS8 on serial port: %s\n", _aqconfig_.serial_port); #ifdef AQ_PDA @@ -1434,11 +1490,11 @@ void main_loop() // Loop until we get the probe messages, that means we didn;t start too soon after last shutdown. while ( (got_probe == false || got_probe_extended == false ) && _keepRunning == true) { - if (blank_read == 10) { + if (blank_read == MAX_ZERO_READ_BEFORE_RECONNECT) { LOG(AQUA_LOG,LOG_ERR, "Nothing read on '%s', are you sure that's right?\n",_aqconfig_.serial_port); - } else if (blank_read == 50) { + } else if (blank_read == MAX_ZERO_READ_BEFORE_RECONNECT*2) { LOG(AQUA_LOG,LOG_ERR, "Nothing read on '%s', are you sure that's right?\n",_aqconfig_.serial_port); - } else if (blank_read == 150) { + } else if (blank_read == MAX_ZERO_READ_BEFORE_RECONNECT*3) { LOG(AQUA_LOG,LOG_ERR, "I'm done, exiting, please check '%s'\n",_aqconfig_.serial_port); return; } @@ -1484,11 +1540,11 @@ void main_loop() else if (packet_length <= 0) { blank_read++; //printf("Blank Reads %d\n",blank_read); - delay(200); + delay(2); } else if (packet_length > 0) { blank_read = 0; - if (i++ > 1000) { // 1000 packets without a probe to BOTH ID's, give up config is wrong + if (i++ > 1000) { if(!got_probe) { LOG(AQUA_LOG,LOG_ERR, "No probe on '0x%02hhx', giving up! (please check config)\n",_aqconfig_.device_id); } @@ -1499,7 +1555,8 @@ void main_loop() #endif stopPacketLogger(); close_serial_port(rs_fd); - mg_mgr_free(&mgr); + //mg_mgr_free(&mgr); + stop_net_services(&mgr); return; } } @@ -1515,14 +1572,16 @@ void main_loop() * */ +//int max_blank_read = 0; + _aqconfig_.readahead_b4_write = read_ahead; LOG(AQUA_LOG,LOG_NOTICE, "Starting communication with Control Panel\n"); int blank_read_reconnect = MAX_ZERO_READ_BEFORE_RECONNECT; // Not the best way to do this, but ok for moment - if (_aqconfig_.net_poll_wait <= 1) - blank_read_reconnect = MAX_ZERO_READ_BEFORE_RECONNECT * 10; + //if (_aqconfig_.net_poll_wait <= 1) + // blank_read_reconnect = MAX_ZERO_READ_BEFORE_RECONNECT; blank_read = 0; // OK, Now go into infinate loop @@ -1531,6 +1590,7 @@ void main_loop() //printf("%d ",blank_read); while ((rs_fd < 0 || blank_read >= blank_read_reconnect) && _keepRunning == true) { + printf("rs_fd =% d\n",rs_fd); if (rs_fd < 0) { // sleep(1); @@ -1545,8 +1605,13 @@ void main_loop() { LOG(AQUA_LOG,LOG_ERR, "Aqualink daemon looks like serial error, resetting.\n"); close_serial_port(rs_fd); + + if (_aqconfig_.rs_poll_speed < 0) + rs_fd = init_blocking_serial_port(_aqconfig_.serial_port); + else + rs_fd = init_serial_port(_aqconfig_.serial_port); } - rs_fd = init_serial_port(_aqconfig_.serial_port); + blank_read = 0; } @@ -1563,14 +1628,16 @@ void main_loop() } else if (packet_length == 0) { - //LOG(AQUA_LOG,LOG_DEBUG_SERIAL, "Nothing read on serial\n"); + //if (blank_read > max_blank_read) { + // LOG(AQUA_LOG,LOG_NOTICE, "Nothing read on serial %d\n",blank_read); + // max_blank_read = blank_read; + //} blank_read++; } else if (packet_length > 0) { -#ifdef AQ_DEBUG_TIME_ACK - clock_gettime(CLOCK_REALTIME, &_rs_packet_readitme); -#endif + DEBUG_TIMER_START(&_rs_packet_timer); + blank_read = 0; //changed = false; @@ -1586,17 +1653,21 @@ void main_loop() else #endif caculate_ack_packet(rs_fd, packet_buffer, ALLBUTTON); + + DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AllButton Emulation Processed packet in"); } #ifdef AQ_ONETOUCH else if (packet_length > 0 && isONET_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) { _aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH); + DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"OneTouch Emulation Processed packet in"); } #endif #ifdef AQ_IAQTOUCH else if (packet_length > 0 && isIAQT_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) { _aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data); caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH); + DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AquaTouch Emulation Processed packet in"); } #endif else if (packet_length > 0 && _aqconfig_.read_all_devices == true) @@ -1644,19 +1715,24 @@ void main_loop() //broadcast_aqualinkstate(mgr.active_connections); _aqualink_data.updated = true; } - } + } + DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"Processed (readonly) packet in"); + } else { + DEBUG_TIMER_CLEAR(_rs_packet_timer); // Clear timer, no need to print anything } if (_aqualink_data.updated) { broadcast_aqualinkstate(mgr.active_connections); - _aqualink_data.updated = false; + //_aqualink_data.updated = false; } } //mg_mgr_poll(&mgr, 10); //mg_mgr_poll(&mgr, 5); - mg_mgr_poll(&mgr, packet_length>0?0:_aqconfig_.net_poll_wait); // Don;t wait if we read something. - //tcdrain(rs_fd); // Make sure buffer has been sent. + //mg_mgr_poll(&mgr, packet_length>0?0:_aqconfig_.net_poll_wait); // Don;t wait if we read something. + poll_net_services(&mgr, packet_length>0?0:_aqconfig_.rs_poll_speed); // Don;t wait if we read something. + + tcdrain(rs_fd); // Make sure buffer has been sent. //mg_mgr_poll(&mgr, 0); // Any unactioned commands @@ -1671,20 +1747,22 @@ void main_loop() } } - //tcdrain(rs_fd); // Make sure buffer has been sent. //delay(10); } //if (_aqconfig_.debug_RSProtocol_packets) stopPacketLogger(); stopPacketLogger(); + + // Stop network + stop_net_services(&mgr); + // Reset and close the port. close_serial_port(rs_fd); // Clear webbrowser - mg_mgr_free(&mgr); + //mg_mgr_free(&mgr); // NSF need to run through config memory and clean up. - LOG(AQUA_LOG,LOG_NOTICE, "Exit!\n"); exit(EXIT_FAILURE); } diff --git a/config.c b/config.c index 4a217ae..80e03ad 100644 --- a/config.c +++ b/config.c @@ -123,7 +123,8 @@ void init_parameters (struct aqconfig * parms) parms->log_raw_RS_bytes = false; parms->readahead_b4_write = false; parms->sync_panel_time = true; - parms->net_poll_wait = DEFAULT_MG_NET_WAIT; + parms->rs_poll_speed = DEFAULT_POLL_SPEED; + parms->thread_netservices = false; generate_mqtt_id(parms->mqtt_ID, MQTT_ID_LEN); } @@ -517,7 +518,14 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) { _aqconfig_.sync_panel_time = text2bool(value); rtn=true; } else if (strncasecmp (param, "network_poll_speed", 18) == 0) { - _aqconfig_.net_poll_wait = strtoul(value, NULL, 10); + LOG(AQUA_LOG,LOG_WARNING, "Config error, 'network_poll_speed' is no longer supported, using value for 'rs_poll_speed'\n"); + _aqconfig_.rs_poll_speed = strtoul(value, NULL, 10); + rtn=true; + } else if (strncasecmp (param, "rs_poll_speed", 13) == 0) { + _aqconfig_.rs_poll_speed = strtoul(value, NULL, 10); + rtn=true; + } else if (strncasecmp (param, "thread_netservices", 18) == 0) { + _aqconfig_.thread_netservices = text2bool(value); rtn=true; } diff --git a/config.h b/config.h index c1cccc5..0547c6e 100644 --- a/config.h +++ b/config.h @@ -73,7 +73,8 @@ struct aqconfig bool readahead_b4_write; bool mqtt_timed_update; bool sync_panel_time; - int net_poll_wait; + int rs_poll_speed; + bool thread_netservices; }; #ifndef CONFIG_C diff --git a/debug_timer.c b/debug_timer.c new file mode 100644 index 0000000..de9d774 --- /dev/null +++ b/debug_timer.c @@ -0,0 +1,119 @@ + +#ifdef AQ_TM_DEBUG +#include +#include +#include "debug_timer.h" +#include "utils.h" +//#include "timespec_subtract.h" + +#define NUM_DEBUG_TIMERS 10 + +static struct timespec _start_time[NUM_DEBUG_TIMERS]; +static int _timeid=0; + +void init_aqd_timer(int *timeid) +{ + int i=0; + for(i=0; i < NUM_DEBUG_TIMERS; i++) { + _start_time[i].tv_sec = 0; + _start_time[i].tv_nsec = 0; + } +} + +void start_aqd_timer(int *id) +{ + bool maxloop=false; + // Just a sanity check, should be redundant. + if (_timeid >= NUM_DEBUG_TIMERS) + _timeid = 0; + + while (_start_time[_timeid].tv_sec != 0 && _start_time[_timeid].tv_nsec != 0) { + if (++_timeid >= NUM_DEBUG_TIMERS) { + if (maxloop) { // Means we ranover loop twice + LOG(DBGT_LOG,LOG_ERR,"Ranout of debug timers\n"); + *id = -1; + return; + } else { + _timeid = 0; + maxloop=true; + } + } + } + + clock_gettime(CLOCK_REALTIME, &_start_time[_timeid++]); + *id = _timeid-1; + //return _timeid-1; +} + +void clear_aqd_timer(int timeid) { + _start_time[timeid].tv_sec = 0; + _start_time[timeid].tv_nsec = 0; +} + +void stop_aqd_timer(int timeid, int16_t from, char *message) +{ + if (timeid < 0 || timeid >= NUM_DEBUG_TIMERS) { + LOG(from,LOG_ERR,"Invalid timeid '%d' for message '%s'\n", timeid, message); + return; + } + static struct timespec now; + static struct timespec elapsed; + clock_gettime(CLOCK_REALTIME, &now); + timespec_subtract(&elapsed, &now, &_start_time[timeid]); + //DBGT_LOG + //LOG(from,LOG_NOTICE, "%s %d.%02ld sec (%08ld ns)\n", message, elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); + LOG(DBGT_LOG,LOG_DEBUG, "%s %s %d.%02ld sec (%08ld ns)\n", logmask2name(from), message, elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); + + // We've used it so free it. + clear_aqd_timer(timeid); +} + +/* Copyright (c) 1991, 1999 Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * + * You are free to use this software under the terms of the GNU General + * Public License, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + */ + + +/* Based on https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html + Subtract the struct timespec values X and Y, + storing the result in RESULT. + Return 1 if the difference is negative, otherwise 0. */ + +//#include +//#include "timespec_subtract.h" + +int timespec_subtract (struct timespec *result, const struct timespec *x, + const struct timespec *y) +{ + struct timespec tmp; + + memcpy (&tmp, y, sizeof(struct timespec)); + /* Perform the carry for the later subtraction by updating y. */ + if (x->tv_nsec < tmp.tv_nsec) + { + int nsec = (tmp.tv_nsec - x->tv_nsec) / 1000000000 + 1; + tmp.tv_nsec -= 1000000000 * nsec; + tmp.tv_sec += nsec; + } + if (x->tv_nsec - tmp.tv_nsec > 1000000000) + { + int nsec = (x->tv_nsec - tmp.tv_nsec) / 1000000000; + tmp.tv_nsec += 1000000000 * nsec; + tmp.tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_nsec is certainly positive. */ + result->tv_sec = x->tv_sec - tmp.tv_sec; + result->tv_nsec = x->tv_nsec - tmp.tv_nsec; + + /* Return 1 if result is negative. */ + return x->tv_sec < tmp.tv_sec; +} + +#endif + diff --git a/debug_timer.h b/debug_timer.h new file mode 100644 index 0000000..a8fc3e2 --- /dev/null +++ b/debug_timer.h @@ -0,0 +1,25 @@ + +#ifndef DEBUG_TIMER_H_ +#define DEBUG_TIMER_H_ + +#ifdef AQ_TM_DEBUG +#include +#include +void init_aqd_timer(); +int timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y); +void stop_aqd_timer(int timeid, int16_t from, char *message); +void start_aqd_timer(int *timeid); +void clear_aqd_timer(int timeid); +#define DEBUG_TIMER_START(x) start_aqd_timer(x) +#define DEBUG_TIMER_STOP(x, y, z) stop_aqd_timer(x, y, z) +#define DEBUG_TIMER_CLEAR(x) clear_aqd_timer(x) + +//#define DEBUG_TIMER_START1() int t; start_aqd_timer(&t) +//#define DEBUG_TIMER_STOP1(y, z) stop_aqd_timer(t, y, z) +#else +#define DEBUG_TIMER_START(x) +#define DEBUG_TIMER_STOP(x, y, z) +#define DEBUG_TIMER_CLEAR(x) +#endif + +#endif //DEBUG_TIMER_H_ diff --git a/devices_jandy.c b/devices_jandy.c index afad0fa..3f4e23b 100644 --- a/devices_jandy.c +++ b/devices_jandy.c @@ -173,6 +173,8 @@ bool setSWGboost(struct aqualinkdata *aqdata, bool on) { aqdata->boost = true; aqdata->swg_percent = 101; } + + return true; } // Only change SWG percent if we are not in SWG programming diff --git a/iaqtouch.c b/iaqtouch.c index a6f0e94..d215afe 100644 --- a/iaqtouch.c +++ b/iaqtouch.c @@ -120,7 +120,7 @@ const char *iaqtGetTableInfoLine(int index) { } struct iaqt_page_button *iaqtFindButtonByIndex(int index) { - int i; + //int i; struct iaqt_page_button *buttons; // NSF Need to merge this from iaqtFindButtonByLabel function @@ -398,17 +398,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) pump = NULL; } - if (rsm_strcmp(_deviceStatus[i],"AQUAPURE") == 0) { - //aq_data->swg_percent = rsm_atoi(&_deviceStatus[i][9]); - if (changeSWGpercent(aq_data, rsm_atoi(&_deviceStatus[i][9]))) - LOG(IAQT_LOG,LOG_DEBUG, "Set swg %% to %d from message'%s'\n",aq_data->swg_percent,_deviceStatus[i]); - } else if (rsm_strcmp(_deviceStatus[i],"salt") == 0) { - aq_data->swg_ppm = rsm_atoi(&_deviceStatus[i][5]); - LOG(IAQT_LOG,LOG_DEBUG, "Set swg PPM to %d from message'%s'\n",aq_data->swg_ppm,_deviceStatus[i]); - } else if (rsm_strcmp(_deviceStatus[i],"Boost Pool") == 0) { - aq_data->boost = true; - // Let RS pickup time remaing message. - } else if (rsm_strcmp(_deviceStatus[i],"Chemlink") == 0) { + if (rsm_strcmp(_deviceStatus[i],"Chemlink") == 0) { /* Info: = Chemlink 1 Info: = ORP 750/PH 7.0 */ i++; @@ -423,6 +413,19 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data) LOG(IAQT_LOG,LOG_INFO, "Set Cemlink ORP = %d PH = %f from message '%s'\n",orp,ph,_deviceStatus[i]); } } +#ifdef READ_SWG_FROM_EXTENDED_ID + else if (rsm_strcmp(_deviceStatus[i],"AQUAPURE") == 0) { + //aq_data->swg_percent = rsm_atoi(&_deviceStatus[i][9]); + if (changeSWGpercent(aq_data, rsm_atoi(&_deviceStatus[i][9]))) + LOG(IAQT_LOG,LOG_DEBUG, "Set swg %% to %d from message'%s'\n",aq_data->swg_percent,_deviceStatus[i]); + } else if (rsm_strcmp(_deviceStatus[i],"salt") == 0) { + aq_data->swg_ppm = rsm_atoi(&_deviceStatus[i][5]); + LOG(IAQT_LOG,LOG_DEBUG, "Set swg PPM to %d from message'%s'\n",aq_data->swg_ppm,_deviceStatus[i]); + } else if (rsm_strcmp(_deviceStatus[i],"Boost Pool") == 0) { + aq_data->boost = true; + // Let RS pickup time remaing message. + } +#endif } // for } @@ -502,12 +505,12 @@ void processPage(struct aqualinkdata *aq_data) } } - +#define REQUEST_STATUS_POLL_COUNT 50 bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data) { static int cnt = 0; - char buff[1024]; + //char buff[1024]; if (packet[PKT_CMD] == CMD_IAQ_PAGE_START) { LOG(IAQT_LOG,LOG_DEBUG, "Turning IAQ SEND off\n"); @@ -571,20 +574,17 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd // Standard ack/poll not interested in printing or kicking threads if (packet[3] == 0x30) { // Load status page every 1000 messages - //if (cnt++ > 50 && in_iaqt_programming_mode(aq_data) == false ) { - // Let's not confuse any message data, only grab status if not in any from of programming mode - /* - if (cnt++ == 50 && in_programming_mode(aq_data) == false ) { - //iaqt_queue_cmd(KEY_IAQTCH_STATUS); - //aq_programmer(AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, NULL, aq_data); - //cnt = 0; - queueGetProgramData(IAQTOUCH, aq_data); - } - else*/ if (cnt++ > 100 && in_programming_mode(aq_data) == false ) { + if (cnt++ > REQUEST_STATUS_POLL_COUNT && in_programming_mode(aq_data) == false ) { iaqt_queue_cmd(KEY_IAQTCH_STATUS); //aq_programmer(AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, NULL, aq_data); cnt = 0; + } else if (in_programming_mode(aq_data) == true) { + // Set count to something close to above, so we will pull latest info once programming has finished. + // This is goot for VSP GPM programming as it takes number of seconds to register once finished programming. + // -5 seems to be too quick for VSP/GPM so using 10 + cnt = REQUEST_STATUS_POLL_COUNT - 10; } + return false; } @@ -592,7 +592,7 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd _lastMsgType = packet[PKT_CMD]; - debuglogPacket(IAQT_LOG ,packet, length); + //debuglogPacket(IAQT_LOG ,packet, length); //beautifyPacket(buff, packet, length); //LOG(IAQT_LOG,LOG_DEBUG, "%s", buff); diff --git a/iaqtouch_aq_programmer.c b/iaqtouch_aq_programmer.c index f27fe5d..03d031d 100644 --- a/iaqtouch_aq_programmer.c +++ b/iaqtouch_aq_programmer.c @@ -31,6 +31,7 @@ #include "aq_panel.h" #include "config.h" #include "devices_jandy.h" +#include "packetLogger.h" // System Page is obfiously fixed and not dynamic loaded, so set buttons to stop confustion. @@ -131,6 +132,14 @@ int ref_iaqt_control_cmd(unsigned char **cmd) { //printf("*********** GET READY SENDING CONTROL ****************\n"); *cmd = _iaqt_control_cmd; + + if ( getLogLevel(IAQT_LOG) >= LOG_DEBUG ) { + char buff[1000]; + //sprintf("Sending control command:") + beautifyPacket(buff, _iaqt_control_cmd, _iaqt_control_cmd_len); + LOG(IAQT_LOG,LOG_DEBUG, "iAQ Touch sending commandsed : %s\n", buff); + } + return _iaqt_control_cmd_len; } @@ -145,9 +154,12 @@ bool waitfor_iaqt_ctrl_queue2empty() int i=0; while ( (_iaqt_control_cmd_len >0 ) && ( i++ < 20) ) { + LOG(IAQT_LOG,LOG_DEBUG, "Waiting for commandset to send\n"); delay(50); } + LOG(IAQT_LOG,LOG_DEBUG, "Wait for commandset over!\n"); + if (_iaqt_control_cmd_len > 0 ) { LOG(IAQT_LOG,LOG_WARNING, "iAQ Touch Send control command Queue did not empty, timeout\n"); return false; @@ -167,11 +179,13 @@ unsigned const char waitfor_iaqt_nextPage(struct aqualinkdata *aq_data) { while( ++i <= numMessageReceived) { - LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage (%d of %d)\n",i,numMessageReceived); + //LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage (%d of %d)\n",i,numMessageReceived); pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) break; } + LOG(IAQT_LOG,LOG_DEBUG, "waitfor_iaqt_nextPage finished in (%d of %d)\n",i,numMessageReceived); + pthread_mutex_unlock(&aq_data->active_thread.thread_mutex); if(wasiaqtThreadKickTypePage()) @@ -225,30 +239,32 @@ void queue_iaqt_control_command(iaqtControlCmdYype type, int num) { // Tell the control panel we are ready to send this shit. send_aqt_cmd(ACK_CMD_READY_CTRL); - + + LOG(IAQT_LOG,LOG_DEBUG, "Queued extended commandsed of length %d\n",_iaqt_control_cmd_len); //printHex(packets, 19); //printf("\n"); //send_jandy_command(NULL, packets, cnt); } -void queue_iaqt_control_command_str(iaqtControlCmdYype type, char *str) { +bool queue_iaqt_control_command_str(iaqtControlCmdYype type, char *str) { if (waitfor_iaqt_ctrl_queue2empty() == false) - return; + return false; _iaqt_control_cmd[0] = DEV_MASTER; _iaqt_control_cmd[1] = 0x24; _iaqt_control_cmd[2] = 0x31; _iaqt_control_cmd_len = char2iaqtRSset(&_iaqt_control_cmd[3], str, strlen(str)); - + // Need to bad time for some reason not yet known if (type == icct_settime) { //Debug: RS Serial: To 0x00 of type iAq pBut | HEX: 0x10|0x02|0x00|0x24|0x31|0x30|0x31|0x3a|0x30|0x31|0x00|0x30|0x32|0x00|0xcd|0xcd|0xcd|0xcd|0xcd|0xcd|0xcd|0x60|0x10|0x03| // From position 11 (8 without pre) add 0x30|0x32|0x00 - _iaqt_control_cmd[++_iaqt_control_cmd_len] = 0x30; - _iaqt_control_cmd[++_iaqt_control_cmd_len] = 0x32; - _iaqt_control_cmd[++_iaqt_control_cmd_len] = 0x00; + _iaqt_control_cmd_len += 3; + _iaqt_control_cmd[9] = 0x30; + _iaqt_control_cmd[10] = 0x32; + _iaqt_control_cmd[11] = 0x00; } // Pad with 0xcd for some reason. for(_iaqt_control_cmd_len = _iaqt_control_cmd_len+3; _iaqt_control_cmd_len <= 18; _iaqt_control_cmd_len++) @@ -256,6 +272,9 @@ void queue_iaqt_control_command_str(iaqtControlCmdYype type, char *str) { // Tell the control panel we are ready to send this shit. send_aqt_cmd(ACK_CMD_READY_CTRL); + + return true; + //debuglogPacket() } @@ -464,9 +483,11 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr ) */ //send_aqt_cmd(0x80); - f_end: - //goto_iaqt_page(IAQ_PAGE_HOME, aq_data); + // Go to status page on startup to read devices goto_iaqt_page(IAQ_PAGE_STATUS, aq_data); + + f_end: + goto_iaqt_page(IAQ_PAGE_HOME, aq_data); cleanAndTerminateThread(threadCtrl); // just stop compiler error, ptr is not valid as it's just been freed @@ -594,6 +615,7 @@ void *get_aqualink_iaqtouch_setpoints( void *ptr ) return ptr; } +// THIS IS NOT FINISHED. void *get_aqualink_iaqtouch_aux_labels( void *ptr ) { struct programmingThreadCtrl *threadCtrl; @@ -616,6 +638,8 @@ void *get_aqualink_iaqtouch_aux_labels( void *ptr ) * Info: Table Messages 05| Aux5 Aux5 No * Info: Table Messages 06| Aux6 Aux6 No * Info: Table Messages 07| Aux7 Aux7 No + * + * Info: Table Messages ??| Aux B7 Aux B7 No */ const char *buf; int aux; @@ -624,9 +648,10 @@ void *get_aqualink_iaqtouch_aux_labels( void *ptr ) for(i=1; i < PANEL_SIZE(); i++) { buf = iaqtGetTableInfoLine(i); + LOG(IAQT_LOG,LOG_INFO, "From Messages %.2d| %s\n",i,buf); //printf("**** BUF '%s'\n",aux,buf); aux = rsm_atoi(buf + 3); - printf("**** AUX %d = '%s'\n",aux,buf + 5); + LOG(IAQT_LOG,LOG_INFO, "**** AUX %d = '%s'\n",aux,buf + 5); } f_end: @@ -915,9 +940,9 @@ void *set_aqualink_iaqtouch_time( void *ptr ) struct aqualinkdata *aq_data = threadCtrl->aq_data; struct iaqt_page_button *button; char buf[20]; - int len; + //int len; int i; - bool AM; + //bool AM; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_SET_TIME); @@ -945,9 +970,13 @@ void *set_aqualink_iaqtouch_time( void *ptr ) send_aqt_cmd(button->keycode); waitfor_iaqt_queue2empty(); // Queue the date string - queue_iaqt_control_command_str(icct_setdate, buf); - LOG(IAQT_LOG,LOG_DEBUG, "Set date to %s\n",buf); - waitfor_iaqt_ctrl_queue2empty(); + if ( queue_iaqt_control_command_str(icct_setdate, buf)) { + LOG(IAQT_LOG,LOG_NOTICE, "Set date to %s\n",buf); + waitfor_iaqt_ctrl_queue2empty(); + } else { + LOG(IAQT_LOG,LOG_ERR, "Failed to queue commandset for setting date\n"); + } + } else { LOG(IAQT_LOG,LOG_DEBUG, "Date %s is accurate, not changing\n",button->name); } @@ -977,9 +1006,12 @@ void *set_aqualink_iaqtouch_time( void *ptr ) // Print HH:MM into string strftime(buf, 20, "%I:%M", result); - queue_iaqt_control_command_str(icct_settime, buf); - LOG(IAQT_LOG,LOG_DEBUG, "Set time to %s\n",buf); - waitfor_iaqt_ctrl_queue2empty(); + if (queue_iaqt_control_command_str(icct_settime, buf)) { + LOG(IAQT_LOG,LOG_NOTICE, "Set time to %s\n",buf); + waitfor_iaqt_ctrl_queue2empty(); + } else { + LOG(IAQT_LOG,LOG_ERR, "Failed to queue commandset for setting time\n"); + } f_end: diff --git a/net_services.c b/net_services.c index b16bd42..3209a54 100644 --- a/net_services.c +++ b/net_services.c @@ -35,19 +35,21 @@ #include "aq_mqtt.h" #include "devices_jandy.h" #include "color_lights.h" +#include "debug_timer.h" #ifdef AQ_PDA #include "pda.h" #endif -#ifdef AQ_DEBUG +/* +#if defined AQ_DEBUG || defined AQ_TM_DEBUG #include "timespec_subtract.h" - //#define AQ_NET_TIMER + //#define AQ_TM_DEBUG #endif - +*/ //static struct aqconfig *_aqconfig_; static struct aqualinkdata *_aqualink_data; -static char *_web_root; +//static char *_web_root; static int _mqtt_exit_flag = false; @@ -64,49 +66,21 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc); void reset_last_mqtt_status(); -#ifdef AQ_NET_TIMER -static struct timespec _start_time[5]; -static int _timeid=0; -void start_net_timer(int *timeid) -{ - if (_timeid >= 5) - _timeid = 0; - - clock_gettime(CLOCK_REALTIME, &_start_time[_timeid++]); - - *timeid = _timeid-1; - //return _timeid-1; -} - -void stop_net_timer(int timeid, char *message) -{ - if (timeid < 0 || timeid >= 5) { - LOG(NET_LOG,LOG_ERR,"Invalid timeid '%d' for message '%s'\n", timeid, message); - return; - } - static struct timespec now; - static struct timespec elapsed; - clock_gettime(CLOCK_REALTIME, &now); - timespec_subtract(&elapsed, &now, &_start_time[timeid]); - LOG(NET_LOG,LOG_NOTICE, "%s %d.%02ld sec (%08ld ns)\n", message, elapsed.tv_sec, elapsed.tv_nsec / 1000000L, elapsed.tv_nsec); -} - -#define DEBUG_TIMER_START(x) start_net_timer(x) -#define DEBUG_TIMER_STOP(x, y) stop_net_timer(x, y) -#else -#define DEBUG_TIMER_START(x) -#define DEBUG_TIMER_STOP(x, y) -#endif static sig_atomic_t s_signal_received = 0; //static const char *s_http_port = "8080"; static struct mg_serve_http_opts _http_server_opts; -static void signal_handler(int sig_num) { - signal(sig_num, signal_handler); // Reinstantiate signal handler - s_signal_received = sig_num; +static void net_signal_handler(int sig_num) { + + if (!_aqconfig_.thread_netservices) { + signal(sig_num, net_signal_handler); // Reinstantiate signal handler to aqualinkd.c + s_signal_received = sig_num; + } else { + intHandler(sig_num); // Force signal handler to aqualinkd.c + } } @@ -116,9 +90,11 @@ static int is_websocket(const struct mg_connection *nc) { static void set_websocket_RSraw(struct mg_connection *nc) { nc->flags |= MG_F_USER_2; } +/* static int is_websocket_RSraw(const struct mg_connection *nc) { return nc->flags & MG_F_USER_2; } +*/ static int is_mqtt(const struct mg_connection *nc) { return nc->flags & MG_F_USER_1; } @@ -135,7 +111,7 @@ static void ws_send(struct mg_connection *nc, char *msg) //LOG(NET_LOG,LOG_DEBUG, "WS: Sent %d characters '%s'\n",size, msg); } -void broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg) +void _broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg) { struct mg_connection *c; char data[JSON_STATUS_SIZE]; @@ -148,16 +124,22 @@ void broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg) // Maybe enhacment in future to sent error messages to MQTT } -void broadcast_aqualinkstate(struct mg_connection *nc) +void _broadcast_aqualinkstate(struct mg_connection *nc) { static int mqtt_count=0; struct mg_connection *c; char data[JSON_STATUS_SIZE]; +#ifdef AQ_TM_DEBUG + int tid; +#endif + DEBUG_TIMER_START(&tid); + build_aqualink_status_JSON(_aqualink_data, data, JSON_STATUS_SIZE); #ifdef AQ_MEMCMP if ( memcmp(_aqualink_data, &_last_mqtt_aqualinkdata, sizeof(struct aqualinkdata) ) == 0) { LOG(NET_LOG,LOG_NOTICE, "**********Structure buffs the same, ignoring request************\n"); + DEBUG_TIMER_CLEAR(&tid); return; } #endif @@ -185,6 +167,8 @@ void broadcast_aqualinkstate(struct mg_connection *nc) memcpy(&_last_mqtt_aqualinkdata, _aqualink_data, sizeof(struct aqualinkdata)); #endif + DEBUG_TIMER_STOP(tid, NET_LOG, "broadcast_aqualinkstate() completed, took "); + return; } @@ -678,7 +662,7 @@ void create_program_request(netRequest requester, action_type type, int value, i _aqualink_data->unactioned.type = type; _aqualink_data->unactioned.id = id; // This is only valid for pump. - if (requester = NET_MQTT) // We can get multiple MQTT requests from some, so this will wait for last one to come in. + if (requester == NET_MQTT) // We can get multiple MQTT requests from some, so this will wait for last one to come in. time(&_aqualink_data->unactioned.requested); else _aqualink_data->unactioned.requested = 0; @@ -771,7 +755,7 @@ uriAtype action_URI(netRequest from, const char *URI, int uri_length, float valu return uBad; } rtn = uActioned; - if (from = NET_MQTT) // We can get multiple MQTT requests for + if (from == NET_MQTT) // We can get multiple MQTT requests for time(&_aqualink_data->unactioned.requested); else _aqualink_data->unactioned.requested = 0; @@ -938,8 +922,12 @@ uriAtype action_URI(netRequest from, const char *URI, int uri_length, float valu return rtn; } + void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg) { char *rtnmsg; +#ifdef AQ_TM_DEBUG + int tid; +#endif //unsigned int i; //LOG(NET_LOG,LOG_DEBUG, "MQTT: topic %.*s %.2f\n",msg->topic.len, msg->topic.p, atof(msg->payload.p)); // If message doesn't end in set we don't care about it. @@ -949,6 +937,7 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg) } LOG(NET_LOG,LOG_DEBUG, "MQTT: topic %.*s %.*s\n",msg->topic.len, msg->topic.p, msg->payload.len, msg->payload.p); + DEBUG_TIMER_START(&tid); //Need to do this in a better manor, but for present it's ok. static char tmp[20]; strncpy(tmp, msg->payload.p, msg->payload.len); @@ -959,8 +948,13 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg) bool convert = (_aqualink_data->temp_units != CELSIUS && _aqconfig_.convert_mqtt_temp)?true:false; int offset = strlen(_aqconfig_.mqtt_aq_topic)+1; action_URI(NET_MQTT, &msg->topic.p[offset], msg->topic.len - offset, value, convert, &rtnmsg); + + DEBUG_TIMER_STOP(tid, NET_LOG, "action_mqtt_message() completed, took "); } + + + float pass_mg_body(struct mg_str *body) { LOG(NET_LOG,LOG_INFO, "Message body:\n'%.*s'\n", body->len, body->p); // Quick n dirty pass value from either of below. @@ -985,13 +979,12 @@ float pass_mg_body(struct mg_str *body) { void action_web_request(struct mg_connection *nc, struct http_message *http_msg) { char *msg = NULL; // struct http_message *http_msg = (struct http_message *)ev_data; -#ifdef AQ_NET_TIMER +#ifdef AQ_TM_DEBUG int tid; int tid2; #endif - DEBUG_TIMER_START(&tid); - + //DEBUG_TIMER_START(&tid); if (getLogLevel(NET_LOG) >= LOG_INFO) { // Simply for log message, check we are at // this log level before running all this // junk @@ -1001,7 +994,7 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg) LOG(NET_LOG,LOG_INFO, "URI request: '%s'\n", uri); free(uri); } - DEBUG_TIMER_STOP(tid, "action_web_request debug print crap took"); + //DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request debug print crap took"); //LOG(NET_LOG,LOG_INFO, "Message request:\n'%.*s'\n", http_msg->message.len, http_msg->message.p); @@ -1009,16 +1002,18 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg) if (strncmp(http_msg->uri.p, "/api", 4 ) != 0) { if (strstr(http_msg->method.p, "GET") && http_msg->query_string.len > 0) { LOG(NET_LOG,LOG_WARNING, "WEB: Old stanza, using old method to action\n"); + DEBUG_TIMER_START(&tid); OLD_action_web_request(nc, http_msg); + DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request() serve Old stanza took"); } else { DEBUG_TIMER_START(&tid); mg_serve_http(nc, http_msg, _http_server_opts); - DEBUG_TIMER_STOP(tid, "action_web_request serve file took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request() serve file took"); } //} else if (strstr(http_msg->method.p, "PUT")) { } else { char buf[50]; - float value; + float value = 0; DEBUG_TIMER_START(&tid); // If query string. @@ -1041,35 +1036,36 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg) { char message[JSON_BUFFER_SIZE]; DEBUG_TIMER_START(&tid2); - build_device_JSON(_aqualink_data, message, JSON_BUFFER_SIZE, false); - DEBUG_TIMER_STOP(tid2, "action_web_request build_device_JSON took"); - mg_send_head(nc, 200, strlen(message), CONTENT_JSON); - mg_send(nc, message, strlen(message)); + int size = build_device_JSON(_aqualink_data, message, JSON_BUFFER_SIZE, false); + DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_device_JSON took"); + mg_send_head(nc, 200, size, CONTENT_JSON); + mg_send(nc, message, size); } break; case uHomebridge: { char message[JSON_BUFFER_SIZE]; - build_device_JSON(_aqualink_data, message, JSON_BUFFER_SIZE, true); - mg_send_head(nc, 200, strlen(message), CONTENT_JSON); - mg_send(nc, message, strlen(message)); + int size = build_device_JSON(_aqualink_data, message, JSON_BUFFER_SIZE, true); + mg_send_head(nc, 200, size, CONTENT_JSON); + mg_send(nc, message, size); } break; case uStatus: { char message[JSON_BUFFER_SIZE]; DEBUG_TIMER_START(&tid2); - build_aqualink_status_JSON(_aqualink_data, message, JSON_BUFFER_SIZE); - DEBUG_TIMER_STOP(tid2, "action_web_request build_aqualink_status_JSON took"); - mg_send_head(nc, 200, strlen(message), CONTENT_JSON); - mg_send(nc, message, strlen(message)); + int size = build_aqualink_status_JSON(_aqualink_data, message, JSON_BUFFER_SIZE); + DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_aqualink_status_JSON took"); + mg_send_head(nc, 200, size, CONTENT_JSON); + mg_send(nc, message, size); } + break; case uDynamicconf: { char message[JSON_BUFFER_SIZE]; DEBUG_TIMER_START(&tid2); int size = build_color_lights_js(_aqualink_data, message, JSON_BUFFER_SIZE); - DEBUG_TIMER_STOP(tid2, "action_web_request build_color_lights_js took"); + DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_color_lights_js took"); mg_send_head(nc, 200, size, CONTENT_JS); mg_send(nc, message, size); } @@ -1101,12 +1097,10 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg) mg_send(nc, GET_RTN_UNKNOWN, strlen(GET_RTN_UNKNOWN)); } - sprintf(buf, "action_web_request serve api request '%.*s' took",http_msg->uri.len, http_msg->uri.p); - - DEBUG_TIMER_STOP(tid, buf); + sprintf(buf, "action_web_request() request '%.*s' took",http_msg->uri.len, http_msg->uri.p); + DEBUG_TIMER_STOP(tid, NET_LOG, buf); } - } @@ -1117,7 +1111,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message char *uri = NULL; char *value = NULL; char *msg = NULL; -#ifdef AQ_NET_TIMER +#ifdef AQ_TM_DEBUG int tid; #endif #ifdef AQ_PDA @@ -1156,7 +1150,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message DEBUG_TIMER_START(&tid); char message[JSON_BUFFER_SIZE]; build_device_JSON(_aqualink_data, message, JSON_BUFFER_SIZE, false); - DEBUG_TIMER_STOP(tid, "action_websocket_request build_device_JSON took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() build_device_JSON took"); ws_send(nc, message); } break; @@ -1165,7 +1159,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message DEBUG_TIMER_START(&tid); char message[JSON_BUFFER_SIZE]; build_aqualink_status_JSON(_aqualink_data, message, JSON_BUFFER_SIZE); - DEBUG_TIMER_STOP(tid, "action_websocket_request build_aqualink_status_JSON took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() build_aqualink_status_JSON took"); ws_send(nc, message); } break; @@ -1231,7 +1225,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { struct http_message *http_msg; struct websocket_message *ws_msg; char aq_topic[30]; - #ifdef AQ_NET_TIMER + #ifdef AQ_TM_DEBUG int tid; #endif //static double last_control_time; @@ -1243,7 +1237,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { http_msg = (struct http_message *)ev_data; DEBUG_TIMER_START(&tid); action_web_request(nc, http_msg); - DEBUG_TIMER_STOP(tid, "WEB Request took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "WEB Request action_web_request() took"); LOG(NET_LOG,LOG_DEBUG, "Served WEB request\n"); break; @@ -1257,7 +1251,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { ws_msg = (struct websocket_message *)ev_data; DEBUG_TIMER_START(&tid); action_websocket_request(nc, ws_msg); - DEBUG_TIMER_STOP(tid, "Websocket Request took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "Websocket Request action_websocket_request() took"); break; case MG_EV_CLOSE: @@ -1350,7 +1344,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { { DEBUG_TIMER_START(&tid); action_mqtt_message(nc, mqtt_msg); - DEBUG_TIMER_STOP(tid, "MQTT Request took"); + DEBUG_TIMER_STOP(tid, NET_LOG, "MQTT Request action_mqtt_message() took"); } if (_aqconfig_.mqtt_dz_sub_topic != NULL && strncmp(mqtt_msg->topic.p, _aqconfig_.mqtt_dz_sub_topic, strlen(_aqconfig_.mqtt_dz_sub_topic)) == 0) { action_domoticz_mqtt_message(nc, mqtt_msg); @@ -1386,7 +1380,7 @@ void start_mqtt(struct mg_mgr *mgr) { if (mg_connect(mgr, _aqconfig_.mqtt_server, ev_handler) == NULL) { LOG(NET_LOG,LOG_ERR, "Failed to create MQTT listener to %s\n", _aqconfig_.mqtt_server); } else { - int i; + //int i; #ifdef AQ_MEMCMP memset(&_last_mqtt_aqualinkdata, 0, sizeof (struct aqualinkdata)); #endif @@ -1397,13 +1391,13 @@ void start_mqtt(struct mg_mgr *mgr) { //bool start_web_server(struct mg_mgr *mgr, struct aqualinkdata *aqdata, char *port, char* web_root) { //bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata, struct aqconfig *aqconfig) { -bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) { +bool _start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) { struct mg_connection *nc; _aqualink_data = aqdata; //_aqconfig_ = aqconfig; - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); + signal(SIGTERM, net_signal_handler); + signal(SIGINT, net_signal_handler); setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0); @@ -1440,6 +1434,119 @@ bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) { } +/********************************************************************************************** + * Thread Net Services + * +*/ + + +pthread_t _net_thread_id; +bool _keepNetServicesRunning = true; +//volatile bool _broadcast = false; // This is redundent when most the fully threadded rather than option. + +void *net_services_thread( void *ptr ) +{ + struct aqualinkdata *aqdata = (struct aqualinkdata *) ptr; + struct mg_mgr mgr; + + _start_net_services(&mgr, aqdata); + + while (_keepNetServicesRunning == true) + { + //poll_net_services(&mgr, 10); + mg_mgr_poll(&mgr, 100); + + if (aqdata->updated == true /*|| _broadcast == true*/) { + LOG(NET_LOG,LOG_DEBUG, "********** Broadcast ************\n"); + _broadcast_aqualinkstate(mgr.active_connections); + aqdata->updated = false; + //_broadcast = false; + } + } + + LOG(NET_LOG,LOG_NOTICE, "Stopping network services thread\n"); + mg_mgr_free(&mgr); + + pthread_exit(0); +} + +bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) +{ + if ( ! _aqconfig_.thread_netservices) { + return _start_net_services(mgr, aqdata); + } + + LOG(NET_LOG,LOG_NOTICE, "Starting network services thread\n"); + + if( pthread_create( &_net_thread_id , NULL , net_services_thread, (void*)aqdata) < 0) { + LOG(NET_LOG, LOG_ERR, "could not create network thread\n"); + return false; + } + + pthread_detach(_net_thread_id); + + return true; +} + +time_t poll_net_services(struct mg_mgr *mgr, int timeout_ms) +{ + if (timeout_ms < 0) + timeout_ms = 0; + + if ( ! _aqconfig_.thread_netservices) { + return mg_mgr_poll(mgr, timeout_ms); + } + + if (timeout_ms > 5) + delay(5); + else if (timeout_ms > 0) + delay(timeout_ms); + + //LOG(NET_LOG,LOG_NOTICE, "Poll network services\n"); + + return 0; +} + +void broadcast_aqualinkstate(struct mg_connection *nc) +{ + if ( ! _aqconfig_.thread_netservices) { + _broadcast_aqualinkstate(nc); + _aqualink_data->updated = false; + return; + } + //_broadcast = true; + //LOG(NET_LOG,LOG_NOTICE, "Broadcast status to network\n"); +} + +void broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg) +{ + if ( ! _aqconfig_.thread_netservices) { + return _broadcast_aqualinkstate_error(nc, msg); + } + + LOG(NET_LOG,LOG_NOTICE, "Broadcast error to network\n"); +} + +void stop_net_services(struct mg_mgr *mgr) { + + if ( ! _aqconfig_.thread_netservices) { + mg_mgr_free(mgr); + return; + } + + _keepNetServicesRunning = false; + + return; +} + + + + + + + + + @@ -1713,7 +1820,7 @@ LOG(NET_LOG,LOG_ERR, "WEB: spalightmode taken out for update (forgot to put it b mg_send(nc, GET_RTN_UNKNOWN, strlen(GET_RTN_UNKNOWN)); } else { - struct mg_serve_http_opts opts; + //struct mg_serve_http_opts opts; //memset(&opts, 0, sizeof(opts)); // Reset all options to defaults //opts.document_root = _web_root; // Serve files from the current directory // LOG(NET_LOG,LOG_DEBUG, "Doc root=%s\n",opts.document_root); diff --git a/net_services.h b/net_services.h index e509f0f..ea400fe 100644 --- a/net_services.h +++ b/net_services.h @@ -16,6 +16,8 @@ //bool start_web_server(struct mg_mgr *mgr, struct aqualinkdata *aqdata, char *port, char* web_root); //bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata, struct aqconfig *aqconfig); bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata); +void stop_net_services(struct mg_mgr *mgr); +time_t poll_net_services(struct mg_mgr *mgr, int timeout_ms); void broadcast_aqualinkstate(struct mg_connection *nc); void broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg); diff --git a/onetouch.c b/onetouch.c index de4f9bc..eb36e8d 100644 --- a/onetouch.c +++ b/onetouch.c @@ -124,6 +124,9 @@ void log_programming_information(struct aqualinkdata *aq_data) case OTM_SET_TEMP: log_heater_setpoints(aq_data); break; + default: + // No need to do anything yet + break; } } @@ -346,6 +349,7 @@ bool log_qeuiptment_status(struct aqualinkdata *aq_data) //printf ("Set Pump Type to %d\n",aq_data->pumps[i].pumpType); } } +#ifdef READ_SWG_FROM_EXTENDED_ID } else if (rsm_strcmp(_menu[2],"AQUAPURE") == 0) { /* Info: OneTouch Menu Line 0 = Equipment Status Info: OneTouch Menu Line 1 = @@ -367,7 +371,7 @@ bool log_qeuiptment_status(struct aqualinkdata *aq_data) } LOG(ONET_LOG,LOG_INFO, "OneTouch PPM = %d\n",ppm); } - +#endif } else if (rsm_strcmp(_menu[2],"Chemlink") == 0) { /* Info: OneTouch Menu Line 0 = Equipment Status Info: OneTouch Menu Line 1 = diff --git a/onetouch_aq_programmer.c b/onetouch_aq_programmer.c index 7a10edf..9044ded 100644 --- a/onetouch_aq_programmer.c +++ b/onetouch_aq_programmer.c @@ -767,7 +767,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) int diff; int i; int len; - unsigned char direction; + unsigned char direction = KEY_ONET_UP; waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_SWG_PERCENT); int val = atoi((char*)threadCtrl->thread_args); @@ -808,7 +808,7 @@ void *set_aqualink_onetouch_swg_percent( void *ptr ) i=0; char *st = onetouch_menu_hlightchars(&len); LOG(ONET_LOG,LOG_DEBUG, "** OneTouch set SWG Percent highlighted='%.*s' len=%d st=%s\n", len, st, len, st); - while (len > 5 || len < 0 && i < 5) { + while (len > 5 || (len < 0 && i < 5)) { LOG(ONET_LOG,LOG_DEBUG, "** OneTouch set SWG Percent highlighted waiting again\n"); delay(50); waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,5); // CMD_PDA_0x04 is just a packer. diff --git a/packetLogger.c b/packetLogger.c index ab36e14..996acd2 100644 --- a/packetLogger.c +++ b/packetLogger.c @@ -98,7 +98,7 @@ int _beautifyPacket(char *buff, unsigned char *packet_buffer, int packet_length, int cnt = 0; if (_includePentair) { - cnt = sprintf(buff, "%s%8.8s Packet | HEX: ",(error?"BAD PACKET ":""),getProtocolType(packet_buffer)==JANDY?"Jandy":"Pentair"); + cnt = sprintf(buff, "%s%8.8s Packet | HEX: ",(error?"BAD PACKET ":""),getProtocolType(packet_buffer)==PENTAIR?"Pentair":"Jandy"); } else { cnt = sprintf(buff, "%sTo 0x%02hhx of type %8.8s | HEX: ",(error?"BAD PACKET ":""), packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length)); } diff --git a/pda.c b/pda.c index 59409c8..3643f8d 100644 --- a/pda.c +++ b/pda.c @@ -200,7 +200,7 @@ void pass_pda_equiptment_status_item(char *msg) } else { - char labelBuff[AQ_MSGLEN + 1]; + char labelBuff[AQ_MSGLEN + 2]; strncpy(labelBuff, msg, AQ_MSGLEN + 1); msg = stripwhitespace(labelBuff); diff --git a/release/aqualinkd b/release/aqualinkd index 4f7cb96..20e9ae4 100755 Binary files a/release/aqualinkd and b/release/aqualinkd differ diff --git a/release/aqualinkd.conf b/release/aqualinkd.conf index 325ad26..be5704d 100755 --- a/release/aqualinkd.conf +++ b/release/aqualinkd.conf @@ -105,14 +105,18 @@ report_zero_pool_temp = no #mqtt_dz_pub_topic = domoticz/in #mqtt_dz_sub_topic = domoticz/out #mqtt_aq_topic = aqualinkd + # MQTT will only post updated information, this option AqualinkD will re-post all MQTT information every ~5 minutes. #mqtt_timed_update = no # Please see forum for this, only set to yes when logging information to support # new devices. Inflrmation will be written to /tmp/RS485.log #debug_RSProtocol_packets = no -# Not documented, only use if asked to for problem solving purposes. + +# Not documented, or expermental. Only use if asked to for problem solving purposes. #serial_readahead_b4_write = yes +#thread_netservices = yes +#rs_poll_speed = -1 # Put AqualinkD to sleep when in PDA mode after inactivity. diff --git a/release/install.sh b/release/install.sh index c69c821..d020076 100755 --- a/release/install.sh +++ b/release/install.sh @@ -38,19 +38,42 @@ command -v systemctl >/dev/null 2>&1 || { echo "This script needs systemd's syst systemctl stop $SERVICE > /dev/null 2>&1 SERVICE_EXISTS=$(echo $?) +# Clean everything if requested. +if [ "$1" == "clean" ]; then + echo "Deleting install" + systemctl disable $SERVICE > /dev/null 2>&1 + if [ -f $BINLocation/$BIN ]; then + rm -f $BINLocation/$BIN + fi + if [ -f $SRVLocation/$SRV ]; then + rm -f $SRVLocation/$SRV + fi + if [ -f $CFGLocation/$CFG ]; then + rm -f $CFGLocation/$CFG + fi + if [ -f $DEFLocation/$DEF ]; then + rm -f $DEFLocation/$DEF + fi + if [ -d $WEBLocation ]; then + rm -rf $WEBLocation + fi + systemctl daemon-reload + exit +fi + # copy files to locations, but only copy cfg if it doesn;t already exist cp $BUILD/$BIN $BINLocation/$BIN cp $BUILD/$SRV $SRVLocation/$SRV if [ -f $CFGLocation/$CFG ]; then - echo "Config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG" + echo "AqualinkD config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG" else cp $BUILD/$CFG $CFGLocation/$CFG fi if [ -f $DEFLocation/$DEF ]; then - echo "Defaults exists, did not copy new defaults to $DEFLocation/$DEF" + echo "AqualinkD defaults exists, did not copy new defaults to $DEFLocation/$DEF" else cp $BUILD/$DEF.defaults $DEFLocation/$DEF fi @@ -70,7 +93,7 @@ if [ ! -d "$WEBLocation" ]; then fi if [ -f "$WEBLocation/config.js" ]; then - echo "$WEBLocation/config.js exists, did not copy overight, please make sure to update manually" + echo "AqualinkD web config exists, did not copy new config, you may need to edit existing $WEBLocation/config.js " rsync -avq --exclude='config.js' $BUILD/../web/* $WEBLocation else cp -r $BUILD/../web/* $WEBLocation @@ -83,5 +106,7 @@ systemctl daemon-reload if [ $SERVICE_EXISTS -eq 0 ]; then echo "Starting daemon $SERVICE" systemctl start $SERVICE +else + echo "Please edit $CFGLocation/$CFG, then start AqualinkD service" fi diff --git a/release/serial_logger b/release/serial_logger index 29085fb..cd0d9c5 100755 Binary files a/release/serial_logger and b/release/serial_logger differ diff --git a/serial_logger.c b/serial_logger.c index 03fbd17..80d2d58 100644 --- a/serial_logger.c +++ b/serial_logger.c @@ -73,7 +73,7 @@ bool _playback_file = false; void intHandler(int dummy) { _keepRunning = false; - logMessage(LOG_NOTICE, "Stopping!"); + LOG(RSSD_LOG, LOG_NOTICE, "Stopping!"); if (_playback_file) // If we are reading file, loop is irevelent exit(0); } @@ -320,6 +320,7 @@ int main(int argc, char *argv[]) { int logLevel = LOG_NOTICE; bool rsRawDebug = false; bool panleProbe = true; + bool rsSerialSpeedTest = false; //bool playback_file = false; //int logLevel; @@ -345,6 +346,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "\t-p (log # packets)\n"); fprintf(stderr, "\t-i (just log these ID's, can use multiple -i)\n"); fprintf(stderr, "\t-r (raw)\n"); + fprintf(stderr, "\t-s (Serial Speed Test)\n"); fprintf(stderr, "\t-rsrd (log raw RS bytes to %s)\n",RS485BYTELOGFILE); fprintf(stderr, "\nie:\t%s /dev/ttyUSB0 -d -p 1000 -i 0x08 -i 0x0a\n\n", argv[0]); return 1; @@ -372,6 +374,8 @@ int main(int argc, char *argv[]) { rsRawDebug = true; } else if (strcmp(argv[i], "-n") == 0) { panleProbe = false; + } else if (strcmp(argv[i], "-s") == 0) { + rsSerialSpeedTest = true; } } @@ -380,7 +384,7 @@ int main(int argc, char *argv[]) { if (_playback_file) { rs_fd = open(argv[1], O_RDONLY | O_NOCTTY | O_NONBLOCK | O_NDELAY); if (rs_fd < 0) { - logMessage(LOG_ERR, "Unable to open file: %s\n", argv[1]); + LOG(RSSD_LOG, LOG_ERR, "Unable to open file: %s\n", argv[1]); displayLastSystemError(argv[1]); return -1; } @@ -414,7 +418,7 @@ int main(int argc, char *argv[]) { // Nothing read } else if (packet_length > 0) { - //logMessage(LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s\n", packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length)); + //LOG(RSSD_LOG, LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s\n", packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length)); if (logLevel > LOG_NOTICE) printPacket(lastID, packet_buffer, packet_length); @@ -448,7 +452,7 @@ int main(int argc, char *argv[]) { } if (packet_buffer[PKT_DEST] == DEV_MASTER /*&& packet_buffer[PKT_CMD] == CMD_ACK*/) { - //logMessage(LOG_NOTICE, "ID is in use 0x%02hhx %x\n", lastID, lastID); + //LOG(RSSD_LOG, LOG_NOTICE, "ID is in use 0x%02hhx %x\n", lastID, lastID); for (i = 0; i <= sindex; i++) { if (slog[i].ID == lastID) { slog[i].inuse = true; @@ -477,6 +481,18 @@ int main(int argc, char *argv[]) { }*/ // NSF + // Test Serial speed & caching + if (rsSerialSpeedTest) { + if (rsRawDebug) + packet_length = get_packet_lograw(rs_fd, packet_buffer); + else + packet_length = get_packet(rs_fd, packet_buffer); + + if (packet_length > 0) { + LOG(RSSD_LOG, LOG_ERR, "SERIOUS RS485 ERROR, Slow serial port read detected, (check RS485 adapteer / os performance / USB serial speed\n"); + } + } + } if (logPackets != 0 && received_packets >= logPackets) { @@ -500,7 +516,7 @@ int main(int argc, char *argv[]) { LOG(RSSD_LOG, LOG_NOTICE, "Jandy ID's found\n"); for (i = 0; i < sindex; i++) { - //logMessage(LOG_NOTICE, "ID 0x%02hhx is %s %s\n", slog[i].ID, (slog[i].inuse == true) ? "in use" : "not used", + //LOG(RSSD_LOG, LOG_NOTICE, "ID 0x%02hhx is %s %s\n", slog[i].ID, (slog[i].inuse == true) ? "in use" : "not used", // (slog[i].inuse == false && canUse(slog[i].ID) == true)? " <-- can use for Aqualinkd" : ""); if (logLevel >= LOG_DEBUG || slog[i].inuse == true || canUse(slog[i].ID) == true) { LOG(RSSD_LOG, LOG_NOTICE, "ID 0x%02hhx is %s %s\n", slog[i].ID, (slog[i].inuse == true) ? "in use" : "not used", diff --git a/utils.c b/utils.c index b9e3c3e..7fc13df 100644 --- a/utils.c +++ b/utils.c @@ -143,7 +143,8 @@ void displayLastSystemError (const char *on_what) if (_daemonise == TRUE) { - logMessage (LOG_ERR, "%d : %s", errno, on_what); + //logMessage (LOG_ERR, "%d : %s", errno, on_what); + LOG(AQUA_LOG, LOG_ERR, "%d : %s", errno, on_what); closelog (); } } @@ -208,6 +209,43 @@ int text2elevel(char* level) return LOG_ERR; } +const char* logmask2name(int16_t from) +{ + switch (from) { + case NET_LOG: + return "NetService:"; + break; + case AQRS_LOG: + return "RS Allbtn: "; + break; + case ONET_LOG: + return "One Touch: "; + break; + case IAQT_LOG: + return "iAQ Touch: "; + break; + case PDA_LOG: + return "PDA: "; + break; + case DJAN_LOG: + return "JandyDvce: "; + break; + case DPEN_LOG: + return "PentaDvce: "; + break; + case RSSD_LOG: + return "RS Serial: "; + break; + case DBGT_LOG: + return "AQ Timing: "; + break; + case AQUA_LOG: + default: + return "AqualinkD: "; + break; + } +} + void timestamp(char* time_string) { time_t now; @@ -354,6 +392,7 @@ void addDebugLogMask(int16_t flag) void _LOG(int16_t from, int msg_level, char * message); +/* void logMessage(int msg_level, const char *format, ...) { if (msg_level > _log_level) { @@ -369,7 +408,7 @@ void logMessage(int msg_level, const char *format, ...) _LOG(AQUA_LOG, msg_level, buffer); } - +*/ void LOG(int16_t from, int msg_level, const char * format, ...) { @@ -388,7 +427,7 @@ void LOG(int16_t from, int msg_level, const char * format, ...) } -void _LOG(int16_t from, int msg_level, char * message) +void _LOG(int16_t from, int msg_level, char *message) { int i; @@ -404,36 +443,9 @@ void _LOG(int16_t from, int msg_level, char * message) message[i+1] = '\0'; } - switch (from) { - case NET_LOG: - strncpy(&message[9], "NetService:", 11); - break; - case AQRS_LOG: - strncpy(&message[9], "RS Allbtn: ", 11); - break; - case ONET_LOG: - strncpy(&message[9], "One Touch: ", 11); - break; - case IAQT_LOG: - strncpy(&message[9], "iAQ Touch: ", 11); - break; - case PDA_LOG: - strncpy(&message[9], "PDA: ", 11); - break; - case DJAN_LOG: - strncpy(&message[9], "JandyDvce: ", 11); - break; - case DPEN_LOG: - strncpy(&message[9], "PentaDvce: ", 11); - break; - case RSSD_LOG: - strncpy(&message[9], "RS Serial: ", 11); - break; - case AQUA_LOG: - default: - strncpy(&message[9], "AqualinkD: ", 11); - break; - } + //strncpy(&message[9], logmask2name(from), 11); // Will give compiller warning as doesn;t realise we are copying into middle of string. + memcpy(&message[9], logmask2name(from), 11); + // Logging has not been setup yet, so STD error & syslog if (_log_level == -1) { fprintf (stderr, message); @@ -512,7 +524,7 @@ void daemonise (char *pidFile, void (*main_function) (void)) /* Check we are root */ if (getuid() != 0) { - logMessage(LOG_ERR,"Can only be run as root\n"); + LOG(AQUA_LOG, LOG_ERR,"Can only be run as root\n"); exit(EXIT_FAILURE); } @@ -523,7 +535,7 @@ void daemonise (char *pidFile, void (*main_function) (void)) //if (EWOULDBLOCK == errno) //; // another instance is running //fputs ("\nAnother instance is already running\n", stderr); - logMessage(LOG_ERR,"\nAnother instance is already running\n"); + LOG(AQUA_LOG, LOG_ERR,"\nAnother instance is already running\n"); exit (EXIT_FAILURE); } @@ -541,12 +553,12 @@ void daemonise (char *pidFile, void (*main_function) (void)) fp = fopen (pidFile, "w"); if (fp == NULL) - logMessage(LOG_ERR,"can't write to PID file %s",pidFile); + LOG(AQUA_LOG, LOG_ERR,"can't write to PID file %s",pidFile); else fprintf(fp, "%d", process_id); fclose (fp); - logMessage (LOG_DEBUG, "process_id of child process %d \n", process_id); + LOG(AQUA_LOG, LOG_DEBUG, "process_id of child process %d \n", process_id); // return success in exit status exit (EXIT_SUCCESS); } diff --git a/utils.h b/utils.h index 1fa06ed..2457060 100644 --- a/utils.h +++ b/utils.h @@ -35,6 +35,8 @@ #define DPEN_LOG (1 << 7) // Pentair Device // misc #define RSSD_LOG (1 << 8) // Serial +#define PROG_LOG (1 << 9) // Programmer +#define DBGT_LOG (1 << 10) // Debug Timer /* typedef enum { @@ -51,7 +53,11 @@ void displayLastSystemError (const char *on_what); void addDebugLogMask(int16_t flag); //#define logMessage(msg_level, format, ...) LOG (1, msg_level, format, ##__VA_ARGS__) -void logMessage(int level, const char *format, ...); + + +//void logMessage(int level, const char *format, ...); + + //void LOG(int from, int level, char *format, ...); void LOG(int16_t from, int msg_level, const char *format, ...); @@ -82,6 +88,7 @@ void stopInlineDebug(); void cleanInlineDebug(); char *getInlineLogFName(); bool islogFileReady(); +const char *logmask2name(int16_t from); //#ifndef _UTILS_C_ extern bool _daemon_; diff --git a/version.h b/version.h index 3c031e2..3f03cd5 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define AQUALINKD_NAME "Aqualink Daemon" -#define AQUALINKD_VERSION "2.2.0b" +#define AQUALINKD_VERSION "2.2.0c" diff --git a/web/controller.html b/web/controller.html index 6309505..7047848 100644 --- a/web/controller.html +++ b/web/controller.html @@ -1485,6 +1485,8 @@ get_devices(); // Set another load 1 minute from now just incase the server hasn't got all the devices yet window.setTimeout(get_devices, (60 * 1000)); + // Get Status just incase control panel hasn't connected yet + get_status(); } socket_di.onmessage = function got_packet(msg) { document.getElementById("header").classList.remove("error"); @@ -1523,6 +1525,17 @@ socket_di.send(JSON.stringify(msg)); } + function get_status() { + /* + var msg = { + command: "GET_DEVICES" + };*/ + var msg = { + uri: "status" + }; + socket_di.send(JSON.stringify(msg)); + } + function send_command(cmd, value=null) { var _cmd = {}; _cmd.command = cmd; diff --git a/web/simple.html b/web/simple.html index f4c05dd..599c8ce 100644 --- a/web/simple.html +++ b/web/simple.html @@ -278,7 +278,7 @@ for (var obj in data['devices']) { if (document.getElementById(data['devices'][obj].id) == null) { _displayNames[data['devices'][obj].id.replace("Aux_", "AUX")] = data['devices'][obj].name; - //console.log("Create " + data['devices'][obj].id); + console.log("Create " + data['devices'][obj].id); createTile(data['devices'][obj]); } } @@ -321,6 +321,10 @@ function createTile(object) { if (object.name == 'NONE') return; + + if (typeof devices !== 'undefined' && devices.indexOf(object.id) < 0) { + return; + } //if (ignore_devices.indexOf(object.id) >= 0) // return; var table = document.getElementById("deviceList"); @@ -339,13 +343,14 @@ cell3.setAttribute('align', 'right'); //cell3.setAttribute('cellpadding', '0'); cell4.setAttribute('align', 'right'); - if (object.type == 'switch') { + if (object.type == 'switch' /*&& object.type_ext != "switch_program"*/) { row.deleteCell(2); row.deleteCell(1); cell1.setAttribute('colspan', '3'); cell4.innerHTML = "
"; setButton(object.id, object.state); - } else if (object.type == 'switch_program') { + /* //Removing light program, too much for simple interface + } else if (object.type == 'switch' && object.type_ext == 'switch_program') { row.deleteCell(2); cell2.setAttribute('colspan', '2'); //cell2.setAttribute('width', '100%'); @@ -364,6 +369,7 @@ } } catch (e) {} setButton(object.id, object.state); + */ } else if (object.type == 'value') { row.deleteCell(2); row.deleteCell(1); @@ -414,19 +420,29 @@ switch (source.getAttribute("type")) { case "range": - cmd.parameter = source.id.substr(7); // remove 'slider_' - cmd.value = source.value; + if ( source.id.includes("SWG") ) { + cmd.uri = source.id.substr(7)+"/percent/set"; + cmd.value = source.value; + } else { + cmd.uri = source.id.substr(7)+"/setpoint/set"; + //cmd.parameter = source.id.substr(7); // remove 'slider_' + cmd.value = source.value; + } break; case "checkbox": + cmd.uri = source.id.substr(7)+"/set"; + cmd.value = source.checked?"1":"0"; //name = source.id.substr(11); //remove 'btn-toggle-'' //state = source.checked?"on":"off"; - cmd.command = source.id.substr(7); + //cmd.command = source.id.substr(7); break; default: // type is null because it's a selector + cmd.uri = source.id.substr(9)+"/program/set"; + cmd.button = source.id.substr(9); //name = source.id.substr(9); //remove 'selector_'' - cmd.parameter = 'LIGHT_MODE'; + //cmd.parameter = 'LIGHT_MODE'; cmd.value = source.value; - cmd.button = source.id.substr(9); // remove 'selector_' + //cmd.button = source.id.substr(9); // remove 'selector_' break; } //console.log(source); @@ -564,7 +580,8 @@ function get_devices() { var msg = { - command: "GET_DEVICES" + //command: "GET_DEVICES" + uri: "devices" }; socket_di.send(JSON.stringify(msg)); }