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
-->
# 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.
* 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.
* 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 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.
* Allow VSP to be asigned to virtual button.
* 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
* <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)
# LX = Jandy LX & LT heaters
# 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_ePump = yes
#read_RS485_vsfPump = yes
#read_RS485_JXi = yes
#read_RS485_LX = yes
#read_RS485_Chem = yes
#read_RS485_iAqualink = yes
# Keep the panel time synced with systemtime. Make sure to set systemtime / NTP correctly.
keep_paneltime_synced = yes
@ -146,7 +148,7 @@ report_zero_spa_temp = yes
# dead.
# ~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.
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.
#ftdi_low_latency = no
@ -264,8 +266,8 @@ use_panel_aux_labels=no
# button_01_pumpIndex=1
# If you have assigned this pump an index number in your Aqualink control panel, (Between 1 & 4), put it here for VSP, RPM, Primp information to be captured.
#
# button_xx_lightMode = (0=Aqualink program, 1=Jandy, 2=Jandy LED, 3=SAm/SAL, 4=Color Logic, 5=Intellibrite, 6=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.
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 LIGHT_PROGRAM_TOPIC "/program"
#define LIGHT_DIMMER_VALUE_TOPIC "/brightness"
/*
#define AIR_TEMPERATURE "Air"
#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 programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button);
char *name2label(char *str)
{
int len = strlen(str);
@ -687,6 +688,9 @@ const char* getRequestName(request_source source)
case NET_TIMER:
return "Timer";
break;
case UNACTION_TIMER:
return "UnactionTimer";
break;
}
static char buf[25];
@ -740,6 +744,9 @@ const char* getActionName(action_type type)
case DATE_TIME:
return "Date Time";
break;
case LIGHT_BRIGHTNESS:
return "Light Brightness";
break;
}
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
// since allbutton (default) is stateless, and rssaadapter is statefull, use rssaadapter for any domoricz requests
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) {
// If off and program light, use the RS serial adapter since that is overiding the state now.
set_aqualink_rssadapter_aux_state(button, isON);
} else {
//set_iaqualink_aux_state(button, isON);
//set_aqualink_rssadapter_aux_state(button, isON);
aq_send_allb_cmd(button->code);
}
@ -882,24 +893,62 @@ bool programDeviceValue(struct aqualinkdata *aqdata, action_type type, int value
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, int value, int button)
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button)
{
int i;
clight_detail *light = NULL;
#ifdef AQ_PDA
if (isPDA_PANEL && !isPDA_IAQT) {
LOG(PANL_LOG,LOG_ERR, "Light mode control not supported in PDA mode\n");
return;
}
#endif
/*
int i;
clight_detail *light = NULL;
for (i=0; i < aqdata->num_lights; i++) {
if (&aqdata->aqbuttons[button] == aqdata->lights[i].button) {
// Found the programmable light
light = &aqdata->lights[i];
break;
}
}
}*/
clight_detail *light = getProgramableLight(aqdata, button);
if (light == NULL) {
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_mode );
aq_programmer(AQ_SET_LIGHTPROGRAM_MODE, buf, aqdata);
} else if (isRSSA_ENABLED && light->lightType != LC_DIMMER) {
unsigned char rssd_value = value;
set_aqualink_rssadapter_aux_extended_state(light->button, rssd_value);
} else if (isRSSA_ENABLED && light->lightType == LC_DIMMER2) {
// Dimmer needs to be turned on before you set dimmer level
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) {
// Dimmer needs to be turned on first
set_aqualink_rssadapter_aux_extended_state(light->button, RS_SA_ON);
// Value 1 = 25, 1 = 50, 3 = 75, 4 = 100 (need to convert value into binary)
if (light->button->led->state != ON) {
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 is not on of those vales, then ignore
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, deviceIndex, value);
break;
case LIGHT_BRIGHTNESS:
programDeviceLightBrightness(aqdata, value, deviceIndex, (source==NET_MQTT?true:false));
break;
case LIGHT_MODE:
if (value <= 0) {
// 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
void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button)
{
/*
int i;
clight_detail *light = NULL;
@ -1023,6 +1081,8 @@ void updateButtonLightProgram(struct aqualinkdata *aqdata, int value, int button
break;
}
}
*/
clight_detail *light = getProgramableLight(aqdata, button);
if (light == NULL) {
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;
}
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

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);
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();
#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 )
{
struct timerthread *tmthread;
tmthread = (struct timerthread *) ptr;
int retval = 0;
int cnt=0;
LOG(TIMR_LOG, LOG_NOTICE, "Start timer for '%s'\n",tmthread->button->name);
// Add mask so we know timer is active
tmthread->button->special_mask |= TIMER_ACTIVE;
/*
#ifndef PRESTATE_ONOFF
delay(WAIT_TIME_BEFORE_ON_CHECK);
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);
}
}
*/
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);
@ -163,12 +179,24 @@ void *timer_worker( void *ptr )
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);
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);
}
if (tmthread->button->led->state != OFF) {
// Need to wait
}
// remove mask so we know timer is dead
tmthread->button->special_mask &= ~ TIMER_ACTIVE;

