diff --git a/README.md b/README.md index 5e3dceb..6ef88cb 100644 --- a/README.md +++ b/README.md @@ -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 * MQTT ID is now using a lot longer name due to arm64/armhf * Ignore SWG 0 messages can now be removed since VSP is fixed. * Increase packet length due to below (also the print message) diff --git a/release/aqualinkd-arm64 b/release/aqualinkd-arm64 index 3c32cdb..8c23e0c 100755 Binary files a/release/aqualinkd-arm64 and b/release/aqualinkd-arm64 differ diff --git a/release/aqualinkd-armhf b/release/aqualinkd-armhf index 6a0f4b6..cf9dfd3 100755 Binary files a/release/aqualinkd-armhf and b/release/aqualinkd-armhf differ diff --git a/release/aqualinkd.conf b/release/aqualinkd.conf index 807ca3c..4540b77 100755 --- a/release/aqualinkd.conf +++ b/release/aqualinkd.conf @@ -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 diff --git a/release/serial_logger-arm64 b/release/serial_logger-arm64 index 18ff159..8e58863 100755 Binary files a/release/serial_logger-arm64 and b/release/serial_logger-arm64 differ diff --git a/release/serial_logger-armhf b/release/serial_logger-armhf index ca90226..a6c6fab 100755 Binary files a/release/serial_logger-armhf and b/release/serial_logger-armhf differ diff --git a/source/allbutton.c b/source/allbutton.c index 1317aa1..8be9a89 100644 --- a/source/allbutton.c +++ b/source/allbutton.c @@ -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); diff --git a/source/aqualink.h b/source/aqualink.h index fc37e40..e057ba1 100644 --- a/source/aqualink.h +++ b/source/aqualink.h @@ -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; diff --git a/source/aqualinkd.c b/source/aqualinkd.c index 185f235..350dc72 100644 --- a/source/aqualinkd.c +++ b/source/aqualinkd.c @@ -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++) { diff --git a/source/color_lights.h b/source/color_lights.h index 11bc441..7d802a9 100644 --- a/source/color_lights.h +++ b/source/color_lights.h @@ -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 --------------------------------------------------------------------------------------------------------- diff --git a/source/config.c b/source/config.c index c8c5aba..9c48311 100644 --- a/source/config.c +++ b/source/config.c @@ -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]; } diff --git a/source/iaqtouch.c b/source/iaqtouch.c index 740de6d..f563f42 100644 --- a/source/iaqtouch.c +++ b/source/iaqtouch.c @@ -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 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; diff --git a/source/iaqtouch_aq_programmer.c b/source/iaqtouch_aq_programmer.c index 8377418..0c11f22 100644 --- a/source/iaqtouch_aq_programmer.c +++ b/source/iaqtouch_aq_programmer.c @@ -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); diff --git a/source/json_messages.c b/source/json_messages.c index 9f0e5b4..e4c2d9e 100644 --- a/source/json_messages.c +++ b/source/json_messages.c @@ -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--; diff --git a/source/net_services.c b/source/net_services.c index d017307..98d0d6d 100644 --- a/source/net_services.c +++ b/source/net_services.c @@ -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) { /* diff --git a/source/packetLogger.c b/source/packetLogger.c index 3a6b866..42d6d80 100644 --- a/source/packetLogger.c +++ b/source/packetLogger.c @@ -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 - return; - } -/* - if ( is_read && _aqconfig_.RSSD_LOG_filter != packet_buffer[PKT_DEST]) { + // 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; } -*/ + lastPacketTo = packet_buffer[PKT_DEST]; } + + //char buff[1000]; char buff[LARGELOGBUFFER]; diff --git a/source/serialadapter.c b/source/serialadapter.c index 9533339..f77ce13 100644 --- a/source/serialadapter.c +++ b/source/serialadapter.c @@ -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]); diff --git a/source/version.h b/source/version.h index 4f13a49..f925d2c 100644 --- a/source/version.h +++ b/source/version.h @@ -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)" diff --git a/web/aqmanager.html b/web/aqmanager.html index 669b670..c38f57a 100644 --- a/web/aqmanager.html +++ b/web/aqmanager.html @@ -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 @@ '
' + '' + data['debugmasks'][obj].name + ''; 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 = ' RS Serial Filter ID (Eg 0x10)'; + 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 @@ Debug - + AqualinkD will be disabled while running diff --git a/web/config.js b/web/config.js index 27e73c9..76eff02 100644 --- a/web/config.js +++ b/web/config.js @@ -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)