master v2.6.1
sfeakes 2025-03-27 11:26:28 -05:00
parent 0b3e98559e
commit 766ddbc502
28 changed files with 585 additions and 130 deletions

View File

@ -81,9 +81,8 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
* http://aqualink.ip/aquapda_sim.html <- (PDA simulator)
#<a name="release"></a>
# ToDo (future release)
* Update AqualinkD Management console to manage configuration
* Create iAqualink Touch Simulator
* Probably decoded enough protocols for AuqlinkD to self configure.
* AuqlinkD to self configure. (Done for ID's, need to do for Panel type/size)
<!--
@ -106,37 +105,23 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
<!--
NEED TO FIX FOR THIS RELEASE.
***** FIX NET_SERVICES.C action_uri() spa and spa_mode get confused. check EVERY strncmp
* DONE MQTT filter_pump/percent/set, maybe add max/min to pump config. / print protocol on startup
* DONE Pump by name and not ID. clean up code
* DONE look at using 0x00 for no exit on serial errors / startup
* DONE look at virtual button support
* vbuton will need the PDA on iAQT protocol working.
* DONE change dimmer to % from steps. (will make HASIO & Homekit easier)
* add config for homekit_f (panel in F homekin in C), F to F or C to C is fine.
* deprecate (hide and default to yes) extended_device_id_programming
* Move following to main and not config.c - show error is vbutton and no extended_device_id, vbutton w/ pump can be onetouch.
* check panel version reported against config.
# Updates in 2.4.1
# DONE install.sh change spa_mode to spa in config.js
# DONE change hassio.c to use rpm speed/percent
# pickup speed faster on iaqualinktouch after change
* pickup speed faster on iaqualinktouch after change
* with iaqualink2 no need to poll iaqtouch devices as frequently
* update documentation on how vbutton / vpump / pump_max & min / enable_iauqalink2
* check rs serial adapter is active if light color mode 11 is used.
* Check SWG messages like "#1 TruClear", see log in this post https://github.com/sfeakes/AqualinkD/discussions/388
* Finish off heat pump / chiller. Probably use a thermostat for both with heat going to heater SP can cool to chiller SP
* Hide passwords (bitmask)
* Startup config validity checks
* remove "extended_programming", or hide it.
* Heat Pump / Chiller for OneTouch
-->
# Updates in 2.6.1
* Added External Sensors to Web UI & HomeKit.
* Added Heat Pump / Chiller Thermostat to Web UI & HomeKit.
* Fixed some bugs in Configuration Editor.
* Link device/virtual/onetouch button with SWG BOOST. (Allows you to set VSP RPM when in Boost mode)
# Updates in 2.6.0
* Added configuration editor in aqmanager. [Wiki - AQManager](https://github.com/sfeakes/AqualinkD/wiki#AQManager)
* Can now self-configure on startup. set `device_id=0xFF`
@ -458,7 +443,10 @@ https://github.com/sfeakes/AqualinkD/wiki
#
# Aqualink Versions tested
This was designed for Jandy Aqualink RS, so should work with AqualinkRS and iAqualink Combo control panels. It will work with Aqualink PDA/AquaPalm and NON Combo iAqualink; but with limitations.
This was designed for Jandy Aqualink RS, so does work with AqualinkRS and iAqualink Combo control panels. It will work with Aqualink PDA/AquaPalm; but with limitations.
AqualinkD is known to work with Panel Versions from Rev H to the Latest Rev Yg
<!--
Below are verified versions, but should work with any AqualinkRS :-
@ -476,7 +464,7 @@ Below are verified versions, but should work with any AqualinkRS :-
If you have tested a version not listed here, please let me know by opening an issue.
#
-->
# License
## Non Commercial Project
All non commercial projects can be run using our open source code under GPLv2 licensing. As long as your project remains in this category there is no charge.

View File

@ -59,6 +59,7 @@ fi
# Login first Run as root not with sudo on my build machine.
# cat ~/.docker.token | docker login --username sfeakes --password-stdin
# any errors clean build env `docker buildx prune``
echo "Building Docker container for $IMAGE using branch $VERSION"
docker buildx build --platform=linux/amd64,linux/arm64 \

Binary file not shown.

Binary file not shown.

View File

@ -119,6 +119,10 @@ enable_scheduler = yes
#event_check_pumpon_hour = 6
#event_check_pumpoff_hour = 24
# This last one will link a button to SWG boost mode. When in boost mode, you usually have a problem that warrants running the pump faster.
# So you can assign a virtual/one touch button to a particular pump RMP, and then turn it on with this option. (it will also turn it off when boost is finished)
#event_booston_check_device = Fast Pump
# Set the RS485 adapter into low latency mode (of supported)
ftdi_low_latency=YES

Binary file not shown.

Binary file not shown.

View File

@ -515,9 +515,11 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
// A master firmware revision message.
strcpy(aq_data->version, msg);
rsm_get_revision(aq_data->revision, aq_data->version, strlen(aq_data->version));
setPanelInformationFromPanelMsg(aq_data, msg, PANEL_CPU | PANEL_REV, ALLBUTTON);
//setBoardCPURevision(aq_data, aq_data->version, strlen(aq_data->version), ALLB_LOG);
//_gotREV = true;
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel version %s\n", aq_data->version);
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision);
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel version %s\n", aq_data->version);
LOG(ALLB_LOG,LOG_DEBUG, "Control Panel revision %s\n", aq_data->revision);
if (_initWithRS == false)
{
//LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n");
@ -580,6 +582,11 @@ void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
else if ( (strncasecmp(msg, "BOOST POOL", 10) == 0) && (strcasestr(msg, "REMAINING") != NULL) ) {
// Ignore messages if in programming mode. We get one of these turning off for some strange reason.
if (in_programming_mode(aq_data) == false) {
if (aq_data->boost == false || boostInLastLoop == false) {
event_happened_set_device_state(AQS_BOOST_ON, aq_data);
}
snprintf(aq_data->boost_msg, 6, "%s", &msg[11]);
aq_data->boost_duration = rsm_HHMM2min(aq_data->boost_msg);
aq_data->boost = true;

View File

@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "config.h"
#include "domoticz.h"
@ -29,7 +30,8 @@
void initPanelButtons(struct aqualinkdata *aqdata, bool rspda, int size, bool combo, bool dual);
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button);
void printPanelSupport(struct aqualinkdata *aqdata);
uint16_t setPanelSupport(struct aqualinkdata *aqdata);
char *name2label(char *str)
{
@ -49,76 +51,330 @@ char *name2label(char *str)
return newst;
}
// This has NOT been tested.
uint16_t getPanelSupport( char *rev_string, int rev_len)
{
uint16_t supported = 0;
char REV[5];
// Move to utils / rsm_string_utils.
if (! rsm_get_revision(REV, rev_string, rev_len) ) {
LOG(PANL_LOG,LOG_ERR, "Couldn't get panel revision from '%s'\n",rev_string);
return 0; // No point in continue
} else if (REV[0] > 90 || REV[0] < 65) { // > Z or < A
LOG(PANL_LOG,LOG_WARNING, "Panel revision is not understood '%s', please report this issue");
/*
* Search string for consecutive numbers, ie 6520 (early revisions). Return the char of first number and set out_length to length or numbers
*/
const char *count_consecutive_digits(const char *str, int length, int *out_len) {
//int count = 0;
char *sp = NULL;
*out_len = 0;
for (int i = 0; i < length; i++) {
if (isdigit((unsigned char)str[i])) {
if (sp == NULL) sp=(char *)str + i;
*out_len += 1;
} else if (*out_len > 0) {
return sp; // End of first digit run
}
}
return sp;
}
/*
* Search string for Letter then consecutive numbers, ie B0029221. Return the letter and set out_length
*/
const char* find_letter_and_digits(const char *str, int length, int *out_len) {
for (int i = 0; i < length; i++) {
if (isalpha((unsigned char)str[i]) && isdigit((unsigned char)str[i+1]) ) {
count_consecutive_digits((char*)&str[i+1], length-(i+1), out_len);
if (*out_len >= 4) {
*out_len += 1; // Count for the first letter.
return &str[i];
}
}
}
const char *sp = count_consecutive_digits(str, length, out_len);
if (*out_len >= 4 && sp != NULL) {
return sp;
} else {
*out_len = 0;
}
return NULL; // Pattern not found
}
/*
* Search for REV or REV. in string and return next char (missing space)
*/
const char* find_rev_chars(const char *str, int length, int *out_len) {
for (int i = 0; i < length; i++) {
if ( str[i] == 'R' && str[i+1] == 'E' && str[i+2] == 'V' ) {
i=i+3;
while (str[i] == '.' || str[i] == ' ') i++;
*out_len=i;
// Could probably simply check for space here.
while (isalpha(str[*out_len]) || isdigit(str[*out_len]) || str[*out_len] == '.') *out_len+=1;
*out_len = *out_len - i;
return str + i;
}
}
return NULL; // Pattern not found
}
/*
pull board CPU, revision & panel string from strings like
' CPU p/n: B0029221'
'B0029221 REV T.0.1'
'E0260801 REV. O.2'
' REV. O.2 '
'B0029221 REV T.0.1'
' REV T.0.1'
'Control Panel version B0316823 REV Yg'
' REV. O.2 '
' 6520 REV I '
'6520 REV I'
'B0029221 REV T.0'
'B0029221 REV T.0.1'
'B0029222 REV T.2'
'B0316823 REV Yg '
'B0316823 REV Yg'
'E0260801 REV. O.2'
'AquaLink: REV T.0.1'
'CPU p/n: B0029221'
'. RS-6 Combo'
'. PD-8 Only'
*/
uint8_t setPanelInformationFromPanelMsg(struct aqualinkdata *aqdata, const char *input, uint8_t type, emulation_type source) {
const char *rev_pos = NULL;
uint8_t rtn = 0;
//const char *rev_pos = strstr(input, "REV"); // Find the position of "REV"
const char *sp;
int length = 0;
if (isMASK_SET(type, PANEL_REV)) {
if (aqdata->panel_rev[0] == '\0') {
if ( (rev_pos = strstr(input, "REV")) != NULL) { // Find the position of "REV"
length = 0;
sp = find_rev_chars(rev_pos, strlen(input) - (rev_pos - input), &length);
if (length>0 && sp != NULL) {
strncpy(aqdata->panel_rev, sp, length);
aqdata->panel_rev[length] = '\0';
setMASK(rtn, PANEL_REV);
LOG(PANL_LOG, LOG_NOTICE, "Panel REV %s from %s\n",aqdata->panel_rev,getJandyDeviceName(source));
setPanelSupport(aqdata);
//printPanelSupport(aqdata);
} else {
//printf("Failed to find REV, length\n");
}
} else {
//printf("Failed to find REV, null\n");
}
} else {
// Already set
}
}
if (isMASK_SET(type, PANEL_CPU)) {
if (aqdata->panel_cpu[0] == '\0') {
if (rev_pos == NULL)
sp = find_letter_and_digits(input, strlen(input), &length);
else
sp = find_letter_and_digits(input, (rev_pos - input), &length);
if (length>0 && sp != NULL) {
strncpy(aqdata->panel_cpu, sp, length);
aqdata->panel_cpu[length] = '\0';
setMASK(rtn,PANEL_CPU);
LOG(PANL_LOG, LOG_NOTICE, "Panel CPU %s from %s\n",aqdata->panel_cpu,getJandyDeviceName(source));
} else {
//printf("Failed to find CPU\n");
}
} else {
// already set
}
}
if (isMASK_SET(type, PANEL_STRING)) {
if (aqdata->panel_string[0] == '\0') {
// Find first RS or PD letters
sp = NULL;
length = strlen(input);
for (int i=0; i < length; i++) {
if ( (input[i] == 'R' && input[i+1] == 'S') ||
(input[i] == 'P' && input[i+1] == 'D'))
{
sp = &input[i];
break;
}
}
if (sp != NULL) {
// Strip trailing whitespace
for(length=strlen(sp)-1; isspace(sp[length]); length--);
length++;
strncpy(aqdata->panel_string, sp, length);
aqdata->panel_string[length] = '\0';
setMASK(rtn,PANEL_STRING);
LOG(PANL_LOG, LOG_NOTICE, "Panel %s from %s\n",aqdata->panel_string,getJandyDeviceName(source));
} else {
// ERROR not in string.
}
} else {
//already set
}
}
return rtn;
}
uint16_t setPanelSupport(struct aqualinkdata *aqdata)
{
if (! isalpha(aqdata->panel_rev[0])) {
LOG(PANL_LOG,LOG_WARNING, "Panel revision is not understood '%s', please report this issue", aqdata->panel_rev);
}
// Get the actual rev letter
//if ( rsm_get_revision(REV, rev_string, rev_len) ) {
// Rev >=I == one touch protocol
// Rev >=O == VSP
// Rev >=Q == iaqualink touch protocol.
// REv >= P == chemlink
// Rev >= I serial adapter.
// Rev >= F == Dommer. But need serial protocol so set to I
// Rev >= L == JandyColors Smart Light Control
// Rev >= F Dimmer. But need serial protocol so set to I
// Rev >= H (Think this was first RS485)
// Rev >= HH Serial Adapter. (first support)
// Rev >= I Serial Adapter.
// Rev >= I One Touch protocol
// Rev >= L JandyColors Smart Light Control
// Rev >= L PC Dock / (Support stopped around REV Y)
// Rev >= M AquaPalm (PDA) - even in MMM this was not usefull
// Rev >= MMM = 12V JandyColor Lights (also light dimmer)
// Rev >= N Hayward ColorLogic LED Light
// Rev >= O.1== Jandy WaterColors LED ( 9 colors )
// Rev >= T.0.1 == limited color light
// Rec >= T.2 == more color lights
// Rev >= N VersaTemp heatpump & chiller
// Rev >= O Variable Speed Pump
// Rev >- O One Touch (VSP) has different wat to display info vs REV T (Between REV O & T not sure when exact changed )
// Rev >= O.1 == Jandy WaterColors LED ( 9 colors )
// Rev >= O.2 ==
// Rev >= P ChemLink (Chem feeder / replaced with TrueDose )
// Rev >= Q Aqualink Touch protocol
// Rev >= R iAqualink (wifi adapter) protocol
// Rev >= L PC Dock
// Rev >= S
// Rev >= T.0.1 == limited color light
// Rev >= T.2 == more color lights
// Rev >= U
// Rev >= V
// Rev >= W pump label (not number)
// Rev >= W iAqualink 3.0 (I think. ie can set VSP rpm / SWG / Chill setpoint over the protocol )
// Rev >= X
// Rev >= Xg
// Rev >= Y TruSense Water Chemistry Analyzer
// Rev >= Yg Virtual Device called Label Auxiliraries
if (REV[0] > 89 || ( REV[0] == 89 && REV[1] >= 103))
supported |= RSP_SUP_VBTN;
if (REV[0] >= 81) // Q in ascii
supported |= RSP_SUP_AQLT;
if (aqdata->panel_rev[0] >= 79) // O in ascii
aqdata->panel_support_options |= RSP_SUP_VSP;
if (REV[0] >= 82) // R
supported |= RSP_SUP_IAQL;
if (REV[0] >= 80) // P in ascii
supported |= RSP_SUP_CHEM;
if (aqdata->panel_rev[0] >= 73){ // I in ascii
aqdata->panel_support_options |= RSP_SUP_ONET;
aqdata->panel_support_options |= RSP_SUP_RSSA;
aqdata->panel_support_options |= RSP_SUP_SWG;
}
if (REV[0] >= 79) // O in ascii
supported |= RSP_SUP_VSP;
if (aqdata->panel_rev[0] >= 73) // I in ascii, dimmer came out in F, but we use the serial adapter to set, so use that as support
aqdata->panel_support_options |= RSP_SUP_DLIT;
if (REV[0] >= 73){ // I in ascii
supported |= RSP_SUP_ONET;
supported |= RSP_SUP_RSSA;
supported |= RSP_SUP_SWG;
if (aqdata->panel_rev[0] >= 76) {// L in ascii
aqdata->panel_support_options |= RSP_SUP_CLIT;
aqdata->panel_support_options |= RSP_SUP_PCDOC;
}
if (aqdata->panel_rev[0] >= 78) // N in ascii
aqdata->panel_support_options |= RSP_SUP_HPCHIL;
if (aqdata->panel_rev[0] >= 79) // O in ascii
aqdata->panel_support_options |= RSP_SUP_VSP;
if (aqdata->panel_rev[0] == 79) // O. VERY SEPCIFIC onetouch uses diferent menu for VSP.
aqdata->panel_support_options |= RSP_SUP_ONET_EARLY;
if (aqdata->panel_rev[0] >= 80) // P in ascii
aqdata->panel_support_options |= RSP_SUP_CHEM;
if (aqdata->panel_rev[0] >= 81) // Q in ascii
aqdata->panel_support_options |= RSP_SUP_AQLT;
if (aqdata->panel_rev[0] >= 82) // R in ascii
aqdata->panel_support_options |= RSP_SUP_IAQL;
if (aqdata->panel_rev[0] >= 87) {// W in ascii
aqdata->panel_support_options |= RSP_SUP_PLAB;
aqdata->panel_support_options |= RSP_SUP_IAQL3;
}
if (REV[0] >= 76) // L in ascii
supported |= RSP_SUP_CLIT;
if (REV[0] >= 73) // I in ascii, dimmer came out in F, but we use the serial adapter to set, so use that as support
supported |= RSP_SUP_DLIT;
if (aqdata->panel_rev[0] > 89 || ( aqdata->panel_rev[0] == 89 && aqdata->panel_rev[1] >= 103)) { // Y=89, g=103
aqdata->panel_support_options |= RSP_SUP_VBTN;
aqdata->panel_support_options |= RSP_SUP_TSCHEM;
aqdata->panel_support_options &= ~RSP_SUP_PCDOC;
}
//if (REV[0] > 84 || (REV[0] == 84 && REV[1] == 64 && REV[2] >= 50) ) // T in ascii (or T and . and 2 )
// supported |= RSP_SUP_CLIT4;
//}
return supported;
return aqdata->panel_support_options;
}
void printPanelSupport(struct aqualinkdata *aqdata) {
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_ONET )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: One Touch\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_AQLT )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Aqualink Touch\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_ONET_EARLY )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: One Touch (Early)\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_IAQL )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: iAqualink 1.0/2.0\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_IAQL3 )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: iAqualink 3.0\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_RSSA )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: RS Serial Adapter\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_VSP )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Variable Speed Pumps\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_CHEM )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Chemical feeder\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_TSCHEM )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: True Sense Chemical Reader\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_SWG )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Salt Water Generator\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_CLIT )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Color Lights\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_DLIT )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Dimmable Lights\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_VBTN )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Virtual Button\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_PLAB )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Variable Speed Pump (By Label & extended ID)\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_HPCHIL )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: Heat Pump / Chiller\n");
}
if (isMASK_SET(aqdata->panel_support_options, RSP_SUP_PCDOC )) {
LOG(PANL_LOG,LOG_NOTICE, "Panel supports: PC Dock\n");
}
}
void changePanelToMode_Only() {
_aqconfig_.paneltype_mask |= RSP_SINGLE;
_aqconfig_.paneltype_mask &= ~RSP_COMBO;

View File

@ -36,20 +36,30 @@
// Bitmask for pannel support against board rev
// used in getPanelSupport()
#define RSP_SUP_ONET (1 << 0)
#define RSP_SUP_AQLT (1 << 1) // Aqualink Touch
#define RSP_SUP_IAQL (1 << 2 ) // iAqualink Wifi
#define RSP_SUP_RSSA (1 << 3 ) // RS Serial Adapter
#define RSP_SUP_VSP (1 << 4)
#define RSP_SUP_CHEM (1 << 5) // chem feeder
#define RSP_SUP_TSCHEM (1 << 6 ) // true sense chem reader
#define RSP_SUP_SWG (1 << 7) // Salt water generator
#define RSP_SUP_CLIT (1 << 8) // color lights
#define RSP_SUP_DLIT (1 << 9) // dimmer lights
#define RSP_SUP_VBTN (1 << 10) // Virtual button
#define RSP_SUP_PLAB (1 << 11) // Pump VSP by Label and not number
#define RSP_SUP_ONET (1 << 0) // OneTouch
#define RSP_SUP_AQLT (1 << 1) // Aqualink Touch
#define RSP_SUP_ONET_EARLY (1 << 14) // OneTouch REV O uses different tpage for VSP
#define RSP_SUP_IAQL (1 << 2) // iAqualink Wifi (1.0/2.0)
#define RSP_SUP_IAQL3 (1 << 15) // iAqualink WiFi (3.0)
#define RSP_SUP_RSSA (1 << 3) // RS Serial Adapter
#define RSP_SUP_VSP (1 << 4) // Variable Speed Pumps
#define RSP_SUP_CHEM (1 << 5) // chem feeder
#define RSP_SUP_TSCHEM (1 << 6) // true sense chem reader
#define RSP_SUP_SWG (1 << 7) // Salt water generator
#define RSP_SUP_CLIT (1 << 8) // color lights
#define RSP_SUP_DLIT (1 << 9) // dimmer lights
#define RSP_SUP_VBTN (1 << 10) // Virtual button
#define RSP_SUP_PLAB (1 << 11) // Pump VSP by Label and not number
#define RSP_SUP_HPCHIL (1 << 12) // Heat Pump chiller
#define RSP_SUP_PCDOC (1 << 13) // PC Dock
#define PANEL_CPU (1 << 0)
#define PANEL_REV (1 << 1)
#define PANEL_STRING (1 << 2)
uint8_t setPanelInformationFromPanelMsg(struct aqualinkdata *aqdata, const char *input, uint8_t type, emulation_type source);
//bool setPanelStringFromPanelMsg(struct aqualinkdata *aqdata, const char *src, int src_len, logmask_t from);
//bool setBoardCPURevisionFromPanelMsg (struct aqualinkdata *aqdata, const char *src, int src_len, logmask_t from);
//void initButtons(struct aqualinkdata *aqdata);
void setPanelByName(struct aqualinkdata *aqdata, const char *str);
void setPanel(struct aqualinkdata *aqdata, bool rs, int size, bool combo, bool dual);

View File

@ -378,6 +378,27 @@ bool event_happened_set_device_state(reset_event_type type, struct aqualinkdata
//LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule is not set and/or pump is already on, leaving\n");
LOG(SCHD_LOG,LOG_DEBUG, "Boost off, schedule Pump on is %sset, time is %sbetween scheduled hours, Pump is %s, (not changing)\n",(isAQS_BOOST_OFF_ENABED?"":"not "),(scheduledOn?"":" not"), (aq_data->aqbuttons[0].led->state ==OFF?"Off":"On"));
}
if (aq_data->boost_linked_device != AQ_UNKNOWN && aq_data->boost_linked_device <= aq_data->total_buttons && aq_data->boost_linked_device >= 0) {
//aq_data->aqbuttons[aq_data->boost_linked_device].code
if (aq_data->aqbuttons[aq_data->boost_linked_device].led->state == OFF) {
panel_device_request(aq_data, ON_OFF, aq_data->boost_linked_device, false, NET_TIMER);
LOG(SCHD_LOG,LOG_INFO, "Boost off, Turing %s off\n",aq_data->aqbuttons[aq_data->boost_linked_device].label);
} else {
LOG(SCHD_LOG,LOG_INFO, "Boost off, %s is already off\n",aq_data->aqbuttons[aq_data->boost_linked_device].label);
}
}
break;
case AQS_BOOST_ON:
if (aq_data->boost_linked_device != AQ_UNKNOWN && aq_data->boost_linked_device <= aq_data->total_buttons && aq_data->boost_linked_device >= 0) {
//aq_data->aqbuttons[aq_data->boost_linked_device].code
if (aq_data->aqbuttons[aq_data->boost_linked_device].led->state == OFF) {
panel_device_request(aq_data, ON_OFF, aq_data->boost_linked_device, true, NET_TIMER);
LOG(SCHD_LOG,LOG_INFO, "Boost on, Turing %s on\n",aq_data->aqbuttons[aq_data->boost_linked_device].label);
} else {
LOG(SCHD_LOG,LOG_INFO, "Boost on, %s is already on\n",aq_data->aqbuttons[aq_data->boost_linked_device].label);
}
}
break;
}

