Version 2.3.0d

pull/94/head
sfeakes 2023-05-17 12:51:00 -05:00
parent 26d2064055
commit 4b8e739788
14 changed files with 3216 additions and 3058 deletions

View File

@ -79,7 +79,7 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to
* Add set time to OneTouch protocol.
* Add support for dimmers in All button, Aqualink Touch & OneTouch protocols.
# Update in Release 2.3.0c (pre release)
# Update in Release 2.3.0d (pre release)
* This is pre-release, please treat it as such.
* Don't use this release on PDA panels unless you can debug/change code <b>I have not been able to test it fully.</b>
* Changed a lot of logic around different protocols.
@ -89,7 +89,7 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to
* Added timers for devices (ie can turn on Pump for x minutes), Long press on device in WebUI.
* Timers supported in MQTT/API.
* Serial logging / error checking enhancements.
* Added simulator back. (still a number of issues).
* Added simulator back. (+ Improved UI).
* Fix issue with incorrect device state after duplicate MQTT messages being sent in rapid succession ( < 0.5 second).
* Found workaround for panel firmware bug in iAqualink Touch protocol where VSP updates sometimes got lost.
* Fix bug in IntelliBrite color lights

View File

@ -119,6 +119,8 @@ bool passJson_scObj(char* line, int length, aqs_cron *values)
readingvalue=false;
}
}
return (captured >= 7)?true:false;
}
int save_schedules_js(char* inBuf, int inSize, char* outBuf, int outSize)

View File

@ -4,9 +4,15 @@
PROCESSNAME=aqualinkd
MYPID=`pidof $PROCESSNAME`
echo "=======";
echo PID:$MYPID
echo "--------"
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
echo "===================";
echo "Process : $PROCESSNAME"
echo "PID : $MYPID"
echo "-------------------"
Rss=`echo 0 $(cat /proc/$MYPID/smaps | grep Rss | awk '{print $2}' | sed 's#^#+#') | bc;`
Shared=`echo 0 $(cat /proc/$MYPID/smaps | grep Shared | awk '{print $2}' | sed 's#^#+#') | bc;`
Private=`echo 0 $(cat /proc/$MYPID/smaps | grep Private | awk '{print $2}' | sed 's#^#+#') | bc;`
@ -20,6 +26,6 @@ echo "Shared " $Shared
echo "Private " $Private
echo "Swap " $Swap
echo "Pss " $Pss
echo "=================";
echo "===================";
echo "Mem " $Mem
echo "=================";
echo "===================";

