mirror of https://github.com/sfeakes/AqualinkD.git
parent
0b3e98559e
commit
766ddbc502
40
README.md
40
README.md
|
@ -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.
|
||||
|
|
|
@ -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.
|
@ -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.
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(®exCompiled);
|
||||
|
||||
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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(®exCompiled,src,1,&match,0)) != 0) {
|
||||
regfree(®exCompiled);
|
||||
printf("********** ERROR didn;t line match \n");
|
||||
//printf("********** ERROR didn;t line match \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue