Skip to content

Commit

Permalink
2.5.0 (Dev 0.3)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfeakes committed Nov 10, 2024
1 parent 6bba146 commit f62f7f7
Show file tree
Hide file tree
Showing 25 changed files with 245 additions and 63 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,17 @@ NEED TO FIX FOR THIS RELEASE.
* PDA panel Rev 6.0 of newer WITH a Jandy iAqualink device attached can use `read_RS485_iAqualink = yes` to speed up device state change detection.
* Added MQTT vsp_pump/speed/set for setting speed (RPM/GPM) by %, for automation hubs.
* Added full dimmer range support for dimmable lights (not limited to 0,25,50,75,100 anymore)
* Added vsp and dimmer to hassio and homebridge-aqualinkd plugin as full range dimmer controls.
* Added vsp and dimmer to Hassio and homebridge-aqualinkd plugin as full range dimmer controls.
* Added color lights & dimmer to Hassio as selectors.
* Updated UI for support fullrange dimmer.
* cleaned up code for spa_mode and spa for newer pannels.
* Allow VSP to be asigned to virtual button.
* Fixed bug with timer not starting.
* Increase Speed of detecting device state changes.
* Added iAqualink2 protocol support.
* Faster OneTouch device support
* Chaged color light logic.
* Faster OneTouch device support.


# Updates in Release 2.4.0
* <b>WARNING</b> Breaking change if you use dimmer (please change button_??_lightMode from 6 to 10)
Expand Down
Binary file modified release/aqualinkd-amd64
Binary file not shown.
Binary file modified release/aqualinkd-arm64
Binary file not shown.
Binary file modified release/aqualinkd-armhf
Binary file not shown.
3 changes: 3 additions & 0 deletions release/aqualinkd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ device_id=0x00
# Valid ID's are 0x30, 0x31, 0x32 & 0x33. for Aqualink Touch
#extended_device_id=0x31

# If using 0x30 to 0x33 for extended_device_id, then enable below if you want to use virtual buttons
#enable_iaqualink=yes


# If you have extended_device_id set, then you can also use that ID for programming some features.
# This means that you can turn things on/off while AqualinkD is programming certian features.
Expand Down
Binary file modified release/serial_logger-arm64
Binary file not shown.
Binary file modified release/serial_logger-armhf
Binary file not shown.
12 changes: 12 additions & 0 deletions source/allbutton.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "rs_msg_utils.h"
#include "devices_jandy.h"
#include "allbutton_aq_programmer.h"
#include "color_lights.h"

/* Below can also be called from serialadapter.c */
void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmask_t from)
Expand Down Expand Up @@ -66,6 +67,17 @@ void processLEDstate(struct aqualinkdata *aq_data, unsigned char *packet, logmas
aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate;
//LOG(from,LOG_WARNING,"Fix Jandy bug, color light '%s' is on, setting status to match!\n", aq_data->lights[i].button->label);
}

