Release 2.3.8

pull/360/head^2 v2.3.8
sfeakes 2024-09-03 18:43:26 -05:00
parent d945d438d7
commit bdbe315c10
22 changed files with 290 additions and 56 deletions

View File

@ -13,7 +13,7 @@ AQ_RS16 = true
AQ_PDA = true
AQ_ONETOUCH = true
AQ_IAQTOUCH = true
AQ_MANAGER =true
AQ_MANAGER = true
#AQ_RS_EXTRA_OPTS = false
#AQ_CONTAINER = false // this is for compiling for containers

View File

@ -87,6 +87,7 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
* Create iAqualink Touch Simulator
* Probably decoded enough protocols for AuqlinkD to self configure.
<!--
* NEED TO FIX for PDA and iAQT protocol.
* Not always doing on/off
@ -110,7 +111,10 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
# Call for Help.
* The only Jandy devices I have not decoded yet are LX heater & Chemical Feeder. If you have either of these devices and are willing to post some logs, please let me know, or post in the [Discussions area](https://github.com/sfeakes/AqualinkD/discussions)
# Updates in 2.3.8 (Dev)
# Updates in 2.3.8
* <b>WARNING</b> Breaking change if you use dimmer (please change button_??_lightMode from 6 to 10)
* Fixed bugs with particular Jandy panel versions and color lights.
* Added support for more color lights, and sped up programming
* Code & Repo refactor
* Decoded more Pentair VSP pump status.
* Changed VSP pump status handling (display more in web UI).

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -260,7 +260,7 @@ use_panel_aux_labels=no
# 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.
#
# button_xx_lightMode = (0=Aqualink program, 1=Jandy, 2=Jandy LED, 3=SAm/SAL, 4=Color Logic, 5=Intellibrite, 6=Dimmer)
# button_xx_lightMode = (0=Aqualink program, 1=Jandy, 2=Jandy LED, 3=SAm/SAL, 4=Color Logic, 5=Intellibrite, 6=Hayw Univ Color, 7,8,9(future), 10=Dimmer)
#
# Below are settings for standard buttons on RS-8 Combo panel used as example.
button_01_label=Filter Pump

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -47,6 +47,14 @@ void processLEDstate(struct aqualinkdata *aq_data)
LOG(ALLB_LOG,LOG_NOTICE, "%s = %d", aq_data->aqbuttons[i].name, aq_data->aqualinkleds[i].state);
}
*/
#ifdef CLIGHT_PANEL_FIX // Use state from RSSD protocol for color light if it's on.
for (int i=0; i < aq_data->num_lights; i++) {
if ( aq_data->lights[i].RSSDstate == ON && aq_data->lights[i].button->led->state != ON ) {
aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate;
//LOG(ALLB_LOG,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aq_data->lights[i].button->label);
}
}
#endif
}
void setUnits(char *msg, struct aqualinkdata *aq_data)

View File

