From 502637f0509c4c88ed6e7553fe8dfb3f8db84228 Mon Sep 17 00:00:00 2001 From: shaun feakes Date: Thu, 15 Mar 2018 15:03:57 -0500 Subject: [PATCH] Serial ID debuger --- Makefile | 11 ++++ aq_programmer.c | 48 +++++++++++++++-- aq_programmer.h | 1 + aq_serial.h | 12 +++-- aqualink.h | 2 +- aqualinkd.c | 62 ++++++++++++++++++---- config.c | 3 ++ config.h | 1 + release/aqualinkd | Bin 217244 -> 217380 bytes release/serial_logger | Bin 0 -> 19976 bytes serial_logger.c | 117 ++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 238 insertions(+), 19 deletions(-) create mode 100755 release/serial_logger create mode 100644 serial_logger.c diff --git a/Makefile b/Makefile index 28a3d1c..9e96647 100755 --- a/Makefile +++ b/Makefile @@ -23,10 +23,14 @@ CFLAGS = -Wall $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_AUTH - # 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 mongoose.c +SL_SRC = serial_logger.c aq_serial.c utils.c + OBJS = $(SRCS:.c=.o) +SL_OBJS = $(SL_SRC:.c=.o) # define the executable file MAIN = ./release/aqualinkd +SLOG = ./release/serial_logger all: $(MAIN) @echo: $(MAIN) have been compiled @@ -34,6 +38,13 @@ all: $(MAIN) $(MAIN): $(OBJS) $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) + +slog: $(SLOG) + @echo: $(SLOG) have been compiled + +$(SLOG): $(SL_OBJS) + $(CC) $(CFLAGS) $(INCLUDES) -o $(SLOG) $(SL_OBJS) + # this is a suffix replacement rule for building .o's from .c's # it uses automatic variables $<: the name of the prerequisite of # the rule(a .c file) and $@: the name of the target of the rule (a .o file) diff --git a/aq_programmer.c b/aq_programmer.c index 3c634fd..70b9f69 100644 --- a/aq_programmer.c +++ b/aq_programmer.c @@ -43,6 +43,7 @@ void *get_freeze_protect_temp( void *ptr ); void *get_aqualink_diag_model( void *ptr ); void *threadded_send_cmd( void *ptr ); void *set_aqualink_light_colormode( void *ptr ); +void *set_aqualink_PDA_init( void *ptr ); bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate state, int numMessageReceived); @@ -60,6 +61,7 @@ unsigned char _pgm_command = NUL; bool _last_sent_was_cmd = false; bool push_aq_cmd(unsigned char cmd) { + //logMessage(LOG_DEBUG, "push_aq_cmd\n"); if (_stack_place < MAX_STACK) { _commands[_stack_place] = cmd; _stack_place++; @@ -74,7 +76,7 @@ bool push_aq_cmd(unsigned char cmd) { unsigned char pop_aq_cmd(struct aqualinkdata *aq_data) { unsigned char cmd = NUL; - + //logMessage(LOG_DEBUG, "pop_aq_cmd\n"); // can only send a command every other ack. if (_last_sent_was_cmd == true) { _last_sent_was_cmd= false; @@ -111,10 +113,10 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data) struct programmingThreadCtrl *programmingthread = malloc(sizeof(struct programmingThreadCtrl)); programmingthread->aq_data = aq_data; - //programmingthread->thread_args = args; - if (args != NULL) - strncpy(programmingthread->thread_args, args, sizeof(programmingthread->thread_args)-1); + //programmingthread->thread_args = args; + if (args != NULL && type != AQ_SEND_CMD) + strncpy(programmingthread->thread_args, args, sizeof(programmingthread->thread_args)-1); switch(type) { case AQ_SEND_CMD: push_aq_cmd((unsigned char)*args); @@ -182,6 +184,12 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data) return; } break; + 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"); + return; + } + break; default: logMessage (LOG_ERR, "Don't understand thread type\n"); break; @@ -283,6 +291,38 @@ void *threadded_send_cmd( void *ptr ) return ptr; } */ + +void *set_aqualink_PDA_init( void *ptr ) +{ + struct programmingThreadCtrl *threadCtrl; + threadCtrl = (struct programmingThreadCtrl *) ptr; + struct aqualinkdata *aq_data = threadCtrl->aq_data; + + waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_INIT); + + int val = atoi((char*)threadCtrl->thread_args); + + logMessage(LOG_DEBUG, "PDA Init\n", val); + + //send_cmd(KEY_PDA_DOWN, aq_data); + //waitForMessage(threadCtrl->aq_data, NULL, 1); + + send_cmd(KEY_PDA_SELECT, aq_data); + waitForMessage(threadCtrl->aq_data, NULL, 1); + + send_cmd(KEY_PDA_DOWN, aq_data); + waitForMessage(threadCtrl->aq_data, NULL, 1); + + send_cmd(KEY_PDA_PGDN, aq_data); + waitForMessage(threadCtrl->aq_data, NULL, 1); + + cleanAndTerminateThread(threadCtrl); + + // just stop compiler error, ptr is not valid as it's just been freed + return ptr; +} + + void *set_aqualink_light_colormode( void *ptr ) { int i; diff --git a/aq_programmer.h b/aq_programmer.h index 0ab88c3..0a789f3 100644 --- a/aq_programmer.h +++ b/aq_programmer.h @@ -14,6 +14,7 @@ typedef enum { AQ_SEND_CMD, AQ_GET_PROGRAMS, AQ_SET_COLORMODE, + AQ_PDA_INIT, } program_type; struct programmingThreadCtrl { diff --git a/aq_serial.h b/aq_serial.h index 0683609..3c8475c 100644 --- a/aq_serial.h +++ b/aq_serial.h @@ -34,6 +34,14 @@ #define CMD_MSG 0x03 #define CMD_MSG_LONG 0x04 +/* PDA KEY CODES */ // Just plating at the moment +#define KEY_PDA_UP 0x06 +#define KEY_PDA_DOWN 0x05 +#define KEY_PDA_BACK 0x02 +#define KEY_PDA_SELECT 0x04 +#define KEY_PDA_PGUP 0x05 +#define KEY_PDA_PGDN 0x05 + /* KEY/BUTTON CODES */ #define KEY_PUMP 0x02 #define KEY_SPA 0x01 @@ -130,8 +138,4 @@ int get_packet(int file_descriptor, unsigned char* packet); void process_status(unsigned char* ptr); const char* get_packet_type(unsigned char* packet, int length); - - - - #endif // AQ_SERIAL_H_ \ No newline at end of file diff --git a/aqualink.h b/aqualink.h index 64c9a91..996b927 100644 --- a/aqualink.h +++ b/aqualink.h @@ -66,7 +66,7 @@ struct aqualinkdata char date[AQ_MSGLEN]; char time[AQ_MSGLEN]; //char datestr[DATE_STRING_LEN]; - //char message[AQ_MSGLONGLEN]; + char message[AQ_MSGLONGLEN]; char *last_message; // Be careful using this, can get core dumps. //char *display_message; unsigned char raw_status[AQ_PSTLEN]; diff --git a/aqualinkd.c b/aqualinkd.c index fa38b60..9299d01 100644 --- a/aqualinkd.c +++ b/aqualinkd.c @@ -42,6 +42,7 @@ #define DEFAULT_CONFIG_FILE "./aqualinkd.conf" + static volatile bool _keepRunning = true; static struct aqconfig _config_parameters; static struct aqualinkdata _aqualink_data; @@ -368,6 +369,38 @@ void processMessage(char *message) kick_aq_program_thread(&_aqualink_data); } +void processPDAMessage(char *message) +{ + char *msg; + + msg = cleanwhitespace(message); + _aqualink_data.last_message = msg; + + logMessage(LOG_INFO, "RS PDA Message :- '%s'\n",msg); + + if (_aqualink_data.message != NULL && strncasecmp(_aqualink_data.message, "AIR", 3) == 0) + { + _aqualink_data.temp_units = FAHRENHEIT; + // RS PDA Message :- '73` 66`' + _aqualink_data.air_temp = atoi(msg); + _aqualink_data.pool_temp = atoi(msg+8); + logMessage(LOG_DEBUG, "Air = %d : Pool = %d\n",_aqualink_data.air_temp, _aqualink_data.pool_temp); + + //aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, &_aqualink_data); + aq_programmer(AQ_PDA_INIT, NULL, &_aqualink_data); + } else if(strstr(msg, "REV ") != NULL) { // 'REV MMM' + aq_programmer(AQ_PDA_INIT, NULL, &_aqualink_data); + } + + //_aqualink_data.last_message = msg; + strncpy(_aqualink_data.message, msg,AQ_MSGLONGLEN); + + // We processed the next message, kick any threads waiting on the message. + kick_aq_program_thread(&_aqualink_data); + +} + + bool process_packet(unsigned char* packet, int length) { bool rtn = false; @@ -426,13 +459,20 @@ bool process_packet(unsigned char* packet, int length) break; case CMD_MSG_LONG: // First in sequence is normal message. - processing_long_msg++; - strncpy(&message[processing_long_msg*AQ_MSGLEN], (char*)packet+PKT_DATA+1, AQ_MSGLEN); - //logMessage(LOG_DEBUG_SERIAL, "RS Received long message '%s'\n",message); - if (processing_long_msg == 3) { - //logMessage(LOG_DEBUG, "RS Finished receiving of MSG_LONG '%s'\n",message); - processMessage(message); - processing_long_msg=0; + if (_config_parameters.pda_mode == true) { + strncpy(message, (char*)packet+PKT_DATA+1, AQ_MSGLEN); + //logMessage(LOG_DEBUG_SERIAL, "RS Received message '%s'\n",(char*)packet); + //logMessage(LOG_DEBUG_SERIAL, "RS deciphered message '%s'\n",message); + processPDAMessage(message); + } else { + processing_long_msg++; + strncpy(&message[processing_long_msg*AQ_MSGLEN], (char*)packet+PKT_DATA+1, AQ_MSGLEN); + //logMessage(LOG_DEBUG_SERIAL, "RS Received long message '%s'\n",message); + if (processing_long_msg == 3) { + //logMessage(LOG_DEBUG, "RS Finished receiving of MSG_LONG '%s'\n",message); + processMessage(message); + processing_long_msg=0; + } } break; case CMD_PROBE: @@ -487,6 +527,7 @@ int main(int argc, char *argv[]) { int i; char *cfgFile = DEFAULT_CONFIG_FILE; + // struct lws_context_creation_info info; // Log only NOTICE messages and above. Debug and info messages @@ -537,6 +578,7 @@ int main(int argc, char *argv[]) { logMessage(LOG_NOTICE, "Config idx spa temp = %d\n", _config_parameters.dzidx_spa_water_temp); logMessage(LOG_NOTICE, "Config idx SWG Percent = %d\n", _config_parameters.dzidx_swg_percent); logMessage(LOG_NOTICE, "Config idx SWG PPM = %d\n", _config_parameters.dzidx_swg_ppm); + logMessage(LOG_NOTICE, "Config PDA Mode = %s\n", bool2text(_config_parameters.pda_mode)); /* removed until domoticz has a better virtual thermostat logMessage(LOG_NOTICE, "Config idx pool thermostat = %d\n", _config_parameters.dzidx_pool_thermostat); logMessage(LOG_NOTICE, "Config idx spa thermostat = %d\n", _config_parameters.dzidx_spa_thermostat); @@ -547,8 +589,6 @@ int main(int argc, char *argv[]) { logMessage(LOG_NOTICE, "Config light_pgm_mode = %.2f\n", _config_parameters.light_programming_mode); // logMessage (LOG_NOTICE, "Config serial_port = %s\n", config_parameters->serial_port); - - for (i=0; i < TOTAL_BUTONS; i++) { logMessage(LOG_NOTICE, "Config BTN %-13s = label %-15s | dzidx %d\n", _aqualink_data.aqbuttons[i].name, _aqualink_data.aqbuttons[i].label , _aqualink_data.aqbuttons[i].dz_idx); //logMessage(LOG_NOTICE, "Button %d\n", i+1, _aqualink_data.aqbuttons[i].label , _aqualink_data.aqbuttons[i].dz_idx); @@ -632,6 +672,7 @@ void main_loop() { send_ack(rs_fd, _aqualink_data.aq_command); _aqualink_data.aq_command = NUL; */ + send_ack(rs_fd, pop_aq_cmd(&_aqualink_data)); // Process the packet. This includes deriving general status, and identifying // warnings and errors. If something changed, notify any listeners @@ -641,9 +682,10 @@ void main_loop() { } else if (packet_length > 0) { // printf("packet not for us %02x\n",packet_buffer[PKT_DEST]); } - if (getLogLevel() >= LOG_DEBUG_SERIAL) + if (getLogLevel() >= LOG_DEBUG_SERIAL) { logMessage(LOG_DEBUG_SERIAL, "Received Packet for ID 0x%02hhx of type %s %s\n",packet_buffer[PKT_DEST], get_packet_type(packet_buffer, packet_length), (packet_buffer[PKT_DEST] == _config_parameters.device_id)?" <-- Aqualinkd ID":""); + } } mg_mgr_poll(&mgr, 0); diff --git a/config.c b/config.c index 985a506..e6ab73d 100644 --- a/config.c +++ b/config.c @@ -71,6 +71,7 @@ void init_parameters (struct aqconfig * parms) parms->light_programming_mode = 0; parms->deamonize = true; parms->log_file = '\0'; + parms->pda_mode = false; generate_mqtt_id(parms->mqtt_ID, MQTT_ID_LEN); } @@ -242,6 +243,8 @@ void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata, c config_parameters->dzidx_swg_ppm = strtoul(indx+1, NULL, 10); } else if (strncasecmp (b_ptr, "override_freeze_protect", 23) == 0) { config_parameters->override_freeze_protect = text2bool(indx+1); + } else if (strncasecmp (b_ptr, "pda_mode", 8) == 0) { + config_parameters->pda_mode = text2bool(indx+1); }/*else if (strncasecmp (b_ptr, "pool_thermostat_dzidx", 21) == 0) { // removed until domoticz has a better virtual thermostat config_parameters->dzidx_pool_thermostat = strtoul(indx+1, NULL, 10); } else if (strncasecmp (b_ptr, "spa_thermostat_dzidx", 20) == 0) { diff --git a/config.h b/config.h index 1951c97..16c11d3 100644 --- a/config.h +++ b/config.h @@ -44,6 +44,7 @@ struct aqconfig int dzidx_swg_ppm; float light_programming_mode; bool override_freeze_protect; + bool pda_mode; //int dzidx_pool_thermostat; // Domoticz virtual thermostats are crap removed until better //int dzidx_spa_thermostat; // Domoticz virtual thermostats are crap removed until better //char mqtt_pub_topic[250]; diff --git a/release/aqualinkd b/release/aqualinkd index 84bfd1c7e4fcda7ee5ea3921443277ccd9e3f728..6005dac8254148644ac3294ebde00d59eecc93bb 100755 GIT binary patch delta 44524 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 G=>GyU5*KLz literal 0 HcmV?d00001 diff --git a/serial_logger.c b/serial_logger.c new file mode 100644 index 0000000..c5fa01f --- /dev/null +++ b/serial_logger.c @@ -0,0 +1,117 @@ + +#include +#include +#include +#include +#include +#include + +#include "aq_serial.h" +#include "utils.h" + +#define SLOG_MAX 20 + +typedef struct serial_id_log { + unsigned char ID; + bool inuse; +} serial_id_log; + +bool _keepRunning = true; + + + +void intHandler(int dummy) { + _keepRunning = false; + logMessage(LOG_NOTICE, "Stopping!"); +} + + +int main(int argc, char *argv[]) { + int rs_fd; + int packet_length; + unsigned char packet_buffer[AQ_MAXPKTLEN]; + unsigned char lastID; + int i=0; + bool found; + serial_id_log slog[SLOG_MAX]; + int sindex = 0; + + if (getuid() != 0) { + fprintf(stderr, "ERROR %s Can only be run as root\n", argv[0]); + return EXIT_FAILURE; + } + + setLoggingPrms(LOG_DEBUG_SERIAL, false, false); + + if (argc < 2) { + logMessage(LOG_DEBUG_SERIAL, "ERROR, first param must be serial port, ie:-\n %s /dev/ttyUSB0\n\n", argv[0]); + return 1; + } + + rs_fd = init_serial_port(argv[1]); + + signal(SIGINT, intHandler); + signal(SIGTERM, intHandler); + + while (_keepRunning == true) { + if ( rs_fd < 0 ) { + logMessage(LOG_DEBUG_SERIAL, "ERROR, serial port disconnect\n"); + } + + packet_length = get_packet(rs_fd, packet_buffer); + if (packet_length == -1) { + // Unrecoverable read error. Force an attempt to reconnect. + logMessage(LOG_DEBUG_SERIAL, "ERROR, on serial port\n"); + _keepRunning = false; + } else if (packet_length == 0) { + // 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)); + + if (packet_buffer[PKT_DEST] != DEV_MASTER) { + found=false; + for (i=0; i <= sindex; i++) { + if (slog[i].ID == packet_buffer[PKT_DEST]) { + found=true; + break; + } + } + if (found != true && sindex < SLOG_MAX) { + slog[sindex].ID = packet_buffer[PKT_DEST]; + slog[sindex].inuse = false; + sindex++; + } + } + + if (packet_buffer[PKT_DEST] == DEV_MASTER && packet_buffer[PKT_CMD] == CMD_ACK) { + logMessage(LOG_DEBUG_SERIAL, "ID is in use 0x%02hhx\n",lastID); + for (i=0; i <= sindex; i++) { + if (slog[i].ID == lastID) { + slog[i].inuse = true; + break; + } + } + } + + lastID = packet_buffer[PKT_DEST]; + } + } + + logMessage(LOG_DEBUG_SERIAL, "\n"); + logMessage(LOG_DEBUG_SERIAL, "ID's found\n"); + for (i=0; i <= sindex; i++) { + logMessage(LOG_DEBUG_SERIAL, "ID 0x%02hhx is %s\n",slog[i].ID, slog[i].inuse==true?"in use":"not used"); + } + /* + static serial_id_logger slog[SLOG_MAX]; + static unsigned char lastID; + static int index = 0; + + if (packet_buffer[PKT_DEST] == DEV_MASTER && packet_buffer[PKT_CMD] == CMD_ACK) { + logMessage(LOG_DEBUG_SERIAL, "ID is in use 0x%02hhx\n",lastID); + } + lastID = packet_buffer[PKT_DEST]; + } + */ + return 0; +} \ No newline at end of file