View File

@ -38,12 +38,14 @@ void get_cron_pump_times();
typedef enum reset_event_type{
AQS_POWER_ON = (1 << 1),
AQS_FRZ_PROTECT_OFF = (1 << 2),
AQS_BOOST_OFF = (1 << 3)
AQS_BOOST_OFF = (1 << 3),
AQS_BOOST_ON = (1 << 4)
} reset_event_type;
#define isAQS_START_PUMP_EVENT_ENABLED ( ((_aqconfig_.schedule_event_mask & AQS_POWER_ON) == AQS_POWER_ON) || \
((_aqconfig_.schedule_event_mask & AQS_FRZ_PROTECT_OFF) == AQS_FRZ_PROTECT_OFF) || \
((_aqconfig_.schedule_event_mask & AQS_BOOST_OFF) == AQS_BOOST_OFF) )
((_aqconfig_.schedule_event_mask & AQS_BOOST_OFF) == AQS_BOOST_OFF) || \
((_aqconfig_.schedule_event_mask & AQS_BOOST_ON) == AQS_BOOST_ON))
//#define isAQS_USE_PUMP_TIME_FROM_CRON_ENABLED !((_aqconfig_.schedule_event_mask & AQS_DONT_USE_CRON_PUMP_TIME) == AQS_DONT_USE_CRON_PUMP_TIME)
#define isAQS_USE_CRON_PUMP_TIME_ENABLED ((_aqconfig_.schedule_event_mask & AQS_USE_CRON_PUMP_TIME) == AQS_USE_CRON_PUMP_TIME)