// Below is for aqualinkd programmable light, set color mode to last if something else turns it on or off.
if (aq_data->lights[i].lightType == LC_PROGRAMABLE && ! in_light_programming_mode(aq_data)) {
if (aq_data->lights[i].button->led->state == OFF && aq_data->lights[i].currentValue != 0) {
set_currentlight_value(&aq_data->lights[i], 0);
//LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE 0 ******\n");
} else if (aq_data->lights[i].button->led->state == ON && aq_data->lights[i].currentValue == 0 && aq_data->lights[i].lastValue != 0) {
set_currentlight_value(&aq_data->lights[i], aq_data->lights[i].lastValue);
//LOG(ALLB_LOG,LOG_NOTICE,"****** SET LIGHT MODE %d ******\n",aq_data->lights[i].lastValue);
}
}
}
#endif
}
Expand Down
25 changes: 20 additions & 5 deletions source/aq_panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ 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 ((button->special_mask & PROGRAM_LIGHT) == PROGRAM_LIGHT && button->led->state == OFF) {
if (isPLIGHT(button->special_mask) && button->led->state == OFF) {
// OK Programable light, and no light mode selected. Now let's work out best way to turn it on. serial_adapter protocol will to it without questions,
// all other will require programmig.
if (isRSSA_ENABLED) {
Expand All @@ -812,9 +812,14 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
//set_light_mode("0", deviceIndex); // 0 means use current light mode
programDeviceLightMode(aqdata, 0, deviceIndex); // 0 means use current light mode
}

// If aqualinkd programmable light, it will come on at last state, so set that.
if ( /*isPLIGHT(button->special_mask) &&*/ ((clight_detail *)button->special_mask_ptr)->lightType == LC_PROGRAMABLE ) {
((clight_detail *)button->special_mask_ptr)->currentValue = ((clight_detail *)button->special_mask_ptr)->lastValue;
}
} else if (isVBUTTON(button->special_mask)) {
// Virtual buttons only supported with Aqualink Touch
LOG(PANL_LOG, LOG_INFO, "Set state for Vitrual Button %s code=0x%02hhx iAqualink2 enabled=%sn",button->name, button->rssd_code, isIAQT_ENABLED?"Yes":"No");
LOG(PANL_LOG, LOG_INFO, "Set state for Virtual Button %s code=0x%02hhx iAqualink2 enabled=%s\n",button->name, button->rssd_code, isIAQT_ENABLED?"Yes":"No");
if (isIAQT_ENABLED) {
// If it's one of the pre-defined onces & iaqualink is enabled, we can set it easile with button.

Expand Down Expand Up @@ -845,7 +850,7 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
//} else if ( source == NET_TIMER && isRSSA_ENABLED ) {
// Timer will sometimes send duplicate, so use RSSA since that protocol has on/off rather than toggle
// set_aqualink_rssadapter_aux_state(button, isON);
} else if (button->special_mask & PROGRAM_LIGHT && isRSSA_ENABLED) {
} else if (isPLIGHT(button->special_mask) && isRSSA_ENABLED) {
// If off and program light, use the RS serial adapter since that is overiding the state now.
set_aqualink_rssadapter_aux_state(button, isON);
} else {
Expand All @@ -854,8 +859,16 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
aq_send_allb_cmd(button->code);
}


// If we turned off a aqualinkd programmable light, set the mode to 0
if (isPLIGHT(button->special_mask) && ! isON && ((clight_detail *)button->special_mask_ptr)->lightType == LC_PROGRAMABLE ) {
updateButtonLightProgram(aqdata, 0, deviceIndex);
}

#ifdef CLIGHT_PANEL_FIX
if (isRSSA_ENABLED) {get_aqualink_rssadapter_colorlight_statuses(aqdata);}
if (isPLIGHT(button->special_mask) && isRSSA_ENABLED) {
get_aqualink_rssadapter_button_status(button);
}
#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
Expand Down Expand Up @@ -1125,7 +1138,9 @@ void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button
return;
}

light->currentValue = value;
light->currentValue = value;
if (value > 0)
light->lastValue = value;
}

clight_detail *getProgramableLight(struct aqualinkdata *aqdata, int button)
Expand Down
2 changes: 1 addition & 1 deletion source/aq_programmer.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const func_ptr _prog_functions[AQP_RSSADAPTER_MAX] = {
[AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM] = set_aqualink_iaqtouch_pump_vs_program,
[AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE] = set_aqualink_iaqtouch_light_colormode,
[AQ_SET_IAQTOUCH_DEVICE_ON_OFF] = set_aqualink_iaqtouch_device_on_off,
[AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF] = set_aqualink_iaqtouch_onetouch_on_off,
//[AQ_SET_IAQTOUCH_ONETOUCH_ON_OFF] = set_aqualink_iaqtouch_onetouch_on_off, // Not finished and not needed
[AQ_PDA_INIT] = set_aqualink_PDA_init,
[AQ_PDA_WAKE_INIT] = set_aqualink_PDA_wakeinit,
[AQ_PDA_DEVICE_STATUS] = get_aqualink_PDA_device_status,
Expand Down
1 change: 1 addition & 0 deletions source/aqualink.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ typedef struct clightd
clight_type lightType;
aqkey *button;
int currentValue;
int lastValue; // Used for AqualinkD self programming
aqledstate RSSDstate; // state from rs serial adapter
} clight_detail;

