mirror of https://github.com/sfeakes/AqualinkD.git
parent
d945d438d7
commit
bdbe315c10
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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.
|
@ -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.
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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":"") );
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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./
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>";
|
||||
|
|
Loading…
Reference in New Issue