pull/360/head^2
sfeakes 2024-08-31 18:01:12 -05:00
parent 47820a1ef9
commit 336224a66c
20 changed files with 185 additions and 28 deletions

View File

@ -123,6 +123,7 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
NEED TO FIX FOR THIS RELEASE.
* Pump by name and not ID.
* look at using 0x00 for no exit on serial errors / startup
* Add 0x?? filter for debug_serial from aqmanager
<done> * MQTT ID is now using a lot longer name due to arm64/armhf
<done> * Ignore SWG 0 messages can now be removed since VSP is fixed.
<done> * Increase packet length due to below (also the print message)

Binary file not shown.

Binary file not shown.

View File

@ -59,7 +59,8 @@ panel_type = RS-8 Combo
# Working RS ID's are 0x0a 0x0b 0x09 0x08 <- 0x08 is usually taken
# If your panel is a PDA only model, then PDA device ID's are 0x60, 0x61, 0x62, 0x63.
# (These are NOT recomended to use unless you absolutly have no other option)
device_id=0x0a
#device_id=0x0a
device_id=0x00
# The ID of Jandy SerialInterface device. These is only one usable ID, if serial_logger

Binary file not shown.

Binary file not shown.

View File

@ -16,6 +16,8 @@ void processLEDstate(struct aqualinkdata *aq_data)
int byte;
int bit;
//debuglogPacket(ALLB_LOG, );
for (byte = 0; byte < 5; byte++)
{
for (bit = 0; bit < 8; bit += 2)
@ -629,7 +631,8 @@ bool process_allbutton_packet(unsigned char *packet, int length, struct aqualink
//LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received ACK length %d.\n", length);
break;
case CMD_STATUS:
//LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received STATUS length %d.\n", length);
//LOG(ALLB_LOG,LOG_DEBUG, "RS Received STATUS length %d.\n", length);
//debuglogPacket(ALLB_LOG, packet, length, true, true);
memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN);
processLEDstate(aq_data);

View File

@ -167,6 +167,7 @@ typedef enum panel_vsp_status
PS_ERROR = -4
} panel_vsp_status;
#define PUMP_NAME_LENGTH 30
typedef struct pumpd
{
@ -175,6 +176,8 @@ typedef struct pumpd
int watts;
unsigned char pumpID;
int pumpIndex;
char pumpName[PUMP_NAME_LENGTH];
//char *pumpName;
pump_type pumpType;
//int buttonID;
protocolType prclType;

View File

@ -667,7 +667,10 @@ int startup(char *self, char *cfgFile)
ext[0] = '\0';
for (j = 0; j < _aqualink_data.num_pumps; j++) {
if (_aqualink_data.pumps[j].button == &_aqualink_data.aqbuttons[i]) {
sprintf(ext, "VSP ID 0x%02hhx | PumpID %-1d |",_aqualink_data.pumps[j].pumpID, _aqualink_data.pumps[j].pumpIndex);
sprintf(ext, "VSP ID 0x%02hhx | PumpID %-1d | %s",
_aqualink_data.pumps[j].pumpID,
_aqualink_data.pumps[j].pumpIndex,
_aqualink_data.pumps[j].pumpName[0]=='\0'?"":_aqualink_data.pumps[j].pumpName);
}
}
for (j = 0; j < _aqualink_data.num_lights; j++) {

View File

@ -29,7 +29,16 @@ int build_color_lights_js(struct aqualinkdata *aqdata, char* buffer, int size);
//char *_color_light_options_[LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS][LIGHT_COLOR_NAME];
#endif //COLOR_LIGHTS_H_
/*
Rev T.2 has the below
Jandy colors <- Same
Jandy LED <- Same
SAm/Sal <- Same
IntelliBrite <- Same
Hayw Univ Col <- Color Logic
*/
/*
Color Name Jandy Colors Jandy LED SAm/SAL Color Logic IntelliBrite dimmer
---------------------------------------------------------------------------------------------------------

View File

@ -718,6 +718,15 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring %s'\n",MAX_PUMPS,param);
}
rtn=true;
} else if (strncasecmp(param + 9, "_pumpName", 9) == 0) { //button_01_pumpIndex=1
pump_detail *pump = getpump(aqdata, num);
if (pump != NULL) {
//pump->pumpName = cleanalloc(value);
strncpy(pump->pumpName ,cleanwhitespace(value), PUMP_NAME_LENGTH-1);
} else {
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring %s'\n",MAX_PUMPS,param);
}
rtn=true;
}
/*
} else if (strncasecmp(param + 9, "_pumpID", 7) == 0) {
@ -771,6 +780,9 @@ pump_detail *getpump(struct aqualinkdata *aqdata, int button)
aqdata->pumps[aqdata->num_pumps].watts = TEMP_UNKNOWN;
aqdata->pumps[aqdata->num_pumps].gpm = TEMP_UNKNOWN;
aqdata->pumps[aqdata->num_pumps].pStatus = PS_OFF;
aqdata->pumps[aqdata->num_pumps].pumpIndex = 0;
//pumpType
aqdata->pumps[aqdata->num_pumps].pumpName[0] = '\0';
aqdata->num_pumps++;
return &aqdata->pumps[aqdata->num_pumps-1];
}

View File

@ -432,15 +432,72 @@ Info: iAQ Touch: Status page 06| #1 AquaPure\
*/
pump_detail *matchPump(const logmask_t from, struct aqualinkdata *aq_data, char *name, int *pump_index)
{
int i;
pump_detail *pump = NULL;
int pi = 0;
LOG(IAQT_LOG,LOG_DEBUG, "Finding pump for message '%s'\n",name);
if (rsm_strcmp(name, "Intelliflo VS") == 0 ||
rsm_strcmp(name, "Intelliflo VF") == 0 ||
rsm_strcmp(name, "Jandy ePUMP") == 0 ||
rsm_strcmp(name, "ePump AC") == 0)
{
pi = rsm_atoi(&name[14]);
if (pi <= 0)
pi = rsm_atoi(&name[10]); // ePump AC seems to display index in different position
}
// Now loop over all the VSP pumps and check the name.
for (i = 0; i < aq_data->num_pumps; i++)
{
if ((pi > 0 && aq_data->pumps[i].pumpIndex == pi) ||
(rsm_strcmp(name, aq_data->pumps[i].pumpName) == 0))
{
*pump_index = i;
pump = &aq_data->pumps[i];
}
}
// Log a warning
if (pi > 0)
{
if (pump == NULL)
{
LOG(from, LOG_WARNING, "Got pump message '%s' but can't find pump # %d, please update aqualinkd.conf\n", name, pi);
}
else if (pump->pumpType == PT_UNKNOWN)
{
if (rsm_strcmp(name, "Intelliflo VS") == 0)
pump->pumpType = VSPUMP;
else if (rsm_strcmp(name, "Intelliflo VF") == 0)
pump->pumpType = VFPUMP;
else if (rsm_strcmp(name, "Jandy ePUMP") == 0 ||
rsm_strcmp(name, "ePump AC") == 0)
pump->pumpType = EPUMP;
}
}
if (pump == NULL)
LOG(from, LOG_DEBUG, "Did not find pump config for '%s'\n", name);
else
LOG(from, LOG_DEBUG, "Found pump '%s', Name='%s', 'Index='%d'\n", name, pump->pumpName, pump->pumpIndex);
return pump;
}
void passDeviceStatusPage(struct aqualinkdata *aq_data)
{
int i;
int pi;
int pi = -2;
pump_detail *pump = NULL;
//bool found_swg = false;
//int pump_index = 0;
for (i=0; i <IAQ_STATUS_PAGE_LINES; i++ ) {
/*
//LOG(IAQT_LOG,LOG_NOTICE, "Passing message %.2d| %s\n",i,_deviceStatus[i]);
if (rsm_strcmp(_deviceStatus[i],"Intelliflo VS") == 0 ||
rsm_strcmp(_deviceStatus[i],"Intelliflo VF") == 0 ||
@ -473,8 +530,10 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
continue;
} else if (rsm_strcmp(_deviceStatus[i],"RPM:") == 0) {
} else*/ if (rsm_strcmp(_deviceStatus[i],"RPM:") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
if (pump != NULL) {
iaqt_pump_update(aq_data, pi); // Log that we saw a pump
pump->rpm = rsm_atoi(&_deviceStatus[i][9]);
pump->pStatus = PS_OK;
aq_data->updated = true;
@ -498,7 +557,9 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"*** Priming ***") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
if (pump != NULL) {
iaqt_pump_update(aq_data, pi); // Log that we saw a pump
//pump->rpm = PUMP_PRIMING; // NSF need to remove future
pump->pStatus = PS_PRIMING;
aq_data->updated = true;
@ -506,7 +567,9 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"(Offline)") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
if (pump != NULL) {
iaqt_pump_update(aq_data, pi); // Log that we saw a pump
//pump->rpm = PUMP_OFFLINE; // NSF need to remove future
pump->pStatus = PS_OFFLINE;
aq_data->updated = true;
@ -514,7 +577,9 @@ void passDeviceStatusPage(struct aqualinkdata *aq_data)
LOG(IAQT_LOG,LOG_WARNING, "Got pump message '%s' but can't find pump\n",_deviceStatus[i]);
continue;
} else if (rsm_strcmp(_deviceStatus[i],"(Priming Error)") == 0) {
pump = matchPump(IAQT_LOG, aq_data, _deviceStatus[i-1], &pi);
if (pump != NULL) {
iaqt_pump_update(aq_data, pi); // Log that we saw a pump
//pump->rpm = PUMP_ERROR; // NSF need to remove future
pump->pStatus = PS_ERROR;
aq_data->updated = true;

View File

@ -686,6 +686,7 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr )
char VSPstr[20];
int structIndex;
struct iaqt_page_button *button;
char *pumpName = NULL;
//printf("**** program string '%s'\n",buf);
@ -694,6 +695,7 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr )
//int pumpRPM = atoi(&buf[2]);
for (structIndex=0; structIndex < aq_data->num_pumps; structIndex++) {
if (aq_data->pumps[structIndex].pumpIndex == pumpIndex) {
pumpName = aq_data->pumps[structIndex].pumpName;
if (aq_data->pumps[structIndex].pumpType == PT_UNKNOWN) {
LOG(IAQT_LOG,LOG_ERR, "Can't set Pump RPM/GPM until type is known\n");
cleanAndTerminateThread(threadCtrl);
@ -707,8 +709,8 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr )
//int pumpRPM = atoi(&buf[2]);
//int pumpIndex = 1;
// Just force to pump 1 for testing
sprintf(VSPstr, "VSP%1d Spd ADJ",pumpIndex);
// NSF Should probably check pumpRPM is not -1 here
waitForSingleThreadOrTerminate(threadCtrl, AQ_SET_IAQTOUCH_PUMP_RPM);
@ -718,10 +720,17 @@ void *set_aqualink_iaqtouch_pump_rpm( void *ptr )
if ( goto_iaqt_page(IAQ_PAGE_DEVICES, aq_data) == false )
goto f_end;
sprintf(VSPstr, "VSP%1d Spd ADJ",pumpIndex);
button = iaqtFindButtonByLabel(VSPstr);
if (button == NULL && pumpName[0] != '\0') {
// Try by name
sprintf(VSPstr, "%s ADJ",pumpName);
button = iaqtFindButtonByLabel(VSPstr);
}
if (button == NULL) {
LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not find '%s' button on page setup\n", VSPstr);
goto f_end;
LOG(IAQT_LOG, LOG_ERR, "IAQ Touch did not Pump by index 'VSP%1d Spd ADJ' or by name '%s' button on page setup\n", pumpIndex, VSPstr);
goto f_end;
}
send_aqt_cmd(button->keycode);

View File

@ -523,11 +523,12 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
length += logmaskjsonobject(RSSA_LOG, buffer+length);
length += logmaskjsonobject(DJAN_LOG, buffer+length);
length += logmaskjsonobject(DPEN_LOG, buffer+length);
length += logmaskjsonobject(RSSD_LOG, buffer+length);
length += logmaskjsonobject(PROG_LOG, buffer+length);
length += logmaskjsonobject(SCHD_LOG, buffer+length);
length += logmaskjsonobject(RSTM_LOG, buffer+length);
length += logmaskjsonobject(SIM_LOG, buffer+length);
length += logmaskjsonobject(RSSD_LOG, buffer+length); // Make sure the last one.
// DBGT_LOG is a compile time only, so don;t include
if (buffer[length-1] == ',')
length--;

View File

@ -1067,10 +1067,21 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
setSystemLogLevel(round(value));
return uAQmanager; // Want to resent updated status
} else if (strncmp(ri1, "addlogmask", 10) == 0 && from == NET_WS) { // Only valid from websocket.
if ( round(value) == RSSD_LOG ) {
// Check for filter on RSSD LOG
if (ri2 != NULL) {
_aqconfig_.RSSD_LOG_filter = strtoul(cleanalloc(ri2), NULL, 16);
LOG(NET_LOG,LOG_NOTICE, "Adding RSSD LOG filter 0x%02hhx", _aqconfig_.RSSD_LOG_filter);
}
}
addDebugLogMask(round(value));
return uAQmanager; // Want to resent updated status
} else if (strncmp(ri1, "removelogmask", 13) == 0 && from == NET_WS) { // Only valid from websocket.
removeDebugLogMask(round(value));
if ( round(value) == RSSD_LOG ) {
_aqconfig_.RSSD_LOG_filter = NUL;
LOG(NET_LOG,LOG_NOTICE, "Removed RSSD LOG filter");
}
return uAQmanager; // Want to resent updated status
} else if (strncmp(ri1, "logfile", 7) == 0) {
/*

View File

@ -13,7 +13,7 @@ static FILE *_byteLogFile = NULL;
static bool _logfile_raw = false;
static bool _logfile_packets = false;
//static bool _includePentair = false;
static unsigned char _lastReadFrom = NUL;
//static unsigned char _lastReadFrom = NUL;
void _logPacket(logmask_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read);
int _beautifyPacket(char *buff, int buff_size, unsigned char *packet_buffer, int packet_length, bool error, bool is_read);
@ -95,6 +95,8 @@ void debuglogPacket(logmask_t from, unsigned char *packet_buffer, int packet_len
void _logPacket(logmask_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read)
{
static unsigned char lastPacketTo = NUL;
// No point in continuing if loglevel is < debug_serial and not writing to file
if ( force == false &&
error == false &&
@ -104,21 +106,19 @@ void _logPacket(logmask_t from, unsigned char *packet_buffer, int packet_length,
return;
}
if ( _aqconfig_.RSSD_LOG_filter != NUL ) {
if (is_read) {
_lastReadFrom = packet_buffer[PKT_DEST];
if ( is_read && _aqconfig_.RSSD_LOG_filter != packet_buffer[PKT_DEST]) {
return;
}
} else if (!is_read && _lastReadFrom != _aqconfig_.RSSD_LOG_filter) { // Must be write
// NOTE Whole IF statment is reversed
if ( ! ( (_aqconfig_.RSSD_LOG_filter == packet_buffer[PKT_DEST]) ||
( packet_buffer[PKT_DEST] == 0x00 && lastPacketTo == _aqconfig_.RSSD_LOG_filter)) )
{
lastPacketTo = packet_buffer[PKT_DEST];
return;
}
/*
if ( is_read && _aqconfig_.RSSD_LOG_filter != packet_buffer[PKT_DEST]) {
return;
}
*/
lastPacketTo = packet_buffer[PKT_DEST];
}
//char buff[1000];
char buff[LARGELOGBUFFER];

View File

@ -255,8 +255,13 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
LOG(RSSA_LOG,LOG_DEBUG, "Probe received, will queue device update shortly\n");
//queueGetProgramData(RSSADAPTER, aq_data);
cnt=-5; // Connection reset, so queue the status update
}
if (packet[PKT_CMD] == 0x13) {
/*
} else if (packet[PKT_CMD] == CMD_STATUS) {
// This is identical to allbutton status packet.
LOG(RSSA_LOG,LOG_DEBUG, "RS Received STATUS length %d.\n", length);
debuglogPacket(RSSA_LOG, packet, length, true, true);
*/
} else if (packet[PKT_CMD] == 0x13) {
//beautifyPacket(buff, packet, length);
//LOG(RSSA_LOG,LOG_DEBUG, "%s", buff);
//LOG(RSSA_LOG,LOG_DEBUG," Command 0x%02hhx = |0x%02hhx|0x%02hhx|0x%02hhx %d|%d|%d\n", packet[4], packet[5], packet[6], packet[7], packet[5], packet[6], packet[7]);

View File

@ -2,4 +2,4 @@
#define AQUALINKD_NAME "Aqualink Daemon"
#define AQUALINKD_SHORT_NAME "AqualinkD"
#define AQUALINKD_VERSION "2.3.8 (dev)"
#define AQUALINKD_VERSION "2.3.8 (dev 0.2)"

View File

@ -246,6 +246,7 @@
var _panel_size = 6;
var _panel_set = 0;
var _latestVersionAvailable = 0;
var _rssd_logmask = 0;
function init_collapsible() {
var coll = document.getElementsByClassName("collapsible");
@ -355,7 +356,7 @@
send_command(msg);
}
function setlogmask(caller) {
console.log(caller.id);
//console.log(caller.id);
var id = parseInt(caller.id.split('_')[1]);
var addremove = "";
if (caller.checked) {
@ -368,6 +369,16 @@
uri: addremove,
value: id
};
// If it's RSSD logmask, and we have filter, append that to the uri.
if (caller.id == _rssd_logmask ) {
var filter = document.getElementById("rssd_filter").value;
if (filter) {
if (addremove == "addlogmask") {
msg.uri = msg.uri + "/" + filter;
}
}
}
send_command(msg);
}
function setlogfile(caller) {
@ -436,6 +447,18 @@
}
}
function checkboxClick(caller) {
try {
if (caller.id == "slog_debug") {
if (caller.checked) {
document.getElementById("slog_ids").disabled = true;
} else {
document.getElementById("slog_ids").disabled = false;
}
}
} catch (Error) { }
}
function update_status(data) {
@ -540,9 +563,19 @@
'<div class="toggle-switch"></div>' +
'<span class="toggle-label">' + data['debugmasks'][obj].name + '</span>';
eCommands.appendChild(element);
if ( data['debugmasks'][obj].name.substr(0,9) == "RS Serial" ) {
_rssd_logmask = element_id;
element = document.createElement('div');
element.style.marginTop = '1px';
element.style.marginBottom = '2px'; // = 'style="margin-left: 5px';
element.innerHTML = '<input id="rssd_filter" type="text" value="" size="4" maxlength="4">&nbsp;RS Serial Filter ID <font size="-2">(Eg 0x10)</font></input>';
eCommands.appendChild(element);
}
}
settoggle(element_id, data['debugmasks'][obj].set);
}
}
function get_appropriate_ws_url() {
@ -705,7 +738,7 @@
cmd.uri = "seriallogger/"+ids+"/"+document.getElementById("slog_debug").checked;
cmd.value = document.getElementById("slog_packets").value
console.log("Command = "+cmd);
//console.log("Command = "+cmd);
//console.log("Packets=" + document.getElementById("slog_packets").value );
//console.log("IDs=" + document.getElementById("slog_ids").value );
//console.log("ListQueriedID=" + document.getElementById("slog_ids_queried").checked );
@ -832,7 +865,7 @@
</tr>
<tr>
<td>Debug</td>
<td><input id="slog_debug" type="checkbox"></input></td>
<td><input id="slog_debug" type="checkbox" onclick="checkboxClick(this)"></input></td>
</tr>
<tr>
<td colspan="2" align="center">AqualinkD will be disabled while running</td>

View File

@ -90,6 +90,7 @@
// Reload background image every X seconds.(useful if camera snapshot)
// 0 means only load once when page loads.
//var background_reload = 10;
//var background_reload = 0;
// By default all Variable Speed Pumps will show RPM.
// this will show GPM on VSP's that you can only set GPM (ie Jandy VF pumps)