Updates for 2.5.0

pull/356/head^2
sfeakes 2024-10-12 17:37:26 -05:00
parent 32f3d8b042
commit cbf65679bc
24 changed files with 766 additions and 285 deletions

View File

@ -132,16 +132,20 @@ NEED TO FIX FOR THIS RELEASE.
# pickup speed faster on iaqualinktouch after change # pickup speed faster on iaqualinktouch after change
--> -->
# Updates in 2.4.1 (under development) # Updates in 2.5.0 (under development)
* PDA panel Rev 6.0 or newer that do not have a Jandy iAqualink device attached can use the AqualinkTouch protocol rather than PDA protocol. * PDA panel Rev 6.0 or newer that do not have a Jandy iAqualink device attached can use the AqualinkTouch protocol rather than PDA protocol.
* This is faster, more reliable and does not intefear with the physical PDA device (like existing implimentation) * This is faster, more reliable and does not intefear with the physical PDA device (like existing implimentation)
* Please consider this very much BETA at the moment. * Please consider this very much BETA at the moment.
* use `device_id=0x33` in aqualinkd.conf * use `device_id=0x33` in aqualinkd.conf.
* 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 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.
* Updated UI for support fullrange dimmer.
* cleaned up code for spa_mode and spa for newer pannels. * cleaned up code for spa_mode and spa for newer pannels.
* Allow VSP to be asigned to virtual button. * Allow VSP to be asigned to virtual button.
* Fixed bug with timer not starting. * Fixed bug with timer not starting.
* Increase Speed of detecting device state changes. * Increase Speed of detecting device state changes.
# Updates in Release 2.4.0 # Updates in Release 2.4.0
* <b>WARNING</b> Breaking change if you use dimmer (please change button_??_lightMode from 6 to 10) * <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.

View File

@ -91,12 +91,14 @@ device_id=0x00
# JXi = Jandy JXi heater (might also be LXi heaters) # JXi = Jandy JXi heater (might also be LXi heaters)
# LX = Jandy LX & LT heaters # LX = Jandy LX & LT heaters
# Chem = Jandy Chemical Feeder # Chem = Jandy Chemical Feeder
# iAqualink = Read iAqualink2 (wifi device). Only relivent in PDA mode IF you have iAqualink2/3 device
#read_RS485_swg = yes #read_RS485_swg = yes
#read_RS485_ePump = yes #read_RS485_ePump = yes
#read_RS485_vsfPump = yes #read_RS485_vsfPump = yes
#read_RS485_JXi = yes #read_RS485_JXi = yes
#read_RS485_LX = yes #read_RS485_LX = yes
#read_RS485_Chem = yes #read_RS485_Chem = yes
#read_RS485_iAqualink = yes
# Keep the panel time synced with systemtime. Make sure to set systemtime / NTP correctly. # Keep the panel time synced with systemtime. Make sure to set systemtime / NTP correctly.
keep_paneltime_synced = yes keep_paneltime_synced = yes
@ -146,7 +148,7 @@ report_zero_spa_temp = yes
# dead. # dead.
# ~40 and we will be replying too slowley, so keep below that. # ~40 and we will be replying too slowley, so keep below that.
# 10~20 is about what most device reply in. But 0-4 works well. # 10~20 is about what most device reply in. But 0-4 works well.
rs485_frame_delay = 4 rs485_frame_delay = 0
# Get rid of the startup warning message about no low latency. BETTER option is to buy a better adapter. # Get rid of the startup warning message about no low latency. BETTER option is to buy a better adapter.
#ftdi_low_latency = no #ftdi_low_latency = no
@ -264,8 +266,8 @@ use_panel_aux_labels=no
# button_01_pumpIndex=1 # 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. # 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=Hayw Univ Color, 7,8,9(future), 10=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, 11=Full Range Dimmer)
# #
# Below are settings for standard buttons on RS-8 Combo panel used as example. # Below are settings for standard buttons on RS-8 Combo panel used as example.
button_01_label=Filter Pump button_01_label=Filter Pump

Binary file not shown.

Binary file not shown.

View File

@ -56,6 +56,8 @@
#define PUMP_SPEED_TOPIC "/Speed" #define PUMP_SPEED_TOPIC "/Speed"
#define LIGHT_PROGRAM_TOPIC "/program" #define LIGHT_PROGRAM_TOPIC "/program"
#define LIGHT_DIMMER_VALUE_TOPIC "/brightness"
/* /*
#define AIR_TEMPERATURE "Air" #define AIR_TEMPERATURE "Air"
#define POOL_TEMPERATURE "Pool_Water" #define POOL_TEMPERATURE "Pool_Water"

View File

@ -30,6 +30,7 @@
void initPanelButtons(struct aqualinkdata *aqdata, bool rspda, int size, bool combo, bool dual); void initPanelButtons(struct aqualinkdata *aqdata, bool rspda, int size, bool combo, bool dual);
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button); void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button);
char *name2label(char *str) char *name2label(char *str)
{ {
int len = strlen(str); int len = strlen(str);
@ -687,6 +688,9 @@ const char* getRequestName(request_source source)
case NET_TIMER: case NET_TIMER:
return "Timer"; return "Timer";
break; break;
case UNACTION_TIMER:
return "UnactionTimer";
break;
} }
static char buf[25]; static char buf[25];
@ -740,6 +744,9 @@ const char* getActionName(action_type type)
case DATE_TIME: case DATE_TIME:
return "Date Time"; return "Date Time";
break; break;
case LIGHT_BRIGHTNESS:
return "Light Brightness";
break;
} }
static char buf[25]; static char buf[25];
@ -821,11 +828,15 @@ 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 // 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 // since allbutton (default) is stateless, and rssaadapter is statefull, use rssaadapter for any domoricz requests
set_aqualink_rssadapter_aux_state(button, isON); set_aqualink_rssadapter_aux_state(button, isON);
//} 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 (button->special_mask & PROGRAM_LIGHT && isRSSA_ENABLED) {
// If off and program light, use the RS serial adapter since that is overiding the state now. // If off and program light, use the RS serial adapter since that is overiding the state now.
set_aqualink_rssadapter_aux_state(button, isON); set_aqualink_rssadapter_aux_state(button, isON);
} else { } else {
//set_iaqualink_aux_state(button, isON); //set_iaqualink_aux_state(button, isON);
//set_aqualink_rssadapter_aux_state(button, isON);
aq_send_allb_cmd(button->code); aq_send_allb_cmd(button->code);
} }
@ -882,24 +893,62 @@ bool programDeviceValue(struct aqualinkdata *aqdata, action_type type, int value
return true; return true;
} }
void programDeviceLightBrightness(struct aqualinkdata *aqdata, int value, int button, bool expectMultiple)
{
clight_detail *light = getProgramableLight(aqdata, button);
if (!isRSSA_ENABLED) {
LOG(PANL_LOG,LOG_ERR, "Light mode brightness is only supported with `rssa_device_id` set\n");
return;
}
if (light == NULL) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button);
return;
}
// DIMMER is 0,25,50,100 DIMMER2 is range
if (light->lightType == LC_DIMMER) {
value = round(value / 25);
}
if (!expectMultiple) {
programDeviceLightMode(aqdata, value, button);
return;
}
time(&aqdata->unactioned.requested);
aqdata->unactioned.value = value;
aqdata->unactioned.type = LIGHT_MODE;
aqdata->unactioned.id = button;
return;
}
//void programDeviceLightMode(struct aqualinkdata *aqdata, char *value, int button) //void programDeviceLightMode(struct aqualinkdata *aqdata, char *value, int button)
//void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button) void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
{ {
int i;
clight_detail *light = NULL;
#ifdef AQ_PDA #ifdef AQ_PDA
if (isPDA_PANEL && !isPDA_IAQT) { if (isPDA_PANEL && !isPDA_IAQT) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not supported in PDA mode\n"); LOG(PANL_LOG,LOG_ERR, "Light mode control not supported in PDA mode\n");
return; return;
} }
#endif #endif
/*
int i;
clight_detail *light = NULL;
for (i=0; i < aqdata->num_lights; i++) { for (i=0; i < aqdata->num_lights; i++) {
if (&aqdata->aqbuttons[button] == aqdata->lights[i].button) { if (&aqdata->aqbuttons[button] == aqdata->lights[i].button) {
// Found the programmable light // Found the programmable light
light = &aqdata->lights[i]; light = &aqdata->lights[i];
break; break;
} }
} }*/
clight_detail *light = getProgramableLight(aqdata, button);
if (light == NULL) { if (light == NULL) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button); LOG(PANL_LOG,LOG_ERR, "Light mode control not configured for button %d\n",button);
@ -916,13 +965,18 @@ void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
_aqconfig_.light_programming_initial_off, _aqconfig_.light_programming_initial_off,
_aqconfig_.light_programming_mode ); _aqconfig_.light_programming_mode );
aq_programmer(AQ_SET_LIGHTPROGRAM_MODE, buf, aqdata); aq_programmer(AQ_SET_LIGHTPROGRAM_MODE, buf, aqdata);
} else if (isRSSA_ENABLED && light->lightType != LC_DIMMER) { } else if (isRSSA_ENABLED && light->lightType == LC_DIMMER2) {
unsigned char rssd_value = value; // Dimmer needs to be turned on before you set dimmer level
set_aqualink_rssadapter_aux_extended_state(light->button, rssd_value); if (light->button->led->state != ON) {
set_aqualink_rssadapter_aux_extended_state(light->button, RS_SA_ON);
}
set_aqualink_rssadapter_aux_extended_state(light->button, value);
} else if (isRSSA_ENABLED && light->lightType == LC_DIMMER) { } else if (isRSSA_ENABLED && light->lightType == LC_DIMMER) {
// Dimmer needs to be turned on first // Dimmer needs to be turned on first
set_aqualink_rssadapter_aux_extended_state(light->button, RS_SA_ON); if (light->button->led->state != ON) {
// Value 1 = 25, 1 = 50, 3 = 75, 4 = 100 (need to convert value into binary) set_aqualink_rssadapter_aux_extended_state(light->button, RS_SA_ON);
}
// Value 1 = 25, 2 = 50, 3 = 75, 4 = 100 (need to convert value into binary)
if (value >= 1 && value <= 4) { if (value >= 1 && value <= 4) {
// If value is not on of those vales, then ignore // If value is not on of those vales, then ignore
unsigned char rssd_value = value * 25; unsigned char rssd_value = value * 25;
@ -979,6 +1033,9 @@ bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int dev
//start_timer(aqdata, &aqdata->aqbuttons[deviceIndex], deviceIndex, value); //start_timer(aqdata, &aqdata->aqbuttons[deviceIndex], deviceIndex, value);
start_timer(aqdata, deviceIndex, value); start_timer(aqdata, deviceIndex, value);
break; break;
case LIGHT_BRIGHTNESS:
programDeviceLightBrightness(aqdata, value, deviceIndex, (source==NET_MQTT?true:false));
break;
case LIGHT_MODE: case LIGHT_MODE:
if (value <= 0) { if (value <= 0) {
// Consider this a bad/malformed request to turn the light off. // Consider this a bad/malformed request to turn the light off.
@ -1013,6 +1070,7 @@ bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int dev
// Programmable light has been updated, so update the status in AqualinkD // Programmable light has been updated, so update the status in AqualinkD
void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button) void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button)
{ {
/*
int i; int i;
clight_detail *light = NULL; clight_detail *light = NULL;
@ -1023,6 +1081,8 @@ void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button
break; break;
} }
} }
*/
clight_detail *light = getProgramableLight(aqdata, button);
if (light == NULL) { if (light == NULL) {
LOG(PANL_LOG,LOG_ERR, "Button not found for light button index=%d\n",button); LOG(PANL_LOG,LOG_ERR, "Button not found for light button index=%d\n",button);
@ -1032,6 +1092,21 @@ void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button
light->currentValue = value; light->currentValue = value;
} }
clight_detail *getProgramableLight(struct aqualinkdata *aqdata, int button)
{
if ( isPLIGHT(aqdata->aqbuttons[button].special_mask) ) {
return (clight_detail *)aqdata->aqbuttons[button].special_mask_ptr;
}
return NULL;
}
pump_detail *getPumpDetail(struct aqualinkdata *aqdata, int button)
{
if ( isVS_PUMP(aqdata->aqbuttons[button].special_mask) ) {
return (pump_detail *)aqdata->aqbuttons[button].special_mask_ptr;
}
return NULL;
}
#ifdef DO_NOT_COMPILE #ifdef DO_NOT_COMPILE

View File

@ -68,6 +68,10 @@ int convertPumpPercentToSpeed(pump_detail *pump, int value); // This is probable
uint16_t getPanelSupport( char *rev_string, int rev_len); uint16_t getPanelSupport( char *rev_string, int rev_len);
aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex); aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex);
clight_detail *getProgramableLight(struct aqualinkdata *aqdata, int button);
pump_detail *getPumpDetail(struct aqualinkdata *aqdata, int button);
//void panneltest(); //void panneltest();
#define isPDA_PANEL ((_aqconfig_.paneltype_mask & RSP_PDA) == RSP_PDA) #define isPDA_PANEL ((_aqconfig_.paneltype_mask & RSP_PDA) == RSP_PDA)

View File

@ -114,19 +114,22 @@ void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceInde
} }
} }
#define WAIT_TIME_BEFORE_ON_CHECK 1000 // 1 second #define WAIT_TIME_BEFORE_ON_CHECK 1000
//#define WAIT_TIME_BEFORE_ON_CHECK 1000000 // 1 second
void *timer_worker( void *ptr ) void *timer_worker( void *ptr )
{ {
struct timerthread *tmthread; struct timerthread *tmthread;
tmthread = (struct timerthread *) ptr; tmthread = (struct timerthread *) ptr;
int retval = 0; int retval = 0;
int cnt=0;
LOG(TIMR_LOG, LOG_NOTICE, "Start timer for '%s'\n",tmthread->button->name); LOG(TIMR_LOG, LOG_NOTICE, "Start timer for '%s'\n",tmthread->button->name);
// Add mask so we know timer is active // Add mask so we know timer is active
tmthread->button->special_mask |= TIMER_ACTIVE; tmthread->button->special_mask |= TIMER_ACTIVE;
/*
#ifndef PRESTATE_ONOFF #ifndef PRESTATE_ONOFF
delay(WAIT_TIME_BEFORE_ON_CHECK); delay(WAIT_TIME_BEFORE_ON_CHECK);
LOG(TIMR_LOG, LOG_DEBUG, "wait finished for button state '%s'\n",tmthread->button->name); LOG(TIMR_LOG, LOG_DEBUG, "wait finished for button state '%s'\n",tmthread->button->name);
@ -141,6 +144,19 @@ void *timer_worker( void *ptr )
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER);
} }
} }
*/
while (tmthread->button->led->state == OFF) {
LOG(TIMR_LOG, LOG_DEBUG, "waiting for button state '%s' to change\n",tmthread->button->name);
delay(WAIT_TIME_BEFORE_ON_CHECK);
if (cnt++ == 5 && !isPDA_PANEL) {
LOG(TIMR_LOG, LOG_NOTICE, "turning on '%s'\n",tmthread->button->name);
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, true, NET_TIMER);
} else if (cnt == 10) {
LOG(TIMR_LOG, LOG_ERR, "button state never turned on'%s'\n",tmthread->button->name);
break;
}
}
pthread_mutex_lock(&tmthread->thread_mutex); pthread_mutex_lock(&tmthread->thread_mutex);
@ -163,12 +179,24 @@ void *timer_worker( void *ptr )
LOG(TIMR_LOG, LOG_NOTICE, "End timer for '%s'\n",tmthread->button->name); LOG(TIMR_LOG, LOG_NOTICE, "End timer for '%s'\n",tmthread->button->name);
if (tmthread->button->led->state != OFF) { // We need to detect if we ended on time or were killed.
// If killed the device is probable off (or being set to off), so we should probably poll a few times before turning off.
// Either that of change ap_panel to not turn off device if timer is set.
//LOG(TIMR_LOG, LOG_NOTICE, "End timer duration '%d'\n",tmthread->duration_min);
// if duration_min is 0 we were killed, if not we got here on timeout, so turn off device.
if (tmthread->duration_min != 0 && tmthread->button->led->state != OFF) {
LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name); LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name);
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER); panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER);
} else { } else if (tmthread->button->led->state == OFF) {
LOG(TIMR_LOG, LOG_INFO, "Timer waking '%s' is already off\n",tmthread->button->name); LOG(TIMR_LOG, LOG_INFO, "Timer waking '%s' is already off\n",tmthread->button->name);
} }
if (tmthread->button->led->state != OFF) {
// Need to wait
}
// remove mask so we know timer is dead // remove mask so we know timer is dead
tmthread->button->special_mask &= ~ TIMER_ACTIVE; tmthread->button->special_mask &= ~ TIMER_ACTIVE;