5156
mongoose.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -569,15 +569,18 @@ void set_macro_status()
// OneTouch Menu Line 5 = CLEAN MODE ON
// OneTouch Menu Line 8 = ONETOUCH 3 OFF
if (get_onetouch_menu_type() == OTM_ONETOUCH) {
strncpy(_macros[0].name, _menu[2], 13);
//strncpy(_macros[0].name, _menu[2], 13); // Compiler warning, use memcpy
memcpy(_macros[0].name, _menu[2], 13);
chopwhitespace(_macros[0].name);
_macros[0].ison = (_menu[2][15] == 'N'?true:false);
strncpy(_macros[1].name, _menu[5], 13);
//strncpy(_macros[1].name, _menu[5], 13);// Compiler warning, use memcpy
memcpy(_macros[1].name, _menu[5], 13);
chopwhitespace(_macros[1].name);
_macros[1].ison = (_menu[5][15] == 'N'?true:false);
strncpy(_macros[2].name, _menu[8], 13);
//strncpy(_macros[2].name, _menu[8], 13);// Compiler warning, use memcpy
memcpy(_macros[2].name, _menu[8], 13);
chopwhitespace(_macros[2].name);
_macros[2].ison = (_menu[8][15] == 'N'?true:false);

Binary file not shown.

View File

@ -234,7 +234,8 @@ use_panel_aux_labels=no
# button_01_pumpIndex=1
# If you have assigned this pump an index number in your Aqualink control panel, (Between 1 & 4), put it here for VSP, RPM, Primp information to be captured.
#
# button_xx_lightMode = (0=Aqualink program, 1=Jandy, 2=Jandy LED, 3=SAm/SAL, 4=Color Logic, 5=Intellibrite, 6=Dimmer)
#
# Below are settings for standard buttons on RS-8 Combo panel used as example.
button_01_label=Filter Pump

Binary file not shown.

View File

@ -56,6 +56,7 @@ char *rsm_strstr(const char *haystack, const char *needle)
if (strlen(sp1) == 0 || strlen(sp2) == 0)
return NULL;
// Need to write this myself for speed
// Maybe use stristr from utils.c in the future. Needs a lot of testing.
//LOG(AQUA_LOG,LOG_DEBUG, "Compare (reset)%d chars of '%s' to '%s'\n",strlen(sp2),sp1,sp2);
return strcasestr(sp1, sp2);
}
@ -149,6 +150,7 @@ int rsm_atoi(const char* str)
return base * sign;
}
// atof that can have blank start
float rsm_atof(const char* str)
{
int i=0;

23
utils.c
View File

@ -468,6 +468,8 @@ void _LOG(int16_t from, int msg_level, char *message)
message[i] = ' ';
}
}
// Add return to end of string if not already their.
// NSF need to come back to this, doesn;t always work
if (message[i] != '\n') {
message[i] = '\n';
message[i+1] = '\0';
@ -496,7 +498,8 @@ void _LOG(int16_t from, int msg_level, char *message)
//int len;
message[8] = ' ';
char *strLevel = elevel2text(msg_level);
strncpy(message, strLevel, strlen(strLevel));
//strncpy(message, strLevel, strlen(strLevel)); // Will give compiler warning, so use memcpy instead
memcpy(message, strLevel, strlen(strLevel));
//len = strlen(message);
/*
if ( message[len-1] != '\n') {
@ -514,14 +517,20 @@ void _LOG(int16_t from, int msg_level, char *message)
int fp = open(_log_filename, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fp != -1) {
timestamp(time);
write(fp, time, strlen(time) );
write(fp, message, strlen(message) );
if ( write(fp, time, strlen(time) ) == -1 ||
write(fp, time, strlen(time) ) == -1 )
{
syslog(LOG_ERR, "Can't write to log file %s\n %s", _log_filename, message);
fprintf (stderr, "Can't write to log file %s\n %s", _log_filename, message);
}
//write(fp, time, strlen(time) );
//write(fp, message, strlen(message) );
close(fp);
} else {
if (_daemonise == TRUE)
syslog(LOG_ERR, "Can't open log file\n %s", message);
syslog(LOG_ERR, "Can't open log file %s\n %s", _log_filename, message);
else
fprintf (stderr, "Can't open debug log\n %s", message);
fprintf (stderr, "Can't open debug log %s\n %s", _log_filename, message);
}
}
@ -603,7 +612,9 @@ void daemonise (char *pidFile, void (*main_function) (void))
exit (EXIT_FAILURE);
}
// Change the current working directory to root.
chdir ("/");
if ( chdir ("/") == -1) {
LOG(AQUA_LOG, LOG_ERR,"Can't set working dir to /");
}
// Close stdin. stdout and stderr
close (STDIN_FILENO);
close (STDOUT_FILENO);

View File

@ -41,8 +41,8 @@
#define DBGT_LOG (1 << 11) // Debug Timer
#define TIMR_LOG (1 << 12) // Timers
// Set scheduler log to aqualink general
#define SCHD_LOG AQUA_LOG
// Set scheduler log to timer log
#define SCHD_LOG TIMR_LOG
/*
typedef enum

View File

@ -1,4 +1,4 @@
#define AQUALINKD_NAME "Aqualink Daemon"
#define AQUALINKD_VERSION "2.3.0c"
#define AQUALINKD_VERSION "2.3.0d"

View File

@ -22,15 +22,30 @@
padding: 0 !important;
}
.wrapper {
display: flex;
justify-content: center;
width: 100%;
/*position: absolute;
justify-content: center;
width: 100%;
height: 100%;*/
}
table {
background-color: rgb(221, 221, 221);
padding: 10px;
}
th {
th {
background-color: white;
}
#title {
background-color: rgb(200, 200, 200);
font-weight: 600;
}
input[type=button],
input[type=submit],
input[type=reset] {
@ -62,9 +77,17 @@
.off {
background-color: rgb(116, 116, 116);
}
.hidden {
display: none;
}
</style>
<script type='text/javascript'>
var _panel_size = 6;
var _panel_set = 0;
function send(source) {
console.log("from" + source.id);
@ -72,62 +95,97 @@
cmd.uri = "rawcommand"
switch (source.id) {
case "Filter_Pump_button":
cmd.value = "2"; //"0x02";
cmd.value = "0x02";
break;
case "Spa_Mode_button":
cmd.value = "1"; // "0x01";
cmd.value = "0x01";
break;
case "Aux_1_button":
cmd.value = "5"; //"0x05";
cmd.value = "0x05";
break;
case "Aux_2_button":
cmd.value = "10"; //"0x0a";
cmd.value = "0x0a";
break;
case "Aux_3_button":
cmd.value = "15"; //"0x0f";
cmd.value = "0x0f";
break;
case "Aux_4_button":
cmd.value = "6"; //"0x06";
if (_panel_size < 12)
cmd.value = "0x06";
else
cmd.value = "0x14"; //Different on RS12+ (0x14)
break;
case "Aux_5_button":
cmd.value = "11"; //"0x0b";
if (_panel_size < 12)
cmd.value = "0x0b";
else
cmd.value = "0x03"; //Different on RS12+ (0x03)
break;
case "Aux_6_button":
cmd.value = "16"; //"0x10";
if (_panel_size < 12)
cmd.value = "0x10";
else
cmd.value = "0x07"; //Different on RS12+ (0x07)
break;
case "Aux_7_button":
cmd.value = "21"; //"0x15";
if (_panel_size < 12)
cmd.value = "0x15";
else
cmd.value = "0x06"; //Different on RS12+ (0x06)
break;
case "Aux_B1_button":
cmd.value = "0x0b";
break;
case "Aux_B2_button":
cmd.value = "0x10";
break;
case "Aux_B3_button":
cmd.value = "0x15";
break;
case "Aux_B4_button":
cmd.value = "0x1a";
break;
case "Aux_B5_button":
cmd.value = "0x04";
break;
case "Aux_B6_button":
cmd.value = "0x08";
break;
case "Aux_B7_button":
cmd.value = "0x0d";
break;
case "Aux_B8_button":
cmd.value = "0x0c";
break;
case "Pool_Heater_button":
cmd.value = "18"; //"0x12";
cmd.value = "0x12";
break;
case "Spa_Heater_button":
cmd.value = "23"; //"0x17";
cmd.value = "0x17";
break;
case "Solar_Heater_button":
cmd.value = "28"; //"0x1c";
cmd.value = "0x1c";
break;
case "B_menu":
//cmd.value = "0x09";
cmd.value = "9";
cmd.value = "0x09";
break;
case "B_cancel":
cmd.value = "14"; //"0x0e";
cmd.value = "0x0e";
break;
case "B_back":
cmd.value = "19"; //"0x13";
cmd.value = "0x13";
break;
case "B_forward":
cmd.value = "24"; //"0x18";
cmd.value = "0x18";
break;
case "B_enter":
cmd.value = "29"; //"0x1d";
cmd.value = "0x1d";
break;
case "B_hold":
cmd.value = "25"; //"0x19";
cmd.value = "0x19";
break;
case "B_overide":
cmd.value = "28"; //"0x1c";
cmd.value = "0x1c";
break;
default:
alert("Unknown button");
@ -135,7 +193,55 @@
break;
}
cmd.value = todec(cmd.value);
send_command(cmd);
// I know we are converting hex to dec and back to hex, but here for checking.
document.getElementById("messages").innerHTML = "Sent "+tohex(cmd.value)+" please wait for response!";
}
function tohex(value) {
var rtn = parseInt(value).toString(16);
if (rtn.length <= 1)
return "0x0"+rtn;
else
return "0x"+rtn;
}
function todec(value) {
let number = parseInt(value, 16);
return number;
}
function set_panel_size(size)
{
if (_panel_set == size){
return;
}
_panel_set = size;
switch(size){
case 6:
document.getElementById("Aux_6_led").classList.add("hidden");
document.getElementById("Aux_6_button").classList.add("hidden");
document.getElementById("Aux_7_led").classList.add("hidden");
document.getElementById("Aux_7_button").classList.add("hidden");
case 8:
document.getElementById("Aux_B1_led").classList.add("hidden");
document.getElementById("Aux_B1_button").classList.add("hidden");
document.getElementById("Aux_B2_led").classList.add("hidden");
document.getElementById("Aux_B2_button").classList.add("hidden");
document.getElementById("Aux_B3_led").classList.add("hidden");
document.getElementById("Aux_B3_button").classList.add("hidden");
document.getElementById("Aux_B4_led").classList.add("hidden");
document.getElementById("Aux_B4_button").classList.add("hidden");
case 12:
document.getElementById("Aux_B5_button").classList.add("hidden");
document.getElementById("Aux_B6_button").classList.add("hidden");
document.getElementById("Aux_B7_button").classList.add("hidden");
document.getElementById("Aux_B8_button").classList.add("hidden");
}
}
@ -144,22 +250,45 @@
if (document.getElementById("status").getAttribute("raw") != data.panel_message) {
document.getElementById("status_three").innerHTML = document.getElementById("status_two").innerHTML;
document.getElementById("status_two").innerHTML = document.getElementById("status").innerHTML;
document.getElementById("status").innerHTML = data.panel_message;
if (data.panel_message == "") {
document.getElementById("status").innerHTML = "&nbsp;";
} else {
document.getElementById("status").innerHTML = data.panel_message;
}
document.getElementById("status").setAttribute("raw", data.panel_message);
document.getElementById("messages").innerHTML = "&nbsp;";
}
for (var obj in data.leds) {
if ((led = document.getElementById(obj.toString() + "_led")) == null) {
if ((led = document.getElementById(obj.toString() + "_led")) == null) {
//console.log("Error " + obj.toString() + " LED not found");
return;
}
if (data.leds[obj] == "on") {
//return;
} else {
if (data.leds[obj] == "on" || data.leds[obj] == "enabled" || data.leds[obj] == "flash") {
//console.log("Set " + obj.toString() + " LED on");
led.classList.add("on");
led.classList.remove("off");
} else {
//console.log("Set " + obj.toString() + " LED off");
led.classList.add("off");
led.classList.remove("on");
}
}
if (obj.toString() == "Aux_4" && _panel_size < 6)
_panel_size=6;
if (obj.toString() == "Aux_6" && _panel_size < 8)
_panel_size=8;
if (obj.toString() == "Aux_B1" && _panel_size < 12)
_panel_size=12;
if (obj.toString() == "Aux_B4")
_panel_size=16;
}
set_panel_size(_panel_size);
}
function update_device(data) {
for (var obj in data['devices']) {
}
}
@ -200,6 +329,7 @@
socket_di.onopen = function () {
// success!
start_simulator();
get_devices();
}
socket_di.onmessage = function got_packet(msg) {
document.getElementById("status").classList.remove("error");
@ -208,6 +338,7 @@
update_status(data);
} else if (data.type == 'devices') {
//update_status(data);
update_device(data);
} else if (data.type == 'aux_labels') {
set_labels(data);
}
@ -232,12 +363,13 @@
uri: "simulator"
};
socket_di.send(JSON.stringify(msg));
}
/*
var msg = {
command: "simulator"
};
socket_di.send(JSON.stringify(msg));*/
function get_devices() {
var msg = {
uri: "devices"
};
socket_di.send(JSON.stringify(msg));
}
function send_command(cmd) {
@ -251,6 +383,7 @@
function init() {
startWebsockets();
}
</script>
@ -259,7 +392,9 @@
<div class="wrapper">
<table border='0' id="deviceList">
<tr style="title">
<td style="title" colspan="12" align="center"><label id="title">&nbsp;&nbsp;AqualinkD All Button Simulator&nbsp;&nbsp;</label></th>
</tr>
<tr>
<td colspan="12" align="center"><label id="status_three">&nbsp;</label></td>
</tr>
@ -327,6 +462,82 @@
<td align="left">
<input id="Aux_7_button" type="button" onclick="send(this);" value="AUX7">
</td>
<td align="right">
<div id="Aux_B1_led" class="led off"></div>
</td>
<td align="left">
<input id="Aux_B1_button" type="button" onclick="send(this);" value="AUXB1">
</td>
<td align="right">
<div id="Aux_B2_led" class="led off"></div>
</td>
<td align="left">
<input id="Aux_B2_button" type="button" onclick="send(this);" value="AUXB2">
</td>
<td align="right">
<div id="Aux_B3_led" class="led off"></div>
</td>
<td align="left">
<input id="Aux_B3_button" type="button" onclick="send(this);" value="AUXB3">
</td>
</tr>
<tr>
<td align="right">
<div id="Aux_B4_led" class="led off"></div>
</td>
<td align="left">
<input id="Aux_B4_button" type="button" onclick="send(this);" value="AUXB4">
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
<input id="Aux_B5_button" type="button" onclick="send(this);" value="AUXB5">
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
<input id="Aux_B6_button" type="button" onclick="send(this);" value="AUXB6">
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
<input id="Aux_B7_button" type="button" onclick="send(this);" value="AUXB7">
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
<input id="Aux_B8_button" type="button" onclick="send(this);" value="AUXB8">
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
&nbsp;
</td>
</tr>
<tr>
<td align="right">
&nbsp;
</td>
<td align="left">
&nbsp;
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
&nbsp;
</td>
<td align="right">
&nbsp;
</td>
<td align="left">
&nbsp;
</td>
<td align="right">
<div id="Pool_Heater_led" class="led off"></div>
</td>
@ -366,6 +577,9 @@
<input type="button" onclick="send(this);" id="B_enter" value="Enter *">
</td>
</tr>
<tr>
<td colspan="12" align="center"><label id="messages">&nbsp;</label></td>
</tr>
</table>
</div>
</body>