View File

@ -307,8 +307,15 @@ struct aqualinkdata
{
//panel_status panelstatus;
uint16_t status_mask;
char version[AQ_MSGLEN*2];
char revision[AQ_MSGLEN];
char version[AQ_MSGLEN*2]; // Will be replaced by below in future
char revision[AQ_MSGLEN]; // Will be replaced by below in future
// The below 4 are set (sometimes) but not used yet
char panel_rev[AQ_MSGLEN]; // From panel
char panel_cpu[AQ_MSGLEN]; // From panel
char panel_string[AQ_MSGLEN]; // This is from actual PANEL not aqualinkd's config
uint16_t panel_support_options;
char date[AQ_MSGLEN];
char time[AQ_MSGLEN];
char last_message[AQ_MSGLONGLEN+1]; // Last ascii message from panel - allbutton (or PDA) protocol
@ -345,6 +352,7 @@ struct aqualinkdata
bool boost;
char boost_msg[10];
int boost_duration; // need to remove boost message and use this
int boost_linked_device;
float ph;
int orp;

View File

@ -260,7 +260,7 @@ void action_delayed_request()
// If we don't know the units yet, we can't action setpoint, so wait until we do.
if (_aqualink_data.temp_units == UNKNOWN &&
(_aqualink_data.unactioned.type == POOL_HTR_SETPOINT || _aqualink_data.unactioned.type == SPA_HTR_SETPOINT || _aqualink_data.unactioned.type == FREEZE_SETPOINT))
(_aqualink_data.unactioned.type == POOL_HTR_SETPOINT || _aqualink_data.unactioned.type == SPA_HTR_SETPOINT || _aqualink_data.unactioned.type == FREEZE_SETPOINT || _aqualink_data.unactioned.type == CHILLER_SETPOINT))
return;
if (_aqualink_data.unactioned.type == POOL_HTR_SETPOINT)
@ -302,6 +302,19 @@ void action_delayed_request()
LOG(AQUA_LOG,LOG_NOTICE, "Freeze setpoint is already %d, not changing\n", _aqualink_data.unactioned.value);
}
}
else if (_aqualink_data.unactioned.type == CHILLER_SETPOINT)
{
_aqualink_data.unactioned.value = setpoint_check(CHILLER_SETPOINT, _aqualink_data.unactioned.value, &_aqualink_data);
if (_aqualink_data.chiller_set_point != _aqualink_data.unactioned.value)
{
aq_programmer(AQ_SET_CHILLER_TEMP, sval, &_aqualink_data);
LOG(AQUA_LOG,LOG_NOTICE, "Setting Chiller setpoint to %d\n", _aqualink_data.unactioned.value);
}
else
{
LOG(AQUA_LOG,LOG_NOTICE, "Chiller setpoint is already %d, not changing\n", _aqualink_data.unactioned.value);
}
}
else if (_aqualink_data.unactioned.type == SWG_SETPOINT)
{
_aqualink_data.unactioned.value = setpoint_check(SWG_SETPOINT, _aqualink_data.unactioned.value, &_aqualink_data);
@ -369,19 +382,6 @@ void action_delayed_request()
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 if (_aqualink_data.unactioned.type == CHILLER_SETPOINT)
{
_aqualink_data.unactioned.value = setpoint_check(CHILLER_SETPOINT, _aqualink_data.unactioned.value, &_aqualink_data);
if (_aqualink_data.chiller_set_point != _aqualink_data.unactioned.value)
{
aq_programmer(AQ_SET_CHILLER_TEMP, sval, &_aqualink_data);
LOG(AQUA_LOG,LOG_NOTICE, "Setting Chiller setpoint to %d\n", _aqualink_data.unactioned.value);
}
else
{
LOG(AQUA_LOG,LOG_NOTICE, "Chiller setpoint is already %d, not changing\n", _aqualink_data.unactioned.value);
}
}
else
{
LOG(AQUA_LOG,LOG_ERR, "Unknown request of type %d\n", _aqualink_data.unactioned.type);
@ -489,7 +489,11 @@ int main(int argc, char *argv[])
else if (strcmp(argv[i], "-rsrd") == 0)
{
_cmdln_lograwRS485 = true;
}
}
else if (strcmp(argv[i], "-nc") == 0)
{
_cmdln_nostartupcheck = true;
}
}
// Set this here, so it doesn;t get reset if the manager restarts the AqualinkD process.
@ -533,7 +537,7 @@ int startup(char *self, char *cfgFile)
setLoggingPrms(_aqconfig_.log_level, _aqconfig_.deamonize, _aqconfig_.log_file, NULL);
#endif
LOG(AQUA_LOG,LOG_NOTICE, "%s v%s\n", AQUALINKD_NAME, AQUALINKD_VERSION);
LOG(AQUA_LOG,LOG_NOTICE, "Starting %s v%s !\n", AQUALINKD_NAME, AQUALINKD_VERSION);
check_print_config(&_aqualink_data);
@ -848,6 +852,9 @@ void main_loop()
//_aqualink_data.panelstatus = STARTING;
AddAQDstatusMask(CHECKING_CONFIG);
//_aqualink_data.panel_rev = NULL;
//_aqualink_data.panel_cpu = NULL;
//_aqualink_data.panel_string = NULL;
_aqualink_data.updated = true;
sprintf(_aqualink_data.last_display_message, "%s", "Connecting to Control Panel");
_aqualink_data.is_display_message_programming = false;