View File

@ -94,6 +94,7 @@ typedef struct aqualinkkey
unsigned char rssd_code; unsigned char rssd_code;
int dz_idx; int dz_idx;
uint8_t special_mask; uint8_t special_mask;
void *special_mask_ptr;
} aqkey; } aqkey;
// special_mask for above aqualinkkey structure. // special_mask for above aqualinkkey structure.
@ -128,6 +129,7 @@ typedef enum action_type {
ON_OFF, ON_OFF,
TIMER, TIMER,
LIGHT_MODE, LIGHT_MODE,
LIGHT_BRIGHTNESS,
DATE_TIME DATE_TIME
} action_type; } action_type;
@ -216,7 +218,8 @@ typedef enum clight_type {
LC_SPARE_1, LC_SPARE_1,
LC_SPARE_2, LC_SPARE_2,
LC_SPARE_3, LC_SPARE_3,
LC_DIMMER, LC_DIMMER, // use 0, 25, 50, 100
LC_DIMMER2, // use range 0 to 100
NUMBER_LIGHT_COLOR_TYPES // This is used to size and count so add more prior to this NUMBER_LIGHT_COLOR_TYPES // This is used to size and count so add more prior to this
} clight_type; } clight_type;
@ -225,7 +228,8 @@ typedef enum {
NET_API, NET_API,
NET_WS, NET_WS,
NET_DZMQTT, NET_DZMQTT,
NET_TIMER // Not used yet, need to change aq_timer.c NET_TIMER, // Not used yet, need to change aq_timer.c
UNACTION_TIMER
} request_source; } request_source;
typedef struct clightd typedef struct clightd

View File