Expand Down
3 changes: 2 additions & 1 deletion source/aqualinkd.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,8 @@ void main_loop()
}

for (i=0; i < MAX_LIGHTS; i++) {
_aqualink_data.lights[i].currentValue = TEMP_UNKNOWN;
//_aqualink_data.lights[i].currentValue = TEMP_UNKNOWN;
_aqualink_data.lights[i].currentValue = 0;
_aqualink_data.lights[i].RSSDstate = OFF;
}

Expand Down
100 changes: 86 additions & 14 deletions source/color_lights.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ 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] =
//char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
{
// AqualnkD Colors ignored as no names in control panel.
{ "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18" },
{ "Off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18" },
{ // Jandy Color
"",
"Off",
"Alpine White", // 0x41
"Sky Blue",
"Cobalt Blue",
Expand All @@ -38,7 +38,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Color Splash"
},
{ // Jandy LED
"",
"Off",
"Alpine White",
"Sky Blue",
"Cobalt Blue",
Expand All @@ -55,7 +55,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Disco Tech"
},
{ // SAm/SAL
"",
"Off",
"White",
"Light Green",
"Green",
Expand All @@ -65,7 +65,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Magenta"
},
{ // Color Logic
"",
"Off",
"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
Expand All @@ -80,7 +80,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Cool Cabaret" // 0x51 (home panel) // 0x4c
},
{ // IntelliBrite
"",
"Off",
"SAm",
"Party",
"Romance",
Expand All @@ -95,7 +95,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"Magenta"
},
{ // 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)
"Royal Blue", // // 0x43 home // non
Expand All @@ -118,7 +118,7 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
{/*Spare 2*/},
{/*Spare 3*/},
{ // 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
Expand Down Expand Up @@ -158,9 +158,55 @@ void setColorLightsPanelVersion(uint8_t supported)
}
*/

bool set_aqualinkd_light_mode_name(char *name, int index, bool isShow)
{
static bool reset = false;

// Reset all options only once.
if (!reset) {
reset = true;
for (int i=1; i<LIGHT_COLOR_OPTIONS; i++) {
_color_light_options[0][i] = NULL;
}
}

_color_light_options[0][index] = name;

return true;
}

const char *get_currentlight_mode_name(clight_detail light, emulation_type protocol)
{
/*
if (light.lightType == LC_PROGRAMABLE && light.button->led->state == OFF) {
return "Off";
}
*/

// Programmable light that's on but no mode, just return blank
if (light.lightType == LC_PROGRAMABLE && light.button->led->state == ON && light.currentValue == 0) {
return "";
}

if (light.currentValue < 0 || light.currentValue > LIGHT_COLOR_OPTIONS ){
return "";
}

// Rename any modes depending on emulation type
if (protocol == ALLBUTTON) {
if (strcmp(_color_light_options[light.lightType][light.currentValue],"Afternoon Skies") == 0) {
return "Afternoon Sky";
}
}

return _color_light_options[light.lightType][light.currentValue];
}

// This should not be uses for getting current lightmode name since it doesn;t have full logic

const char *light_mode_name(clight_type type, int index, emulation_type protocol)
{
if (index <= 0 || index > LIGHT_COLOR_OPTIONS ){
if (index < 0 || index > LIGHT_COLOR_OPTIONS ){
return "";
}

Expand All @@ -174,6 +220,7 @@ const char *light_mode_name(clight_type type, int index, emulation_type protocol
return _color_light_options[type][index];
}


bool isShowMode(const char *mode)
{
if (strcmp(mode, "Color Splash") == 0 ||
Expand Down Expand Up @@ -209,23 +256,32 @@ void set_currentlight_value(clight_detail *light, int index)
light->currentValue = index;
} else {
// We want to leave the last color, so if 0 don't do anything, but set to 0 if bad value
if (index < 0 || index > LIGHT_COLOR_OPTIONS)
if (index <= 0 || index > LIGHT_COLOR_OPTIONS) {
light->currentValue = 0;
else if (index > 0 && index < LIGHT_COLOR_OPTIONS)
} else if (index > 0 && index < LIGHT_COLOR_OPTIONS) {
light->currentValue = index;
//light->lastValue = index;
}
}
}

// Used for dynamic config JS
int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)
{
memset(&buffer[0], 0, size);
int length = 0;
int i, j;

length += sprintf(buffer+length, "var _light_program = [];\n");
length += sprintf(buffer+length, "_light_program[0] = light_program;\n");

if ( strcmp(_color_light_options[0][1], "1") == 0) {
length += sprintf(buffer+length, "_light_program[0] = light_program;\n");
i=1;
} else {
i=0;
}

for (i=1; i < NUMBER_LIGHT_COLOR_TYPES; i++) {
for (; i < NUMBER_LIGHT_COLOR_TYPES; i++) {
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)
Expand All @@ -238,3 +294,19 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)
return length;
}

int build_color_light_jsonarray(int index, char* buffer, int size)
{
memset(&buffer[0], 0, size);
int i;
int length=0;

for (i=0; i < LIGHT_COLOR_OPTIONS; i++) { // Start a 1 since index 0 is blank
if (_color_light_options[index][i] != NULL) {
length += sprintf(buffer+length, "\"%s\",", _color_light_options[index][i] );
}
}
buffer[--length] = '\0';

return length;
}

4 changes: 4 additions & 0 deletions source/color_lights.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ typedef enum clight_type {
} clight_type;
*/
//const char *light_mode_name(clight_type type, int index);
const char *get_currentlight_mode_name(clight_detail light, emulation_type protocol);
const char *light_mode_name(clight_type type, int index, emulation_type protocol);
int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size);
int build_color_light_jsonarray(int index, char* buffer, int size);

void set_currentlight_value(clight_detail *light, int index);

bool set_aqualinkd_light_mode_name(char *name, int index, bool isShow);

//char *_color_light_options_[LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS][LIGHT_COLOR_NAME];

Expand Down
24 changes: 19 additions & 5 deletions source/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "aq_panel.h"
#include "aqualink.h"
#include "iaqualink.h"
#include "color_lights.h"

#define MAXCFGLINE 256

Expand Down Expand Up @@ -673,9 +674,22 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
} else if (strncasecmp (param, "device_pre_state", 16) == 0) {
_aqconfig_.device_pre_state = text2bool(value);
rtn=true;
}

else if (strncasecmp(param, "button_", 7) == 0) {
} else if (strncasecmp(param, "light_program_", 14) == 0) {
int num = strtoul(param + 14, NULL, 10);
if ( num >= LIGHT_COLOR_OPTIONS ) {
LOG(AQUA_LOG,LOG_ERR, "Config error, light_program_%d is out of range\n",num);
}
char *name = cleanalloc(value);
int len = strlen(name);
if ( strncmp(name+len-7, " - Show", 7) == 0 ) {
name[len-7] = '\0';
//printf("Value '%s' index %d is show\n",name,num);
set_aqualinkd_light_mode_name(name,num,true);
} else {
set_aqualinkd_light_mode_name(name,num,false);
}
rtn=true;
} else if (strncasecmp(param, "button_", 7) == 0) {
// Check we have inichalized panel information, if not use any settings we may have
if (_aqconfig_.paneltype_mask == 0)
setPanel(aqdata, _tmpPanel->rs, _tmpPanel->size, _tmpPanel->combo, _tmpPanel->dual);
Expand Down Expand Up @@ -781,8 +795,8 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
vbutton->rssd_code = IAQ_ONETOUCH_5;
break;
case 6:
vbutton->code = IAQ_ONETOUCH_5;
vbutton->rssd_code = IAQ_ONETOUCH_5;
vbutton->code = IAQ_ONETOUCH_6;
vbutton->rssd_code = IAQ_ONETOUCH_6;
break;
default:
vbutton->code = NUL;
Expand Down
Loading

0 comments on commit f62f7f7

Please sign in to comment.