mirror of https://github.com/sfeakes/AqualinkD.git
Version 1.3.3f
parent
c28ef1709c
commit
c2fe658d17
8
Makefile
8
Makefile
|
@ -1,4 +1,8 @@
|
|||
|
||||
#
|
||||
# Options
|
||||
# make DEBUG=true // Turn on timing statments
|
||||
# make EXFLAGS="-D BETA_PDA_AUTOLABEL" // Add compile flags
|
||||
#
|
||||
# define the C compiler to use
|
||||
CC = gcc
|
||||
|
||||
|
@ -16,7 +20,7 @@ DBG =
|
|||
|
||||
# define any compile-time flags
|
||||
#GCCFLAGS = -Wall -O3 -Wextra
|
||||
GCCFLAGS = -Wall -O3
|
||||
GCCFLAGS = -Wall -O3 $(EXFLAGS)
|
||||
#GCCFLAGS = -Wall
|
||||
|
||||
#CFLAGS = -Wall -g $(LIBS)
|
||||
|
|
|
@ -63,7 +63,7 @@ Designed to mimic AqualinkRS6 All Button keypad, and just like the keypad you ca
|
|||
* 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)
|
||||
#<a name="release"></a>
|
||||
## Update in Release 1.3.3d (a,b,c)
|
||||
## Update in Release 1.3.3d (a,b,c,e,f)
|
||||
* Some PDA fixes / enhancements.
|
||||
## Update in Release 1.3.3
|
||||
* AqualinkD will now automaticaly find a usable ID if not specifically configured.
|
||||
|
|
|
@ -233,6 +233,9 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data)
|
|||
type != AQ_SET_SPA_HEATER_TEMP &&
|
||||
type != AQ_SET_SWG_PERCENT &&
|
||||
type != AQ_PDA_DEVICE_ON_OFF &&
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
type != AQ_GET_AUX_LABELS &&
|
||||
#endif
|
||||
type != AQ_GET_POOL_SPA_HEATER_TEMPS ) {
|
||||
logMessage(LOG_ERR, "Selected Programming mode '%d' not supported with PDA mode control panel\n",type);
|
||||
return;
|
||||
|
@ -351,7 +354,7 @@ void aq_programmer(program_type type, char *args, struct aqualinkdata *aq_data)
|
|||
logMessage (LOG_ERR, "could not create thread\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case AQ_GET_AUX_LABELS:
|
||||
if( pthread_create( &programmingthread->thread_id , NULL , get_aqualink_aux_labels, (void*)programmingthread) < 0) {
|
||||
logMessage (LOG_ERR, "could not create thread\n");
|
||||
|
@ -392,9 +395,9 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
|
|||
|
||||
while ( (threadCtrl->aq_data->active_thread.thread_id != 0) && ( i++ <= tries) ) {
|
||||
//logMessage (LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id);
|
||||
logMessage (LOG_DEBUG, "Thread %d,%p sleeping, waiting for thread %d,%p to finish\n",
|
||||
type, &threadCtrl->thread_id, threadCtrl->aq_data->active_thread.ptype,
|
||||
threadCtrl->aq_data->active_thread.thread_id);
|
||||
logMessage (LOG_DEBUG, "Thread %d,%p (%s) sleeping, waiting for thread %d,%p (%s) to finish\n",
|
||||
type, &threadCtrl->thread_id, ptypeName(type),
|
||||
threadCtrl->aq_data->active_thread.ptype, threadCtrl->aq_data->active_thread.thread_id, ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
||||
sleep(waitTime);
|
||||
}
|
||||
|
||||
|
@ -415,22 +418,24 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
|
|||
#endif
|
||||
|
||||
//logMessage (LOG_DEBUG, "Thread %d is active\n", threadCtrl->aq_data->active_thread.thread_id);
|
||||
logMessage (LOG_DEBUG, "Thread %d,%p is active\n",
|
||||
logMessage (LOG_DEBUG, "Thread %d,%p is active (%s)\n",
|
||||
threadCtrl->aq_data->active_thread.ptype,
|
||||
threadCtrl->aq_data->active_thread.thread_id);
|
||||
threadCtrl->aq_data->active_thread.thread_id,
|
||||
ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
||||
}
|
||||
|
||||
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl)
|
||||
{
|
||||
#ifndef AQ_DEBUG
|
||||
logMessage(LOG_DEBUG, "Thread %d,%p finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id);
|
||||
logMessage(LOG_DEBUG, "Thread %d,%p (%s) finished\n",threadCtrl->aq_data->active_thread.ptype, threadCtrl->thread_id,ptypeName(threadCtrl->aq_data->active_thread.ptype));
|
||||
#else
|
||||
struct timespec elapsed;
|
||||
clock_gettime(CLOCK_REALTIME, &threadCtrl->aq_data->last_active_time);
|
||||
timespec_subtract(&elapsed, &threadCtrl->aq_data->last_active_time, &threadCtrl->aq_data->start_active_time);
|
||||
logMessage(LOG_DEBUG, "Thread %d,%p finished in %d.%03ld sec\n",
|
||||
logMessage(LOG_DEBUG, "Thread %d,%p (%s) finished in %d.%03ld sec\n",
|
||||
threadCtrl->aq_data->active_thread.ptype,
|
||||
threadCtrl->aq_data->active_thread.thread_id,
|
||||
ptypeName(threadCtrl->aq_data->active_thread.ptype)
|
||||
elapsed.tv_sec, elapsed.tv_nsec / 1000000L);
|
||||
#endif
|
||||
|
||||
|
@ -634,6 +639,12 @@ void *get_aqualink_aux_labels( void *ptr )
|
|||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_GET_AUX_LABELS);
|
||||
|
||||
if (pda_mode() == true) {
|
||||
get_PDA_aqualink_aux_labels(aq_data);
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
if ( select_menu_item(aq_data, "REVIEW") != true ) {
|
||||
logMessage(LOG_WARNING, "Could not select REVIEW menu\n");
|
||||
cancel_menu();
|
||||
|
@ -1489,7 +1500,7 @@ const char *ptypeName(program_type type)
|
|||
return "Switch PDA device on/off";
|
||||
break;
|
||||
case AQ_GET_AUX_LABELS:
|
||||
return "Get labels";
|
||||
return "Get AUX labels";
|
||||
break;
|
||||
case AQ_PDA_WAKE_INIT:
|
||||
return "PDA init after wake";
|
||||
|
|
23
aqualinkd.c
23
aqualinkd.c
|
@ -208,6 +208,7 @@ void processMessage(char *message)
|
|||
static bool _gotREV = false;
|
||||
static int freeze_msg_count = 0;
|
||||
static int service_msg_count = 0;
|
||||
static int swg_msg_count = 0;
|
||||
// NSF replace message with msg
|
||||
msg = stripwhitespace(message);
|
||||
strcpy(_aqualink_data.last_message, msg);
|
||||
|
@ -234,13 +235,13 @@ void processMessage(char *message)
|
|||
_aqualink_data.service_mode_state = OFF;
|
||||
service_msg_count = 0;
|
||||
}
|
||||
/*
|
||||
|
||||
// If we have more than 10 messages without "Service Mode is active" assume it's off.
|
||||
if (_aqualink_data.service_mode_state == ON && service_msg_count++ > 10) {
|
||||
_aqualink_data.service_mode_state = OFF;
|
||||
service_msg_count = 0;
|
||||
if (_aqualink_data.ar_swg_status == SWG_STATUS_ON && swg_msg_count++ > 20) {
|
||||
_aqualink_data.ar_swg_status = SWG_STATUS_OFF;
|
||||
swg_msg_count = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// If we have more than 10 messages without "FREE PROTECT ACTIVATED" assume it's off.
|
||||
if (_aqualink_data.frz_protect_state == ON && freeze_msg_count++ > 10)
|
||||
{
|
||||
|
@ -362,11 +363,13 @@ void processMessage(char *message)
|
|||
else if (strncasecmp(msg, MSG_SWG_PCT, MSG_SWG_PCT_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.swg_percent = atoi(msg + MSG_SWG_PCT_LEN);
|
||||
//logMessage(LOG_DEBUG, "Stored SWG Percent as %d\n", _aqualink_data.swg_percent);
|
||||
if (_aqualink_data.ar_swg_status == SWG_STATUS_OFF) {_aqualink_data.ar_swg_status = SWG_STATUS_ON; swg_msg_count = 0;}
|
||||
//logMessage(LOG_DEBUG, "*** '%s' ***\n", msg);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_SWG_PPM, MSG_SWG_PPM_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.swg_ppm = atoi(msg + MSG_SWG_PPM_LEN);
|
||||
if (_aqualink_data.ar_swg_status == SWG_STATUS_OFF) {_aqualink_data.ar_swg_status = SWG_STATUS_ON; swg_msg_count = 0;}
|
||||
//logMessage(LOG_DEBUG, "Stored SWG PPM as %d\n", _aqualink_data.swg_ppm);
|
||||
}
|
||||
else if ((msg[1] == ':' || msg[2] == ':') && msg[strlen(msg) - 1] == 'M')
|
||||
|
@ -1031,7 +1034,11 @@ void main_loop()
|
|||
|
||||
if (_config_parameters.pda_mode == true)
|
||||
{
|
||||
init_pda(&_aqualink_data);
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
init_pda(&_aqualink_data, &_config_parameters);
|
||||
#else
|
||||
init_pda(&_aqualink_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_config_parameters.device_id == 0x00) {
|
||||
|
@ -1139,6 +1146,7 @@ void main_loop()
|
|||
_aqualink_data.swg_delayed_percent = TEMP_UNKNOWN;
|
||||
}
|
||||
_aqualink_data.swg_ppm = packet_buffer[4] * 100;
|
||||
//logMessage(LOG_DEBUG, "Read SWG PPM %d from ID 0x%02hhx\n", _aqualink_data.swg_ppm, SWG_DEV_ID);
|
||||
}
|
||||
interestedInNextAck = false;
|
||||
}
|
||||
|
@ -1154,6 +1162,7 @@ void main_loop()
|
|||
{
|
||||
// Only read SWG Percent if we are not programming, as we might be changing this
|
||||
_aqualink_data.swg_percent = (int)packet_buffer[4];
|
||||
//logMessage(LOG_DEBUG, "Read SWG Percent %d from ID 0x%02hhx\n", _aqualink_data.swg_percent, SWG_DEV_ID);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
66
pda.c
66
pda.c
|
@ -6,11 +6,14 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "aqualink.h"
|
||||
|
||||
#include "init_buttons.h"
|
||||
#include "pda.h"
|
||||
#include "pda_menu.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
|
||||
// static struct aqualinkdata _aqualink_data;
|
||||
static struct aqualinkdata *_aqualink_data;
|
||||
static unsigned char _last_packet_type;
|
||||
|
@ -22,11 +25,23 @@ static bool _initWithRS = false;
|
|||
#define PDA_SLEEP_FOR 120 // 30 seconds
|
||||
#define PDA_WAKE_FOR 6 // ~1 seconds
|
||||
|
||||
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
static struct aqconfig *_aqualink_config;
|
||||
void init_pda(struct aqualinkdata *aqdata, struct aqconfig *aqconfig)
|
||||
{
|
||||
_aqualink_data = aqdata;
|
||||
_aqualink_config = aqconfig;
|
||||
set_pda_mode(true);
|
||||
}
|
||||
#else
|
||||
void init_pda(struct aqualinkdata *aqdata)
|
||||
{
|
||||
_aqualink_data = aqdata;
|
||||
set_pda_mode(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool pda_shouldSleep() {
|
||||
//logMessage(LOG_DEBUG, "PDA loop count %d, will sleep at %d\n",_pda_loop_cnt,PDA_LOOP_COUNT);
|
||||
|
@ -448,6 +463,40 @@ void process_pda_packet_msg_long_unknown(const char *msg)
|
|||
}
|
||||
}
|
||||
|
||||
void process_pda_packet_msg_long_level_aux_device(const char *msg)
|
||||
{
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
int li=-1;
|
||||
char *str, *label;
|
||||
|
||||
if (! _aqualink_config->use_panel_aux_labels)
|
||||
return;
|
||||
// NSF Need to check config for use_panel_aux_labels value and ignore if not set
|
||||
|
||||
// Only care once we have the full menu, so check line
|
||||
// PDA Line 0 = LABEL AUX1
|
||||
// PDA Line 1 =
|
||||
// PDA Line 2 = CURRENT LABEL
|
||||
// PDA Line 3 = AUX1
|
||||
|
||||
|
||||
if ( (strlen(pda_m_line(3)) > 0 ) &&
|
||||
(strncasecmp(pda_m_line(2)," CURRENT LABEL ", 16) == 0) &&
|
||||
(strncasecmp(pda_m_line(0)," LABEL AUX", 12) == 0) ) {
|
||||
str = pda_m_line(0);
|
||||
li = atoi(&str[12] ); // 12 is a guess, need to check on real system
|
||||
if (li > 0) {
|
||||
str = cleanwhitespace(pda_m_line(3));
|
||||
label = (char*)malloc(strlen(str)+1);
|
||||
strcpy ( label, str );
|
||||
_aqualink_data->aqbuttons[li-1].pda_label = label;
|
||||
} else {
|
||||
logMessage(LOG_ERR, "PDA couldn't get AUX? number\n", pda_m_line(0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void process_pda_freeze_protect_devices()
|
||||
{
|
||||
// PDA Line 0 = FREEZE PROTECT
|
||||
|
@ -481,7 +530,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
bool rtn = true;
|
||||
int i;
|
||||
char *msg;
|
||||
static bool init = false;
|
||||
//static bool init = false;
|
||||
|
||||
process_pda_menu_packet(packet, length);
|
||||
|
||||
|
@ -496,10 +545,12 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
|
||||
case CMD_ACK:
|
||||
logMessage(LOG_DEBUG, "RS Received ACK length %d.\n", length);
|
||||
if (init == false)
|
||||
//if (init == false)
|
||||
if (_initWithRS == false)
|
||||
{
|
||||
logMessage(LOG_DEBUG, "Running PDA_INIT\n");
|
||||
aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
||||
init = true;
|
||||
//init = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -585,6 +636,9 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
case PM_AQUAPURE:
|
||||
process_pda_packet_msg_long_SWG(msg);
|
||||
break;
|
||||
case PM_AUX_LABEL_DEVICE:
|
||||
process_pda_packet_msg_long_level_aux_device(msg);
|
||||
break;
|
||||
//case PM_FW_VERSION:
|
||||
// process_pda_packet_msg_long_FW_version(msg);
|
||||
//break;
|
||||
|
@ -609,6 +663,12 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
_initWithRS = true;
|
||||
logMessage(LOG_DEBUG, "**** PDA INIT ****");
|
||||
aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
||||
delay(50); // Make sure this one runs first.
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
if (_aqualink_config->use_panel_aux_labels)
|
||||
aq_programmer(AQ_GET_AUX_LABELS, NULL, _aqualink_data);
|
||||
#endif
|
||||
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
||||
} else {
|
||||
logMessage(LOG_DEBUG, "**** PDA WAKE INIT ****");
|
||||
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
||||
|
|
9
pda.h
9
pda.h
|
@ -3,7 +3,14 @@
|
|||
#ifndef PDA_H_
|
||||
#define PDA_H_
|
||||
|
||||
void init_pda(struct aqualinkdata *aqdata);
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
#include "aqualink.h"
|
||||
#include "config.h"
|
||||
void init_pda(struct aqualinkdata *aqdata, struct aqconfig *aqconfig);
|
||||
#else
|
||||
void init_pda(struct aqualinkdata *aqdata);
|
||||
#endif
|
||||
|
||||
bool process_pda_packet(unsigned char* packet, int length);
|
||||
bool pda_shouldSleep();
|
||||
void pda_wake();
|
||||
|
|
|
@ -421,12 +421,12 @@ void *set_aqualink_PDA_init( void *ptr )
|
|||
|
||||
//printf("****** Version '%s' ********\n",aq_data->version);
|
||||
}
|
||||
|
||||
/*
|
||||
// Get status of all devices
|
||||
if (! loopover_devices(aq_data)) {
|
||||
logMessage(LOG_ERR, "PDA Init :- can't find menu\n");
|
||||
}
|
||||
|
||||
*/
|
||||
// Get heater setpoints
|
||||
if (! get_PDA_aqualink_pool_spa_heater_temps(aq_data)) {
|
||||
logMessage(LOG_ERR, "PDA Init :- Error getting heater setpoints\n");
|
||||
|
@ -437,7 +437,6 @@ void *set_aqualink_PDA_init( void *ptr )
|
|||
logMessage(LOG_ERR, "PDA Init :- Error getting freeze setpoints\n");
|
||||
}
|
||||
|
||||
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
pda_reset_sleep();
|
||||
|
@ -709,6 +708,30 @@ bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int v
|
|||
//return true;
|
||||
}
|
||||
|
||||
// Test ine this.
|
||||
bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data) {
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
int i=0;
|
||||
char label[10];
|
||||
|
||||
logMessage(LOG_INFO, "Finding PDA labels, (BETA ONLY)\n");
|
||||
|
||||
if (! goto_pda_menu(aq_data, PM_AUX_LABEL)) {
|
||||
logMessage(LOG_ERR, "Error finding aux label menu\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i=1;i<8;i++) {
|
||||
sprintf(label, "AUX%d",i);
|
||||
select_pda_menu_item(aq_data, label, true);
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
|
||||
// Read first page of devices and make some assumptions.
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool waitForPDAMessage(struct aqualinkdata *aq_data, int numMessageReceived, unsigned char packettype)
|
||||
|
|
|
@ -18,6 +18,8 @@ bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int v
|
|||
bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data);
|
||||
bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data);
|
||||
|
||||
bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data);
|
||||
|
||||
//void pda_programming_thread_check(struct aqualinkdata *aq_data);
|
||||
|
||||
#endif // AQ_PDA_PROGRAMMER_H_
|
|
@ -123,6 +123,11 @@ pda_menu_type pda_m_type()
|
|||
strncasecmp(_menu[1]," AquaPalm", 12) == 0 ||
|
||||
strncasecmp(_menu[1]," PDA-P", 6) == 0) // PDA-P4 Only -or- PDA-PS4 Combo
|
||||
return PM_FW_VERSION;
|
||||
else if (strncasecmp(_menu[0]," LABEL AUX ", 16) == 0) // Catch AUX and not AUX4
|
||||
return PM_AUX_LABEL;
|
||||
else if (strncasecmp(_menu[0]," LABEL AUX", 12) == 0 && // Will have number ie AUX4
|
||||
strncasecmp(_menu[2]," CURRENT LABEL ", 16) == 0)
|
||||
return PM_AUX_LABEL_DEVICE;
|
||||
|
||||
return PM_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ typedef enum pda_menu_type {
|
|||
PM_AQUAPURE,
|
||||
PM_SYSTEM_SETUP,
|
||||
PM_AUX_LABEL,
|
||||
PM_AUX_LABEL_DEVICE, // label a specific device
|
||||
PM_FREEZE_PROTECT,
|
||||
PM_FREEZE_PROTECT_DEVICES,
|
||||
PM_VSP,
|
||||
|
|
Binary file not shown.
|
@ -105,14 +105,15 @@ light_programming_initial_off=12
|
|||
# Everything below here, if it ends with dzidx, then that's the ID for domoticz,
|
||||
# so not needed if you are not suing dooticz.
|
||||
# Domoticz ID's for temps.
|
||||
air_temp_dzidx=0
|
||||
pool_water_temp_dzidx=0
|
||||
spa_water_temp_dzidx=0
|
||||
SWG_percent_dzidx=0
|
||||
SWG_PPM_dzidx=0
|
||||
#air_temp_dzidx=0
|
||||
#pool_water_temp_dzidx=0
|
||||
#spa_water_temp_dzidx=0
|
||||
#SWG_percent_dzidx=0
|
||||
#SWG_PPM_dzidx=0
|
||||
|
||||
|
||||
# Try to use labels from Control Panel.
|
||||
# Use/find labels from Control Panel, these will overwrite the button_xx_label below,
|
||||
# it dows NOT work in PDA mode.
|
||||
use_panel_aux_labels=no
|
||||
|
||||
# These are all the button labels you want to use for the web interface and Domoticz virtual sensors.
|
||||
|
@ -122,7 +123,7 @@ use_panel_aux_labels=no
|
|||
# Optional, 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 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F)
|
||||
# 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
|
||||
|
||||
|
@ -143,6 +144,7 @@ button_03_label=Cleaner
|
|||
button_04_label=Waterfall
|
||||
#button_04_dzidx=40
|
||||
#button_04_PDA_label=AUX2
|
||||
#button_01_pumpID=0x61
|
||||
|
||||
button_05_label=Spa Blower
|
||||
#button_05_dzidx=41
|
||||
|
|
Loading…
Reference in New Issue