@ -355,6 +355,9 @@ void action_delayed_request()
LOG(AQUA_LOG,LOG_NOTICE, "Changing spa heater setpoint by %d\n", _aqualink_data.unactioned.value); LOG(AQUA_LOG,LOG_NOTICE, "Changing spa heater setpoint by %d\n", _aqualink_data.unactioned.value);
aq_programmer(AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP, sval, &_aqualink_data); aq_programmer(AQ_ADD_RSSADAPTER_SPA_HEATER_TEMP, sval, &_aqualink_data);
} }
else if (_aqualink_data.unactioned.type == LIGHT_MODE) {
panel_device_request(&_aqualink_data, LIGHT_MODE, _aqualink_data.unactioned.id, _aqualink_data.unactioned.value, UNACTION_TIMER);
}
else else
{ {
LOG(AQUA_LOG,LOG_ERR, "Unknown request of type %d\n", _aqualink_data.unactioned.type); LOG(AQUA_LOG,LOG_ERR, "Unknown request of type %d\n", _aqualink_data.unactioned.type);
@ -496,6 +499,10 @@ int startup(char *self, char *cfgFile)
} }
} else if (isPDA_PANEL) { } else if (isPDA_PANEL) {
if ( (_aqconfig_.device_id >= 0x60 && _aqconfig_.device_id <= 0x63) || _aqconfig_.device_id == 0x33 ) { if ( (_aqconfig_.device_id >= 0x60 && _aqconfig_.device_id <= 0x63) || _aqconfig_.device_id == 0x33 ) {
if ( _aqconfig_.device_id == 0x33 ) {
LOG(AQUA_LOG,LOG_NOTICE, "Enabeling iAqualink protocol.\n");
_aqconfig_.enable_iaqualink = true;
}
// We are good // We are good
} else { } else {
LOG(AQUA_LOG,LOG_ERR, "Device ID 0x%02hhx does not match PDA panel, please check config!\n", _aqconfig_.device_id); LOG(AQUA_LOG,LOG_ERR, "Device ID 0x%02hhx does not match PDA panel, please check config!\n", _aqconfig_.device_id);
@ -572,6 +579,9 @@ int startup(char *self, char *cfgFile)
LOG(AQUA_LOG,LOG_NOTICE, "Config rssa_device_id = 0x%02hhx\n", _aqconfig_.rssa_device_id); LOG(AQUA_LOG,LOG_NOTICE, "Config rssa_device_id = 0x%02hhx\n", _aqconfig_.rssa_device_id);
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH #if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
LOG(AQUA_LOG,LOG_NOTICE, "Config extra_device_id = 0x%02hhx\n", _aqconfig_.extended_device_id); LOG(AQUA_LOG,LOG_NOTICE, "Config extra_device_id = 0x%02hhx\n", _aqconfig_.extended_device_id);
if (_aqconfig_.enable_iaqualink) {
LOG(AQUA_LOG,LOG_NOTICE, "Config enable_iaqualink = %s\n", bool2text(_aqconfig_.enable_iaqualink));
}
LOG(AQUA_LOG,LOG_NOTICE, "Config extra_device_prog = %s\n", bool2text(_aqconfig_.extended_device_id_programming)); LOG(AQUA_LOG,LOG_NOTICE, "Config extra_device_prog = %s\n", bool2text(_aqconfig_.extended_device_id_programming));
#endif #endif
LOG(AQUA_LOG,LOG_NOTICE, "Config serial_port = %s\n", _aqconfig_.serial_port); LOG(AQUA_LOG,LOG_NOTICE, "Config serial_port = %s\n", _aqconfig_.serial_port);

View File

@ -123,9 +123,12 @@ const char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS]
"50%", // 0xb2 (simulator) = 178 dec same as (0x99 + 25) "50%", // 0xb2 (simulator) = 178 dec same as (0x99 + 25)
"75%", // 0xcb (simulator) = 203 dec "75%", // 0xcb (simulator) = 203 dec
"100%" // 0xe4 = 228 dec "100%" // 0xe4 = 228 dec
} },
{/* Dimmer with full range */}
}; };
// DON'T FORGET TO CHANGE #define DIMMER_LIGHT_INDEX 10 in color_lights.h
/* /*
@ -198,11 +201,19 @@ bool isShowMode(const char *mode)
void set_currentlight_value(clight_detail *light, int index) void set_currentlight_value(clight_detail *light, int index)
{ {
// Dimmer 2 has different values (range 1 to 100)
if (light->lightType == LC_DIMMER2) {
if (index < 0 || index > 100)
light->currentValue = 0;
else
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 // 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; light->currentValue = 0;
else if (index > 0 && index < LIGHT_COLOR_OPTIONS) else if (index > 0 && index < LIGHT_COLOR_OPTIONS)
light->currentValue = index; light->currentValue = index;
}
} }
int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size) int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size)

View File

@ -13,6 +13,8 @@
#define RSSD_COLOR_LIGHT_OFFSET 64 #define RSSD_COLOR_LIGHT_OFFSET 64
#define RSSD_DIMMER_LIGHT_OFFSET 128 #define RSSD_DIMMER_LIGHT_OFFSET 128
//#define DIMMER_LIGHT_TYPE_INDEX 10
/* /*
// color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite) // color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite)
typedef enum clight_type { typedef enum clight_type {

View File

@ -698,9 +698,11 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
LOG(AQUA_LOG,LOG_ERR, "Config error, unknown light mode '%s'\n",type); LOG(AQUA_LOG,LOG_ERR, "Config error, unknown light mode '%s'\n",type);
} else { } else {
aqdata->lights[aqdata->num_lights].button = &aqdata->aqbuttons[num]; aqdata->lights[aqdata->num_lights].button = &aqdata->aqbuttons[num];
aqdata->lights[aqdata->num_lights].lightType = type; aqdata->lights[aqdata->num_lights].lightType = type;
aqdata->num_lights++;
aqdata->aqbuttons[num].special_mask |= PROGRAM_LIGHT; aqdata->aqbuttons[num].special_mask |= PROGRAM_LIGHT;
aqdata->aqbuttons[num].special_mask_ptr = &aqdata->lights[aqdata->num_lights];
aqdata->num_lights++;
} }
} else { } else {
LOG(AQUA_LOG,LOG_ERR, "Config error, (colored|programmable) Lights limited to %d, ignoring %s'\n",MAX_LIGHTS,param); LOG(AQUA_LOG,LOG_ERR, "Config error, (colored|programmable) Lights limited to %d, ignoring %s'\n",MAX_LIGHTS,param);
@ -809,6 +811,7 @@ pump_detail *getPumpFromButtonID(struct aqualinkdata *aqdata, aqkey *button)
if (aqdata->num_pumps < MAX_PUMPS) { if (aqdata->num_pumps < MAX_PUMPS) {
//printf ("Creating pump %d\n",button); //printf ("Creating pump %d\n",button);
button->special_mask |= VS_PUMP; button->special_mask |= VS_PUMP;
button->special_mask_ptr = (void*)&aqdata->pumps[aqdata->num_pumps];
aqdata->pumps[aqdata->num_pumps].button = button; aqdata->pumps[aqdata->num_pumps].button = button;
aqdata->pumps[aqdata->num_pumps].pumpType = PT_UNKNOWN; aqdata->pumps[aqdata->num_pumps].pumpType = PT_UNKNOWN;
aqdata->pumps[aqdata->num_pumps].rpm = TEMP_UNKNOWN; aqdata->pumps[aqdata->num_pumps].rpm = TEMP_UNKNOWN;

View File

@ -135,6 +135,26 @@ const char *HASSIO_VSP_DISCOVER = "{"
"\"retain\": false" "\"retain\": false"
"}"; "}";
const char *HASSIO_DIMMER_DISCOVER = "{"
"\"device\": {" HASS_DEVICE "},"
"\"availability\": {" HASS_AVAILABILITY "},"
"\"type\": \"light\","
"\"unique_id\": \"aqualinkd_%s\"," // Aux_5
"\"name\": \"%s\"," // Dimmer_name
"\"state_topic\": \"%s/%s\"," // aqualinkd,Aux_5
"\"command_topic\": \"%s/%s/set\"," // aqualinkd,Aux_5
"\"json_attributes_topic\": \"%s/%s/delay\"," // aqualinkd,Aux_5
"\"json_attributes_template\": \"{{ {'delay': value|int} | tojson }}\","
"\"payload_on\": \"1\","
"\"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"
"}";
// Need to add timer attributes to the switches, once figure out how to use in homeassistant // Need to add timer attributes to the switches, once figure out how to use in homeassistant
// ie aqualinkd/Filter_Pump/timer/duration // ie aqualinkd/Filter_Pump/timer/duration
@ -371,7 +391,20 @@ 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_.convert_mqtt_temp?HASSIO_CONVERT_CLIMATE_TOF:HASSIO_NO_CONVERT_CLIMATE)); (_aqconfig_.convert_mqtt_temp?HASSIO_CONVERT_CLIMATE_TOF:HASSIO_NO_CONVERT_CLIMATE));
sprintf(topic, "%s/climate/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name); sprintf(topic, "%s/climate/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->aqbuttons[i].name);
send_mqtt(nc, topic, msg); send_mqtt(nc, topic, msg);
} else if ( isPLIGHT(aqdata->aqbuttons[i].special_mask) && ((clight_detail *)aqdata->aqbuttons[i].special_mask_ptr)->lightType == LC_DIMMER2 ) {
// Dimmer
sprintf(msg,HASSIO_DIMMER_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,LIGHT_DIMMER_VALUE_TOPIC,
_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 { } else {
// Switches // 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}" , //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}" ,

View File

@ -39,6 +39,11 @@ unsigned char _std_cmd[2];
int _iaqua_q_length = 0; int _iaqua_q_length = 0;
bool _aqua_last_cmdfrom_queue = false; bool _aqua_last_cmdfrom_queue = false;
unsigned char _cmd_readyCommand[] = {0x3f, 0x20};
unsigned char _fullcmd[] = {0x00, 0x24, 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool push_iaqualink_cmd(unsigned char *cmd, int length) { bool push_iaqualink_cmd(unsigned char *cmd, int length) {
if (_iaqua_q_length >= IAQUA_QLEN ) { if (_iaqua_q_length >= IAQUA_QLEN ) {
LOG(IAQL_LOG,LOG_ERR, "Queue overflow, last command ignored!\n"); LOG(IAQL_LOG,LOG_ERR, "Queue overflow, last command ignored!\n");
@ -49,7 +54,7 @@ bool push_iaqualink_cmd(unsigned char *cmd, int length) {
_iqaua_queue[_iaqua_q_length].length = length; _iqaua_queue[_iaqua_q_length].length = length;
_iaqua_q_length++; _iaqua_q_length++;
LOG(IAQL_LOG, LOG_NOTICE, "Queue cmd, size %d, queu length=%d\n",length, _iaqua_q_length); LOG(IAQL_LOG, LOG_INFO, "Queue cmd, size %d, queu length=%d\n",length, _iaqua_q_length);
//LOG(IAQL_LOG,LOG_DEBUG, "Added to message queue, position %d 0x%02hhx|0x%02hhx|0x%02hhx|0x%02hhx\n",_rssa_q_length-1,_rssa_queue[_rssa_q_length-1][0],_rssa_queue[_rssa_q_length-1][1],_rssa_queue[_rssa_q_length-1][2],_rssa_queue[_rssa_q_length-1][3]); //LOG(IAQL_LOG,LOG_DEBUG, "Added to message queue, position %d 0x%02hhx|0x%02hhx|0x%02hhx|0x%02hhx\n",_rssa_q_length-1,_rssa_queue[_rssa_q_length-1][0],_rssa_queue[_rssa_q_length-1][1],_rssa_queue[_rssa_q_length-1][2],_rssa_queue[_rssa_q_length-1][3]);
return true; return true;
@ -86,6 +91,8 @@ int get_iaqualink_cmd(unsigned char source_message_type, unsigned char **dest_me
_aqua_last_cmdfrom_queue = true; _aqua_last_cmdfrom_queue = true;
} else { } else {
LOG(IAQL_LOG,LOG_WARNING,"Next command in queue is too large, ignoring\n"); LOG(IAQL_LOG,LOG_WARNING,"Next command in queue is too large, ignoring\n");
LOG(IAQL_LOG,LOG_ERR,"Re sending get prepare frame\n");
*dest_message = _cmd_readyCommand;
} }
} }
@ -182,25 +189,25 @@ void lastchecksum(unsigned char *packet, int length){
switch (packet[PKT_CMD]){ switch (packet[PKT_CMD]){
case 0x70: case 0x70:
if (last70checksum != packet[length-3] && last70checksum != 0x00) { if (last70checksum != packet[length-3] && last70checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x70 *******\n"); LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x70 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
} }
last70checksum = packet[length-3]; last70checksum = packet[length-3];
break; break;
case 0x71: case 0x71:
if (last71checksum != packet[length-3] && last71checksum != 0x00) { if (last71checksum != packet[length-3] && last71checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x71 *******\n"); LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x71 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
} }
last71checksum = packet[length-3]; last71checksum = packet[length-3];
break; break;
case 0x72: case 0x72:
if (last72checksum != packet[length-3] && last72checksum != 0x00) { if (last72checksum != packet[length-3] && last72checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x72 *******\n"); LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x72 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
} }
last72checksum = packet[length-3]; last72checksum = packet[length-3];
break; break;
@ -214,6 +221,7 @@ void lastchecksum(unsigned char *packet, int length){
All taken from panel Yg, but only heater setpoints seem to work. All taken from panel Yg, but only heater setpoints seem to work.
Only setpoints seem to work, Only setpoints seem to work,
Can't get to work on T2 panel
RPM to 2750 RPM to 2750
Bit 6 = 0x5e Bit 6 = 0x5e
Bit 10 * 256 + Bit 11 Bit 10 * 256 + Bit 11
@ -223,6 +231,8 @@ HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0a|0xbe|0x00|0x00|0x00|
RPM to 2995 RPM to 2995
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03| HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03|
Can't get to work on T2 panel
SWG 50% SWG 50%
Byte 6 = 0x19 Byte 6 = 0x19
Byte 7 = 50% Byte 7 = 50%
@ -233,11 +243,13 @@ SWG 51%
Byte 7 = 51% Byte 7 = 51%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03| HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03|
Works on T2
Spa Setpoint 102 Spa Setpoint 102
Byte 6 = 0x06 Byte 6 = 0x06
Byte 8 = 0x66=102 Byte 8 = 0x66=102
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x06|0x00|0x66|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x16|0x10|0x03| HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x06|0x00|0x66|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x16|0x10|0x03|
Works on T2
Pool Setpoint 72 Pool Setpoint 72
Byte 6 = 0x05 Byte 6 = 0x05
Byte 8 = 0x48=72 Byte 8 = 0x48=72
@ -245,8 +257,6 @@ HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x05|0x00|0x48|0x00|0x00|0x00|0x00|0x00|0x00|
*/ */
unsigned char _cmd_readyCommand[] = {0x3f, 0x20};
unsigned char _fullcmd[] = {0x00, 0x24, 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void set_iaqualink_aux_state(aqkey *button, bool isON) { void set_iaqualink_aux_state(aqkey *button, bool isON) {
@ -259,6 +269,8 @@ void set_iaqualink_aux_state(aqkey *button, bool isON) {
LOG(IAQL_LOG, LOG_ERR, "Couldn't find iaqualink keycode for button %s\n",button->label); LOG(IAQL_LOG, LOG_ERR, "Couldn't find iaqualink keycode for button %s\n",button->label);
} }
// reset
_fullcmd[4] = 0x00;
} }
void set_iaqualink_heater_setpoint(int value, bool isPool) { void set_iaqualink_heater_setpoint(int value, bool isPool) {
@ -275,6 +287,24 @@ void set_iaqualink_heater_setpoint(int value, bool isPool) {
push_iaqualink_cmd(_cmd_readyCommand, 2); push_iaqualink_cmd(_cmd_readyCommand, 2);
push_iaqualink_cmd(_fullcmd, 19); push_iaqualink_cmd(_fullcmd, 19);
// reset
_fullcmd[4] = 0x00;
_fullcmd[6] = 0x00;
}
void iAqSetButtonState(struct aqualinkdata *aq_data, int index, const unsigned char byte)
{
if ( aq_data->aqbuttons[index].led->state != OFF && byte == 0x00) {
aq_data->aqbuttons[index].led->state = OFF;
LOG(IAQL_LOG, LOG_INFO, "Set %s off\n",aq_data->aqbuttons[index].label);
} else if ( aq_data->aqbuttons[index].led->state != ON && byte == 0x01) {
aq_data->aqbuttons[index].led->state = ON;
LOG(IAQL_LOG, LOG_INFO, "Set %s on\n",aq_data->aqbuttons[index].label);
} else if ( aq_data->aqbuttons[index].led->state != ENABLE && byte == 0x03) {
aq_data->aqbuttons[index].led->state = ENABLE;
LOG(IAQL_LOG, LOG_INFO, "Set %s enabled\n",aq_data->aqbuttons[index].label);
}
} }
/* /*
@ -287,7 +317,7 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
{ {
if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS) if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS)
{ {
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true); logPacket(IAQL_LOG, LOG_INFO, packet, length, true);
int startIndex = 4 + 1; int startIndex = 4 + 1;
int numberBytes = packet[4]; int numberBytes = packet[4];
int offsetIndex = startIndex + numberBytes; int offsetIndex = startIndex + numberBytes;
@ -314,12 +344,15 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
if (byteType == 0) { if (byteType == 0) {
label = "Filter Pump "; label = "Filter Pump ";
if (isPDA_PANEL) { iAqSetButtonState(aq_data, 0, byte); }
} else if (byteType == 1) { } else if (byteType == 1) {
label = "Pool Heater "; // 0x01=on&heating, 0x03=ena label = "Pool Heater "; // 0x00 off 0x01=on&heating, 0x03=enabled
if (isPDA_PANEL) { iAqSetButtonState(aq_data, aq_data->pool_heater_index , byte); }
} else if (byteType == 2) { } else if (byteType == 2) {
label = "Spa "; label = "Spa ";
} else if (byteType == 3) { } else if (byteType == 3) {
label = "Spa Heater "; // 0x01=on&heating, 0x03=ena label = "Spa Heater "; // 0x01=on&heating, 0x03=ena
if (isPDA_PANEL) { iAqSetButtonState(aq_data, aq_data->spa_heater_index , byte); }
} else if (byteType == 6) { } else if (byteType == 6) {
label = "Pool Htr setpoint"; label = "Pool Htr setpoint";
} else if (byteType == 8 || byteType == 9) {// 8 usually, also get 9 & 14 (different spa/heater modes not sorted out yet. 14 sometimes blank as well) } else if (byteType == 8 || byteType == 9) {// 8 usually, also get 9 & 14 (different spa/heater modes not sorted out yet. 14 sometimes blank as well)
@ -338,9 +371,9 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
else else
label = " "; label = " ";
LOG(IAQL_LOG, LOG_NOTICE, "%-17s = %3d | index=%d type=(%0.2d 0x%02hhx) value=0x%02hhx offset=%d\n", label, byte, i, byteType, byteType, byte, (offsetIndex + i)); LOG(IAQL_LOG, LOG_INFO, "%-17s = %3d | index=%d type=(%0.2d 0x%02hhx) value=0x%02hhx offset=%d\n", label, byte, i, byteType, byteType, byte, (offsetIndex + i));
} }
LOG(IAQL_LOG, LOG_NOTICE, "Status from other protocols Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d, WaterTemp=%d, AirTemp=%d\n", LOG(IAQL_LOG, LOG_INFO, "Status from other protocols Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d, WaterTemp=%d, AirTemp=%d\n",
aq_data->aqbuttons[0].led->state == OFF ? "Off" : "On ", aq_data->aqbuttons[0].led->state == OFF ? "Off" : "On ",
aq_data->aqbuttons[1].led->state == OFF ? "Off" : "On ", aq_data->aqbuttons[1].led->state == OFF ? "Off" : "On ",
aq_data->swg_percent, aq_data->swg_percent,
@ -352,13 +385,14 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
} }
else if (packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS) else if (packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS)
{ {
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true); logPacket(IAQL_LOG, LOG_INFO, packet, length, true);
int numLabels = packet[4]; int numLabels = packet[4];
int start = numLabels + 4 + 1; int start = numLabels + 4 + 1;
if (numLabels == 1) if (numLabels == 1)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "**** !!! haven't decoded above packet yet !!! *****\n"); // This just seem to list a ton of pump (names)
LOG(IAQL_LOG, LOG_INFO, "**** !!! haven't decoded above packet yet !!! *****\n");
return false; return false;
} }
@ -367,14 +401,14 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
int status = packet[start]; int status = packet[start];
int length = packet[start + 1]; int length = packet[start + 1];
int byteType = packet[5 + i]; int byteType = packet[5 + i];
LOG(IAQL_LOG, LOG_NOTICE, "%-15.*s = %s | index %d type=(%0.2d 0x%02hhx) status=0x%02hhx start=%d length=%d\n", length, &packet[start + 2], (status == 0x00 ? "Off" : "On "), i, byteType, byteType, status, start, length); LOG(IAQL_LOG, LOG_INFO, "%-15.*s = %s | index %d type=(%0.2d 0x%02hhx) status=0x%02hhx start=%d length=%d\n", length, &packet[start + 2], (status == 0x00 ? "Off" : "On "), i, byteType, byteType, status, start, length);
// Check against virtual onetouch buttons. // Check against virtual onetouch buttons.
for (int bi=aq_data->virtual_button_start ; bi < aq_data->total_buttons ; bi++) { for (int bi=aq_data->virtual_button_start ; bi < aq_data->total_buttons ; bi++) {
if (rsm_strcmp((char *)&packet[start + 2], aq_data->aqbuttons[bi].label) == 0) { if (rsm_strcmp((char *)&packet[start + 2], aq_data->aqbuttons[bi].label) == 0) {
//LOG(IAQL_LOG, LOG_NOTICE, "Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); //LOG(IAQL_LOG, LOG_INFO, "Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On "));
// == means doesn;t match, RS 1=on 0=off / LED enum 1=off 0=on // == means doesn;t match, RS 1=on 0=off / LED enum 1=off 0=on
if (aq_data->aqbuttons[bi].led->state == status) { if (aq_data->aqbuttons[bi].led->state == status) {
LOG(IAQL_LOG, LOG_NOTICE, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On ")); LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On "));
aq_data->aqbuttons[bi].led->state = (status == 0x00 ? OFF:ON); aq_data->aqbuttons[bi].led->state = (status == 0x00 ? OFF:ON);
aq_data->updated = true; aq_data->updated = true;
} }
@ -385,7 +419,7 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
} }
else if (packet[PKT_CMD] == CMD_IAQ_AUX_STATUS) else if (packet[PKT_CMD] == CMD_IAQ_AUX_STATUS)
{ {
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true); logPacket(IAQL_LOG, LOG_INFO, packet, length, true);
// Look at notes in iaqualink.c for how this packet is made up // Look at notes in iaqualink.c for how this packet is made up
// Since this is so similar to above CMD_IAQ_1TOUCH_STATUS, we should look at using same logic for both. // Since this is so similar to above CMD_IAQ_1TOUCH_STATUS, we should look at using same logic for both.
int start = packet[4]; int start = packet[4];
@ -397,17 +431,17 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
int labellen = packet[status + 4]; int labellen = packet[status + 4];
if (labelstart + labellen < length) if (labelstart + labellen < length)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "%-15.*s = %s | bit1=0x%02hhx bit2=0x%02hhx bit3=0x%02hhx bit4=0x%02hhx\n", labellen, &packet[labelstart], (packet[status] == 0x00 ? "Off" : "On "), packet[status], packet[status + 1], packet[status + 2], packet[status + 3]); LOG(IAQL_LOG, LOG_INFO, "%-15.*s = %s | bit1=0x%02hhx bit2=0x%02hhx bit3=0x%02hhx bit4=0x%02hhx\n", labellen, &packet[labelstart], (packet[status] == 0x00 ? "Off" : "On "), packet[status], packet[status + 1], packet[status + 2], packet[status + 3]);
} }
if (isPDA_PANEL) { if (isPDA_PANEL) {
for (int bi=2 ; bi < aq_data->total_buttons ; bi++) { for (int bi=2 ; bi < aq_data->total_buttons ; bi++) {
if (rsm_strcmp((char *)&packet[labelstart], aq_data->aqbuttons[bi].label) == 0) { if (rsm_strcmp((char *)&packet[labelstart], aq_data->aqbuttons[bi].label) == 0) {
if (aq_data->aqbuttons[bi].led->state == packet[status]) { if (aq_data->aqbuttons[bi].led->state == packet[status]) {
LOG(IAQL_LOG, LOG_NOTICE, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(packet[status] == 0x00 ? "Off" : "On ")); LOG(IAQL_LOG, LOG_INFO, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(packet[status] == 0x00 ? "Off" : "On "));
aq_data->aqbuttons[bi].led->state = (packet[status] == 0x00 ? OFF:ON); aq_data->aqbuttons[bi].led->state = (packet[status] == 0x00 ? OFF:ON);
aq_data->updated = true; aq_data->updated = true;
} }
//LOG(IAQL_LOG, LOG_NOTICE, "Match %s to %.*s state(aqd=%d pnl=%d)\n",aq_data->aqbuttons[bi].label, labellen, (char *)&packet[labelstart], aq_data->aqbuttons[bi].led->state, packet[status]); //LOG(IAQL_LOG, LOG_INFO, "Match %s to %.*s state(aqd=%d pnl=%d)\n",aq_data->aqbuttons[bi].label, labellen, (char *)&packet[labelstart], aq_data->aqbuttons[bi].led->state, packet[status]);
} }
} }
} }
@ -437,19 +471,27 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink
static int cnt = 0; static int cnt = 0;
//static unsigned char ID = 0; //static unsigned char ID = 0;
//static cur_swg = 0; //static cur_swg = 0;
static unsigned char sendid = 0x00;
if (packet[PKT_CMD] == 0x53) if (packet[PKT_CMD] == 0x53)
{ {
cnt++; cnt++;
if (cnt == 20) { if (cnt == 20) {
cnt=0; cnt=0;
/*
sendid=sendid==0x18?0x60:0x18;
_fullcmd[4] = sendid;
push_iaqualink_cmd(_cmd_readyCommand, 2);
push_iaqualink_cmd(_fullcmd, 19);
_fullcmd[4] = 0x00;
*/
push_iaqualink_cmd(cmd_getMainstatus, 2); push_iaqualink_cmd(cmd_getMainstatus, 2);
push_iaqualink_cmd(cmd_getTouchstatus, 2); push_iaqualink_cmd(cmd_getTouchstatus, 2);
push_iaqualink_cmd(cmd_getAuxstatus, 2); push_iaqualink_cmd(cmd_getAuxstatus, 2);
/* /*
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"********** Send %d 0x%02hhx ************\n",ID,ID); LOG(IAQL_LOG, LOG_INFO,"********** Send %d 0x%02hhx ************\n",ID,ID);
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
_fullcmd[4] = ID++; _fullcmd[4] = ID++;
push_iaqualink_cmd(_cmd_readyCommand, 2); push_iaqualink_cmd(_cmd_readyCommand, 2);
@ -478,13 +520,13 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink
//push_iaqualink_cmd(cmd_getAuxstatus, 2); //push_iaqualink_cmd(cmd_getAuxstatus, 2);
/* /*
if (aq_data->swg_percent != cur_swg && cur_swg != 0) { if (aq_data->swg_percent != cur_swg && cur_swg != 0) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"********** SWG Changed to %d ************\n",aq_data->swg_percent); LOG(IAQL_LOG, LOG_INFO,"********** SWG Changed to %d ************\n",aq_data->swg_percent);
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n"); LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
exit(0); exit(0);
} }
cur_swg = aq_data->swg_percent; cur_swg = aq_data->swg_percent;
LOG(IAQL_LOG, LOG_NOTICE,"******* QUEUE SWG Comand of %d | 0x%02hhx *************\n",ID,ID); LOG(IAQL_LOG, LOG_INFO,"******* QUEUE SWG Comand of %d | 0x%02hhx *************\n",ID,ID);
ID++;*/ ID++;*/
} }
@ -524,7 +566,7 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
*/ */
if (packet_buffer[PKT_CMD] == CMD_PROBE) if (packet_buffer[PKT_CMD] == CMD_PROBE)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "Got probe on '0x%02hhx' 2nd iAqualink Protocol\n", packet_buffer[PKT_DEST]); LOG(IAQL_LOG, LOG_INFO, "Got probe on '0x%02hhx' 2nd iAqualink Protocol\n", packet_buffer[PKT_DEST]);
send_extended_ack(rs_fd, packet_buffer[PKT_CMD], 0x00); send_extended_ack(rs_fd, packet_buffer[PKT_CMD], 0x00);
} }
else if (packet_buffer[PKT_CMD] == 0x53) else if (packet_buffer[PKT_CMD] == 0x53)
@ -534,22 +576,22 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
if (cnt == 10) if (cnt == 10)
{ {
//cnt = 5; //cnt = 5;
LOG(IAQL_LOG, LOG_NOTICE, "Sent accept next packet Comand\n"); LOG(IAQL_LOG, LOG_INFO, "Sent accept next packet Comand\n");
send_extended_ack(rs_fd, 0x3f, 0x20); send_extended_ack(rs_fd, 0x3f, 0x20);
} }
if (cnt == 20) if (cnt == 20)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "Sending get status\n"); LOG(IAQL_LOG, LOG_INFO, "Sending get status\n");
send_extended_ack(rs_fd, 0x3f, 0x08); send_extended_ack(rs_fd, 0x3f, 0x08);
} }
else if (cnt == 22) else if (cnt == 22)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "Sending get other status\n"); LOG(IAQL_LOG, LOG_INFO, "Sending get other status\n");
send_extended_ack(rs_fd, 0x3f, 0x10); send_extended_ack(rs_fd, 0x3f, 0x10);
} }
else if (cnt == 24) else if (cnt == 24)
{ {
LOG(IAQL_LOG, LOG_NOTICE, "Sending get aux button status\n"); LOG(IAQL_LOG, LOG_INFO, "Sending get aux button status\n");
send_extended_ack(rs_fd, 0x3f, 0x18); send_extended_ack(rs_fd, 0x3f, 0x18);
} }
else else
@ -576,7 +618,7 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
//pb3[4] = id++; //pb3[4] = id++;
//swg[5] = ++id; //swg[5] = ++id;
LOG(IAQL_LOG, LOG_NOTICE, "*** Sending SWG dec=%d hex=0x%02hhx\n", swg[5], swg[5]); LOG(IAQL_LOG, LOG_INFO, "*** Sending SWG dec=%d hex=0x%02hhx\n", swg[5], swg[5]);
// send_packet(rs_fd, pb2, 25); // send_packet(rs_fd, pb2, 25);
send_jandy_command(rs_fd, swg, 19); send_jandy_command(rs_fd, swg, 19);
} }
@ -588,199 +630,3 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
} }
#endif #endif
/*
----
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x20. (0x20 command)
Retrieve 0x73 command Same ID iAqualink
Reply iAQ pButton ( turn something on / set something)
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x08. (0x08 command)
Retrieve 0x70 command on AqualinkTouch ID
Reply iAQ pButton (status / last part of frame is board cpu)
-- Byte 4 = offset.
-- Byte 21 look like spa heat 0x00=off, 0x03=enabled
-- offest+ 8 spa setpoint
-- offset+ 10 air temp
-- offest+ 13 pool temp
-- offset+ 14 SWG% ?????
-- Byte 27 looks like air temp
-- Byte 28 air temp????
-- Byte 30 pool temp
-- Byte 34 looks like SWG%
-- after byte 0xff is board
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x10. (0x10 command)
Retrieve 0x71 command on AqualinkTouch ID
Reply iAQ pButton (not sure)
Byte 4 & 5 seems to indicate a different sub type
0x71|0x01|0x19 = status about pool / spa / speed 1,2,3,4 / pool & spa heat
0x71|0x01|0x1a = no idea
0x71|0x01|0x17 = Pump numbers (doesn't seem to have any status, just pump names)
0x71|0x06|0x01 = Touch like spa mode / all off
0x71|0x07|0x01 = Same as above. but more trailing packets.
Retrieve poll 0x53
Reply ack w/ command 0x3f 0x18. (0x18 is command)
Retrieve 0x72 command on AqualinkTouch ID
Get a massive packet Aux status
----
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x20. (0x20 command)
Retrieve 0x72 command
Reply iAQ pButton (turn something on / set something). Below are examples.
RPM to 2750
Bit 10 * 256 + Bit 11
Bit 6 & 7 probably pump index.
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0a|0xbe|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xd5|0x10|0x03|
RPM to 2995
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03|
SWG 50%
Byte 7 = 50%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x32|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0e|0x10|0x03|
SWG 51%
Byte 7 = 51%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03|
---------
Send command 0x18 to 0xa1 returns below to 0x31. Looks like status of aux devices.
Retrieve poll 0x53
Reply ack w/ command 0x3f 0x18. (0x18 is command)
Get a massive packet back, of aux status
Filter pump does not effect the below.
Heater on/off does not effect below.
HEater setpoints does not effect.
Only Aux on/off seem to effect the status.
4th bit tells you where to start,
after start 4 bits are status
last bit of status tell you chars in label.
after label repeat start 4 bits.
For Aux1 10th bit 0=off 1=on 11 to 14 15 to 19=name
Aux2 19th
Aux3 28
Aux4 37
In Below Aux 3 color light / Aux 4 dimmer / Aux 5 color light (different type to aux3)
Aux 1 off / Aux 3 on
HEX: 0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd5|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 213| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
Aux 1 on / Aux 3 on
| HEX: 0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd6|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 1| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 214| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
Aux 1 off Aux3 to different light color
Hex |0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x00|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd4|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 0| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 212| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
RS16 panel.
HEX: 0x10|0x02|0x31|0x72|0x0f|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|0x09|0x0a|0x0b|0x0c|0x0d|0x0e|0x0f|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x33|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x34|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x36|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x37|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x31|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x32|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x33|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x34|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x35|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x36|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x37|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x38|0x77|0x10|0x03|
Dec | 16| 2| 49| 114| 15| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 1| 0| 0| 4| 65| 117| 120| 51| 1| 1| 0| 0| 4| 65| 117| 120| 52| 1| 1| 0| 0| 4| 65| 117| 120| 53| 1| 1| 0| 0| 4| 65| 117| 120| 54| 1| 1| 0| 0| 4| 65| 117| 120| 55| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 49| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 50| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 51| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 52| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 53| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 54| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 55| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 56| 119| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | | | | | A| u| x| 6| | | | | | A| u| x| 7| | | | | | A| u| x| | B| 1| | | | | | A| u| x| | B| 2| | | | | | A| u| x| | B| 3| | | | | | A| u| x| | B| 4| | | | | | A| u| x| | B| 5| | | | | | A| u| x| | B| 6| | | | | | A| u| x| | B| 7| | | | | | A| u| x| | B| 8| w| |
Hex |0x10|0x02|0x31|0x72|
*/
/* Startup sequences
RS16 combo
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x00|0x0c|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x00|0x05|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
RS8 Combo rev T.2
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x00|0x0c|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x00|0x05|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
RS4 rev Yg
Notice: Serial Log:Read Jandy packet To 0xa3 of type Probe | HEX: 0x10|0x02|0xa3|0x00|0xb5|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x61' | HEX: 0x10|0x02|0xa3|0x61|0x00|0x00|0x00|0x04|0x00|0x27|0x41|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x50' | HEX: 0x10|0x02|0xa3|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x25|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x51' | HEX: 0x10|0x02|0xa3|0x51|0x00|0x06|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x59' | HEX: 0x10|0x02|0xa3|0x59|0x00|0x0e|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x52' | HEX: 0x10|0x02|0xa3|0x52|0x00|0x07|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x53' | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x3f|0x00|0x52|0x10|0x03|
RS6 rev T2 RS8 (home)
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x01|0x0d|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x03|0x08|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
*/
/*
0x10|0x02|0x31|0x72|0x0f|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|0x09|0x0a|0x0b|0x0c|0x0d|0x0e|0x0f|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x33|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x34|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x36|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x31|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x32|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x33|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x34|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x35|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x36|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x38|0x70|0x10|0x03|
Only panel (RS8)
Air index 3 type 15 (pump off)
Air index 3 type 14 (pump off)
Air index 3 type 8 (pump on)
Water index 5 type 15 (pump on)
Temp2 ndex 8 type 20
always 1 | index=4 type=(15 0x0f)
Comb0
Spa setpoint index 8 type 14
Air index 8 type 26
*/