View File

@ -94,6 +94,7 @@ typedef struct aqualinkkey
unsigned char rssd_code;
int dz_idx;
uint8_t special_mask;
void *special_mask_ptr;
} aqkey;
// special_mask for above aqualinkkey structure.
@ -128,6 +129,7 @@ typedef enum action_type {
ON_OFF,
TIMER,
LIGHT_MODE,
LIGHT_BRIGHTNESS,
DATE_TIME
} action_type;
@ -216,7 +218,8 @@ typedef enum clight_type {
LC_SPARE_1,
LC_SPARE_2,
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
} clight_type;
@ -225,7 +228,8 @@ typedef enum {
NET_API,
NET_WS,
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;
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);
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
{
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) {
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
} else {
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);
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
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));
#endif
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)
"75%", // 0xcb (simulator) = 203 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)
{
// 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
if (index < 0 || index > LIGHT_COLOR_OPTIONS)
light->currentValue = 0;
else if (index > 0 && index < LIGHT_COLOR_OPTIONS)
light->currentValue = index;
if (index < 0 || index > LIGHT_COLOR_OPTIONS)
light->currentValue = 0;
else if (index > 0 && index < LIGHT_COLOR_OPTIONS)
light->currentValue = index;
}
}
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_DIMMER_LIGHT_OFFSET 128
//#define DIMMER_LIGHT_TYPE_INDEX 10
/*
// color light modes (Aqualink program, Jandy, Jandy LED, SAm/SAL, Color Logic, Intellibrite)
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);
} else {
aqdata->lights[aqdata->num_lights].button = &aqdata->aqbuttons[num];
aqdata->lights[aqdata->num_lights].lightType = type;
aqdata->num_lights++;
aqdata->lights[aqdata->num_lights].lightType = type;
aqdata->aqbuttons[num].special_mask |= PROGRAM_LIGHT;
aqdata->aqbuttons[num].special_mask_ptr = &aqdata->lights[aqdata->num_lights];
aqdata->num_lights++;
}
} else {
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) {
//printf ("Creating pump %d\n",button);
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].pumpType = PT_UNKNOWN;
aqdata->pumps[aqdata->num_pumps].rpm = TEMP_UNKNOWN;

View File

@ -135,6 +135,26 @@ const char *HASSIO_VSP_DISCOVER = "{"
"\"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
// 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_.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);
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 {
// 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}" ,

View File

@ -39,6 +39,11 @@ unsigned char _std_cmd[2];
int _iaqua_q_length = 0;
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) {
if (_iaqua_q_length >= IAQUA_QLEN ) {
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;
_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]);
return true;
@ -86,6 +91,8 @@ int get_iaqualink_cmd(unsigned char source_message_type, unsigned char **dest_me
_aqua_last_cmdfrom_queue = true;
} else {
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]){
case 0x70:
if (last70checksum != packet[length-3] && last70checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x70 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x70 *******\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
}
last70checksum = packet[length-3];
break;
case 0x71:
if (last71checksum != packet[length-3] && last71checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x71 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x71 *******\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
}
last71checksum = packet[length-3];
break;
case 0x72:
if (last72checksum != packet[length-3] && last72checksum != 0x00) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x72 *******\n");
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"******* CHECKSUM CHANGED for 0x72 *******\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
}
last72checksum = packet[length-3];
break;
@ -214,6 +221,7 @@ void lastchecksum(unsigned char *packet, int length){
All taken from panel Yg, but only heater setpoints seem to work.
Only setpoints seem to work,
Can't get to work on T2 panel
RPM to 2750
Bit 6 = 0x5e
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
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%
Byte 6 = 0x19
Byte 7 = 50%
@ -233,11 +243,13 @@ 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|
Works on T2
Spa Setpoint 102
Byte 6 = 0x06
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|
Works on T2
Pool Setpoint 72
Byte 6 = 0x05
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) {
@ -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);
}
// reset
_fullcmd[4] = 0x00;
}
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(_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)
{
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true);
logPacket(IAQL_LOG, LOG_INFO, packet, length, true);
int startIndex = 4 + 1;
int numberBytes = packet[4];
int offsetIndex = startIndex + numberBytes;
@ -314,12 +344,15 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
if (byteType == 0) {
label = "Filter Pump ";
if (isPDA_PANEL) { iAqSetButtonState(aq_data, 0, byte); }
} 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) {
label = "Spa ";
} else if (byteType == 3) {
label = "Spa Heater "; // 0x01=on&heating, 0x03=ena
if (isPDA_PANEL) { iAqSetButtonState(aq_data, aq_data->spa_heater_index , byte); }
} else if (byteType == 6) {
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)
@ -338,9 +371,9 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
else
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[1].led->state == OFF ? "Off" : "On ",
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)
{
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true);
logPacket(IAQL_LOG, LOG_INFO, packet, length, true);
int numLabels = packet[4];
int start = numLabels + 4 + 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;
}
@ -367,14 +401,14 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
int status = packet[start];
int length = packet[start + 1];
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.
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) {
//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
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->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)
{
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
// Since this is so similar to above CMD_IAQ_1TOUCH_STATUS, we should look at using same logic for both.
int start = packet[4];
@ -397,17 +431,17 @@ bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqu
int labellen = packet[status + 4];
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) {
for (int bi=2 ; bi < aq_data->total_buttons ; bi++) {
if (rsm_strcmp((char *)&packet[labelstart], aq_data->aqbuttons[bi].label) == 0) {
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->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 unsigned char ID = 0;
//static cur_swg = 0;
static unsigned char sendid = 0x00;
if (packet[PKT_CMD] == 0x53)
{
cnt++;
if (cnt == 20) {
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_getTouchstatus, 2);
push_iaqualink_cmd(cmd_getAuxstatus, 2);
/*
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"********** Send %d 0x%02hhx ************\n",ID,ID);
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"********** Send %d 0x%02hhx ************\n",ID,ID);
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
_fullcmd[4] = ID++;
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);
/*
if (aq_data->swg_percent != cur_swg && cur_swg != 0) {
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_NOTICE,"********** SWG Changed to %d ************\n",aq_data->swg_percent);
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
LOG(IAQL_LOG, LOG_INFO,"********** SWG Changed to %d ************\n",aq_data->swg_percent);
LOG(IAQL_LOG, LOG_INFO,"*****************************************\n");
exit(0);
}
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++;*/
}
@ -524,7 +566,7 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
*/
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);
}
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)
{
//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);
}
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);
}
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);
}
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);
}
else
@ -576,7 +618,7 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
//pb3[4] = 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_jandy_command(rs_fd, swg, 19);
}
@ -588,199 +630,3 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
}
#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.
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);
for (i=0; i < aqdata->num_pumps; i++) {
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].gpm,
aqdata->pumps[i].watts,
(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;
}
@ -268,7 +269,17 @@ char *get_aux_information(aqkey *button, struct aqualinkdata *aqdata, char *buff
//printf("Button %s is ProgramableLight\n", button->name);
for (i=0; i < aqdata->num_lights; i++) {
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;
}
}
@ -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) );
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, ",\"time\":\"%s\"",aqdata->time );//"1:16 PM",
if ( aqdata->temp_units == FAHRENHEIT )
@ -718,7 +730,11 @@ printf("Pump Type %d\n",aqdata->pumps[i].pumpType);
length += sprintf(buffer+length, ",\"light_program\":{" );
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) );
}
}
if (buffer[length-1] == ',')
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);
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);
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
} 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;

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);
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)
@ -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"));
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)
{
@ -352,19 +358,19 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
aq_data->lights[i].button->rssd_code == packet[7] ) {
// CHANGE TO DEBUG BEFORE RELEASE
if (aq_data->lights[i].lightType != LC_DIMMER) {
LOG(RSSA_LOG,LOG_DEBUG,"ColorLight '%s' is %s 0x%02hhx value name '%s'\n",
aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON",
packet[6],
packet[6]==0x00?"--":light_mode_name( aq_data->lights[i].lightType,(packet[6] - RSSD_COLOR_LIGHT_OFFSET), RSSADAPTER) );
} else if (aq_data->lights[i].lightType == LC_DIMMER) {
if (aq_data->lights[i].lightType == LC_DIMMER || aq_data->lights[i].lightType == LC_DIMMER2) {
LOG(RSSA_LOG,LOG_DEBUG,"DimmerLight '%s' is %s 0x%02hhx value '%d'%%\n",
aq_data->lights[i].button->label,
packet[6]==0x00?"OFF":"ON",
packet[6],
packet[6]==0x00?0:(packet[6] - RSSD_DIMMER_LIGHT_OFFSET));
}
}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);
#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 = aq_data->lights[i].RSSDstate;
#endif
// Set the color index. (packet[6] - RSSD_COLOR_LIGHT_OFFSET)-1
if (aq_data->lights[i].lightType != LC_DIMMER) {
#endif
switch(aq_data->lights[i].lightType) {
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));
} else if (aq_data->lights[i].lightType == LC_DIMMER) {
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_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('timer_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");
setColors();
load_background();
@ -915,7 +916,8 @@
subdiv.setAttribute('id', id + '_status');
subdiv.textContent = formatSatus(status);
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" ) {
div.setAttribute('onclick', "switchTileState('" + id + "')");
//console.log("add onclick switchtilestate to "+id);
@ -957,6 +959,7 @@
send_setpoint(id);
}
/*
function setTileValue(id, value) {
var ext = '';
@ -1028,7 +1031,8 @@
function setTileOnText(id, text) {
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;
} else {
//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');
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') {
document.getElementById(object.id).setAttribute('lighttype', object.Light_Type);
}
@ -1276,6 +1280,7 @@
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';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_program') {
active_option = document.getElementById('pswitch_options');
@ -1284,6 +1289,16 @@
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';
} 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';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_swg') {
active_option = document.getElementById('swg_options');
@ -1292,6 +1307,7 @@
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';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'setpoint_freeze') {
active_option = document.getElementById('swg_options');
@ -1300,6 +1316,7 @@
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';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_vsp') {
active_option = document.getElementById('vspswitch_options');
@ -1308,6 +1325,7 @@
document.getElementById('swg_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';
} else if (id != null && document.getElementById(id).getAttribute('type') == 'switch_timer') {
active_option = document.getElementById('timer_options');
@ -1316,6 +1334,7 @@
document.getElementById('swg_options').style.display = 'none';
document.getElementById('vspswitch_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') == 'scheduler') {
active_option = document.getElementById('scheduler_options');
@ -1324,6 +1343,7 @@
document.getElementById('swg_options').style.display = 'none';
document.getElementById('vspswitch_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';
} /*else if (id != null && document.getElementById(id).getAttribute('type') == 'simulator') {
active_option = document.getElementById('simulator_iframe');
@ -1361,6 +1381,8 @@
document.getElementById("timer_options").click();
else if (document.getElementById('scheduler_options').style.display == 'flex')
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('swg_options').style.display = 'none';
@ -1368,6 +1390,7 @@
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('wrapper').classList.remove("opaque");
return;
@ -1388,6 +1411,7 @@
var tm_ext;
var oswitch;
var vsp_slider_changed = false;
var dimmer_slider_changed = false;
if (type == 'setpoint_swg') {
slider = document.getElementById("swg_option_slider_range");
slider_output = document.getElementById("swg_option_slider_text_value");
@ -1424,6 +1448,14 @@
close_button = document.getElementById("scheduler_options_close");
//} else if (type == 'simulator') {
// 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 {
slider = document.getElementById("option_slider_range");
slider_output = document.getElementById("option_slider_text_value");
@ -1472,6 +1504,11 @@
slider.step = 5;
ext = ' RPM';
}
} else if (type == 'light_dimmer') {
slider.min = 0;
slider.max = 100;
slider.step = 1;
ext = ' %';
}
if (type == 'scheduler') {
@ -1479,6 +1516,7 @@
} else if (type == 'simulator') {
// title.innerHTML = "Simulator";
} else {
//console.log("Set "+id+" to "+document.getElementById(id + '_name').innerHTML);
title.innerHTML = document.getElementById(id + '_name').innerHTML;
}
@ -1532,6 +1570,24 @@
oswitch.onclick = function() {
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') {
oswitch = document.getElementById("timer_switch");
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.
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') {
//console.log ("Boost attribute = "+tile.getAttribute('boost'));
//console.log ("state = "+state);
@ -2162,26 +2224,32 @@
}
for (var obj in data.timers) {
setTileOnText(obj.toString(),"On (timer)");
//console.log("TIMER "+obj.toString());
}
for (var obj in data.timer_durations) {
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) {
if (data.light_program[obj] != "") {
var light_mode = data.light_program[obj];
// If aqualinkd probrammed light, need to get convert int to text index, if not value is text
// If aqualinkd programmed light, need to convert int to text index, if not value is text
try {
var light_type = document.getElementById(obj.toString()).getAttribute('lighttype')
var light_type = document.getElementById(obj.toString()).getAttribute('lighttype');
if (light_type == 0) {
var light_mode = _light_program[light_type][parseInt(data.light_program[obj])-1];
if (light_mode.endsWith(" - Show"))
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) {}
setTileOnText(obj.toString(),light_mode);
// Below is only needed for full dimmer
}
}
@ -2430,6 +2498,8 @@
message.uri = id+"/percent/set";
else if (type == "switch_vsp")
message.uri = id+"/RPM/set";
else if (type == "light_dimmer")
message.uri = id+"/brightness/set";
else
message.uri = id+"/setpoint/set";
//console.log("Send value back "+temperature.parameter+" "+temperature.value);
@ -2543,6 +2613,7 @@
</table>
</div>
</div>
<div id='thermostat_options' class='options hide'>
<div id='thermostat_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'>
@ -2592,6 +2663,7 @@
</table>
</div>
</div>
<div id='swg_options' class='options hide'>
<div id='swg_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'>
@ -2628,6 +2700,7 @@
</table>
</div>
</div>
<div id='pswitch_options' class='options hide'>
<div id='pswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table id='pswitch_table' border='0' cellpadding='10px' width="100%">
@ -2674,6 +2747,7 @@
</table>
</div>
</div>
<div id='vspswitch_options' class='options hide'>
<div id='vspswitch_options_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'>
@ -2723,6 +2797,55 @@
</table>
</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_pane' class='options_pane' onclick='event.stopPropagation();'>
<table border='0' cellpadding='10px'>