View File

@ -547,6 +547,12 @@ void init_parameters (struct aqconfig * parms)
_cfgParams[_numCfgParams].name = CFG_N_event_check_pumpoff_hour;
_cfgParams[_numCfgParams].default_value = (void *)&_dcfg_zero;
_numCfgParams++;
_cfgParams[_numCfgParams].value_ptr = &_aqconfig_.sched_chk_booston_device;
_cfgParams[_numCfgParams].value_type = CFG_STRING;
_cfgParams[_numCfgParams].name = CFG_N_event_check_booston_device;
_cfgParams[_numCfgParams].default_value = NULL;
_numCfgParams++;
_cfgParams[_numCfgParams].value_ptr = &_aqconfig_.ftdi_low_latency;
_cfgParams[_numCfgParams].value_type = CFG_BOOL;
@ -1614,6 +1620,22 @@ void check_print_config (struct aqualinkdata *aqdata)
LOG(AQUA_LOG,LOG_WARNING, "Config error, 'read_RS485_iAqualink' is not valid when 'enable_iaqualink=yes', ignoring read_RS485_iAqualink!\n");
_aqconfig_.read_RS485_devmask &= ~READ_RS485_IAQUALNK;
}
// Find the boost linked device if one is set
if (_aqconfig_.sched_chk_booston_device != NULL) {
//printf("checking boost linked device\n");
for (i = 0; i < aqdata->total_buttons; i++)
{
if (rsm_strncmp(_aqconfig_.sched_chk_booston_device, aqdata->aqbuttons[i].label, strlen(aqdata->aqbuttons[i].label)) == 0) {
aqdata->boost_linked_device = i;
setMASK(_aqconfig_.schedule_event_mask, AQS_BOOST_ON);
break;
}
}
LOG(AQUA_LOG,LOG_WARNING, "Config error, couldn't find button `%s` from config option `%s`\n",_aqconfig_.sched_chk_booston_device,CFG_N_event_check_booston_device);
} else {
aqdata->boost_linked_device = AQ_UNKNOWN;
}
/*
@ -1903,6 +1925,17 @@ int save_config_js(const char* inBuf, int inSize, char* outBuf, int outSize, str
cursor += groupArray[0].rm_eo;
}
// The above will reset all the panel profocol masks since it re-sets the panel, so set them back here.
if (_aqconfig_.rssa_device_id >= 0x48 && _aqconfig_.rssa_device_id <= 0x49) {
addPanelRSserialAdapterInterface();
}
if (_aqconfig_.extended_device_id >= 0x40 && _aqconfig_.extended_device_id <= 0x43) {
addPanelOneTouchInterface();
} else if (_aqconfig_.extended_device_id >= 0x30 && _aqconfig_.extended_device_id <= 0x33) {
addPanelIAQTouchInterface();
}
regfree(&regexCompiled);
check_print_config(aqdata);
@ -1920,10 +1953,10 @@ const char *pumpType2String(pump_type ptype) {
return "JANDY ePUMP";
break;
case VSPUMP:
return "Pentair VF";
return "Pentair VS";
break;
case VFPUMP:
return "Pentair VS";
return "Pentair VF";
break;
case PT_UNKNOWN:
default:

View File

@ -103,6 +103,7 @@ struct aqconfig
int8_t schedule_event_mask; // Was int16_t, but no need
int sched_chk_pumpon_hour;
int sched_chk_pumpoff_hour;
char *sched_chk_booston_device;
bool ftdi_low_latency;
int frame_delay;
bool device_pre_state;
@ -362,6 +363,8 @@ int _numCfgParams;
#define CFG_N_event_check_usecron "event_check_use_scheduler_times"
#define CFG_C_event_check_usecron 32
#define CFG_N_event_check_booston_device "event_booston_check_device"
#define CFG_N_ftdi_low_latency "ftdi_low_latency"
#define CFG_C_ftdi_low_latency 16
#define CFG_N_rs485_frame_delay "rs485_frame_delay"

View File

@ -948,6 +948,11 @@ void processPage(struct aqualinkdata *aq_data)
Info: iAQ Touch: Table Messages 04| CPU p/n: B0029221
Info: iAQ Touch: Table Messages 05| TL Rev:
*/
setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[2], PANEL_STRING, IAQTOUCH);
setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[3], PANEL_REV, IAQTOUCH);
setPanelInformationFromPanelMsg(aq_data, (char *)_tableInformation[4], PANEL_CPU, IAQTOUCH);
if (isPDA_PANEL && ((char *)_tableInformation[03]) > 0) {
if ( rsm_get_revision(aq_data->revision,(char *)_tableInformation[3], sizeof(aq_data->revision) ) == TRUE) {
int len = rsm_get_boardcpu(aq_data->version, sizeof(aq_data->version), (char *)_tableInformation[4], IAQT_TABLE_MSGLEN );
@ -1168,7 +1173,10 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd
}
LOG(IAQT_LOG,LOG_NOTICE, "Enabling iAqualink Protocol on 0x%02hhx\n",_aqconfig_.extended_device_id2);
}
//LOG(IAQT_LOG,LOG_ERR, "STARTUP REMOVED GET PANEL DATA FOR TESTING\n");
// Don't like this here. Come back and rethink getting panel string.
//iaqt_queue_cmd(KEY_IAQTCH_HELP);
//iaqt_queue_cmd(KEY_IAQTCH_HOME);
queueGetProgramData(IAQTOUCH, aq_data);
gotInit = true;
}