View File

@ -106,4 +106,273 @@ Below get's sent to AqualinkTouch with iAqualink is enabled.
End of message is board cpu and panel type. End of message is board cpu and panel type.
Read Jandy packet To 0x33 of type Unknown '0x70' | HEX: 0x10|0x02|0x33|0x70|0x0d|0x00|0x01|0x02|0x03|0x05|0x06|0x07|0x0e|0x0f|0x1a|0x1d|0x20|0x21|0x00|0x00|0x00|0x00|0x00|0x48|0x00|0x66|0x00|0x50|0x00|0x00|0x00|0xff|0x42|0x30|0x33|0x31|0x36|0x38|0x32|0x33|0x20|0x52|0x53|0x2d|0x34|0x20|0x43|0x6f|0x6d|0x62|0x6f|0x00|0x00|0x4b|0x10|0x03| Read Jandy packet To 0x33 of type Unknown '0x70' | HEX: 0x10|0x02|0x33|0x70|0x0d|0x00|0x01|0x02|0x03|0x05|0x06|0x07|0x0e|0x0f|0x1a|0x1d|0x20|0x21|0x00|0x00|0x00|0x00|0x00|0x48|0x00|0x66|0x00|0x50|0x00|0x00|0x00|0xff|0x42|0x30|0x33|0x31|0x36|0x38|0x32|0x33|0x20|0x52|0x53|0x2d|0x34|0x20|0x43|0x6f|0x6d|0x62|0x6f|0x00|0x00|0x4b|0x10|0x03|
*/
/*
----
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x20. (0x20 command)
Retrieve 0x73 command Same ID iAqualink
Reply iAQ pButton ( turn something on / set something)
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x08. (0x08 command)
Retrieve 0x70 command on AqualinkTouch ID
Reply iAQ pButton (status / last part of frame is board cpu)
-- Byte 4 = offset.
-- Byte 21 look like spa heat 0x00=off, 0x03=enabled
-- offest+ 8 spa setpoint
-- offset+ 10 air temp
-- offest+ 13 pool temp
-- offset+ 14 SWG% ?????
-- Byte 27 looks like air temp
-- Byte 28 air temp????
-- Byte 30 pool temp
-- Byte 34 looks like SWG%
-- after byte 0xff is board
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x10. (0x10 command)
Retrieve 0x71 command on AqualinkTouch ID
Reply iAQ pButton (not sure)
Byte 4 & 5 seems to indicate a different sub type
0x71|0x01|0x19 = status about pool / spa / speed 1,2,3,4 / pool & spa heat
0x71|0x01|0x1a = no idea
0x71|0x01|0x17 = Pump numbers (doesn't seem to have any status, just pump names)
0x71|0x06|0x01 = Touch like spa mode / all off
0x71|0x07|0x01 = Same as above. but more trailing packets.
Retrieve poll 0x53
Reply ack w/ command 0x3f 0x18. (0x18 is command)
Retrieve 0x72 command on AqualinkTouch ID
Get a massive packet Aux status
----
Retrieve poll 0x53
Reply ack w/ command 0x01|0x3f|0x20. (0x20 command)
Retrieve 0x72 command
Reply iAQ pButton (turn something on / set something). Below are examples.
RPM to 2750
Bit 10 * 256 + Bit 11
Bit 6 & 7 probably pump index.
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0a|0xbe|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xd5|0x10|0x03|
RPM to 2995
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03|
SWG 50%
Byte 7 = 50%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x32|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0e|0x10|0x03|
SWG 51%
Byte 7 = 51%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03|
---------
Send command 0x18 to 0xa1 returns below to 0x31. Looks like status of aux devices.
Retrieve poll 0x53
Reply ack w/ command 0x3f 0x18. (0x18 is command)
Get a massive packet back, of aux status
Filter pump does not effect the below.
Heater on/off does not effect below.
HEater setpoints does not effect.
Only Aux on/off seem to effect the status.
4th bit tells you where to start,
after start 4 bits are status
last bit of status tell you chars in label.
after label repeat start 4 bits.
For Aux1 10th bit 0=off 1=on 11 to 14 15 to 19=name
Aux2 19th
Aux3 28
Aux4 37
In Below Aux 3 color light / Aux 4 dimmer / Aux 5 color light (different type to aux3)
Aux 1 off / Aux 3 on
HEX: 0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd5|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 213| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
Aux 1 on / Aux 3 on
| HEX: 0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd6|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 1| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 214| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
Aux 1 off Aux3 to different light color
Hex |0x10|0x02|0x31|0x72|0x05|0x01|0x02|0x03|0x04|0x05|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x00|0x07|0x02|0x03|0x04|0x41|0x75|0x78|0x33|0x00|0x01|0x01|0x00|0x04|0x41|0x75|0x78|0x34|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0xd4|0x10|0x03|
Dec | 16| 2| 49| 114| 5| 1| 2| 3| 4| 5| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 0| 7| 2| 3| 4| 65| 117| 120| 51| 0| 1| 1| 0| 4| 65| 117| 120| 52| 0| 1| 0| 0| 4| 65| 117| 120| 53| 212| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | |
RS16 panel.
HEX: 0x10|0x02|0x31|0x72|0x0f|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|0x09|0x0a|0x0b|0x0c|0x0d|0x0e|0x0f|0x00|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x33|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x34|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x36|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x37|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x31|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x32|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x33|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x34|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x35|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x36|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x37|0x01|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x38|0x77|0x10|0x03|
Dec | 16| 2| 49| 114| 15| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 0| 1| 0| 0| 4| 65| 117| 120| 49| 1| 1| 0| 0| 4| 65| 117| 120| 50| 1| 1| 0| 0| 4| 65| 117| 120| 51| 1| 1| 0| 0| 4| 65| 117| 120| 52| 1| 1| 0| 0| 4| 65| 117| 120| 53| 1| 1| 0| 0| 4| 65| 117| 120| 54| 1| 1| 0| 0| 4| 65| 117| 120| 55| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 49| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 50| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 51| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 52| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 53| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 54| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 55| 1| 1| 0| 0| 6| 65| 117| 120| 32| 66| 56| 119| 16| 3
Ascii | | | 1| r| | | | | | | | | | | | | | | | | | | | | | A| u| x| 1| | | | | | A| u| x| 2| | | | | | A| u| x| 3| | | | | | A| u| x| 4| | | | | | A| u| x| 5| | | | | | A| u| x| 6| | | | | | A| u| x| 7| | | | | | A| u| x| | B| 1| | | | | | A| u| x| | B| 2| | | | | | A| u| x| | B| 3| | | | | | A| u| x| | B| 4| | | | | | A| u| x| | B| 5| | | | | | A| u| x| | B| 6| | | | | | A| u| x| | B| 7| | | | | | A| u| x| | B| 8| w| |
Hex |0x10|0x02|0x31|0x72|
*/
/* Startup sequences
RS16 combo
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x00|0x0c|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x00|0x05|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
RS8 Combo rev T.2
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x00|0x0c|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x00|0x05|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
RS4 rev Yg
Notice: Serial Log:Read Jandy packet To 0xa3 of type Probe | HEX: 0x10|0x02|0xa3|0x00|0xb5|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x61' | HEX: 0x10|0x02|0xa3|0x61|0x00|0x00|0x00|0x04|0x00|0x27|0x41|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x50' | HEX: 0x10|0x02|0xa3|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x25|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x51' | HEX: 0x10|0x02|0xa3|0x51|0x00|0x06|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x59' | HEX: 0x10|0x02|0xa3|0x59|0x00|0x0e|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x52' | HEX: 0x10|0x02|0xa3|0x52|0x00|0x07|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0xa3 of type Unknown '0x53' | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
Notice: Serial Log:Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x3f|0x00|0x52|0x10|0x03|
RS6 rev T2 RS8 (home)
Debug: RS Serial: Read Jandy packet To 0xa1 of type Probe | HEX: 0x10|0x02|0xa1|0x00|0xb3|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x61' | HEX: 0x10|0x02|0xa1|0x61|0x00|0x00|0x00|0x01|0x00|0x1d|0x32|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x50' | HEX: 0x10|0x02|0xa1|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x23|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x51' | HEX: 0x10|0x02|0xa1|0x51|0x31|0x42|0x41|0x36|0x32|0x38|0x32|0x35|0x42|0x37|0x43|0x36|0x39|0x41|0x34|0x43|0x00|0xa2|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x59' | HEX: 0x10|0x02|0xa1|0x59|0x01|0x0d|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX: 0x10|0x02|0xa1|0x52|0x03|0x08|0x10|0x03|
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
*/
/*
0x10|0x02|0x31|0x72|0x0f|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|0x09|0x0a|0x0b|0x0c|0x0d|0x0e|0x0f|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x33|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x34|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x36|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x31|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x32|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x33|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x34|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x35|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x36|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x38|0x70|0x10|0x03|
Only panel (RS8)
Air index 3 type 15 (pump off)
Air index 3 type 14 (pump off)
Air index 3 type 8 (pump on)
Water index 5 type 15 (pump on)
Temp2 ndex 8 type 20
always 1 | index=4 type=(15 0x0f)
Comb0
Spa setpoint index 8 type 14
Air index 8 type 26
*/
/*
Pump RPM
All taken from panel Yg, but only heater setpoints seem to work.
Only setpoints seem to work,
RPM to 2750
Bit 6 = 0x5e
Bit 10 * 256 + Bit 11
Bit 7 or 9 probably pump index.
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0a|0xbe|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xd5|0x10|0x03|
RPM to 2995
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03|
Below is setting RPM to 2505
packet To 0xa3 of type iAqalnk Poll | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
packet To 0x00 of type Ack w/ Command | HEX: 0x10|0x02|0x00|0x01|0x3f|0x20|0x72|0x10|0x03|
packet To 0x33 of type iAq Poll | HEX: 0x10|0x02|0x33|0x30|0x75|0x10|0x03|
packet To 0xa3 of type Unknown '0x73' | HEX: 0x10|0x02|0xa3|0x73|0x28|0x10|0x03|
packet To 0x00 of type iAqualnk sendCmd | HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x09|0xc9|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xdf|0x10|0x03|
packet To 0x33 of type iAq Poll | HEX: 0x10|0x02|0x33|0x30|0x75|0x10|0x03|
packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
packet To 0x33 of type iAq 1Tch status | HEX: 0x10|0x02|0x33|0x71|0x07|0x01|0x02|0x03|0x04|0x05|0x0f|0x12|0x00|0x07|0x41|0x6c|0x6c|0x20|0x4f|0x46|0x46|0x00|0x08|0x53|0x70|0x61|0x20|0x4d|0x6f|0x64|0x65|0x00|0x0a|0x43|0x6c|0x65|0x61|0x6e|0x20|0x4d|0x6f|0x64|0x65|0x00|0x08|0x42|0x75|0x62|0x62|0x6c|0x65|0x72|0x73|0x00|0x0a|0x57|0x61|0x74|0x65|0x72|0x66|0x61|0x6c|0x6c|0x31|0x04|0x09|0xc9|0x0d|0x7a|0x06|0xa4|0x0a|0xbe|0x08|0xca|0x08|0xca|0x0a|0xbe|0x0a|0xbe|0x05|0xdc|0x04|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x6a|0x10|0x03|
All OFF = Off | index 0 type=(01 0x01) status=0x00 start=12 length=7
Spa Mode = Off | index 1 type=(02 0x02) status=0x00 start=21 length=8
Clean Mode = Off | index 2 type=(03 0x03) status=0x00 start=31 length=10
Bubblers = Off | index 3 type=(04 0x04) status=0x00 start=43 length=8
Waterfall1 = Off | index 4 type=(05 0x05) status=0x00 start=53 length=10
*** RPM is in the next bytes from iAq 1Tch status. But can't tell how to pull them since SWG is also here as well. ****
*/
/*
SWG
SWG 50%
Byte 6 = 0x19
Byte 7 = 50%
Byte 9 & 10 ????
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x32|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0e|0x10|0x03|
SWG 51%
Byte 7 = 51%
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03|
Below is set SWG to 35
packet To 0xa3 of type iAqalnk Poll | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
packet To 0x00 of type Ack w/ Command | HEX: 0x10|0x02|0x00|0x01|0x3f|0x20|0x72|0x10|0x03|
packet To 0x33 of type iAq Poll | HEX: 0x10|0x02|0x33|0x30|0x75|0x10|0x03|
packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
packet To 0xa3 of type Unknown '0x73' | HEX: 0x10|0x02|0xa3|0x73|0x28|0x10|0x03|
packet To 0x00 of type iAqualnk sendCmd | HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x23|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xff|0x10|0x03|
packet To 0x33 of type iAq Poll | HEX: 0x10|0x02|0x33|0x30|0x75|0x10|0x03|
packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
packet To 0x33 of type iAq 1Tch status | HEX: 0x10|0x02|0x33|0x71|0x07|0x01|0x02|0x03|0x04|0x05|0x12|0x20|0x00|0x07|0x41|0x6c|0x6c|0x20|0x4f|0x46|0x46|0x00|0x08|0x53|0x70|0x61|0x20|0x4d|0x6f|0x64|0x65|0x00|0x0a|0x43|0x6c|0x65|0x61|0x6e|0x20|0x4d|0x6f|0x64|0x65|0x00|0x08|0x42|0x75|0x62|0x62|0x6c|0x65|0x72|0x73|0x00|0x0a|0x57|0x61|0x74|0x65|0x72|0x66|0x61|0x6c|0x6c|0x31|0x04|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x23|0x00|0x00|0x18|0x00|0x00|0x01|0x00|0xd3|0x10|0x03|
All OFF = Off | index 0 type=(01 0x01) status=0x00 start=12 length=7
Spa Mode = Off | index 1 type=(02 0x02) status=0x00 start=21 length=8
Clean Mode = Off | index 2 type=(03 0x03) status=0x00 start=31 length=10
Bubblers = Off | index 3 type=(04 0x04) status=0x00 start=43 length=8
Waterfall1 = Off | index 4 type=(05 0x05) status=0x00 start=53 length=10
*** SWG is in the next bytes from iAq 1Tch status. But can't tell how to pull them since RPM is also here as well. ****
*/ */

