pull/476/head
sfeakes 2025-10-11 15:14:43 -05:00
parent dc0bbe02cc
commit 0d6cd6f2ed
22 changed files with 408 additions and 128 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -19,6 +19,7 @@
#include <string.h>
#include <ctype.h>
#include "rs_devices.h"
#include "config.h"
#include "aq_panel.h"
#include "serialadapter.h"
@ -134,7 +135,7 @@ void checkPanelConfig(struct aqualinkdata *aqdata) {
// Check panel rev for common errors.
// Aqualink Touch.
if ( _aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) {
if ( is_aqualink_touch_id(_aqconfig_.extended_device_id)) {
if ( !isMASKSET(aqdata->panel_support_options, RSP_SUP_AQLT)) {
LOG(PANL_LOG, LOG_ERR, "Panel REV %s does not support AqualinkTouch protocol, please change configuration option '%s'\n",aqdata->panel_rev, CFG_N_extended_device_id);
LOG(PANL_LOG, LOG_WARNING, "Removing option '%s', please correct configuration\n",CFG_N_extended_device_id);
@ -144,7 +145,7 @@ void checkPanelConfig(struct aqualinkdata *aqdata) {
}
// One Touch
if ( _aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) {
if ( is_onetouch_id(_aqconfig_.extended_device_id)) {
if ( !isMASKSET(aqdata->panel_support_options, RSP_SUP_ONET)) {
LOG(PANL_LOG, LOG_ERR, "Panel REV %s does not support OneTouch protocol, please change configuration option '%s'\n",aqdata->panel_rev, CFG_N_extended_device_id);
LOG(PANL_LOG, LOG_WARNING, "Removing option '%s', please correct configuration\n",CFG_N_extended_device_id);
@ -154,7 +155,7 @@ void checkPanelConfig(struct aqualinkdata *aqdata) {
}
// Serial Adapter
if ( _aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x49) {
if ( is_rsserialadapter_id(_aqconfig_.rssa_device_id)) {
if ( !isMASKSET(aqdata->panel_support_options, RSP_SUP_RSSA)) {
LOG(PANL_LOG, LOG_ERR, "Panel REV %s does not support RS SerialAdapter protocol, please change configuration option '%s'\n",aqdata->panel_rev, CFG_N_rssa_device_id);
LOG(PANL_LOG, LOG_WARNING, "Removing option '%s', please correct configuration\n",CFG_N_rssa_device_id);
@ -1223,7 +1224,10 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
{
// Check for panel programmable light. if so simple ON isn't going to work well
// Could also add "light mode" check, as this is only valid for panel configured light not aqualinkd configured light.
if (isPLIGHT(button->special_mask) && button->led->state == OFF) {
if (isPLIGHT(button->special_mask) && isVBUTTON(button->special_mask)) {
programDeviceLightMode(aqdata, (isON?0:-1), deviceIndex); // -1 means off 0 means use current light mode
//aq_program(AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE, button, (isON?0:-1), 0, aqdata); // should use this in teh furuter, or get programDeviceLightMode to call it.
} else if (isPLIGHT(button->special_mask) && button->led->state == OFF) {
// Full range dimmer can get stuck off on rev T.2 (maybe others), to overcome use allbutton with any % other than 0
if ( ((clight_detail *)button->special_mask_ptr)->lightType == LC_DIMMER2 ||
((clight_detail *)button->special_mask_ptr)->lightType == LC_DIMMER ) // NSF should remove this once figured out Line #1354 programDeviceLightBrightness()

View File

@ -723,6 +723,9 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
int tries = 120;
static int waitTime = 1;
int i=0;
// Make sure to update UI
SET_DIRTY(threadCtrl->aqdata->is_dirty);
/*
i = 0;
while (get_aq_cmd_length() > 0 && ( i++ <= tries) ) {
@ -767,6 +770,9 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
threadCtrl->aqdata->active_thread.ptype,
threadCtrl->aqdata->active_thread.thread_id,
ptypeName(threadCtrl->aqdata->active_thread.ptype));
// Make sure to update UI
SET_DIRTY(threadCtrl->aqdata->is_dirty);
}
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl)

View File

@ -31,6 +31,7 @@
#include "aq_serial.h"
#include "rs_devices.h"
#include "utils.h"
#include "config.h"
#include "packetLogger.h"
@ -53,17 +54,17 @@ emulation_type getJandyDeviceType(unsigned char ID) {
// Using emulation_type from aqprogrammer. At some point may merge into one
// and call device type
if (ID >= 0x08 && ID <= 0x0B)
if ( is_allbutton_id(ID) )
return ALLBUTTON;
if (ID >= 0x40 && ID <= 0x43)
if ( is_onetouch_id(ID))
return ONETOUCH;
if (ID >= 0x48 && ID <= 0x4B)
if ( is_rsserialadapter_id(ID))
return RSSADAPTER;
if (ID >= 0x60 && ID <= 0x63)
if ( is_pda_id(ID))
return AQUAPDA;
if (ID >= 0x30 && ID <= 0x33)
if (is_aqualink_touch_id(ID ))
return IAQTOUCH;
if (ID >= 0xa0 && ID <= 0xa3)
if (is_iaqualink_id(ID))
return IAQUALNK;
/*

View File

@ -41,22 +41,63 @@ const char *getJandyDeviceName(emulation_type etype);
# Jandy pump ID's
# 0x78, 0x79, 0x7A, 0x7B
*/
#define PENTAIR_DEC_PUMP_MIN 96 // 0x60
#define PENTAIR_DEC_PUMP_MAX 111 // 0x6F
#define JANDY_DEC_SWG_MIN 80 // 0x50
#define JANDY_DEC_SWG_MAX 83 // 0x53
#define JANDY_DEC_PUMP_MIN 120 // 0x78
#define JANDY_DEC_PUMP_MAX 123 // 0x7b
// Have also seen epump at 0xe0 with panel rev W that supports more pumps
#define JANDY_DEC_PUMP2_MIN 224 // 0xe0
#define JANDY_DEC_PUMP2_MAX 228 // 0xe3 // (should be 0xEF?????) Their are probably more, but this is a guess
#define JANDY_DEC_JXI_MIN 104 // 0x68
#define JANDY_DEC_JXI_MAX 107 // 0x6B
#define JANDY_DEC_LX_MIN 56 // 0x38
#define JANDY_DEC_LX_MAX 59 // 0x3B
#define JANDY_DEC_CHEM_MIN 128 // 0x80
#define JANDY_DEC_CHEM_MAX 131 // 0x83
/*
#define PENTAIR_DEV_PUMP_MIN 0x60 // 96
#define PENTAIR_DEV_PUMP_MAX 0x6F // 111
#define JANDY_DEV_SWG_MIN 0x50 // 80
#define JANDY_DEV_SWG_MAX 0x53 // 83
#define JANDY_DEV_PUMP_MIN 0x78 // 120
#define JANDY_DEV_PUMP_MAX 0x7B // 123
// Have also seen epump at 0xE0 with panel rev W that supports more pumps
#define JANDY_DEV_PUMP2_MIN 0xE0 // 224
#define JANDY_DEV_PUMP2_MAX 0xE3 // 228 // (should be 0xEF?????) Guess
#define JANDY_DEV_JXI_MIN 0x68 // 104
#define JANDY_DEV_JXI_MAX 0x6B // 107
#define JANDY_DEV_LX_MIN 0x38 // 56
#define JANDY_DEV_LX_MAX 0x3B // 59
#define JANDY_DEV_CHEM_MIN 0x80 // 128
#define JANDY_DEV_CHEM_MAX 0x83 // 131
#define JANDY_DEV_IAQLN_MIN 0xA0 // 160
#define JANDY_DEV_IAQLN_MAX 0xA3 // 163
#define JANDY_DEV_AQLNK_MIN 0x30 // 48
#define JANDY_DEV_AQLNK_MAX 0x33 // 51
#define JANDY_DEV_HPUMP_MIN 0x70 // 112
#define JANDY_DEV_HPUMP_MAX 0x73 // 115
#define JANDY_DEV_JLIGHT_MIN 0xF0 // 240
#define JANDY_DEV_JLIGHT_MAX 0xF4 // 244 (guess)
*/
/* Below is a guess. We *think* 0x84 and 0x86 are one TruSense, so assuming 0x85 and 0x87 would be a 2nd */
// 0x83 is ChemLink and 0x88 is heater, so 84 to 86 are free
//#define JANDY_DEV_CHEM_ANLZ_MIN 0x84
//#define JANDY_DEV_CHEM_ANLZ_MAX 0x87
/*
#define PENTAIR_DEV_PUMP_MIN 96 // 0x60
#define PENTAIR_DEV_PUMP_MAX 111 // 0x6F
#define JANDY_DEV_SWG_MIN 80 // 0x50
#define JANDY_DEV_SWG_MAX 83 // 0x53
#define JANDY_DEV_PUMP_MIN 120 // 0x78
#define JANDY_DEV_PUMP_MAX 123 // 0x7b
// Have also seen epump at 0xe0 with panel rev W that supports more pumps
#define JANDY_DEV_PUMP2_MIN 224 // 0xe0
#define JANDY_DEV_PUMP2_MAX 228 // 0xe3 // (should be 0xEF?????) Their are probably more, but this is a guess
#define JANDY_DEV_JXI_MIN 104 // 0x68
#define JANDY_DEV_JXI_MAX 107 // 0x6B
#define JANDY_DEV_LX_MIN 56 // 0x38
#define JANDY_DEV_LX_MAX 59 // 0x3B
#define JANDY_DEV_CHEM_MIN 128 // 0x80
#define JANDY_DEV_CHEM_MAX 131 // 0x83
#define JANDY_DEV_IAQLN_MIN 0xa0 //
#define JANDY_DEV_IAQLN_MAX 0xa3 // 0
@ -70,13 +111,13 @@ const char *getJandyDeviceName(emulation_type etype);
#define JANDY_DEV_JLIGHT_MIN 0xF0
#define JANDY_DEV_JLIGHT_MAX 0xF4 // 0xF4 is total guess.
//#define JANDY_DEC_CHEM_SENSOR1 0x84 // Not sure if this is a range or not.
//#define JANDY_DEC_CHEM_SENSOR2 0x86 // Not sure if this is a range or not.
//#define JANDY_DEV_CHEM_SENSOR1 0x84 // Not sure if this is a range or not.
//#define JANDY_DEV_CHEM_SENSOR2 0x86 // Not sure if this is a range or not.
*/
/* Below is a guess. We *think* 0x84 and 0x86 are one TruSense, so assuming 0x85 and 0x87 would be a 2nd */
// 0x83 is ChemLink and 0x88 is heater, so 84 to 86 are free
#define JANDY_DEV_CHEM_ANLZ_MIN 0x84
#define JANDY_DEV_CHEM_ANLZ_MAX 0x87
//#define JANDY_DEV_CHEM_ANLZ_MIN 0x84
//#define JANDY_DEV_CHEM_ANLZ_MAX 0x87
/*
//===== Device ID's =====//

View File

@ -10,6 +10,8 @@
#include "sensors.h"
//#include "aq_panel.h" // Moved to later in file to overcome circular dependancy. (crappy I know)
#define PRINTF(format, ...) printf("%s:%d: " format, __FILE__, __LINE__, ##__VA_ARGS__)
#define isMASK_SET(bitmask, mask) ((bitmask & mask) == mask)
#define setMASK(bitmask, mask) (bitmask |= mask)
#define removeMASK(bitmask, mask) (bitmask &= ~mask)

View File

@ -29,6 +29,7 @@
#include <time.h> // Need GNU_SOURCE & XOPEN defined for strptime
#define AQUALINKD_C
#include "rs_devices.h"
#include "mongoose.h"
#include "aqualink.h"
#include "utils.h"
@ -589,7 +590,7 @@ int startup(char *self, char *cfgFile)
// Sanity check on Device ID's against panel type
if (isRS_PANEL) {
if ( (_aqconfig_.device_id >= 0x08 && _aqconfig_.device_id <= 0x0B) || _aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) {
if ( is_allbutton_id(_aqconfig_.device_id) || _aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) {
// We are good
} else {
LOG(AQUA_LOG,LOG_ERR, "Device ID 0x%02hhx does not match RS panel, Going to search for ID!\n", _aqconfig_.device_id);
@ -597,7 +598,7 @@ int startup(char *self, char *cfgFile)
//return EXIT_FAILURE;
}
} else if (isPDA_PANEL) {
if ( (_aqconfig_.device_id >= 0x60 && _aqconfig_.device_id <= 0x63) || _aqconfig_.device_id == 0x33 || _aqconfig_.device_id == 0xFF) {
if ( is_pda_id(_aqconfig_.device_id) || _aqconfig_.device_id == 0x33 || _aqconfig_.device_id == 0xFF) {
if ( _aqconfig_.device_id == 0x33 ) {
LOG(AQUA_LOG,LOG_NOTICE, "Enabeling iAqualink protocol.\n");
_aqconfig_.enable_iaqualink = true;
@ -613,7 +614,7 @@ int startup(char *self, char *cfgFile)
}
if (_aqconfig_.rssa_device_id != 0x00) {
if (_aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x4B /*&& _aqconfig_.rssa_device_id != 0xFF*/) {
if ( is_rsserialadapter_id(_aqconfig_.rssa_device_id) ) {
// We are good
} else {
LOG(AQUA_LOG,LOG_ERR, "RSSA Device ID 0x%02hhx does not match RS panel, please check config!\n", _aqconfig_.rssa_device_id);
@ -623,9 +624,7 @@ int startup(char *self, char *cfgFile)
if (_aqconfig_.extended_device_id != 0x00) {
if ( (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) ||
(_aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) /*||
_aqconfig_.extended_device_id != 0xFF*/ ) {
if ( is_aqualink_touch_id(_aqconfig_.extended_device_id) || is_onetouch_id(_aqconfig_.extended_device_id ) ) {
// We are good
} else {
LOG(AQUA_LOG,LOG_ERR, "Extended Device ID 0x%02hhx does not match OneTouch or AqualinkTouch ID, please check config!\n", _aqconfig_.extended_device_id);
@ -1087,13 +1086,13 @@ void main_loop()
}
#endif
if (_aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x49) {
if ( is_rsserialadapter_id(_aqconfig_.rssa_device_id )) {
addPanelRSserialAdapterInterface();
}
if (_aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) {
if ( is_onetouch_id(_aqconfig_.extended_device_id)) {
addPanelOneTouchInterface();
} else if (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) {
} else if ( is_aqualink_touch_id(_aqconfig_.extended_device_id)) {
addPanelIAQTouchInterface();
}

View File

@ -3,6 +3,7 @@
#include <ctype.h>
#include <string.h>
#include "rs_devices.h"
#include "aqualink.h"
#include "aq_serial.h"
#include "auto_configure.h"
@ -147,9 +148,23 @@ bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int pack
PDA_ID = packet[PKT_DEST];
}
if (is_iaqualink_id(lastID) && packet[PKT_DEST] == DEV_MASTER && seen_iAqualink2 == false )
{ // Saw a iAqualink2/3 device, so can't use ID, but set to read device info.
// NSF This is not a good way to check, will probably be false positive if you are using iAqualink2 and hit restart.
_aqconfig_.extended_device_id2 = 0x00;
_aqconfig_.enable_iaqualink = false;
_aqconfig_.read_RS485_devmask |= READ_RS485_IAQUALNK;
seen_iAqualink2 = true;
LOG(AQUA_LOG,LOG_NOTICE, "Saw inuse iAqualink2/3 ID 0x%02hhx, turning off AqualinkD on that ID\n",lastID);
}
if (lastID != 0x00 && packet[PKT_DEST] == DEV_MASTER ) { // Can't use got a reply to the last probe.
lastID = 0x00;
} else if (lastID != 0x00 && packet[PKT_DEST] != DEV_MASTER) {
lastID = 0x00;
}
else if (lastID != 0x00 && packet[PKT_DEST] != DEV_MASTER)
{
// We can use last ID.
// Save the first good ID.
if (firstprobe == 0x00 && lastID != 0x60) {
@ -165,26 +180,20 @@ bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int pack
SET_DIRTY(aqdata->is_dirty);
//AddAQDstatusMask(AUTOCONFIGURE_PANEL); // Not implimented yet.
}
if ( (lastID >= 0x08 && lastID <= 0x0B) &&
(_aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) ) {
if ( is_allbutton_id(lastID) && (_aqconfig_.device_id == 0x00 || _aqconfig_.device_id == 0xFF) ) {
_aqconfig_.device_id = lastID;
LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused device ID 0x%02hhx\n",lastID);
foundIDs++;
} else if ( (lastID >= 0x48 && lastID <= 0x49) &&
(_aqconfig_.rssa_device_id == 0x00 || _aqconfig_.rssa_device_id == 0xFF) ) {
} else if ( is_rsserialadapter_id(lastID) && (_aqconfig_.rssa_device_id == 0x00 || _aqconfig_.rssa_device_id == 0xFF) ) {
_aqconfig_.rssa_device_id = lastID;
LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused RSSA ID 0x%02hhx\n",lastID);
foundIDs++;
} else if ( (lastID >= 0x40 && lastID <= 0x43) &&
(_aqconfig_.extended_device_id == 0x00 || _aqconfig_.extended_device_id == 0xFF) ) {
} else if ( is_onetouch_id(lastID) && (_aqconfig_.extended_device_id == 0x00 || _aqconfig_.extended_device_id == 0xFF) ) {
_aqconfig_.extended_device_id = lastID;
_aqconfig_.extended_device_id_programming = true;
// Don't increase foundIDs as we prefer not to use this one.
LOG(AQUA_LOG,LOG_NOTICE, "Found valid unused extended ID 0x%02hhx\n",lastID);
} else if ( (lastID >= 0x30 && lastID <= 0x33) &&
(_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33)) { //Overide if it's been set to Touch or not set.
} else if ( is_aqualink_touch_id(lastID) && (_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33)) { //Overide if it's been set to Touch or not set.
_aqconfig_.extended_device_id = lastID;
_aqconfig_.extended_device_id_programming = true;
if (!seen_iAqualink2) {
@ -211,15 +220,19 @@ bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int pack
}
if ( (packet[PKT_CMD] == CMD_PROBE) && (
(packet[PKT_DEST] >= 0x08 && packet[PKT_DEST] <= 0x0B) ||
is_allbutton_id(packet[PKT_DEST]) ||
//(packet[PKT_DEST] >= 0x60 && packet[PKT_DEST] <= 0x63) ||
(packet[PKT_DEST] >= 0x40 && packet[PKT_DEST] <= 0x43) ||
(packet[PKT_DEST] >= 0x30 && packet[PKT_DEST] <= 0x33) ||
(packet[PKT_DEST] >= 0x48 && packet[PKT_DEST] <= 0x49) ))
is_rsserialadapter_id(packet[PKT_DEST]) ||
is_aqualink_touch_id(packet[PKT_DEST]) ||
is_onetouch_id(packet[PKT_DEST]) ))
{
lastID = packet[PKT_DEST]; // Store the valid ID.
}
else if (packet[PKT_DEST] >= 0xa0 && packet[PKT_DEST] <= 0xa3 && seen_iAqualink2 == false ) // we get a packet to iAqualink2/3 make sure to turn off,
else if (is_iaqualink_id(packet[PKT_DEST])) {
lastID = packet[PKT_DEST]; // Store the valid ID.
}
/*
else if (is_iaqualink_id(packet[PKT_DEST]) && seen_iAqualink2 == false ) // we get a packet to iAqualink2/3 make sure to turn off,
{ // Saw a iAqualink2/3 device, so can't use ID, but set to read device info.
// NSF This is not a good way to check, will probably be false positive if you are using iAqualink2 and hit restart.
_aqconfig_.extended_device_id2 = 0x00;
@ -227,7 +240,7 @@ bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int pack
_aqconfig_.read_RS485_devmask |= READ_RS485_IAQUALNK;
seen_iAqualink2 = true;
LOG(AQUA_LOG,LOG_NOTICE, "Saw inuse iAqualink2/3 ID 0x%02hhx, turning off AqualinkD on that ID\n",packet[PKT_DEST]);
}
}*/
if (!done)
return false;

View File

@ -5,5 +5,4 @@
bool auto_configure(struct aqualinkdata *aqdata, unsigned char* packet, int packet_length, int rs_fd);
#endif //AUTO_CONFIGURE_H_

View File

@ -23,14 +23,14 @@ bool isShowMode(const char *mode);
char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
//char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
{
// AqualnkD Colors ignored as no names in control panel.
// 0 = AqualnkD Colors ignored as no names in control panel.
{ "Off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18" },
{ // Jandy Color
{ // 1 = Jandy Color
"Off",
"Alpine White", // 0x41
"Sky Blue",
"Cobalt Blue",
"Caribbean Blue",
"Caribbean Blu",
"Spring Green",
"Emerald Green",
"Emerald Rose",
@ -39,12 +39,12 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Violet",
"Color Splash"
},
{ // Jandy LED
{ // 2 = Jandy LED
"Off",
"Alpine White",
"Sky Blue",
"Cobalt Blue",
"Caribbean Blue",
"Caribbean Blu",
"Spring Green",
"Emerald Green",
"Emerald Rose",
@ -56,7 +56,7 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Fat Tuesday",
"Disco Tech"
},
{ // SAm/SAL
{ // 3 = SAm/SAL
"Off",
"White",
"Light Green",
@ -66,7 +66,7 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Lavender",
"Magenta"
},
{ // Color Logic
{ // 4 = Color Logic
"Off",
"Voodoo Lounge", // 0x41 (both home and sim)
"Deep Blue Sea", // 0x42 (both gome and sim)
@ -81,7 +81,7 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Mardi Gras", // 0x50 (home panel) // 0x4b (simulator)
"Cool Cabaret" // 0x51 (home panel) // 0x4c
},
{ // IntelliBrite
{ // 5 = IntelliBrite
"Off",
"SAm",
"Party",
@ -96,7 +96,7 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"White",
"Magenta"
},
{ // Haywood Universal Color
{ // 6 = Haywood Universal Color
"Off",
"Voodoo Lounge", // 0x41 (both home and sim) // Looks like 28 + <value or index> = 0x41 = 1st index
"Deep Blue Sea", // 0x42 (both gome and sim)
@ -116,7 +116,7 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Mardi Gras", // 0x50 (home panel) // 0x4b (simulator)
"Cool Cabaret" // 0x51 (home panel) // 0x4c
},
{// Jandy Infinate Water Colors (RS485)
{// 7 = Jandy Infinate Water Colors (RS485)
"Off",
"Alpine White",
"Sky Blue",
@ -134,16 +134,16 @@ char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
"Fat Tuesday",
"Disco Tech"
},
{/*Spare 2*/},
{/*Spare 3*/},
{ // Dimmer // From manual this is 0 for off, 128+<value%> so 153 = 25% = 0x99
{/* 8 = Spare 2*/},
{/* 9 = Spare 3*/},
{ // 10 = Dimmer // From manual this is 0 for off, 128+<value%> so 153 = 25% = 0x99
"Off",
"25%", // 0x99 (simulator) = 153 dec
"50%", // 0xb2 (simulator) = 178 dec same as (0x99 + 25)
"75%", // 0xcb (simulator) = 203 dec
"100%" // 0xe4 = 228 dec
},
{/* Dimmer with full range */}
{/* 11 = Dimmer with full range */}
};
// DON'T FORGET TO CHANGE #define DIMMER_LIGHT_INDEX 10 in color_lights.h
@ -251,9 +251,15 @@ const char *get_currentlight_mode_name(clight_detail light, emulation_type proto
}
// Rename any modes depending on emulation type
if (protocol == ALLBUTTON) {
// Afternoon Skies = Afternoon Sky
if (strcmp(_color_light_options[light.lightType][light.currentValue],"Afternoon Skies") == 0) {
return "Afternoon Sky";
}
//Caribbean Blue = Caribbean Blu
if (strcmp(_color_light_options[light.lightType][light.currentValue],"Caribbean Blue") == 0) {
return "Caribbean Blu";
}
}
return _color_light_options[light.lightType][light.currentValue];

View File

@ -42,6 +42,7 @@
#define CONFIG_C
#include "rs_devices.h"
#include "config.h"
#include "utils.h"
#include "aq_serial.h"
@ -1321,7 +1322,7 @@ bool populatePumpData(struct aqualinkdata *aqdata, char *pumpcfg ,aqkey *button,
strncpy(pump->pumpName ,cleanwhitespace(value), PUMP_NAME_LENGTH-1);
} else if (strncasecmp(pumpcfg, "pumpID", 6) == 0) {
pump->pumpID = strtoul(cleanalloc(value), NULL, 16);
if ( (int)pump->pumpID >= PENTAIR_DEC_PUMP_MIN && (int)pump->pumpID <= PENTAIR_DEC_PUMP_MAX) {
if ( is_pentair_pump_id(pump->pumpID) ) {
pump->prclType = PENTAIR;
} else {
pump->prclType = JANDY;
@ -1858,10 +1859,8 @@ void check_print_config (struct aqualinkdata *aqdata)
aqdata->pumps[j].pumpName[0]=='\0'?"":aqdata->pumps[j].pumpName);
}
}
for (j = 0; j < aqdata->num_lights; j++) {
if (aqdata->lights[j].button == &aqdata->aqbuttons[i]) {
sprintf(ext,"Light Progm %-1d |",aqdata->lights[j].lightType);
}
if (isPLIGHT(aqdata->aqbuttons[i].special_mask)) {
sprintf(ext,"Light Progm %-1d |", ((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType);
}
if (isVBUTTON(aqdata->aqbuttons[i].special_mask)) {
if (aqdata->aqbuttons[i].rssd_code != NUL) {
@ -2061,12 +2060,12 @@ int save_config_js(const char* inBuf, int inSize, char* outBuf, int outSize, str
// The above will reset all the panel profocol masks since it re-sets the panel, so set them back here.
if (_aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x49) {
if (is_rsserialadapter_id(_aqconfig_.rssa_device_id)) {
addPanelRSserialAdapterInterface();
}
if (_aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) {
if (is_onetouch_id(_aqconfig_.extended_device_id)) {
addPanelOneTouchInterface();
} else if (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) {
} else if ( is_aqualink_touch_id(_aqconfig_.extended_device_id)) {
addPanelIAQTouchInterface();
}

View File

@ -14,9 +14,12 @@
* https://github.com/sfeakes/aqualinkd
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "rs_devices.h"
#include "devices_jandy.h"
#include "aq_serial.h"
#include "aqualink.h"
@ -134,62 +137,61 @@ bool processJandyPacket(unsigned char *packet_buffer, int packet_length, struct
interestedInNextAck = DRS_NONE;
previous_packet_to = NUL;
}
else if (READ_RSDEV_SWG && packet_buffer[PKT_DEST] >= JANDY_DEC_SWG_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_SWG_MAX)
else if (READ_RSDEV_SWG && is_swg_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_SWG;
printJandyDebugPacket("SWG", packet_buffer, packet_length);
rtn = processPacketToSWG(packet_buffer, packet_length, aqdata/*, _aqconfig_.swg_zero_ignore*/);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_ePUMP && ( (packet_buffer[PKT_DEST] >= JANDY_DEC_PUMP_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_PUMP_MAX)
|| (packet_buffer[PKT_DEST] >= JANDY_DEC_PUMP2_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_PUMP2_MAX) ) )
else if (READ_RSDEV_ePUMP && is_jandy_pump_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_EPUMP;
printJandyDebugPacket("EPump", packet_buffer, packet_length);
rtn = processPacketToJandyPump(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_JXI && packet_buffer[PKT_DEST] >= JANDY_DEC_JXI_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_JXI_MAX)
else if (READ_RSDEV_JXI && is_jxi_heater_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_JXI;
printJandyDebugPacket("JXi", packet_buffer, packet_length);
rtn = processPacketToJandyJXiHeater(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_LX && packet_buffer[PKT_DEST] >= JANDY_DEC_LX_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_LX_MAX)
else if (READ_RSDEV_LX && is_lx_heater_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_LX;
printJandyDebugPacket("LX", packet_buffer, packet_length);
rtn = processPacketToJandyLXHeater(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_CHEM_FEDR && packet_buffer[PKT_DEST] >= JANDY_DEC_CHEM_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_CHEM_MAX)
else if (READ_RSDEV_CHEM_FEDR && is_chem_feeder_id(packet_buffer[PKT_DEST] ))
{
interestedInNextAck = DRS_CHEM_FEED;
printJandyDebugPacket("ChemL", packet_buffer, packet_length);
rtn = processPacketToJandyChemFeeder(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_CHEM_ANLZ && packet_buffer[PKT_DEST] == JANDY_DEV_CHEM_ANLZ_MIN && packet_buffer[PKT_DEST] == JANDY_DEV_CHEM_ANLZ_MAX)
else if (READ_RSDEV_CHEM_ANLZ && is_chem_anlzer_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_CHEM_ANLZ;
printJandyDebugPacket("CemSnr", packet_buffer, packet_length);
rtn = processPacketToJandyChemAnalyzer(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_iAQLNK && packet_buffer[PKT_DEST] >= JANDY_DEV_AQLNK_MIN && packet_buffer[PKT_DEST] <= JANDY_DEV_AQLNK_MAX
else if (READ_RSDEV_iAQLNK && is_aqualink_touch_id(packet_buffer[PKT_DEST]) // should we add is_iaqualink_id() as well????
&& packet_buffer[PKT_DEST] != _aqconfig_.extended_device_id) // We would have already read extended_device_id frame
{
process_iAqualinkStatusPacket(packet_buffer, packet_length, aqdata);
}
else if (READ_RSDEV_HPUMP && packet_buffer[PKT_DEST] >= JANDY_DEV_HPUMP_MIN && packet_buffer[PKT_DEST] <= JANDY_DEV_HPUMP_MAX)
else if (READ_RSDEV_HPUMP && is_heat_pump_id(packet_buffer[PKT_DEST] ))
{
interestedInNextAck = DRS_HEATPUMP;
printJandyDebugPacket("HPump", packet_buffer, packet_length);
rtn = processPacketToHeatPump(packet_buffer, packet_length, aqdata);
previous_packet_to = packet_buffer[PKT_DEST];
}
else if (READ_RSDEV_JLIGHT && packet_buffer[PKT_DEST] >= JANDY_DEV_JLIGHT_MIN && packet_buffer[PKT_DEST] <= JANDY_DEV_JLIGHT_MAX)
else if (READ_RSDEV_JLIGHT && is_jandy_light_id(packet_buffer[PKT_DEST]))
{
interestedInNextAck = DRS_JLIGHT;
printJandyDebugPacket("JLight", packet_buffer, packet_length);

View File

@ -21,6 +21,7 @@
#include <string.h>
#include "aqualink.h"
#include "rs_devices.h"
#include "aq_serial.h"
#include "devices_pentair.h"
#include "utils.h"
@ -45,7 +46,7 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual
//static int pumpIndex = 1;
// Status from pump
if ( packet[PEN_PKT_CMD] == PEN_CMD_STATUS && packet[PEN_PKT_FROM] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_FROM] <= PENTAIR_DEC_PUMP_MAX ){
if ( packet[PEN_PKT_CMD] == PEN_CMD_STATUS && is_pentair_pump_id(packet[PEN_PKT_FROM] ) ){
// We have Pentair Pump packet, let's see if it's configured.
//printf("PUMP\n");
@ -97,7 +98,7 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual
//
}
// Set RPM/GPM to pump
else if (packet[PEN_PKT_CMD] == PEN_CMD_SPEED && packet[PEN_PKT_DEST] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEC_PUMP_MAX) {
else if (packet[PEN_PKT_CMD] == PEN_CMD_SPEED && packet[PEN_PKT_DEST] >= PENTAIR_DEV_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEV_PUMP_MAX) {
//(msg.extractPayloadByte(2) & 32) >> 5 === 0 ? 'RPM' : 'GPM';
@ -110,7 +111,7 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual
}
}
// Set power to pump
else if (packet[PEN_PKT_CMD] == PEN_CMD_POWER && packet[PEN_PKT_DEST] >= PENTAIR_DEC_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEC_PUMP_MAX) {
else if (packet[PEN_PKT_CMD] == PEN_CMD_POWER && packet[PEN_PKT_DEST] >= PENTAIR_DEV_PUMP_MIN && packet[PEN_PKT_DEST] <= PENTAIR_DEV_PUMP_MAX) {
if (packet[9] == 0x0A) {
LOG(DPEN_LOG, LOG_INFO,"Pentair Pump 0x%02hhx request set power ON\n",packet[PEN_PKT_DEST]);
} else {

View File

@ -187,9 +187,13 @@ struct iaqt_page_button *iaqtFindButtonByLabel(const char *label) {
for (i=0; i < IAQ_PAGE_BUTTONS; i++) {
//if (_pageButtons[i].state != 0 || _pageButtons[i].type != 0 || _pageButtons[i].unknownByte != 0)
if (rsm_strcmp((char *)buttons[i].name,label) == 0)
if (rsm_strcmp((char *)buttons[i].name,label) == 0) {
LOG(IAQT_LOG, LOG_DEBUG, "Found button '%s'\n",label);
return &buttons[i];
}
}
LOG(IAQT_LOG, LOG_DEBUG, "Did not find button '%s'\n",label);
return NULL;
}
@ -958,7 +962,8 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd
// NEED to rethink this approach. ie, selecting light needs to hold open while showing page, no page end, then select light color, then message "please wait", the finally done
}
}
} else if (isPDA_PANEL && packet[PKT_CMD] == CMD_IAQ_MSG_LONG) {
//} else if (isPDA_PANEL && packet[PKT_CMD] == CMD_IAQ_MSG_LONG) { // might want to add isPDA or JandyInfinateLight
} else if (packet[PKT_CMD] == CMD_IAQ_MSG_LONG) {
char *sp;
// Set disply message if PDA panel
memset(message, 0, AQ_MSGLONGLEN + 1);

View File

@ -615,19 +615,32 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
int typ = atoi(&buf[10]);
bool use_current_mode = false;
bool turn_off = false;
aqkey *key = NULL;
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE);
//char *buf = (char*)threadCtrl->thread_args;
if (btn < 0 || btn >= aqdata->total_buttons ) {
LOG(IAQT_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn);
cleanAndTerminateThread(threadCtrl);
return ptr;
struct programmerArgs *pargs = &threadCtrl->pArgs;
if (pargs->button != NULL) {
key = threadCtrl->pArgs.button;
val = pargs->value;
if (isPLIGHT(key->special_mask)) {
typ = ((clight_detail *)key->special_mask_ptr)->lightType;
} else {
LOG(IAQT_LOG, LOG_ERR, "Can't can't get light type for button %s\n", key->label);
cleanAndTerminateThread(threadCtrl);
return ptr;
}
} else {
if (btn < 0 || btn >= aqdata->total_buttons ) {
LOG(IAQT_LOG, LOG_ERR, "Can't program light mode on button %d\n", btn);
cleanAndTerminateThread(threadCtrl);
return ptr;
}
key = &aqdata->aqbuttons[btn];
}
aqkey *key = &aqdata->aqbuttons[btn];
//unsigned char code = key->code;
// We also need to cater for light being ON AND changing the color mode. we have extra OK to hit.
@ -635,11 +648,11 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
use_current_mode = true;
LOG(IAQT_LOG, LOG_INFO, "Light Programming #: %d, button: %s, color light type: %d, using current mode\n", val, key->label, typ);
// NOT SURE WHAT TO DO HERE..... No color mode and iaatouch doesn;t support last color in PDA mode.
} else if (val == -1) {
} else if (val == -1) {
turn_off = true;
LOG(IAQT_LOG, LOG_INFO, "Light Programming #: %d, button: %s, color light type: %d, Turning off\n", val, key->label, typ);
} else {
mode_name = light_mode_name(typ, val-1, IAQTOUCH);
} else {
mode_name = light_mode_name(typ, val, IAQTOUCH);
use_current_mode = false;
if (mode_name == NULL) {
LOG(IAQT_LOG, LOG_ERR, "Light Programming #: %d, button: %s, color light type: %d, couldn't find mode name '%s'\n", val, key->label, typ, mode_name);
@ -650,9 +663,12 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
}
}
// See if it's on the current page
button = iaqtFindButtonByLabel(key->label);
PRINTF("First button find = %s\n",button==NULL?"null":button->name);
if (button == NULL) {
// No luck, go to the device page
if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aqdata) == false )
@ -660,12 +676,14 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
button = iaqtFindButtonByLabel(key->label);
PRINTF("Second button find = %s\n",button==NULL?"null":button->name);
// If not found see if page has next
if (button == NULL && iaqtFindButtonByIndex(16)->type == 0x03 ) {
iaqt_queue_cmd(KEY_IAQTCH_NEXT_PAGE);
waitfor_iaqt_nextPage(aqdata);
// This will fail, since not looking at device page 2 buttons
button = iaqtFindButtonByLabel(key->label);
PRINTF("Third button find = %s\n",button==NULL?"null":button->name);
}
}
@ -673,7 +691,9 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find '%s' button on device list\n", key->label);
goto f_end;
}
PRINTF("FOUND button = %s\n",button==NULL?"null":button->name);
// WE have a iaqualink button, press it.
LOG(IAQT_LOG, LOG_DEBUG, "IAQ Touch found '%s' sending keycode '0x%02hhx'\n", key->label, button->keycode);
send_aqt_cmd(button->keycode);
// See if we want to use the last color, or turn it off
@ -681,6 +701,7 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
// After pressing the button, Just need to wait for 5 seconds and it will :-
// a) if off turn on and default to last color.
// b) if on, turn off. (pain that we need to wait 5 seconds.)
PRINTF("******** WAIT for next message\n");
waitfor_iaqt_queue2empty();
waitfor_iaqt_nextPage(aqdata);
if (use_current_mode) {
@ -707,19 +728,29 @@ void *set_aqualink_iaqtouch_light_colormode( void *ptr )
goto f_end;
}
// Now find the light mode and press it.
button = iaqtFindButtonByLabel(mode_name);
if (button == NULL) {
LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did find color '%s' in color light page\n",mode_name);
goto f_end;
}
LOG(IAQT_LOG, LOG_DEBUG, "IAQ Touch found '%s' sending keycode '0x%02hhx'\n", mode_name, button->keycode);
send_aqt_cmd(button->keycode);
waitfor_iaqt_queue2empty();
// Wait for popup message to disapera
unsigned char page;
while ( (page = waitfor_iaqt_nextPage(aqdata)) != NUL) {
PRINTF("******** next page is '0x%02hhx'\n",page);
}
//LOG(IAQT_LOG, LOG_ERR, "IAQ Touch WAIYING FOR 1 MESSAGES\n");
//waitfor_iaqt_messages(aqdata, 1);
// Finally found the color. select it
send_aqt_cmd(button->keycode);
waitfor_iaqt_nextPage(aqdata);
//send_aqt_cmd(button->keycode);
//waitfor_iaqt_nextPage(aqdata);
f_end:
goto_iaqt_page(IAQ_PAGE_HOME, aqdata);

View File

@ -1376,11 +1376,11 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
//aqualinkd/CHEM/pH/set
//aqualinkd/CHEM/ORP/set
if ( strncasecmp(ri2, "ORP", 3) == 0 ) {
_aqualink_data->orp = round(value);
SET_IF_CHANGED(_aqualink_data->orp, round(value), _aqualink_data->is_dirty);
rtn = uActioned;
LOG(NET_LOG,LOG_NOTICE, "%s: request to set ORP to %d\n",actionName[from],_aqualink_data->orp);
} else if ( strncasecmp(ri2, "Ph", 2) == 0 ) {
_aqualink_data->ph = value;
SET_IF_CHANGED(_aqualink_data->ph, value, _aqualink_data->is_dirty);
rtn = uActioned;
LOG(NET_LOG,LOG_NOTICE, "%s: request to set Ph to %.2f\n",actionName[from],_aqualink_data->ph);
} else {

95
source/rs_devices.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef RS_DEVICES_H_
#define RS_DEVICES_H_
#include <stdbool.h>
#define ALLBUTTON_MIN 0x08
#define ALLBUTTON_MAX 0x0B
#define RS_SERIAL_ADAPTER_MIN 0x48
#define RS_SERIAL_ADAPTER_MAX 0x49
#define ONETOUCH_MIN 0x40
#define ONETOUCH_MAX 0x43
#define AQUALINKTOUCH_MIN 0x30
#define AQUALINKTOUCH_MAX 0x33
#define IAQUALINK_MIN 0xA0
#define IAQUALINK_MAX 0xA3
#define SPA_REMOTE_MIN 0x20
#define SPA_REMOTE_MAX 0x23
#define REMOTE_PWR_CENT_MIN 0x28
#define REMOTE_PWR_CENT_MAX 0x2B
#define PC_DOCK_MIN 0x58
#define PC_DOCK_MAX 0x5B
#define PDA_MIN 0x60
#define PDA_MAX 0x63
#define JANDY_DEV_SWG_MIN 0x50
#define JANDY_DEV_SWG_MAX 0x53
#define JANDY_DEV_PUMP_MIN 0x78
#define JANDY_DEV_PUMP_MAX 0x7B
#define JANDY_DEV_PUMP2_MIN 0xE0
#define JANDY_DEV_PUMP2_MAX 0xE3
#define JANDY_DEV_JXI_MIN 0x68
#define JANDY_DEV_JXI_MAX 0x6B
#define JANDY_DEV_LX_MIN 0x38
#define JANDY_DEV_LX_MAX 0x3B
#define JANDY_DEV_CHEM_MIN 0x80
#define JANDY_DEV_CHEM_MAX 0x83
#define JANDY_DEV_HPUMP_MIN 0x70
#define JANDY_DEV_HPUMP_MAX 0x73
#define JANDY_DEV_JLIGHT_MIN 0xF0
#define JANDY_DEV_JLIGHT_MAX 0xF4
#define JANDY_DEV_CHEM_ANLZ_MIN 0x84
#define JANDY_DEV_CHEM_ANLZ_MAX 0x87
#define PENTAIR_DEV_PUMP_MIN 0x60
#define PENTAIR_DEV_PUMP_MAX 0x6F
// Helper macro for range checks
#define BETWEEN_UCHAR(val, min, max) ((unsigned char)(val) >= (unsigned char)(min) && (unsigned char)(val) <= (unsigned char)(max))
// --- Inline ID checkers ---
static inline bool is_allbutton_id(unsigned char val) { return BETWEEN_UCHAR(val, ALLBUTTON_MIN, ALLBUTTON_MAX); }
static inline bool is_rsserialadapter_id(unsigned char val) { return BETWEEN_UCHAR(val, RS_SERIAL_ADAPTER_MIN, RS_SERIAL_ADAPTER_MAX); }
static inline bool is_onetouch_id(unsigned char val) { return BETWEEN_UCHAR(val, ONETOUCH_MIN, ONETOUCH_MAX); }
static inline bool is_aqualink_touch_id(unsigned char val) { return BETWEEN_UCHAR(val, AQUALINKTOUCH_MIN, AQUALINKTOUCH_MAX); }
static inline bool is_iaqualink_id(unsigned char val) { return BETWEEN_UCHAR(val, IAQUALINK_MIN, IAQUALINK_MAX); }
static inline bool is_spa_remote_id(unsigned char val) { return BETWEEN_UCHAR(val, SPA_REMOTE_MIN, SPA_REMOTE_MAX); }
static inline bool is_remote_powercenter_id(unsigned char val){ return BETWEEN_UCHAR(val, REMOTE_PWR_CENT_MIN, REMOTE_PWR_CENT_MAX); }
static inline bool is_pc_dock_id(unsigned char val) { return BETWEEN_UCHAR(val, PC_DOCK_MIN, PC_DOCK_MAX); }
static inline bool is_pda_id(unsigned char val) { return BETWEEN_UCHAR(val, PDA_MIN, PDA_MAX); }
static inline bool is_swg_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_SWG_MIN, JANDY_DEV_SWG_MAX); }
static inline bool is_jxi_heater_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_JXI_MIN, JANDY_DEV_JXI_MAX); }
static inline bool is_lx_heater_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_LX_MIN, JANDY_DEV_LX_MAX); }
static inline bool is_chem_feeder_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_CHEM_MIN, JANDY_DEV_CHEM_MAX); }
static inline bool is_chem_anlzer_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_CHEM_ANLZ_MIN, JANDY_DEV_CHEM_ANLZ_MAX); }
static inline bool is_heat_pump_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_HPUMP_MIN, JANDY_DEV_HPUMP_MAX); }
static inline bool is_jandy_light_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_JLIGHT_MIN, JANDY_DEV_JLIGHT_MAX); }
static inline bool is_jandy_pump_std_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_PUMP_MIN, JANDY_DEV_PUMP_MAX); }
static inline bool is_jandy_pump_new_id(unsigned char val) { return BETWEEN_UCHAR(val, JANDY_DEV_PUMP2_MIN, JANDY_DEV_PUMP2_MAX); }
static inline bool is_jandy_pump_id(unsigned char val) {return is_jandy_pump_std_id(val) || is_jandy_pump_new_id(val);}
static inline bool is_pentair_pump_id(unsigned char val) { return BETWEEN_UCHAR(val, PENTAIR_DEV_PUMP_MIN, PENTAIR_DEV_PUMP_MAX); }
#endif // RS_DEVICES_H_

View File

@ -26,6 +26,7 @@
#include <fcntl.h>
#include <time.h>
#include "rs_devices.h"
#include "serial_logger.h"
#include "aq_serial.h"
#include "utils.h"
@ -161,6 +162,7 @@ int serial_logger (int rs_fd, char *port_name, int logLevel, int slogger_packets
#define EPUMP " <-- Jandy VSP ePump"
#define EPUMP2 " <-- Jandy VSP (rev W or newer)"
#define CHEM " <-- Chemlink"
#define CHEM_ANLZ " <-- TruSense"
#define JXI_HEATER " <-- JXi / LRZ Heater"
#define IAQLNK2 " <-- iAqualink 2.0"
@ -181,6 +183,72 @@ int serial_logger (int rs_fd, char *port_name, int logLevel, int slogger_packets
// 0xE0 -> this is pump ID on rev W panel (16 pumps available total) - so maybe last is 0xF0 or 0xEF
const char *getDevice(unsigned char ID)
{
if (ID >= 0x00 && ID <= 0x03)
return MASTER;
if (is_allbutton_id(ID))
return KEYPAD;
if (is_swg_id(ID))
return SWG;
if (is_spa_remote_id(ID))
return SPA_R;
if (is_aqualink_touch_id(ID))
return AQUA;
if (is_onetouch_id(ID))
return ONE_T;
if (is_rsserialadapter_id(ID))
return RS_SERL;
if (is_pc_dock_id(ID))
return PC_DOCK;
if (is_pda_id(ID))
return PDA;
if (is_lx_heater_id(ID))
return LX_HEATER;
if (is_jxi_heater_id(ID))
return JXI_HEATER;
if (is_heat_pump_id(ID))
return HEAT_PUMP;
if (is_jandy_pump_id(ID))
return EPUMP;
if (is_chem_feeder_id(ID))
return CHEM;
if (is_chem_anlzer_id(ID))
return CHEM_ANLZ;
if (is_iaqualink_id(ID))
return IAQLNK2;
if (is_remote_powercenter_id(ID))
return REM_PWR_CENT;
if (is_jandy_pump_std_id(ID))
return EPUMP;
if (is_jandy_pump_new_id(ID))
return EPUMP2;
if (is_jandy_light_id(ID))
return JWC_LIGHTS;
return UNKNOWN;
}
/*
const char *getDevice(unsigned char ID) {
if (ID >= 0x00 && ID <= 0x03)
return MASTER;
@ -241,6 +309,8 @@ const char *getDevice(unsigned char ID) {
return UNKNOWN;
}
*/
const char *getPentairDevice(unsigned char ID) {
if (ID >= 0x60 && ID <= 0x6F)
@ -715,7 +785,8 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
bool found_vsp =false;
bool found_jxi =false;
bool found_lx =false;
bool found_chem =false;
bool found_chemlink =false;
bool found_trusense =false;
bool found_pent_vsp =false;
bool found_iAqualnk =false;
@ -935,17 +1006,19 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
}
if (slog[i].inuse == true) {
if (slog[i].ID >= JANDY_DEC_SWG_MIN && slog[i].ID <= JANDY_DEC_SWG_MAX) {
if ( is_swg_id(slog[i].ID)) {
found_swg =true;
} else if (slog[i].ID >= JANDY_DEC_PUMP_MIN && slog[i].ID <= JANDY_DEC_PUMP_MAX) {
} else if ( is_jandy_pump_id(slog[i].ID )) {
found_vsp =true;
} else if (slog[i].ID >= JANDY_DEC_JXI_MIN && slog[i].ID <= JANDY_DEC_JXI_MAX) {
} else if ( is_jxi_heater_id(slog[i].ID)) {
found_jxi =true;
} else if (slog[i].ID >= JANDY_DEC_LX_MIN && slog[i].ID <= JANDY_DEC_LX_MAX) {
} else if ( is_lx_heater_id(slog[i].ID)) {
found_lx =true;
} else if (slog[i].ID >= JANDY_DEC_CHEM_MIN && slog[i].ID <= JANDY_DEC_CHEM_MAX) {
found_chem =true;
} else if (slog[i].ID >= JANDY_DEV_AQLNK_MIN && slog[i].ID <= JANDY_DEV_AQLNK_MAX) {
} else if ( is_chem_feeder_id(slog[i].ID )) {
found_chemlink =true;
} else if ( is_chem_anlzer_id(slog[i].ID )) {
found_trusense =true;
} else if ( is_iaqualink_id(slog[i].ID )) {
found_iAqualnk =true;
}
}
@ -960,7 +1033,7 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
(pent_slog[i].inuse == false)?canUseExtended(pent_slog[i].ID):getPentairDevice(pent_slog[i].ID));
if (pent_slog[i].inuse == true) {
if (pent_slog[i].ID >= PENTAIR_DEC_PUMP_MIN && pent_slog[i].ID <= PENTAIR_DEC_PUMP_MAX) {
if (is_pentair_pump_id(pent_slog[i].ID)) {
found_pent_vsp=true;
}
}
@ -1027,11 +1100,13 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_JXi = yes\n");
if (found_lx)
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_LX = yes\n");
if (found_chem)
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_Chem = yes\n");
if (found_chemlink)
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_ChemLink = yes\n");
if (found_trusense)
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_TruSense = yes\n");
if (found_iAqualnk)
LOG(SLOG_LOG, LOG_NOTICE, "read_RS485_iAqualink = yes\n");
else if (!found_iAqualnk && (extID >= JANDY_DEV_AQLNK_MIN && extID <= JANDY_DEV_AQLNK_MAX))
else if (!found_iAqualnk && (is_aqualink_touch_id(extID)))
LOG(SLOG_LOG, LOG_NOTICE, "enable_iaqualink = yes\n");
LOG(SLOG_LOG, LOG_NOTICE, "-------------------------\n");

View File

@ -52,8 +52,9 @@
--tile_status_text: rgb(87, 87, 87);
--value_tile_normal_color: rgb(4, 159, 248);
--value_tile_attention_color: rgb(255, 187, 0);
--value_tile_outofrange_color: rgb(255, 123, 0);
/*--value_tile_attention_color: rgb(255, 187, 0);*/
--value_tile_attention_color: rgb(255, 160, 0);
--value_tile_outofrange_color: rgb(255, 100, 0);
--options_radio_ball: 20px;
--options_radio_highlight: #2196F3;
@ -711,7 +712,7 @@
//console.log("The code is not running inside an iframe.");
}
console.log("Tile width "+window.getComputedStyle(document.documentElement).getPropertyValue('--tile-width'));
//console.log("Tile width "+window.getComputedStyle(document.documentElement).getPropertyValue('--tile-width'));
}
function populateLightProgram(type=0, current_mode="") {
@ -2808,8 +2809,10 @@
socket_di.onopen = function() {
// success!
get_devices();
// Set another load 1 minute from now just incase the server hasn't got all the devices yet
window.setTimeout(get_devices, (60 * 1000));
// Set recurring fetch every 1 minute
if (!window.devicesInterval) {
window.devicesInterval = setInterval(() => {get_devices();}, 60 * 1000);
}
// Get Status just incase control panel hasn't connected yet
get_status();
}
@ -2821,8 +2824,6 @@
} else if (data.type == 'devices') {
check_devices(data);
resetBackgroundSize();
//window.setTimeout(get_devices, (300 * 1000)); // Check for new dvices ever 5 mins.
window.setTimeout(get_devices, (60 * 1000)); // Check for new dvices ever 1 mins.
} else if (data.type == 'schedules') {
cs_schedules(data);
}