Serial ID debuger

pull/46/head
shaun feakes 2018-03-15 15:03:57 -05:00
parent 9e7e03b3e9
commit 502637f050
11 changed files with 238 additions and 19 deletions

View File

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

View File

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

View File

@ -14,6 +14,7 @@ typedef enum {
AQ_SEND_CMD,
AQ_GET_PROGRAMS,
AQ_SET_COLORMODE,
AQ_PDA_INIT,
} program_type;
struct programmingThreadCtrl {

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

BIN
release/serial_logger Executable file

Binary file not shown.

117
serial_logger.c Normal file
View File

@ -0,0 +1,117 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#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;
}