View File

@ -252,12 +252,13 @@ char *get_aux_information(aqkey *button, struct aqualinkdata *aqdata, char *buff
//printf("Button %s is VSP\n", button->name); //printf("Button %s is VSP\n", button->name);
for (i=0; i < aqdata->num_pumps; i++) { for (i=0; i < aqdata->num_pumps; i++) {
if (button == aqdata->pumps[i].button) { if (button == aqdata->pumps[i].button) {
length += sprintf(buffer, ",\"type_ext\":\"switch_vsp\",\"Pump_RPM\":\"%d\",\"Pump_GPM\":\"%d\",\"Pump_Watts\":\"%d\",\"Pump_Type\":\"%s\",\"Pump_Status\":\"%d\"", length += sprintf(buffer, ",\"type_ext\":\"switch_vsp\",\"Pump_RPM\":\"%d\",\"Pump_GPM\":\"%d\",\"Pump_Watts\":\"%d\",\"Pump_Type\":\"%s\",\"Pump_Status\":\"%d\",\"Pump_Speed\":\"%d\"",
aqdata->pumps[i].rpm, aqdata->pumps[i].rpm,
aqdata->pumps[i].gpm, aqdata->pumps[i].gpm,
aqdata->pumps[i].watts, aqdata->pumps[i].watts,
(aqdata->pumps[i].pumpType==VFPUMP?"vfPump":(aqdata->pumps[i].pumpType==VSPUMP?"vsPump":"ePump")), (aqdata->pumps[i].pumpType==VFPUMP?"vfPump":(aqdata->pumps[i].pumpType==VSPUMP?"vsPump":"ePump")),
getPumpStatus(i, aqdata)); getPumpStatus(i, aqdata),
getPumpSpeedAsPercent(&aqdata->pumps[i]));
return buffer; return buffer;
} }
@ -268,7 +269,17 @@ char *get_aux_information(aqkey *button, struct aqualinkdata *aqdata, char *buff
//printf("Button %s is ProgramableLight\n", button->name); //printf("Button %s is ProgramableLight\n", button->name);
for (i=0; i < aqdata->num_lights; i++) { for (i=0; i < aqdata->num_lights; i++) {
if (button == aqdata->lights[i].button) { if (button == aqdata->lights[i].button) {
length += sprintf(buffer, ",\"type_ext\": \"switch_program\", \"Light_Type\":\"%d\"", aqdata->lights[i].lightType); if (aqdata->lights[i].lightType == LC_DIMMER2) {
length += sprintf(buffer, ",\"type_ext\": \"light_dimmer\", \"Light_Type\":\"%d\", \"Light_Program\":\"%d\", \"Program_Name\":\"%d%%\" ",
aqdata->lights[i].lightType,
aqdata->lights[i].currentValue,
aqdata->lights[i].currentValue);
} else {
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));
}
return buffer; return buffer;
} }
} }
@ -294,6 +305,7 @@ int build_device_JSON(struct aqualinkdata *aqdata, char* buffer, int size, bool
bool homekit_f = (homekit && ( aqdata->temp_units==FAHRENHEIT || aqdata->temp_units == UNKNOWN) ); bool homekit_f = (homekit && ( aqdata->temp_units==FAHRENHEIT || aqdata->temp_units == UNKNOWN) );
length += sprintf(buffer+length, "{\"type\": \"devices\""); length += sprintf(buffer+length, "{\"type\": \"devices\"");
length += sprintf(buffer+length, ",\"aqualinkd_version\":\"%s\"",AQUALINKD_VERSION);//"09/01/16 THU",
length += sprintf(buffer+length, ",\"date\":\"%s\"",aqdata->date );//"09/01/16 THU", length += sprintf(buffer+length, ",\"date\":\"%s\"",aqdata->date );//"09/01/16 THU",
length += sprintf(buffer+length, ",\"time\":\"%s\"",aqdata->time );//"1:16 PM", length += sprintf(buffer+length, ",\"time\":\"%s\"",aqdata->time );//"1:16 PM",
if ( aqdata->temp_units == FAHRENHEIT ) if ( aqdata->temp_units == FAHRENHEIT )
@ -718,7 +730,11 @@ printf("Pump Type %d\n",aqdata->pumps[i].pumpType);
length += sprintf(buffer+length, ",\"light_program\":{" ); length += sprintf(buffer+length, ",\"light_program\":{" );
for (i=0; i < aqdata->num_lights; i++) for (i=0; i < aqdata->num_lights; i++)
{ {
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) );
}
} }
if (buffer[length-1] == ',') if (buffer[length-1] == ',')
length--; length--;

