mirror of https://github.com/sfeakes/AqualinkD.git
V2.0.0a
parent
03a9b62ca1
commit
fcd828c818
9
Makefile
9
Makefile
|
|
@ -11,9 +11,10 @@ LIBS := -l pthread -l m
|
|||
#LIBS := -lpthread -lwebsockets
|
||||
|
||||
# debug of not
|
||||
#DBG = -g -O0 -fsanitize=address -static-libasan
|
||||
#DBG = -g
|
||||
DBG =
|
||||
#DBG = -g -O0 -fsanitize=address
|
||||
DBG = -g
|
||||
#DBG = -D ONETOUCH
|
||||
#DBG =
|
||||
|
||||
# USe below to remove unused functions and global variables.
|
||||
#LFLAGS = -Wl,--gc-sections,--print-gc-sections
|
||||
|
|
@ -32,7 +33,7 @@ CFLAGS = $(GCCFLAGS) $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISABLE_HTTP_DIGEST_
|
|||
# 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 pda_aq_programmer.c aquapure.c packetLogger.c pentair_messages.c mongoose.c
|
||||
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 pda_aq_programmer.c aquapure.c onetouch.c onetouch_aq_programmer.c packetLogger.c pentair_messages.c mongoose.c
|
||||
DBG_SRC = timespec_subtract.c
|
||||
|
||||
# If run with `make DEBUG=true` add debug files and pass parameter for compile
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -65,11 +65,17 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to
|
|||
* http://aqualink.ip/ <- (Standard WEB UI
|
||||
* http://aqualink.ip/simple.html <- (Simple opion if you don't like the above)
|
||||
* http://aqualink.ip/simulator.html <- (RS8 All Button Control Panel simulator)
|
||||
* http://aqualink.ip/debug.html <- (Turn on/off debug/serial debug & download logs)
|
||||
#<a name="release"></a>
|
||||
# Update in Release 1.3.9b
|
||||
* Small fixes for Jandy protocol.
|
||||
* Fixed some debug messages.
|
||||
# Update in Release 1.3.9
|
||||
# Update in Release 2.0.0a
|
||||
* Big update, lots of core changes, <b>please read wiki section https://github.com/sfeakes/AqualinkD/wiki/Version_2</b>
|
||||
* Full Variable Speed Pump support.
|
||||
* Please consider this ALPHA version, no need to upgrade unless you need VSP support. Use a previous version unless you want VSP.
|
||||
* I've noticed there is an issues with colored lights if your light is configured as such in the control panel. For this release suggest you either :-
|
||||
* A) use AqualinkD to control the colors and configure Jandy control panel as normal light
|
||||
* B) Don't use AqualinkD to turn light on/off (or if you do, wait ~10 seconds)
|
||||
# Update in Release 1.3.9a
|
||||
* Improved Debugging for serial.
|
||||
* Added panel Timeout mode support to UI and MQTT
|
||||
* Fixed SWG bug while in Service & Timeout modes
|
||||
* Cleanded up SWG code and MQTT status messages for SWG and SWG/enabled
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
//#define PUMP_TOPIC "Pump_"
|
||||
#define PUMP_RPM_TOPIC "/RPM"
|
||||
#define PUMP_GPH_TOPIC "/GPH"
|
||||
#define PUMP_GPM_TOPIC "/GPM"
|
||||
#define PUMP_WATTS_TOPIC "/Watts"
|
||||
/*
|
||||
#define AIR_TEMPERATURE "Air"
|
||||
|
|
|
|||
404
aq_programmer.c
404
aq_programmer.c
|
|
@ -30,6 +30,7 @@
|
|||
#include "pda_menu.h"
|
||||
#include "init_buttons.h"
|
||||
#include "pda_aq_programmer.h"
|
||||
#include "onetouch_aq_programmer.h"
|
||||
|
||||
#ifdef AQ_DEBUG
|
||||
#include <time.h>
|
||||
|
|
@ -56,6 +57,9 @@ void *set_aqualink_light_colormode( void *ptr );
|
|||
void *set_aqualink_PDA_init( void *ptr );
|
||||
void *set_aqualink_SWG( void *ptr );
|
||||
void *set_aqualink_boost( void *ptr );
|
||||
void *set_aqualink_pump_rpm( void *ptr );
|
||||
void *set_aqualink_onetouch_macro( void *ptr );
|
||||
void *get_aqualink_onetouch_setpoints( void *ptr );
|
||||
|
||||
//void *get_aqualink_PDA_device_status( void *ptr );
|
||||
//void *set_aqualink_PDA_device_on_off( void *ptr );
|
||||
|
|
@ -67,12 +71,14 @@ bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* me
|
|||
|
||||
bool push_aq_cmd(unsigned char cmd);
|
||||
void waitfor_queue2empty();
|
||||
void longwaitfor_queue2empty();
|
||||
|
||||
#define MAX_STACK 20
|
||||
int _stack_place = 0;
|
||||
unsigned char _commands[MAX_STACK];
|
||||
//unsigned char pgm_commands[MAX_STACK];
|
||||
unsigned char _pgm_command = NUL;
|
||||
//unsigned char _ot_pgm_command = NUL;
|
||||
|
||||
bool _last_sent_was_cmd = false;
|
||||
|
||||
|
|
@ -81,6 +87,23 @@ void aq_send_cmd(unsigned char cmd) {
|
|||
push_aq_cmd(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
void ot_send_cmd(unsigned char cmd) {
|
||||
_ot_pgm_command = cmd;
|
||||
}
|
||||
|
||||
unsigned char pop_ot_cmd(unsigned char receive_type)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
|
||||
if (receive_type == CMD_STATUS) {
|
||||
cmd = _ot_pgm_command;
|
||||
_ot_pgm_command = NUL;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
*/
|
||||
bool push_aq_cmd(unsigned char cmd) {
|
||||
|
||||
//logMessage(LOG_DEBUG, "push_aq_cmd '0x%02hhx'\n", cmd);
|
||||
|
|
@ -102,17 +125,47 @@ int get_aq_cmd_length()
|
|||
}
|
||||
|
||||
unsigned char pop_aq_cmd(struct aqualinkdata *aq_data)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
// Only send commands on status messages
|
||||
// Are we in programming mode and it's not ONETOUCH programming mode
|
||||
if (aq_data->active_thread.thread_id != 0 && in_ot_programming_mode(aq_data) == false ) {
|
||||
//if (aq_data->active_thread.thread_id != 0) {
|
||||
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);
|
||||
} else if (_pgm_command != NUL) {
|
||||
logMessage(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);
|
||||
}
|
||||
} 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);
|
||||
memmove(&_commands[0], &_commands[1], sizeof(unsigned char) * _stack_place ) ;
|
||||
} else {
|
||||
logMessage(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);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
unsigned char pop_aq_cmd_OLD(struct aqualinkdata *aq_data)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
// Only send commands on status messages
|
||||
// Are we in programming mode
|
||||
if (aq_data->active_thread.thread_id != 0) {
|
||||
/*if ( (_pgm_command == KEY_MENU && aq_data->last_packet_type == CMD_STATUS) ||
|
||||
if ( (_pgm_command == KEY_MENU && aq_data->last_packet_type == CMD_STATUS) ||
|
||||
// Need to not the key_menu below
|
||||
( _pgm_command != NUL && (aq_data->last_packet_type == CMD_STATUS || aq_data->last_packet_type == CMD_MSG_LONG) )) {*/
|
||||
if ( (_pgm_command != NUL && (aq_data->last_packet_type == CMD_STATUS)) ||
|
||||
// Boost pool has to send commands to msg long
|
||||
(aq_data->active_thread.ptype == AQ_SET_BOOST && (aq_data->last_packet_type == CMD_STATUS || aq_data->last_packet_type == CMD_MSG_LONG)) ) {
|
||||
( _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);
|
||||
|
|
@ -134,95 +187,39 @@ unsigned char pop_aq_cmd(struct aqualinkdata *aq_data)
|
|||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
//unsigned char pop_aq_cmd_old(struct aqualinkdata *aq_data);
|
||||
|
||||
unsigned char pop_aq_cmd_XXXXXX(struct aqualinkdata *aq_data)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
static bool last_sent_was_cmd = false;
|
||||
|
||||
// USE BELOW IF PDA HAS ISSUES WITH NEW COMMAND LOGIC
|
||||
|
||||
//if ( pda_mode() == true ) {
|
||||
// return pop_aq_cmd_old(aq_data);
|
||||
//}
|
||||
|
||||
// Only press menu to a status command
|
||||
// Only send commands on status messages when programming date
|
||||
// Otherwise send every other command.
|
||||
|
||||
// Are we in programming mode
|
||||
if (aq_data->active_thread.thread_id != 0) {
|
||||
if ( ((_pgm_command == KEY_MENU || aq_data->active_thread.ptype == AQ_SET_TIME) && aq_data->last_packet_type == CMD_STATUS) ||
|
||||
(pda_mode() == false && aq_data->active_thread.ptype != AQ_SET_TIME && last_sent_was_cmd == false) ||
|
||||
(pda_mode() == true && aq_data->last_packet_type == CMD_STATUS)
|
||||
//(pda_mode() == true && last_sent_was_cmd == false)
|
||||
) {
|
||||
cmd = _pgm_command;
|
||||
_pgm_command = NUL;
|
||||
logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx' (programming)\n", cmd);
|
||||
/*} else if (aq_data->active_thread.ptype != AQ_SET_TIME && last_sent_was_cmd == false) {
|
||||
cmd = _pgm_command;
|
||||
_pgm_command = NUL;
|
||||
logMessage(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);
|
||||
} else {
|
||||
logMessage(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);
|
||||
memmove(&_commands[0], &_commands[1], sizeof(unsigned char) * _stack_place ) ;
|
||||
} else {
|
||||
logMessage(LOG_DEBUG, "RS SEND cmd '0x%02hhx'\n", cmd);
|
||||
}
|
||||
|
||||
if (cmd == NUL)
|
||||
last_sent_was_cmd= false;
|
||||
else
|
||||
last_sent_was_cmd= true;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
unsigned char pop_aq_cmd_old(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;
|
||||
}
|
||||
else if (aq_data->active_thread.thread_id != 0) {
|
||||
cmd = _pgm_command;
|
||||
_pgm_command = NUL;
|
||||
//logMessage(LOG_DEBUG, "pop_aq_cmd '0x%02hhx' (programming)\n", cmd);
|
||||
}
|
||||
else if (_stack_place > 0) {
|
||||
cmd = _commands[0];
|
||||
_stack_place--;
|
||||
//logMessage(LOG_DEBUG, "pop_aq_cmd '0x%02hhx'\n", cmd);
|
||||
//memcpy(&_commands[0], &_commands[1], (sizeof(unsigned char) * MAX_STACK) - 1);
|
||||
memmove(&_commands[0], &_commands[1], sizeof(unsigned char) * _stack_place ) ;
|
||||
}
|
||||
|
||||
if (cmd == NUL)
|
||||
_last_sent_was_cmd= false;
|
||||
else
|
||||
_last_sent_was_cmd= true;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
*/
|
||||
|
||||
int roundTo(int num, int denominator) {
|
||||
return ((num + (denominator/2) ) / denominator )* denominator;
|
||||
}
|
||||
|
||||
//(Intelliflo VF you set GPM, not RPM)
|
||||
int RPM_check(pump_type type, int value, struct aqualinkdata *aqdata)
|
||||
{
|
||||
int rtn = value;
|
||||
// RPM 3450 seems to be max
|
||||
// RPM 600 min
|
||||
// GPM 130 max
|
||||
// GPM 15 min
|
||||
if (type == VFPUMP) {
|
||||
if (rtn > 130)
|
||||
rtn = 130;
|
||||
else if (rtn < 15)
|
||||
rtn = 15;
|
||||
else
|
||||
rtn = roundTo(rtn, 5);
|
||||
} else {
|
||||
if (rtn > 3450)
|
||||
rtn = 3450;
|
||||
else if (rtn < 600)
|
||||
rtn = 600;
|
||||
else
|
||||
rtn = roundTo(rtn, 5);
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
int setpoint_check(int type, int value, struct aqualinkdata *aqdata)
|
||||
{
|
||||
int rtn = value;
|
||||
|
|
@ -303,6 +300,28 @@ int setpoint_check(int type, int value, struct aqualinkdata *aqdata)
|
|||
return rtn;
|
||||
}
|
||||
|
||||
void queueGetExtendedProgramData(emulation_type source_type, struct aqualinkdata *aq_data, bool labels)
|
||||
{
|
||||
// Wait for onetouch if enabeled.
|
||||
if ( source_type == ALLBUTTON && ( onetouch_enabled() == false || extended_device_id_programming() == false ) ) {
|
||||
aq_send_cmd(NUL);
|
||||
aq_programmer(AQ_GET_POOL_SPA_HEATER_TEMPS, NULL, aq_data);
|
||||
aq_programmer(AQ_GET_FREEZE_PROTECT_TEMP, NULL, aq_data);
|
||||
if (labels)
|
||||
aq_programmer(AQ_GET_AUX_LABELS, NULL, aq_data);
|
||||
} else if ( source_type == ONETOUCH) {
|
||||
aq_programmer(AQ_GET_ONETOUCH_SETPOINTS, NULL, aq_data);
|
||||
} else if ( source_type == AQUAPDA) {
|
||||
aq_programmer(AQ_PDA_INIT, NULL, aq_data);
|
||||
}
|
||||
}
|
||||
|
||||
void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data)
|
||||
{
|
||||
queueGetExtendedProgramData(source_type, aq_data, false);
|
||||
}
|
||||
|
||||
/*
|
||||
void kick_aq_program_thread(struct aqualinkdata *aq_data)
|
||||
{
|
||||
if (aq_data->active_thread.thread_id != 0) {
|
||||
|
|
@ -310,11 +329,78 @@ void kick_aq_program_thread(struct aqualinkdata *aq_data)
|
|||
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
||||
}
|
||||
}
|
||||
*/
|
||||
bool in_ot_programming_mode(struct aqualinkdata *aq_data)
|
||||
{
|
||||
//( type != AQ_SET_PUMP_RPM || type != AQ_SET_OT_MACRO )) {
|
||||
|
||||
void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data)
|
||||
if ( ( aq_data->active_thread.thread_id != 0 ) &&
|
||||
( aq_data->active_thread.ptype == AQ_SET_ONETOUCH_PUMP_RPM ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_MACRO ||
|
||||
aq_data->active_thread.ptype == AQ_GET_ONETOUCH_SETPOINTS ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_TIME ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SWG_PERCENT ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_BOOST ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_POOL_HEATER_TEMP ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_SPA_HEATER_TEMP ||
|
||||
aq_data->active_thread.ptype == AQ_SET_ONETOUCH_FREEZEPROTECT)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_type)
|
||||
{
|
||||
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);
|
||||
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
pthread_cond_broadcast(&aq_data->active_thread.thread_cond);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data)
|
||||
{
|
||||
struct programmingThreadCtrl *programmingthread = malloc(sizeof(struct programmingThreadCtrl));
|
||||
|
||||
|
||||
program_type type = r_type;
|
||||
|
||||
// reset any types if to onetouch if available and if one touch is quicker
|
||||
// At moment. onetouch is quicker for boost, and slower for heaters
|
||||
if (onetouch_enabled() && extended_device_id_programming()) {
|
||||
switch (r_type){
|
||||
case AQ_GET_POOL_SPA_HEATER_TEMPS:
|
||||
case AQ_GET_FREEZE_PROTECT_TEMP:
|
||||
type = AQ_GET_ONETOUCH_SETPOINTS;
|
||||
break;
|
||||
case AQ_SET_POOL_HEATER_TEMP:
|
||||
type = AQ_SET_ONETOUCH_POOL_HEATER_TEMP;
|
||||
break;
|
||||
case AQ_SET_SPA_HEATER_TEMP:
|
||||
type = AQ_SET_ONETOUCH_SPA_HEATER_TEMP;
|
||||
break;
|
||||
case AQ_SET_BOOST:
|
||||
type = AQ_SET_ONETOUCH_BOOST;
|
||||
break;
|
||||
default:
|
||||
type = r_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check we are doing something valid request
|
||||
if (pda_mode() == true) {
|
||||
pda_reset_sleep();
|
||||
if (type != AQ_PDA_INIT &&
|
||||
|
|
@ -332,7 +418,11 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data)
|
|||
type != AQ_SET_BOOST) {
|
||||
logMessage(LOG_ERR, "Selected Programming mode '%d' not supported with PDA mode control panel\n",type);
|
||||
return;
|
||||
}
|
||||
} /*else if (onetouch_enabled() == false &&
|
||||
( type != AQ_SET_ONETOUCH_PUMP_RPM || type != AQ_SET_ONETOUCH_MACRO || type != AQ_GET_ONETOUCH_SETPOINTS)) {
|
||||
logMessage(LOG_ERR, "Selected Programming mode '%d' not supported without OneTouch mode (extra_device_id) enabled\n",type);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
programmingthread->aq_data = aq_data;
|
||||
|
|
@ -460,6 +550,54 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data)
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_PUMP_RPM:
|
||||
if( pthread_create( &programmingthread->thread_id , NULL , set_aqualink_pump_rpm, (void*)programmingthread) < 0) {
|
||||
logMessage (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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logMessage (LOG_ERR, "Don't understand thread type\n");
|
||||
break;
|
||||
|
|
@ -707,19 +845,17 @@ STOP BOOST POOL
|
|||
if (val==true) {
|
||||
waitForMessage(threadCtrl->aq_data, "TO START BOOST POOL", 5);
|
||||
send_cmd(KEY_ENTER);
|
||||
waitfor_queue2empty();
|
||||
longwaitfor_queue2empty();
|
||||
} else {
|
||||
int wait_messages = 5;
|
||||
int i=0;
|
||||
//waitfor_queue2empty();
|
||||
//waitForMessage(aq_data, NULL, 1);
|
||||
while( i++ < wait_messages)
|
||||
{
|
||||
waitForMessage(aq_data, "STOP BOOST POOL", 1);
|
||||
if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) {
|
||||
// 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);
|
||||
//_pgm_command = KEY_ENTER;
|
||||
send_cmd(KEY_ENTER);
|
||||
logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n");
|
||||
//waitfor_queue2empty();
|
||||
break;
|
||||
|
|
@ -727,38 +863,29 @@ STOP BOOST POOL
|
|||
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);
|
||||
delay(200);
|
||||
if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) {
|
||||
_pgm_command = KEY_ENTER;
|
||||
//_pgm_command = KEY_ENTER;
|
||||
send_cmd(KEY_ENTER);
|
||||
logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n");
|
||||
break;
|
||||
}
|
||||
send_cmd(KEY_RIGHT);
|
||||
//printf("WAIT\n");
|
||||
waitfor_queue2empty();
|
||||
longwaitfor_queue2empty();
|
||||
//printf("FINISHED WAIT\n");
|
||||
}
|
||||
//waitfor_queue2empty();
|
||||
//waitForMessage(aq_data, NULL, 1);
|
||||
}
|
||||
|
||||
waitForMessage(aq_data, "STOP BOOST POOL", 1);
|
||||
if (stristr(aq_data->last_message, "STOP BOOST POOL") != NULL) {
|
||||
//logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n");
|
||||
send_cmd(KEY_ENTER);
|
||||
} else {
|
||||
logMessage(LOG_DEBUG, "**** GIVING UP ****\n");
|
||||
if (i < wait_messages) {
|
||||
// Takes ages to see bost is off from menu, to set it here.
|
||||
aq_data->boost = false;
|
||||
aq_data->boost_msg[0] = '\0';
|
||||
aq_data->swg_percent = 0;
|
||||
}
|
||||
/*
|
||||
if (stristr(aq_data->last_message, "STOP BOOST POOL") == NULL) {
|
||||
send_cmd(KEY_RIGHT);
|
||||
logMessage(LOG_DEBUG, "**** FOUND STOP BOOST POOL ****\n");
|
||||
} else {
|
||||
logMessage(LOG_ERR, "**** NOT FOUND STOP BOOST POOL ****\n");
|
||||
}
|
||||
*/
|
||||
// Extra message overcome.
|
||||
//send_cmd(KEY_RIGHT);
|
||||
//waitfor_queue2empty();
|
||||
/*
|
||||
// Extra message overcome.
|
||||
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");
|
||||
cancel_menu();
|
||||
|
|
@ -767,6 +894,7 @@ STOP BOOST POOL
|
|||
}*/
|
||||
//send_cmd(KEY_ENTER);
|
||||
}
|
||||
|
||||
waitForMessage(aq_data,NULL, 1);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
|
@ -1403,11 +1531,11 @@ void send_cmd(unsigned char cmd, struct aqualinkdata *aq_data)
|
|||
}
|
||||
*/
|
||||
|
||||
void waitfor_queue2empty()
|
||||
void _waitfor_queue2empty(bool longwait)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
while ( (_pgm_command != NUL) && ( i++ < 20) ) {
|
||||
while ( (_pgm_command != NUL) && ( i++ < (30*(longwait?2:1) ) ) ) {
|
||||
//sleep(1); // NSF Change to smaller time.
|
||||
//logMessage(LOG_DEBUG, "******** QUEUE IS FULL ******** delay\n");
|
||||
delay(50);
|
||||
|
|
@ -1416,7 +1544,7 @@ void waitfor_queue2empty()
|
|||
if (_pgm_command != NUL) {
|
||||
if (pda_mode()) {
|
||||
// Wait for longer in PDA mode since it's slower.
|
||||
while ( (_pgm_command != NUL) && ( i++ < 100) ) {
|
||||
while ( (_pgm_command != NUL) && ( i++ < (130*(longwait?2:1)) ) ) {
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
|
@ -1425,6 +1553,15 @@ void waitfor_queue2empty()
|
|||
|
||||
}
|
||||
|
||||
void waitfor_queue2empty()
|
||||
{
|
||||
_waitfor_queue2empty(false);
|
||||
}
|
||||
void longwaitfor_queue2empty()
|
||||
{
|
||||
_waitfor_queue2empty(true);
|
||||
}
|
||||
|
||||
void send_cmd(unsigned char cmd)
|
||||
{
|
||||
waitfor_queue2empty();
|
||||
|
|
@ -1753,6 +1890,33 @@ const char *ptypeName(program_type type)
|
|||
case AQ_SET_BOOST:
|
||||
return "SWG Boost";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_PUMP_RPM:
|
||||
return "Set Pump RPM";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_MACRO:
|
||||
return "Set OneTouch Macro";
|
||||
break;
|
||||
case AQ_GET_ONETOUCH_SETPOINTS:
|
||||
return "Get OneTouch setpoints";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_TIME:
|
||||
return "Set OneTouch time";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_BOOST:
|
||||
return "Set OneTouch Boost";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_SWG_PERCENT:
|
||||
return "Set OneTouch SWG Percent";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_FREEZEPROTECT:
|
||||
return "Set OneTouch Freezeprotect";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_POOL_HEATER_TEMP:
|
||||
return "Set OneTouch Pool Heater Temp";
|
||||
break;
|
||||
case AQ_SET_ONETOUCH_SPA_HEATER_TEMP:
|
||||
return "Set OneTouch Spa Heater Temp";
|
||||
break;
|
||||
case AQP_NULL:
|
||||
default:
|
||||
return "Unknown";
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef AQ_PROGRAMMER_H_
|
||||
#define AQ_PROGRAMMER_H_
|
||||
|
||||
#include <pthread.h>
|
||||
//#include "aqualink.h"
|
||||
|
||||
// need to get the C values from aqualink manual and add those just incase
|
||||
// someone has the controller set to C.
|
||||
|
|
@ -21,6 +23,12 @@
|
|||
#define PTHREAD_ARG 25
|
||||
#define LIGHT_MODE_BUFER PTHREAD_ARG
|
||||
|
||||
typedef enum emulation_type{
|
||||
ALLBUTTON,
|
||||
ONETOUCH,
|
||||
AQUAPDA // AQUAPALM and PDA are taken as specific type.
|
||||
} emulation_type;
|
||||
|
||||
typedef enum {
|
||||
AQP_NULL = -1,
|
||||
AQ_GET_POOL_SPA_HEATER_TEMPS,
|
||||
|
|
@ -39,7 +47,16 @@ typedef enum {
|
|||
AQ_PDA_DEVICE_ON_OFF,
|
||||
AQ_GET_AUX_LABELS,
|
||||
AQ_PDA_WAKE_INIT,
|
||||
AQ_SET_BOOST
|
||||
AQ_SET_BOOST,
|
||||
AQ_SET_ONETOUCH_PUMP_RPM,
|
||||
AQ_SET_ONETOUCH_MACRO,
|
||||
AQ_GET_ONETOUCH_SETPOINTS,
|
||||
AQ_SET_ONETOUCH_POOL_HEATER_TEMP,
|
||||
AQ_SET_ONETOUCH_SPA_HEATER_TEMP,
|
||||
AQ_SET_ONETOUCH_FREEZEPROTECT,
|
||||
AQ_SET_ONETOUCH_TIME,
|
||||
AQ_SET_ONETOUCH_BOOST,
|
||||
AQ_SET_ONETOUCH_SWG_PERCENT
|
||||
} program_type;
|
||||
|
||||
struct programmingThreadCtrl {
|
||||
|
|
@ -49,14 +66,22 @@ struct programmingThreadCtrl {
|
|||
struct aqualinkdata *aq_data;
|
||||
};
|
||||
|
||||
typedef enum pump_type {
|
||||
PT_UNKNOWN = -1,
|
||||
EPUMP,
|
||||
VSPUMP,
|
||||
VFPUMP
|
||||
} pump_type;
|
||||
|
||||
|
||||
//void aq_programmer(program_type type, void *args, struct aqualinkdata *aq_data);
|
||||
void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data);
|
||||
void kick_aq_program_thread(struct aqualinkdata *aq_data);
|
||||
|
||||
//void kick_aq_program_thread(struct aqualinkdata *aq_data);
|
||||
void kick_aq_program_thread(struct aqualinkdata *aq_data, emulation_type source_type);
|
||||
bool in_ot_programming_mode(struct aqualinkdata *aq_data);
|
||||
void aq_send_cmd(unsigned char cmd);
|
||||
|
||||
void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data);
|
||||
void queueGetExtendedProgramData(emulation_type source_type, struct aqualinkdata *aq_data, bool labels);
|
||||
unsigned char pop_aq_cmd(struct aqualinkdata *aq_data);
|
||||
//bool push_aq_cmd(unsigned char cmd);
|
||||
|
||||
|
|
@ -68,6 +93,8 @@ unsigned char pop_aq_cmd(struct aqualinkdata *aq_data);
|
|||
|
||||
int get_aq_cmd_length();
|
||||
int setpoint_check(int type, int value, struct aqualinkdata *aqdata);
|
||||
int RPM_check(pump_type type, int value, struct aqualinkdata *aqdata);
|
||||
//int RPM_check(int type, int value, struct aqualinkdata *aqdata);
|
||||
const char *ptypeName(program_type type);
|
||||
|
||||
// These shouldn't be here, but just for the PDA AQ PROGRAMMER
|
||||
|
|
|
|||
117
aq_serial.c
117
aq_serial.c
|
|
@ -40,7 +40,27 @@ static struct termios _oldtio;
|
|||
void send_packet(int fd, unsigned char *packet, int length);
|
||||
//unsigned char getProtocolType(unsigned char* packet);
|
||||
|
||||
/*
|
||||
#ifdef ONETOUCH
|
||||
bool _onetouch_mode = false;
|
||||
void set_onetouch_mode(bool mode)
|
||||
{
|
||||
if (mode)
|
||||
logMessage(LOG_NOTICE, "AqualinkD is using Onetouch mode\n");
|
||||
|
||||
_onetouch_mode = mode;
|
||||
}
|
||||
bool onetouch_mode()
|
||||
{
|
||||
return _onetouch_mode;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
bool _pda_mode = false;
|
||||
bool _onetouch_enabled = false;
|
||||
bool _extended_device_id_programming = false;
|
||||
|
||||
void set_pda_mode(bool mode)
|
||||
{
|
||||
if (mode)
|
||||
|
|
@ -53,6 +73,30 @@ bool pda_mode()
|
|||
return _pda_mode;
|
||||
}
|
||||
|
||||
void set_onetouch_enabled(bool mode)
|
||||
{
|
||||
if (mode)
|
||||
logMessage(LOG_NOTICE, "AqualinkD is using use ONETOUCH mode for VSP programming\n");
|
||||
_onetouch_enabled = mode;
|
||||
}
|
||||
|
||||
bool onetouch_enabled()
|
||||
{
|
||||
return _onetouch_enabled;
|
||||
}
|
||||
|
||||
void set_extended_device_id_programming(bool mode)
|
||||
{
|
||||
if (mode)
|
||||
logMessage(LOG_NOTICE, "AqualinkD is using use ONETOUCH mode for programming (where supported)\n");
|
||||
_extended_device_id_programming = mode;
|
||||
}
|
||||
|
||||
bool extended_device_id_programming()
|
||||
{
|
||||
return _extended_device_id_programming;
|
||||
}
|
||||
|
||||
const char* get_packet_type(unsigned char* packet , int length)
|
||||
{
|
||||
static char buf[15];
|
||||
|
|
@ -101,7 +145,7 @@ const char* get_packet_type(unsigned char* packet , int length)
|
|||
return "PDA Shiftlines";
|
||||
break;
|
||||
case CMD_PDA_HIGHLIGHTCHARS:
|
||||
return "PDA C_HlightChar";
|
||||
return "PDA HlightChars";
|
||||
break;
|
||||
case CMD_IAQ_MSG:
|
||||
return "iAq Message";
|
||||
|
|
@ -438,10 +482,8 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
}
|
||||
|
||||
if ( getLogLevel() >= LOG_DEBUG_SERIAL) {
|
||||
//char buf[30];
|
||||
//sprintf(buf, "Sent %8.8s ", get_packet_type(packet+1, length));
|
||||
//log_packet(buf, packet, length);
|
||||
logMessage(LOG_DEBUG_SERIAL, "Serial send %d bytes\n",length-2);
|
||||
// Packet is padded with 0x00, so discard for logging
|
||||
logMessage(LOG_DEBUG_SERIAL, "Serial write %d bytes\n",length-2);
|
||||
logPacket(&packet[1], length-2);
|
||||
}
|
||||
}
|
||||
|
|
@ -460,6 +502,8 @@ void _send_ack(int fd, unsigned char ack_type, unsigned char command)
|
|||
ackPacket[7] = generate_checksum(ackPacket, length-1);
|
||||
}
|
||||
|
||||
//printf("***Send ACK (%s) ***\n",(ack_type==ACK_NORMAL?"Normal":(ack_type==ACK_SCREEN_BUSY?"ScreenBusy":"ScreenBusyDisplay")) );
|
||||
|
||||
send_packet(fd, ackPacket, length);
|
||||
}
|
||||
|
||||
|
|
@ -660,10 +704,8 @@ int _get_packet(int fd, unsigned char* packet, bool rawlog)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ( getLogLevel() >= LOG_DEBUG_SERIAL) {
|
||||
logMessage(LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
||||
logPacket(packet, index);
|
||||
}
|
||||
logMessage(LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
||||
logPacket(packet, index);
|
||||
// Return the packet length.
|
||||
return index;
|
||||
}
|
||||
|
|
@ -673,6 +715,63 @@ int _get_packet(int fd, unsigned char* packet, bool rawlog)
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#else //USE_AQ_SERIAL_OLD
|
||||
|
||||
|
||||
|
|
|
|||
60
aq_serial.h
60
aq_serial.h
|
|
@ -65,9 +65,27 @@
|
|||
|
||||
/* ACK RETURN COMMANDS */
|
||||
#define ACK_NORMAL 0x00
|
||||
#define ACK_SCREEN_BUSY 0x01 // Seems to be busy but can cache a message,
|
||||
#define ACK_SCREEN_BUSY_SCROLL 0x01 // Seems to be busy but can cache a message,
|
||||
#define ACK_SCREEN_BUSY_BLOCK 0x03 // Seems to be don't send me shit.
|
||||
|
||||
// Remove this and fix all compile errors when get time.
|
||||
#define ACK_SCREEN_BUSY ACK_SCREEN_BUSY_SCROLL
|
||||
|
||||
#define ACK_PDA 0x40
|
||||
#define ACK_ONETOUCH 0x80
|
||||
#define ACK_ALLB_SIM 0x80 // Jandy's Allbutton simulator uses this and not ACK_NORMAL
|
||||
#define ACK_ALLB_SIM_BUSY 0x81 // Jandy's Allbutton simulator uses this and not ACK_SCREEN_BUSY_SCROLL
|
||||
|
||||
/* ONE TOUCH KEYCODES */
|
||||
#define KEY_ONET_UP 0x06
|
||||
#define KEY_ONET_DOWN 0x05
|
||||
#define KEY_ONET_SELECT 0x04
|
||||
#define KEY_ONET_PAGE_UP 0x03 // Top
|
||||
#define KEY_ONET_BACK 0x02 // Middle
|
||||
#define KEY_ONET_PAGE_DN 0x01 // Bottom
|
||||
#define KEY_ONET_SELECT_1 KEY_ONET_PAGE_UP
|
||||
#define KEY_ONET_SELECT_2 KEY_ONET_BACK
|
||||
#define KEY_ONET_SELECT_3 KEY_ONET_PAGE_DN
|
||||
|
||||
/* AquaRite commands */
|
||||
#define CMD_GETID 0x14 // May be remote control control
|
||||
|
|
@ -187,7 +205,7 @@ SPILLOVER IS DISABLED WHILE SPA IS ON
|
|||
|
||||
#define MSG_PMP_RPM "RPM:"
|
||||
#define MSG_PMP_WAT "Watts:"
|
||||
#define MSG_PMP_GPH "GPH:"
|
||||
#define MSG_PMP_GPM "GPM:"
|
||||
|
||||
|
||||
/* AQUAPURE SWG */
|
||||
|
|
@ -221,11 +239,36 @@ SPILLOVER IS DISABLED WHILE SPA IS ON
|
|||
#define CMD_PDA_SHIFTLINES 0x0F
|
||||
#define CMD_PDA_HIGHLIGHTCHARS 0x10
|
||||
|
||||
// One Touch commands
|
||||
//#define CMD_PDA_0x04 0x04 // No idea, might be building menu
|
||||
|
||||
/* iAqualink */
|
||||
#define CMD_IAQ_MSG 0x25
|
||||
/* None of these are used, just here to gather data for the moment */
|
||||
#define CMD_IAQ_MSG 0x25 // Equiptment status message??
|
||||
#define CMD_IAQ_MENU_MSG 0x24
|
||||
|
||||
#define CMD_IAQ_MSG_LONG 0x2c // Long status message??
|
||||
#define CMD_IAQ_MSG_3 0x2d // Equiptment status message??
|
||||
#define CMD_IAQ_0x30 0x30
|
||||
#define CMD_IAQ_0x23 0x23
|
||||
#define CMD_IAQ_0x24 0x24 // Text for labels or maybe buttons (looks like next BIT is placment)
|
||||
#define CMD_IAQ_0x25 0x25 // Status for labels
|
||||
#define CMD_IAQ_0x31 0x31 // Some pump speed info
|
||||
|
||||
#define IAQ_KEY_PUMP 0x11
|
||||
#define IAQ_KEY_SPA 0x12
|
||||
#define IAQ_KEY_POOL_HEAT 0x13
|
||||
#define IAQ_KEY_SPA_HEAT 0x14
|
||||
#define IAQ_KEY_CUST_1 0x15
|
||||
#define IAQ_KEY_CUST_2 0x16
|
||||
#define IAQ_KEY_CUST_3 0x17
|
||||
#define IAQ_KEY_AUX1 0x19 // Depending on page this is 0x15
|
||||
#define IAQ_KEY_AUX2 0x1a
|
||||
#define IAQ_KEY_AUX3 0x1b
|
||||
#define IAQ_KEY_AUX4 0x1c
|
||||
#define IAQ_KEY_AUX5 0x1d
|
||||
#define IAQ_KEY_AUX6 0x1e
|
||||
#define IAQ_KEY_AUX7 0x1f
|
||||
|
||||
typedef enum {
|
||||
ON,
|
||||
|
|
@ -275,11 +318,22 @@ int get_packet_lograw(int fd, unsigned char* packet);
|
|||
void process_status(unsigned char* ptr);
|
||||
const char* get_packet_type(unsigned char* packet , int length);
|
||||
|
||||
void set_onetouch_enabled(bool mode);
|
||||
bool onetouch_enabled();
|
||||
|
||||
void set_extended_device_id_programming(bool mode);
|
||||
bool extended_device_id_programming();
|
||||
|
||||
void send_jandy_command(int fd, unsigned char *packet_buffer, int size);
|
||||
void send_pentair_command(int fd, unsigned char *packet_buffer, int size);
|
||||
void send_command(int fd, unsigned char *packet_buffer, int size);
|
||||
|
||||
/*
|
||||
#ifdef ONETOUCH
|
||||
void set_onetouch_mode(bool mode);
|
||||
bool onetouch_mode();
|
||||
#endif
|
||||
*/
|
||||
//void send_test_cmd(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3);
|
||||
//void send_command(int fd, unsigned char destination, unsigned char b1, unsigned char b2, unsigned char b3);
|
||||
//void send_messaged(int fd, unsigned char destination, char *message);
|
||||
|
|
|
|||
20
aqualink.h
20
aqualink.h
|
|
@ -59,25 +59,40 @@ typedef enum action_type {
|
|||
SPA_HTR_SETOINT,
|
||||
FREEZE_SETPOINT,
|
||||
SWG_SETPOINT,
|
||||
SWG_BOOST
|
||||
SWG_BOOST,
|
||||
PUMP_RPM
|
||||
} action_type;
|
||||
|
||||
struct action {
|
||||
action_type type;
|
||||
time_t requested;
|
||||
int value;
|
||||
int id; // Only used for Pumps at the moment.
|
||||
//char value[10];
|
||||
};
|
||||
|
||||
// Moved to aq_programmer to stop circular dependancy
|
||||
/*
|
||||
typedef enum pump_type {
|
||||
PT_UNKNOWN = -1,
|
||||
EPUMP,
|
||||
VSPUMP,
|
||||
VFPUMP
|
||||
} pump_type;
|
||||
*/
|
||||
|
||||
typedef struct pumpd
|
||||
{
|
||||
int rpm;
|
||||
int gph;
|
||||
int gpm;
|
||||
int watts;
|
||||
unsigned char pumpID;
|
||||
int pumpIndex;
|
||||
pump_type pumpType;
|
||||
//int buttonID;
|
||||
protocolType ptype;
|
||||
aqkey *button;
|
||||
//bool updated;
|
||||
} pump_detail;
|
||||
|
||||
struct aqualinkdata
|
||||
|
|
@ -115,6 +130,7 @@ struct aqualinkdata
|
|||
aqledstate service_mode_state;
|
||||
aqledstate frz_protect_state;
|
||||
unsigned char last_packet_type;
|
||||
int num_pumps;
|
||||
pump_detail pumps[MAX_PUMPS];
|
||||
int open_websockets;
|
||||
bool boost;
|
||||
|
|
|
|||
634
aqualinkd.c
634
aqualinkd.c
File diff suppressed because it is too large
Load Diff
18
aquapure.c
18
aquapure.c
|
|
@ -17,19 +17,23 @@ bool processPacketToSWG(unsigned char *packet, int packet_length, struct aqualin
|
|||
// Not really sure what to do with this, just ignore 0xff / 255 for the moment. (if statment above)
|
||||
|
||||
// SWG can get ~10 messages to set to 0 then go back again for some reason, so don't go to 0 until 10 messages are received
|
||||
if (swg_zero_cnt <= swg_zero_ignore && packet[4] == 0x00 && packet[5] == 0x73) {
|
||||
if (swg_zero_cnt <= swg_zero_ignore && packet[4] == 0x00) {
|
||||
logMessage(LOG_DEBUG, "Ignoring SWG set to %d due to packet packet count %d <= %d from control panel to SWG 0x%02hhx 0x%02hhx\n", (int)packet[4],
|
||||
swg_zero_cnt, swg_zero_ignore, packet[4], packet[5]);
|
||||
swg_zero_cnt++;
|
||||
} else if (swg_zero_cnt > swg_zero_ignore && packet[4] == 0x00 && packet[5] == 0x73) {
|
||||
aqdata->swg_percent = (int)packet[4];
|
||||
changedAnything = true;
|
||||
} else if (swg_zero_cnt > swg_zero_ignore && packet[4] == 0x00) {
|
||||
if (aqdata->swg_percent != (int)packet[4]) {
|
||||
aqdata->swg_percent = (int)packet[4];
|
||||
changedAnything = true;
|
||||
}
|
||||
// logMessage(LOG_DEBUG, "SWG set to %d due to packet packet count %d <= %d from control panel to SWG 0x%02hhx 0x%02hhx\n",
|
||||
// (int)packet[4],swg_zero_cnt,SWG_ZERO_IGNORE_COUNT,packet[4],packet[5]); swg_zero_cnt++;
|
||||
} else {
|
||||
swg_zero_cnt = 0;
|
||||
aqdata->swg_percent = (int)packet[4];
|
||||
changedAnything = true;
|
||||
if (aqdata->swg_percent != (int)packet[4]) {
|
||||
aqdata->swg_percent = (int)packet[4];
|
||||
changedAnything = true;
|
||||
}
|
||||
// logMessage(LOG_DEBUG, "SWG set to %d due to packet from control panel to SWG 0x%02hhx 0x%02hhx\n",
|
||||
// aqdata.swg_percent,packet[4],packet[5]);
|
||||
}
|
||||
|
|
@ -66,7 +70,7 @@ bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqual
|
|||
aqledstate get_swg_led_state(struct aqualinkdata *aqdata)
|
||||
{
|
||||
switch (aqdata->ar_swg_status) {
|
||||
// Level = (0=gray, 1=green, 2=yellow, 3=orange, 4=red)
|
||||
|
||||
case SWG_STATUS_ON:
|
||||
return (aqdata->swg_percent > 0?ON:ENABLE);
|
||||
break;
|
||||
|
|
|
|||
324
config.c
324
config.c
|
|
@ -33,19 +33,24 @@
|
|||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#define CONFIG_C
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
#include "aq_serial.h"
|
||||
|
||||
#define MAXCFGLINE 256
|
||||
|
||||
|
||||
|
||||
char *generate_mqtt_id(char *buf, int len);
|
||||
pump_detail *getpump(struct aqualinkdata *aqdata, int button);
|
||||
|
||||
/*
|
||||
* initialize data to default values
|
||||
*/
|
||||
void init_parameters (struct aqconfig * parms)
|
||||
{
|
||||
//int i;
|
||||
//char *p;
|
||||
parms->serial_port = DEFAULT_SERIALPORT;
|
||||
parms->log_level = DEFAULT_LOG_LEVEL;
|
||||
|
|
@ -53,6 +58,7 @@ void init_parameters (struct aqconfig * parms)
|
|||
parms->web_directory = DEFAULT_WEBROOT;
|
||||
//parms->device_id = strtoul(DEFAULT_DEVICE_ID, &p, 16);
|
||||
parms->device_id = strtoul(DEFAULT_DEVICE_ID, NULL, 16);
|
||||
parms->onetouch_device_id = 0x00;
|
||||
//sscanf(DEFAULT_DEVICE_ID, "0x%x", &parms->device_id);
|
||||
parms->override_freeze_protect = FALSE;
|
||||
|
||||
|
|
@ -76,6 +82,7 @@ void init_parameters (struct aqconfig * parms)
|
|||
parms->deamonize = true;
|
||||
parms->log_file = '\0';
|
||||
parms->pda_mode = false;
|
||||
parms->onetouch_mode = false;
|
||||
parms->pda_sleep_mode = false;
|
||||
parms->convert_mqtt_temp = true;
|
||||
parms->convert_dz_temp = true;
|
||||
|
|
@ -90,6 +97,7 @@ void init_parameters (struct aqconfig * parms)
|
|||
parms->swg_zero_ignore = DEFAILT_SWG_ZERO_IGNORE_COUNT;
|
||||
parms->display_warnings_web = false;
|
||||
parms->log_raw_RS_bytes = false;
|
||||
parms->extended_device_id_programming = false;
|
||||
|
||||
generate_mqtt_id(parms->mqtt_ID, MQTT_ID_LEN);
|
||||
}
|
||||
|
|
@ -219,69 +227,69 @@ void readCfg_OLD (struct aqconfig *config_parameters, struct aqualinkdata *aqdat
|
|||
if ( indx != NULL)
|
||||
{
|
||||
if (strncasecmp (b_ptr, "socket_port", 11) == 0) {
|
||||
//config_parameters->socket_port = cleanint(indx+1);
|
||||
config_parameters->socket_port = cleanalloc(indx+1);
|
||||
//_aqconfig_.socket_port = cleanint(indx+1);
|
||||
_aqconfig_.socket_port = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "serial_port", 11) == 0) {
|
||||
config_parameters->serial_port = cleanalloc(indx+1);
|
||||
_aqconfig_.serial_port = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "log_level", 9) == 0) {
|
||||
config_parameters->log_level = text2elevel(cleanalloc(indx+1));
|
||||
_aqconfig_.log_level = text2elevel(cleanalloc(indx+1));
|
||||
// should fee mem here
|
||||
} else if (strncasecmp (b_ptr, "device_id", 9) == 0) {
|
||||
config_parameters->device_id = strtoul(cleanalloc(indx+1), NULL, 16);
|
||||
_aqconfig_.device_id = strtoul(cleanalloc(indx+1), NULL, 16);
|
||||
// should fee mem here
|
||||
} else if (strncasecmp (b_ptr, "web_directory", 13) == 0) {
|
||||
config_parameters->web_directory = cleanalloc(indx+1);
|
||||
_aqconfig_.web_directory = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "log_file", 8) == 0) {
|
||||
config_parameters->log_file = cleanalloc(indx+1);
|
||||
_aqconfig_.log_file = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_address", 12) == 0) {
|
||||
config_parameters->mqtt_server = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_server = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_dz_sub_topic", 17) == 0) {
|
||||
config_parameters->mqtt_dz_sub_topic = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_dz_sub_topic = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_dz_pub_topic", 17) == 0) {
|
||||
config_parameters->mqtt_dz_pub_topic = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_dz_pub_topic = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_aq_topic", 13) == 0) {
|
||||
config_parameters->mqtt_aq_topic = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_aq_topic = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_user", 9) == 0) {
|
||||
config_parameters->mqtt_user = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_user = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "mqtt_passwd", 11) == 0) {
|
||||
config_parameters->mqtt_passwd = cleanalloc(indx+1);
|
||||
_aqconfig_.mqtt_passwd = cleanalloc(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "air_temp_dzidx", 14) == 0) {
|
||||
config_parameters->dzidx_air_temp = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_air_temp = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "pool_water_temp_dzidx", 21) == 0) {
|
||||
config_parameters->dzidx_pool_water_temp = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_pool_water_temp = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "spa_water_temp_dzidx", 20) == 0) {
|
||||
config_parameters->dzidx_spa_water_temp = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_spa_water_temp = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "light_programming_mode", 21) == 0) {
|
||||
config_parameters->light_programming_mode = atof(cleanalloc(indx+1)); // should free this
|
||||
_aqconfig_.light_programming_mode = atof(cleanalloc(indx+1)); // should free this
|
||||
} else if (strncasecmp (b_ptr, "light_programming_initial_on", 28) == 0) {
|
||||
config_parameters->light_programming_initial_on = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.light_programming_initial_on = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "light_programming_initial_off", 29) == 0) {
|
||||
config_parameters->light_programming_initial_off = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.light_programming_initial_off = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "light_programming_button", 21) == 0) {
|
||||
config_parameters->light_programming_button = strtoul(indx+1, NULL, 10) - 1;
|
||||
_aqconfig_.light_programming_button = strtoul(indx+1, NULL, 10) - 1;
|
||||
} else if (strncasecmp (b_ptr, "SWG_percent_dzidx", 17) == 0) {
|
||||
config_parameters->dzidx_swg_percent = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_percent = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "SWG_PPM_dzidx", 13) == 0) {
|
||||
config_parameters->dzidx_swg_ppm = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_ppm = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "SWG_Status_dzidx", 14) == 0) {
|
||||
config_parameters->dzidx_swg_status = strtoul(indx+1, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_status = strtoul(indx+1, NULL, 10);
|
||||
} else if (strncasecmp (b_ptr, "override_freeze_protect", 23) == 0) {
|
||||
config_parameters->override_freeze_protect = text2bool(indx+1);
|
||||
_aqconfig_.override_freeze_protect = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "pda_mode", 8) == 0) {
|
||||
config_parameters->pda_mode = text2bool(indx+1);
|
||||
set_pda_mode(config_parameters->pda_mode);
|
||||
_aqconfig_.pda_mode = text2bool(indx+1);
|
||||
set_pda_mode(_aqconfig_.pda_mode);
|
||||
} else if (strncasecmp (b_ptr, "convert_mqtt_temp_to_c", 22) == 0) {
|
||||
config_parameters->convert_mqtt_temp = text2bool(indx+1);
|
||||
_aqconfig_.convert_mqtt_temp = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "convert_dz_temp_to_c", 21) == 0) {
|
||||
config_parameters->convert_dz_temp = text2bool(indx+1);
|
||||
_aqconfig_.convert_dz_temp = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "flash_mqtt_buttons", 18) == 0) {
|
||||
config_parameters->flash_mqtt_buttons = text2bool(indx+1);
|
||||
_aqconfig_.flash_mqtt_buttons = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "report_zero_pool_temp", 21) == 0) {
|
||||
config_parameters->report_zero_pool_temp = text2bool(indx+1);
|
||||
_aqconfig_.report_zero_pool_temp = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "report_zero_spa_temp", 20) == 0) {
|
||||
config_parameters->report_zero_spa_temp = text2bool(indx+1);
|
||||
_aqconfig_.report_zero_spa_temp = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "report_zero_pool_temp", 21) == 0) {
|
||||
config_parameters->report_zero_pool_temp = text2bool(indx+1);
|
||||
_aqconfig_.report_zero_pool_temp = text2bool(indx+1);
|
||||
} else if (strncasecmp (b_ptr, "button_", 7) == 0) {
|
||||
int num = strtoul(b_ptr+7, NULL, 10) - 1;
|
||||
//logMessage (LOG_DEBUG, "Button %d\n", strtoul(b_ptr+7, NULL, 10));
|
||||
|
|
@ -310,146 +318,154 @@ void readCfg_OLD (struct aqconfig *config_parameters, struct aqualinkdata *aqdat
|
|||
}
|
||||
*/
|
||||
|
||||
bool setConfigValue(struct aqconfig *config_parameters, struct aqualinkdata *aqdata, char *param, char *value) {
|
||||
bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
||||
bool rtn = false;
|
||||
static int pi=0;
|
||||
|
||||
if (strncasecmp(param, "socket_port", 11) == 0) {
|
||||
config_parameters->socket_port = cleanalloc(value);
|
||||
_aqconfig_.socket_port = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "serial_port", 11) == 0) {
|
||||
config_parameters->serial_port = cleanalloc(value);
|
||||
_aqconfig_.serial_port = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "log_level", 9) == 0) {
|
||||
config_parameters->log_level = text2elevel(cleanalloc(value));
|
||||
_aqconfig_.log_level = text2elevel(cleanalloc(value));
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "device_id", 9) == 0) {
|
||||
config_parameters->device_id = strtoul(cleanalloc(value), NULL, 16);
|
||||
_aqconfig_.device_id = strtoul(cleanalloc(value), NULL, 16);
|
||||
} else if (strncasecmp (param, "extended_device_id_programming", 30) == 0) {
|
||||
// Has to be before the below.
|
||||
_aqconfig_.extended_device_id_programming = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "extended_device_id", 9) == 0) {
|
||||
_aqconfig_.onetouch_device_id = strtoul(cleanalloc(value), NULL, 16);
|
||||
//_config_parameters.onetouch_device_id != 0x00
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "web_directory", 13) == 0) {
|
||||
config_parameters->web_directory = cleanalloc(value);
|
||||
_aqconfig_.web_directory = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "log_file", 8) == 0) {
|
||||
config_parameters->log_file = cleanalloc(value);
|
||||
_aqconfig_.log_file = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_address", 12) == 0) {
|
||||
config_parameters->mqtt_server = cleanalloc(value);
|
||||
_aqconfig_.mqtt_server = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_dz_sub_topic", 17) == 0) {
|
||||
config_parameters->mqtt_dz_sub_topic = cleanalloc(value);
|
||||
_aqconfig_.mqtt_dz_sub_topic = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_dz_pub_topic", 17) == 0) {
|
||||
config_parameters->mqtt_dz_pub_topic = cleanalloc(value);
|
||||
_aqconfig_.mqtt_dz_pub_topic = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_aq_topic", 13) == 0) {
|
||||
config_parameters->mqtt_aq_topic = cleanalloc(value);
|
||||
_aqconfig_.mqtt_aq_topic = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_user", 9) == 0) {
|
||||
config_parameters->mqtt_user = cleanalloc(value);
|
||||
_aqconfig_.mqtt_user = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "mqtt_passwd", 11) == 0) {
|
||||
config_parameters->mqtt_passwd = cleanalloc(value);
|
||||
_aqconfig_.mqtt_passwd = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "air_temp_dzidx", 14) == 0) {
|
||||
config_parameters->dzidx_air_temp = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_air_temp = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "pool_water_temp_dzidx", 21) == 0) {
|
||||
config_parameters->dzidx_pool_water_temp = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_pool_water_temp = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "spa_water_temp_dzidx", 20) == 0) {
|
||||
config_parameters->dzidx_spa_water_temp = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_spa_water_temp = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "light_programming_mode", 21) == 0) {
|
||||
config_parameters->light_programming_mode = atof(cleanalloc(value)); // should free this
|
||||
_aqconfig_.light_programming_mode = atof(cleanalloc(value)); // should free this
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "light_programming_initial_on", 28) == 0) {
|
||||
config_parameters->light_programming_initial_on = strtoul(value, NULL, 10);
|
||||
_aqconfig_.light_programming_initial_on = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "light_programming_initial_off", 29) == 0) {
|
||||
config_parameters->light_programming_initial_off = strtoul(value, NULL, 10);
|
||||
_aqconfig_.light_programming_initial_off = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "light_programming_button_spa", 28) == 0) {
|
||||
config_parameters->light_programming_button_spa = strtoul(value, NULL, 10) - 1;
|
||||
_aqconfig_.light_programming_button_spa = strtoul(value, NULL, 10) - 1;
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "light_programming_button", 24) == 0 ||
|
||||
strncasecmp(param, "light_programming_button_pool", 29) == 0) {
|
||||
config_parameters->light_programming_button_pool = strtoul(value, NULL, 10) - 1;
|
||||
_aqconfig_.light_programming_button_pool = strtoul(value, NULL, 10) - 1;
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "SWG_percent_dzidx", 17) == 0) {
|
||||
config_parameters->dzidx_swg_percent = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_percent = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "SWG_PPM_dzidx", 13) == 0) {
|
||||
config_parameters->dzidx_swg_ppm = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_ppm = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "SWG_Status_dzidx", 14) == 0) {
|
||||
config_parameters->dzidx_swg_status = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_swg_status = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "override_freeze_protect", 23) == 0) {
|
||||
config_parameters->override_freeze_protect = text2bool(value);
|
||||
_aqconfig_.override_freeze_protect = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "pda_mode", 8) == 0) {
|
||||
config_parameters->pda_mode = text2bool(value);
|
||||
set_pda_mode(config_parameters->pda_mode);
|
||||
//config_parameters->use_PDA_auxiliary = false;
|
||||
_aqconfig_.pda_mode = text2bool(value);
|
||||
set_pda_mode(_aqconfig_.pda_mode);
|
||||
//_aqconfig_.use_PDA_auxiliary = false;
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "pda_sleep_mode", 8) == 0) {
|
||||
config_parameters->pda_sleep_mode = text2bool(value);
|
||||
//set_pda_mode(config_parameters->pda_mode);
|
||||
_aqconfig_.pda_sleep_mode = text2bool(value);
|
||||
//set_pda_mode(_aqconfig_.pda_mode);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "convert_mqtt_temp_to_c", 22) == 0) {
|
||||
config_parameters->convert_mqtt_temp = text2bool(value);
|
||||
_aqconfig_.convert_mqtt_temp = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "convert_dz_temp_to_c", 20) == 0) {
|
||||
config_parameters->convert_dz_temp = text2bool(value);
|
||||
_aqconfig_.convert_dz_temp = text2bool(value);
|
||||
rtn=true;
|
||||
/*
|
||||
} else if (strncasecmp(param, "flash_mqtt_buttons", 18) == 0) {
|
||||
config_parameters->flash_mqtt_buttons = text2bool(value);
|
||||
_aqconfig_.flash_mqtt_buttons = text2bool(value);
|
||||
rtn=true;*/
|
||||
} else if (strncasecmp(param, "report_zero_spa_temp", 20) == 0) {
|
||||
config_parameters->report_zero_spa_temp = text2bool(value);
|
||||
_aqconfig_.report_zero_spa_temp = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "report_zero_pool_temp", 21) == 0) {
|
||||
config_parameters->report_zero_pool_temp = text2bool(value);
|
||||
_aqconfig_.report_zero_pool_temp = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "read_all_devices", 16) == 0) {
|
||||
config_parameters->read_all_devices = text2bool(value);
|
||||
_aqconfig_.read_all_devices = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "use_panel_aux_labels", 20) == 0) {
|
||||
config_parameters->use_panel_aux_labels = text2bool(value);
|
||||
_aqconfig_.use_panel_aux_labels = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "force_SWG", 9) == 0) {
|
||||
config_parameters->force_swg = text2bool(value);
|
||||
_aqconfig_.force_swg = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "debug_RSProtocol_packets", 24) == 0) {
|
||||
config_parameters->debug_RSProtocol_packets = text2bool(value);
|
||||
_aqconfig_.debug_RSProtocol_packets = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "read_pentair_packets", 17) == 0) {
|
||||
config_parameters->read_pentair_packets = text2bool(value);
|
||||
config_parameters->read_all_devices = true;
|
||||
_aqconfig_.read_pentair_packets = text2bool(value);
|
||||
if (_aqconfig_.read_pentair_packets)
|
||||
_aqconfig_.read_all_devices = true;
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "swg_zero_ignore_count", 21) == 0) {
|
||||
config_parameters->swg_zero_ignore = strtoul(value, NULL, 10);
|
||||
_aqconfig_.swg_zero_ignore = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "display_warnings_in_web", 23) == 0) {
|
||||
config_parameters->display_warnings_web = text2bool(value);
|
||||
_aqconfig_.display_warnings_web = text2bool(value);
|
||||
rtn=true;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (strncasecmp (param, "use_PDA_auxiliary", 17) == 0) {
|
||||
config_parameters->use_PDA_auxiliary = text2bool(value);
|
||||
_aqconfig_.use_PDA_auxiliary = text2bool(value);
|
||||
if ( pda_mode() ) {
|
||||
logMessage(LOG_ERR, "ERROR Can't use `use_PDA_auxiliary` in PDA mode, ignoring'\n");
|
||||
config_parameters->use_PDA_auxiliary = false;
|
||||
_aqconfig_.use_PDA_auxiliary = false;
|
||||
}
|
||||
rtn=true;
|
||||
} */
|
||||
// removed until domoticz has a better virtual thermostat
|
||||
/*else if (strncasecmp (param, "pool_thermostat_dzidx", 21) == 0) {
|
||||
config_parameters->dzidx_pool_thermostat = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_pool_thermostat = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "spa_thermostat_dzidx", 20) == 0) {
|
||||
config_parameters->dzidx_spa_thermostat = strtoul(value, NULL, 10);
|
||||
_aqconfig_.dzidx_spa_thermostat = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
} */
|
||||
else if (strncasecmp(param, "button_", 7) == 0) {
|
||||
|
|
@ -463,30 +479,92 @@ bool setConfigValue(struct aqconfig *config_parameters, struct aqualinkdata *aqd
|
|||
} else if (strncasecmp(param + 9, "_PDA_label", 10) == 0) {
|
||||
aqdata->aqbuttons[num].pda_label = cleanalloc(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpID", 7) == 0) {
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
pump->pumpID = strtoul(cleanalloc(value), NULL, 16);
|
||||
if (pump->pumpID < 119) {
|
||||
pump->ptype = PENTAIR;
|
||||
} else {
|
||||
pump->ptype = JANDY;
|
||||
//pump->pumpType = EPUMP; // For testing let the interface set this
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring %s'\n",MAX_PUMPS-1,param);
|
||||
}
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpIndex", 10) == 0) { //button_01_pumpIndex=1
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
pump->pumpIndex = strtoul(value, NULL, 10);
|
||||
} else {
|
||||
logMessage(LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring %s'\n",MAX_PUMPS-1,param);
|
||||
}
|
||||
rtn=true;
|
||||
}
|
||||
/*
|
||||
} else if (strncasecmp(param + 9, "_pumpID", 7) == 0) {
|
||||
//aqdata->aqbuttons[num].pda_label = cleanalloc(value);
|
||||
//96 to 111 = Pentair, 120 to 123 = Jandy
|
||||
if (pi < MAX_PUMPS) {
|
||||
aqdata->pumps[pi].button = &aqdata->aqbuttons[num];
|
||||
aqdata->pumps[pi].pumpID = strtoul(cleanalloc(value), NULL, 16);
|
||||
aqdata->pumps[pi].pumpIndex = pi+1;
|
||||
//aqdata->pumps[pi].buttonID = num;
|
||||
if (aqdata->pumps[pi].pumpID < 119)
|
||||
aqdata->pumps[pi].ptype = PENTAIR;
|
||||
else
|
||||
aqdata->pumps[pi].ptype = JANDY;
|
||||
pi++;
|
||||
|
||||
} else {
|
||||
logMessage(LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring %s'\n",MAX_PUMPS,param);
|
||||
}
|
||||
rtn=true;
|
||||
}
|
||||
} else if (strncasecmp(param + 9, "_pumpIndex", 10) == 0) { //button_01_pumpIndex=1
|
||||
}*/
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
pump_detail *getpump(struct aqualinkdata *aqdata, int button)
|
||||
{
|
||||
//static int _pumpindex = 0;
|
||||
//aqdata->num_pumps
|
||||
int pi;
|
||||
|
||||
void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata, char *cfgFile)
|
||||
// Does it exist
|
||||
for (pi=0; pi < aqdata->num_pumps; pi++) {
|
||||
if (aqdata->pumps[pi].button == &aqdata->aqbuttons[button]) {
|
||||
//printf ("Found pump %d\n",button);
|
||||
return &aqdata->pumps[pi];
|
||||
}
|
||||
}
|
||||
|
||||
// Create new entry
|
||||
if (aqdata->num_pumps < MAX_PUMPS) {
|
||||
//printf ("Creating pump %d\n",button);
|
||||
aqdata->pumps[aqdata->num_pumps].button = &aqdata->aqbuttons[button];
|
||||
aqdata->pumps[aqdata->num_pumps].pumpType = PT_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].rpm = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].watts = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].gpm = TEMP_UNKNOWN;
|
||||
aqdata->num_pumps++;
|
||||
return &aqdata->pumps[aqdata->num_pumps-1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void init_config()
|
||||
{
|
||||
init_parameters(&_aqconfig_);
|
||||
}
|
||||
|
||||
//void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata, char *cfgFile)
|
||||
void read_config (struct aqualinkdata *aqdata, char *cfgFile)
|
||||
{
|
||||
FILE * fp ;
|
||||
char bufr[MAXCFGLINE];
|
||||
|
|
@ -496,7 +574,7 @@ void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata, c
|
|||
//int tokenindex = 0;
|
||||
char *b_ptr;
|
||||
|
||||
config_parameters->config_file = cleanalloc(cfgFile);
|
||||
_aqconfig_.config_file = cleanalloc(cfgFile);
|
||||
|
||||
if( (fp = fopen(cfgFile, "r")) != NULL){
|
||||
while(! feof(fp)){
|
||||
|
|
@ -511,7 +589,7 @@ void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata, c
|
|||
indx = strchr(b_ptr, '=');
|
||||
if ( indx != NULL)
|
||||
{
|
||||
if ( ! setConfigValue(config_parameters, aqdata, b_ptr, indx+1))
|
||||
if ( ! setConfigValue(aqdata, b_ptr, indx+1))
|
||||
logMessage(LOG_ERR, "Unknown config parameter '%.*s'\n",strlen(b_ptr)-1, b_ptr);
|
||||
}
|
||||
}
|
||||
|
|
@ -596,67 +674,67 @@ void writeIntValue (FILE *fp, char *msg, int value)
|
|||
fprintf(fp, "%s = %d\n", msg, value);
|
||||
}
|
||||
|
||||
bool writeCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata)
|
||||
bool writeCfg (struct aqualinkdata *aqdata)
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
bool fs = remount_root_ro(false);
|
||||
|
||||
fp = fopen(config_parameters->config_file, "w");
|
||||
fp = fopen(_aqconfig_.config_file, "w");
|
||||
if (fp == NULL) {
|
||||
logMessage(LOG_ERR, "Open config file failed '%s'\n", config_parameters->config_file);
|
||||
logMessage(LOG_ERR, "Open config file failed '%s'\n", _aqconfig_.config_file);
|
||||
remount_root_ro(true);
|
||||
//fprintf(stdout, "Open file failed 'sprinkler.cron'\n");
|
||||
return false;
|
||||
}
|
||||
fprintf(fp, "#***** AqualinkD configuration *****\n");
|
||||
|
||||
fprintf(fp, "socket_port = %s\n", config_parameters->socket_port);
|
||||
fprintf(fp, "serial_port = %s\n", config_parameters->serial_port);
|
||||
fprintf(fp, "device_id = 0x%02hhx\n", config_parameters->device_id);
|
||||
fprintf(fp, "read_all_devices = %s", bool2text(config_parameters->read_all_devices));
|
||||
writeCharValue(fp, "log_level", errorlevel2text(config_parameters->log_level));
|
||||
writeCharValue(fp, "web_directory", config_parameters->web_directory);
|
||||
writeCharValue(fp, "log_file", config_parameters->log_file);
|
||||
fprintf(fp, "pda_mode = %s\n", bool2text(config_parameters->pda_mode));
|
||||
fprintf(fp, "socket_port = %s\n", _aqconfig_.socket_port);
|
||||
fprintf(fp, "serial_port = %s\n", _aqconfig_.serial_port);
|
||||
fprintf(fp, "device_id = 0x%02hhx\n", _aqconfig_.device_id);
|
||||
fprintf(fp, "read_all_devices = %s", bool2text(_aqconfig_.read_all_devices));
|
||||
writeCharValue(fp, "log_level", errorlevel2text(_aqconfig_.log_level));
|
||||
writeCharValue(fp, "web_directory", _aqconfig_.web_directory);
|
||||
writeCharValue(fp, "log_file", _aqconfig_.log_file);
|
||||
fprintf(fp, "pda_mode = %s\n", bool2text(_aqconfig_.pda_mode));
|
||||
|
||||
fprintf(fp, "\n#** MQTT Configuration **\n");
|
||||
writeCharValue(fp, "mqtt_address", config_parameters->mqtt_server);
|
||||
writeCharValue(fp, "mqtt_dz_sub_topic", config_parameters->mqtt_dz_sub_topic);
|
||||
writeCharValue(fp, "mqtt_dz_pub_topic", config_parameters->mqtt_dz_pub_topic);
|
||||
writeCharValue(fp, "mqtt_aq_topic", config_parameters->mqtt_aq_topic);
|
||||
writeCharValue(fp, "mqtt_user", config_parameters->mqtt_user);
|
||||
writeCharValue(fp, "mqtt_passwd", config_parameters->mqtt_passwd);
|
||||
writeCharValue(fp, "mqtt_address", _aqconfig_.mqtt_server);
|
||||
writeCharValue(fp, "mqtt_dz_sub_topic", _aqconfig_.mqtt_dz_sub_topic);
|
||||
writeCharValue(fp, "mqtt_dz_pub_topic", _aqconfig_.mqtt_dz_pub_topic);
|
||||
writeCharValue(fp, "mqtt_aq_topic", _aqconfig_.mqtt_aq_topic);
|
||||
writeCharValue(fp, "mqtt_user", _aqconfig_.mqtt_user);
|
||||
writeCharValue(fp, "mqtt_passwd", _aqconfig_.mqtt_passwd);
|
||||
|
||||
fprintf(fp, "\n#** General **\n");
|
||||
fprintf(fp, "convert_mqtt_temp_to_c = %s\n", bool2text(config_parameters->convert_mqtt_temp));
|
||||
fprintf(fp, "override_freeze_protect = %s\n", bool2text(config_parameters->override_freeze_protect));
|
||||
//fprintf(fp, "flash_mqtt_buttons = %s\n", bool2text(config_parameters->flash_mqtt_buttons));
|
||||
fprintf(fp, "report_zero_spa_temp = %s\n", bool2text(config_parameters->report_zero_spa_temp));
|
||||
fprintf(fp, "report_zero_pool_temp = %s\n", bool2text(config_parameters->report_zero_pool_temp));
|
||||
fprintf(fp, "convert_mqtt_temp_to_c = %s\n", bool2text(_aqconfig_.convert_mqtt_temp));
|
||||
fprintf(fp, "override_freeze_protect = %s\n", bool2text(_aqconfig_.override_freeze_protect));
|
||||
//fprintf(fp, "flash_mqtt_buttons = %s\n", bool2text(_aqconfig_.flash_mqtt_buttons));
|
||||
fprintf(fp, "report_zero_spa_temp = %s\n", bool2text(_aqconfig_.report_zero_spa_temp));
|
||||
fprintf(fp, "report_zero_pool_temp = %s\n", bool2text(_aqconfig_.report_zero_pool_temp));
|
||||
|
||||
fprintf(fp, "\n#** Programmable light **\n");
|
||||
//if (config_parameters->light_programming_button_pool <= 0) {
|
||||
// fprintf(fp, "#light_programming_button_pool = %d\n", config_parameters->light_programming_button_pool);
|
||||
// fprintf(fp, "#light_programming_mode = %f\n", config_parameters->light_programming_mode);
|
||||
// fprintf(fp, "#light_programming_initial_on = %d\n", config_parameters->light_programming_initial_on);
|
||||
// fprintf(fp, "#light_programming_initial_off = %d\n", config_parameters->light_programming_initial_off);
|
||||
//if (_aqconfig_.light_programming_button_pool <= 0) {
|
||||
// fprintf(fp, "#light_programming_button_pool = %d\n", _aqconfig_.light_programming_button_pool);
|
||||
// fprintf(fp, "#light_programming_mode = %f\n", _aqconfig_.light_programming_mode);
|
||||
// fprintf(fp, "#light_programming_initial_on = %d\n", _aqconfig_.light_programming_initial_on);
|
||||
// fprintf(fp, "#light_programming_initial_off = %d\n", _aqconfig_.light_programming_initial_off);
|
||||
//} else {
|
||||
fprintf(fp, "light_programming_button_pool = %d\n", config_parameters->light_programming_button_pool);
|
||||
fprintf(fp, "light_programming_button_spa = %d\n", config_parameters->light_programming_button_spa);
|
||||
fprintf(fp, "light_programming_mode = %f\n", config_parameters->light_programming_mode);
|
||||
fprintf(fp, "light_programming_initial_on = %d\n", config_parameters->light_programming_initial_on);
|
||||
fprintf(fp, "light_programming_initial_off = %d\n", config_parameters->light_programming_initial_off);
|
||||
fprintf(fp, "light_programming_button_pool = %d\n", _aqconfig_.light_programming_button_pool);
|
||||
fprintf(fp, "light_programming_button_spa = %d\n", _aqconfig_.light_programming_button_spa);
|
||||
fprintf(fp, "light_programming_mode = %f\n", _aqconfig_.light_programming_mode);
|
||||
fprintf(fp, "light_programming_initial_on = %d\n", _aqconfig_.light_programming_initial_on);
|
||||
fprintf(fp, "light_programming_initial_off = %d\n", _aqconfig_.light_programming_initial_off);
|
||||
//}
|
||||
|
||||
fprintf(fp, "\n#** Domoticz **\n");
|
||||
fprintf(fp, "convert_dz_temp_to_c = %s\n", bool2text(config_parameters->convert_dz_temp));
|
||||
writeIntValue(fp, "air_temp_dzidx", config_parameters->dzidx_air_temp);
|
||||
writeIntValue(fp, "pool_water_temp_dzidx", config_parameters->dzidx_pool_water_temp);
|
||||
writeIntValue(fp, "spa_water_temp_dzidx", config_parameters->dzidx_spa_water_temp);
|
||||
writeIntValue(fp, "SWG_percent_dzidx", config_parameters->dzidx_swg_percent);
|
||||
writeIntValue(fp, "SWG_PPM_dzidx", config_parameters->dzidx_swg_ppm);
|
||||
writeIntValue(fp, "SWG_Status_dzidx", config_parameters->dzidx_swg_status);
|
||||
fprintf(fp, "convert_dz_temp_to_c = %s\n", bool2text(_aqconfig_.convert_dz_temp));
|
||||
writeIntValue(fp, "air_temp_dzidx", _aqconfig_.dzidx_air_temp);
|
||||
writeIntValue(fp, "pool_water_temp_dzidx", _aqconfig_.dzidx_pool_water_temp);
|
||||
writeIntValue(fp, "spa_water_temp_dzidx", _aqconfig_.dzidx_spa_water_temp);
|
||||
writeIntValue(fp, "SWG_percent_dzidx", _aqconfig_.dzidx_swg_percent);
|
||||
writeIntValue(fp, "SWG_PPM_dzidx", _aqconfig_.dzidx_swg_ppm);
|
||||
writeIntValue(fp, "SWG_Status_dzidx", _aqconfig_.dzidx_swg_status);
|
||||
|
||||
fprintf(fp, "\n#** Buttons **\n");
|
||||
for (i=0; i < TOTAL_BUTTONS; i++)
|
||||
|
|
|
|||
31
config.h
31
config.h
|
|
@ -7,7 +7,8 @@
|
|||
#include "aqualink.h"
|
||||
|
||||
|
||||
#define DEFAULT_LOG_LEVEL 5
|
||||
//#define DEFAULT_LOG_LEVEL 10
|
||||
#define DEFAULT_LOG_LEVEL LOG_NOTICE
|
||||
#define DEFAULT_WEBPORT "6580"
|
||||
#define DEFAULT_WEBROOT "./"
|
||||
#define DEFAULT_SERIALPORT "/dev/ttyUSB0"
|
||||
|
|
@ -18,7 +19,6 @@
|
|||
#define DEFAULT_MQTT_SERVER NULL
|
||||
#define DEFAULT_MQTT_USER NULL
|
||||
#define DEFAULT_MQTT_PASSWD NULL
|
||||
// Set this high, as people are confused about SWG bouncing to zero on some panels, just stop the questions
|
||||
#define DEFAILT_SWG_ZERO_IGNORE_COUNT 20
|
||||
|
||||
#define MQTT_ID_LEN 18 // 20 seems to kill mosquitto 1.6
|
||||
|
|
@ -31,6 +31,8 @@ struct aqconfig
|
|||
char *socket_port;
|
||||
char *web_directory;
|
||||
unsigned char device_id;
|
||||
unsigned char onetouch_device_id;
|
||||
bool extended_device_id_programming;
|
||||
bool deamonize;
|
||||
char *log_file;
|
||||
char *mqtt_dz_sub_topic;
|
||||
|
|
@ -53,6 +55,7 @@ struct aqconfig
|
|||
int light_programming_button_spa;
|
||||
bool override_freeze_protect;
|
||||
bool pda_mode;
|
||||
bool onetouch_mode;
|
||||
bool pda_sleep_mode;
|
||||
bool convert_mqtt_temp;
|
||||
bool convert_dz_temp;
|
||||
|
|
@ -75,13 +78,31 @@ struct aqconfig
|
|||
//char *mqtt_pub_tp_ptr = mqtt_pub_topic[];
|
||||
};
|
||||
|
||||
#ifndef CONFIG_C
|
||||
extern struct aqconfig _aqconfig_;
|
||||
#else
|
||||
struct aqconfig _aqconfig_;
|
||||
#endif
|
||||
/*
|
||||
#ifndef CONFIG_C
|
||||
#ifdef AQUALINKD_C
|
||||
extern struct aqconfig _aqconfig_;
|
||||
#else
|
||||
extern const struct aqconfig _aqconfig_;
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
void init_parameters (struct aqconfig * parms);
|
||||
//bool parse_config (struct aqconfig * parms, char *cfgfile);
|
||||
//void readCfg (struct aqconfig *config_parameters, char *cfgFile);
|
||||
void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqualink_data, char *cfgFile);
|
||||
bool writeCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqdata);
|
||||
bool setConfigValue(struct aqconfig *config_parameters, struct aqualinkdata *aqdata, char *param, char *value);
|
||||
//void readCfg (struct aqconfig *config_parameters, struct aqualinkdata *aqualink_data, char *cfgFile);
|
||||
void read_config(struct aqualinkdata *aqdata, char *cfgFile);
|
||||
void init_config();
|
||||
|
||||
bool writeCfg (struct aqualinkdata *aqdata);
|
||||
bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value);
|
||||
|
||||
char *cleanalloc(char*str);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
/*
|
||||
Nothing seems to change these in simulator, need real pump to test
|
||||
0x10|0x02|0x7a|0x44|0x00|0x58|0x1b|0x43|0x10|0x03|
|
||||
|
||||
0x10|0x02|0x7a|0x44|0x00|0x58|0x1b|0x43|0x10|0x03|
|
||||
|
||||
0x10|0x02|0x7a|0x44|0x00|0x58|0x1b|0x43|0x10|0x03|
|
||||
0x10|0x02|0x7a|0x41|0xcd|0x10|0x03|
|
||||
|
||||
0x10|0x02|0x7a|0x44|0x00|0x58|0x1b|0x43|0x10|0x03|
|
||||
0x10|0x02|0x7a|0x41|0xcd|0x10|0x03|
|
||||
|
||||
0x10|0x02|0x7a|0x44|0x00|0x58|0x1b|0x43|0x10|0x03|
|
||||
0x10|0x02|0x7a|0x41|0xcd|0x10|0x03|
|
||||
*/
|
||||
|
|
@ -171,12 +171,15 @@ char *get_aux_information(aqkey *button, struct aqualinkdata *aqdata, char *buff
|
|||
int length = 0;
|
||||
buffer[0] = '\0';
|
||||
|
||||
for (i=0; i < MAX_PUMPS; i++) {
|
||||
for (i=0; i < aqdata->num_pumps; i++) {
|
||||
if (button == aqdata->pumps[i].button) {
|
||||
if (aqdata->pumps[i].rpm != TEMP_UNKNOWN || aqdata->pumps[i].gph != TEMP_UNKNOWN || aqdata->pumps[i].watts != TEMP_UNKNOWN) {
|
||||
length += sprintf(buffer, ",\"Pump_RPM\":\"%d\",\"Pump_GPH\":\"%d\",\"Pump_Watts\":\"%d\"", aqdata->pumps[i].rpm,aqdata->pumps[i].gph,aqdata->pumps[i].watts);
|
||||
|
||||
//if (aqdata->pumps[i].rpm != TEMP_UNKNOWN || aqdata->pumps[i].gpm != TEMP_UNKNOWN || aqdata->pumps[i].watts != TEMP_UNKNOWN) {
|
||||
length += sprintf(buffer, ",\"Pump_RPM\":\"%d\",\"Pump_GPM\":\"%d\",\"Pump_Watts\":\"%d\",\"Pump_Type\":\"%s\"",
|
||||
aqdata->pumps[i].rpm,aqdata->pumps[i].gpm,aqdata->pumps[i].watts,
|
||||
(aqdata->pumps[i].pumpType==VFPUMP?"vfPump":(aqdata->pumps[i].pumpType==VSPUMP?"vsPump":"ePump")));
|
||||
break;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,21 +234,38 @@ int build_device_JSON(struct aqualinkdata *aqdata, int programable_switch1, int
|
|||
LED2int(aqdata->aqbuttons[i].led->state));
|
||||
} else if ( (programable_switch1 > 0 && programable_switch1 == i) ||
|
||||
(programable_switch2 > 0 && programable_switch2 == i)) {
|
||||
/*
|
||||
length += sprintf(buffer+length, "{\"type\": \"switch_program\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"status\": \"%s\", \"int_status\": \"%d\" %s},",
|
||||
aqdata->aqbuttons[i].name,
|
||||
aqdata->aqbuttons[i].label,
|
||||
aqdata->aqbuttons[i].led->state==ON?JSON_ON:JSON_OFF,
|
||||
LED2text(aqdata->aqbuttons[i].led->state),
|
||||
LED2int(aqdata->aqbuttons[i].led->state),
|
||||
get_aux_information(&aqdata->aqbuttons[i], aqdata, aux_info));
|
||||
get_aux_information(&aqdata->aqbuttons[i], aqdata, aux_info));*/
|
||||
length += sprintf(buffer+length, "{\"type\": \"switch\", \"type_ext\": \"switch_program\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"status\": \"%s\", \"int_status\": \"%d\"},",
|
||||
aqdata->aqbuttons[i].name,
|
||||
aqdata->aqbuttons[i].label,
|
||||
aqdata->aqbuttons[i].led->state==ON?JSON_ON:JSON_OFF,
|
||||
LED2text(aqdata->aqbuttons[i].led->state),
|
||||
LED2int(aqdata->aqbuttons[i].led->state));
|
||||
} else {
|
||||
length += sprintf(buffer+length, "{\"type\": \"switch\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"status\": \"%s\", \"int_status\": \"%d\" %s},",
|
||||
if ( get_aux_information(&aqdata->aqbuttons[i], aqdata, aux_info)[0] == '\0' ) {
|
||||
length += sprintf(buffer+length, "{\"type\": \"switch\", \"type_ext\": \"switch\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"status\": \"%s\", \"int_status\": \"%d\"},",
|
||||
aqdata->aqbuttons[i].name,
|
||||
aqdata->aqbuttons[i].label,
|
||||
aqdata->aqbuttons[i].led->state==ON?JSON_ON:JSON_OFF,
|
||||
LED2text(aqdata->aqbuttons[i].led->state),
|
||||
LED2int(aqdata->aqbuttons[i].led->state));
|
||||
} else {
|
||||
length += sprintf(buffer+length, "{\"type\": \"switch\", \"type_ext\": \"switch_vsp\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"status\": \"%s\", \"int_status\": \"%d\" %s},",
|
||||
aqdata->aqbuttons[i].name,
|
||||
aqdata->aqbuttons[i].label,
|
||||
aqdata->aqbuttons[i].led->state==ON?JSON_ON:JSON_OFF,
|
||||
LED2text(aqdata->aqbuttons[i].led->state),
|
||||
LED2int(aqdata->aqbuttons[i].led->state),
|
||||
get_aux_information(&aqdata->aqbuttons[i], aqdata, aux_info));
|
||||
aux_info);
|
||||
//get_aux_information(&aqdata->aqbuttons[i], aqdata, aux_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -455,10 +475,12 @@ int build_aqualink_status_JSON(struct aqualinkdata *aqdata, char* buffer, int si
|
|||
//length += sprintf(buffer+length, "}, \"extra\":{" );
|
||||
length += sprintf(buffer+length, "},");
|
||||
|
||||
for (i=0; i < MAX_PUMPS; i++) {
|
||||
if (aqdata->pumps[i].rpm != TEMP_UNKNOWN || aqdata->pumps[i].gph != TEMP_UNKNOWN || aqdata->pumps[i].watts != TEMP_UNKNOWN) {
|
||||
length += sprintf(buffer+length, "\"Pump_%d\":{\"name\":\"%s\",\"id\":\"%s\",\"RPM\":\"%d\",\"GPH\":\"%d\",\"Watts\":\"%d\"},",
|
||||
i+1,aqdata->pumps[i].button->label,aqdata->pumps[i].button->name,aqdata->pumps[i].rpm,aqdata->pumps[i].gph,aqdata->pumps[i].watts);
|
||||
// NSF Check below needs to be for VSP Pump (any state), not just known state
|
||||
for (i=0; i < aqdata->num_pumps; i++) {
|
||||
if (aqdata->pumps[i].pumpType != PT_UNKNOWN && (aqdata->pumps[i].rpm != TEMP_UNKNOWN || aqdata->pumps[i].gpm != TEMP_UNKNOWN || aqdata->pumps[i].watts != TEMP_UNKNOWN)) {
|
||||
length += sprintf(buffer+length, "\"Pump_%d\":{\"name\":\"%s\",\"id\":\"%s\",\"RPM\":\"%d\",\"GPM\":\"%d\",\"Watts\":\"%d\",\"Pump_Type\":\"%s\"},",
|
||||
i+1,aqdata->pumps[i].button->label,aqdata->pumps[i].button->name,aqdata->pumps[i].rpm,aqdata->pumps[i].gpm,aqdata->pumps[i].watts,
|
||||
(aqdata->pumps[i].pumpType==VFPUMP?"vfPump":(aqdata->pumps[i].pumpType==VSPUMP?"vsPump":"ePump")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
//FUNCTION PROTOTYPES
|
||||
|
||||
#define JSON_LABEL_SIZE 300
|
||||
#define JSON_STATUS_SIZE 800
|
||||
#define JSON_STATUS_SIZE 1024
|
||||
#define JSON_MQTT_MSG_SIZE 100
|
||||
|
||||
#define JSON_ON "on"
|
||||
|
|
|
|||
280
net_services.c
280
net_services.c
|
|
@ -37,7 +37,7 @@
|
|||
#include "aquapure.h"
|
||||
|
||||
|
||||
static struct aqconfig *_aqualink_config;
|
||||
//static struct aqconfig *_aqconfig_;
|
||||
static struct aqualinkdata *_aqualink_data;
|
||||
static char *_web_root;
|
||||
|
||||
|
|
@ -70,7 +70,13 @@ static void signal_handler(int sig_num) {
|
|||
|
||||
|
||||
static int is_websocket(const struct mg_connection *nc) {
|
||||
return nc->flags & MG_F_IS_WEBSOCKET;
|
||||
return nc->flags & MG_F_IS_WEBSOCKET && !(nc->flags & MG_F_USER_2);
|
||||
}
|
||||
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;
|
||||
|
|
@ -153,7 +159,7 @@ void send_domoticz_mqtt_state_msg(struct mg_connection *nc, int idx, int value)
|
|||
|
||||
char mqtt_msg[JSON_MQTT_MSG_SIZE];
|
||||
build_mqtt_status_JSON(mqtt_msg ,JSON_MQTT_MSG_SIZE, idx, value, TEMP_UNKNOWN);
|
||||
send_mqtt(nc, _aqualink_config->mqtt_dz_pub_topic, mqtt_msg);
|
||||
send_mqtt(nc, _aqconfig_.mqtt_dz_pub_topic, mqtt_msg);
|
||||
}
|
||||
|
||||
void send_domoticz_mqtt_temp_msg(struct mg_connection *nc, int idx, int value)
|
||||
|
|
@ -162,8 +168,8 @@ void send_domoticz_mqtt_temp_msg(struct mg_connection *nc, int idx, int value)
|
|||
return;
|
||||
|
||||
char mqtt_msg[JSON_MQTT_MSG_SIZE];
|
||||
build_mqtt_status_JSON(mqtt_msg ,JSON_MQTT_MSG_SIZE, idx, 0, (_aqualink_data->temp_units==FAHRENHEIT && _aqualink_config->convert_dz_temp)?roundf(degFtoC(value)):value);
|
||||
send_mqtt(nc, _aqualink_config->mqtt_dz_pub_topic, mqtt_msg);
|
||||
build_mqtt_status_JSON(mqtt_msg ,JSON_MQTT_MSG_SIZE, idx, 0, (_aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_dz_temp)?roundf(degFtoC(value)):value);
|
||||
send_mqtt(nc, _aqconfig_.mqtt_dz_pub_topic, mqtt_msg);
|
||||
}
|
||||
void send_domoticz_mqtt_numeric_msg(struct mg_connection *nc, int idx, int value)
|
||||
{
|
||||
|
|
@ -172,7 +178,7 @@ void send_domoticz_mqtt_numeric_msg(struct mg_connection *nc, int idx, int value
|
|||
|
||||
char mqtt_msg[JSON_MQTT_MSG_SIZE];
|
||||
build_mqtt_status_JSON(mqtt_msg ,JSON_MQTT_MSG_SIZE, idx, 0, value);
|
||||
send_mqtt(nc, _aqualink_config->mqtt_dz_pub_topic, mqtt_msg);
|
||||
send_mqtt(nc, _aqconfig_.mqtt_dz_pub_topic, mqtt_msg);
|
||||
}
|
||||
void send_domoticz_mqtt_status_message(struct mg_connection *nc, int idx, int value, char *svalue) {
|
||||
if (idx <= 0)
|
||||
|
|
@ -181,17 +187,17 @@ void send_domoticz_mqtt_status_message(struct mg_connection *nc, int idx, int va
|
|||
char mqtt_msg[JSON_MQTT_MSG_SIZE];
|
||||
build_mqtt_status_message_JSON(mqtt_msg, JSON_MQTT_MSG_SIZE, idx, value, svalue);
|
||||
|
||||
send_mqtt(nc, _aqualink_config->mqtt_dz_pub_topic, mqtt_msg);
|
||||
send_mqtt(nc, _aqconfig_.mqtt_dz_pub_topic, mqtt_msg);
|
||||
}
|
||||
|
||||
void send_mqtt_state_msg(struct mg_connection *nc, char *dev_name, aqledstate state)
|
||||
{
|
||||
static char mqtt_pub_topic[250];
|
||||
|
||||
sprintf(mqtt_pub_topic, "%s/%s/delay",_aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s/delay",_aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, (state==FLASH?MQTT_ON:MQTT_OFF));
|
||||
|
||||
sprintf(mqtt_pub_topic, "%s/%s",_aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s",_aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, (state==OFF?MQTT_OFF:MQTT_ON));
|
||||
}
|
||||
|
||||
|
|
@ -203,8 +209,8 @@ void send_mqtt_aux_msg(struct mg_connection *nc, char *dev_name, char *dev_topic
|
|||
|
||||
sprintf(msg, "%d", value);
|
||||
|
||||
//sprintf(mqtt_pub_topic, "%s/%s%d%s",_aqualink_config->mqtt_aq_topic, root_topic, dev_index, dev_topic);
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqualink_config->mqtt_aq_topic, dev_name, dev_topic);
|
||||
//sprintf(mqtt_pub_topic, "%s/%s%d%s",_aqconfig_.mqtt_aq_topic, root_topic, dev_index, dev_topic);
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqconfig_.mqtt_aq_topic, dev_name, dev_topic);
|
||||
send_mqtt(nc, mqtt_pub_topic, msg);
|
||||
}
|
||||
|
||||
|
|
@ -213,15 +219,15 @@ void send_mqtt_heater_state_msg(struct mg_connection *nc, char *dev_name, aqleds
|
|||
|
||||
static char mqtt_pub_topic[250];
|
||||
|
||||
sprintf(mqtt_pub_topic, "%s/%s",_aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s",_aqconfig_.mqtt_aq_topic, dev_name);
|
||||
|
||||
if (state == ENABLE) {
|
||||
send_mqtt(nc, mqtt_pub_topic, MQTT_OFF);
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqualink_config->mqtt_aq_topic, dev_name, ENABELED_SUBT);
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqconfig_.mqtt_aq_topic, dev_name, ENABELED_SUBT);
|
||||
send_mqtt(nc, mqtt_pub_topic, MQTT_ON);
|
||||
} else {
|
||||
send_mqtt(nc, mqtt_pub_topic, (state==OFF?MQTT_OFF:MQTT_ON));
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqualink_config->mqtt_aq_topic, dev_name, ENABELED_SUBT);
|
||||
sprintf(mqtt_pub_topic, "%s/%s%s",_aqconfig_.mqtt_aq_topic, dev_name, ENABELED_SUBT);
|
||||
send_mqtt(nc, mqtt_pub_topic, (state==OFF?MQTT_OFF:MQTT_ON));
|
||||
}
|
||||
}
|
||||
|
|
@ -231,8 +237,8 @@ void send_mqtt_temp_msg(struct mg_connection *nc, char *dev_name, long value)
|
|||
{
|
||||
static char mqtt_pub_topic[250];
|
||||
static char degC[10];
|
||||
sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqualink_config->convert_mqtt_temp)?degFtoC(value):value );
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_mqtt_temp)?degFtoC(value):value );
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, degC);
|
||||
}
|
||||
/*
|
||||
|
|
@ -241,9 +247,9 @@ void send_mqtt_temp_msg_new(struct mg_connection *nc, char *dev_name, long value
|
|||
static char mqtt_pub_topic[250];
|
||||
static char degC[5];
|
||||
// NSF remove false below once we have finished.
|
||||
sprintf(degC, "%.2f", (false && _aqualink_data->temp_units==FAHRENHEIT && _aqualink_config->convert_mqtt_temp)?degFtoC(value):value );
|
||||
sprintf(degC, "%.2f", (false && _aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_mqtt_temp)?degFtoC(value):value );
|
||||
//sprintf(degC, "%d", value );
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, degC);
|
||||
}
|
||||
*/
|
||||
|
|
@ -252,8 +258,8 @@ void send_mqtt_setpoint_msg(struct mg_connection *nc, char *dev_name, long value
|
|||
static char mqtt_pub_topic[250];
|
||||
static char degC[10];
|
||||
|
||||
sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqualink_config->convert_mqtt_temp)?degFtoC(value):value );
|
||||
sprintf(mqtt_pub_topic, "%s/%s/setpoint", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(degC, "%.2f", (_aqualink_data->temp_units==FAHRENHEIT && _aqconfig_.convert_mqtt_temp)?degFtoC(value):value );
|
||||
sprintf(mqtt_pub_topic, "%s/%s/setpoint", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, degC);
|
||||
}
|
||||
void send_mqtt_numeric_msg(struct mg_connection *nc, char *dev_name, int value)
|
||||
|
|
@ -262,7 +268,7 @@ void send_mqtt_numeric_msg(struct mg_connection *nc, char *dev_name, int value)
|
|||
static char msg[10];
|
||||
|
||||
sprintf(msg, "%d", value);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, msg);
|
||||
}
|
||||
void send_mqtt_float_msg(struct mg_connection *nc, char *dev_name, float value) {
|
||||
|
|
@ -270,7 +276,7 @@ void send_mqtt_float_msg(struct mg_connection *nc, char *dev_name, float value)
|
|||
static char msg[10];
|
||||
|
||||
sprintf(msg, "%.2f", value);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, msg);
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +287,7 @@ void send_mqtt_int_msg(struct mg_connection *nc, char *dev_name, int value) {
|
|||
static char msg[10];
|
||||
|
||||
sprintf(msg, "%d", value);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, msg);
|
||||
*/
|
||||
}
|
||||
|
|
@ -289,7 +295,7 @@ void send_mqtt_int_msg(struct mg_connection *nc, char *dev_name, int value) {
|
|||
void send_mqtt_string_msg(struct mg_connection *nc, char *dev_name, char *msg) {
|
||||
static char mqtt_pub_topic[250];
|
||||
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqualink_config->mqtt_aq_topic, dev_name);
|
||||
sprintf(mqtt_pub_topic, "%s/%s", _aqconfig_.mqtt_aq_topic, dev_name);
|
||||
send_mqtt(nc, mqtt_pub_topic, msg);
|
||||
}
|
||||
|
||||
|
|
@ -321,41 +327,41 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
_last_mqtt_aqualinkdata.air_temp = _aqualink_data->air_temp;
|
||||
send_mqtt_temp_msg(nc, AIR_TEMP_TOPIC, _aqualink_data->air_temp);
|
||||
//send_mqtt_temp_msg_new(nc, AIR_TEMPERATURE_TOPIC, _aqualink_data->air_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_air_temp, _aqualink_data->air_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_air_temp, _aqualink_data->air_temp);
|
||||
}
|
||||
/*
|
||||
if (_aqualink_data->pool_temp != TEMP_UNKNOWN && _aqualink_data->pool_temp != _last_mqtt_aqualinkdata.pool_temp) {
|
||||
_last_mqtt_aqualinkdata.pool_temp = _aqualink_data->pool_temp;
|
||||
send_mqtt_temp_msg(nc, POOL_TEMP_TOPIC, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_pool_water_temp, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_pool_water_temp, _aqualink_data->pool_temp);
|
||||
// IF spa is off, report pool water temp to Domoticz.
|
||||
if (_aqualink_data->spa_temp == TEMP_UNKNOWN)
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_spa_water_temp, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_spa_water_temp, _aqualink_data->pool_temp);
|
||||
}
|
||||
*/
|
||||
|
||||
if (_aqualink_data->pool_temp != _last_mqtt_aqualinkdata.pool_temp) {
|
||||
if (_aqualink_data->pool_temp == TEMP_UNKNOWN && _aqualink_config->report_zero_pool_temp) {
|
||||
if (_aqualink_data->pool_temp == TEMP_UNKNOWN && _aqconfig_.report_zero_pool_temp) {
|
||||
_last_mqtt_aqualinkdata.pool_temp = TEMP_UNKNOWN;
|
||||
send_mqtt_temp_msg(nc, POOL_TEMP_TOPIC, (_aqualink_config->convert_mqtt_temp?-18:0));
|
||||
send_mqtt_temp_msg(nc, POOL_TEMP_TOPIC, (_aqconfig_.convert_mqtt_temp?-18:0));
|
||||
} else if (_aqualink_data->pool_temp != TEMP_UNKNOWN) {
|
||||
_last_mqtt_aqualinkdata.pool_temp = _aqualink_data->pool_temp;
|
||||
send_mqtt_temp_msg(nc, POOL_TEMP_TOPIC, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_pool_water_temp, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_pool_water_temp, _aqualink_data->pool_temp);
|
||||
// IF spa is off, report pool water temp to Domoticz.
|
||||
if (_aqualink_data->spa_temp == TEMP_UNKNOWN)
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_spa_water_temp, _aqualink_data->pool_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_spa_water_temp, _aqualink_data->pool_temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (_aqualink_data->spa_temp != _last_mqtt_aqualinkdata.spa_temp) {
|
||||
if (_aqualink_data->spa_temp == TEMP_UNKNOWN && _aqualink_config->report_zero_spa_temp) {
|
||||
if (_aqualink_data->spa_temp == TEMP_UNKNOWN && _aqconfig_.report_zero_spa_temp) {
|
||||
_last_mqtt_aqualinkdata.spa_temp = TEMP_UNKNOWN;
|
||||
send_mqtt_temp_msg(nc, SPA_TEMP_TOPIC, (_aqualink_config->convert_mqtt_temp?-18:0));
|
||||
send_mqtt_temp_msg(nc, SPA_TEMP_TOPIC, (_aqconfig_.convert_mqtt_temp?-18:0));
|
||||
} else if (_aqualink_data->spa_temp != TEMP_UNKNOWN) {
|
||||
_last_mqtt_aqualinkdata.spa_temp = _aqualink_data->spa_temp;
|
||||
send_mqtt_temp_msg(nc, SPA_TEMP_TOPIC, _aqualink_data->spa_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_spa_water_temp, _aqualink_data->spa_temp);
|
||||
send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_spa_water_temp, _aqualink_data->spa_temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +369,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
_last_mqtt_aqualinkdata.pool_htr_set_point = _aqualink_data->pool_htr_set_point;
|
||||
send_mqtt_setpoint_msg(nc, BTN_POOL_HTR, _aqualink_data->pool_htr_set_point);
|
||||
// removed until domoticz has a better virtuel thermostat
|
||||
//send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_pool_thermostat, _aqualink_data->pool_htr_set_point);
|
||||
//send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_pool_thermostat, _aqualink_data->pool_htr_set_point);
|
||||
}
|
||||
|
||||
if (_aqualink_data->spa_htr_set_point != TEMP_UNKNOWN && _aqualink_data->spa_htr_set_point != _last_mqtt_aqualinkdata.spa_htr_set_point) {
|
||||
|
|
@ -384,7 +390,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
send_mqtt_string_msg(nc, FREEZE_PROTECT_ENABELED, MQTT_ON);
|
||||
/*
|
||||
send_mqtt_string_msg(nc, FREEZE_PROTECT_ENABELED, MQTT_ON);
|
||||
//send_domoticz_mqtt_temp_msg(nc, _aqualink_config->dzidx_rfz_protect, _aqualink_data->frz_protect_set_point);
|
||||
//send_domoticz_mqtt_temp_msg(nc, _aqconfig_.dzidx_rfz_protect, _aqualink_data->frz_protect_set_point);
|
||||
} else if (_aqualink_data->frz_protect_set_point != _last_mqtt_aqualinkdata.frz_protect_set_point) {
|
||||
_last_mqtt_aqualinkdata.frz_protect_set_point = _aqualink_data->frz_protect_set_point;
|
||||
send_mqtt_string_msg(nc, FREEZE_PROTECT_ENABELED, MQTT_OFF);*/
|
||||
|
|
@ -411,7 +417,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
if (!_aqualink_data->simulate_panel)
|
||||
sprintf(_aqualink_data->last_display_message, message);
|
||||
|
||||
send_domoticz_mqtt_status_message(nc, _aqualink_config->dzidx_swg_status, dzalert, &message[9]);
|
||||
send_domoticz_mqtt_status_message(nc, _aqconfig_.dzidx_swg_status, dzalert, &message[9]);
|
||||
send_mqtt_int_msg(nc, SWG_TOPIC, status);
|
||||
|
||||
if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF)
|
||||
|
|
@ -436,13 +442,13 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
send_mqtt_numeric_msg(nc, SWG_PERCENT_TOPIC, _aqualink_data->swg_percent);
|
||||
send_mqtt_float_msg(nc, SWG_PERCENT_F_TOPIC, roundf(degFtoC(_aqualink_data->swg_percent)));
|
||||
send_mqtt_float_msg(nc, SWG_SETPOINT_TOPIC, roundf(degFtoC(_aqualink_data->swg_percent)));
|
||||
send_domoticz_mqtt_numeric_msg(nc, _aqualink_config->dzidx_swg_percent, _aqualink_data->swg_percent);
|
||||
send_domoticz_mqtt_numeric_msg(nc, _aqconfig_.dzidx_swg_percent, _aqualink_data->swg_percent);
|
||||
}
|
||||
if (_aqualink_data->swg_ppm != TEMP_UNKNOWN && ( force_update || _aqualink_data->swg_ppm != _last_mqtt_aqualinkdata.swg_ppm)) {
|
||||
_last_mqtt_aqualinkdata.swg_ppm = _aqualink_data->swg_ppm;
|
||||
send_mqtt_numeric_msg(nc, SWG_PPM_TOPIC, _aqualink_data->swg_ppm);
|
||||
send_mqtt_float_msg(nc, SWG_PPM_F_TOPIC, roundf(degFtoC(_aqualink_data->swg_ppm)));
|
||||
send_domoticz_mqtt_numeric_msg(nc, _aqualink_config->dzidx_swg_ppm, _aqualink_data->swg_ppm);
|
||||
send_domoticz_mqtt_numeric_msg(nc, _aqconfig_.dzidx_swg_ppm, _aqualink_data->swg_ppm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -453,7 +459,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
// Loop over LED's and send any changes.
|
||||
for (i=0; i < TOTAL_BUTTONS; i++) {
|
||||
/*
|
||||
if ( _aqualink_data->aqbuttons[i].led->state == FLASH && _aqualink_config->flash_mqtt_buttons == true ) {
|
||||
if ( _aqualink_data->aqbuttons[i].led->state == FLASH && _aqconfig_.flash_mqtt_buttons == true ) {
|
||||
// Simply send on or off depending on if current second is odd or even.
|
||||
// will send too many off and on messages as we get hit multiple times a second, but most effecient way to handle this
|
||||
// considering flash is not very often and not for long.
|
||||
|
|
@ -475,7 +481,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
}
|
||||
|
||||
// Loop over Pumps
|
||||
for (i=0; i < MAX_PUMPS; i++) {
|
||||
for (i=0; i < _aqualink_data->num_pumps; i++) {
|
||||
//_aqualink_data->pumps[i].rpm = TEMP_UNKNOWN;
|
||||
//_aqualink_data->pumps[i].gph = TEMP_UNKNOWN;
|
||||
//_aqualink_data->pumps[i].watts = TEMP_UNKNOWN;
|
||||
|
|
@ -485,10 +491,10 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_RPM_TOPIC, _aqualink_data->pumps[i].rpm);
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_RPM_TOPIC, _aqualink_data->pumps[i].rpm);
|
||||
}
|
||||
if (_aqualink_data->pumps[i].gph != TEMP_UNKNOWN && _aqualink_data->pumps[i].gph != _last_mqtt_aqualinkdata.pumps[i].gph) {
|
||||
_last_mqtt_aqualinkdata.pumps[i].gph = _aqualink_data->pumps[i].gph;
|
||||
if (_aqualink_data->pumps[i].gpm != TEMP_UNKNOWN && _aqualink_data->pumps[i].gpm != _last_mqtt_aqualinkdata.pumps[i].gpm) {
|
||||
_last_mqtt_aqualinkdata.pumps[i].gpm = _aqualink_data->pumps[i].gpm;
|
||||
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_GPH_TOPIC, _aqualink_data->pumps[i].gph);
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_GPH_TOPIC, _aqualink_data->pumps[i].gph);
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_GPM_TOPIC, _aqualink_data->pumps[i].gpm);
|
||||
}
|
||||
if (_aqualink_data->pumps[i].watts != TEMP_UNKNOWN && _aqualink_data->pumps[i].watts != _last_mqtt_aqualinkdata.pumps[i].watts) {
|
||||
_last_mqtt_aqualinkdata.pumps[i].watts = _aqualink_data->pumps[i].watts;
|
||||
|
|
@ -507,7 +513,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
//if (_aqualink_data->aqbuttons[i].dz_idx != DZ_NULL_IDX) {
|
||||
if (_aqualink_data->aqbuttons[i].code == KEY_POOL_HTR || _aqualink_data->aqbuttons[i].code == KEY_SPA_HTR) {
|
||||
send_mqtt_heater_state_msg(nc, _aqualink_data->aqbuttons[i].name, _aqualink_data->aqbuttons[i].led->state);
|
||||
} else if (_aqualink_data->aqbuttons[i].led->state == FLASH && _aqualink_config->flash_mqtt_buttons == true) {
|
||||
} else if (_aqualink_data->aqbuttons[i].led->state == FLASH && _aqconfig_.flash_mqtt_buttons == true) {
|
||||
// This messed up the origional LED state, which means we send the flash to WEB UI as well.
|
||||
time_t now;
|
||||
now = time(NULL);
|
||||
|
|
@ -553,12 +559,12 @@ int getTempforMeteohub(char *buffer)
|
|||
|
||||
void set_light_mode(char *value, int button)
|
||||
{
|
||||
if (_aqualink_config->pda_mode == true) {
|
||||
if (_aqconfig_.pda_mode == true) {
|
||||
logMessage(LOG_ERR, "Light mode control not supported in PDA mode\n");
|
||||
return;
|
||||
}
|
||||
if (_aqualink_config->light_programming_button_pool != button &&
|
||||
_aqualink_config->light_programming_button_spa != button) {
|
||||
if (_aqconfig_.light_programming_button_pool != button &&
|
||||
_aqconfig_.light_programming_button_spa != button) {
|
||||
logMessage(LOG_ERR, "Light mode control not configured for button %d\n",button);
|
||||
return;
|
||||
}
|
||||
|
|
@ -567,9 +573,9 @@ void set_light_mode(char *value, int button)
|
|||
// 5 below is light index, need to look this up so it's not hard coded.
|
||||
sprintf(buf, "%-5s%-5d%-5d%-5d%.2f",value,
|
||||
button,
|
||||
_aqualink_config->light_programming_initial_on,
|
||||
_aqualink_config->light_programming_initial_off,
|
||||
_aqualink_config->light_programming_mode );
|
||||
_aqconfig_.light_programming_initial_on,
|
||||
_aqconfig_.light_programming_initial_off,
|
||||
_aqconfig_.light_programming_mode );
|
||||
//logMessage(LOG_NOTICE, "WEB: requset light mode %s\n", buf);
|
||||
aq_programmer(AQ_SET_COLORMODE, buf, _aqualink_data);
|
||||
}
|
||||
|
|
@ -611,24 +617,20 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
char value[20];
|
||||
mg_get_http_var(&http_msg->query_string, "value", value, sizeof(value));
|
||||
//aq_programmer(AQ_SET_COLORMODE, value, _aqualink_data);
|
||||
set_light_mode(value, _aqualink_config->light_programming_button_pool);
|
||||
set_light_mode(value, _aqconfig_.light_programming_button_pool);
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else if (strcmp(command, "spalightmode") == 0) {
|
||||
char value[20];
|
||||
mg_get_http_var(&http_msg->query_string, "value", value, sizeof(value));
|
||||
//aq_programmer(AQ_SET_COLORMODE, value, _aqualink_data);
|
||||
set_light_mode(value, _aqualink_config->light_programming_button_spa);
|
||||
set_light_mode(value, _aqconfig_.light_programming_button_spa);
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else if (strcmp(command, "diag") == 0) {
|
||||
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, _aqualink_data);
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else if (strcmp(command, "settime") == 0) {
|
||||
aq_programmer(AQ_SET_TIME, NULL, _aqualink_data);
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else if (strcmp(command, "swg_percent") == 0) {
|
||||
char value[20];
|
||||
mg_get_http_var(&http_msg->query_string, "value", value, sizeof(value));
|
||||
|
|
@ -659,12 +661,12 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else if (strcmp(command, "devices") == 0) {
|
||||
char message[JSON_LABEL_SIZE*10];
|
||||
int size = build_device_JSON(_aqualink_data, _aqualink_config->light_programming_button_pool, _aqualink_config->light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
|
||||
int size = build_device_JSON(_aqualink_data, _aqconfig_.light_programming_button_pool, _aqconfig_.light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
|
||||
mg_send_head(nc, 200, size, "Content-Type: application/json");
|
||||
mg_send(nc, message, size);
|
||||
} else if (strcmp(command, "homebridge") == 0) {
|
||||
char message[JSON_LABEL_SIZE*10];
|
||||
int size = build_device_JSON(_aqualink_data, _aqualink_config->light_programming_button_pool, _aqualink_config->light_programming_button_spa, message, JSON_LABEL_SIZE*10, true);
|
||||
int size = build_device_JSON(_aqualink_data, _aqconfig_.light_programming_button_pool, _aqconfig_.light_programming_button_spa, message, JSON_LABEL_SIZE*10, true);
|
||||
mg_send_head(nc, 200, size, "Content-Type: application/json");
|
||||
mg_send(nc, message, size);
|
||||
} else if (strcmp(command, "setconfigprm") == 0) {
|
||||
|
|
@ -674,7 +676,7 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
mg_get_http_var(&http_msg->query_string, "param", param, sizeof(param));
|
||||
mg_get_http_var(&http_msg->query_string, "value", value, sizeof(value));
|
||||
|
||||
if (setConfigValue(_aqualink_config, _aqualink_data, param, value)) {
|
||||
if (setConfigValue(_aqualink_data, param, value)) {
|
||||
webrtn = GET_RTN_OK;
|
||||
logMessage(LOG_INFO, "Web: request to config %s to %s\n", param, value);
|
||||
} else {
|
||||
|
|
@ -684,7 +686,7 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
mg_send_head(nc, 200, strlen(webrtn), "Content-Type: text/plain");
|
||||
mg_send(nc, webrtn, strlen(webrtn));
|
||||
} else if (strcmp(command, "writeconfig") == 0) {
|
||||
if (writeCfg (_aqualink_config, _aqualink_data)) {
|
||||
if (writeCfg (_aqualink_data)) {
|
||||
mg_send_head(nc, 200, strlen(GET_RTN_OK), "Content-Type: text/plain");
|
||||
mg_send(nc, GET_RTN_OK, strlen(GET_RTN_OK));
|
||||
} else {
|
||||
|
|
@ -704,8 +706,12 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
stopInlineDebug();
|
||||
rtn = GET_RTN_OK;
|
||||
} else if (strcmp(value, "serialstart") == 0) {
|
||||
startInlineSerialDebug();
|
||||
logMessage(LOG_DEBUG, "WEB: Started inline debug mode\n");
|
||||
rtn = GET_RTN_OK;
|
||||
} else if (strcmp(value, "serialstop") == 0) {
|
||||
logMessage(LOG_DEBUG, "WEB: Stoped inline debug mode\n");
|
||||
stopInlineDebug();
|
||||
rtn = GET_RTN_OK;
|
||||
} else if (strcmp(value, "status") == 0) {
|
||||
snprintf(value,80,"{\"sLevel\":\"%s\", \"iLevel\":%d, \"logReady\":\"%s\"}\n",elevel2text(getLogLevel()),getLogLevel(),islogFileReady()?"true":"false" );
|
||||
|
|
@ -724,6 +730,28 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
}
|
||||
mg_send_head(nc, 200, strlen(rtn), "Content-Type: text/plain");
|
||||
mg_send(nc, rtn, strlen(rtn));
|
||||
} else if (strncmp(command, "Pump_", 5) == 0) {
|
||||
// Set Pump RPM
|
||||
bool found = false;
|
||||
int pumpIndex = atoi(command+5); // Check for 0
|
||||
char value[10];
|
||||
mg_get_http_var(&http_msg->query_string, "value", value, sizeof(value));
|
||||
int rpm = atoi(value);
|
||||
// Check for pumpIndex = 0 (BAD) and check RPM Value
|
||||
//printf("******** ADD CHECK FOR PUMP & RPM HERE ********\n");
|
||||
int pi;
|
||||
for (pi=0; pi < _aqualink_data->num_pumps; pi++) {
|
||||
if (_aqualink_data->pumps[pi].pumpIndex == pumpIndex) {
|
||||
logMessage(LOG_NOTICE, "WEB: request to change pump %d to %d\n",pumpIndex, round(rpm));
|
||||
_aqualink_data->unactioned.type = PUMP_RPM;
|
||||
_aqualink_data->unactioned.value = round(rpm);
|
||||
_aqualink_data->unactioned.id = pumpIndex;
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
logMessage(LOG_ERR, "WEB: Didn't find pump %d from command %s\n",pumpIndex,command);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < TOTAL_BUTTONS; i++) {
|
||||
|
|
@ -736,7 +764,7 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
// *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
logMessage(LOG_DEBUG, "WEB: Message request '%s' change state to '%s'\n", command, value);
|
||||
|
||||
if (_aqualink_config->pda_mode == true) {
|
||||
if (_aqconfig_.pda_mode == true) {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d",i, (strcmp(value, "on") == 0)?ON:OFF);
|
||||
//printf("******* '%s' ********\n",msg);
|
||||
|
|
@ -825,8 +853,12 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
//aq_programmer(AQ_SEND_CMD, (char *)&n, NULL);
|
||||
aq_send_cmd((unsigned char)n);
|
||||
//char message[JSON_LABEL_SIZE*10];
|
||||
//build_device_JSON(_aqualink_data, _aqualink_config->light_programming_button, message, JSON_LABEL_SIZE*10);
|
||||
//build_device_JSON(_aqualink_data, _aqconfig_.light_programming_button, message, JSON_LABEL_SIZE*10);
|
||||
//ws_send(nc, message);
|
||||
} else if (strcmp(request.first.key, "mode") == 0) {
|
||||
if (strcmp(request.first.value, "onetouchraw") == 0) {
|
||||
set_websocket_RSraw(nc);
|
||||
}
|
||||
} else if (strcmp(request.first.key, "command") == 0) {
|
||||
_aqualink_data->simulate_panel = false;
|
||||
if (strcmp(request.first.value, "GET_AUX_LABELS") == 0) {
|
||||
|
|
@ -835,7 +867,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
ws_send(nc, labels);
|
||||
} else if (strcmp(request.first.value, "GET_DEVICES") == 0) {
|
||||
char message[JSON_LABEL_SIZE*10];
|
||||
build_device_JSON(_aqualink_data, _aqualink_config->light_programming_button_pool, _aqualink_config->light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
|
||||
build_device_JSON(_aqualink_data, _aqconfig_.light_programming_button_pool, _aqconfig_.light_programming_button_spa, message, JSON_LABEL_SIZE*10, false);
|
||||
ws_send(nc, message);
|
||||
} else if ( strcmp(request.first.value, "simulator") == 0) {
|
||||
_aqualink_data->simulate_panel = true;
|
||||
|
|
@ -857,7 +889,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
if (strcmp(request.first.value, _aqualink_data->aqbuttons[i].name) == 0) {
|
||||
logMessage (LOG_INFO, "WS: button '%s' pressed\n",_aqualink_data->aqbuttons[i].name);
|
||||
// send_command( (unsigned char)_aqualink_data->aqbuttons[i].code);
|
||||
if (_aqualink_config->pda_mode == false) {
|
||||
if (_aqconfig_.pda_mode == false) {
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
aq_send_cmd(_aqualink_data->aqbuttons[i].code);
|
||||
} else {
|
||||
|
|
@ -889,7 +921,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
_aqualink_data->swg_percent = value; // Set the value as if it's already been set, just incase it's 0 as we won't get that message, or will update next time
|
||||
}
|
||||
} else if (strcmp(request.first.value, "POOL_LIGHT_MODE") == 0) {
|
||||
set_light_mode(request.second.value, _aqualink_config->light_programming_button_pool);
|
||||
set_light_mode(request.second.value, _aqconfig_.light_programming_button_pool);
|
||||
} else if (strcmp(request.first.value, "LIGHT_MODE") == 0) {
|
||||
int i;
|
||||
for (i = 0; i < TOTAL_BUTTONS; i++) {
|
||||
|
|
@ -900,7 +932,26 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
}
|
||||
//set_light_mode(request.second.value, 0);
|
||||
} else {
|
||||
logMessage(LOG_DEBUG, "WS: Unknown parameter %s\n", request.first.value);
|
||||
int i;
|
||||
bool found = false;
|
||||
for (i = 0; i < TOTAL_BUTTONS; i++) {
|
||||
if (strcmp(request.first.value, _aqualink_data->aqbuttons[i].name) == 0) {
|
||||
int pi;
|
||||
logMessage (LOG_INFO, "WS: button parameter request '%s' '%s'\n",_aqualink_data->aqbuttons[i].name, request.second.value);
|
||||
for (pi=0; pi < _aqualink_data->num_pumps; pi++) {
|
||||
if (_aqualink_data->pumps[pi].button == &_aqualink_data->aqbuttons[i]) {
|
||||
logMessage(LOG_NOTICE, "WS: request to change pump %d %s to %s\n",pi, _aqualink_data->aqbuttons[i].name, request.second.value);
|
||||
_aqualink_data->unactioned.type = PUMP_RPM;
|
||||
_aqualink_data->unactioned.value = atoi(request.second.value);
|
||||
_aqualink_data->unactioned.id = _aqualink_data->pumps[pi].pumpIndex;
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
logMessage(LOG_DEBUG, "WS: Unknown parameter %s\n", request.first.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -925,12 +976,12 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg)
|
|||
|
||||
//printf("Topic %.*s\n",msg->topic.len, msg->topic.p);
|
||||
// get the parts from the topic
|
||||
char *pt1 = (char *)&msg->topic.p[strlen(_aqualink_config->mqtt_aq_topic)+1];
|
||||
char *pt1 = (char *)&msg->topic.p[strlen(_aqconfig_.mqtt_aq_topic)+1];
|
||||
char *pt2 = NULL;
|
||||
char *pt3 = NULL;
|
||||
|
||||
//for (i=10; i < msg->topic.len; i++) {
|
||||
for (i=strlen(_aqualink_config->mqtt_aq_topic)+1; i < msg->topic.len; i++) {
|
||||
for (i=strlen(_aqconfig_.mqtt_aq_topic)+1; i < msg->topic.len; i++) {
|
||||
if ( msg->topic.p[i] == '/' ) {
|
||||
if (pt2 == NULL) {
|
||||
pt2 = (char *)&msg->topic.p[++i];
|
||||
|
|
@ -949,8 +1000,11 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg)
|
|||
//aqualinkd/Pool_Heater/set
|
||||
//aqualinkd/SWG/Percent_f/set
|
||||
|
||||
//aqualinkd/Filter_Pump/RPM/set // Should add this at some point
|
||||
//aqualinkd/Pump_1/RPM/set
|
||||
|
||||
if (pt3 != NULL && (strncmp(pt2, "setpoint", 8) == 0) && (strncmp(pt3, "set", 3) == 0)) {
|
||||
int val = _aqualink_data->unactioned.value = (_aqualink_data->temp_units != CELSIUS && _aqualink_config->convert_mqtt_temp) ? round(degCtoF(value)) : round(value);
|
||||
int val = _aqualink_data->unactioned.value = (_aqualink_data->temp_units != CELSIUS && _aqconfig_.convert_mqtt_temp) ? round(degCtoF(value)) : round(value);
|
||||
if (strncmp(pt1, BTN_POOL_HTR, strlen(BTN_POOL_HTR)) == 0) {
|
||||
_aqualink_data->unactioned.value = setpoint_check(POOL_HTR_SETOINT, val, _aqualink_data);
|
||||
_aqualink_data->unactioned.type = POOL_HTR_SETOINT;
|
||||
|
|
@ -984,6 +1038,28 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg)
|
|||
} else if ((pt3 != NULL && (strncmp(pt1, "SWG", 3) == 0) && (strncmp(pt2, "Boost", 5) == 0) && (strncmp(pt3, "set", 3) == 0))) {
|
||||
_aqualink_data->unactioned.value = round(value);
|
||||
_aqualink_data->unactioned.type = SWG_BOOST;
|
||||
} else if ((pt3 != NULL && (strncmp(pt1, "Pump_", 5) == 0) && ((strncmp(pt2, "RPM", 3) == 0) || (strncmp(pt2, "GPM", 3) == 0)) && (strncmp(pt3, "set", 3) == 0))) {
|
||||
// Set Pump RPM
|
||||
bool found = false;
|
||||
int pumpIndex = atoi(pt1+5); // Check for 0
|
||||
// Check for pumpIndex = 0 (BAD) and check RPM Value
|
||||
//printf("******** ADD CHECK FOR PUMP & RPM HERE ********\n");
|
||||
int pi;
|
||||
for (pi=0; pi < _aqualink_data->num_pumps; pi++) {
|
||||
if (_aqualink_data->pumps[pi].pumpIndex == pumpIndex) {
|
||||
//printf("******** Set pump %d RPM to %d ******\n",pumpIndex, round(value));
|
||||
//int val = RPM_check(_aqualink_data->pumps[pi].pumpType, val, _aqualink_data);
|
||||
//RPM_check( val)
|
||||
logMessage(LOG_NOTICE, "MQTT: request to change pump %d %s to %d\n",pumpIndex, (strncmp(pt2, "RPM", 3) == 0)?"RPM":"GPM", round(value));
|
||||
_aqualink_data->unactioned.type = PUMP_RPM;
|
||||
_aqualink_data->unactioned.value = round(value);
|
||||
_aqualink_data->unactioned.id = pumpIndex;
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
logMessage(LOG_ERR, "MQTT: Didn't find pump %d from message %.*s\n",pumpIndex,msg->topic.len, msg->topic.p);
|
||||
} else if (pt2 != NULL && (strncmp(pt2, "set", 3) == 0) && (strncmp(pt2, "setpoint", 8) != 0)) {
|
||||
// Must be a switch on / off
|
||||
for (i=0; i < TOTAL_BUTTONS; i++) {
|
||||
|
|
@ -1003,7 +1079,7 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg)
|
|||
} else {
|
||||
logMessage(LOG_INFO, "MQTT: received '%s' for '%s', turning '%s'\n", (value==0?"OFF":"ON"), _aqualink_data->aqbuttons[i].name,(value==0?"OFF":"ON"));
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
if (_aqualink_config->pda_mode == false) {
|
||||
if (_aqconfig_.pda_mode == false) {
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
aq_send_cmd(_aqualink_data->aqbuttons[i].code);
|
||||
} else {
|
||||
|
|
@ -1048,7 +1124,7 @@ void action_domoticz_mqtt_message(struct mg_connection *nc, struct mg_mqtt_messa
|
|||
} else {
|
||||
logMessage(LOG_INFO, "MQTT: DZ: received '%s' for '%s', turning '%s'\n", (nvalue==DZ_OFF?"OFF":"ON"), _aqualink_data->aqbuttons[i].name,(nvalue==DZ_OFF?"OFF":"ON"));
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
if (_aqualink_config->pda_mode == false) {
|
||||
if (_aqconfig_.pda_mode == false) {
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)&_aqualink_data->aqbuttons[i].code, _aqualink_data);
|
||||
aq_send_cmd(_aqualink_data->aqbuttons[i].code);
|
||||
} else {
|
||||
|
|
@ -1062,7 +1138,7 @@ void action_domoticz_mqtt_message(struct mg_connection *nc, struct mg_mqtt_messa
|
|||
}
|
||||
}
|
||||
/* removed until domoticz has a better virtual thermostat
|
||||
if (idx == _aqualink_config->dzidx_pool_thermostat) {
|
||||
if (idx == _aqconfig_.dzidx_pool_thermostat) {
|
||||
float degC = atof(svalue);
|
||||
int degF = (int)degCtoF(degC);
|
||||
if (degC > 0.0 && 1 < (degF - _aqualink_data->pool_htr_set_point)) {
|
||||
|
|
@ -1071,7 +1147,7 @@ void action_domoticz_mqtt_message(struct mg_connection *nc, struct mg_mqtt_messa
|
|||
} else {
|
||||
logMessage(LOG_INFO, "MQTT: DZ: received temp setting '%s' for 'pool heater setpoint' matched current setting (or was zero), ignoring!\n", svalue);
|
||||
}
|
||||
} else if (idx == _aqualink_config->dzidx_spa_thermostat) {
|
||||
} else if (idx == _aqconfig_.dzidx_spa_thermostat) {
|
||||
float degC = atof(svalue);
|
||||
int degF = (int)degCtoF(degC);
|
||||
if (degC > 0.0 && 1 < (degF - _aqualink_data->spa_htr_set_point)) {
|
||||
|
|
@ -1132,18 +1208,18 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||
//char *MQTT_id = "AQUALINK_MQTT_TEST_ID";
|
||||
struct mg_send_mqtt_handshake_opts opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.user_name = _aqualink_config->mqtt_user;
|
||||
opts.password = _aqualink_config->mqtt_passwd;
|
||||
opts.user_name = _aqconfig_.mqtt_user;
|
||||
opts.password = _aqconfig_.mqtt_passwd;
|
||||
opts.keep_alive = 5;
|
||||
opts.flags |= MG_MQTT_CLEAN_SESSION; // NFS Need to readup on this
|
||||
|
||||
snprintf(aq_topic, 24, "%s/%s", _aqualink_config->mqtt_aq_topic,MQTT_LWM_TOPIC);
|
||||
snprintf(aq_topic, 24, "%s/%s", _aqconfig_.mqtt_aq_topic,MQTT_LWM_TOPIC);
|
||||
opts.will_topic = aq_topic;
|
||||
opts.will_message = MQTT_OFF;
|
||||
|
||||
mg_set_protocol_mqtt(nc);
|
||||
mg_send_mqtt_handshake_opt(nc, _aqualink_config->mqtt_ID, opts);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing mqtt with id of: %s\n", _aqualink_config->mqtt_ID);
|
||||
mg_send_mqtt_handshake_opt(nc, _aqconfig_.mqtt_ID, opts);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing mqtt with id of: %s\n", _aqconfig_.mqtt_ID);
|
||||
//last_control_time = mg_time();
|
||||
} break;
|
||||
|
||||
|
|
@ -1160,27 +1236,27 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||
_mqtt_exit_flag = true;
|
||||
}
|
||||
|
||||
snprintf(aq_topic, 29, "%s/#", _aqualink_config->mqtt_aq_topic);
|
||||
if (_aqualink_config->mqtt_aq_topic != NULL && _aqualink_config->mqtt_dz_sub_topic != NULL) {
|
||||
snprintf(aq_topic, 29, "%s/#", _aqconfig_.mqtt_aq_topic);
|
||||
if (_aqconfig_.mqtt_aq_topic != NULL && _aqconfig_.mqtt_dz_sub_topic != NULL) {
|
||||
topics[0].topic = aq_topic;
|
||||
topics[0].qos = qos;
|
||||
topics[1].topic = _aqualink_config->mqtt_dz_sub_topic;
|
||||
topics[1].topic = _aqconfig_.mqtt_dz_sub_topic;
|
||||
topics[1].qos = qos;
|
||||
mg_mqtt_subscribe(nc, topics, 2, 42);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", aq_topic);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", _aqualink_config->mqtt_dz_sub_topic);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", _aqconfig_.mqtt_dz_sub_topic);
|
||||
}
|
||||
else if (_aqualink_config->mqtt_aq_topic != NULL) {
|
||||
else if (_aqconfig_.mqtt_aq_topic != NULL) {
|
||||
topics[0].topic = aq_topic;
|
||||
topics[0].qos = qos;
|
||||
mg_mqtt_subscribe(nc, topics, 1, 42);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", aq_topic);
|
||||
}
|
||||
else if (_aqualink_config->mqtt_dz_sub_topic != NULL) {
|
||||
topics[0].topic = _aqualink_config->mqtt_dz_sub_topic;;
|
||||
else if (_aqconfig_.mqtt_dz_sub_topic != NULL) {
|
||||
topics[0].topic = _aqconfig_.mqtt_dz_sub_topic;;
|
||||
topics[0].qos = qos;
|
||||
mg_mqtt_subscribe(nc, topics, 1, 42);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", _aqualink_config->mqtt_dz_sub_topic);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", _aqconfig_.mqtt_dz_sub_topic);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1190,20 +1266,21 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||
break;
|
||||
case MG_EV_MQTT_SUBACK:
|
||||
logMessage(LOG_INFO, "MQTT: Subscription(s) acknowledged\n");
|
||||
snprintf(aq_topic, 24, "%s/%s", _aqualink_config->mqtt_aq_topic,MQTT_LWM_TOPIC);
|
||||
snprintf(aq_topic, 24, "%s/%s", _aqconfig_.mqtt_aq_topic,MQTT_LWM_TOPIC);
|
||||
send_mqtt(nc, aq_topic ,MQTT_ON);
|
||||
break;
|
||||
case MG_EV_MQTT_PUBLISH:
|
||||
mqtt_msg = (struct mg_mqtt_message *)ev_data;
|
||||
|
||||
if (mqtt_msg->message_id != 0) {
|
||||
logMessage(LOG_INFO, "MQTT: received (msg_id: %d), looks like my own message, ignoring\n", mqtt_msg->message_id);
|
||||
logMessage(LOG_DEBUG, "MQTT: received (msg_id: %d), looks like my own message, ignoring\n", mqtt_msg->message_id);
|
||||
}
|
||||
// NSF Need to change strlen to a global so it's not executed every time we check a topic
|
||||
if (_aqualink_config->mqtt_aq_topic != NULL && strncmp(mqtt_msg->topic.p, _aqualink_config->mqtt_aq_topic, strlen(_aqualink_config->mqtt_aq_topic)) == 0) {
|
||||
if (_aqconfig_.mqtt_aq_topic != NULL && strncmp(mqtt_msg->topic.p, _aqconfig_.mqtt_aq_topic, strlen(_aqconfig_.mqtt_aq_topic)) == 0)
|
||||
{
|
||||
action_mqtt_message(nc, mqtt_msg);
|
||||
}
|
||||
if (_aqualink_config->mqtt_dz_sub_topic != NULL && strncmp(mqtt_msg->topic.p, _aqualink_config->mqtt_dz_sub_topic, strlen(_aqualink_config->mqtt_dz_sub_topic)) == 0) {
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1224,13 +1301,13 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||
}
|
||||
|
||||
void start_mqtt(struct mg_mgr *mgr) {
|
||||
logMessage (LOG_NOTICE, "Starting MQTT client to %s\n", _aqualink_config->mqtt_server);
|
||||
if ( _aqualink_config->mqtt_server == NULL ||
|
||||
( _aqualink_config->mqtt_aq_topic == NULL && _aqualink_config->mqtt_dz_pub_topic == NULL && _aqualink_config->mqtt_dz_sub_topic == NULL) )
|
||||
logMessage (LOG_NOTICE, "Starting MQTT client to %s\n", _aqconfig_.mqtt_server);
|
||||
if ( _aqconfig_.mqtt_server == NULL ||
|
||||
( _aqconfig_.mqtt_aq_topic == NULL && _aqconfig_.mqtt_dz_pub_topic == NULL && _aqconfig_.mqtt_dz_sub_topic == NULL) )
|
||||
return;
|
||||
|
||||
if (mg_connect(mgr, _aqualink_config->mqtt_server, ev_handler) == NULL) {
|
||||
logMessage (LOG_ERR, "Failed to create MQTT listener to %s\n", _aqualink_config->mqtt_server);
|
||||
if (mg_connect(mgr, _aqconfig_.mqtt_server, ev_handler) == NULL) {
|
||||
logMessage (LOG_ERR, "Failed to create MQTT listener to %s\n", _aqconfig_.mqtt_server);
|
||||
} else {
|
||||
int i;
|
||||
for (i=0; i < TOTAL_BUTTONS; i++) {
|
||||
|
|
@ -1246,10 +1323,11 @@ 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, struct aqconfig *aqconfig) {
|
||||
bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) {
|
||||
struct mg_connection *nc;
|
||||
_aqualink_data = aqdata;
|
||||
_aqualink_config = aqconfig;
|
||||
//_aqconfig_ = aqconfig;
|
||||
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
|
|
@ -1257,8 +1335,8 @@ bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata, struct
|
|||
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||
|
||||
mg_mgr_init(mgr, NULL);
|
||||
logMessage (LOG_NOTICE, "Starting web server on port %s\n", _aqualink_config->socket_port);
|
||||
nc = mg_bind(mgr, _aqualink_config->socket_port, ev_handler);
|
||||
logMessage (LOG_NOTICE, "Starting web server on port %s\n", _aqconfig_.socket_port);
|
||||
nc = mg_bind(mgr, _aqconfig_.socket_port, ev_handler);
|
||||
if (nc == NULL) {
|
||||
logMessage (LOG_ERR, "Failed to create listener\n");
|
||||
return false;
|
||||
|
|
@ -1266,7 +1344,7 @@ bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata, struct
|
|||
|
||||
// Set up HTTP server parameters
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
s_http_server_opts.document_root = _aqualink_config->web_directory; // Serve current directory
|
||||
s_http_server_opts.document_root = _aqconfig_.web_directory; // Serve current directory
|
||||
s_http_server_opts.enable_directory_listing = "yes";
|
||||
|
||||
#ifndef MG_DISABLE_MQTT
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
//void main_server();
|
||||
//void main_server_TEST(struct aqualinkdata *aqdata, char *s_http_port);
|
||||
//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, struct aqconfig *aqconfig);
|
||||
bool start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata);
|
||||
void broadcast_aqualinkstate(struct mg_connection *nc);
|
||||
void broadcast_aqualinkstate_error(struct mg_connection *nc, char *msg);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,689 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "onetouch.h"
|
||||
#include "onetouch_aq_programmer.h"
|
||||
#include "aq_serial.h"
|
||||
#include "utils.h"
|
||||
#include "aq_serial.h"
|
||||
#include "packetLogger.h"
|
||||
#include "aq_programmer.h"
|
||||
#include "aqualink.h"
|
||||
//#include "pda_menu.h"
|
||||
|
||||
|
||||
int _ot_hlightindex = -1;
|
||||
int _ot_hlightcharindexstart = -1;
|
||||
int _ot_hlightcharindexstop = -1;
|
||||
char _menu[ONETOUCH_LINES][AQ_MSGLEN+1];
|
||||
struct ot_macro _macros[3];
|
||||
|
||||
void set_macro_status();
|
||||
void pump_update(struct aqualinkdata *aq_data, int updated);
|
||||
|
||||
void print_onetouch_menu()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < ONETOUCH_LINES; i++) {
|
||||
//printf("PDA Line %d = %s\n",i,_menu[i]);
|
||||
logMessage(LOG_INFO, "OneTouch Menu Line %d = %s\n",i,_menu[i]);
|
||||
}
|
||||
|
||||
if (_ot_hlightcharindexstart > -1) {
|
||||
logMessage(LOG_INFO, "OneTouch Menu highlighted line = %d, '%s' hligh-char(s) '%.*s'\n",
|
||||
_ot_hlightindex,_menu[_ot_hlightindex],
|
||||
(_ot_hlightcharindexstart - _ot_hlightcharindexstop + 1), &_menu[_ot_hlightindex][_ot_hlightcharindexstart]);
|
||||
} else if (_ot_hlightindex > -1) {
|
||||
logMessage(LOG_INFO, "OneTouch Menu highlighted line = %d = %s\n",_ot_hlightindex,_menu[_ot_hlightindex]);
|
||||
}
|
||||
}
|
||||
|
||||
int onetouch_menu_hlightindex()
|
||||
{
|
||||
return _ot_hlightindex;
|
||||
}
|
||||
|
||||
char *onetouch_menu_hlight()
|
||||
{
|
||||
return onetouch_menu_line(_ot_hlightindex);
|
||||
}
|
||||
|
||||
char *onetouch_menu_hlightchars(int *len)
|
||||
{
|
||||
*len = _ot_hlightcharindexstart - _ot_hlightcharindexstop + 1;
|
||||
return &_menu[_ot_hlightindex][_ot_hlightcharindexstart];
|
||||
}
|
||||
|
||||
char *onetouch_menu_line(int index)
|
||||
{
|
||||
if (index >= 0 && index < ONETOUCH_LINES)
|
||||
return _menu[index];
|
||||
else
|
||||
return "-"; // Just return something bad so I can use string comparison with no null check
|
||||
// return NULL;
|
||||
}
|
||||
|
||||
// Find exact menu item.
|
||||
int onetouch_menu_find_index(char *text)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ONETOUCH_LINES; i++) {
|
||||
if (ot_strcmp(onetouch_menu_line(i), text) == 0)
|
||||
//if (ot_strcmp(onetouch_menu_line(i), text, limit) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool process_onetouch_menu_packet(unsigned char* packet, int length)
|
||||
{
|
||||
bool rtn = true;
|
||||
signed char first_line;
|
||||
signed char last_line;
|
||||
signed char line_shift;
|
||||
signed char i;
|
||||
|
||||
switch (packet[PKT_CMD]) {
|
||||
case CMD_PDA_CLEAR:
|
||||
_ot_hlightindex = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
memset(_menu, 0, ONETOUCH_LINES * (AQ_MSGLEN+1));
|
||||
break;
|
||||
case CMD_MSG_LONG:
|
||||
if (packet[PKT_DATA] < ONETOUCH_LINES) {
|
||||
memset(_menu[(int)packet[PKT_DATA]], 0, AQ_MSGLEN);
|
||||
strncpy(_menu[(int)packet[PKT_DATA]], (char*)packet+PKT_DATA+1, AQ_MSGLEN);
|
||||
_menu[packet[PKT_DATA]][AQ_MSGLEN] = '\0';
|
||||
}
|
||||
//if (getLogLevel() >= LOG_DEBUG){print_onetouch_menu();}
|
||||
break;
|
||||
case CMD_PDA_HIGHLIGHT:
|
||||
// when switching from hlight to hlightchars index 255 is sent to turn off hlight
|
||||
if (packet[4] <= ONETOUCH_LINES) {
|
||||
_ot_hlightindex = packet[4];
|
||||
_ot_hlightcharindexstart = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
} else {
|
||||
_ot_hlightindex = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
}
|
||||
logMessage(LOG_DEBUG, "OneTouch Menu highlighted line = %d = %s\n",_ot_hlightindex,_menu[_ot_hlightindex]);
|
||||
//if (getLogLevel() >= LOG_DEBUG){print_onetouch_menu();}
|
||||
break;
|
||||
case CMD_PDA_HIGHLIGHTCHARS:
|
||||
if (packet[4] <= ONETOUCH_LINES) {
|
||||
_ot_hlightindex = packet[4];
|
||||
_ot_hlightcharindexstart = packet[5];
|
||||
_ot_hlightcharindexstop = packet[6];
|
||||
} else {
|
||||
_ot_hlightindex = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
_ot_hlightcharindexstart = -1;
|
||||
}
|
||||
logMessage(LOG_DEBUG, "OneTouch Menu highlighted line = %d, '%s' chars '%.*s'\n",
|
||||
_ot_hlightindex,_menu[_ot_hlightindex],
|
||||
(_ot_hlightcharindexstart - _ot_hlightcharindexstop + 1), &_menu[_ot_hlightindex][_ot_hlightcharindexstart]);
|
||||
//if (getLogLevel() >= LOG_DEBUG){print_onetouch_menu();}
|
||||
break;
|
||||
case CMD_PDA_SHIFTLINES:
|
||||
/// press up from top - shift menu down by 1
|
||||
// PDA Shif | HEX: 0x10|0x02|0x62|0x0f|0x01|0x08|0x01|0x8d|0x10|0x03|
|
||||
// press down from bottom - shift menu up by 1
|
||||
// PDA Shif | HEX: 0x10|0x02|0x62|0x0f|0x01|0x08|0xff|0x8b|0x10|0x03|
|
||||
first_line = (signed char)(packet[4]);
|
||||
last_line = (signed char)(packet[5]);
|
||||
line_shift = (signed char)(packet[6]);
|
||||
logMessage(LOG_DEBUG, "\n");
|
||||
if (line_shift < 0) {
|
||||
for (i = first_line-line_shift; i <= last_line; i++) {
|
||||
memcpy(_menu[i+line_shift], _menu[i], AQ_MSGLEN+1);
|
||||
}
|
||||
} else {
|
||||
for (i = last_line; i >= first_line+line_shift; i--) {
|
||||
memcpy(_menu[i], _menu[i-line_shift], AQ_MSGLEN+1);
|
||||
}
|
||||
}
|
||||
//if (getLogLevel() >= LOG_DEBUG){print_onetouch_menu();}
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
void setUnits_ot(char *str, struct aqualinkdata *aq_data)
|
||||
{
|
||||
// NSF This needs to use setUnits from aqualinkd.c
|
||||
if (aq_data->temp_units == UNKNOWN) {
|
||||
if (str[15] == 'F')
|
||||
aq_data->temp_units = FAHRENHEIT;
|
||||
else if (str[15] == 'C')
|
||||
aq_data->temp_units = CELSIUS;
|
||||
else
|
||||
aq_data->temp_units = UNKNOWN;
|
||||
|
||||
logMessage(LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aq_data->temp_units);
|
||||
}
|
||||
}
|
||||
|
||||
bool log_heater_setpoints(struct aqualinkdata *aq_data)
|
||||
{
|
||||
bool rtn = false;
|
||||
|
||||
if (ot_strcmp(_menu[2], "Pool Heat") == 0)
|
||||
aq_data->pool_htr_set_point = ot_atoi(&_menu[2][10]);
|
||||
if (ot_strcmp(_menu[3], "Spa Heat") == 0 )
|
||||
aq_data->spa_htr_set_point = ot_atoi(&_menu[3][9]);
|
||||
|
||||
setUnits_ot(_menu[2], aq_data);
|
||||
|
||||
logMessage(LOG_DEBUG, "POOL HEATER SETPOINT %d\n",aq_data->pool_htr_set_point);
|
||||
logMessage(LOG_DEBUG, "SPA HEATER SETPOINT %d\n",aq_data->spa_htr_set_point);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
bool log_panelversion(struct aqualinkdata *aq_data)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// It's already been set
|
||||
if (strlen(aq_data->version) > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy(aq_data->version, trimwhitespace(_menu[4]));
|
||||
// Trim trailing space
|
||||
end = aq_data->version + strlen(aq_data->version) - 1;
|
||||
while(end > aq_data->version && isspace(*end)) end--;
|
||||
|
||||
strcpy(end+2, trimwhitespace(_menu[7]));
|
||||
// Trim trailing space
|
||||
end = aq_data->version + strlen(aq_data->version) - 1;
|
||||
while(end > aq_data->version && isspace(*end)) end--;
|
||||
|
||||
// Write new null terminator
|
||||
*(end+1) = 0;
|
||||
|
||||
logMessage(LOG_DEBUG, "**** '%s' ****\n",aq_data->version);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Info: OneTouch Menu Line 3 = Temp 38`F
|
||||
bool log_freeze_setpoints(struct aqualinkdata *aq_data)
|
||||
{
|
||||
bool rtn = false;
|
||||
|
||||
if (ot_strcmp(_menu[3], "Temp") == 0)
|
||||
aq_data->frz_protect_set_point = ot_atoi(&_menu[3][11]);
|
||||
|
||||
setUnits_ot(_menu[3], aq_data);
|
||||
|
||||
logMessage(LOG_DEBUG, "FREEZE PROTECT SETPOINT %d\n",aq_data->frz_protect_set_point);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
bool log_qeuiptment_status(struct aqualinkdata *aq_data)
|
||||
{
|
||||
bool rtn = false;
|
||||
|
||||
if (ot_strcmp(_menu[2],"Intelliflo VS") == 0 ||
|
||||
ot_strcmp(_menu[2],"Intelliflo VF") == 0 ||
|
||||
ot_strcmp(_menu[2],"Jandy ePUMP") == 0) {
|
||||
rtn = true;
|
||||
int rpm = 0;
|
||||
int watts = 0;
|
||||
int gpm = 0;
|
||||
int pump_index = ot_atoi(&_menu[2][14]);
|
||||
// RPM displays differently depending on 3 or 4 digit rpm.
|
||||
if (ot_strcmp(_menu[3],"RPM:") == 0){
|
||||
rpm = ot_atoi(&_menu[3][10]);
|
||||
if (ot_strcmp(_menu[4],"Watts:") == 0) {
|
||||
watts = ot_atoi(&_menu[4][11]);
|
||||
}
|
||||
if (ot_strcmp(_menu[5],"GPM:") == 0) {
|
||||
gpm = ot_atoi(&_menu[5][11]);
|
||||
}
|
||||
} else if (ot_strcmp(_menu[3],"*** Priming ***") == 0){
|
||||
rpm = PUMP_PRIMING;
|
||||
} else if (ot_strcmp(_menu[3],"(Offline)") == 0){
|
||||
rpm = PUMP_OFFLINE;
|
||||
}
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch Pump %s, Index %d, RPM %d, Watts %d, GPM %d\n",_menu[2],pump_index,rpm,watts,gpm);
|
||||
|
||||
int i;
|
||||
for (i=0; i < aq_data->num_pumps; i++) {
|
||||
if (aq_data->pumps[i].pumpIndex == pump_index) {
|
||||
//printf("**** FOUND PUMP %d at index %d *****\n",pump_index,i);
|
||||
//aq_data->pumps[i].updated = true;
|
||||
pump_update(aq_data, i);
|
||||
aq_data->pumps[i].rpm = rpm;
|
||||
aq_data->pumps[i].watts = watts;
|
||||
aq_data->pumps[i].gpm = gpm;
|
||||
if (aq_data->pumps[i].pumpType == PT_UNKNOWN){
|
||||
if (ot_strcmp(_menu[2],"Intelliflo VS") == 0)
|
||||
aq_data->pumps[i].pumpType = VSPUMP;
|
||||
else if (ot_strcmp(_menu[2],"Intelliflo VF") == 0)
|
||||
aq_data->pumps[i].pumpType = VFPUMP;
|
||||
else if (ot_strcmp(_menu[2],"Jandy ePUMP") == 0)
|
||||
aq_data->pumps[i].pumpType = EPUMP;
|
||||
}
|
||||
//printf ("Set Pump Type to %d\n",aq_data->pumps[i].pumpType);
|
||||
}
|
||||
}
|
||||
|
||||
//aqdata->pumps[pumpIndex-1].rpm = atoi((char *) &packet_buffer[13]);
|
||||
|
||||
} else if (true == false) {
|
||||
/*
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = AQUAPURE 30%
|
||||
Debug: OneTouch Menu Line 3 = Salt 3800 PPM
|
||||
Debug: OneTouch Menu Line 4 = Add 2 lbs Salt
|
||||
*/
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
ot_menu_type get_onetouch_memu_type()
|
||||
{
|
||||
if (ot_strcmp(_menu[11],"SYSTEM") == 0)
|
||||
return OTM_ONETOUCH;
|
||||
else if (ot_strcmp(_menu[0],"Jandy AquaLinkRS") == 0)
|
||||
return OTM_SYSTEM;
|
||||
else if (ot_strcmp(_menu[0],"EQUIPMENT STATUS") == 0)
|
||||
return OTM_EQUIPTMENT_STATUS;
|
||||
else if (ot_strcmp(_menu[0],"Select Speed") == 0)
|
||||
return OTM_SELECT_SPEED;
|
||||
else if (ot_strcmp(_menu[0],"Menu") == 0)
|
||||
return OTM_MENUHELP;
|
||||
else if (ot_strcmp(_menu[0],"Set Temp") == 0)
|
||||
return OTM_SET_TEMP;
|
||||
else if (ot_strcmp(_menu[0],"Set Time") == 0)
|
||||
return OTM_SET_TIME;
|
||||
else if (ot_strcmp(_menu[0],"System Setup") == 0)
|
||||
return OTM_SYSTEM_SETUP;
|
||||
else if (ot_strcmp(_menu[0],"Freeze Protect") == 0)
|
||||
return OTM_FREEZE_PROTECT;
|
||||
else if (ot_strcmp(_menu[0],"Boost Pool") == 0)
|
||||
return OTM_BOOST;
|
||||
else if (ot_strcmp(_menu[7],"REV ") == 0) // NSF Need a better check.
|
||||
return OTM_VERSION;
|
||||
|
||||
return OTM_UNKNOWN;
|
||||
}
|
||||
|
||||
void pump_update(struct aqualinkdata *aq_data, int updated) {
|
||||
const int bitmask[MAX_PUMPS] = {1,2,4,8};
|
||||
static unsigned char updates = '\0';
|
||||
int i;
|
||||
|
||||
if (updated == -1) {
|
||||
for(i=0; i < MAX_PUMPS; i++) {
|
||||
if ((updates & bitmask[i]) != bitmask[i]) {
|
||||
aq_data->pumps[i].rpm = TEMP_UNKNOWN;
|
||||
aq_data->pumps[i].gpm = TEMP_UNKNOWN;
|
||||
aq_data->pumps[i].watts = TEMP_UNKNOWN;
|
||||
}
|
||||
}
|
||||
updates = '\0';
|
||||
} else if (updated >=0 && updated < MAX_PUMPS) {
|
||||
updates |= bitmask[updated];
|
||||
}
|
||||
}
|
||||
|
||||
bool new_menu(struct aqualinkdata *aq_data)
|
||||
{
|
||||
static bool initRS = false;
|
||||
bool rtn = false;
|
||||
static ot_menu_type last_menu_type = OTM_UNKNOWN;
|
||||
ot_menu_type menu_type = get_onetouch_memu_type();
|
||||
|
||||
print_onetouch_menu();
|
||||
|
||||
switch (menu_type) {
|
||||
case OTM_ONETOUCH:
|
||||
set_macro_status();
|
||||
break;
|
||||
case OTM_EQUIPTMENT_STATUS:
|
||||
if (initRS == false) {
|
||||
queueGetProgramData(ONETOUCH, aq_data);
|
||||
initRS = true;
|
||||
}
|
||||
rtn = log_qeuiptment_status(aq_data);
|
||||
// Hit select to get to next menu ASAP.
|
||||
if ( in_ot_programming_mode(aq_data) == false )
|
||||
ot_queue_cmd(KEY_ONET_SELECT);
|
||||
break;
|
||||
case OTM_SET_TEMP:
|
||||
rtn = log_heater_setpoints(aq_data);
|
||||
break;
|
||||
case OTM_FREEZE_PROTECT:
|
||||
rtn = log_freeze_setpoints(aq_data);
|
||||
break;
|
||||
case OTM_VERSION:
|
||||
rtn = log_panelversion(aq_data);
|
||||
logMessage(LOG_DEBUG, "**** ONETOUCH INIT ****");
|
||||
queueGetProgramData(ONETOUCH, aq_data);
|
||||
//set_aqualink_onetouch_pool_heater_temp()
|
||||
//aq_programmer(AQ_SET_ONETOUCH_POOL_HEATER_TEMP, "95", aq_data);
|
||||
//aq_programmer(AQ_SET_ONETOUCH_SPA_HEATER_TEMP, "94", aq_data);
|
||||
initRS = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (last_menu_type == OTM_EQUIPTMENT_STATUS && menu_type != OTM_EQUIPTMENT_STATUS ) {
|
||||
// End of equiptment status chain of menus, reset any pump that wasn't listed in menus
|
||||
pump_update(aq_data, -1);
|
||||
}
|
||||
|
||||
last_menu_type = menu_type;
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
void set_macro_status()
|
||||
{
|
||||
// OneTouch Menu Line 2 = SPA MODE OFF
|
||||
// OneTouch Menu Line 5 = CLEAN MODE ON
|
||||
// OneTouch Menu Line 8 = ONETOUCH 3 OFF
|
||||
if (get_onetouch_memu_type() == OTM_ONETOUCH) {
|
||||
strncpy(_macros[0].name, _menu[2], 13);
|
||||
chopwhitespace(_macros[0].name);
|
||||
_macros[0].ison = (_menu[2][15] == 'N'?true:false);
|
||||
|
||||
strncpy(_macros[1].name, _menu[5], 13);
|
||||
chopwhitespace(_macros[1].name);
|
||||
_macros[1].ison = (_menu[5][15] == 'N'?true:false);
|
||||
|
||||
strncpy(_macros[2].name, _menu[8], 13);
|
||||
chopwhitespace(_macros[2].name);
|
||||
_macros[2].ison = (_menu[8][15] == 'N'?true:false);
|
||||
|
||||
logMessage(LOG_DEBUG, "Macro #1 '%s' is %s\n",_macros[0].name,_macros[0].ison?"On":"Off");
|
||||
logMessage(LOG_DEBUG, "Macro #2 '%s' is %s\n",_macros[1].name,_macros[1].ison?"On":"Off");
|
||||
logMessage(LOG_DEBUG, "Macro #3 '%s' is %s\n",_macros[2].name,_macros[2].ison?"On":"Off");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char _last_msg_type = 0x00;
|
||||
unsigned char _last_kick_type = -1;
|
||||
|
||||
int thread_kick_type()
|
||||
{
|
||||
return _last_kick_type;
|
||||
}
|
||||
|
||||
unsigned char *last_onetouch_packet()
|
||||
{
|
||||
return &_last_msg_type;
|
||||
}
|
||||
|
||||
bool process_onetouch_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
static bool filling_menu = false;
|
||||
bool rtn = false;
|
||||
//int i;
|
||||
//char *msg;
|
||||
//static unsigned char last_msg_type = 0x00;
|
||||
//static bool init = false;
|
||||
|
||||
//process_pda_packet(packet, length);
|
||||
|
||||
//logMessage(LOG_DEBUG, "RS Received ONETOUCH 0x%02hhx\n", packet[PKT_CMD]);
|
||||
//debuglogPacket(packet, length);
|
||||
|
||||
process_onetouch_menu_packet(packet, length);
|
||||
|
||||
// Check for new menu.
|
||||
// Usually PDA_CLEAR bunch of CMD_MSG_LONG then a CMD_PDA_HIGHLIGHT or CMD_PDA_HIGHLIGHTCHARS
|
||||
// When we hit page down, just CMD_MSG_LONG then a CMD_PDA_HIGHLIGHT. (not seen CMD_PDA_HIGHLIGHTCHARS yet)
|
||||
if ( (filling_menu == true &&
|
||||
(//packet[PKT_CMD] == CMD_PDA_HIGHLIGHTCHARS ||
|
||||
packet[PKT_CMD] == CMD_PDA_HIGHLIGHT ||
|
||||
packet[PKT_CMD] == CMD_STATUS) )
|
||||
||
|
||||
( _last_msg_type == CMD_MSG_LONG && packet[PKT_CMD] == CMD_PDA_HIGHLIGHT )
|
||||
)
|
||||
{
|
||||
filling_menu = false;
|
||||
rtn = new_menu(aq_data);
|
||||
_last_kick_type = KICKT_MENU;
|
||||
} else {
|
||||
_last_kick_type = KICKT_CMD;
|
||||
}
|
||||
|
||||
if (packet[PKT_CMD] == CMD_PDA_CLEAR)
|
||||
filling_menu = true;
|
||||
|
||||
/*
|
||||
//if (_last_msg_type == CMD_MSG_LONG && packet[PKT_CMD] != CMD_MSG_LONG) {
|
||||
if (_last_msg_type == CMD_MSG_LONG && ( packet[PKT_CMD] != CMD_MSG_LONG && packet[PKT_CMD] != CMD_PDA_HIGHLIGHTCHARS) ) { // CMD_PDA_SHIFTLINES
|
||||
rtn = new_menu(aq_data);
|
||||
_last_kick_type = KICKT_MENU;
|
||||
} else {
|
||||
_last_kick_type = KICKT_CMD;
|
||||
}
|
||||
*/
|
||||
_last_msg_type = packet[PKT_CMD];
|
||||
|
||||
// Receive 0x04 for System menu (before 0x02)
|
||||
// Receive 0x04 for startup menu (before 0x02)
|
||||
// Receive 0x08 for Equiptment menu (before 0x02)
|
||||
|
||||
// Receive 0x04 while building menu
|
||||
|
||||
if ( packet[PKT_CMD] == CMD_MSG_LONG)
|
||||
logMessage(LOG_DEBUG, "RS received ONETOUCH packet of type %s length %d '%.*s'\n", get_packet_type(packet, length), length, AQ_MSGLEN, (char*)packet+PKT_DATA+1);
|
||||
else
|
||||
logMessage(LOG_DEBUG, "RS received ONETOUCH packet of type %s length %d\n", get_packet_type(packet, length), length);
|
||||
|
||||
|
||||
//debuglogPacket(packet, length);
|
||||
|
||||
//if ( in_ot_programming_mode(aq_data) == true )
|
||||
kick_aq_program_thread(aq_data, ONETOUCH);
|
||||
/*
|
||||
switch (packet[PKT_CMD])
|
||||
{
|
||||
case CMD_ACK:
|
||||
//logMessage(LOG_DEBUG, "RS Received ACK length %d.\n", length);
|
||||
break;
|
||||
|
||||
//case CMD_PDA_HIGHLIGHT: // This doesn't work for end of menu, if menu is complete then get a change line, highlight isn't sent.
|
||||
//set_macro_status();
|
||||
// break;
|
||||
|
||||
case 0x04:
|
||||
case 0x08:
|
||||
logMessage(LOG_DEBUG, "RS Received MENU complete\n");
|
||||
set_macro_status();
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case CMD_MSG_LONG:
|
||||
msg = (char *)packet + PKT_DATA + 1;
|
||||
logMessage(LOG_DEBUG, "RS Received message data 0x%02hhx string '%s'\n",packet[PKT_DATA],msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
//logMessage(LOG_DEBUG, "RS Received 0x%02hhx\n", packet[PKT_CMD]);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
// Check s2 exists in s1
|
||||
int ot_strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
char *sp1 = (char *)s1;
|
||||
char *sp2 = (char *)s2;
|
||||
//int i=0;
|
||||
// Get rid of all padding
|
||||
while(isspace(*sp1)) sp1++;
|
||||
while(isspace(*sp2)) sp2++;
|
||||
|
||||
// Need to write this myself for speed
|
||||
//logMessage(LOG_DEBUG, "OneTouch compare (reset)%d chars of '%s' to '%s'\n",strlen(sp2),sp1,sp2);
|
||||
return strncasecmp(sp1, sp2, strlen(sp2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define INT_MAX +2147483647
|
||||
#define INT_MIN -2147483647
|
||||
|
||||
// atoi that can have blank start
|
||||
int ot_atoi(const char* str)
|
||||
{
|
||||
int sign = 1, base = 0, i = 0;
|
||||
// if whitespaces then ignore.
|
||||
while (str[i] == ' ') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// checking for valid input
|
||||
while (str[i] >= '0' && str[i] <= '9') {
|
||||
// handling overflow test case
|
||||
if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) {
|
||||
if (sign == 1)
|
||||
return INT_MAX;
|
||||
else
|
||||
return INT_MIN;
|
||||
}
|
||||
base = 10 * base + (str[i++] - '0');
|
||||
}
|
||||
return base * sign;
|
||||
}
|
||||
|
||||
/*
|
||||
Version something like
|
||||
Info: OneTouch Menu Line 0 =
|
||||
Info: OneTouch Menu Line 1 =
|
||||
Info: OneTouch Menu Line 2 =
|
||||
Info: OneTouch Menu Line 3 =
|
||||
Info: OneTouch Menu Line 4 = B0029221
|
||||
Info: OneTouch Menu Line 5 = RS-8 Combo
|
||||
Info: OneTouch Menu Line 6 =
|
||||
Info: OneTouch Menu Line 7 = REV T.0.1
|
||||
Info: OneTouch Menu Line 8 =
|
||||
Info: OneTouch Menu Line 9 =
|
||||
Info: OneTouch Menu Line 10 =
|
||||
Info: OneTouch Menu Line 11 =
|
||||
*/
|
||||
/*
|
||||
Info: OneTouch Menu Line 0 = Set Temp
|
||||
Info: OneTouch Menu Line 1 =
|
||||
Info: OneTouch Menu Line 2 = Pool Heat 90`F
|
||||
Info: OneTouch Menu Line 3 = Spa Heat 102`F
|
||||
Info: OneTouch Menu Line 4 =
|
||||
Info: OneTouch Menu Line 5 = Maintain OFF
|
||||
Info: OneTouch Menu Line 6 = Hours 12AM-12AM
|
||||
Info: OneTouch Menu Line 7 =
|
||||
Info: OneTouch Menu Line 8 = Highlight an
|
||||
Info: OneTouch Menu Line 9 = item and press
|
||||
Info: OneTouch Menu Line 10 = Select
|
||||
Info: OneTouch Menu Line 11 =
|
||||
*/
|
||||
/*
|
||||
nfo: OneTouch Menu Line 0 = Freeze Protect
|
||||
Info: OneTouch Menu Line 1 =
|
||||
Info: OneTouch Menu Line 2 =
|
||||
Info: OneTouch Menu Line 3 = Temp 38`F
|
||||
Info: OneTouch Menu Line 4 =
|
||||
Info: OneTouch Menu Line 5 =
|
||||
Info: OneTouch Menu Line 6 = Use Arrow Keys
|
||||
Info: OneTouch Menu Line 7 = to set value.
|
||||
Info: OneTouch Menu Line 8 = Press SELECT
|
||||
Info: OneTouch Menu Line 9 = to continue.
|
||||
Info: OneTouch Menu Line 10 =
|
||||
Info: OneTouch Menu Line 11 =
|
||||
*/
|
||||
|
||||
/*
|
||||
Pump Stuff Use Intelliflo|Jandy & last number of line.
|
||||
(Intelliflo VF you set GPM, not RPM)
|
||||
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = Intelliflo VS 3
|
||||
Debug: OneTouch Menu Line 3 = *** Priming ***
|
||||
Debug: OneTouch Menu Line 4 = Watts: 100
|
||||
Debug: OneTouch Menu Line 5 =
|
||||
Debug: OneTouch Menu Line 6 =
|
||||
Debug: OneTouch Menu Line 7 =
|
||||
Debug: OneTouch Menu Line 8 =
|
||||
Debug: OneTouch Menu Line 9 =
|
||||
Debug: OneTouch Menu Line 10 =
|
||||
Debug: OneTouch Menu Line 11 =
|
||||
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = Intelliflo VS 3
|
||||
Debug: OneTouch Menu Line 3 = RPM: 2750
|
||||
Debug: OneTouch Menu Line 3 = RPM: 600 // Option for 3 digit RPM
|
||||
Debug: OneTouch Menu Line 4 = Watts: 55
|
||||
Debug: OneTouch Menu Line 5 =
|
||||
Debug: OneTouch Menu Line 6 =
|
||||
Debug: OneTouch Menu Line 7 =
|
||||
Debug: OneTouch Menu Line 8 =
|
||||
Debug: OneTouch Menu Line 9 =
|
||||
Debug: OneTouch Menu Line 10 =
|
||||
Debug: OneTouch Menu Line 11 =
|
||||
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = Intelliflo VF 2
|
||||
Debug: OneTouch Menu Line 3 = (Offline)
|
||||
Debug: OneTouch Menu Line 4 =
|
||||
Debug: OneTouch Menu Line 5 =
|
||||
Debug: OneTouch Menu Line 6 =
|
||||
Debug: OneTouch Menu Line 7 =
|
||||
Debug: OneTouch Menu Line 8 =
|
||||
Debug: OneTouch Menu Line 9 =
|
||||
Debug: OneTouch Menu Line 10 =
|
||||
Debug: OneTouch Menu Line 11 =
|
||||
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = Intelliflo VF 2
|
||||
Debug: OneTouch Menu Line 3 = RPM: 2250
|
||||
Debug: OneTouch Menu Line 4 = Watts: 55
|
||||
Debug: OneTouch Menu Line 5 = GPM: 80
|
||||
Debug: OneTouch Menu Line 6 =
|
||||
Debug: OneTouch Menu Line 7 =
|
||||
Debug: OneTouch Menu Line 8 =
|
||||
Debug: OneTouch Menu Line 9 =
|
||||
Debug: OneTouch Menu Line 10 =
|
||||
Debug: OneTouch Menu Line 11 =
|
||||
|
||||
Debug: OneTouch Menu Line 0 = Equipment Status
|
||||
Debug: OneTouch Menu Line 1 =
|
||||
Debug: OneTouch Menu Line 2 = Jandy ePUMP 1
|
||||
Debug: OneTouch Menu Line 3 = RPM: 1750
|
||||
Debug: OneTouch Menu Line 4 = Watts: 43
|
||||
Debug: OneTouch Menu Line 5 =
|
||||
Debug: OneTouch Menu Line 6 =
|
||||
Debug: OneTouch Menu Line 7 =
|
||||
Debug: OneTouch Menu Line 8 =
|
||||
Debug: OneTouch Menu Line 9 =
|
||||
Debug: OneTouch Menu Line 10 =
|
||||
Debug: OneTouch Menu Line 11 =
|
||||
*/
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
#ifndef ONETOUCH_H_
|
||||
#define ONETOUCH_H_
|
||||
|
||||
#include "aq_serial.h"
|
||||
#include "aqualink.h"
|
||||
|
||||
#define ONETOUCH_LINES 12
|
||||
|
||||
#define PUMP_PRIMING -1
|
||||
#define PUMP_OFFLINE -2
|
||||
|
||||
#define KICKT_CMD 0
|
||||
#define KICKT_MENU 1
|
||||
|
||||
typedef enum ot_menu_type {
|
||||
OTM_ONETOUCH,
|
||||
OTM_EQUIPTMENT_STATUS,
|
||||
OTM_SYSTEM, // Default screen with date,time & temperature
|
||||
OTM_MAIN,
|
||||
OTM_EQUIPTMENT,
|
||||
OTM_EQUIPTMENT_ONOFF,
|
||||
OTM_SELECT_SPEED,
|
||||
OTM_MENUHELP,
|
||||
OTM_VERSION,
|
||||
OTM_SET_TEMP,
|
||||
OTM_SET_TIME,
|
||||
OTM_SYSTEM_SETUP,
|
||||
OTM_FREEZE_PROTECT,
|
||||
OTM_SET_AQUAPURE,
|
||||
OTM_BOOST,
|
||||
OTM_UNKNOWN
|
||||
} ot_menu_type;
|
||||
|
||||
struct ot_macro {
|
||||
char name[AQ_MSGLEN];
|
||||
bool ison;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Left Top Button
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x03|0x96|0x10|0x03|
|
||||
|
||||
Left Middle Button (Back)
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x02|0x95|0x10|0x03|
|
||||
|
||||
Left Botom Button
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x01|0x94|0x10|0x03|
|
||||
|
||||
Select Button
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x04|0x97|0x10|0x03|
|
||||
|
||||
Up Button
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x06|0x99|0x10|0x03|
|
||||
|
||||
Down Button
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x80|0x05|0x98|0x10|0x03|
|
||||
|
||||
|
||||
*/
|
||||
|
||||
bool process_onetouch_packet(unsigned char *packet, int length,struct aqualinkdata *aq_data);
|
||||
ot_menu_type get_onetouch_memu_type();
|
||||
unsigned char *last_onetouch_packet();
|
||||
int thread_kick_type();
|
||||
|
||||
int onetouch_menu_hlightindex();
|
||||
char *onetouch_menu_hlight();
|
||||
char *onetouch_menu_line(int index);
|
||||
char *onetouch_menu_hlightchars(int *len);
|
||||
int onetouch_menu_find_index(char *text);
|
||||
int ot_atoi(const char* str);
|
||||
int ot_strcmp(const char *s1, const char *s2);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // ONETOUCH_H_
|
||||
|
|
@ -0,0 +1,803 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "aq_programmer.h"
|
||||
#include "onetouch.h"
|
||||
#include "aqualink.h"
|
||||
|
||||
unsigned char _ot_pgm_command = NUL;
|
||||
|
||||
// External command
|
||||
bool ot_queue_cmd(unsigned char cmd) {
|
||||
|
||||
if (_ot_pgm_command == NUL) {
|
||||
_ot_pgm_command = cmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char pop_ot_cmd(unsigned char receive_type)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
|
||||
if (receive_type == CMD_STATUS) {
|
||||
cmd = _ot_pgm_command;
|
||||
_ot_pgm_command = NUL;
|
||||
}
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch Sending '0x%02hhx' to controller\n", cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void waitfor_ot_queue2empty()
|
||||
{
|
||||
int i=0;
|
||||
|
||||
while ( (_ot_pgm_command != NUL) && ( i++ < 20) ) {
|
||||
delay(50);
|
||||
}
|
||||
|
||||
if (_ot_pgm_command != NUL) {
|
||||
// Wait for longer interval
|
||||
while ( (_ot_pgm_command != NUL) && ( i++ < 100) ) {
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
if (_ot_pgm_command != NUL) {
|
||||
logMessage(LOG_WARNING, "OneTouch Send command Queue did not empty, timeout\n");
|
||||
}
|
||||
}
|
||||
|
||||
// This is for internal use only.
|
||||
// Will only work in programming mode
|
||||
void send_ot_cmd(unsigned char cmd)
|
||||
{
|
||||
waitfor_ot_queue2empty();
|
||||
|
||||
ot_queue_cmd(cmd);
|
||||
|
||||
logMessage(LOG_INFO, "OneTouch Queue send '0x%02hhx' to controller (programming)\n", _ot_pgm_command);
|
||||
}
|
||||
|
||||
bool waitForOT_MessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived)
|
||||
{
|
||||
//logMessage(LOG_DEBUG, "waitForOT_MessageType 0x%02hhx || 0x%02hhx\n",mtype1,mtype2);
|
||||
|
||||
int i=0;
|
||||
pthread_mutex_lock(&aq_data->active_thread.thread_mutex);
|
||||
|
||||
while( ++i <= numMessageReceived)
|
||||
{
|
||||
logMessage(LOG_DEBUG, "waitForOT_MessageType 0x%02hhx||0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype1,mtype2,*last_onetouch_packet(),i,numMessageReceived);
|
||||
|
||||
if (*last_onetouch_packet() == mtype1 || *last_onetouch_packet() == mtype2) break;
|
||||
|
||||
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&aq_data->active_thread.thread_mutex);
|
||||
|
||||
if (*last_onetouch_packet() != mtype1 && *last_onetouch_packet() != mtype2) {
|
||||
//logMessage(LOG_ERR, "Could not select MENU of Aqualink control panel\n");
|
||||
logMessage(LOG_DEBUG, "waitForOT_MessageType: did not receive 0x%02hhx||0x%02hhx\n",mtype1,mtype2);
|
||||
return false;
|
||||
} else
|
||||
logMessage(LOG_DEBUG, "waitForOT_MessageType: received 0x%02hhx\n",*last_onetouch_packet());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool waitForNextOT_Menu(struct aqualinkdata *aq_data) {
|
||||
//waitForOT_MessageTypes(aq_data,CMD_PDA_CLEAR,CMD_PDA_0x04,10);
|
||||
//return waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
|
||||
int i=0;
|
||||
const int numMessageReceived = 20;
|
||||
|
||||
pthread_mutex_lock(&aq_data->active_thread.thread_mutex);
|
||||
|
||||
while( ++i <= 20)
|
||||
{
|
||||
logMessage(LOG_DEBUG, "waitForNextOT_Menu (%d of %d)\n",i,numMessageReceived);
|
||||
|
||||
//if(thread_kick_type() == KICKT_MENU) break;
|
||||
|
||||
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
|
||||
if(thread_kick_type() == KICKT_MENU) break;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&aq_data->active_thread.thread_mutex);
|
||||
|
||||
if(thread_kick_type() == KICKT_MENU)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool highlight_onetouch_menu_item(struct aqualinkdata *aq_data, char *item)
|
||||
{
|
||||
int i;
|
||||
int index;
|
||||
int cnt;
|
||||
// Should probably to an UP as well as DOWN here.
|
||||
// Also need page up and down " ^^ More vv"
|
||||
if ( (index = onetouch_menu_find_index(item)) != -1) {
|
||||
cnt = index - onetouch_menu_hlightindex();
|
||||
logMessage(LOG_DEBUG, "*** OneTouch menu caculator selected=%d, wanted=%d, move=%d times ***\n",onetouch_menu_hlightindex(),index,cnt);
|
||||
for (i=0; i < cnt; i ++) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,3);
|
||||
if (ot_strcmp(onetouch_menu_hlight(), item) == 0) {
|
||||
// We got here early, probably because blank menu item
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check if it's quicker to go up rather than down, if second page can't go up.
|
||||
// This doesn;t work yet, not all versions of control panels have the same amount of items.
|
||||
/*
|
||||
if (cnt <= 5 || ot_strcmp(onetouch_menu_line(10), " ^^ More", 10) == 0 ) {
|
||||
logMessage(LOG_DEBUG, "OneTouch device programmer pressing down %d times\n",cnt);
|
||||
for (i=0; i < cnt; i ++) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
//waitfor_ot_queue2empty();
|
||||
//waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
}
|
||||
} else {
|
||||
cnt = 11 - cnt;
|
||||
logMessage(LOG_DEBUG, "OneTouch device programmer pressing up %d times\n",cnt);
|
||||
for (i=0; i < cnt; i ++) {
|
||||
send_ot_cmd(KEY_ONET_UP);
|
||||
//waitfor_ot_queue2empty();
|
||||
//waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
}
|
||||
}*/
|
||||
// Not much quicker doing it this way that in the for loops above, may have to change back.
|
||||
//waitfor_ot_queue2empty();
|
||||
//waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
} else {
|
||||
// Is their another page to search
|
||||
if (ot_strcmp(onetouch_menu_line(10), "^^ More") == 0) {
|
||||
char first_item[AQ_MSGLEN+1];
|
||||
do {
|
||||
send_ot_cmd(KEY_ONET_PAGE_DN);
|
||||
waitForNextOT_Menu(aq_data);
|
||||
if (onetouch_menu_find_index(item) != -1) {
|
||||
return highlight_onetouch_menu_item(aq_data, item);
|
||||
}
|
||||
} while (strncpy(first_item, onetouch_menu_line(1), AQ_MSGLEN));
|
||||
// Need to get menu item 1.
|
||||
// Hit page down until menu item matches 1.
|
||||
} else
|
||||
logMessage(LOG_ERR, "OneTouch device programmer menu item '%s' does not exist\n",item);
|
||||
//print_onetouch_menu();
|
||||
}
|
||||
|
||||
if ( ot_strcmp(onetouch_menu_hlight(), item) != 0) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer menu item '%s' not selected\n",item);
|
||||
//print_onetouch_menu();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool select_onetouch_menu_item(struct aqualinkdata *aq_data, char *item)
|
||||
{
|
||||
if (highlight_onetouch_menu_item(aq_data, item)) {
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitForNextOT_Menu(aq_data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool goto_onetouch_system_menu(struct aqualinkdata *aq_data)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
if (get_onetouch_memu_type() == OTM_SYSTEM)
|
||||
return true;
|
||||
|
||||
// Get back to a known point, the system menu
|
||||
while (get_onetouch_memu_type() != OTM_SYSTEM && get_onetouch_memu_type() != OTM_ONETOUCH && i < 5 ) {
|
||||
send_ot_cmd(KEY_ONET_BACK);
|
||||
waitForNextOT_Menu(aq_data);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (get_onetouch_memu_type() == OTM_SYSTEM) {
|
||||
//printf("*** SYSTEM MENU ***\n");
|
||||
//return false;
|
||||
} else if (get_onetouch_memu_type() == OTM_ONETOUCH) {
|
||||
//printf("*** ONE TOUCH MENU ***\n");
|
||||
// Can only be one of 2 options in this menu, so if it's not the one we want, hit down first
|
||||
if ( ot_strcmp(onetouch_menu_hlight(), "System") != 0) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
}
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForNextOT_Menu(aq_data);
|
||||
//return false;
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer couldn't get to System menu\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (get_onetouch_memu_type() != OTM_SYSTEM) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer couldn't get to System menu\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool goto_onetouch_menu(struct aqualinkdata *aq_data, ot_menu_type menu)
|
||||
{
|
||||
char *second_menu = false;
|
||||
char *third_menu = false;
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch device programmer request for menu %d\n",menu);
|
||||
|
||||
if ( ! goto_onetouch_system_menu(aq_data) ) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get system menu\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we are at main menu, we should have 3 options
|
||||
/* Debug: OneTouch Menu Line 9 = Equipment ON/OFF
|
||||
Debug: OneTouch Menu Line 10 = OneTouch ON/OFF
|
||||
Debug: OneTouch Menu Line 11 = Menu / Help
|
||||
*/
|
||||
|
||||
// First setup any secondary menu's to hit.
|
||||
switch(menu){
|
||||
case OTM_SET_TEMP:
|
||||
second_menu = "Set Temp";
|
||||
break;
|
||||
case OTM_SET_TIME:
|
||||
second_menu = "Set Time";
|
||||
break;
|
||||
case OTM_SET_AQUAPURE:
|
||||
second_menu = "Set AQUAPURE";
|
||||
break;
|
||||
case OTM_FREEZE_PROTECT:
|
||||
second_menu = "System Setup";
|
||||
third_menu = "Freeze Protect";
|
||||
break;
|
||||
case OTM_SYSTEM_SETUP:
|
||||
second_menu = "System Setup";
|
||||
break;
|
||||
case OTM_BOOST:
|
||||
second_menu = "Boost";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Now actually get the menu
|
||||
switch(menu){
|
||||
case OTM_SYSTEM:
|
||||
// We are already here
|
||||
return true;
|
||||
break;
|
||||
case OTM_EQUIPTMENT_ONOFF:
|
||||
//if ( select_onetouch_menu_item(aq_data, "Equipment ON/OFF") == false ) { // NSF Should use this
|
||||
if ( ot_strcmp(onetouch_menu_hlight(), "Equipment ON/OFF") == 0) {
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForNextOT_Menu(aq_data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case OTM_MENUHELP:
|
||||
case OTM_SET_TEMP:
|
||||
case OTM_SET_TIME:
|
||||
case OTM_SET_AQUAPURE:
|
||||
case OTM_FREEZE_PROTECT:
|
||||
case OTM_BOOST:
|
||||
case OTM_SYSTEM_SETUP:
|
||||
if ( select_onetouch_menu_item(aq_data, " Menu / Help") == false ) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer couldn't select menu %d\n",menu);
|
||||
}
|
||||
if (second_menu)
|
||||
select_onetouch_menu_item(aq_data, second_menu);
|
||||
if (third_menu)
|
||||
select_onetouch_menu_item(aq_data, third_menu);
|
||||
/*
|
||||
if (menu == OTM_SET_HEATER) {
|
||||
select_onetouch_menu_item(aq_data, "Set Temp");
|
||||
} else if (menu == OTM_SET_TIME) {
|
||||
select_onetouch_menu_item(aq_data, "Set Time");
|
||||
} else if (menu == OTM_SET_AQUAPURE) {
|
||||
select_onetouch_menu_item(aq_data, "Set AQUAPURE");
|
||||
}
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
logMessage(LOG_ERR, "OneTouch device programmer doesn't know how to access menu %d\n",menu);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_onetouch_memu_type() != menu)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool in_ot_programming_mode(struct aqualinkdata *aq_data)
|
||||
{
|
||||
//( type != AQ_SET_PUMP_RPM || type != AQ_SET_OT_MACRO )) {
|
||||
|
||||
if ( ( aq_data->active_thread.thread_id != 0 ) &&
|
||||
( aq_data->active_thread.ptype == AQ_SET_PUMP_RPM ||
|
||||
aq_data->active_thread.ptype == AQ_SET_OT_MACRO ||
|
||||
aq_data->active_thread.ptype == AQ_GET_OT_POOL_SPA_HEATER_TEMPS)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Return the digit at factor
|
||||
// num=12 factor=10 would return 2
|
||||
// num=12 factor=100 would return 1
|
||||
int digit(int num, int factor)
|
||||
{
|
||||
return ( (num % factor) - (num % (factor/10)) ) / (factor/10) ;
|
||||
}
|
||||
|
||||
// REturn the differance at a particular digit.
|
||||
// new=120, old=130, factor=100 return 2-3 = -1
|
||||
int digitDiff(int new, int old, int factor)
|
||||
{
|
||||
return ( digit(old, factor) - digit(new, factor) );
|
||||
}
|
||||
|
||||
bool intPress(int diff) {
|
||||
int i;
|
||||
unsigned char key = KEY_ONET_UP;
|
||||
|
||||
if (diff < 0) {
|
||||
diff = 0 - diff;
|
||||
key = KEY_ONET_DOWN;
|
||||
//printf ("**** Pressing down %d times\n",diff);
|
||||
} else {
|
||||
//printf ("**** Pressing UP %d times\n",diff);
|
||||
}
|
||||
|
||||
for (i=0; i < diff; i++) {
|
||||
send_ot_cmd(key);
|
||||
waitfor_ot_queue2empty();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
PROGRAMMING FUNCTIONS
|
||||
*/
|
||||
|
||||
void *set_aqualink_pump_rpm( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
char *buf = (char*)threadCtrl->thread_args;
|
||||
char VSPstr[20];
|
||||
int i, structIndex;
|
||||
|
||||
//printf("**** program string '%s'\n",buf);
|
||||
|
||||
int pumpIndex = atoi(&buf[0]);
|
||||
int pumpRPM = -1;
|
||||
//int pumpRPM = atoi(&buf[2]);
|
||||
for (structIndex=0; structIndex < aq_data->num_pumps; structIndex++) {
|
||||
if (aq_data->pumps[structIndex].pumpIndex == pumpIndex) {
|
||||
if (aq_data->pumps[structIndex].pumpType == PT_UNKNOWN) {
|
||||
logMessage(LOG_ERR, "Can't set Pump RPM/GPM until type is known\n");
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
pumpRPM = RPM_check(aq_data->pumps[structIndex].pumpType, atoi(&buf[2]), aq_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// NSF Should probably check pumpRPM is not -1 here
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_PUMP_RPM);
|
||||
|
||||
logMessage(LOG_NOTICE, "OneTouch Set Pump %d to RPM %d, from '%s'\n",pumpIndex,pumpRPM,buf);
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_EQUIPTMENT_ONOFF) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get Equiptment on/off menu\n");
|
||||
}
|
||||
|
||||
sprintf(VSPstr, "VSP%1d Spd Adj",pumpIndex);
|
||||
/*
|
||||
if ( (index = onetouch_menu_find_index(VSPstr)) != -1) {
|
||||
int cnt = index - onetouch_menu_hlightindex();
|
||||
for (i=0; i < cnt; i ++) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
waitfor_ot_queue2empty();
|
||||
}
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitForNextOT_Menu(aq_data);
|
||||
*/
|
||||
if ( select_onetouch_menu_item(aq_data, VSPstr) ) {
|
||||
if ( get_onetouch_memu_type() == OTM_SELECT_SPEED) {
|
||||
// Now fine menu item with X as last digit, and select that menu.
|
||||
//Pool X
|
||||
for (i=0; i < 12; i++) {
|
||||
if ( onetouch_menu_hlight()[15] != 'X' ) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||
} else {
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForNextOT_Menu(aq_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//OneTouch Menu Line 3 = set to 50 GPM
|
||||
//OneTouch Menu Line 3 = set to 1750 RPM
|
||||
if ( strstr(onetouch_menu_hlight(), "set to") != NULL ) {
|
||||
//printf("FOUND MENU")
|
||||
if (strstr(onetouch_menu_hlight(), "RPM") != NULL ) {
|
||||
// RPM 3450 & 600 max & min
|
||||
int RPM = ot_atoi(&onetouch_menu_hlight()[7]);
|
||||
intPress(digitDiff(RPM, pumpRPM, 10000));
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
intPress(digitDiff(RPM, pumpRPM, 1000));
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
intPress(digitDiff(RPM, pumpRPM, 100));
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
intPress(digitDiff(RPM, pumpRPM, 10));
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
// Reset the pump RPM
|
||||
aq_data->pumps[structIndex].rpm = RPM;
|
||||
} else if (strstr(onetouch_menu_hlight(), "GPM") != NULL ) {
|
||||
// GPM 130 max, GPM 15 min
|
||||
for (i=0; i < 24 ; i++) { // Max of 23 key presses to get from max to min
|
||||
int GPM = ot_atoi(&onetouch_menu_hlight()[8]);
|
||||
//printf ("*** GPM = %d | Setting to %d\n",GPM,pumpRPM);
|
||||
if ( GPM > pumpRPM ) {
|
||||
send_ot_cmd(KEY_ONET_DOWN);
|
||||
} else if (GPM < pumpRPM) {
|
||||
send_ot_cmd(KEY_ONET_UP);
|
||||
} else {
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
aq_data->pumps[structIndex].gpm = GPM;
|
||||
waitfor_ot_queue2empty();
|
||||
break;
|
||||
}
|
||||
waitfor_ot_queue2empty();
|
||||
// This really does slow it down, but we hit up.down once too ofter without it, need to fix.
|
||||
waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,5);
|
||||
// Reset the pump GPM
|
||||
aq_data->pumps[structIndex].rpm = GPM;
|
||||
//waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,5);
|
||||
//waitForNextOT_Menu(aq_data);
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer Not sure how to set '%s'\n",onetouch_menu_hlight());
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't select VSP\n");
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer Couldn't find Select Speed menu\n");
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer Couldn't find VSP in Equiptment on/off menu\n");
|
||||
}
|
||||
//printf( "Menu Index %d\n", onetouch_menu_find_index(VSPstr));
|
||||
|
||||
//printf("**** GOT THIS FAR, NOW LET'S GO BACK ****\n");
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get back to System menu\n");
|
||||
}
|
||||
|
||||
//printf("**** CLEAN EXIT ****\n");
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_macro( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
//sprintf(msg, "%-5d%-5d",index, (strcmp(value, "on") == 0)?ON:OFF);
|
||||
// Use above to set
|
||||
char *buf = (char*)threadCtrl->thread_args;
|
||||
unsigned int device = atoi(&buf[0]);
|
||||
unsigned int state = atoi(&buf[5]);
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_MACRO);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch Marco\n");
|
||||
|
||||
logMessage(LOG_ERR, "OneTouch Macro not implimented (device=%d|state=%d)\n",device,state);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *get_aqualink_onetouch_setpoints( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_ONETOUCH_SETPOINTS);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch get heater temps\n");
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_SET_TEMP) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get heater temp menu\n");
|
||||
}
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_FREEZE_PROTECT) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get freeze protect menu\n");
|
||||
}
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get back to System menu\n");
|
||||
}
|
||||
/*
|
||||
logMessage(LOG_DEBUG, "*** OneTouch device programmer TEST page down ***\n");
|
||||
goto_onetouch_menu(aq_data, OTM_SYSTEM_SETUP);
|
||||
highlight_onetouch_menu_item(aq_data, "About");
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForNextOT_Menu(aq_data);
|
||||
logMessage(LOG_DEBUG, "*** OneTouch device programmer END TEST page down ***\n");
|
||||
*/
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void set_aqualink_onetouch_heater_setpoint( struct aqualinkdata *aq_data, bool ispool, int val )
|
||||
{
|
||||
int cval;
|
||||
int diff;
|
||||
int i;
|
||||
int len;
|
||||
//char *st;
|
||||
unsigned char direction;
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_SET_TEMP) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get heater temp menu\n");
|
||||
}
|
||||
|
||||
if(ispool){
|
||||
if (!highlight_onetouch_menu_item(aq_data, "Pool Heat")) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get pool heater temp menu\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!highlight_onetouch_menu_item(aq_data, "Spa Heat")) {
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get spa heater temp menu\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
waitForOT_MessageTypes(aq_data,CMD_PDA_HIGHLIGHTCHARS,0x00,15); // CMD_PDA_0x04 is just a packer.
|
||||
|
||||
{
|
||||
char *st = onetouch_menu_hlightchars(&len);
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp highlighted='%.*s'\n", len, st);
|
||||
}
|
||||
|
||||
cval = atoi(onetouch_menu_hlightchars(&len));
|
||||
diff = val - cval;
|
||||
if (diff > 0) {
|
||||
direction = KEY_ONET_UP;
|
||||
} else if (diff < 0) {
|
||||
direction = KEY_ONET_DOWN;
|
||||
diff=-diff;
|
||||
}
|
||||
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp diff='%d'\n", diff);
|
||||
|
||||
for (i=0; i < diff; i++) {
|
||||
send_ot_cmd(direction);
|
||||
waitfor_ot_queue2empty();
|
||||
}
|
||||
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
send_ot_cmd(KEY_ONET_BACK);
|
||||
waitfor_ot_queue2empty();
|
||||
|
||||
/*
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp line='%s'\n", onetouch_menu_line(line));
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp highlight='%d'\n", onetouch_menu_hlightindex());
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp highlightline='%s'\n", onetouch_menu_line(onetouch_menu_hlightindex()));
|
||||
logMessage(LOG_DEBUG, "** OneTouch set heater temp highlightchars='%s'\n", onetouch_menu_hlight());
|
||||
*/
|
||||
//onetouch_menu_line(line)
|
||||
//onetouch_menu_hlightindex
|
||||
//onetouch_menu_hlight
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_pool_heater_temp( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_POOL_HEATER_TEMP);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
val = setpoint_check(POOL_HTR_SETOINT, val, aq_data);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch set pool heater temp to %d\n", val);
|
||||
set_aqualink_onetouch_heater_setpoint(aq_data, true, val);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_spa_heater_temp( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_SPA_HEATER_TEMP);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
val = setpoint_check(SPA_HTR_SETOINT, val, aq_data);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch set spa heater temp to %d\n", val);
|
||||
set_aqualink_onetouch_heater_setpoint(aq_data, false, val);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_boost( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_BOOST);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch request set Boost to '%d'\n",val==true?"On":"Off");
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_BOOST) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get BOOST menu\n");
|
||||
} else {
|
||||
if ( ot_strcmp(onetouch_menu_hlight(), "Start") == 0 ) {
|
||||
if (val) {
|
||||
logMessage(LOG_DEBUG, "OneTouch Boost is Off, turning On\n");
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
} else {
|
||||
logMessage(LOG_INFO, "OneTouch Boost is Off, ignore request\n");
|
||||
}
|
||||
} else if ( ot_strcmp(onetouch_menu_hlight(), "Pause") == 0 ) {
|
||||
if (! val) {
|
||||
logMessage(LOG_DEBUG, "OneTouch set Boost is ON, turning Off\n");
|
||||
highlight_onetouch_menu_item(aq_data, "Stop");
|
||||
send_ot_cmd(KEY_ONET_SELECT);
|
||||
waitfor_ot_queue2empty();
|
||||
// Takes ages to see bost is off from menu, to set it here.
|
||||
aq_data->boost = false;
|
||||
aq_data->boost_msg[0] = '\0';
|
||||
aq_data->swg_percent = 0;
|
||||
} else {
|
||||
logMessage(LOG_INFO, "OneTouch Boost is On, ignore request\n");
|
||||
}
|
||||
} else {
|
||||
logMessage(LOG_ERR, "OneTouch Boost unknown menu\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get back to System menu\n");
|
||||
}
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_swg_percent( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_SWG_PERCENT);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch set SWG Percent\n");
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_SET_AQUAPURE) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get Aquapure menu\n");
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get back to System menu\n");
|
||||
}
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_freezeprotect( void *ptr )
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *set_aqualink_onetouch_time( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_ONETOUCH_TIME);
|
||||
|
||||
logMessage(LOG_DEBUG, "OneTouch set time\n");
|
||||
|
||||
if ( !goto_onetouch_menu(aq_data, OTM_SET_TIME) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer failed to get time menu\n");
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if (! goto_onetouch_menu(aq_data, OTM_SYSTEM) ){
|
||||
logMessage(LOG_ERR, "OneTouch device programmer didn't get back to System menu\n");
|
||||
}
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
|
||||
// just stop compiler error, ptr is not valid as it's just been freed
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef ONETOUCH_AQ_PROGRAMMER_H_
|
||||
#define ONETOUCH_AQ_PROGRAMMER_H_
|
||||
|
||||
unsigned char pop_ot_cmd(unsigned char receive_type);
|
||||
bool ot_queue_cmd(unsigned char cmd);
|
||||
|
||||
//bool in_ot_programming_mode(struct aqualinkdata *aq_data);
|
||||
|
||||
void *set_aqualink_pump_rpm( void *ptr );
|
||||
void *set_aqualink_onetouch_macro( void *ptr );
|
||||
void *get_aqualink_onetouch_setpoints( void *ptr );
|
||||
void *set_aqualink_onetouch_spa_heater_temp( void *ptr );
|
||||
void *set_aqualink_onetouch_pool_heater_temp( void *ptr );
|
||||
void *set_aqualink_onetouch_swg_percent( void *ptr );
|
||||
void *set_aqualink_onetouch_boost( void *ptr );
|
||||
void *set_aqualink_onetouch_time( void *ptr );
|
||||
void *set_aqualink_onetouch_freezeprotect( void *ptr );
|
||||
|
||||
#endif // ONETOUCH_AQ_PROGRAMMER_H_
|
||||
|
|
@ -11,7 +11,7 @@ static FILE *_byteLogFile = NULL;
|
|||
static bool _log2file = false;
|
||||
static bool _includePentair = false;
|
||||
|
||||
void _logPacket(unsigned char *packet_buffer, int packet_length, bool error);
|
||||
void _logPacket(unsigned char *packet_buffer, int packet_length, bool error, bool force);
|
||||
|
||||
void startPacketLogger(bool debug_RSProtocol_packets, bool read_pentair_packets) {
|
||||
_log2file = debug_RSProtocol_packets;
|
||||
|
|
@ -37,17 +37,21 @@ void writePacketLog(char *buffer) {
|
|||
}
|
||||
|
||||
void logPacket(unsigned char *packet_buffer, int packet_length) {
|
||||
_logPacket(packet_buffer, packet_length, false);
|
||||
_logPacket(packet_buffer, packet_length, false, false);
|
||||
}
|
||||
|
||||
void logPacketError(unsigned char *packet_buffer, int packet_length) {
|
||||
_logPacket(packet_buffer, packet_length, true);
|
||||
_logPacket(packet_buffer, packet_length, true, false);
|
||||
}
|
||||
|
||||
void _logPacket(unsigned char *packet_buffer, int packet_length, bool error)
|
||||
void debuglogPacket(unsigned char *packet_buffer, int packet_length) {
|
||||
_logPacket(packet_buffer, packet_length, false, true);
|
||||
}
|
||||
|
||||
void _logPacket(unsigned char *packet_buffer, int packet_length, bool error, bool force)
|
||||
{
|
||||
// No point in continuing if loglevel is < debug_serial and not writing to file
|
||||
if ( error == false && getLogLevel() < LOG_DEBUG_SERIAL && _log2file == false)
|
||||
if ( force == false && error == false && getLogLevel() < LOG_DEBUG_SERIAL && _log2file == false)
|
||||
return;
|
||||
|
||||
char buff[1000];
|
||||
|
|
@ -70,8 +74,12 @@ void _logPacket(unsigned char *packet_buffer, int packet_length, bool error)
|
|||
|
||||
if (error == true)
|
||||
logMessage(LOG_WARNING, "%s", buff);
|
||||
else
|
||||
logMessage(LOG_DEBUG_SERIAL, "%s", buff);
|
||||
else {
|
||||
if (force)
|
||||
logMessage(LOG_DEBUG, "%s", buff);
|
||||
else
|
||||
logMessage(LOG_DEBUG_SERIAL, "%s", buff);
|
||||
}
|
||||
}
|
||||
|
||||
//#define RAW_BUFFER_SIZE 100
|
||||
|
|
|
|||
|
|
@ -13,5 +13,8 @@ void logPacket(unsigned char *packet_buffer, int packet_length);
|
|||
void logPacketError(unsigned char *packet_buffer, int packet_length);
|
||||
void logPacketByte(unsigned char *byte);
|
||||
|
||||
// Only use for manual debugging
|
||||
void debuglogPacket(unsigned char *packet_buffer, int packet_length);
|
||||
|
||||
|
||||
#endif //PACKETLOGGER_H_
|
||||
15
pda.c
15
pda.c
|
|
@ -43,11 +43,11 @@ static bool _initWithRS = false;
|
|||
|
||||
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
static struct aqconfig *_aqualink_config;
|
||||
void init_pda(struct aqualinkdata *aqdata, struct aqconfig *aqconfig)
|
||||
//static struct aqconfig *_aqconfig_;
|
||||
void init_pda(struct aqualinkdata *aqdata)
|
||||
{
|
||||
_aqualink_data = aqdata;
|
||||
_aqualink_config = aqconfig;
|
||||
//_aqconfig_ = aqconfig;
|
||||
set_pda_mode(true);
|
||||
}
|
||||
#else
|
||||
|
|
@ -491,7 +491,7 @@ void process_pda_packet_msg_long_level_aux_device(const char *msg)
|
|||
int li=-1;
|
||||
char *str, *label;
|
||||
|
||||
if (! _aqualink_config->use_panel_aux_labels)
|
||||
if (! _aqconfig_->use_panel_aux_labels)
|
||||
return;
|
||||
// NSF Need to check config for use_panel_aux_labels value and ignore if not set
|
||||
|
||||
|
|
@ -686,10 +686,11 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
{
|
||||
_initWithRS = true;
|
||||
logMessage(LOG_DEBUG, "**** PDA INIT ****");
|
||||
aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
||||
//aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
||||
queueGetProgramData(AQUAPDA, _aqualink_data);
|
||||
delay(50); // Make sure this one runs first.
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
if (_aqualink_config->use_panel_aux_labels)
|
||||
if (_aqconfig_->use_panel_aux_labels)
|
||||
aq_programmer(AQ_GET_AUX_LABELS, NULL, _aqualink_data);
|
||||
#endif
|
||||
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
||||
|
|
@ -707,7 +708,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
packet[PKT_CMD] == CMD_PDA_HIGHLIGHTCHARS)
|
||||
{
|
||||
// We processed the next message, kick any threads waiting on the message.
|
||||
kick_aq_program_thread(_aqualink_data);
|
||||
kick_aq_program_thread(_aqualink_data, AQUAPDA);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ bool processiAqualinkMsg(unsigned char *packet_buffer, int packet_length, struct
|
|||
|
||||
pumpIndex = atoi((char *) &lastmessage[14]);
|
||||
|
||||
if ( pumpIndex < MAX_PUMPS && pumpIndex < 0) {
|
||||
if ( pumpIndex < aqdata->num_pumps && pumpIndex < 0) {
|
||||
pumpIndex = 1;
|
||||
logMessage(LOG_ERR, "Can't find pump index for messsage '%.*s' in string '%.*s' using %d\n",AQ_MSGLEN, packet_buffer+4, AQ_MSGLEN, lastmessage, pumpIndex);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -64,6 +64,17 @@ report_zero_pool_temp = no
|
|||
# You can use 0x00 and AqualinkD will find an ID for you, but this makes a slow startup
|
||||
device_id=0x0a
|
||||
|
||||
# The ID for extended settings, These are ONE TOUCH MACROS & VARIABLE SPEED PUMP RPM
|
||||
# Do not enable this if you don't use either, you'll just waste memory and cpu cycles
|
||||
# Valid ID's are 0x40, 0x41, 0x42 & 0x43.
|
||||
# If you have a one touch remote do not use Ox40
|
||||
#extended_device_id=0x41
|
||||
|
||||
# If you have extended_device_id set, then you can also use that ID for programming some features.
|
||||
# This means that you can turn things on/off while AqualinkD is programming certian features.
|
||||
# At the moment only heater setpoints & swg boost is on the extended device programming
|
||||
#extended_device_id_programming = yes
|
||||
|
||||
# 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
|
||||
|
|
@ -127,18 +138,23 @@ use_panel_aux_labels=no
|
|||
# Simply change these to your setup, comment out ones that ent in _dzidx if you don't use Domoticz.
|
||||
# If using PDA mode, PDA Labels below are of the utmost importance, the PDA labels MUST match the labels in the "EQUIPTMENT ON/OFF" menu of the PDA device.
|
||||
#
|
||||
# Optional, If you have a Variable Speed Pump, then assign the RS485 ID to the button below so RPM/GPH/WATTS are displayed
|
||||
# Optional, ( button_01_pumpID & button_01_pumpIndex )
|
||||
# If you have a Variable Speed Pump, then assign the RS485 ID to the button below so RPM/GPH/WATTS are displayed
|
||||
# Format is button_01_pumpID=0x60. Leave blank if you don't have a VSP.
|
||||
# Pentair pump ID's
|
||||
# 0x60 to 0x6F (0x60, 0x61 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F)
|
||||
# Jandy pump ID's
|
||||
# 0x78, 0x79, 0x7A, 0x7B
|
||||
#
|
||||
# button_01_pumpIndex=1
|
||||
# If you have assigned this pump an index number in your Aqualink control panel, (Between 1 & 4), put it here for VSP, RPM, Primp information to be captured.
|
||||
|
||||
# Labels for standard butons (shown in web UI), and domoticz idx's
|
||||
button_01_label=Filter Pump
|
||||
#button_01_dzidx=37
|
||||
#button_01_PDA_label=FILTER PUMP
|
||||
#button_01_pumpID=0x60
|
||||
#button_01_pumpIndex=1
|
||||
|
||||
button_02_label=Spa Mode
|
||||
#button_02_dzidx=38
|
||||
|
|
@ -151,7 +167,8 @@ button_03_label=Cleaner
|
|||
button_04_label=Waterfall
|
||||
#button_04_dzidx=40
|
||||
#button_04_PDA_label=AUX2
|
||||
#button_01_pumpID=0x61
|
||||
#button_04_pumpID=0x61
|
||||
#button_04_pumpIndex=2
|
||||
|
||||
button_05_label=Spa Blower
|
||||
#button_05_dzidx=41
|
||||
|
|
|
|||
|
|
@ -38,42 +38,19 @@ 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 "AqualinkD config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG"
|
||||
echo "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 "AqualinkD defaults exists, did not copy new defaults to $DEFLocation/$DEF"
|
||||
echo "Defaults exists, did not copy new defaults to $DEFLocation/$DEF"
|
||||
else
|
||||
cp $BUILD/$DEF.defaults $DEFLocation/$DEF
|
||||
fi
|
||||
|
|
@ -93,7 +70,7 @@ if [ ! -d "$WEBLocation" ]; then
|
|||
fi
|
||||
|
||||
if [ -f "$WEBLocation/config.js" ]; then
|
||||
echo "AqualinkD web config exists, did not copy new config, you may need to edit existing $WEBLocation/config.js "
|
||||
echo "$WEBLocation/config.js exists, did not copy overight, please make sure to update manually"
|
||||
rsync -avq --exclude='config.js' $BUILD/../web/* $WEBLocation
|
||||
else
|
||||
cp -r $BUILD/../web/* $WEBLocation
|
||||
|
|
@ -106,7 +83,5 @@ 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
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -28,11 +28,12 @@
|
|||
|
||||
#include "aq_serial.h"
|
||||
#include "utils.h"
|
||||
#include "packetLogger.h"
|
||||
|
||||
#define SLOG_MAX 80
|
||||
#define PACKET_MAX 600
|
||||
|
||||
#define VERSION "serial_logger V1.1"
|
||||
#define VERSION "serial_logger V1.2"
|
||||
|
||||
/*
|
||||
typedef enum used {
|
||||
|
|
@ -51,6 +52,7 @@ bool _keepRunning = true;
|
|||
|
||||
unsigned char _goodID[] = {0x0a, 0x0b, 0x08, 0x09};
|
||||
unsigned char _goodPDAID[] = {0x60, 0x61, 0x62, 0x63};
|
||||
unsigned char _goodONETID[] = {0x40, 0x41, 0x42, 0x43};
|
||||
unsigned char _filter[10];
|
||||
int _filters=0;
|
||||
bool _rawlog=false;
|
||||
|
|
@ -67,7 +69,7 @@ void intHandler(int dummy) {
|
|||
#define SWG " <-- Salt Water Generator (Aquarite mode)"
|
||||
#define KEYPAD " <-- RS Keypad"
|
||||
#define SPA_R " <-- Spa remote"
|
||||
#define AQUA " <-- Aqualink (iAqualink?)"
|
||||
#define AQUA " <-- Aqualink (iAqualink / Touch)"
|
||||
#define HEATER " <-- LX Heater"
|
||||
#define ONE_T " <-- Onetouch device"
|
||||
#define PC_DOCK " <-- PC Interface (RS485 to RS232)"
|
||||
|
|
@ -152,6 +154,10 @@ bool canUse(unsigned char ID) {
|
|||
if (ID == _goodPDAID[i])
|
||||
return true;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ID == _goodONETID[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
char* canUseExtended(unsigned char ID) {
|
||||
|
|
@ -164,6 +170,10 @@ char* canUseExtended(unsigned char ID) {
|
|||
if (ID == _goodPDAID[i])
|
||||
return " <-- can use for Aqualinkd (PDA mode only)";
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ID == _goodONETID[i])
|
||||
return " <-- can use for Aqualinkd (Extended Device ID)";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +259,7 @@ int main(int argc, char *argv[]) {
|
|||
int received_packets = 0;
|
||||
int logPackets = PACKET_MAX;
|
||||
int logLevel = LOG_NOTICE;
|
||||
bool rsRawDebug = false;
|
||||
//bool playback_file = false;
|
||||
|
||||
//int logLevel;
|
||||
|
|
@ -264,7 +275,14 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if (argc < 2 || access( argv[1], F_OK ) == -1 ) {
|
||||
fprintf(stderr, "ERROR, first param must be valid serial port, ie:-\n\t%s /dev/ttyUSB0\n\n", argv[0]);
|
||||
fprintf(stderr, "Optional parameters are -d (debug) & -p <number> (log # packets) & -i <ID> & -r (raw) ie:=\n\t%s /dev/ttyUSB0 -d -p 1000 -i 0x08\n\n", argv[0]);
|
||||
//fprintf(stderr, "Optional parameters are -d (debug) & -p <number> (log # packets) & -i <ID> & -r (raw) ie:=\n\t%s /dev/ttyUSB0 -d -p 1000 -i 0x08\n\n", argv[0]);
|
||||
fprintf(stderr, "Optional parameters are :-\n");
|
||||
fprintf(stderr, "\t-d (debug)\n");
|
||||
fprintf(stderr, "\t-p <number> (log # packets)\n");
|
||||
fprintf(stderr, "\t-i <ID> (just log these ID's, can use multiple -i)\n");
|
||||
fprintf(stderr, "\t-r (raw)\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;
|
||||
}
|
||||
|
||||
|
|
@ -286,6 +304,8 @@ int main(int argc, char *argv[]) {
|
|||
logLevel = LOG_DEBUG;
|
||||
} else if (strcmp(argv[i], "-f") == 0) {
|
||||
_playback_file = true;
|
||||
} else if (strcmp(argv[i], "-rsrd") == 0) {
|
||||
rsRawDebug = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +335,10 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
//packet_length = get_packet(rs_fd, packet_buffer);
|
||||
packet_length = get_packet(rs_fd, packet_buffer);
|
||||
if (rsRawDebug)
|
||||
packet_length = get_packet_lograw(rs_fd, packet_buffer);
|
||||
else
|
||||
packet_length = get_packet(rs_fd, packet_buffer);
|
||||
|
||||
if (packet_length == -1) {
|
||||
// Unrecoverable read error. Force an attempt to reconnect.
|
||||
|
|
@ -401,6 +424,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if (sindex >= SLOG_MAX)
|
||||
logMessage(LOG_ERR, "Ran out of storage, some ID's were not captured, please increase SLOG_MAX and recompile\n");
|
||||
|
||||
logMessage(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",
|
||||
|
|
|
|||
10
utils.c
10
utils.c
|
|
@ -87,6 +87,14 @@ void startInlineDebug()
|
|||
_log_filename = DEFAULT_LOG_FILE;
|
||||
}
|
||||
|
||||
void startInlineSerialDebug()
|
||||
{
|
||||
_log_level = LOG_DEBUG_SERIAL;
|
||||
_log2file = true;
|
||||
if (_log_filename == NULL)
|
||||
_log_filename = DEFAULT_LOG_FILE;
|
||||
}
|
||||
|
||||
void stopInlineDebug()
|
||||
{
|
||||
_log_level = _cfg_log_level;
|
||||
|
|
@ -343,7 +351,7 @@ void logMessage(int msg_level, char *format, ...)
|
|||
strncpy(buffer, " ", 8);
|
||||
vsprintf (&buffer[8], format, args);
|
||||
va_end(args);
|
||||
|
||||
|
||||
//test(msg_level, buffer);
|
||||
//fprintf (stderr, buffer);
|
||||
|
||||
|
|
|
|||
1
utils.h
1
utils.h
|
|
@ -56,6 +56,7 @@ char *prittyString(char *str);
|
|||
//void writePacketLog(char *buff);
|
||||
//void closePacketLog();
|
||||
void startInlineDebug();
|
||||
void startInlineSerialDebug();
|
||||
void stopInlineDebug();
|
||||
void cleanInlineDebug();
|
||||
char *getInlineLogFName();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
#define AQUALINKD_NAME "Aqualink Daemon"
|
||||
#define AQUALINKD_VERSION "1.3.9c"
|
||||
#define AQUALINKD_VERSION "2.0.0a"
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@
|
|||
// 0 means only load once when page loads.
|
||||
//var background_reload = 10;
|
||||
|
||||
// By default all Variable Speed Pumps will show RPM.
|
||||
// this will show GPM on VSP's that you can only set GPM (ie Jandy VF pumps)
|
||||
//var show_vsp_gpm=false;
|
||||
|
||||
var body_background = "#EBEBEA";
|
||||
var body_text = "#000000";
|
||||
|
||||
|
|
|
|||
|
|
@ -469,6 +469,12 @@
|
|||
var _aqualink_data;
|
||||
var _landscape = false;
|
||||
var _displayNames = [];
|
||||
|
||||
if (typeof show_vsp_gpm !== 'undefined' && show_vsp_gpm == false)
|
||||
var _show_vsp_gpm=false;
|
||||
else
|
||||
var _show_vsp_gpm=true;
|
||||
|
||||
//init();
|
||||
function init() {
|
||||
setSizeSpecifics();
|
||||
|
|
@ -476,6 +482,7 @@
|
|||
document.getElementById('thermostat_options').classList.remove("hide");
|
||||
document.getElementById('swg_options').classList.remove("hide");
|
||||
document.getElementById('pswitch_options').classList.remove("hide");
|
||||
document.getElementById('vspswitch_options').classList.remove("hide");
|
||||
setColors();
|
||||
load_background();
|
||||
showTileOptions(false);
|
||||
|
|
@ -714,10 +721,13 @@
|
|||
subdiv.setAttribute('id', id + '_status');
|
||||
subdiv.textContent = formatSatus(status);
|
||||
div.appendChild(subdiv);
|
||||
if (type == "switch" && subtype != "switch_program") {
|
||||
if (type == "switch" && (subtype != "switch_program" && subtype != "switch_vsp") ) {
|
||||
//if (type == "switch" && subtype != "switch_program" ) {
|
||||
div.setAttribute('onclick', "switchTileState('" + id + "')");
|
||||
//console.log("add onclick switchtilestate to "+id);
|
||||
} else /*if (id != "SWG/Percent")*/ {
|
||||
add_clickEvent(div, id);
|
||||
//console.log("add click Event to "+id);
|
||||
}
|
||||
}
|
||||
document.getElementById('wrapper').appendChild(div);
|
||||
|
|
@ -735,9 +745,9 @@
|
|||
try {
|
||||
if (state == (document.getElementById(id).getAttribute('status') == 'off')) {
|
||||
send_command(id);
|
||||
console.log("Switch state "+id+" to "+(state)?"on":"off");
|
||||
//console.log("Switch state "+id+" to "+(state)?"on":"off");
|
||||
} else {
|
||||
console.log("state "+id+" to "+(state)?"on":"off")
|
||||
//console.log("state "+id+" to "+(state)?"on":"off")
|
||||
}
|
||||
setTileOn(id, ((state) ? "on" : "off"));
|
||||
} catch(exception) {}
|
||||
|
|
@ -866,10 +876,10 @@
|
|||
text = 'Generating';
|
||||
}
|
||||
else if (type == 'setpoint_thermo')
|
||||
if (status == 'enabled')
|
||||
//if (status == 'enabled')
|
||||
text = 'Heat to ' + tile.getAttribute('setpoint');
|
||||
else
|
||||
text = 'Heating to ' + tile.getAttribute('setpoint');
|
||||
//else
|
||||
// text = 'Heating to ' + tile.getAttribute('setpoint'); // too large for phone
|
||||
else if (type == 'setpoint_freeze')
|
||||
text = 'Turn on ' + tile.getAttribute('setpoint') + "°";
|
||||
//else
|
||||
|
|
@ -921,12 +931,42 @@
|
|||
if (typeof devices !== 'undefined' && devices.indexOf(object.id) < 0) {
|
||||
return;
|
||||
}
|
||||
if (object.type == 'switch' || object.type == 'switch_program') {
|
||||
//if (object.type == 'switch' || object.type == 'switch_program') {
|
||||
if (object.type == 'switch') {
|
||||
var img = object.id.replace('/', '_');
|
||||
add_tile(object.id, object.name, object.state, 'switch', object.type, 'hk/' + img + '-off.png', 'hk/' + img + '-on.png');
|
||||
var ext_type;
|
||||
if (typeof object.type_ext !== 'undefined')
|
||||
ext_type = object.type_ext;
|
||||
else
|
||||
ext_type = object.type;
|
||||
|
||||
add_tile(object.id, object.name, object.state, 'switch', ext_type, 'hk/' + img + '-off.png', 'hk/' + img + '-on.png');
|
||||
setTileOn(object.id, object.status, null);
|
||||
if (typeof object.Pump_RPM !== 'undefined' && object.Pump_RPM) {
|
||||
setTileOnText(object.id, 'RPM:'+object.Pump_RPM);
|
||||
if (typeof object.type_ext !== 'undefined' && object.type_ext == 'switch_vsp') {
|
||||
if (typeof object.Pump_RPM !== 'undefined' && object.Pump_RPM) {
|
||||
if (object.Pump_RPM == -2) {
|
||||
setTileOnText(object.id, 'Pump Offline'); // Small txt
|
||||
document.getElementById(object.id).setAttribute('setpoint', 0);
|
||||
} else if (object.Pump_RPM == -1) {
|
||||
setTileOnText(object.id, 'Pump Priming'); // Small text
|
||||
document.getElementById(object.id).setAttribute('setpoint', 0);
|
||||
} else {
|
||||
if (object.Pump_Type == "vfPump") {
|
||||
if (_show_vsp_gpm == true)
|
||||
setTileOnText(object.id, 'GPM:'+object.Pump_GPM);
|
||||
else
|
||||
setTileOnText(object.id, 'RPM:'+object.Pump_RPM);
|
||||
|
||||
document.getElementById(object.id).setAttribute('setpoint', object.Pump_GPM);
|
||||
} else {
|
||||
setTileOnText(object.id, 'RPM:'+object.Pump_RPM);
|
||||
document.getElementById(object.id).setAttribute('setpoint', object.Pump_RPM);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof object.Pump_Type !== 'undefined') {
|
||||
document.getElementById(object.id).setAttribute('pumptype', object.Pump_Type);
|
||||
}
|
||||
}
|
||||
} else if (object.type == 'value' || object.type == 'temperature') {
|
||||
add_tile(object.id, object.name, object.state, 'value', object.type);
|
||||
|
|
@ -942,6 +982,7 @@
|
|||
}
|
||||
|
||||
function showTileOptions(show, id, contex) {
|
||||
console.log("showTileOptions " + show + " "+id+" "+contex);
|
||||
var active_option;
|
||||
if (show == true) {
|
||||
var wrapH = document.getElementById('wrapper').clientHeight + 'px';
|
||||
|
|
@ -949,14 +990,22 @@
|
|||
active_option = document.getElementById('thermostat_options');
|
||||
document.getElementById('swg_options').style.display = 'none';
|
||||
document.getElementById('pswitch_options').style.display = 'none';
|
||||
document.getElementById('vspswitch_options').style.display = 'none';
|
||||
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_program') {
|
||||
active_option = document.getElementById('pswitch_options');
|
||||
document.getElementById('thermostat_options').style.display = 'none';
|
||||
document.getElementById('swg_options').style.display = 'none';
|
||||
} else /*if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg')*/ {
|
||||
document.getElementById('vspswitch_options').style.display = 'none';
|
||||
} else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg') {
|
||||
active_option = document.getElementById('swg_options');
|
||||
document.getElementById('thermostat_options').style.display = 'none';
|
||||
document.getElementById('pswitch_options').style.display = 'none';
|
||||
document.getElementById('vspswitch_options').style.display = 'none';
|
||||
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_vsp') {
|
||||
active_option = document.getElementById('vspswitch_options');
|
||||
document.getElementById('thermostat_options').style.display = 'none';
|
||||
document.getElementById('pswitch_options').style.display = 'none';
|
||||
document.getElementById('swg_options').style.display = 'none';
|
||||
}
|
||||
active_option.style.display = 'flex';
|
||||
var optionH = window.getComputedStyle(active_option, null).getPropertyValue("height");
|
||||
|
|
@ -974,10 +1023,13 @@
|
|||
document.getElementById("swg_options_close").click();
|
||||
else if (document.getElementById('pswitch_options').style.display == 'flex')
|
||||
document.getElementById("pswitch_options_close").click();
|
||||
else if (document.getElementById('vspswitch_options').style.display == 'flex')
|
||||
document.getElementById("vspswitch_options").click();
|
||||
}
|
||||
document.getElementById('thermostat_options').style.display = 'none';
|
||||
document.getElementById('swg_options').style.display = 'none';
|
||||
document.getElementById('pswitch_options').style.display = 'none';
|
||||
document.getElementById('vspswitch_options').style.display = 'none';
|
||||
document.getElementById('wrapper').classList.remove("opaque");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1011,6 +1063,12 @@
|
|||
title = document.getElementById("pswitch_option_title");
|
||||
close_button = document.getElementById("pswitch_options_close");
|
||||
//ext = '°' + _temperature_units;
|
||||
} else if (type == 'switch_vsp') {
|
||||
slider = document.getElementById("vspoption_slider_range");
|
||||
slider_output = document.getElementById("vspoption_slider_text_value");
|
||||
title = document.getElementById("vspswitch_option_title");
|
||||
close_button = document.getElementById("vspswitch_option_close");
|
||||
//ext = '°' + _temperature_units;
|
||||
} else {
|
||||
slider = document.getElementById("option_slider_range");
|
||||
slider_output = document.getElementById("option_slider_text_value");
|
||||
|
|
@ -1042,6 +1100,18 @@
|
|||
slider.max = 40;
|
||||
slider.step = 1;
|
||||
}
|
||||
} else if (type == 'switch_vsp') {
|
||||
if ( tile.getAttribute('pumptype') == "vfPump" ) { // RPM vs GPM
|
||||
slider.min = 15;
|
||||
slider.max = 130;
|
||||
slider.step = 5;
|
||||
ext = ' GPM';
|
||||
} else {
|
||||
slider.min = 600;
|
||||
slider.max = 3450;
|
||||
slider.step = 5;
|
||||
ext = ' RPM';
|
||||
}
|
||||
}
|
||||
title.innerHTML = document.getElementById(id + '_name').innerHTML;
|
||||
if (type == 'switch_program') {
|
||||
|
|
@ -1070,6 +1140,21 @@
|
|||
oswitch_output.innerHTML = ((oswitch.checked) ? "Boost On" : "Boost Off");
|
||||
//setTileOn(id, ((oswitch.checked)?"on":"off"), null);
|
||||
}
|
||||
} else if (type == 'switch_vsp') {
|
||||
slider.value = sp_value;
|
||||
oswitch = document.getElementById("vspoption_switch");
|
||||
oswitch.checked = tile_state;
|
||||
var oswitch_output = document.getElementById("vspoption_switch_text_value");
|
||||
slider_output.innerHTML = slider.value + ext;
|
||||
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
|
||||
slider.oninput = function() {
|
||||
slider_output.innerHTML = this.value + ext;
|
||||
//sp_value = this.value
|
||||
}
|
||||
oswitch.onclick = function() {
|
||||
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
|
||||
//setTileOn(id, ((oswitch.checked)?"on":"off"), null);
|
||||
}
|
||||
} else {
|
||||
slider.value = sp_value;
|
||||
oswitch = document.getElementById("option_switch");
|
||||
|
|
@ -1133,6 +1218,12 @@
|
|||
if (sp_value != slider.value && slider.value != 101) // Don't change setpoint if slider is on boost
|
||||
setThermostatSetpoint(id, slider.value);
|
||||
}
|
||||
} else if (type == 'switch_program') {
|
||||
var value = slider.value;
|
||||
if (state == (tile.getAttribute('status') == 'off'))
|
||||
setTileState(id, state);
|
||||
if (sp_value != slider.value)
|
||||
setThermostatSetpoint(id, slider.value)
|
||||
} else {
|
||||
var value = slider.value;
|
||||
if (state == (tile.getAttribute('status') == 'off'))
|
||||
|
|
@ -1215,7 +1306,24 @@
|
|||
while (i < 5) {
|
||||
//console.log(data["Pump_"+i].RPM);
|
||||
if ((typeof data["Pump_"+i] !== 'undefined') && (typeof data["Pump_"+i].RPM !== 'undefined')) {
|
||||
setTileOnText(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM);
|
||||
if (data["Pump_"+i].RPM == -2) {
|
||||
setTileOnText(data["Pump_"+i].id, 'Pump Offline');
|
||||
} else if (data["Pump_"+i].RPM == -1) {
|
||||
setTileOnText(data["Pump_"+i].id, 'Pump Priming');
|
||||
} else {
|
||||
//setTileOnText(object.id, 'RPM:'+object.Pump_RPM);
|
||||
if (data["Pump_"+i].Pump_Type == "vfPump") {
|
||||
if (_show_vsp_gpm == true)
|
||||
setTileOnText(data["Pump_"+i].id, 'GPM:'+data["Pump_"+i].GPM);
|
||||
else
|
||||
setTileOnText(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM);
|
||||
|
||||
document.getElementById(data["Pump_"+i].id).setAttribute('setpoint', data["Pump_"+i].GPM);
|
||||
} else {
|
||||
document.getElementById(data["Pump_"+i].id).setAttribute('setpoint', data["Pump_"+i].RPM);
|
||||
setTileOnText(data["Pump_"+i].id, 'RPM:'+data["Pump_"+i].RPM);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (document.getElementById(data["Pump_"+i].id).getAttribute('status') == 'on')
|
||||
document.getElementById(data["Pump_"+i].id + '_status').innerHTML = 'RPM:'+data["Pump_"+i].RPM;
|
||||
|
|
@ -1247,8 +1355,12 @@
|
|||
createTile(data['devices'][obj]);
|
||||
} else {
|
||||
//console.log("old type "+document.getElementById(data['devices'][obj].id).getAttribute('type')+" | new "+data['devices'][obj].type);
|
||||
if (document.getElementById(data['devices'][obj].id).getAttribute('type') != data['devices'][obj].type) {
|
||||
//console.log("Remove and create "+data['devices'][obj].id);
|
||||
var element_type = document.getElementById(data['devices'][obj].id).getAttribute('type');
|
||||
|
||||
if ( (element_type != data['devices'][obj].type) &&
|
||||
(typeof data['devices'][obj].type_ext !== 'undefined' && element_type != data['devices'][obj].type_ext ) ) {
|
||||
console.log("Remove and create "+data['devices'][obj].id);
|
||||
console.log("Old type "+element_type+" | new type "+data['devices'][obj].type+" sub "+data['devices'][obj].type_ext);
|
||||
var element = document.getElementById(data['devices'][obj].id);
|
||||
element.parentNode.removeChild(element);
|
||||
createTile(data['devices'][obj]);
|
||||
|
|
@ -1335,8 +1447,10 @@
|
|||
if ((tile = document.getElementById(id)) == null) {
|
||||
return;
|
||||
}
|
||||
if (tile.getAttribute('setpoint'))
|
||||
temperature.parameter = tile.getAttribute('id');
|
||||
temperature.value = tile.getAttribute('setpoint');
|
||||
//console.log("Send value back "+temperature.parameter+" "+temperature.value);
|
||||
socket_di.send(JSON.stringify(temperature));
|
||||
}
|
||||
|
||||
|
|
@ -1516,6 +1630,42 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id='vspswitch_options' class='options hide'>
|
||||
<div id='vspswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'>
|
||||
<table border='0' cellpadding='10px'>
|
||||
<tr class='options_title'>
|
||||
<th colspan='2'><span id="vspswitch_option_title"></span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align='right' width='50%'><span class="option_text" id='vspoption_switch_text_value'></span>
|
||||
</td>
|
||||
<td align='left' width='50%'>
|
||||
<label class="option_switch">
|
||||
<input type="checkbox" id='vspoption_switch'>
|
||||
<span class="option_switch_slide"></span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' align='center'><span class="option_text" id="vspoption_slider_text_value"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<div class="slidecontainer">
|
||||
<input type="range" class="option_slider" id='vspoption_slider_range'>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' align='center'>
|
||||
<input type="button" value="close" id='vspswitch_option_close' class='options_button'>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ Button style taken from https://github.com/ubuwaits/css3-buttons */
|
|||
|
||||
if (element.id == "start") {
|
||||
document.getElementById('messages').innerHTML = "Debug Starting!"
|
||||
} else if (element.id == "serialstart") {
|
||||
document.getElementById('messages').innerHTML = "Serial Debug Starting!"
|
||||
} else if (element.id == "stop") {
|
||||
document.getElementById('messages').innerHTML = "Debug Stopping!"
|
||||
} else if (element.id == "clean") {
|
||||
|
|
@ -90,10 +92,15 @@ Button style taken from https://github.com/ubuwaits/css3-buttons */
|
|||
//console.log(data.iLevel + " : " + data.sLevel);
|
||||
if ( data.iLevel >= 7 ) {
|
||||
document.getElementById('start').disabled = true;
|
||||
document.getElementById('stop').disabled = false;
|
||||
document.getElementById('messages').innerHTML = "Debug Running!"
|
||||
document.getElementById('serialstart').disabled = true;
|
||||
document.getElementById('stop').disabled = false;
|
||||
if ( data.iLevel >= 8 )
|
||||
document.getElementById('messages').innerHTML = "Serial debug Running!"
|
||||
else
|
||||
document.getElementById('messages').innerHTML = "Debug Running!"
|
||||
} else if ( data.iLevel < 7 ) {
|
||||
document.getElementById('start').disabled = false;
|
||||
document.getElementById('serialstart').disabled = false;
|
||||
document.getElementById('stop').disabled = true;
|
||||
document.getElementById('messages').innerHTML = "Not debugging, Log level = "+data.sLevel;
|
||||
}
|
||||
|
|
@ -125,20 +132,25 @@ Button style taken from https://github.com/ubuwaits/css3-buttons */
|
|||
|
||||
<body onload="update();">
|
||||
<table cellpadding="10" border="0" align="center">
|
||||
<tr><td colspan="2" align="center">
|
||||
<tr><td colspan="3" align="center">
|
||||
<div id="messages"> </div>
|
||||
</td></tr>
|
||||
<tr><td align="center">
|
||||
<button class="blue-pill" id="start" type="button" onclick='action(this);'>Start Debug</button>
|
||||
</td><td align="center">
|
||||
<button class="blue-pill" id="serialstart" type="button" onclick='action(this);'>Start Serial Debug</button>
|
||||
</td><td align="center">
|
||||
<button class="blue-pill" id="stop" type="button" onclick='action(this);'>Stop Debug</button>
|
||||
</td></tr>
|
||||
<tr><td colspan="2" align="center">
|
||||
<button class="blue-pill" id="download" type="button" onclick='action(this);'>Download Debug File</button>
|
||||
<tr><td colspan="3" align="center">
|
||||
<table cellpadding="10" border="0" align="center">
|
||||
<tr><td>
|
||||
<button class="blue-pill" id="download" type="button" onclick='action(this);'>Download Debug File</button>
|
||||
</td><td>
|
||||
<button class="blue-pill" id="clean" type="button" onclick='action(this);'>Clean Debug File</button>
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td colspan="2" align="center">
|
||||
<button class="blue-pill" id="clean" type="button" onclick='action(this);'>Clean Debug File</button>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue