mirror of https://github.com/sfeakes/AqualinkD.git
V2.3.0e
parent
1cb3be4ede
commit
9f91af03ce
|
@ -78,15 +78,16 @@ Designed to mimic AqualinkRS6 All Button keypad and (like the keypad) is used to
|
||||||
* Allow selecting of pre-defined VSP programs (Aqualink Touch & OneTouch protocols.)
|
* Allow selecting of pre-defined VSP programs (Aqualink Touch & OneTouch protocols.)
|
||||||
* Add set time to OneTouch protocol.
|
* Add set time to OneTouch protocol.
|
||||||
|
|
||||||
# Update in Release 2.3.0d (pre release)
|
# Update in Release 2.3.0e (pre release)
|
||||||
* This is pre-release, please treat it as such.
|
* This is pre-release, please treat it as such.
|
||||||
* Proceed with caution on PDA panels <i>I have not been able to test it fully on all variants</i> and you may need to go back to your current (or previous) version of AqualinkD
|
* Proceed with caution on PDA panels <i>I have not been able to test it fully on all variants</i> and you may need to go back to your current (or previous) version of AqualinkD
|
||||||
* Changed a lot of logic around different protocols.
|
* Changed a lot of logic around different protocols.
|
||||||
* Add support for dimmers.
|
|
||||||
* AqualinkD will find out the fastest way to change something depending on the protocols available.
|
* AqualinkD will find out the fastest way to change something depending on the protocols available.
|
||||||
* Added scheduler (click time in web ui). supports full calendar year (ie seasons), See wiki for details.
|
* Added scheduler (click time in web ui). supports full calendar year (ie seasons), See wiki for details.
|
||||||
* Added timers for devices (ie can turn on Pump for x minutes), Long press on device in WebUI.
|
* Added timers for devices (ie can turn on Pump for x minutes), Long press on device in WebUI.
|
||||||
* Timers supported in MQTT/API.
|
* Timers supported in MQTT/API.
|
||||||
|
* Add support for dimmers.
|
||||||
|
* Extended SWG status now in web UI.
|
||||||
* Serial logging / error checking enhancements.
|
* Serial logging / error checking enhancements.
|
||||||
* Added simulator back. (+ Improved UI).
|
* Added simulator back. (+ Improved UI).
|
||||||
* Fix issue with incorrect device state after duplicate MQTT messages being sent in rapid succession ( < 0.5 second).
|
* Fix issue with incorrect device state after duplicate MQTT messages being sent in rapid succession ( < 0.5 second).
|
||||||
|
|
|
@ -109,7 +109,7 @@ setPanel("RS-8 Combo");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
char _panelString[36];
|
char _panelString[60];
|
||||||
void setPanelString()
|
void setPanelString()
|
||||||
{
|
{
|
||||||
sprintf(_panelString, "%s%s-%d %s%s%s",
|
sprintf(_panelString, "%s%s-%d %s%s%s",
|
||||||
|
|
|
@ -81,8 +81,8 @@ bool waitForButtonState(struct aqualinkdata *aq_data, aqkey* button, aqledstate
|
||||||
bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived);
|
bool waitForEitherMessage(struct aqualinkdata *aq_data, char* message1, char* message2, int numMessageReceived);
|
||||||
|
|
||||||
bool push_aq_cmd(unsigned char cmd);
|
bool push_aq_cmd(unsigned char cmd);
|
||||||
void waitfor_queue2empty();
|
//void waitfor_queue2empty();
|
||||||
void longwaitfor_queue2empty();
|
//void longwaitfor_queue2empty();
|
||||||
|
|
||||||
void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride);
|
void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data, bool allowOveride);
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,9 @@ void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_dat
|
||||||
//void queueGetExtendedProgramData(emulation_type source_type, struct aqualinkdata *aq_data, bool labels);
|
//void queueGetExtendedProgramData(emulation_type source_type, struct aqualinkdata *aq_data, bool labels);
|
||||||
unsigned char pop_aq_cmd(struct aqualinkdata *aq_data);
|
unsigned char pop_aq_cmd(struct aqualinkdata *aq_data);
|
||||||
|
|
||||||
|
void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, program_type type);
|
||||||
|
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl);
|
||||||
|
|
||||||
//void force_queue_delete() // Yes I want compiler warning if this is used.
|
//void force_queue_delete() // Yes I want compiler warning if this is used.
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,11 +140,6 @@ int RPM_check(pump_type type, int value, struct aqualinkdata *aqdata);
|
||||||
const char *ptypeName(program_type type);
|
const char *ptypeName(program_type type);
|
||||||
const char *programtypeDisplayName(program_type type);
|
const char *programtypeDisplayName(program_type type);
|
||||||
|
|
||||||
// These shouldn't be here, but just for the PDA AQ PROGRAMMER
|
|
||||||
void send_cmd(unsigned char cmd);
|
|
||||||
bool push_aq_cmd(unsigned char cmd);
|
|
||||||
void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, program_type type);
|
|
||||||
void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl);
|
|
||||||
bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,7 +51,10 @@ const char* get_packet_type(unsigned char* packet , int length)
|
||||||
|
|
||||||
switch (packet[PKT_CMD]) {
|
switch (packet[PKT_CMD]) {
|
||||||
case CMD_ACK:
|
case CMD_ACK:
|
||||||
return "Ack";
|
if (packet[5] == NUL)
|
||||||
|
return "Ack";
|
||||||
|
else
|
||||||
|
return "Ack w/ Command";
|
||||||
break;
|
break;
|
||||||
case CMD_STATUS:
|
case CMD_STATUS:
|
||||||
return "Status";
|
return "Status";
|
||||||
|
@ -919,7 +922,7 @@ int get_packet(int fd, unsigned char* packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
||||||
if (_aqconfig_.log_protocol_packets)
|
if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL)
|
||||||
logPacketRead(packet, index);
|
logPacketRead(packet, index);
|
||||||
// Return the packet length.
|
// Return the packet length.
|
||||||
return index;
|
return index;
|
||||||
|
|
54
aqualinkd.c
54
aqualinkd.c
|
@ -1235,6 +1235,14 @@ int main(int argc, char *argv[])
|
||||||
LOG(AQUA_LOG,LOG_NOTICE, "Config light_pgm_mode = %.2f\n", _aqconfig_.light_programming_mode);
|
LOG(AQUA_LOG,LOG_NOTICE, "Config light_pgm_mode = %.2f\n", _aqconfig_.light_programming_mode);
|
||||||
LOG(AQUA_LOG,LOG_NOTICE, "Debug RS485 protocol = %s\n", bool2text(_aqconfig_.log_protocol_packets));
|
LOG(AQUA_LOG,LOG_NOTICE, "Debug RS485 protocol = %s\n", bool2text(_aqconfig_.log_protocol_packets));
|
||||||
LOG(AQUA_LOG,LOG_NOTICE, "Debug RS485 protocol raw = %s\n", bool2text(_aqconfig_.log_raw_bytes));
|
LOG(AQUA_LOG,LOG_NOTICE, "Debug RS485 protocol raw = %s\n", bool2text(_aqconfig_.log_raw_bytes));
|
||||||
|
if ( _aqconfig_.RSSD_LOG_filter != NUL)
|
||||||
|
LOG(AQUA_LOG,LOG_NOTICE, "Log RS485 packets from = 0x%02hhx\n", _aqconfig_.RSSD_LOG_filter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
//LOG(AQUA_LOG,LOG_NOTICE, "Use PDA 4 auxiliary info = %s\n", bool2text(_aqconfig_.use_PDA_auxiliary));
|
//LOG(AQUA_LOG,LOG_NOTICE, "Use PDA 4 auxiliary info = %s\n", bool2text(_aqconfig_.use_PDA_auxiliary));
|
||||||
//LOG(AQUA_LOG,LOG_NOTICE, "Read Pentair Packets = %s\n", bool2text(_aqconfig_.read_pentair_packets));
|
//LOG(AQUA_LOG,LOG_NOTICE, "Read Pentair Packets = %s\n", bool2text(_aqconfig_.read_pentair_packets));
|
||||||
// logMessage (LOG_NOTICE, "Config serial_port = %s\n", config_parameters->serial_port);
|
// logMessage (LOG_NOTICE, "Config serial_port = %s\n", config_parameters->serial_port);
|
||||||
|
@ -1861,52 +1869,6 @@ void main_loop()
|
||||||
if (getProtocolType(packet_buffer) == JANDY)
|
if (getProtocolType(packet_buffer) == JANDY)
|
||||||
{
|
{
|
||||||
_aqualink_data.updated = processJandyPacket(packet_buffer, packet_length, &_aqualink_data);
|
_aqualink_data.updated = processJandyPacket(packet_buffer, packet_length, &_aqualink_data);
|
||||||
/*
|
|
||||||
// We received the ack from a Jandy device we are interested in
|
|
||||||
if (packet_buffer[PKT_DEST] == DEV_MASTER && interestedInNextAck != DRS_NONE)
|
|
||||||
{
|
|
||||||
if (interestedInNextAck == DRS_SWG)
|
|
||||||
{
|
|
||||||
_aqualink_data.updated = processPacketFromSWG(packet_buffer, packet_length, &_aqualink_data);
|
|
||||||
}
|
|
||||||
else if (interestedInNextAck == DRS_EPUMP)
|
|
||||||
{
|
|
||||||
_aqualink_data.updated = processPacketFromJandyPump(packet_buffer, packet_length, &_aqualink_data);
|
|
||||||
}
|
|
||||||
interestedInNextAck = DRS_NONE;
|
|
||||||
previous_packet_to = NUL;
|
|
||||||
}
|
|
||||||
// We were expecting an ack from Jandy device but didn't receive it.
|
|
||||||
else if (packet_buffer[PKT_DEST] != DEV_MASTER && interestedInNextAck != DRS_NONE )
|
|
||||||
{
|
|
||||||
if (interestedInNextAck == DRS_SWG && _aqualink_data.ar_swg_device_status != SWG_STATUS_OFF)
|
|
||||||
{ // SWG Offline
|
|
||||||
processMissingAckPacketFromSWG(previous_packet_to, &_aqualink_data);
|
|
||||||
}
|
|
||||||
else if (interestedInNextAck == DRS_EPUMP)
|
|
||||||
{ // ePump offline
|
|
||||||
processMissingAckPacketFromJandyPump(previous_packet_to, &_aqualink_data);
|
|
||||||
}
|
|
||||||
interestedInNextAck = DRS_NONE;
|
|
||||||
previous_packet_to = NUL;
|
|
||||||
}
|
|
||||||
else if (READ_RSDEV_SWG && packet_buffer[PKT_DEST] == SWG_DEV_ID)
|
|
||||||
{
|
|
||||||
interestedInNextAck = DRS_SWG;
|
|
||||||
_aqualink_data.updated = processPacketToSWG(packet_buffer, packet_length, &_aqualink_data, _aqconfig_.swg_zero_ignore);
|
|
||||||
previous_packet_to = packet_buffer[PKT_DEST];
|
|
||||||
}
|
|
||||||
else if (READ_RSDEV_ePUMP && packet_buffer[PKT_DEST] >= JANDY_DEC_PUMP_MIN && packet_buffer[PKT_DEST] <= JANDY_DEC_PUMP_MAX)
|
|
||||||
{
|
|
||||||
interestedInNextAck = DRS_EPUMP;
|
|
||||||
_aqualink_data.updated = processPacketToJandyPump(packet_buffer, packet_length, &_aqualink_data);
|
|
||||||
previous_packet_to = packet_buffer[PKT_DEST];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interestedInNextAck = DRS_NONE;
|
|
||||||
previous_packet_to = NUL;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
// Process Pentair Device Packed (pentair have to & from in message, so no need to)
|
// Process Pentair Device Packed (pentair have to & from in message, so no need to)
|
||||||
else if (getProtocolType(packet_buffer) == PENTAIR && READ_RSDEV_vsfPUMP) {
|
else if (getProtocolType(packet_buffer) == PENTAIR && READ_RSDEV_vsfPUMP) {
|
||||||
|
|
4
config.c
4
config.c
|
@ -79,6 +79,7 @@ void init_parameters (struct aqconfig * parms)
|
||||||
//parms->device_id = strtoul(DEFAULT_DEVICE_ID, &p, 16);
|
//parms->device_id = strtoul(DEFAULT_DEVICE_ID, &p, 16);
|
||||||
parms->device_id = strtoul(DEFAULT_DEVICE_ID, NULL, 16);
|
parms->device_id = strtoul(DEFAULT_DEVICE_ID, NULL, 16);
|
||||||
parms->rssa_device_id = NUL;
|
parms->rssa_device_id = NUL;
|
||||||
|
parms->RSSD_LOG_filter = NUL;
|
||||||
parms->paneltype_mask = 0;
|
parms->paneltype_mask = 0;
|
||||||
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
||||||
parms->extended_device_id = NUL;
|
parms->extended_device_id = NUL;
|
||||||
|
@ -381,6 +382,9 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
||||||
} else if (strncasecmp(param, "rssa_device_id", 14) == 0) {
|
} else if (strncasecmp(param, "rssa_device_id", 14) == 0) {
|
||||||
_aqconfig_.rssa_device_id = strtoul(cleanalloc(value), NULL, 16);
|
_aqconfig_.rssa_device_id = strtoul(cleanalloc(value), NULL, 16);
|
||||||
rtn=true;
|
rtn=true;
|
||||||
|
} else if (strncasecmp(param, "RSSD_LOG_filter", 15) == 0) {
|
||||||
|
_aqconfig_.RSSD_LOG_filter = strtoul(cleanalloc(value), NULL, 16);
|
||||||
|
rtn=true;
|
||||||
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
||||||
} else if (strncasecmp (param, "extended_device_id_programming", 30) == 0) {
|
} else if (strncasecmp (param, "extended_device_id_programming", 30) == 0) {
|
||||||
// Has to be before the below.
|
// Has to be before the below.
|
||||||
|
|
1
config.h
1
config.h
|
@ -77,6 +77,7 @@ struct aqconfig
|
||||||
bool display_warnings_web;
|
bool display_warnings_web;
|
||||||
bool log_protocol_packets; // Read & Write as packets
|
bool log_protocol_packets; // Read & Write as packets
|
||||||
bool log_raw_bytes; // Read as bytes
|
bool log_raw_bytes; // Read as bytes
|
||||||
|
unsigned char RSSD_LOG_filter;
|
||||||
//bool log_raw_RS_bytes;
|
//bool log_raw_RS_bytes;
|
||||||
bool readahead_b4_write;
|
bool readahead_b4_write;
|
||||||
bool mqtt_timed_update;
|
bool mqtt_timed_update;
|
||||||
|
|
|
@ -501,6 +501,9 @@ int build_aqualink_status_JSON(struct aqualinkdata *aqdata, char* buffer, int si
|
||||||
if ( aqdata->orp != TEMP_UNKNOWN )
|
if ( aqdata->orp != TEMP_UNKNOWN )
|
||||||
length += sprintf(buffer+length, ",\"chem_orp\":\"%d\"",aqdata->orp );
|
length += sprintf(buffer+length, ",\"chem_orp\":\"%d\"",aqdata->orp );
|
||||||
|
|
||||||
|
if ( READ_RSDEV_SWG )
|
||||||
|
length += sprintf(buffer+length, ",\"swg_fullstatus\": \"%d\"", aqdata->ar_swg_device_status);
|
||||||
|
|
||||||
length += sprintf(buffer+length, ",\"leds\":{" );
|
length += sprintf(buffer+length, ",\"leds\":{" );
|
||||||
for (i=0; i < aqdata->total_buttons; i++)
|
for (i=0; i < aqdata->total_buttons; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@ static FILE *_byteLogFile = NULL;
|
||||||
static bool _logfile_raw = false;
|
static bool _logfile_raw = false;
|
||||||
static bool _logfile_packets = false;
|
static bool _logfile_packets = false;
|
||||||
//static bool _includePentair = false;
|
//static bool _includePentair = false;
|
||||||
|
static unsigned char _lastReadFrom = NUL;
|
||||||
|
|
||||||
void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read);
|
void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read);
|
||||||
int _beautifyPacket(char *buff, unsigned char *packet_buffer, int packet_length, bool error, bool is_read);
|
int _beautifyPacket(char *buff, unsigned char *packet_buffer, int packet_length, bool error, bool is_read);
|
||||||
|
@ -95,9 +96,29 @@ void debuglogPacket(int16_t from, unsigned char *packet_buffer, int packet_lengt
|
||||||
void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read)
|
void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, bool error, bool force, bool is_read)
|
||||||
{
|
{
|
||||||
// No point in continuing if loglevel is < debug_serial and not writing to file
|
// No point in continuing if loglevel is < debug_serial and not writing to file
|
||||||
if ( force == false && error == false && getLogLevel(from) < LOG_DEBUG_SERIAL /*&& _logfile_raw == false*/ && _logfile_packets == false) {
|
if ( force == false &&
|
||||||
|
error == false &&
|
||||||
|
getLogLevel(from) < LOG_DEBUG_SERIAL &&
|
||||||
|
/*_logfile_raw == false &&*/
|
||||||
|
_logfile_packets == false ) {
|
||||||
return;
|
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]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
char buff[1000];
|
char buff[1000];
|
||||||
|
|
||||||
_beautifyPacket(buff, packet_buffer, packet_length, error, is_read);
|
_beautifyPacket(buff, packet_buffer, packet_length, error, is_read);
|
||||||
|
@ -110,6 +131,8 @@ void _logPacket(int16_t from, unsigned char *packet_buffer, int packet_length, b
|
||||||
else {
|
else {
|
||||||
if (force)
|
if (force)
|
||||||
LOG(from,LOG_DEBUG, "%s", buff);
|
LOG(from,LOG_DEBUG, "%s", buff);
|
||||||
|
//else if (is_read && _aqconfig_.serial_debug_filter != NUL && _aqconfig_.serial_debug_filter == packet_buffer[PKT_DEST])
|
||||||
|
// LOG(from,LOG_NOTICE, "%s", buff);
|
||||||
else
|
else
|
||||||
LOG(from,LOG_DEBUG_SERIAL, "%s", buff);
|
LOG(from,LOG_DEBUG_SERIAL, "%s", buff);
|
||||||
}
|
}
|
||||||
|
|
420
pda.c
420
pda.c
|
@ -32,10 +32,6 @@
|
||||||
#include "devices_jandy.h"
|
#include "devices_jandy.h"
|
||||||
#include "rs_msg_utils.h"
|
#include "rs_msg_utils.h"
|
||||||
|
|
||||||
// This needs to be tested on a real panel.
|
|
||||||
//#define NEW_UPDATE_METHOD
|
|
||||||
|
|
||||||
|
|
||||||
// static struct aqualinkdata _aqualink_data;
|
// static struct aqualinkdata _aqualink_data;
|
||||||
static struct aqualinkdata *_aqualink_data;
|
static struct aqualinkdata *_aqualink_data;
|
||||||
static unsigned char _last_packet_type;
|
static unsigned char _last_packet_type;
|
||||||
|
@ -137,31 +133,30 @@ void set_pda_led(struct aqualinkled *led, char state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NEW_UPDATE_METHOD
|
|
||||||
void equiptment_update_cycle(int eqID) {
|
void equiptment_update_cycle(int eqID) {
|
||||||
// If you have a -1, it's a reset to clear / update information.
|
// If you have a -1, it's a reset to clear / update information.
|
||||||
int i;
|
int i;
|
||||||
static uint32_t update_equiptment_bitmask = 0;
|
static uint32_t update_equiptment_bitmask = 0;
|
||||||
|
|
||||||
if (eqID == -1) {
|
if (eqID == -1) {
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "(not implimented) Start new equiptment cycle\n");
|
LOG(PDA_LOG,LOG_DEBUG, "Start new equiptment cycle\n");
|
||||||
|
|
||||||
for (i=0; i < _aqualink_data->total_buttons; i++) {
|
for (i=0; i < _aqualink_data->total_buttons - 2 ; i++) { // total_buttons - 2 because we don't get heaters in this cycle
|
||||||
if ((update_equiptment_bitmask & (1 << (i+1))) != (1 << (i+1))) {
|
if ((update_equiptment_bitmask & (1 << (i+1))) != (1 << (i+1))) {
|
||||||
if (_aqualink_data->aqbuttons[i].led->state != OFF) {
|
if (_aqualink_data->aqbuttons[i].led->state != OFF) {
|
||||||
_aqualink_data->aqbuttons[i].led->state = OFF;
|
_aqualink_data->aqbuttons[i].led->state = OFF;
|
||||||
_aqualink_data->updated = true;
|
_aqualink_data->updated = true;
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "(not implimented) Turn off equiptment id %d %s not seen in last cycle\n", i, _aqualink_data->aqbuttons[i].name);
|
LOG(PDA_LOG,LOG_DEBUG, "Turn off equiptment id %d %s not seen in last cycle\n", i, _aqualink_data->aqbuttons[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update_equiptment_bitmask = 0;
|
update_equiptment_bitmask = 0;
|
||||||
} else {
|
} else {
|
||||||
update_equiptment_bitmask |= (1 << (eqID+1));
|
update_equiptment_bitmask |= (1 << (eqID+1));
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "(not implimented) Added equiptment id %d %s to updated cycle\n", eqID, _aqualink_data->aqbuttons[eqID].name);
|
LOG(PDA_LOG,LOG_DEBUG, "Added equiptment id %d %s to updated cycle\n", eqID, _aqualink_data->aqbuttons[eqID].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void pass_pda_equiptment_status_item_OLD(char *msg)
|
void pass_pda_equiptment_status_item_OLD(char *msg)
|
||||||
{
|
{
|
||||||
|
@ -250,10 +245,8 @@ void pass_pda_equiptment_status_item_OLD(char *msg)
|
||||||
{
|
{
|
||||||
if (strcasecmp(msg, _aqualink_data->aqbuttons[i].label) == 0)
|
if (strcasecmp(msg, _aqualink_data->aqbuttons[i].label) == 0)
|
||||||
{
|
{
|
||||||
#ifdef NEW_UPDATE_METHOD
|
|
||||||
equiptment_update_cycle(i);
|
equiptment_update_cycle(i);
|
||||||
#endif
|
LOG(PDA_LOG,LOG_DEBUG, "Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg);
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "*** Found Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg);
|
|
||||||
// It's on (or delayed) if it's listed here.
|
// It's on (or delayed) if it's listed here.
|
||||||
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
|
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
|
||||||
{
|
{
|
||||||
|
@ -414,17 +407,21 @@ void setSingleDeviceMode()
|
||||||
|
|
||||||
void process_pda_packet_msg_long_set_time(const char *msg)
|
void process_pda_packet_msg_long_set_time(const char *msg)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
// NOT Working at moment, also wrong format
|
// NOT Working at moment, also wrong format
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "process_pda_packet_msg_long_set_temp\n");
|
LOG(PDA_LOG,LOG_DEBUG, "process_pda_packet_msg_long_set_temp\n");
|
||||||
if (msg[4] == '/' && msg[7] == '/'){
|
if (msg[4] == '/' && msg[7] == '/'){
|
||||||
//DATE
|
//DATE
|
||||||
rsm_strncpycut(_aqualink_data->date, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
|
//rsm_strncpycut(_aqualink_data->date, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
|
||||||
|
strncpy(_aqualink_data->date, msg + 11, 3);
|
||||||
} else if (msg[6] == ':' && msg[11] == 'M') {
|
} else if (msg[6] == ':' && msg[11] == 'M') {
|
||||||
// TIME
|
// TIME
|
||||||
rsm_strncpycut(_aqualink_data->time, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
|
//rsm_strncpycut(_aqualink_data->time, msg, AQ_MSGLEN-1, AQ_MSGLEN-1);
|
||||||
|
if (msg[4] == ' ')
|
||||||
|
strncpy(_aqualink_data->time, msg + 5, 6);
|
||||||
|
else
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_pda_packet_msg_long_set_temp(const char *msg)
|
void process_pda_packet_msg_long_set_temp(const char *msg)
|
||||||
|
@ -538,6 +535,25 @@ void process_pda_packet_msg_long_unknown(const char *msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pda_pump_update(struct aqualinkdata *aq_data, int updated) {
|
||||||
|
const int bitmask[MAX_PUMPS] = {1,2,4,8};
|
||||||
|
static unsigned char updates = '\0';
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (updated == -1) {
|
||||||
|
for(i=0; i < MAX_PUMPS; i++) {
|
||||||
|
if ((updates & bitmask[i]) != bitmask[i]) {
|
||||||
|
aq_data->pumps[i].rpm = PUMP_OFF_RPM;
|
||||||
|
aq_data->pumps[i].gpm = PUMP_OFF_GPM;
|
||||||
|
aq_data->pumps[i].watts = PUMP_OFF_WAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updates = '\0';
|
||||||
|
} else if (updated >=0 && updated < MAX_PUMPS) {
|
||||||
|
updates |= bitmask[updated];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void log_pump_information() {
|
void log_pump_information() {
|
||||||
int i;
|
int i;
|
||||||
//bool rtn = false;
|
//bool rtn = false;
|
||||||
|
@ -578,9 +594,10 @@ void log_pump_information() {
|
||||||
|
|
||||||
for (i=0; i < _aqualink_data->num_pumps; i++) {
|
for (i=0; i < _aqualink_data->num_pumps; i++) {
|
||||||
if (_aqualink_data->pumps[i].pumpIndex == pump_index) {
|
if (_aqualink_data->pumps[i].pumpIndex == pump_index) {
|
||||||
|
LOG(PDA_LOG,LOG_INFO, "PDA Pump label: %s Index: %d, ID: %d, RPM: %d, Watts: %d, GPM: %d\n",_aqualink_data->pumps[i].button->name, i ,pump_index,pump_index,rpm,watts,gpm);
|
||||||
//printf("**** FOUND PUMP %d at index %d *****\n",pump_index,i);
|
//printf("**** FOUND PUMP %d at index %d *****\n",pump_index,i);
|
||||||
//aq_data->pumps[i].updated = true;
|
//aq_data->pumps[i].updated = true;
|
||||||
//pump_update(_aqualink_data, i);
|
pda_pump_update(_aqualink_data, i);
|
||||||
_aqualink_data->pumps[i].rpm = rpm;
|
_aqualink_data->pumps[i].rpm = rpm;
|
||||||
_aqualink_data->pumps[i].watts = watts;
|
_aqualink_data->pumps[i].watts = watts;
|
||||||
_aqualink_data->pumps[i].gpm = gpm;
|
_aqualink_data->pumps[i].gpm = gpm;
|
||||||
|
@ -594,27 +611,19 @@ void log_pump_information() {
|
||||||
_aqualink_data->pumps[i].pumpType = EPUMP;
|
_aqualink_data->pumps[i].pumpType = EPUMP;
|
||||||
}
|
}
|
||||||
//printf ("Set Pump Type to %d\n",aq_data->pumps[i].pumpType);
|
//printf ("Set Pump Type to %d\n",aq_data->pumps[i].pumpType);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LOG(PDA_LOG,LOG_ERR, "PDA Could not find config for Pump %s, Index %d, RPM %d, Watts %d, GPM %d\n",m3_line,pump_index,rpm,watts,gpm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lineindex, bool reset)
|
void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lineindex, bool reset)
|
||||||
{
|
{
|
||||||
//pass_pda_equiptment_status_item(msg);
|
LOG(PDA_LOG,LOG_DEBUG, "*** Pass Equiptment msg '%.16s'\n", msg_line);
|
||||||
|
|
||||||
#ifdef NEW_UPDATE_METHOD
|
|
||||||
if (reset) {
|
|
||||||
equiptment_update_cycle(-1);
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "*************** Equiptment reset\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "*************** Pass Equiptment msg '%.16s'\n", msg_line);
|
|
||||||
|
|
||||||
if (msg_line == NULL) {
|
if (msg_line == NULL) {
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "*************** Pass Equiptment msg is NULL do nothing\n");
|
LOG(PDA_LOG,LOG_DEBUG, "*** Pass Equiptment msg is NULL do nothing\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,16 +652,8 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin
|
||||||
// FILTER PUMP
|
// FILTER PUMP
|
||||||
// CLEANER
|
// CLEANER
|
||||||
//
|
//
|
||||||
// Equipment Status
|
|
||||||
//
|
// VSP Pumps are not read here, since they are over multiple lines.
|
||||||
// Intelliflo VS 1
|
|
||||||
// RPM: 1700
|
|
||||||
// Watts: 367
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
// Check message for status of device
|
// Check message for status of device
|
||||||
// Loop through all buttons and match the PDA text.
|
// Loop through all buttons and match the PDA text.
|
||||||
|
@ -678,53 +679,29 @@ void process_pda_packet_msg_long_equiptment_status(const char *msg_line, int lin
|
||||||
_aqualink_data->swg_ppm = atoi(index + strlen(MSG_SWG_PPM));
|
_aqualink_data->swg_ppm = atoi(index + strlen(MSG_SWG_PPM));
|
||||||
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
|
//if (_aqualink_data->ar_swg_status == SWG_STATUS_OFF) {_aqualink_data->ar_swg_status = SWG_STATUS_ON;}
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "SALT = %d\n", _aqualink_data->swg_ppm);
|
LOG(PDA_LOG,LOG_DEBUG, "SALT = %d\n", _aqualink_data->swg_ppm);
|
||||||
}
|
}
|
||||||
else if ((index = rsm_strnstr(msg, MSG_PMP_RPM, AQ_MSGLEN)) != NULL)
|
|
||||||
{ // Default to pump 0, should check for correct pump
|
|
||||||
_aqualink_data->pumps[0].rpm = atoi(index + strlen(MSG_PMP_RPM));
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "RPM = %d\n", _aqualink_data->pumps[0].rpm);
|
|
||||||
log_pump_information();
|
|
||||||
}
|
|
||||||
else if ((index = rsm_strnstr(msg, MSG_PMP_WAT, AQ_MSGLEN)) != NULL)
|
|
||||||
{ // Default to pump 0, should check for correct pump
|
|
||||||
_aqualink_data->pumps[0].watts = atoi(index + strlen(MSG_PMP_WAT));
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Watts = %d\n", _aqualink_data->pumps[0].watts);
|
|
||||||
log_pump_information();
|
|
||||||
}
|
|
||||||
else if ((index = rsm_strnstr(msg, MSG_PMP_GPM, AQ_MSGLEN)) != NULL)
|
|
||||||
{ // Default to pump 0, should check for correct pump
|
|
||||||
_aqualink_data->pumps[0].gpm = atoi(index + strlen(MSG_PMP_GPM));
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "GPM = %d\n", _aqualink_data->pumps[0].gpm);
|
|
||||||
log_pump_information();
|
|
||||||
}
|
|
||||||
else if ((index = rsm_strnstr(msg, "(Offline)", AQ_MSGLEN)) != NULL)
|
|
||||||
{ // Default to pump 0, should check for correct pump
|
|
||||||
//_aqualink_data->pumps[0].gpm = atoi(index + strlen(MSG_PMP_GPM));
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Pump offline\n");
|
|
||||||
log_pump_information();
|
|
||||||
}
|
|
||||||
else if (rsm_strncmp(msg_line, "POOL HEAT ENA",AQ_MSGLEN) == 0)
|
else if (rsm_strncmp(msg_line, "POOL HEAT ENA",AQ_MSGLEN) == 0)
|
||||||
{
|
{
|
||||||
_aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state = ENABLE;
|
_aqualink_data->aqbuttons[_aqualink_data->pool_heater_index].led->state = ENABLE;
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Pool Hearter is enabled\n");
|
LOG(PDA_LOG,LOG_DEBUG, "Pool Hearter is enabled\n");
|
||||||
|
//equiptment_update_cycle(_aqualink_data->pool_heater_index);
|
||||||
}
|
}
|
||||||
else if (rsm_strncmp(msg_line, "SPA HEAT ENA",AQ_MSGLEN) == 0)
|
else if (rsm_strncmp(msg_line, "SPA HEAT ENA",AQ_MSGLEN) == 0)
|
||||||
{
|
{
|
||||||
_aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state = ENABLE;
|
_aqualink_data->aqbuttons[_aqualink_data->spa_heater_index].led->state = ENABLE;
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Pool Hearter is enabled\n");
|
LOG(PDA_LOG,LOG_DEBUG, "Spa Hearter is enabled\n");
|
||||||
|
//equiptment_update_cycle(_aqualink_data->spa_heater_index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < _aqualink_data->total_buttons; i++)
|
for (i = 0; i < _aqualink_data->total_buttons; i++)
|
||||||
{
|
{
|
||||||
//LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%s' against '%s'\n",labelBuff,_aqualink_data->aqbuttons[i].label);
|
//LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%s' against '%s'\n",labelBuff,_aqualink_data->aqbuttons[i].label);
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%.*s' against '%s'\n",AQ_MSGLEN,msg_line,_aqualink_data->aqbuttons[i].label);
|
//LOG(PDA_LOG,LOG_DEBUG, "*** check msg '%.*s' against '%s'\n",AQ_MSGLEN,msg_line,_aqualink_data->aqbuttons[i].label);
|
||||||
if (rsm_strncmp(msg_line, _aqualink_data->aqbuttons[i].label, AQ_MSGLEN-1) == 0)
|
if (rsm_strncmp(msg_line, _aqualink_data->aqbuttons[i].label, AQ_MSGLEN-1) == 0)
|
||||||
//if (rsm_strcmp(_aqualink_data->aqbuttons[i].label, labelBuff) == 0)
|
//if (rsm_strcmp(_aqualink_data->aqbuttons[i].label, labelBuff) == 0)
|
||||||
{
|
{
|
||||||
#ifdef NEW_UPDATE_METHOD
|
|
||||||
equiptment_update_cycle(i);
|
equiptment_update_cycle(i);
|
||||||
#endif
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Found Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg_line);
|
LOG(PDA_LOG,LOG_DEBUG, "Found Status for %s = '%.*s'\n", _aqualink_data->aqbuttons[i].label, AQ_MSGLEN, msg_line);
|
||||||
// It's on (or delayed) if it's listed here.
|
// It's on (or delayed) if it's listed here.
|
||||||
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
|
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
|
||||||
|
@ -808,211 +785,138 @@ bool process_pda_packet(unsigned char *packet, int length)
|
||||||
//int i;
|
//int i;
|
||||||
char *msg;
|
char *msg;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
static bool equiptment_updated = false;
|
static bool equiptment_update_loop = false;
|
||||||
//static bool init = false;
|
static bool read_equiptment_menu = false;
|
||||||
|
|
||||||
if (getLogLevel(PDA_LOG) == LOG_DEBUG) {
|
|
||||||
char buff[1024];
|
|
||||||
beautifyPacket(buff, packet, length, true);
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "%s", buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
process_pda_menu_packet(packet, length, in_programming_mode(_aqualink_data));
|
||||||
// Some panels don't give the startup messages we used to key the init sequence, so check here
|
|
||||||
// need to put this in a better spot some time in the future
|
|
||||||
if (_initWithRS == false && pda_m_type() == PM_FW_VERSION && packet[PKT_CMD] == CMD_PDA_CLEAR ) {
|
|
||||||
_initWithRS == true;
|
|
||||||
queueGetProgramData(AQUAPDA, _aqualink_data);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
process_pda_menu_packet(packet, length);
|
|
||||||
|
|
||||||
// NSF.
|
|
||||||
|
|
||||||
//_aqualink_data->last_msg_was_status = false;
|
|
||||||
|
|
||||||
// debugPacketPrint(0x00, packet, length);
|
|
||||||
|
|
||||||
switch (packet[PKT_CMD])
|
switch (packet[PKT_CMD])
|
||||||
{
|
{
|
||||||
|
case CMD_ACK:
|
||||||
case CMD_ACK:
|
LOG(PDA_LOG,LOG_DEBUG, "RS Received ACK length %d.\n", length);
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "RS Received ACK length %d.\n", length);
|
|
||||||
//if (init == false)
|
|
||||||
/*
|
|
||||||
if (_initWithRS == false)
|
|
||||||
{
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Running PDA_INIT\n");
|
|
||||||
aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
|
||||||
//init = true;
|
|
||||||
}*/
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_STATUS:
|
case CMD_PDA_CLEAR:
|
||||||
_aqualink_data->last_display_message[0] = '\0';
|
read_equiptment_menu = false; // Reset the have read menu flag, since this is new menu.
|
||||||
if (equiptment_updated == true && pda_m_type() != PM_EQUIPTMENT_STATUS)
|
break;
|
||||||
{
|
|
||||||
process_pda_packet_msg_long_equiptment_status(NULL, 0, true);
|
|
||||||
equiptment_updated = false;
|
|
||||||
} else if (_initWithRS == false && pda_m_type() == PM_FW_VERSION) {
|
|
||||||
_initWithRS = true;
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "**** PDA INIT ****\n");
|
|
||||||
//aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
|
||||||
queueGetProgramData(AQUAPDA, _aqualink_data);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// If we get a status packet, and we are on the status menu, this is a list of what's on
|
|
||||||
// or pending so unless flash turn everything off, and just turn on items that are listed.
|
|
||||||
// This is the only way to update a device that's been turned off by a real PDA / keypad.
|
|
||||||
// Note: if the last line of the status menu is present it may be cut off
|
|
||||||
if (pda_m_type() == PM_EQUIPTMENT_STATUS)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (_aqualink_data->frz_protect_state == ON)
|
case CMD_STATUS:
|
||||||
_aqualink_data->frz_protect_state = ENABLE;
|
_aqualink_data->last_display_message[0] = '\0';
|
||||||
|
if (equiptment_update_loop == false && pda_m_type() == PM_EQUIPTMENT_STATUS)
|
||||||
//if (_aqualink_data->ar_swg_status == SWG_STATUS_ON)
|
|
||||||
// _aqualink_data->ar_swg_status = SWG_STATUS_OFF;
|
|
||||||
|
|
||||||
if (_aqualink_data->swg_led_state == ON)
|
|
||||||
setSWGenabled(_aqualink_data);
|
|
||||||
|
|
||||||
// Need to remove this when new way works.
|
|
||||||
#ifndef NEW_UPDATE_METHOD
|
|
||||||
if (pda_m_line(PDA_LINES - 1)[0] == '\0')
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < _aqualink_data->total_buttons; i++)
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA Start new Equiptment loop ****\n");
|
||||||
{
|
equiptment_update_loop = true;
|
||||||
if (_aqualink_data->aqbuttons[i].led->state != FLASH)
|
// Need to process the equiptment full MENU here
|
||||||
{
|
|
||||||
_aqualink_data->aqbuttons[i].led->state = OFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (read_equiptment_menu == false && equiptment_update_loop == true && pda_m_type() == PM_EQUIPTMENT_STATUS)
|
||||||
{
|
{
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "PDA Equipment status may be truncated.\n");
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA read Equiptment page ****\n");
|
||||||
|
log_pump_information();
|
||||||
|
read_equiptment_menu = true;
|
||||||
}
|
}
|
||||||
|
else if (equiptment_update_loop == true && pda_m_type() != PM_EQUIPTMENT_STATUS)
|
||||||
|
{
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA End Equiptment loop ****\n");
|
||||||
|
// Moved onto different MENU. Probably need to update any pump changes
|
||||||
|
equiptment_update_loop = false;
|
||||||
|
|
||||||
for (i = 1; i < PDA_LINES; i++)
|
// End of equiptment status chain of menus, reset any pump or equiptment that wasn't listed in menus as long as we are not in programming mode
|
||||||
pass_pda_equiptment_status_item(pda_m_line(i));
|
if (!in_programming_mode(_aqualink_data) ) {
|
||||||
#else
|
pda_pump_update(_aqualink_data, -1);
|
||||||
if (!equiptment_updated) {
|
equiptment_update_cycle(-1);
|
||||||
equiptment_updated = true;
|
|
||||||
for (i = 1; i < PDA_LINES; i++) {
|
|
||||||
pass_pda_equiptment_status_item(pda_m_line(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
else if (_initWithRS == false && pda_m_type() == PM_FW_VERSION)
|
||||||
}
|
|
||||||
if (pda_m_type() == PM_FREEZE_PROTECT_DEVICES)
|
|
||||||
{
|
|
||||||
process_pda_freeze_protect_devices();
|
|
||||||
}*/
|
|
||||||
break;
|
|
||||||
case CMD_MSG_LONG:
|
|
||||||
{
|
|
||||||
//printf ("*******************************************************************************************\n");
|
|
||||||
//printf ("menu type %d\n",pda_m_type());
|
|
||||||
|
|
||||||
msg = (char *)packet + PKT_DATA + 1;
|
|
||||||
index = packet[PKT_DATA] & 0xF;
|
|
||||||
|
|
||||||
//strcpy(_aqualink_data->last_message, msg);
|
|
||||||
|
|
||||||
if (packet[PKT_DATA] == 0x82)
|
|
||||||
{ // Air & Water temp is always this ID
|
|
||||||
process_pda_packet_msg_long_temp(msg);
|
|
||||||
#ifdef NEW_UPDATE_METHOD
|
|
||||||
// if (!equiptment_updated) {
|
|
||||||
// equiptment_update_cycle(-1); // Reset equiptment cycle
|
|
||||||
// equiptment_updated = false;
|
|
||||||
// }
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (packet[PKT_DATA] == 0x40)
|
|
||||||
{ // Time is always on this ID
|
|
||||||
process_pda_packet_msg_long_time(msg);
|
|
||||||
// If it wasn't a specific msg, (above) then run through and see what kind
|
|
||||||
// of message it is depending on the PDA menu. Note don't process EQUIPTMENT
|
|
||||||
// STATUS menu here, wait until a CMD_STATUS is received.
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (pda_m_type()) {
|
|
||||||
case PM_EQUIPTMENT_CONTROL:
|
|
||||||
process_pda_packet_msg_long_equipment_control(msg);
|
|
||||||
break;
|
|
||||||
case PM_HOME:
|
|
||||||
case PM_BUILDING_HOME:
|
|
||||||
process_pda_packet_msg_long_home(msg);
|
|
||||||
break;
|
|
||||||
case PM_EQUIPTMENT_STATUS:
|
|
||||||
process_pda_packet_msg_long_equiptment_status(msg, index, false);
|
|
||||||
equiptment_updated = true;
|
|
||||||
break;
|
|
||||||
case PM_SET_TEMP:
|
|
||||||
process_pda_packet_msg_long_set_temp(msg);
|
|
||||||
break;
|
|
||||||
case PM_SPA_HEAT:
|
|
||||||
process_pda_packet_msg_long_spa_heat(msg);
|
|
||||||
break;
|
|
||||||
case PM_POOL_HEAT:
|
|
||||||
process_pda_packet_msg_long_pool_heat(msg);
|
|
||||||
break;
|
|
||||||
case PM_FREEZE_PROTECT:
|
|
||||||
process_pda_packet_msg_long_freeze_protect(msg);
|
|
||||||
break;
|
|
||||||
case PM_AQUAPURE:
|
|
||||||
process_pda_packet_msg_long_SWG(msg);
|
|
||||||
break;
|
|
||||||
case PM_AUX_LABEL_DEVICE:
|
|
||||||
process_pda_packet_msg_long_level_aux_device(msg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PM_SET_TIME:
|
|
||||||
process_pda_packet_msg_long_set_time(msg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//case PM_FW_VERSION:
|
|
||||||
// process_pda_packet_msg_long_FW_version(msg);
|
|
||||||
//break;
|
|
||||||
case PM_UNKNOWN:
|
|
||||||
default:
|
|
||||||
process_pda_packet_msg_long_unknown(msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("** Line index='%d' Highligh='%s' Message='%.*s'\n",pda_m_hlightindex(), pda_m_hlight(), AQ_MSGLEN, msg);
|
|
||||||
LOG(PDA_LOG,LOG_INFO, "PDA Menu '%d' Selectedline '%s', Last line received '%.*s'\n", pda_m_type(), pda_m_hlight(), AQ_MSGLEN, msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CMD_PDA_0x1B:
|
|
||||||
{
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "**** CMD_PDA_0x1B ****\n");
|
|
||||||
// We get two of these on startup, one with 0x00 another with 0x01 at index 4. Just act on one.
|
|
||||||
// Think this is PDA finishd showing startup screen
|
|
||||||
if (packet[4] == 0x00) {
|
|
||||||
if (_initWithRS == false)
|
|
||||||
{
|
{
|
||||||
_initWithRS = true;
|
_initWithRS = true;
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "**** PDA INIT ****\n");
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA INIT ****\n");
|
||||||
//aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
//printf("**** PDA INIT PUT BACK IN ****\n");
|
||||||
queueGetProgramData(AQUAPDA, _aqualink_data);
|
queueGetProgramData(AQUAPDA, _aqualink_data);
|
||||||
delay(50); // Make sure this one runs first.
|
|
||||||
#ifdef BETA_PDA_AUTOLABEL
|
|
||||||
if (_aqconfig_->use_panel_aux_labels)
|
|
||||||
aq_programmer(AQ_GET_AUX_LABELS, NULL, _aqualink_data);
|
|
||||||
#endif
|
|
||||||
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
|
||||||
} else {
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "**** PDA WAKE INIT ****\n");
|
|
||||||
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
break;
|
case CMD_MSG_LONG:
|
||||||
|
msg = (char *)packet + PKT_DATA + 1;
|
||||||
|
index = packet[PKT_DATA] & 0xF;
|
||||||
|
if (packet[PKT_DATA] == 0x82)
|
||||||
|
{ // Air & Water temp is always this ID
|
||||||
|
process_pda_packet_msg_long_temp(msg);
|
||||||
|
}
|
||||||
|
else if (packet[PKT_DATA] == 0x40)
|
||||||
|
{ // Time is always on this ID
|
||||||
|
process_pda_packet_msg_long_time(msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pda_m_type())
|
||||||
|
{
|
||||||
|
case PM_EQUIPTMENT_CONTROL:
|
||||||
|
process_pda_packet_msg_long_equipment_control(msg);
|
||||||
|
break;
|
||||||
|
case PM_HOME:
|
||||||
|
case PM_BUILDING_HOME:
|
||||||
|
process_pda_packet_msg_long_home(msg);
|
||||||
|
break;
|
||||||
|
case PM_EQUIPTMENT_STATUS:
|
||||||
|
process_pda_packet_msg_long_equiptment_status(msg, index, false);
|
||||||
|
break;
|
||||||
|
case PM_SET_TEMP:
|
||||||
|
process_pda_packet_msg_long_set_temp(msg);
|
||||||
|
break;
|
||||||
|
case PM_SPA_HEAT:
|
||||||
|
process_pda_packet_msg_long_spa_heat(msg);
|
||||||
|
break;
|
||||||
|
case PM_POOL_HEAT:
|
||||||
|
process_pda_packet_msg_long_pool_heat(msg);
|
||||||
|
break;
|
||||||
|
case PM_FREEZE_PROTECT:
|
||||||
|
process_pda_packet_msg_long_freeze_protect(msg);
|
||||||
|
break;
|
||||||
|
case PM_AQUAPURE:
|
||||||
|
process_pda_packet_msg_long_SWG(msg);
|
||||||
|
break;
|
||||||
|
case PM_AUX_LABEL_DEVICE:
|
||||||
|
process_pda_packet_msg_long_level_aux_device(msg);
|
||||||
|
break;
|
||||||
|
case PM_SET_TIME:
|
||||||
|
process_pda_packet_msg_long_set_time(msg);
|
||||||
|
break;
|
||||||
|
//case PM_FW_VERSION:
|
||||||
|
// process_pda_packet_msg_long_FW_version(msg);
|
||||||
|
//break;
|
||||||
|
case PM_UNKNOWN:
|
||||||
|
default:
|
||||||
|
process_pda_packet_msg_long_unknown(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_PDA_0x1B:
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "**** CMD_PDA_0x1B ****\n");
|
||||||
|
// We get two of these on startup, one with 0x00 another with 0x01 at index 4. Just act on one.
|
||||||
|
// Think this is PDA finishd showing startup screen
|
||||||
|
if (packet[4] == 0x00) {
|
||||||
|
if (_initWithRS == false)
|
||||||
|
{
|
||||||
|
_initWithRS = true;
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA INIT ****\n");
|
||||||
|
//aq_programmer(AQ_PDA_INIT, NULL, _aqualink_data);
|
||||||
|
queueGetProgramData(AQUAPDA, _aqualink_data);
|
||||||
|
delay(50); // Make sure this one runs first.
|
||||||
|
#ifdef BETA_PDA_AUTOLABEL
|
||||||
|
if (_aqconfig_->use_panel_aux_labels)
|
||||||
|
aq_programmer(AQ_GET_AUX_LABELS, NULL, _aqualink_data);
|
||||||
|
#endif
|
||||||
|
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
||||||
|
} else {
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "**** PDA WAKE INIT ****\n");
|
||||||
|
aq_programmer(AQ_PDA_WAKE_INIT, NULL, _aqualink_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet[PKT_CMD] == CMD_MSG_LONG || packet[PKT_CMD] == CMD_PDA_HIGHLIGHT ||
|
if (packet[PKT_CMD] == CMD_MSG_LONG || packet[PKT_CMD] == CMD_PDA_HIGHLIGHT ||
|
||||||
|
@ -1022,8 +926,14 @@ bool process_pda_packet(unsigned char *packet, int length)
|
||||||
// We processed the next message, kick any threads waiting on the message.
|
// We processed the next message, kick any threads waiting on the message.
|
||||||
kick_aq_program_thread(_aqualink_data, AQUAPDA);
|
kick_aq_program_thread(_aqualink_data, AQUAPDA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HERE AS A TEST. NEED TO FULLY TEST THIS IS GOES TO PROD.
|
||||||
|
else if (packet[PKT_CMD] == CMD_STATUS)
|
||||||
|
{
|
||||||
|
kick_aq_program_thread(_aqualink_data, AQUAPDA);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "pda_aq_programmer.h"
|
#include "pda_aq_programmer.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "aq_panel.h"
|
#include "aq_panel.h"
|
||||||
|
#include "rs_msg_utils.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef AQ_DEBUG
|
#ifdef AQ_DEBUG
|
||||||
|
@ -123,7 +124,8 @@ bool wait_pda_selected_item(struct aqualinkdata *aq_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waitForPDAnextMenu(struct aqualinkdata *aq_data) {
|
bool waitForPDAnextMenu(struct aqualinkdata *aq_data) {
|
||||||
waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10);
|
if (!waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10))
|
||||||
|
return false;
|
||||||
return waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
return waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,10 +252,12 @@ bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charli
|
||||||
if ((min_index != -1) && ((index - i) > (i - min_index + max_index - index + 1))) {
|
if ((min_index != -1) && ((index - i) > (i - min_index + max_index - index + 1))) {
|
||||||
cnt = i - min_index + max_index - index + 1;
|
cnt = i - min_index + max_index - index + 1;
|
||||||
for (i=0; i < cnt; i++) {
|
for (i=0; i < cnt; i++) {
|
||||||
|
waitfor_queue2empty();
|
||||||
send_cmd(KEY_PDA_UP);
|
send_cmd(KEY_PDA_UP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i=pda_m_hlightindex(); i < index; i++) {
|
for (i=pda_m_hlightindex(); i < index; i++) {
|
||||||
|
waitfor_queue2empty();
|
||||||
send_cmd(KEY_PDA_DOWN);
|
send_cmd(KEY_PDA_DOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,10 +265,12 @@ bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charli
|
||||||
if ((min_index != -1) && ((i - index) > (index - min_index + max_index - i + 1))) {
|
if ((min_index != -1) && ((i - index) > (index - min_index + max_index - i + 1))) {
|
||||||
cnt = i - min_index + max_index - index + 1;
|
cnt = i - min_index + max_index - index + 1;
|
||||||
for (i=0; i < cnt; i++) {
|
for (i=0; i < cnt; i++) {
|
||||||
|
waitfor_queue2empty();
|
||||||
send_cmd(KEY_PDA_UP);
|
send_cmd(KEY_PDA_UP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i=pda_m_hlightindex(); i > index; i--) {
|
for (i=pda_m_hlightindex(); i > index; i--) {
|
||||||
|
waitfor_queue2empty();
|
||||||
send_cmd(KEY_PDA_UP);
|
send_cmd(KEY_PDA_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +297,7 @@ bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wa
|
||||||
|
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "PDA Device programmer selected menu item '%s'\n",menuText);
|
LOG(PDA_LOG,LOG_DEBUG, "PDA Device programmer selected menu item '%s'\n",menuText);
|
||||||
if (waitForNextMenu)
|
if (waitForNextMenu)
|
||||||
waitForPDAnextMenu(aq_data);
|
return waitForPDAnextMenu(aq_data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -306,6 +312,7 @@ bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wa
|
||||||
// https://www.jandy.com/-/media/zodiac/global/downloads/h/h0574200.pdf
|
// https://www.jandy.com/-/media/zodiac/global/downloads/h/h0574200.pdf
|
||||||
// and 6594 - AquaLink RS Control Panel Installation Manual
|
// and 6594 - AquaLink RS Control Panel Installation Manual
|
||||||
// https://www.jandy.com/-/media/zodiac/global/downloads/0748-91071/6594.pdf
|
// https://www.jandy.com/-/media/zodiac/global/downloads/0748-91071/6594.pdf
|
||||||
|
|
||||||
bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
@ -600,8 +607,10 @@ void *set_aqualink_PDA_init( void *ptr )
|
||||||
//printf("****** Version '%s' ********\n",aq_data->version);
|
//printf("****** Version '%s' ********\n",aq_data->version);
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "PDA type=%d, version=%s\n", _PDA_Type, aq_data->version);
|
LOG(PDA_LOG,LOG_DEBUG, "PDA type=%d, version=%s\n", _PDA_Type, aq_data->version);
|
||||||
// don't wait for version menu to time out press back to get to home menu faster
|
// don't wait for version menu to time out press back to get to home menu faster
|
||||||
send_cmd(KEY_PDA_BACK);
|
//send_cmd(KEY_PDA_BACK);
|
||||||
if (! waitForPDAnextMenu(aq_data)) {
|
//if (! waitForPDAnextMenu(aq_data)) { // waitForPDAnextMenu waits for highlight chars, which we don't get on normal menu
|
||||||
|
|
||||||
|
if (! waitForPDAMessageType(aq_data,CMD_PDA_CLEAR,10)) {
|
||||||
LOG(PDA_LOG,LOG_ERR, "PDA Init :- wait for next menu failed\n");
|
LOG(PDA_LOG,LOG_ERR, "PDA Init :- wait for next menu failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,6 +635,8 @@ void *set_aqualink_PDA_init( void *ptr )
|
||||||
|
|
||||||
pda_reset_sleep();
|
pda_reset_sleep();
|
||||||
|
|
||||||
|
goto_pda_menu(aq_data, PM_HOME);
|
||||||
|
|
||||||
cleanAndTerminateThread(threadCtrl);
|
cleanAndTerminateThread(threadCtrl);
|
||||||
|
|
||||||
// just stop compiler error, ptr is not valid as it's just been freed
|
// just stop compiler error, ptr is not valid as it's just been freed
|
||||||
|
@ -678,7 +689,11 @@ bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data) {
|
||||||
|
|
||||||
// Get heater setpoints
|
// Get heater setpoints
|
||||||
if (! goto_pda_menu(aq_data, PM_SET_TEMP)) {
|
if (! goto_pda_menu(aq_data, PM_SET_TEMP)) {
|
||||||
return false;
|
LOG(PDA_LOG,LOG_ERR, "Could not get heater setpoints, trying again!\n");
|
||||||
|
// Going to try this twice.
|
||||||
|
if (! goto_pda_menu(aq_data, PM_SET_TEMP)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -715,19 +730,23 @@ bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived)
|
bool _waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived, bool forceNext)
|
||||||
{
|
{
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx\n",mtype);
|
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx\n",mtype);
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
pthread_mutex_lock(&aq_data->active_thread.thread_mutex);
|
pthread_mutex_lock(&aq_data->active_thread.thread_mutex);
|
||||||
|
|
||||||
|
if (forceNext) { // Ignore current message type, and wait for next
|
||||||
|
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
while( ++i <= numMessageReceived)
|
while( ++i <= numMessageReceived)
|
||||||
{
|
{
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype,aq_data->last_packet_type,i,numMessageReceived);
|
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageType 0x%02hhx, last message type was 0x%02hhx (%d of %d)\n",mtype,aq_data->last_packet_type,i,numMessageReceived);
|
||||||
|
|
||||||
if (aq_data->last_packet_type == mtype) break;
|
if (aq_data->last_packet_type == mtype) break;
|
||||||
|
|
||||||
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
|
pthread_cond_wait(&aq_data->active_thread.thread_cond, &aq_data->active_thread.thread_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,6 +762,16 @@ bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, in
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool waitForPDAMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived){
|
||||||
|
return _waitForPDAMessageType(aq_data, mtype, numMessageReceived, false);
|
||||||
|
}
|
||||||
|
bool waitForPDANextMessageType(struct aqualinkdata *aq_data, unsigned char mtype, int numMessageReceived){
|
||||||
|
return _waitForPDAMessageType(aq_data, mtype, numMessageReceived, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Wait for Message, hit return on particular menu.
|
// Wait for Message, hit return on particular menu.
|
||||||
bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line)
|
bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mtype1, unsigned char mtype2, int numMessageReceived, char *text, int line)
|
||||||
{
|
{
|
||||||
|
@ -785,6 +814,10 @@ bool waitForPDAMessageTypes(struct aqualinkdata *aq_data, unsigned char mtype1,
|
||||||
return waitForPDAMessageTypesOrMenu(aq_data, mtype1, mtype2, numMessageReceived, NULL, 0);
|
return waitForPDAMessageTypesOrMenu(aq_data, mtype1, mtype2, numMessageReceived, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use -1 for cur_val if you want this to find the delected value and change it.
|
||||||
|
Use number for cur_val to increase / decrease from known start point
|
||||||
|
*/
|
||||||
bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_val, char *select_label, int step) {
|
bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_val, char *select_label, int step) {
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
|
@ -792,19 +825,43 @@ bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_
|
||||||
// :TODO: Should probably change below to call find_pda_menu_item(), rather than doing it here
|
// :TODO: Should probably change below to call find_pda_menu_item(), rather than doing it here
|
||||||
// If we lease this, need to limit on the number of loops
|
// If we lease this, need to limit on the number of loops
|
||||||
//while ( strncasecmp(pda_m_hlight(), select_label, 8) != 0 ) {
|
//while ( strncasecmp(pda_m_hlight(), select_label, 8) != 0 ) {
|
||||||
while ( strncasecmp(pda_m_hlight(), select_label, strlen(select_label)) != 0 ) {
|
//while ( strncasecmp(pda_m_hlight(), select_label, strlen(select_label)) != 0 ) {
|
||||||
|
while ( rsm_strncmp(pda_m_hlight(), select_label, strlen(select_label)) != 0 ) {
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector selecting '%s' current selection '%s'\n", select_label, pda_m_hlight());
|
||||||
send_cmd(KEY_PDA_DOWN);
|
send_cmd(KEY_PDA_DOWN);
|
||||||
delay(500); // Last message probably was CMD_PDA_HIGHLIGHT, so wait before checking.
|
//delay(500); // Last message probably was CMD_PDA_HIGHLIGHT, so wait before checking.
|
||||||
waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,2);
|
waitfor_queue2empty();
|
||||||
|
waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,5);
|
||||||
if (i > 10) {
|
if (i > 10) {
|
||||||
LOG(PDA_LOG,LOG_ERR, "Numeric selector could not find string '%s'\n", select_label);
|
LOG(PDA_LOG,LOG_ERR, "Numeric selector could not find string '%s'\n", select_label);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector, selecting '%s'\n", pda_m_hlight());
|
||||||
send_cmd(KEY_PDA_SELECT);
|
send_cmd(KEY_PDA_SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cur_val == -1) {
|
||||||
|
char *hghlight_chars;
|
||||||
|
int hlight_length=0;
|
||||||
|
int i=0;
|
||||||
|
//hghlight_chars = pda_m_hlightchars(&hlight_length);
|
||||||
|
while (hlight_length >= 15 || hlight_length <= 0) {
|
||||||
|
delay(500);
|
||||||
|
waitForPDANextMessageType(aq_data,CMD_PDA_HIGHLIGHTCHARS,5);
|
||||||
|
hghlight_chars = pda_m_hlightchars(&hlight_length);
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector, highlight chars '%.*s'\n",hlight_length , hghlight_chars);
|
||||||
|
if (++i >= 20) {
|
||||||
|
LOG(PDA_LOG,LOG_ERR, "Numeric selector, didn't find highlight chars, current selection is '%.*s'\n",hlight_length , hghlight_chars);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_val = atoi(hghlight_chars);
|
||||||
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector, highlight chars '%.*s', numeric value using %d\n",hlight_length , hghlight_chars, cur_val);
|
||||||
|
}
|
||||||
|
|
||||||
if (val < cur_val) {
|
if (val < cur_val) {
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : lower from %d to %d\n", select_label, cur_val, val);
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : lower from %d to %d\n", select_label, cur_val, val);
|
||||||
for (i = cur_val; i > val; i=i-step) {
|
for (i = cur_val; i > val; i=i-step) {
|
||||||
|
@ -816,7 +873,7 @@ bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_
|
||||||
send_cmd(KEY_PDA_UP);
|
send_cmd(KEY_PDA_UP);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(PDA_LOG,LOG_INFO, "Numeric selector %s value : already at %d\n", select_label, val);
|
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : already at %d\n", select_label, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_cmd(KEY_PDA_SELECT);
|
send_cmd(KEY_PDA_SELECT);
|
||||||
|
@ -829,12 +886,15 @@ bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val) {
|
||||||
|
|
||||||
if (! goto_pda_menu(aq_data, PM_AQUAPURE)) {
|
if (! goto_pda_menu(aq_data, PM_AQUAPURE)) {
|
||||||
LOG(PDA_LOG,LOG_ERR, "Error finding SWG setpoints menu\n");
|
LOG(PDA_LOG,LOG_ERR, "Error finding SWG setpoints menu\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF)
|
if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) {
|
||||||
return set_PDA_numeric_field_value(aq_data, val, aq_data->swg_percent, "SET SPA", 5);
|
//int cur_val = atoi
|
||||||
else
|
return set_PDA_numeric_field_value(aq_data, val, -1, "SET SPA", 5);
|
||||||
return set_PDA_numeric_field_value(aq_data, val, aq_data->swg_percent, "SET POOL", 5);
|
} else {
|
||||||
|
return set_PDA_numeric_field_value(aq_data, val, -1, "SET POOL", 5);
|
||||||
|
}
|
||||||
|
|
||||||
//return true;
|
//return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,14 @@ bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data);
|
||||||
bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val);
|
bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val);
|
||||||
bool set_PDA_aqualink_time(struct aqualinkdata *aq_data);
|
bool set_PDA_aqualink_time(struct aqualinkdata *aq_data);
|
||||||
|
|
||||||
|
|
||||||
|
// These are from aq_programmer.c , exposed here for PDA AQ PROGRAMMER
|
||||||
|
void send_cmd(unsigned char cmd);
|
||||||
|
bool push_aq_cmd(unsigned char cmd);
|
||||||
|
bool waitForMessage(struct aqualinkdata *aq_data, char* message, int numMessageReceived);
|
||||||
|
void waitfor_queue2empty();
|
||||||
|
void longwaitfor_queue2empty();
|
||||||
|
|
||||||
//void pda_programming_thread_check(struct aqualinkdata *aq_data);
|
//void pda_programming_thread_check(struct aqualinkdata *aq_data);
|
||||||
|
|
||||||
#endif // AQ_PDA_PROGRAMMER_H_
|
#endif // AQ_PDA_PROGRAMMER_H_
|
30
pda_menu.c
30
pda_menu.c
|
@ -44,7 +44,7 @@ void print_menu()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_hlightcharindexstart > -1) {
|
if (_hlightcharindexstart > -1) {
|
||||||
LOG(PDA_LOG,LOG_DEBUG, "PDA Menu highlighted characters numer=%d start=%d end=%d actual='%.*s'\n",(_hlightcharindexstop-_hlightcharindexstart),_hlightcharindexstart,_hlightcharindexstop,(_hlightcharindexstop-_hlightcharindexstart),&_menu[_hlightindex][_hlightcharindexstart+1]);
|
LOG(PDA_LOG,LOG_DEBUG, "PDA Menu highlighted characters line#=%d numer=%d start=%d end=%d actual='%.*s'\n",_hlightindex,(_hlightcharindexstop-_hlightcharindexstart),_hlightcharindexstart,_hlightcharindexstop,(_hlightcharindexstop-_hlightcharindexstart),&_menu[_hlightindex][_hlightcharindexstart+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,11 @@ char *pda_m_line(int index)
|
||||||
|
|
||||||
char *pda_m_hlightchars(int *len)
|
char *pda_m_hlightchars(int *len)
|
||||||
{
|
{
|
||||||
*len = _hlightcharindexstop - _hlightcharindexstart + 1;
|
if (_hlightindex <= -1) {
|
||||||
|
*len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*len = _hlightcharindexstop - _hlightcharindexstart;
|
||||||
return &_menu[_hlightindex][_hlightcharindexstart];
|
return &_menu[_hlightindex][_hlightcharindexstart];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +200,7 @@ Line 0 = EQUIPMENT
|
||||||
(Line 0 is first. Highlight when complete)
|
(Line 0 is first. Highlight when complete)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool process_pda_menu_packet(unsigned char* packet, int length)
|
bool process_pda_menu_packet(unsigned char* packet, int length, bool force_print_menu)
|
||||||
{
|
{
|
||||||
bool rtn = true;
|
bool rtn = true;
|
||||||
signed char first_line;
|
signed char first_line;
|
||||||
|
@ -204,6 +208,7 @@ bool process_pda_menu_packet(unsigned char* packet, int length)
|
||||||
signed char line_shift;
|
signed char line_shift;
|
||||||
signed char i;
|
signed char i;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
static bool printed_page = false;
|
||||||
|
|
||||||
|
|
||||||
switch (packet[PKT_CMD]) {
|
switch (packet[PKT_CMD]) {
|
||||||
|
@ -212,6 +217,13 @@ bool process_pda_menu_packet(unsigned char* packet, int length)
|
||||||
_hlightcharindexstart = -1;
|
_hlightcharindexstart = -1;
|
||||||
_hlightcharindexstop = -1;
|
_hlightcharindexstop = -1;
|
||||||
memset(_menu, 0, PDA_LINES * (AQ_MSGLEN+1));
|
memset(_menu, 0, PDA_LINES * (AQ_MSGLEN+1));
|
||||||
|
printed_page = false;
|
||||||
|
break;
|
||||||
|
case CMD_STATUS:
|
||||||
|
if ( printed_page == false && (getLogLevel(PDA_LOG) >= LOG_DEBUG)){
|
||||||
|
print_menu();
|
||||||
|
printed_page = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_MSG_LONG:
|
case CMD_MSG_LONG:
|
||||||
/*
|
/*
|
||||||
|
@ -226,7 +238,7 @@ bool process_pda_menu_packet(unsigned char* packet, int length)
|
||||||
strncpy(_menu[index], (char*)packet+PKT_DATA+1, AQ_MSGLEN);
|
strncpy(_menu[index], (char*)packet+PKT_DATA+1, AQ_MSGLEN);
|
||||||
_menu[index][AQ_MSGLEN] = '\0';
|
_menu[index][AQ_MSGLEN] = '\0';
|
||||||
}
|
}
|
||||||
if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();}
|
if (getLogLevel(PDA_LOG) >= LOG_DEBUG && force_print_menu ){print_menu();}
|
||||||
break;
|
break;
|
||||||
case CMD_PDA_HIGHLIGHT:
|
case CMD_PDA_HIGHLIGHT:
|
||||||
// when switching from hlight to hlightchars index 255 is sent to turn off hlight
|
// when switching from hlight to hlightchars index 255 is sent to turn off hlight
|
||||||
|
@ -236,10 +248,11 @@ bool process_pda_menu_packet(unsigned char* packet, int length)
|
||||||
_hlightcharindexstop = -1;
|
_hlightcharindexstop = -1;
|
||||||
} else {
|
} else {
|
||||||
_hlightindex = -1;
|
_hlightindex = -1;
|
||||||
_hlightcharindexstart = -1;
|
_hlightcharindexstart = -1;
|
||||||
_hlightcharindexstop = -1;
|
_hlightcharindexstop = -1;
|
||||||
}
|
}
|
||||||
if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();}
|
//if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();}
|
||||||
|
if (getLogLevel(PDA_LOG) >= LOG_DEBUG && force_print_menu ){print_menu();}
|
||||||
break;
|
break;
|
||||||
case CMD_PDA_HIGHLIGHTCHARS:
|
case CMD_PDA_HIGHLIGHTCHARS:
|
||||||
// pkt[4] = line, pkt[5] = startchar, pkt[6] = endchar, pkt[7] = clr/inv
|
// pkt[4] = line, pkt[5] = startchar, pkt[6] = endchar, pkt[7] = clr/inv
|
||||||
|
@ -253,13 +266,16 @@ bool process_pda_menu_packet(unsigned char* packet, int length)
|
||||||
// https://github.com/ballle98/AqualinkD/issues/46
|
// https://github.com/ballle98/AqualinkD/issues/46
|
||||||
// Character highlight should not update highlight index
|
// Character highlight should not update highlight index
|
||||||
if (packet[4] <= PDA_LINES) {
|
if (packet[4] <= PDA_LINES) {
|
||||||
|
_hlightindex = packet[4];
|
||||||
_hlightcharindexstart = packet[5];
|
_hlightcharindexstart = packet[5];
|
||||||
_hlightcharindexstop = packet[6];
|
_hlightcharindexstop = packet[6];
|
||||||
} else {
|
} else {
|
||||||
|
_hlightindex = -1;
|
||||||
_hlightcharindexstart = -1;
|
_hlightcharindexstart = -1;
|
||||||
_hlightcharindexstop = -1;
|
_hlightcharindexstop = -1;
|
||||||
}
|
}
|
||||||
if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();}
|
//if (getLogLevel(PDA_LOG) >= LOG_DEBUG){print_menu();}
|
||||||
|
if (getLogLevel(PDA_LOG) >= LOG_DEBUG && force_print_menu ){print_menu();}
|
||||||
break;
|
break;
|
||||||
case CMD_PDA_SHIFTLINES:
|
case CMD_PDA_SHIFTLINES:
|
||||||
// press up from top - shift menu down by 1
|
// press up from top - shift menu down by 1
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef enum pda_menu_type {
|
||||||
*/
|
*/
|
||||||
//bool pda_mode();
|
//bool pda_mode();
|
||||||
//void set_pda_mode(bool val);
|
//void set_pda_mode(bool val);
|
||||||
bool process_pda_menu_packet(unsigned char* packet, int length);
|
bool process_pda_menu_packet(unsigned char* packet, int length, bool force_print_menu);
|
||||||
int pda_m_hlightindex();
|
int pda_m_hlightindex();
|
||||||
char *pda_m_hlight();
|
char *pda_m_hlight();
|
||||||
char *pda_m_line(int index);
|
char *pda_m_line(int index);
|
||||||
|
|
Binary file not shown.
|
@ -123,11 +123,14 @@ report_zero_pool_temp = no
|
||||||
# MQTT will only post updated information, this option AqualinkD will re-post all MQTT information every ~5 minutes.
|
# MQTT will only post updated information, this option AqualinkD will re-post all MQTT information every ~5 minutes.
|
||||||
#mqtt_timed_update = no
|
#mqtt_timed_update = no
|
||||||
|
|
||||||
# Please see forum for this, only set to yes when logging information to support
|
# Please see forum for this, only set to yes when logging information to support new devices. (or debugging protocol)
|
||||||
# new devices. Inflrmation will be written to /tmp/RS485.log & /tmp/RS485_raw.log respectively
|
# Information will be written to /tmp/RS485.log & /tmp/RS485_raw.log respectively
|
||||||
#debug_RSProtocol_packets = no
|
#debug_RSProtocol_packets = no
|
||||||
#debug_RSProtocol_bytes = no
|
#debug_RSProtocol_bytes = no
|
||||||
|
|
||||||
|
# Log any packets from this device.
|
||||||
|
#serial_debug_filter = 0x00
|
||||||
|
|
||||||
# Not documented. These will change how RS485 / Serial works, Only use if asked to for problem solving purposes.
|
# Not documented. These will change how RS485 / Serial works, Only use if asked to for problem solving purposes.
|
||||||
#serial_readahead_b4_write = yes
|
#serial_readahead_b4_write = yes
|
||||||
#thread_netservices = yes
|
#thread_netservices = yes
|
||||||
|
|
|
@ -103,7 +103,7 @@ int rsm_strncmp(const char *haystack, const char *needle, int length)
|
||||||
while(isspace(*ep1)) ep1--;
|
while(isspace(*ep1)) ep1--;
|
||||||
|
|
||||||
|
|
||||||
//LOG(AQUA_LOG,LOG_DEBUG, "CHECK haystack SP1='%c' EP1='%c' SP2='%c' '%.*s' for '%s' length=%d\n",*sp1,*ep1,*sp2,(ep1-sp1)+1,sp1,sp2,(ep1-sp1)+1);
|
LOG(AQUA_LOG,LOG_DEBUG, "CHECK haystack SP1='%c' EP1='%c' SP2='%c' '%.*s' for '%s' length=%d\n",*sp1,*ep1,*sp2,(ep1-sp1)+1,sp1,sp2,(ep1-sp1)+1);
|
||||||
// Need to write this myself for speed
|
// Need to write this myself for speed
|
||||||
// Need to check if full length string (no space on end), that the +1 is accurate. MIN should do it
|
// Need to check if full length string (no space on end), that the +1 is accurate. MIN should do it
|
||||||
return strncasecmp(sp1, sp2, MIN((ep1-sp1)+1,length));
|
return strncasecmp(sp1, sp2, MIN((ep1-sp1)+1,length));
|
||||||
|
|
4
utils.c
4
utils.c
|
@ -82,7 +82,9 @@ int getLogLevel(int16_t from)
|
||||||
// RSSD_LOG should default to INFO unless the mask is explicitly set.
|
// RSSD_LOG should default to INFO unless the mask is explicitly set.
|
||||||
// IE Even if DEBUG is set, (Note ignored for the moment)
|
// IE Even if DEBUG is set, (Note ignored for the moment)
|
||||||
|
|
||||||
if ( ((_logforcemask & from) == from ) && _log_level < LOG_DEBUG_SERIAL)
|
if ( from == RSSD_LOG && ((_logforcemask & from) == from ) && _log_level < LOG_DEBUG_SERIAL)
|
||||||
|
return LOG_DEBUG_SERIAL;
|
||||||
|
else if ( ((_logforcemask & from) == from ) && _log_level < LOG_DEBUG_SERIAL)
|
||||||
return LOG_DEBUG;
|
return LOG_DEBUG;
|
||||||
|
|
||||||
return _log_level;
|
return _log_level;
|
||||||
|
|
|
@ -60,6 +60,22 @@
|
||||||
"Cool Cabaret - Show"
|
"Cool Cabaret - Show"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// all SWG return a status number, some have different meanings. Change the text below to suit, NOT THE NUMBER.
|
||||||
|
var swgStatus = {
|
||||||
|
0: "On",
|
||||||
|
1: "No flow",
|
||||||
|
2: "Low salt",
|
||||||
|
4: "High salt",
|
||||||
|
8: "Clean cell",
|
||||||
|
9: "Turning off",
|
||||||
|
16: "High current",
|
||||||
|
32: "Low volts",
|
||||||
|
64: "Low temp",
|
||||||
|
128: "Check PCB",
|
||||||
|
255: "Off"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BELOW IS NOT RELIVENT FOR simple.html or simple inteface
|
* BELOW IS NOT RELIVENT FOR simple.html or simple inteface
|
||||||
*
|
*
|
||||||
|
|
|
@ -580,6 +580,25 @@
|
||||||
else
|
else
|
||||||
var _link_spa_and_heater=false;
|
var _link_spa_and_heater=false;
|
||||||
|
|
||||||
|
// If swgStatus was defined in config.js, use it, else create our own
|
||||||
|
if (typeof swgStatus !== 'undefined') {
|
||||||
|
var _swgStatus = swgStatus;
|
||||||
|
} else {
|
||||||
|
var _swgStatus = {
|
||||||
|
0: "On",
|
||||||
|
1: "No flow",
|
||||||
|
2: "Low salt",
|
||||||
|
4: "High salt",
|
||||||
|
8: "Clean cell",
|
||||||
|
9: "Turning off",
|
||||||
|
16: "High current",
|
||||||
|
32: "Low volts",
|
||||||
|
64: "Low temp",
|
||||||
|
128: "Check PCB",
|
||||||
|
255: "Off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
setSizeSpecifics();
|
setSizeSpecifics();
|
||||||
populateLightProgram(-1);
|
populateLightProgram(-1);
|
||||||
|
@ -1014,6 +1033,7 @@
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setTileOn(id, status) {
|
function setTileOn(id, status) {
|
||||||
//console.log("setTileOn "+id+ " "+status);
|
//console.log("setTileOn "+id+ " "+status);
|
||||||
var tile;
|
var tile;
|
||||||
|
@ -1052,7 +1072,12 @@
|
||||||
var type;
|
var type;
|
||||||
if ((type = tile.getAttribute('type')) != null) {
|
if ((type = tile.getAttribute('type')) != null) {
|
||||||
if (type == 'setpoint_swg') {
|
if (type == 'setpoint_swg') {
|
||||||
if (tile.getAttribute('Boost') == 'on')
|
var exstatus = parseInt(tile.getAttribute('fullstatus'))
|
||||||
|
// Could also ignore "Enabled" in below, that way we don't jump different stats on startup
|
||||||
|
if (exstatus > 0 && exstatus < 255) {// Not off or on
|
||||||
|
//text = swgFullstatus2String(exstatus);
|
||||||
|
text = _swgStatus[exstatus];
|
||||||
|
} else if (tile.getAttribute('Boost') == 'on')
|
||||||
text = "Boost";
|
text = "Boost";
|
||||||
else if (status == 'enabled')
|
else if (status == 'enabled')
|
||||||
text = 'Enabled';
|
text = 'Enabled';
|
||||||
|
@ -2035,11 +2060,14 @@
|
||||||
|
|
||||||
if (typeof(data.swg_ppm) !== 'undefined')
|
if (typeof(data.swg_ppm) !== 'undefined')
|
||||||
setTileValue("SWG/PPM", data.swg_ppm);
|
setTileValue("SWG/PPM", data.swg_ppm);
|
||||||
|
if (typeof(data.swg_fullstatus) !== 'undefined')
|
||||||
|
setTileAttribute('SWG', "fullstatus", data.swg_fullstatus);
|
||||||
|
|
||||||
if (typeof(data.chem_ph) !== 'undefined')
|
if (typeof(data.chem_ph) !== 'undefined')
|
||||||
setTileValue("CHEM/pH", data.chem_ph);
|
setTileValue("CHEM/pH", data.chem_ph);
|
||||||
if (typeof(data.chem_orp) !== 'undefined')
|
if (typeof(data.chem_orp) !== 'undefined')
|
||||||
setTileValue("CHEM/ORP", data.chem_orp);
|
setTileValue("CHEM/ORP", data.chem_orp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
setTileValue("Air", data.air_temp);
|
setTileValue("Air", data.air_temp);
|
||||||
setTileValue("Pool_Water", data.pool_temp);
|
setTileValue("Pool_Water", data.pool_temp);
|
||||||
|
@ -2050,8 +2078,8 @@
|
||||||
if (obj.toString() == 'SWG/Boost') {
|
if (obj.toString() == 'SWG/Boost') {
|
||||||
//console.log("BOOST IS "+data.leds[obj]);
|
//console.log("BOOST IS "+data.leds[obj]);
|
||||||
setTileAttribute('SWG', "Boost", data.leds[obj]);
|
setTileAttribute('SWG', "Boost", data.leds[obj]);
|
||||||
setTileValue
|
//setTileValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var obj in data.timers) {
|
for (var obj in data.timers) {
|
||||||
setTileOnText(obj.toString(),"On (timer)");
|
setTileOnText(obj.toString(),"On (timer)");
|
||||||
|
|
Loading…
Reference in New Issue