View File

@ -956,7 +956,21 @@ 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); 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); 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, ALLBUTTON)); if (_aqualink_data->lights[i].lightType == LC_DIMMER2) {
char message[30];
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));
}
/*
if (_aqualink_data->lights[i].lightType == LC_DIMMER) {
sprintf(topic, "%s%s", _aqualink_data->lights[i].button->name, LIGHT_DIMMER_VALUE_TOPIC);
send_mqtt_int_msg(nc, topic, _aqualink_data->lights[i].currentValue * 25);
} else*/ if (_aqualink_data->lights[i].lightType == LC_DIMMER2) {
sprintf(topic, "%s%s", _aqualink_data->lights[i].button->name, LIGHT_DIMMER_VALUE_TOPIC);
send_mqtt_int_msg(nc, topic, _aqualink_data->lights[i].currentValue);
}
} }
} }
} }
@ -1272,6 +1286,22 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
LOG(NET_LOG,LOG_WARNING, "%s: Didn't find device that matched URI '%.*s'\n",actionName[from], uri_length, URI); LOG(NET_LOG,LOG_WARNING, "%s: Didn't find device that matched URI '%.*s'\n",actionName[from], uri_length, URI);
rtn = uBad; rtn = uBad;
} }
} else if ((ri3 != NULL && (strncasecmp(ri2, "brightness", 10) == 0) && (strncasecmp(ri3, "set", 3) == 0))) {
found = false;
for (i=0; i < _aqualink_data->total_buttons; i++) {
if (strncmp(ri1, _aqualink_data->aqbuttons[i].name, strlen(_aqualink_data->aqbuttons[i].name)) == 0 ||
strncmp(ri1, _aqualink_data->aqbuttons[i].label, strlen(_aqualink_data->aqbuttons[i].label)) == 0)
{
found = true;
panel_device_request(_aqualink_data, LIGHT_BRIGHTNESS, i, value, from);
break;
}
}
if(!found) {
*rtnmsg = NO_PLIGHT_DEVICE;
LOG(NET_LOG,LOG_WARNING, "%s: Didn't find device that matched URI '%.*s'\n",actionName[from], uri_length, URI);
rtn = uBad;
}
// Action a pump RPM/GPM message // Action a pump RPM/GPM message
} else if ((ri3 != NULL && ((strncasecmp(ri2, "RPM", 3) == 0) || (strncasecmp(ri2, "GPM", 3) == 0) || (strncasecmp(ri2, "Speed", 5) == 0) || (strncasecmp(ri2, "VSP", 3) == 0)) && (strncasecmp(ri3, "set", 3) == 0))) { } else if ((ri3 != NULL && ((strncasecmp(ri2, "RPM", 3) == 0) || (strncasecmp(ri2, "GPM", 3) == 0) || (strncasecmp(ri2, "Speed", 5) == 0) || (strncasecmp(ri2, "VSP", 3) == 0)) && (strncasecmp(ri3, "set", 3) == 0))) {
found = false; found = false;

View File

@ -138,7 +138,8 @@ void set_aqualink_rssadapter_aux_extended_state(const aqkey *button, const unsig
LOG(RSSA_LOG,LOG_DEBUG, "Sending 0x%02hhx to %s\n",state, button->label); LOG(RSSA_LOG,LOG_DEBUG, "Sending 0x%02hhx to %s\n",state, button->label);
rssadapter_device_state(button->rssd_code, state); rssadapter_device_state(button->rssd_code, state); // Set state
rssadapter_device_state(button->rssd_code, 0x00); // 0x00 meand Get curent state (for color lights the return state is 0)
} }
void set_aqualink_rssadapter_aux_state(const aqkey *button, bool turnOn) void set_aqualink_rssadapter_aux_state(const aqkey *button, bool turnOn)
@ -146,7 +147,12 @@ void set_aqualink_rssadapter_aux_state(const aqkey *button, bool turnOn)
LOG(RSSA_LOG,LOG_DEBUG, "Turning button %s %s\n",button->label,(turnOn?"On":"Off")); LOG(RSSA_LOG,LOG_DEBUG, "Turning button %s %s\n",button->label,(turnOn?"On":"Off"));
rssadapter_device_state( button->rssd_code, (turnOn?RS_SA_ON:RS_SA_OFF) ); rssadapter_device_state( button->rssd_code, (turnOn?RS_SA_ON:RS_SA_OFF) );
// NOTE. If we turn off AUX1 and get this return HEX: 0x10|0x02|0x48|0x13|0x02|0x00|0x0e|0x15|0x92|0x10|0x03|
// The 0x0e means some from of oiption is set (ie cleaner). Maybe try to turn cleaner off instead 0x15 is aux1 1x10 is cleaner.
} }
/* /*
void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn) void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn)
{ {
@ -352,19 +358,19 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
aq_data->lights[i].button->rssd_code == packet[7] ) { aq_data->lights[i].button->rssd_code == packet[7] ) {
// CHANGE TO DEBUG BEFORE RELEASE // CHANGE TO DEBUG BEFORE RELEASE
if (aq_data->lights[i].lightType != LC_DIMMER) { if (aq_data->lights[i].lightType == LC_DIMMER || aq_data->lights[i].lightType == LC_DIMMER2) {
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", LOG(RSSA_LOG,LOG_DEBUG,"DimmerLight '%s' is %s 0x%02hhx value '%d'%%\n",
aq_data->lights[i].button->label, aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON", packet[6]==0x00?"OFF":"ON",
packet[6], packet[6],
packet[6]==0x00?0:(packet[6] - RSSD_DIMMER_LIGHT_OFFSET)); packet[6]==0x00?0:(packet[6] - RSSD_DIMMER_LIGHT_OFFSET));
} }else{
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) );
}
aq_data->lights[i].RSSDstate = (packet[6]==0x00?OFF:ON); aq_data->lights[i].RSSDstate = (packet[6]==0x00?OFF:ON);
#ifdef CLIGHT_PANEL_FIX #ifdef CLIGHT_PANEL_FIX
@ -377,13 +383,24 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
aq_data->lights[i].button->led->state==OFF?"OFF":"ON"); aq_data->lights[i].button->led->state==OFF?"OFF":"ON");
} }
aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate; aq_data->lights[i].button->led->state = aq_data->lights[i].RSSDstate;
#endif #endif
// Set the color index. (packet[6] - RSSD_COLOR_LIGHT_OFFSET)-1 switch(aq_data->lights[i].lightType) {
if (aq_data->lights[i].lightType != LC_DIMMER) { case LC_DIMMER:
set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25);
break;
case LC_DIMMER2:
set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET));
break;
default:
set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET));
break;
}
/*
if (aq_data->lights[i].lightType != LC_DIMMER ) {
set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET)); set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_COLOR_LIGHT_OFFSET));
} else if (aq_data->lights[i].lightType == LC_DIMMER) { } else if (aq_data->lights[i].lightType == LC_DIMMER) {
set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25); set_currentlight_value(&aq_data->lights[i], (packet[6] - RSSD_DIMMER_LIGHT_OFFSET) / 25);
} }*/
} }
} }