View File

@ -532,7 +532,7 @@ int build_device_JSON(struct aqualinkdata *aqdata, char* buffer, int size, bool
"on",
((homekit)?2:0),
((homekit_f)?degFtoC(aqdata->pool_temp):aqdata->pool_temp));
length += sprintf(buffer+length, "{\"type\": \"temperature\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"value\": \"%.*f\" }",
length += sprintf(buffer+length, "{\"type\": \"temperature\", \"id\": \"%s\", \"name\": \"%s\", \"state\": \"%s\", \"value\": \"%.*f\" },",
SPA_TEMP_TOPIC,
/*SPA_TEMPERATURE,*/
"Spa Water Temperature",
@ -540,11 +540,26 @@ int build_device_JSON(struct aqualinkdata *aqdata, char* buffer, int size, bool
((homekit)?2:0),
((homekit_f)?degFtoC(aqdata->spa_temp):aqdata->spa_temp));
for (i=0; i < aqdata->num_sensors; i++)
{
if (aqdata->sensors[i].value != TEMP_UNKNOWN) {
//length += sprintf(buffer+length, "\"%s\": \"%.2f\",", aqdata->sensors[i].label, aqdata->sensors[i].value );
length += sprintf(buffer+length, "{\"type\": \"temperature\", \"id\": \"%s/%s\", \"name\": \"%s\", \"state\": \"%s\", \"value\": \"%.*f\" },",
SENSOR_TOPIC,aqdata->sensors[i].label,
aqdata->sensors[i].label,
"on",
((homekit)?2:0),
((homekit_f)?aqdata->sensors[i].value:aqdata->sensors[i].value));
}
}
/*
length += sprintf(buffer+length, "], \"aux_device_detail\": [");
for (i=0; i < MAX_PUMPS; i++) {
}
*/
if (buffer[length-1] == ',')
length--;
length += sprintf(buffer+length, "]}");
LOG(NET_LOG,LOG_DEBUG, "JSON: %s used %d of %d\n", homekit?"homebridge":"web", length, size);

View File

@ -167,7 +167,7 @@ void _broadcast_simulator_message(struct mg_connection *nc) {
#ifdef AQ_MANAGER
#define WS_LOG_LENGTH 200
#define WS_LOG_LENGTH 400
// Send log message to any aqManager websocket.
void ws_send_logmsg(struct mg_connection *nc, char *msg) {
struct mg_connection *c;

View File

@ -273,11 +273,29 @@ bool log_heater_setpoints(struct aqualinkdata *aq_data)
return rtn;
}
/*
One Touch: OneTouch Menu Line 0 =
One Touch: OneTouch Menu Line 1 =
One Touch: OneTouch Menu Line 2 =
One Touch: OneTouch Menu Line 3 =
One Touch: OneTouch Menu Line 4 = MODEL E0260801
One Touch: OneTouch Menu Line 5 = RS-8 Combo
One Touch: OneTouch Menu Line 6 =
One Touch: OneTouch Menu Line 7 = REV. O.2
One Touch: OneTouch Menu Line 8 =
One Touch: OneTouch Menu Line 9 =
One Touch: OneTouch Menu Line 10 =
One Touch: OneTouch Menu Line 11 =
*/
bool log_panelversion(struct aqualinkdata *aq_data)
{
char *end;
static bool revTest=false;
setPanelInformationFromPanelMsg(aq_data, _menu[4], PANEL_CPU, ONETOUCH);
setPanelInformationFromPanelMsg(aq_data, _menu[5], PANEL_STRING, ONETOUCH);
setPanelInformationFromPanelMsg(aq_data, _menu[7], PANEL_REV, ONETOUCH);
// It's already been set
if (strlen(aq_data->version) > 0) {
// If another protocol set the version, we need to check the rev.
@ -307,7 +325,7 @@ bool log_panelversion(struct aqualinkdata *aq_data)
LOG(ONET_LOG,LOG_NOTICE, "Control Panel version %s\n", aq_data->version);
LOG(ONET_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision);
if ( strcmp(aq_data->revision, "0.1") == 0 || strcmp(aq_data->revision, "0.2") == 0 ) {
if ( strcmp(aq_data->revision, "O.1") == 0 || strcmp(aq_data->revision, "O.2") == 0 ) {
LOG(ONET_LOG,LOG_NOTICE, "Setting early version for OneTouch\n");
_panel_version_P2 = true;
}

View File

@ -58,6 +58,40 @@ Pull revision from string examples
AllButton: Control Panel version B0316823 REV Yg
*/
// This should be removed soon
int rsm_get_revision_new(char *dest, int dest_len, const char *src, int src_len)
{
char *sp = NULL;
char *ep = NULL;
sp = rsm_strnstr(src, "REV", src_len);
if (sp == NULL) {
return 0;
}
sp = sp+3;
while ( *sp == ' ' || *sp == '.') {
sp = sp+1;
}
// sp is now the start of string revision #
ep = sp;
while ( *ep != ' ' && *ep != '\0') {
ep = ep+1;
}
int len=ep-sp;
// Check we got something usefull
if (len > 5) {
return 0;
}
len = AQ_MIN(len, dest_len);
memcpy(dest, sp, len);
dest[len] = '\0';
return len;
}
// This should be removed soon
bool rsm_get_revision(char *dest, const char *src, int src_len)
{
char *sp = NULL;
@ -94,6 +128,7 @@ pull board CPU from strings line
'B0029221 REV T.0.1'
'E0260801 REV. O.2'
*/
// This should be removed soon
int rsm_get_boardcpu(char *dest, int dest_len, const char *src, int src_len)
{
//char *regexString="/\\w\\d{4,10}/gi";
@ -110,7 +145,7 @@ int rsm_get_boardcpu(char *dest, int dest_len, const char *src, int src_len)
if ((regexec(&regexCompiled,src,1,&match,0)) != 0) {
regfree(&regexCompiled);
printf("********** ERROR didn;t line match \n");
//printf("********** ERROR didn;t line match \n");
return 0;
}

View File

@ -4,6 +4,7 @@
//#define MIN(x, y) (((x) < (y)) ? (x) : (y))
bool rsm_get_revision(char *dest, const char *src, int src_len);
int rsm_get_revision_new(char *dest, int dest_len, const char *src, int src_len);
int rsm_get_boardcpu(char *dest, int dest_len, const char *src, int src_len);
char *rsm_charafterstr(const char *haystack, const char *needle, int length);

View File

@ -882,25 +882,25 @@ Debug: AqualinkD: To 0x48 of type Unknown | HEX: 0x10|0x02|0x48|0x13|0x07|0x0
#MODEL?
Jandy From 0x48 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x05|0x18|0x10|0x03|
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x79|0x00|0xff|0x10|0x03| // 23 121
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x79|0x00|0xff|0x10|0x03| // 25 121
!00 MODEL = 6521 -RS 6 Combo
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x78|0x00|0xfe|0x10|0x03| // 23 120
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x78|0x00|0xfe|0x10|0x03| // 25 120
!00 MODEL = 6520 -RS 8 Combo
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7a|0x00|0x00|0x10|0x03| // 23 122
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7a|0x00|0x00|0x10|0x03| // 25 122
!00 MODEL = 6522 - RS 4 Combo
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7b|0x00|0x01|0x10|0x03| // 23 123
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7b|0x00|0x01|0x10|0x03| // 25 123
!00 MODEL = 6523 - RS 8 Only
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7c|0x00|0x02|0x10|0x03| // 23 124
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7c|0x00|0x02|0x10|0x03| // 25 124
!00 MODEL = 6524 - RS 6 only
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7d|0x00|0x03|0x10|0x03| // 23 125
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7d|0x00|0x03|0x10|0x03| // 25 125
!00 MODEL = 6525 - RS 4 only
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7e|0x01|0x05|0x10|0x03| // 23 126 1
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x7e|0x01|0x05|0x10|0x03| // 25 126 1
!00 MODEL = 6526 - dual 6/2
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x1c|0x21|0x00|0xaa|0x10|0x03| // 28 33
@ -921,10 +921,10 @@ Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x1c|
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x1c|0x31|0x01|0xbb|0x10|0x03| // 28 49 1
!00 MODEL = 7217 - dual 2/14
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x88|0x00|0x0e|0x10|0x03| // 23 136
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x88|0x00|0x0e|0x10|0x03| // 25 136
!00 MODEL = 6536 - PD8 Combo
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x89|0x00|0x0f|0x10|0x03| // 23 137
Jandy To 0x48 of type RSSA DevStatus | HEX: 0x10|0x02|0x48|0x13|0x00|0x19|0x89|0x00|0x0f|0x10|0x03| // 25 137
!00 MODEL = 6537 - PD8 only
#OPMODE?

View File

@ -311,7 +311,7 @@ const char* loglevel2cgn_name(int level)
}
}
const char* logmask2name(logmask_t from)
const char *logmask2name(logmask_t from)
{
switch (from) {
case NET_LOG:

View File

@ -4,4 +4,4 @@
#define AQUALINKD_SHORT_NAME "AqualinkD"
// Use Magor . Minor . Patch
#define AQUALINKD_VERSION "2.6.0"
#define AQUALINKD_VERSION "2.6.1"

View File

@ -13,7 +13,12 @@
<script type="text/javascript" src="confighelp.js"></script>
<style>
:root {
--max-config-height: 870px;
--max-config-height: 870px;
--aqualinkd-scale: 0.75;
--aqualinkd-container: 265px;
--aqualinkd-iframe: 350px; /* Seems backwards, but the way the iframe scales the iframe need to be the same amount bigger 350*0.75*/
--logcontainer-height: 510px; /* This will get changed on page load */
}
html {}
@ -44,6 +49,21 @@
.aqualinkd {
grid-column: 1 / -1;
width: 133%;
height: var(--aqualinkd-container); /* Iframe is set to 350px in the HTML so scale it back here */
/*transform: scale(0.75);*/
transform: scale(var(--aqualinkd-scale));
transform-origin: 0 0;
}
.aqualinkd_iframe {
width: 100% ;
height: var(--aqualinkd-iframe);
/* transform scale also scales the whole iframe, so make the with 133% larger 133 * 0.75 = 100 */
/*
width: 133%;
transform: scale(0.75);
transform-origin: 0 0;*/
}
.commands {
@ -146,8 +166,9 @@
.logcontainer {
font-family: monospace;
height: 510px;
/*height: 510px;*//* This was size before scaling aqualinkd iframe*/
/*height: 650px;*/
height: var(--logcontainer-height);
width: 100%;
overflow: auto;
display: flex;
@ -289,6 +310,8 @@
filter: alpha(opacity=0);
opacity: 0.0;
}
/*
.helptxt {
font-size: x-small;
@ -390,6 +413,7 @@
const LOGS2DISPLAY = 500;
function update_log_message(message) {
//console.log(message);
var element = document.createElement("div");
if (message.startsWith("Error:")) {
element.classList.add("logmsgerror");
@ -1500,6 +1524,11 @@
}
*/
function init() {
// Resize log container
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
console.log("Height="+h+" Setting to "+(h-290) );
document.documentElement.style.setProperty('--logcontainer-height', (h-290)+'px');
startWebsockets();
getLatestVersion();
}
@ -1597,7 +1626,8 @@
<div class="wrapper">
<div class="aqualinkd">
<iframe id="aqd" src="/" width="100%" height="350px"></iframe>
<!--<iframe id="aqd" class="aqd_iframe" src="/" width="100%" height="350px"></iframe>-->
<iframe id="aqd" class="aqualinkd_iframe" src="/"></iframe>
</div>
<div class="inner">
<div class="commands">

View File

@ -54,6 +54,7 @@
"Aux_V14",
"Aux_V15",
"Chiller",
"Sensor/CPU",
];
// This get's picked up by dynamic_config.js and used as mode 0

View File

@ -1232,7 +1232,7 @@
} else if (status == 'on' && type == 'setpoint_chiller') {
tile_icon.classList.remove("enabled");
tile_icon.classList.remove("disabled");
console.log("mode="+tile_icon.parentElement.parentElement.getAttribute("mode"));
//console.log("mode="+tile_icon.parentElement.parentElement.getAttribute("mode"));
if ( tile_icon.parentElement.parentElement.getAttribute("mode") == "heat" ) {
tile_icon.classList.remove("cool");
tile_icon.classList.add("heat");
@ -1259,10 +1259,12 @@
}
function createTile(object) {
//console.log("Create tile "+object.id);
if (object.name == 'NONE') {
return;
}
if (typeof devices !== 'undefined' && devices.indexOf(object.id) < 0) {
//console.log("Create tile <exclude list> "+object.label);
return;
}
//if (object.type == 'switch' || object.type == 'switch_program') {
@ -2320,6 +2322,11 @@
//console.log("TIMER "+obj.toString()+" duration "+data.timer_durations[obj]);
}
for (var obj in data.sensors) {
//console.log("Set Value `Sensor/"+obj.toString()+"' to "+data.sensors[obj]);
setTileValue("Sensor/"+obj.toString(), data.sensors[obj]);
}
for (var obj in data.alternate_modes) {
//console.log(obj.toString() +" "+ data.alternate_modes[obj.toString()] );
try {