diff --git a/README.md b/README.md
index aaf76e4..a18baeb 100644
--- a/README.md
+++ b/README.md
@@ -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
* WARNING Breaking change if you use dimmer (please change button_??_lightMode from 6 to 10)
diff --git a/release/aqualinkd-amd64 b/release/aqualinkd-amd64
index fddb6d4..90e4728 100755
Binary files a/release/aqualinkd-amd64 and b/release/aqualinkd-amd64 differ
diff --git a/release/aqualinkd-arm64 b/release/aqualinkd-arm64
index a140aa0..d49db63 100755
Binary files a/release/aqualinkd-arm64 and b/release/aqualinkd-arm64 differ
diff --git a/release/aqualinkd-armhf b/release/aqualinkd-armhf
index 4ce4cda..1f7dc0d 100755
Binary files a/release/aqualinkd-armhf and b/release/aqualinkd-armhf differ
diff --git a/release/aqualinkd.conf b/release/aqualinkd.conf
index f3ce9bd..967299c 100755
--- a/release/aqualinkd.conf
+++ b/release/aqualinkd.conf
@@ -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.
diff --git a/release/serial_logger-arm64 b/release/serial_logger-arm64
index d297ad9..49320c1 100755
Binary files a/release/serial_logger-arm64 and b/release/serial_logger-arm64 differ
diff --git a/release/serial_logger-armhf b/release/serial_logger-armhf
index 8e4475f..fda09fb 100755
Binary files a/release/serial_logger-armhf and b/release/serial_logger-armhf differ
diff --git a/source/allbutton.c b/source/allbutton.c
index 701db55..30dcdd3 100644
--- a/source/allbutton.c
+++ b/source/allbutton.c
@@ -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)
@@ -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
}
diff --git a/source/aq_panel.c b/source/aq_panel.c
index 46aa762..d4b178a 100644
--- a/source/aq_panel.c
+++ b/source/aq_panel.c
@@ -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) {
@@ -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.
@@ -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 {
@@ -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
@@ -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)
diff --git a/source/aq_programmer.c b/source/aq_programmer.c
index 63b67b8..f20272b 100644
--- a/source/aq_programmer.c
+++ b/source/aq_programmer.c
@@ -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,
diff --git a/source/aqualink.h b/source/aqualink.h
index 22a4e51..e85d42c 100644
--- a/source/aqualink.h
+++ b/source/aqualink.h
@@ -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;
diff --git a/source/aqualinkd.c b/source/aqualinkd.c
index 7d9f1fc..b93c81b 100644
--- a/source/aqualinkd.c
+++ b/source/aqualinkd.c
@@ -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;
}
diff --git a/source/color_lights.c b/source/color_lights.c
index 4cab45e..1c8f228 100644
--- a/source/color_lights.c
+++ b/source/color_lights.c
@@ -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",
@@ -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",
@@ -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",
@@ -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
@@ -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",
@@ -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 + = 0x41 = 1st index
"Deep Blue Sea", // 0x42 (both gome and sim)
"Royal Blue", // // 0x43 home // non
@@ -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+ so 153 = 25% = 0x99
- "",
+ "Off",
"25%", // 0x99 (simulator) = 153 dec
"50%", // 0xb2 (simulator) = 178 dec same as (0x99 + 25)
"75%", // 0xcb (simulator) = 203 dec
@@ -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; iled->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 "";
}
@@ -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 ||
@@ -209,13 +256,16 @@ 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);
@@ -223,9 +273,15 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)
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)
@@ -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;
+}
+
diff --git a/source/color_lights.h b/source/color_lights.h
index 70c91b3..df40bbc 100644
--- a/source/color_lights.h
+++ b/source/color_lights.h
@@ -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];
diff --git a/source/config.c b/source/config.c
index 4c8afe0..e9013e2 100644
--- a/source/config.c
+++ b/source/config.c
@@ -41,6 +41,7 @@
#include "aq_panel.h"
#include "aqualink.h"
#include "iaqualink.h"
+#include "color_lights.h"
#define MAXCFGLINE 256
@@ -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);
@@ -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;
diff --git a/source/hassio.c b/source/hassio.c
index 8c06c2a..1e099a3 100644
--- a/source/hassio.c
+++ b/source/hassio.c
@@ -10,6 +10,7 @@
#include "aq_mqtt.h"
#include "rs_msg_utils.h"
#include "config.h"
+#include "color_lights.h"
#include "version.h"
@@ -50,9 +51,7 @@ const char *HASSIO_CLIMATE_DISCOVER = "{"
"\"temperature_command_topic\": \"%s/%s/setpoint/set\","
"\"temperature_state_topic\": \"%s/%s/setpoint\","
/*"\"temperature_state_template\": \"{{ value_json }}\","*/
- "%s,"
- "\"qos\": 1,"
- "\"retain\": false"
+ "%s"
"}";
const char *HASSIO_FREEZE_PROTECT_DISCOVER = "{"
@@ -126,9 +125,7 @@ const char *HASSIO_VSP_DISCOVER = "{"
//"\"percentage_value_template\": \"{%% if value | float(0) > %d %%} {{ (((value | float(0) - %d) / %d) * 100) | int }}{%% else %%} 1{%% endif %%}\"," // min,min,(max-min)
//"\"percentage_command_template\": \"{{ ((value | float(0) / 100) * %d) + %d | int }}\"," // (3450-130), 600
"\"speed_range_max\": 100,"
- "\"speed_range_min\": 1," // 18|12 600rpm|15gpm
- "\"qos\": 1,"
- "\"retain\": false"
+ "\"speed_range_min\": 1" // 18|12 600rpm|15gpm
"}";
@@ -146,9 +143,21 @@ const char *HASSIO_DIMMER_DISCOVER = "{"
"\"payload_off\": \"0\","
"\"brightness_command_topic\": \"%s/%s%s/set\"," // aqualinkd,Aux_5,/brightness
"\"brightness_state_topic\": \"%s/%s%s\"," // aqualinkd/Aux_5,/brightness
- "\"brightness_scale\": 100,"
- "\"qos\": 1,"
- "\"retain\": false"
+ "\"brightness_scale\": 100"
+"}";
+
+const char *HASSIO_SELECTOR_DISCOVER = "{"
+ "\"device\": {" HASS_DEVICE "},"
+ "\"availability\": {" HASS_AVAILABILITY "},"
+ "\"type\": \"select\","
+ "\"unique_id\": \"aqualinkd_%s_selector\"," // Aux_5
+ "\"name\": \"%s program\"," // light name
+ "\"state_topic\": \"%s/%s/program/name\"," // aqualinkd,Aux_5
+ "\"state_template\": \"{{ this.attributes.options(value) }}\","
+ "\"command_topic\": \"%s/%s/program/set\"," // aqualinkd,Aux_5
+ "\"options\": [ %s ]," // "Off", "Voodoo Lounge", "Deep Blue Sea"
+ "\"command_template\": \"{{ this.attributes.options.index(value) }}\","
+ "\"icon\": \"%s\""
"}";
// Need to add timer attributes to the switches, once figure out how to use in homeassistant
@@ -167,8 +176,7 @@ const char *HASSIO_SWITCH_DISCOVER = "{"
"\"json_attributes_template\": \"{{ {'delay': value|int} | tojson }}\","
"\"payload_on\": \"1\","
"\"payload_off\": \"0\","
- "\"qos\": 1,"
- "\"retain\": false"
+ "\"icon\": \"%s\""
"}";
const char *HASSIO_TEMP_SENSOR_DISCOVER = "{"
@@ -176,7 +184,7 @@ const char *HASSIO_TEMP_SENSOR_DISCOVER = "{"
"\"availability\": {" HASS_AVAILABILITY "},"
"\"type\": \"sensor\","
"\"state_class\": \"measurement\","
- "\"unique_id\": \"aqualinkd_%s\","
+ "\"unique_id\": \"aqualinkd_%s_temp\","
"\"name\": \"%s Temp\","
"\"state_topic\": \"%s/%s\","
"\"value_template\": \"{{ value_json }}\","
@@ -404,6 +412,36 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
_aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,LIGHT_DIMMER_VALUE_TOPIC);
sprintf(topic, "%s/light/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name);
send_mqtt(nc, topic, msg);
+ } else if ( isPLIGHT(aqdata->aqbuttons[i].special_mask) ) {
+ // Color Lights & Dimmer as selector switch
+ // Build the
+
+ char buf[512];
+ build_color_light_jsonarray(((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType, buf, 512 );
+ sprintf(msg,HASSIO_SELECTOR_DISCOVER,
+ _aqconfig_.mqtt_aq_topic,
+ aqdata->aqbuttons[i].name,
+ aqdata->aqbuttons[i].label,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ buf,
+ "mdi:lightbulb");
+ sprintf(topic, "%s/select/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name);
+ send_mqtt(nc, topic, msg);
+
+ // Duplicate normal switch as we want a duplicate
+ sprintf(msg, HASSIO_SWITCH_DISCOVER,
+ _aqconfig_.mqtt_aq_topic,
+ aqdata->aqbuttons[i].name,
+ aqdata->aqbuttons[i].label,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ "mdi:lightbulb");
+ sprintf(topic, "%s/switch/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name);
+ send_mqtt(nc, topic, msg);
+
} else {
// Switches
//sprintf(msg,"{\"type\": \"switch\",\"unique_id\": \"%s\",\"name\": \"%s\",\"state_topic\": \"aqualinkd/%s\",\"command_topic\": \"aqualinkd/%s/set\",\"json_attributes_topic\": \"aqualinkd/%s/delay\",\"json_attributes_topic\": \"aqualinkd/%s/delay\",\"json_attributes_template\": \"{{ {'delay': value|int} | tojson }}\",\"payload_on\": \"1\",\"payload_off\": \"0\",\"qos\": 1,\"retain\": false}" ,
@@ -414,7 +452,8 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
_aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
_aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
_aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
- _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name);
+ _aqconfig_.mqtt_aq_topic,aqdata->aqbuttons[i].name,
+ "mdi:toggle-switch-variant");
sprintf(topic, "%s/switch/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name);
send_mqtt(nc, topic, msg);
}
@@ -458,7 +497,8 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
_aqconfig_.mqtt_aq_topic,SWG_BOOST_TOPIC,
_aqconfig_.mqtt_aq_topic,SWG_BOOST_TOPIC,
_aqconfig_.mqtt_aq_topic,SWG_BOOST_TOPIC,
- _aqconfig_.mqtt_aq_topic,SWG_BOOST_TOPIC);
+ _aqconfig_.mqtt_aq_topic,SWG_BOOST_TOPIC,
+ "mdi:toggle-switch-variant");
sprintf(topic, "%s/switch/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, idbuf);
send_mqtt(nc, topic, msg);
diff --git a/source/iaqtouch.c b/source/iaqtouch.c
index eba37ab..81a9072 100644
--- a/source/iaqtouch.c
+++ b/source/iaqtouch.c
@@ -555,7 +555,7 @@ pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char
{
if (pump == NULL)
{
- LOG(from, LOG_WARNING, "Got pump message '%s' but can't find pump # %d, please update aqualinkd.conf\n", name, pi);
+ LOG(from, LOG_INFO, "Got pump message '%s' but can't find pump # %d, please update aqualinkd.conf\n", name, pi);
}
else if (pump->pumpType == PT_UNKNOWN)
{
@@ -627,7 +627,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
pump->pStatus = PS_OK;
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"GPM:") == 0) {
if (pump != NULL) {
@@ -635,7 +635,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
pump->pStatus = PS_OK;
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"Watts:") == 0) {
if (pump != NULL) {
@@ -643,7 +643,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
//pump->ppStatus = DON"T SET, WE GET WATTS IN PRIMING
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"*** Priming ***") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
@@ -653,7 +653,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
pump->pStatus = PS_PRIMING;
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"(Offline)") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
@@ -663,7 +663,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
pump->pStatus = PS_OFFLINE;
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"(Priming Error)") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
@@ -673,7 +673,7 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
pump->pStatus = PS_ERROR;
aq_data->updated = true;
} else
- LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
+ LOG(IAQT_LOG,LOG_INFO, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
// Need to catch messages like
// *** Priming ***
diff --git a/source/iaqtouch_aq_programmer.c b/source/iaqtouch_aq_programmer.c
index ce27d6d..19078a6 100644
--- a/source/iaqtouch_aq_programmer.c
+++ b/source/iaqtouch_aq_programmer.c
@@ -560,7 +560,8 @@ void *set_aqualink_iaqtouch_device_on_off( void *ptr )
return ptr;
}
-
+/*
+ // Not complete, and not needed with
void *set_aqualink_iaqtouch_onetouch_on_off( void *ptr )
{
struct programmingThreadCtrl *threadCtrl;
@@ -590,6 +591,7 @@ void *set_aqualink_iaqtouch_onetouch_on_off( void *ptr )
return ptr;
}
+*/
diff --git a/source/json_messages.c b/source/json_messages.c
index 3b59b76..d7c81cd 100644
--- a/source/json_messages.c
+++ b/source/json_messages.c
@@ -278,7 +278,8 @@ char *get_aux_information(aqkey *button, struct aqualinkdata *aqdata, char *buff
length += sprintf(buffer, ",\"type_ext\": \"switch_program\", \"Light_Type\":\"%d\", \"Light_Program\":\"%d\", \"Program_Name\":\"%s\" ",
aqdata->lights[i].lightType,
aqdata->lights[i].currentValue,
- light_mode_name(aqdata->lights[i].lightType, aqdata->lights[i].currentValue, ALLBUTTON));
+ get_currentlight_mode_name(aqdata->lights[i], ALLBUTTON));
+ //light_mode_name(aqdata->lights[i].lightType, aqdata->lights[i].currentValue, ALLBUTTON));
}
return buffer;
}
@@ -733,7 +734,8 @@ printf("Pump Type %d\n",aqdata->pumps[i].pumpType);
if (aqdata->lights[i].lightType == LC_DIMMER2) {
length += sprintf(buffer+length, "\"%s\": \"%d%%\",", aqdata->lights[i].button->name, aqdata->lights[i].currentValue );
} else {
- length += sprintf(buffer+length, "\"%s\": \"%s\",", aqdata->lights[i].button->name, light_mode_name(aqdata->lights[i].lightType, aqdata->lights[i].currentValue, RSSADAPTER) );
+ //length += sprintf(buffer+length, "\"%s\": \"%s\",", aqdata->lights[i].button->name, light_mode_name(aqdata->lights[i].lightType, aqdata->lights[i].currentValue, RSSADAPTER) );
+ length += sprintf(buffer+length, "\"%s\": \"%s\",", aqdata->lights[i].button->name, get_currentlight_mode_name(aqdata->lights[i], RSSADAPTER) );
}
}
if (buffer[length-1] == ',')
diff --git a/source/net_services.c b/source/net_services.c
index 93830ba..5403863 100644
--- a/source/net_services.c
+++ b/source/net_services.c
@@ -950,6 +950,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
// Loop over programmable lights
for (i=0; i < _aqualink_data->num_lights; i++) {
+ //LOG(NET_LOG,LOG_NOTICE, "Light %10s | %d | lmode=%.2d cmode=%.2d | name=%s\n",_aqualink_data->lights[i].button->label,_aqualink_data->lights[i].button->led->state,_aqualink_data->lights[i].lastValue,_aqualink_data->lights[i].currentValue,get_currentlight_mode_name(_aqualink_data->lights[i], RSSADAPTER));
char topic[50];
if ( _aqualink_data->lights[i].currentValue != TEMP_UNKNOWN && _aqualink_data->lights[i].currentValue != _last_mqtt_aqualinkdata.lights[i].currentValue ) {
_last_mqtt_aqualinkdata.lights[i].currentValue = _aqualink_data->lights[i].currentValue;
@@ -961,7 +962,8 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
sprintf(message, "%d%%", _aqualink_data->lights[i].currentValue);
send_mqtt_string_msg(nc, topic, message);
} else {
- send_mqtt_string_msg(nc, topic, light_mode_name(_aqualink_data->lights[i].lightType, _aqualink_data->lights[i].currentValue, ALLBUTTON));
+ //send_mqtt_string_msg(nc, topic, light_mode_name(_aqualink_data->lights[i].lightType, _aqualink_data->lights[i].currentValue, RSSADAPTER));
+ send_mqtt_string_msg(nc, topic, get_currentlight_mode_name(_aqualink_data->lights[i], RSSADAPTER));
}
/*
if (_aqualink_data->lights[i].lightType == LC_DIMMER) {
diff --git a/source/serialadapter.c b/source/serialadapter.c
index 4650284..006cfd1 100644
--- a/source/serialadapter.c
+++ b/source/serialadapter.c
@@ -11,7 +11,7 @@
#include "color_lights.h"
#include "allbutton.h"
-#define RSSA_QLEN 20
+#define RSSA_QLEN 40
unsigned char _rssa_queue[RSSA_QLEN][4];
int _rssa_q_length = 0;
@@ -43,7 +43,6 @@ void processRSSALEDstate(struct aqualinkdata *aq_data, unsigned char *packet)
bool push_rssa_cmd(unsigned char *cmd) {
-
if (_rssa_q_length >= RSSA_QLEN ) {
LOG(RSSA_LOG,LOG_ERR, "Queue overflow, last command ignored!\n");
return false;
@@ -219,8 +218,13 @@ void set_aqualink_rssadapter_spa_setpoint(char *args, struct aqualinkdata *aqdat
}
-#ifdef CLIGHT_PANEL_FIX
+#ifdef CLIGHT_PANEL_FIX
/* This is to overcome Jandy bug where panel doesn;t show the state of color light */
+void get_aqualink_rssadapter_button_status(aqkey *button)
+{
+ if (button->rssd_code != NUL)
+ rssadapter_device_state(button->rssd_code, 0x00);
+}
void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aq_data)
{
for (int i=0; i < aq_data->num_lights; i++) {
diff --git a/source/serialadapter.h b/source/serialadapter.h
index caa9603..b4a899e 100644
--- a/source/serialadapter.h
+++ b/source/serialadapter.h
@@ -23,6 +23,7 @@ void increase_aqualink_rssadapter_spa_setpoint(char *args, struct aqualinkdata *
#ifdef CLIGHT_PANEL_FIX
void get_aqualink_rssadapter_colorlight_statuses(struct aqualinkdata *aqdata);
+ void get_aqualink_rssadapter_button_status(aqkey *button);
#endif
/*
diff --git a/source/version.h b/source/version.h
index 9a2b6d2..748eb27 100644
--- a/source/version.h
+++ b/source/version.h
@@ -4,4 +4,4 @@
#define AQUALINKD_SHORT_NAME "AqualinkD"
// Use Magor . Minor . Patch
-#define AQUALINKD_VERSION "2.5.0 (Dev 0.2)"
+#define AQUALINKD_VERSION "2.5.0 (dev 0.3)"
diff --git a/web/config.js b/web/config.js
index b23dc95..5cf1b3f 100644
--- a/web/config.js
+++ b/web/config.js
@@ -56,6 +56,7 @@
];
// This get's picked up by dynamic_config.js and used as mode 0
+ // As version 2.5.0 Please use aqualinkd.conf for this configuration.
var light_program = [
"Voodoo Lounge - Show",
"Blue Sea",
diff --git a/web/controller.html b/web/controller.html
index 740e4b5..1a45851 100644
--- a/web/controller.html
+++ b/web/controller.html
@@ -1708,7 +1708,7 @@
var x;
for (x = 0; x < radio.length; x++) {
if (radio[x].checked == true) {
- console.log("Light Current= "+(getTileSPvalue(id)+1)+" - "+getTileOnText(id)+" Selected="+radio[x].value+" - "+document.getElementById('pswitch_option_switch_text_value').innerHTML);
+ //console.log("Light Current= "+(getTileSPvalue(id)+1)+" - "+getTileOnText(id)+" Selected="+radio[x].value+" - "+document.getElementById('pswitch_option_switch_text_value').innerHTML);
if (getTileSPvalue(id)+1 != radio[x].value) {
send_light_mode(radio[x].value, id, document.getElementById('pswitch_option_switch_text_value').innerHTML);
}
@@ -2275,12 +2275,16 @@
var light_mode = -1;
// If aqualinkd programmed light, need to convert int to text index, if not value is text
try {
- var light_type = document.getElementById(obj.toString()).getAttribute('lighttype');
+ var light_type = document.getElementById(obj.toString()).getAttribute('lighttype');
if (light_type == "0") {
light_mode = parseInt(data.light_program_names[obj])-1;
- var light_mode_name = _light_program[light_type][light_mode];
- if (light_mode_name.endsWith(" - Show")) {
- light_mode_name = light_mode_name.slice(0, -7);
+ // For backward compatibility we could get a name here or number (number is is lights modes are in config.js vs aqualinkd.conf)
+ //console.log("Light "+light_mode);
+ if (! isNaN(light_mode)) {
+ light_mode_name = _light_program[light_type][light_mode];
+ if (light_mode_name.endsWith(" - Show")) {
+ light_mode_name = light_mode_name.slice(0, -7);
+ }
}
} else if (/*light_type == 10 ||*/ light_type == 11) {
// Fo Dimmer Lights.
@@ -2291,7 +2295,8 @@
}
} catch (e) { /*console.log(e);*/ }
- setTileOnText(obj.toString(),light_mode_name);
+ if (light_mode_name != "-999%" && light_mode_name != "Off")
+ setTileOnText(obj.toString(),light_mode_name);
try {
document.getElementById(obj.toString()).setAttribute('spvalue', light_mode);