View File

@ -2,4 +2,6 @@
#define AQUALINKD_NAME "Aqualink Daemon" #define AQUALINKD_NAME "Aqualink Daemon"
#define AQUALINKD_SHORT_NAME "AqualinkD" #define AQUALINKD_SHORT_NAME "AqualinkD"
#define AQUALINKD_VERSION "2.4.1 (Dev 0.2)"
// Use Magor . Minor . Patch
#define AQUALINKD_VERSION "2.5.0 (Dev 0.1)"

View File

@ -640,6 +640,7 @@
document.getElementById('vspswitch_options').classList.remove("hide"); document.getElementById('vspswitch_options').classList.remove("hide");
document.getElementById('timer_options').classList.remove("hide"); document.getElementById('timer_options').classList.remove("hide");
document.getElementById('scheduler_options').classList.remove("hide"); document.getElementById('scheduler_options').classList.remove("hide");
document.getElementById('dimmerlight_options').classList.remove("hide");
//document.getElementById('simulator_iframe').classList.remove("hide"); //document.getElementById('simulator_iframe').classList.remove("hide");
setColors(); setColors();
load_background(); load_background();
@ -915,7 +916,8 @@
subdiv.setAttribute('id', id + '_status'); subdiv.setAttribute('id', id + '_status');
subdiv.textContent = formatSatus(status); subdiv.textContent = formatSatus(status);
div.appendChild(subdiv); div.appendChild(subdiv);
if (type == "switch" && (subtype != "switch_program" && subtype != "switch_vsp" && subtype != "switch_timer") ) { if (type == "switch" && (subtype != "switch_program" && subtype != "switch_vsp" &&
subtype != "switch_timer" && subtype != "light_dimmer") ) {
//if (type == "switch" && subtype != "switch_program" ) { //if (type == "switch" && subtype != "switch_program" ) {
div.setAttribute('onclick', "switchTileState('" + id + "')"); div.setAttribute('onclick', "switchTileState('" + id + "')");
//console.log("add onclick switchtilestate to "+id); //console.log("add onclick switchtilestate to "+id);
@ -957,6 +959,7 @@
send_setpoint(id); send_setpoint(id);
} }
/* /*
function setTileValue(id, value) { function setTileValue(id, value) {
var ext = ''; var ext = '';
@ -1028,7 +1031,8 @@
function setTileOnText(id, text) { function setTileOnText(id, text) {
try { try {
if (document.getElementById(id).getAttribute('status') == 'on') { var tile = document.getElementById(id);
if (tile.getAttribute('status') == 'on' || tile.getAttribute('status') == 'enabled') {
document.getElementById(id + '_status').innerHTML = text; document.getElementById(id + '_status').innerHTML = text;
} else { } else {
//console.log("Tile "+id+" status is '"+document.getElementById(id).getAttribute('status')+"' not setting text to '"+text+"'"); //console.log("Tile "+id+" status is '"+document.getElementById(id).getAttribute('status')+"' not setting text to '"+text+"'");
@ -1227,7 +1231,7 @@
add_tile(object.id, object.name, object.state, 'switch', ext_type, 'hk/' + img + '-off.png', 'hk/' + img + '-on.png'); add_tile(object.id, object.name, object.state, 'switch', ext_type, 'hk/' + img + '-off.png', 'hk/' + img + '-on.png');
setTileOn(object.id, object.status, null); setTileOn(object.id, object.status, null);
if (typeof object.type_ext !== 'undefined' && object.type_ext == 'switch_program') { if (typeof object.type_ext !== 'undefined' && (object.type_ext == 'switch_program' || object.type_ext == 'light_dimmer')) {
if (typeof object.Light_Type !== 'undefined') { if (typeof object.Light_Type !== 'undefined') {
document.getElementById(object.id).setAttribute('lighttype', object.Light_Type); document.getElementById(object.id).setAttribute('lighttype', object.Light_Type);
} }
@ -1276,6 +1280,7 @@
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_program') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_program') {
active_option = document.getElementById('pswitch_options'); active_option = document.getElementById('pswitch_options');
@ -1284,6 +1289,16 @@
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'light_dimmer') {
active_option = document.getElementById('dimmerlight_options');
document.getElementById('thermostat_options').style.display = 'none';
document.getElementById('swg_options').style.display = 'none';
document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg') {
active_option = document.getElementById('swg_options'); active_option = document.getElementById('swg_options');
@ -1292,6 +1307,7 @@
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_freeze') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_freeze') {
active_option = document.getElementById('swg_options'); active_option = document.getElementById('swg_options');
@ -1300,6 +1316,7 @@
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_vsp') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_vsp') {
active_option = document.getElementById('vspswitch_options'); active_option = document.getElementById('vspswitch_options');
@ -1308,6 +1325,7 @@
document.getElementById('swg_options').style.display = 'none'; document.getElementById('swg_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_timer') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_timer') {
active_option = document.getElementById('timer_options'); active_option = document.getElementById('timer_options');
@ -1316,6 +1334,7 @@
document.getElementById('swg_options').style.display = 'none'; document.getElementById('swg_options').style.display = 'none';
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'scheduler') { } else if (id != null && document.getElementById(id).getAttribute('type') == 'scheduler') {
active_option = document.getElementById('scheduler_options'); active_option = document.getElementById('scheduler_options');
@ -1324,6 +1343,7 @@
document.getElementById('swg_options').style.display = 'none'; document.getElementById('swg_options').style.display = 'none';
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
} /*else if (id != null && document.getElementById(id).getAttribute('type') == 'simulator') { } /*else if (id != null && document.getElementById(id).getAttribute('type') == 'simulator') {
active_option = document.getElementById('simulator_iframe'); active_option = document.getElementById('simulator_iframe');
@ -1361,6 +1381,8 @@
document.getElementById("timer_options").click(); document.getElementById("timer_options").click();
else if (document.getElementById('scheduler_options').style.display == 'flex') else if (document.getElementById('scheduler_options').style.display == 'flex')
document.getElementById("scheduler_options").click(); document.getElementById("scheduler_options").click();
else if (document.getElementById('dimmerlight_options').style.display == 'flex')
document.getElementById("dimmerlight_options").click();
} }
document.getElementById('thermostat_options').style.display = 'none'; document.getElementById('thermostat_options').style.display = 'none';
document.getElementById('swg_options').style.display = 'none'; document.getElementById('swg_options').style.display = 'none';
@ -1368,6 +1390,7 @@
document.getElementById('vspswitch_options').style.display = 'none'; document.getElementById('vspswitch_options').style.display = 'none';
document.getElementById('timer_options').style.display = 'none'; document.getElementById('timer_options').style.display = 'none';
document.getElementById('scheduler_options').style.display = 'none'; document.getElementById('scheduler_options').style.display = 'none';
document.getElementById('dimmerlight_options').style.display = 'none';
//document.getElementById('simulator_iframe').style.display = 'none'; //document.getElementById('simulator_iframe').style.display = 'none';
document.getElementById('wrapper').classList.remove("opaque"); document.getElementById('wrapper').classList.remove("opaque");
return; return;
@ -1388,6 +1411,7 @@
var tm_ext; var tm_ext;
var oswitch; var oswitch;
var vsp_slider_changed = false; var vsp_slider_changed = false;
var dimmer_slider_changed = false;
if (type == 'setpoint_swg') { if (type == 'setpoint_swg') {
slider = document.getElementById("swg_option_slider_range"); slider = document.getElementById("swg_option_slider_range");
slider_output = document.getElementById("swg_option_slider_text_value"); slider_output = document.getElementById("swg_option_slider_text_value");
@ -1424,6 +1448,14 @@
close_button = document.getElementById("scheduler_options_close"); close_button = document.getElementById("scheduler_options_close");
//} else if (type == 'simulator') { //} else if (type == 'simulator') {
// close_button = document.getElementById("simulator_iframe_close"); // close_button = document.getElementById("simulator_iframe_close");
} else if (type == 'light_dimmer') {
slider = document.getElementById("dimmeroption_slider_range");
slider_output = document.getElementById("dimmeroption_slider_text_value");
tm_slider = document.getElementById("dimmer_timer_slider_range");
tm_slider_output = document.getElementById("dimmer_timer_slider_text_value");
title = document.getElementById("dimmerswitch_option_title");
close_button = document.getElementById("dimmerswitch_option_close");
ext = "%";
} else { } else {
slider = document.getElementById("option_slider_range"); slider = document.getElementById("option_slider_range");
slider_output = document.getElementById("option_slider_text_value"); slider_output = document.getElementById("option_slider_text_value");
@ -1472,6 +1504,11 @@
slider.step = 5; slider.step = 5;
ext = ' RPM'; ext = ' RPM';
} }
} else if (type == 'light_dimmer') {
slider.min = 0;
slider.max = 100;
slider.step = 1;
ext = ' %';
} }
if (type == 'scheduler') { if (type == 'scheduler') {
@ -1479,6 +1516,7 @@
} else if (type == 'simulator') { } else if (type == 'simulator') {
// title.innerHTML = "Simulator"; // title.innerHTML = "Simulator";
} else { } else {
//console.log("Set "+id+" to "+document.getElementById(id + '_name').innerHTML);
title.innerHTML = document.getElementById(id + '_name').innerHTML; title.innerHTML = document.getElementById(id + '_name').innerHTML;
} }
@ -1532,6 +1570,24 @@
oswitch.onclick = function() { oswitch.onclick = function() {
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off"); oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
} }
} else if (type == 'light_dimmer') {
slider.value = sp_value;
oswitch = document.getElementById("dimmeroption_switch");
oswitch.checked = tile_state;
var oswitch_output = document.getElementById("dimmeroption_switch_text_value");
slider_output.innerHTML = slider.value + ext;
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
slider.oninput = function() {
dimmer_slider_changed = true;
slider_output.innerHTML = this.value + ext;
if (this.value <= 0 && oswitch.checked == true) {
oswitch.checked = false;
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
} else if (oswitch.checked != true) {
oswitch.checked = true;
oswitch_output.innerHTML = ((oswitch.checked) ? "On" : "Off");
}
}
} else if (type == 'switch_timer') { } else if (type == 'switch_timer') {
oswitch = document.getElementById("timer_switch"); oswitch = document.getElementById("timer_switch");
oswitch.checked = tile_state; oswitch.checked = tile_state;
@ -1630,6 +1686,12 @@
// if (state == (tile.getAttribute('status') == 'off')) // Only bother with this if we didn;t set the light mode. // if (state == (tile.getAttribute('status') == 'off')) // Only bother with this if we didn;t set the light mode.
setTileState(id, state); setTileState(id, state);
} }
} else if (type == 'light_dimmer') {
var value = slider.value;
if (state == (tile.getAttribute('status') == 'off'))
setTileState(id, state);
if (sp_value != slider.value && dimmer_slider_changed == true)
setThermostatSetpoint(id, slider.value)
} else if (type == 'setpoint_swg') { } else if (type == 'setpoint_swg') {
//console.log ("Boost attribute = "+tile.getAttribute('boost')); //console.log ("Boost attribute = "+tile.getAttribute('boost'));
//console.log ("state = "+state); //console.log ("state = "+state);
@ -2162,26 +2224,32 @@
} }
for (var obj in data.timers) { for (var obj in data.timers) {
setTileOnText(obj.toString(),"On (timer)"); setTileOnText(obj.toString(),"On (timer)");
//console.log("TIMER "+obj.toString());
} }
for (var obj in data.timer_durations) { for (var obj in data.timer_durations) {
setTileOnText(obj.toString(),"Timer "+toHoursAndMinutes(data.timer_durations[obj])); setTileOnText(obj.toString(),"Timer "+toHoursAndMinutes(data.timer_durations[obj]));
//console.log("TIMER "+obj.toString()+" duration "+data.timer_durations[obj]);
} }
for (var obj in data.light_program) { for (var obj in data.light_program) {
if (data.light_program[obj] != "") { if (data.light_program[obj] != "") {
var light_mode = data.light_program[obj]; var light_mode = data.light_program[obj];
// If aqualinkd programmed light, need to convert int to text index, if not value is text
// If aqualinkd probrammed light, need to get convert int to text index, if not value is text
try { try {
var light_type = document.getElementById(obj.toString()).getAttribute('lighttype') var light_type = document.getElementById(obj.toString()).getAttribute('lighttype');
if (light_type == 0) { if (light_type == 0) {
var light_mode = _light_program[light_type][parseInt(data.light_program[obj])-1]; var light_mode = _light_program[light_type][parseInt(data.light_program[obj])-1];
if (light_mode.endsWith(" - Show")) if (light_mode.endsWith(" - Show"))
light_mode = light_mode.slice(0, -7); light_mode = light_mode.slice(0, -7);
//console.log("light program -- "+light_mode);
} else if (light_type == 10 || light_type == 11) {
// Fo Dimmer Lights.
document.getElementById(obj.toString()).setAttribute('setpoint', parseInt(light_mode));
} }
} catch (e) {} } catch (e) {}
setTileOnText(obj.toString(),light_mode); setTileOnText(obj.toString(),light_mode);
// Below is only needed for full dimmer
} }
} }
@ -2430,6 +2498,8 @@
message.uri = id+"/percent/set"; message.uri = id+"/percent/set";
else if (type == "switch_vsp") else if (type == "switch_vsp")
message.uri = id+"/RPM/set"; message.uri = id+"/RPM/set";
else if (type == "light_dimmer")
message.uri = id+"/brightness/set";
else else
message.uri = id+"/setpoint/set"; message.uri = id+"/setpoint/set";
//console.log("Send value back "+temperature.parameter+" "+temperature.value); //console.log("Send value back "+temperature.parameter+" "+temperature.value);
@ -2543,6 +2613,7 @@
</table> </table>
</div> </div>
</div> </div>
<div id='thermostat_options' class='options hide'> <div id='thermostat_options' class='options hide'>
<div id='thermostat_options_pane' class='options_pane' onclick='event.stopPropagation();'> <div id='thermostat_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'> <table border='0' cellpadding='10px'>
@ -2592,6 +2663,7 @@
</table> </table>
</div> </div>
</div> </div>
<div id='swg_options' class='options hide'> <div id='swg_options' class='options hide'>
<div id='swg_options_pane' class='options_pane' onclick='event.stopPropagation();'> <div id='swg_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'> <table border='0' cellpadding='10px'>
@ -2628,6 +2700,7 @@
</table> </table>
</div> </div>
</div> </div>
<div id='pswitch_options' class='options hide'> <div id='pswitch_options' class='options hide'>
<div id='pswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'> <div id='pswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table id='pswitch_table' border='0' cellpadding='10px' width="100%"> <table id='pswitch_table' border='0' cellpadding='10px' width="100%">
@ -2674,6 +2747,7 @@
</table> </table>
</div> </div>
</div> </div>
<div id='vspswitch_options' class='options hide'> <div id='vspswitch_options' class='options hide'>
<div id='vspswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'> <div id='vspswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'> <table border='0' cellpadding='10px'>
@ -2723,6 +2797,55 @@
</table> </table>
</div> </div>
</div> </div>
<div id='dimmerlight_options' class='options hide'>
<div id='dimmerlight_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'>
<tr class='options_title'>
<th colspan='2'><span id="dimmerswitch_option_title"></span>
</th>
</tr>
<tr>
<td align='right' width='50%'><span class="option_text" id='dimmeroption_switch_text_value'></span>
</td>
<td align='left' width='50%'>
<label class="option_switch">
<input type="checkbox" id='dimmeroption_switch'>
<span class="option_switch_slide"></span>
</label>
</td>
</tr>
<tr>
<td colspan='2' align='center'><span class="option_text" id="dimmeroption_slider_text_value"></span>
</td>
</tr>
<tr>
<td colspan='2'>
<div class="slidecontainer">
<input type="range" class="option_slider" id='dimmeroption_slider_range'>
</div>
</td>
</tr>
<tr>
<td colspan='2' align='center'><span class="option_text" id="dimmer_timer_slider_text_value"></span>
</td>
</tr>
<tr>
<td colspan='2'>
<div class="slidecontainer">
<input type="range" class="option_slider" id='dimmer_timer_slider_range'>
</div>
</td>
</tr>
<tr>
<td colspan='2' align='center'>
<input type="button" value="close" id='dimmerswitch_option_close' class='options_button'>
</td>
</tr>
</table>
</div>
</div>
<div id='timer_options' class='options hide'> <div id='timer_options' class='options hide'>
<div id='timer_options_pane' class='options_pane' onclick='event.stopPropagation();'> <div id='timer_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'> <table border='0' cellpadding='10px'>