@ -61,6 +61,12 @@ uint8_t getPanelSupport( char *rev_string, int rev_len)
// Rev >=Q == iaqualink touch protocol.
// REv >= P == chemlink
// Rev >= HH serial adapter.
// Rev >= L == JandyColors Smart Light Control
// Rev >= MMM = 12V JandyColor Lights (also light dimmer)
// Rev >= N Hayward ColorLogic LED Light
// Rev >= O.1== Jandy WaterColors LED ( 9 colors )
// Rev >= T.0.1 == limited color light
// Rec >= T.2 == full color lights
// Rev Yg (and maybe before) has Pump label (not number), and also Virtual Device called Label Auxiliraries
if (REV[0] >= 81) // Q in ascii
@ -71,13 +77,25 @@ uint8_t getPanelSupport( char *rev_string, int rev_len)
if (REV[0] >= 79) // O in ascii
supported |= RSP_SUP_VSP;
if (REV[0] >= 73) // I in ascii
supported |= RSP_SUP_ONET;
if (REV[0] > 72 || (REV[0] == 72 && REV[1] == 72) ) // H in ascii
supported |= RSP_SUP_SERA;
if (REV[0] >= 77) // M in ascii
supported |= REP_SUP_CLIT1;
if (REV[0] >= 78) // N in ascii
supported |= REP_SUP_CLIT2;
if (REV[0] >= 79) // O in ascii
supported |= REP_SUP_CLIT3;
if (REV[0] > 84 || (REV[0] == 84 && REV[1] == 64 && REV[2] >= 50) ) // T in ascii (or T and . and 2 )
supported |= REP_SUP_CLIT4;
}
return supported;
@ -302,6 +320,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_PUMP;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_PUMP;
index++;
if (combo) {
@ -312,6 +331,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_SPA;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_SPA;
index++;
}
@ -322,6 +342,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX1;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX1;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[4-1];
@ -331,6 +352,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX2;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX2;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[3-1];
@ -340,6 +362,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX3;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX3;
index++;
@ -351,6 +374,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX4;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX4;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[8-1];
@ -360,6 +384,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX5;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX5;
index++;
}
@ -371,6 +396,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX6;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX6;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[1-1];
@ -380,6 +406,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX7;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX7;
index++;
}
#ifdef AQ_RS16
@ -401,6 +428,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB1;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX8;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[12-1];
@ -410,6 +438,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB2;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX9;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[1-1];
@ -419,6 +448,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB3;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX10;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[13-1];
@ -428,6 +458,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB4;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX11;
index++;
}
@ -439,6 +470,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB5;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX12;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[22-1]; // doesn't actually exist
@ -448,6 +480,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB6;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX13;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[23-1]; // doesn't actually exist
@ -456,6 +489,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].name = BTN_AUXB7;
aqdata->aqbuttons[index].code = KEY_AUXB7;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX14;
index++;
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[24-1]; // doesn't actually exist
@ -465,6 +499,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUXB8;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX15;
index++;
}
#endif // AQ_RS16
@ -479,6 +514,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
aqdata->aqbuttons[index].code = KEY_AUX6;
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
aqdata->aqbuttons[index].special_mask = 0;
aqdata->aqbuttons[index].rssd_code = RS_SA_AUX6;
index++;
}
//Dual panels (2/10 & 2/14) have no AUX7, they go from AUX6 to AUXB1, but the keycodes are the same as other panels
@ -664,9 +700,17 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
// Domoticz has a bad habbit of resending the same state back to us, when we use the PRESTATE_ONOFF option
// since allbutton (default) is stateless, and rssaadapter is statefull, use rssaadapter for any domoricz requests
set_aqualink_rssadapter_aux_state(deviceIndex, isON);
} else if (button->special_mask & PROGRAM_LIGHT && isRSSA_ENABLED) {
// If off and program light, use the RS serial adapter since that is overiding the state now.
set_aqualink_rssadapter_aux_state(deviceIndex, isON);
} else {
aq_send_allb_cmd(button->code);
}
#ifdef CLIGHT_PANEL_FIX
if (isRSSA_ENABLED) {get_aqualink_rssadapter_colorlight_statuses(aqdata);}
#endif
// Pre set device to state, next status will correct if state didn't take, but this will stop multiple ON messages setting on/off
//#ifdef PRESTATE_ONOFF
if (_aqconfig_.device_pre_state) {
@ -750,6 +794,20 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
_aqconfig_.light_programming_initial_off,
_aqconfig_.light_programming_mode );
aq_programmer(AQ_SET_LIGHTPROGRAM_MODE, buf, aqdata);
} else if (isRSSA_ENABLED && light->lightType != LC_DIMMER) {
unsigned char rssd_value = value;
set_aqualink_rssadapter_aux_extended_state(light->button, rssd_value);
} else if (isRSSA_ENABLED && light->lightType == LC_DIMMER) {
// Dimmer needs to be turned on first
set_aqualink_rssadapter_aux_extended_state(light->button, RS_SA_ON);
// Value 1 = 25, 1 = 50, 3 = 75, 4 = 100 (need to convert value into binary)
if (value >= 1 && value <= 4) {
// If value is not on of those vales, then ignore
unsigned char rssd_value = value * 25;
set_aqualink_rssadapter_aux_extended_state(light->button, rssd_value);
} else {
LOG(PANL_LOG,LOG_ERR, "Light mode %d is not valid for '%s'\n",value, light->button->label);
}
} else {
//sprintf(buf, "%-5s%-5d%-5d",value, button, light->lightType);
sprintf(buf, "%-5d%-5d%-5d",value, button, light->lightType);

View File

@ -38,6 +38,11 @@
#define RSP_SUP_VSP (1 << 2)
#define RSP_SUP_CHEM (1 << 3)
#define RSP_SUP_SERA (1 << 4) // Serial adapter
#define REP_SUP_CLIT1 (1 << 5) // color lights (first suppoer)
#define REP_SUP_CLIT2 (1 << 6) // color lights
#define REP_SUP_CLIT3 (1 << 7) // color lights
#define REP_SUP_CLIT4 (1 << 8) // Full color lights (T.2)
//void initButtons(struct aqualinkdata *aqdata);
void setPanelByName(struct aqualinkdata *aqdata, const char *str);

View File

@ -872,7 +872,7 @@ void send_packet(int fd, unsigned char *packet, int length)
//LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial write %d bytes\n",length-2);
//LOG(RSSD_LOG,LOG_DEBUG, "Serial write %d bytes, type 0x%02hhx cmd 0x%02hhx\n",length-2,packet[5],packet[6]);
if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL)
logPacketWrite(&packet[1], length-2);
logPacketWrite(&packet[1], length-1);
/*
if (getLogLevel(PDA_LOG) == LOG_DEBUG) {
char buff[1024];

View File

@ -18,6 +18,8 @@
#endif
#define CLIGHT_PANEL_FIX // Overcome bug in some jandy panels where color light status of on is not in LED status
#define TIME_CHECK_INTERVAL 3600
//#define TIME_CHECK_INTERVAL 100 // DEBUG ONLY
#define ACCEPTABLE_TIME_DIFF 120
@ -81,6 +83,7 @@ typedef struct aqualinkkey
// char *pda_label;
//#endif
unsigned char code;
unsigned char rssd_code;
int dz_idx;
uint8_t special_mask;
} aqkey;
@ -199,6 +202,10 @@ typedef enum clight_type {
LC_SAL,
LC_CLOGIG,
LC_INTELLIB,
LC_HAYWCL,
LC_SPARE_1,
LC_SPARE_2,
LC_SPARE_3,
LC_DIMMER,
NUMBER_LIGHT_COLOR_TYPES // This is used to size and count so add more prior to this
} clight_type;
@ -216,6 +223,7 @@ typedef struct clightd
clight_type lightType;
aqkey *button;
int currentValue;
aqledstate RSSDstate; // state from rs serial adapter
} clight_detail;
@ -305,6 +313,9 @@ struct aqualinkdata
struct timespec last_active_time;
struct timespec start_active_time;
#endif
// Overcome color light bug, by reconnecting allbutton panel.
//bool reconnectAllButton;
};

View File

@ -694,6 +694,16 @@ int startup(char *self, char *cfgFile)
_aqualink_data.aqbuttons[i].name, _aqualink_data.aqbuttons[i].label, ext);
}
}
/*
for (i=0; i < _aqualink_data.total_buttons; i++)
{
LOG(AQUA_LOG,LOG_NOTICE, "Button index=%d, label=%s, code=0x%02hhx, rssd code=0x%02hhx\n",
i,
_aqualink_data.aqbuttons[i].label,
_aqualink_data.aqbuttons[i].code,
_aqualink_data.aqbuttons[i].rssd_code);
}
*/
if (_aqconfig_.deamonize == true)
{
@ -878,6 +888,7 @@ void main_loop()
for (i=0; i < MAX_LIGHTS; i++) {
_aqualink_data.lights[i].currentValue = TEMP_UNKNOWN;
_aqualink_data.lights[i].RSSDstate = OFF;
}
if (_aqconfig_.force_swg == true) {

View File

@ -7,13 +7,25 @@
#include "color_lights.h"
/*
Jandy Colors
Jandy LED Light
Sam/SL
Color Logic
Intelibright
Haywood Universal Color
*/
/****** This list MUST be in order of clight_type enum *******/
const 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.
{ "bogus" },
{ // Jandy Color
"Alpine White",
"",
"Alpine White", // 0x41
"Sky Blue",
"Cobalt Blue",
"Caribbean Blue",
@ -21,10 +33,12 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Emerald Green",
"Emerald Rose",
"Magenta",
"Garnet Red",
"Violet",
"Color Splash"
},
{ // Jandy LED
"",
"Alpine White",
"Sky Blue",
"Cobalt Blue",
@ -41,6 +55,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Disco Tech"
},
{ // SAm/SAL
"",
"White",
"Light Green",
"Green",
@ -49,27 +64,23 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Lavender",
"Magenta"
},
{ // Color Logic
"Voodoo Lounge",
"Deep Blue Sea",
//"Royal Blue",
"Afternoon Skies", // 'Afternoon Sky' on allbutton, Skies on iaqtouch
//"Aqua Green",
"Emerald",
{ // Color Logic
"",
"Voodoo Lounge", // 0x41 (both home and sim)
"Deep Blue Sea", // 0x42 (both gome and sim)
"Afternoon Skies", // 0x44 home // 0x43 sim // 'Afternoon Sky' on allbutton, Skies on iaqtouch
"Emerald", // 0x44
"Sangria",
"Cloud White",
//"Warm Red",
//"Flamingo",
//"Vivid Violet",
//"Sangria",
"Twilight",
"Tranquility",
"Gemstone",
"USA",
"Mardi Gras",
"Cool Cabaret"
},
"Cloud White", // 0x46
"Twilight", // 0x4c (home panel) // 0x47
"Tranquility", // 0x4d (home panel) // 0x48
"Gemstone", // 0x4e (home panel) // 0x49 (simulator)
"USA", // 0x4f (home panel) // 0x4a (simulator)
"Mardi Gras", // 0x50 (home panel) // 0x4b (simulator)
"Cool Cabaret" // 0x51 (home panel) // 0x4c
},
{ // IntelliBrite
"",
"SAm",
"Party",
"Romance",
@ -83,15 +94,67 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"White",
"Magenta"
},
{ // Dimmer
"25%",
"50%",
"75%",
"100%"
{ // Haywood Universal Color
"",
"Voodoo Lounge", // 0x41 (both home and sim) // Looks like 28 + <value or index> = 0x41 = 1st index
"Deep Blue Sea", // 0x42 (both gome and sim)
"Royal Blue", // // 0x43 home // non
"Afternoon Skies", // 0x44 home // 0x43 sim // 'Afternoon Sky' on allbutton, Skies on iaqtouch
"Aqua Green", //
"Emerald", // 0x44
"Cloud White", // 0x46
"Warm Red", //
"Flamingo", //
"Vivid Violet", //
"Sangria", // 0x4b (home panel) // Non existant
"Twilight", // 0x4c (home panel) // 0x47
"Tranquility", // 0x4d (home panel) // 0x48
"Gemstone", // 0x4e (home panel) // 0x49 (simulator)
"USA", // 0x4f (home panel) // 0x4a (simulator)
"Mardi Gras", // 0x50 (home panel) // 0x4b (simulator)
"Cool Cabaret" // 0x51 (home panel) // 0x4c
},
{/*Spare 1*/},
{/*Spare 2*/},
{/*Spare 3*/},
{ // Dimmer // From manual this is 0 for off, 128+<value%> so 153 = 25% = 0x99
"",
"25%", // 0x99 (simulator) = 153 dec
"50%", // 0xb2 (simulator) = 178 dec same as (0x99 + 25)
"75%", // 0xcb (simulator) = 203 dec
"100%" // 0xe4 = 228 dec
}
};
/*
void deleteLightOption(int type, int index)
{
int arrlen = LIGHT_COLOR_OPTIONS;
memmove(_color_light_options[type]+index, _color_light_options[type]+index+1, (--arrlen - index) * sizeof *_color_light_options[type]);
}
void setColorLightsPanelVersion(uint8_t supported)
{
static bool set = false;
if (set)
return;
if ((supported & REP_SUP_CLIT4) == REP_SUP_CLIT4)
return; // Full panel support, no need to delete anything
//deleteLightOption(4, 11); // Color Logic "Sangria"
deleteLightOption(4, 9); // Color Logic "Vivid Violet",
deleteLightOption(4, 8); // Color Logic "Flamingo"
deleteLightOption(4, 7); // Color Logic "Warm Red",
deleteLightOption(4, 4); // Color Logic "Aqua Green"
deleteLightOption(4, 2); // Color Logic "Royal Blue"
set = true;
}
*/
const char *light_mode_name(clight_type type, int index, emulation_type protocol)
{
// Rename any modes depending on emulation type
@ -139,8 +202,8 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)
length += sprintf(buffer+length, "_light_program[0] = light_program;\n");
for (i=1; i < NUMBER_LIGHT_COLOR_TYPES; i++) {
length += sprintf(buffer+length, "_light_program[%d] = [", i);
for (j=0; j < LIGHT_COLOR_OPTIONS; j++) {
length += sprintf(buffer+length, "_light_program[%d] = [ ", i);
for (j=1; j < LIGHT_COLOR_OPTIONS; j++) { // Start a 1 since index 0 is blank
if (_color_light_options[i][j] != NULL)
length += sprintf(buffer+length, "\"%s%s\",", _color_light_options[i][j], (isShowMode(_color_light_options[i][j])?" - Show":"") );
}

View File

@ -6,9 +6,13 @@
#include "aq_programmer.h"
#define LIGHT_COLOR_NAME 16
#define LIGHT_COLOR_OPTIONS 17
#define LIGHT_COLOR_OPTIONS 19
//#define LIGHT_COLOR_TYPES LC_DIMMER+1
// The status returned from RS Serial Adapter has this added as a base.
#define RSSD_COLOR_LIGHT_OFFSET 64
#define RSSD_DIMMER_LIGHT_OFFSET 128
/*
// color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite)
typedef enum clight_type {

View File

@ -949,7 +949,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
send_mqtt_aux_msg(nc, _aqualink_data->lights[i].button->name, LIGHT_PROGRAM_TOPIC, _aqualink_data->lights[i].currentValue);
sprintf(topic, "%s%s/name", _aqualink_data->lights[i].button->name, LIGHT_PROGRAM_TOPIC);
send_mqtt_string_msg(nc, topic, light_mode_name(_aqualink_data->lights[i].lightType, _aqualink_data->lights[i].currentValue - 1, ALLBUTTON));
send_mqtt_string_msg(nc, topic, light_mode_name(_aqualink_data->lights[i].lightType, _aqualink_data->lights[i].currentValue, ALLBUTTON));
}
}
}

View File

@ -8,6 +8,7 @@
#include "aqualink.h"
#include "serialadapter.h"
#include "packetLogger.h"
#include "color_lights.h"
#define RSSA_QLEN 20
@ -91,6 +92,7 @@ void queue_aqualink_rssadapter_setpoint(unsigned char typeID, int val) {
push_rssa_cmd(setSP);
}
/* NSF Need to delete this and use aqbuttonp[].rssd_code */
unsigned char devID(int bIndex) {
// pool = 0; spa = 1; aux1 = 2 etc
// rssa pool / spa are different. aux1 = 21 (0x15) then goes up from their in order.
@ -111,7 +113,8 @@ unsigned char devID(int bIndex) {
return 0x00;
}
void rssadapter_device_state(unsigned char devID, unsigned char state) {
void rssadapter_device_state(const unsigned char devID, const unsigned char state) {
unsigned char setDev[] = {0x00,0x01,state,devID};
push_rssa_cmd(setDev);
}
@ -121,11 +124,19 @@ void rssadapter_device_off(unsigned char devID) {
push_rssa_cmd(setDev);
}
*/
void set_aqualink_rssadapter_aux_extended_state(const aqkey *button, const unsigned char state) {
LOG(RSSA_LOG,LOG_DEBUG, "Sending 0x%02hhx to %s\n",state, button->label);
rssadapter_device_state(button->rssd_code, state);
}
void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn)
{
LOG(RSSA_LOG,LOG_DEBUG, "Turning button %d %s\n",buttonIndex,(turnOn?"On":"Off"));
rssadapter_device_state( devID(buttonIndex), (turnOn?0x81:0x80) );
rssadapter_device_state( devID(buttonIndex), (turnOn?RS_SA_ON:RS_SA_OFF) );
}
void increase_aqualink_rssadapter_pool_setpoint(char *args, struct aqualinkdata *aqdata) {
@ -185,11 +196,19 @@ void set_aqualink_rssadapter_spa_setpoint(char *args, struct aqualinkdata *aqdat
*/
}
void DEBUG_GET_STATE(struct aqualinkdata *aq_data, int buttonIndex) {
LOG(RSSA_LOG,LOG_DEBUG, "Getting state for index=%d %s\n",buttonIndex,aq_data->aqbuttons[buttonIndex].label);
rssadapter_device_state( devID(buttonIndex), 0x00 );
#ifdef CLIGHT_PANEL_FIX
/* This is to overcome Jandy bug where panel doesn;t show the state of color light */
void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aq_data)
{
for (int i=0; i < aq_data->num_lights; i++) {
if (aq_data->lights[i].lightType != LC_PROGRAMABLE ) {
// LC_PROGRAMABLE is aqualinkd to set, so works as normal button
rssadapter_device_state(aq_data->lights[i].button->rssd_code, 0x00); // 0x00 meand Get curent state
}
}
}
#endif
void get_aqualink_rssadapter_setpoints() {
//push_rssa_cmd(getModel);
@ -231,13 +250,11 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
//LOG(RSSA_LOG,LOG_DEBUG, " Received message\n");
//debuglogPacket(RSSA_LOG, packet, length, true);
if ( (cnt % 20 == 0) || cnt == 10 ) {
//if (!(cnt % 20) || cnt == 10 ) {
DEBUG_GET_STATE(aq_data, 5); // 4 = AUX 3
#ifdef CLIGHT_PANEL_FIX
if ( (cnt % 10 == 0) || cnt == 0 ) { // NSF Change to 20 and 1
get_aqualink_rssadapter_colorlight_statuses(aq_data);
}
#endif
if (cnt == 0 || cnt >= 250) {
LOG(RSSA_LOG,LOG_INFO, "Queue device update requests\n");
@ -311,13 +328,57 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
LOG(RSSA_LOG,LOG_INFO,"Pool SP2 is %d\n", packet[6]);
aq_data->spa_htr_set_point = (int) packet[6];
rtn = true;
} else if (packet[4] == 0x03) {
} else if (packet[4] == 0x03 || packet[4] == 0x02) { // 03 reply from query state, 02 reply from set state
// These are device status messages
LOG(RSSA_LOG,LOG_DEBUG,"AUX?? 0x%02hhx state is 0x%02hhx '%s' %s\n",
packet[7],
packet[6],
aq_data->aqbuttons[(packet[7] - (unsigned char)0x13)].label,
packet[6]==0x00?"off":"on");
for (int i=0; i < aq_data->num_lights; i++) {
if (aq_data->lights[i].lightType != LC_PROGRAMABLE &&
aq_data->lights[i].button->rssd_code == packet[7] ) {
// CHANGE TO DEBUG BEFORE RELEASE
if (aq_data->lights[i].lightType != LC_DIMMER) {
LOG(RSSA_LOG,LOG_DEBUG,"ColorLight '%s' is %s 0x%02hhx value name '%s'\n",
aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON",
packet[6],
packet[6]==0x00?"--":light_mode_name( aq_data->lights[i].lightType,(packet[6] - RSSD_COLOR_LIGHT_OFFSET), RSSADAPTER) );
} else if (aq_data->lights[i].lightType == LC_DIMMER) {
LOG(RSSA_LOG,LOG_DEBUG,"DimmerLight '%s' is %s 0x%02hhx value '%d'%%\n",
aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON",
packet[6],
packet[6]==0x00?0:(packet[6] - RSSD_DIMMER_LIGHT_OFFSET));
}
aq_data->lights[i].RSSDstate = (packet[6]==0x00?OFF:ON);
#ifdef CLIGHT_PANEL_FIX
// Set LED to the correct state, but only print warning if light is on and panel states off.
if (aq_data->lights[i].RSSDstate == ON && aq_data->lights[i].button->led->state == OFF) {
// 0x00 is off, 0x01 is usually on, but get 0x44 for color light 0x4e=gemstone, 0x41=vodo
LOG(RSSA_LOG,LOG_DEBUG,"ColorLight '%s' is out of sync with panel, light is '%s', panel states '%s', Fixed Jany bug!\n",
aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON",
aq_data->lights[i].button->led->state==OFF?"OFF":"ON");
}
aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate;
#endif
// Set the color index. (packet[6] - RSSD_COLOR_LIGHT_OFFSET)-1
if (aq_data->lights[i].lightType != LC_DIMMER) {
int color_index = (packet[6] - RSSD_COLOR_LIGHT_OFFSET);
if (color_index <= 0 || color_index > LIGHT_COLOR_OPTIONS)
color_index = 0;
//LOG(RSSA_LOG,LOG_DEBUG,"Color index %d\n",color_index);
aq_data->lights[i].currentValue = color_index;
} else if (aq_data->lights[i].lightType == LC_DIMMER) {
int dimmer_index = (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25;
if (dimmer_index < 0 || dimmer_index > 4)
dimmer_index = 0;
//LOG(RSSA_LOG,LOG_DEBUG,"Dimmer index %d\n",dimmer_index);
aq_data->lights[i].currentValue = dimmer_index;
}
}
}
#ifdef AQ_RS16
if (packet[7] == RS_SA_AUX12) {
LOG(RSSA_LOG,LOG_INFO,"AUX12 %d\n", packet[6]);
@ -444,7 +505,7 @@ In return
0x10|0x02|0x48|0x13 |0x02 |0x00 |0x0d|0x10|0x8c|0x10|0x03|
0x10|0x02|0x48|MsgType|Status1|Status2|0x0e|DeviceID|0xXX|0x10|0x03|
MsgType - Byte 3 = 0x13 (some state message)??
StatType - Byte 4 = 0x02 or 0x03 (not sure meaning) Status Type ????
StatType - Byte 4 = 0x02 reply from setstate / 0x03 reply from getstatus (I THINK)
Status1 - Byte 5 = 0x00 0x01 (???) if Byte4 is 0x02 then this is state 0x00=off 0x01=on /
Status2 - Byte 6 = 0x00 0x01 0x0e(option switch set can't change???) if byte4 is 0x03, this this looks to be state
DeviceID - Byte 7 = Should match request.
@ -1324,4 +1385,4 @@ Debug: RS Serial: To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|
*/
#endif
#endif

View File

@ -11,13 +11,19 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
//void rssadapter_device_off(unsigned char devID);
void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn);
//void set_aqualink_rssadapter_aux_extended_state(int buttonIndex, const unsigned char state);
void set_aqualink_rssadapter_aux_extended_state(const aqkey *button, const unsigned char state);
void get_aqualink_rssadapter_setpoints();
void set_aqualink_rssadapter_pool_setpoint(char *args, struct aqualinkdata *aqdata);
void set_aqualink_rssadapter_spa_setpoint(char *args, struct aqualinkdata *aqdata);
void increase_aqualink_rssadapter_pool_setpoint(char *args, struct aqualinkdata *aqdata);
void increase_aqualink_rssadapter_spa_setpoint(char *args, struct aqualinkdata *aqdata);
#ifdef CLIGHT_PANEL_FIX
void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aqdata);
#endif
/*
CAN ONLY REPLY WITH BELOW TO STATUS MESSAGE, UNLESS FOLLOWON 0x07
@ -43,6 +49,9 @@ Same as previous reply.
*/
#define RS_SA_ON 0x81
#define RS_SA_OFF 0x80
#define RS_SA_DEVSTATUS 0x13
// Setpoints changes are in this group./

View File

@ -2,4 +2,4 @@
#define AQUALINKD_NAME "Aqualink Daemon"
#define AQUALINKD_SHORT_NAME "AqualinkD"
#define AQUALINKD_VERSION "2.3.8 (dev 0.5)"
#define AQUALINKD_VERSION "2.3.8"

View File

@ -683,7 +683,7 @@
var row;
row = tbody.deleteRow(2);
row = tbody.insertRow(2);
if (type == 6) {
if (type == 10) {
row.innerHTML = "<td align='center'>Dimmer</td><td align='center'></td>";
} else {
row.innerHTML = "<td align='center'>Solid Color</td><td align='center'>Light Show</td>";