mirror of https://github.com/sfeakes/AqualinkD.git
2.5.0 (Dev 0.3)
parent
6bba1462a4
commit
f62f7f786c
|
@ -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)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 + <value or index> = 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+<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
|
||||
|
@ -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 "";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 ***
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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] == ',')
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue