mirror of https://github.com/sfeakes/AqualinkD.git
Refactor & Code Cleanup
parent
40e2c38ce0
commit
60e6541d09
59
Dockerfile
59
Dockerfile
|
@ -1,59 +0,0 @@
|
|||
#####################################
|
||||
#
|
||||
# Build container
|
||||
# The most basic build for aqualinkd latest version
|
||||
#####################################
|
||||
|
||||
FROM debian:bookworm AS aqualinkd-build
|
||||
|
||||
#VOLUME ["/aqualinkd-build"]
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y install build-essential libsystemd-dev
|
||||
|
||||
# Seup working dir
|
||||
RUN mkdir /home/AqualinkD
|
||||
WORKDIR /home/AqualinkD
|
||||
|
||||
# Get latest release
|
||||
RUN curl -sL $(curl -s https://api.github.com/repos/sfeakes/AqualinkD/releases/latest | grep "tarball_url" | cut -d'"' -f4) | tar xz --strip-components=1
|
||||
|
||||
# Build aqualinkd
|
||||
RUN make clean && \
|
||||
make container
|
||||
|
||||
#####################################
|
||||
#
|
||||
# Runtime container
|
||||
#
|
||||
#####################################
|
||||
|
||||
FROM debian:bookworm-slim AS aqualinkd
|
||||
|
||||
#ARG AQUALINKD_VERSION
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y cron curl && \
|
||||
apt-get clean
|
||||
|
||||
# Set cron to read local.d
|
||||
RUN sed -i '/EXTRA_OPTS=.-l./s/^#//g' /etc/default/cron
|
||||
|
||||
# Add Open Container Initiative (OCI) annotations.
|
||||
# See: https://github.com/opencontainers/image-spec/blob/main/annotations.md
|
||||
|
||||
LABEL org.opencontainers.image.title="AqualinkD"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/repository/docker/sfeakes/aqualinkd/general"
|
||||
LABEL org.opencontainers.image.source="https://github.com/sfeakes/AqualinkD"
|
||||
LABEL org.opencontainers.image.documentation="https://github.com/sfeakes/AqualinkD"
|
||||
#LABEL org.opencontainers.image.version=$AQUALINKD_VERSION
|
||||
|
||||
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd /usr/local/bin/aqualinkd
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/serial_logger /usr/local/bin/serial_logger
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/web/ /var/www/aqualinkd/
|
||||
COPY --from=aqualinkd-build /home/AqualinkD/release/aqualinkd.conf /etc/aqualinkd.conf
|
||||
#COPY --from=aqualinkd-build /home/AqualinkD/docker/aqualinkd-docker.cmd /usr/local/bin/aqualinkd-docker
|
||||
RUN curl -s -o /usr/local/bin/aqualinkd-docker https://raw.githubusercontent.com/sfeakes/AqualinkD/master/extras/aqualinkd-docker.cmd
|
||||
|
||||
CMD ["sh", "-c", "/usr/local/bin/aqualinkd-docker"]
|
63
Makefile
63
Makefile
|
@ -80,7 +80,7 @@ endif
|
|||
|
||||
|
||||
# Main source files
|
||||
SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c net_services.c json_messages.c rs_msg_utils.c\
|
||||
SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c allbutton.c allbutton_aq_programmer.c net_services.c json_messages.c rs_msg_utils.c\
|
||||
devices_jandy.c packetLogger.c devices_pentair.c color_lights.c serialadapter.c aq_timer.c aq_scheduler.c web_config.c\
|
||||
serial_logger.c mongoose.c hassio.c simulator.c timespec_subtract.c
|
||||
|
||||
|
@ -140,10 +140,14 @@ SL_SRC = serial_logger.c aq_serial.c utils.c packetLogger.c rs_msg_utils.c times
|
|||
#MG_SRC = mongoose.c
|
||||
|
||||
# Build durectories
|
||||
SRC_DIR := ./
|
||||
OBJ_DIR := ./build
|
||||
DBG_OBJ_DIR := $(OBJ_DIR)/debug
|
||||
SL_OBJ_DIR := $(OBJ_DIR)/slog
|
||||
|
||||
INCLUDES := -I$(SRC_DIR)
|
||||
|
||||
# define path for obj files per architecture
|
||||
OBJ_DIR_ARMHF := $(OBJ_DIR)/armhf
|
||||
OBJ_DIR_ARM64 := $(OBJ_DIR)/arm64
|
||||
OBJ_DIR_AMD64 := $(OBJ_DIR)/amd64
|
||||
|
@ -151,18 +155,37 @@ SL_OBJ_DIR_ARMHF := $(OBJ_DIR_ARMHF)/slog
|
|||
SL_OBJ_DIR_ARM64 := $(OBJ_DIR_ARM64)/slog
|
||||
SL_OBJ_DIR_AMD64 := $(OBJ_DIR_AMD64)/slog
|
||||
|
||||
# Object files
|
||||
OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(SRCS))
|
||||
DBG_OBJ_FILES := $(patsubst %.c,$(DBG_OBJ_DIR)/%.o,$(DBG_SRC))
|
||||
SL_OBJ_FILES := $(patsubst %.c,$(SL_OBJ_DIR)/%.o,$(SL_SRC))
|
||||
# append path to source
|
||||
SRCS := $(patsubst %.c,$(SRC_DIR)/%.c,$(SRCS))
|
||||
DBG_SRC := $(patsubst %.c,$(SRC_DIR)/%.c,$(DBG_SRC))
|
||||
SL_SRC := $(patsubst %.c,$(SRC_DIR)/%.c,$(SL_SRC))
|
||||
|
||||
# append path to obj files per architecture
|
||||
OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS))
|
||||
DBG_OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(DBG_OBJ_DIR)/%.o,$(DBG_SRC))
|
||||
SL_OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(SL_OBJ_DIR)/%.o,$(SL_SRC))
|
||||
|
||||
OBJ_FILES_ARMHF := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR_ARMHF)/%.o,$(SRCS))
|
||||
OBJ_FILES_ARM64 := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR_ARM64)/%.o,$(SRCS))
|
||||
OBJ_FILES_AMD64 := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR_AMD64)/%.o,$(SRCS))
|
||||
|
||||
SL_OBJ_FILES_ARMHF := $(patsubst $(SRC_DIR)/%.c,$(SL_OBJ_DIR_ARMHF)/%.o,$(SL_SRC))
|
||||
SL_OBJ_FILES_ARM64 := $(patsubst $(SRC_DIR)/%.c,$(SL_OBJ_DIR_ARM64)/%.o,$(SL_SRC))
|
||||
SL_OBJ_FILES_AMD64 := $(patsubst $(SRC_DIR)/%.c,$(SL_OBJ_DIR_AMD64)/%.o,$(SL_SRC))
|
||||
|
||||
#OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(SRCS))
|
||||
#DBG_OBJ_FILES := $(patsubst %.c,$(DBG_OBJ_DIR)/%.o,$(DBG_SRC))
|
||||
#SL_OBJ_FILES := $(patsubst %.c,$(SL_OBJ_DIR)/%.o,$(SL_SRC))
|
||||
|
||||
#OBJ_FILES_ARMHF := $(patsubst %.c,$(OBJ_DIR_ARMHF)/%.o,$(SRCS))
|
||||
#OBJ_FILES_ARM64 := $(patsubst %.c,$(OBJ_DIR_ARM64)/%.o,$(SRCS))
|
||||
#OBJ_FILES_AMD64 := $(patsubst %.c,$(OBJ_DIR_AMD64)/%.o,$(SRCS))
|
||||
|
||||
#SL_OBJ_FILES_ARMHF := $(patsubst %.c,$(SL_OBJ_DIR_ARMHF)/%.o,$(SL_SRC))
|
||||
#SL_OBJ_FILES_ARM64 := $(patsubst %.c,$(SL_OBJ_DIR_ARM64)/%.o,$(SL_SRC))
|
||||
#SL_OBJ_FILES_AMD64 := $(patsubst %.c,$(SL_OBJ_DIR_AMD64)/%.o,$(SL_SRC))
|
||||
|
||||
OBJ_FILES_ARMHF := $(patsubst %.c,$(OBJ_DIR_ARMHF)/%.o,$(SRCS))
|
||||
OBJ_FILES_ARM64 := $(patsubst %.c,$(OBJ_DIR_ARM64)/%.o,$(SRCS))
|
||||
OBJ_FILES_AMD64 := $(patsubst %.c,$(OBJ_DIR_AMD64)/%.o,$(SRCS))
|
||||
|
||||
SL_OBJ_FILES_ARMHF := $(patsubst %.c,$(SL_OBJ_DIR_ARMHF)/%.o,$(SL_SRC))
|
||||
SL_OBJ_FILES_ARM64 := $(patsubst %.c,$(SL_OBJ_DIR_ARM64)/%.o,$(SL_SRC))
|
||||
SL_OBJ_FILES_AMD64 := $(patsubst %.c,$(SL_OBJ_DIR_AMD64)/%.o,$(SL_SRC))
|
||||
#MG_OBJ_FILES := $(patsubst %.c,$(OBJ_DIR)/%.o,$(MG_SRC))
|
||||
|
||||
# define the executable file
|
||||
|
@ -252,31 +275,31 @@ install:
|
|||
|
||||
|
||||
# Rules to compile
|
||||
$(OBJ_DIR)/%.o: %.c | $(OBJ_DIR)
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(DBG_OBJ_DIR)/%.o: %.c | $(DBG_OBJ_DIR)
|
||||
$(DBG_OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(DBG_OBJ_DIR)
|
||||
$(CC) $(DBG_CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(SL_OBJ_DIR)/%.o: %.c | $(SL_OBJ_DIR)
|
||||
$(SL_OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(SL_OBJ_DIR)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(OBJ_DIR_ARMHF)/%.o: %.c | $(OBJ_DIR_ARMHF)
|
||||
$(OBJ_DIR_ARMHF)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR_ARMHF)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(SL_OBJ_DIR_ARMHF)/%.o: %.c | $(SL_OBJ_DIR_ARMHF)
|
||||
$(SL_OBJ_DIR_ARMHF)/%.o: $(SRC_DIR)/%.c | $(SL_OBJ_DIR_ARMHF)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(OBJ_DIR_ARM64)/%.o: %.c | $(OBJ_DIR_ARM64)
|
||||
$(OBJ_DIR_ARM64)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR_ARM64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(SL_OBJ_DIR_ARM64)/%.o: %.c | $(SL_OBJ_DIR_ARM64)
|
||||
$(SL_OBJ_DIR_ARM64)/%.o: $(SRC_DIR)/%.c | $(SL_OBJ_DIR_ARM64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(OBJ_DIR_AMD64)/%.o: %.c | $(OBJ_DIR_AMD64)
|
||||
$(OBJ_DIR_AMD64)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR_AMD64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
$(SL_OBJ_DIR_AMD64)/%.o: %.c | $(SL_OBJ_DIR_AMD64)
|
||||
$(SL_OBJ_DIR_AMD64)/%.o: $(SRC_DIR)/%.c | $(SL_OBJ_DIR_AMD64)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
# Rules to link
|
||||
|
|
|
@ -0,0 +1,697 @@
|
|||
#define _GNU_SOURCE 1 // for strcasestr & strptime
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aqualink.h"
|
||||
#include "allbutton.h"
|
||||
#include "rs_msg_utils.h"
|
||||
#include "devices_jandy.h"
|
||||
#include "allbutton_aq_programmer.h"
|
||||
|
||||
void processLEDstate(struct aqualinkdata *aq_data)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
int byte;
|
||||
int bit;
|
||||
|
||||
for (byte = 0; byte < 5; byte++)
|
||||
{
|
||||
for (bit = 0; bit < 8; bit += 2)
|
||||
{
|
||||
if (((aq_data->raw_status[byte] >> (bit + 1)) & 1) == 1)
|
||||
aq_data->aqualinkleds[i].state = FLASH;
|
||||
else if (((aq_data->raw_status[byte] >> bit) & 1) == 1)
|
||||
aq_data->aqualinkleds[i].state = ON;
|
||||
else
|
||||
aq_data->aqualinkleds[i].state = OFF;
|
||||
|
||||
//LOG(ALLB_LOG,LOG_DEBUG,"Led %d state %d",i+1,aq_data->aqualinkleds[i].state);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// Reset enabled state for heaters, as they take 2 led states
|
||||
if (aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[POOL_HTR_LED_INDEX].state == ON)
|
||||
aq_data->aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
|
||||
if (aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SPA_HTR_LED_INDEX].state == ON)
|
||||
aq_data->aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
|
||||
if (aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON)
|
||||
aq_data->aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
/*
|
||||
for (i=0; i < TOTAL_BUTTONS; i++) {
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "%s = %d", aq_data->aqbuttons[i].name, aq_data->aqualinkleds[i].state);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void setUnits(char *msg, struct aqualinkdata *aq_data)
|
||||
{
|
||||
char buf[AQ_MSGLEN*3];
|
||||
|
||||
rsm_strncpy(buf, (unsigned char *)msg, AQ_MSGLEN*3, AQ_MSGLONGLEN);
|
||||
|
||||
//ascii(buf, msg);
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "Getting temp units from message '%s', looking at '%c'\n", buf, buf[strlen(buf) - 1]);
|
||||
|
||||
if (msg[strlen(msg) - 1] == 'F')
|
||||
aq_data->temp_units = FAHRENHEIT;
|
||||
else if (msg[strlen(msg) - 1] == 'C')
|
||||
aq_data->temp_units = CELSIUS;
|
||||
else
|
||||
aq_data->temp_units = UNKNOWN;
|
||||
|
||||
LOG(ALLB_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", aq_data->temp_units);
|
||||
}
|
||||
|
||||
// Defined as int16_t so 16 bits to mask
|
||||
#define MSG_FREEZE (1 << 0) // 1
|
||||
#define MSG_SERVICE (1 << 1) // 1
|
||||
#define MSG_SWG (1 << 2)
|
||||
#define MSG_BOOST (1 << 3)
|
||||
#define MSG_TIMEOUT (1 << 4)
|
||||
#define MSG_RS13BUTTON (1 << 5)
|
||||
#define MSG_RS14BUTTON (1 << 6)
|
||||
#define MSG_RS15BUTTON (1 << 7)
|
||||
#define MSG_RS16BUTTON (1 << 8)
|
||||
#define MSG_BATTERY_LOW (1 << 9)
|
||||
#define MSG_SWG_DEVICE (1 << 10)
|
||||
|
||||
#ifdef AQ_RS16
|
||||
int16_t RS16_endswithLEDstate(char *msg, struct aqualinkdata *aq_data)
|
||||
{
|
||||
char *sp;
|
||||
int i;
|
||||
aqledstate state = LED_S_UNKNOWN;
|
||||
|
||||
//if (_aqconfig_.rs_panel_size < 16)
|
||||
if (PANEL_SIZE() < 16)
|
||||
return false;
|
||||
|
||||
sp = strrchr(msg, ' ');
|
||||
|
||||
if( sp == NULL )
|
||||
return false;
|
||||
|
||||
if (strncasecmp(sp, " on", 3) == 0)
|
||||
state = ON;
|
||||
else if (strncasecmp(sp, " off", 4) == 0)
|
||||
state = OFF;
|
||||
else if (strncasecmp(sp, " enabled", 8) == 0) // Total guess, need to check
|
||||
state = ENABLE;
|
||||
else if (strncasecmp(sp, " no idea", 8) == 0) // need to figure out these states
|
||||
state = FLASH;
|
||||
|
||||
if (state == LED_S_UNKNOWN)
|
||||
return false;
|
||||
|
||||
// Only need to start at Aux B5->B8 (12-15)
|
||||
// Loop over only aqdata->aqbuttons[13] to aqdata->aqbuttons[16]
|
||||
for (i = aq_data->rs16_vbutton_start; i <= aq_data->rs16_vbutton_end; i++) {
|
||||
//TOTAL_BUTTONS
|
||||
if ( stristr(msg, aq_data->aqbuttons[i].label) != NULL) {
|
||||
aq_data->aqbuttons[i].led->state = state;
|
||||
LOG(ALLB_LOG,LOG_INFO, "Set %s to %d\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state);
|
||||
// Return true should be the result, but in the if we want to continue to display message
|
||||
//return true;
|
||||
if (i == 13)
|
||||
return MSG_RS13BUTTON;
|
||||
else if (i == 14)
|
||||
return MSG_RS14BUTTON;
|
||||
else if (i == 15)
|
||||
return MSG_RS15BUTTON;
|
||||
else if (i == 16)
|
||||
return MSG_RS16BUTTON;
|
||||
else
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", aq_data->aqbuttons[i].label, aq_data->aqbuttons[i].led->state, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset);
|
||||
|
||||
void processMessage(char *message, struct aqualinkdata *aq_data)
|
||||
{
|
||||
_processMessage(message, aq_data, false);
|
||||
}
|
||||
void processMessageReset(struct aqualinkdata *aq_data)
|
||||
{
|
||||
_processMessage(NULL, aq_data, true);
|
||||
}
|
||||
void _processMessage(char *message, struct aqualinkdata *aq_data, bool reset)
|
||||
{
|
||||
char *msg;
|
||||
static bool _initWithRS = false;
|
||||
//static bool _gotREV = false;
|
||||
//static int freeze_msg_count = 0;
|
||||
//static int service_msg_count = 0;
|
||||
//static int swg_msg_count = 0;
|
||||
//static int boost_msg_count = 0;
|
||||
static int16_t msg_loop = 0;
|
||||
// NSF replace message with msg
|
||||
#ifdef AQ_RS16
|
||||
int16_t rs16;
|
||||
#endif
|
||||
|
||||
//msg = stripwhitespace(message);
|
||||
//strcpy(aq_data->last_message, msg);
|
||||
//LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
|
||||
|
||||
|
||||
|
||||
// Check long messages in this if/elseif block first, as some messages are similar.
|
||||
// ie "POOL TEMP" and "POOL TEMP IS SET TO" so want correct match first.
|
||||
//
|
||||
|
||||
//if (stristr(msg, "JANDY AquaLinkRS") != NULL) {
|
||||
if (!reset) {
|
||||
msg = stripwhitespace(message);
|
||||
strcpy(aq_data->last_message, msg);
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
|
||||
// Just set this to off, it will re-set since it'll be the only message we get if on
|
||||
aq_data->service_mode_state = OFF;
|
||||
} else {
|
||||
//aq_data->display_message = NULL;
|
||||
aq_data->last_display_message[0] = ' ';
|
||||
aq_data->last_display_message[1] = '\0';
|
||||
|
||||
// Anything that wasn't on during the last set of messages, turn off
|
||||
if ((msg_loop & MSG_FREEZE) != MSG_FREEZE)
|
||||
aq_data->frz_protect_state = OFF;
|
||||
|
||||
if ((msg_loop & MSG_SERVICE) != MSG_SERVICE &&
|
||||
(msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) {
|
||||
aq_data->service_mode_state = OFF; // IF we get this message then Service / Timeout is off
|
||||
}
|
||||
|
||||
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aq_data->swg_led_state != LED_S_UNKNOWN) {
|
||||
// No Additional SWG devices messages like "no flow"
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF )
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_OFF);
|
||||
else
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_ON);
|
||||
}
|
||||
|
||||
// If no AQUAPURE message, either (no SWG, it's set 0, or it's off).
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->swg_led_state != LED_S_UNKNOWN ) {
|
||||
if (aq_data->swg_percent != 0 || aq_data->swg_led_state == ON) {
|
||||
// Something is wrong here. Let's check pump, if on set SWG to 0, if off turn SWE off
|
||||
if ( aq_data->aqbuttons[PUMP_INDEX].led->state == OFF) {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
|
||||
setSWGoff(aq_data);
|
||||
} else {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n");
|
||||
changeSWGpercent(aq_data, 0);
|
||||
}
|
||||
} else if (isIAQT_ENABLED == false && isONET_ENABLED == false && READ_RSDEV_SWG == false ) {
|
||||
//We have no other way to read SWG %=0, so turn SWG on with pump
|
||||
if ( aq_data->aqbuttons[PUMP_INDEX].led->state == ON) {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
|
||||
//changeSWGpercent(aq_data, 0);
|
||||
setSWGenabled(aq_data);
|
||||
}
|
||||
}
|
||||
// NSF Need something to catch startup when SWG=0 so we set it to enabeled.
|
||||
// when other ways/protocols to detect SWG=0 are turned off.
|
||||
}
|
||||
/*
|
||||
// AQUAPURE=0 we never get that message on ALLBUTTON so don't turn off unless filter pump if off
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && aq_data->aqbuttons[PUMP_INDEX].led->state == OFF ) {
|
||||
//aq_data->ar_swg_status = SWG_STATUS_OFF;
|
||||
setSWGoff(aq_data);
|
||||
}
|
||||
*/
|
||||
if ((msg_loop & MSG_BOOST) != MSG_BOOST) {
|
||||
aq_data->boost = false;
|
||||
aq_data->boost_msg[0] = '\0';
|
||||
aq_data->boost_duration = 0;
|
||||
//if (aq_data->swg_percent >= 101)
|
||||
// aq_data->swg_percent = 0;
|
||||
}
|
||||
|
||||
if ((msg_loop & MSG_BATTERY_LOW) != MSG_BATTERY_LOW)
|
||||
aq_data->battery = OK;
|
||||
|
||||
#ifdef AQ_RS16
|
||||
//if ( _aqconfig_.rs_panel_size >= 16) {
|
||||
//if ( (int)PANEL_SIZE >= 16) { // NSF No idea why this fails on RS-4, but it does. Come back and find out why
|
||||
if ( PANEL_SIZE() >= 16 ) {
|
||||
//printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE());
|
||||
if ((msg_loop & MSG_RS13BUTTON) != MSG_RS13BUTTON)
|
||||
aq_data->aqbuttons[13].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS14BUTTON) != MSG_RS14BUTTON)
|
||||
aq_data->aqbuttons[14].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS15BUTTON) != MSG_RS15BUTTON)
|
||||
aq_data->aqbuttons[15].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS16BUTTON) != MSG_RS16BUTTON)
|
||||
aq_data->aqbuttons[16].led->state = OFF;
|
||||
}
|
||||
#endif
|
||||
msg_loop = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stristr(msg, LNG_MSG_BATTERY_LOW) != NULL)
|
||||
{
|
||||
aq_data->battery = LOW;
|
||||
msg_loop |= MSG_BATTERY_LOW;
|
||||
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_POOL_TEMP_SET) != NULL)
|
||||
{
|
||||
//LOG(ALLB_LOG,LOG_DEBUG, "**************** pool htr long message: %s", &message[20]);
|
||||
aq_data->pool_htr_set_point = atoi(message + 20);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_SPA_TEMP_SET) != NULL)
|
||||
{
|
||||
//LOG(ALLB_LOG,LOG_DEBUG, "spa htr long message: %s", &message[19]);
|
||||
aq_data->spa_htr_set_point = atoi(message + 19);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_SET) != NULL)
|
||||
{
|
||||
//LOG(ALLB_LOG,LOG_DEBUG, "frz protect long message: %s", &message[28]);
|
||||
aq_data->frz_protect_set_point = atoi(message + 28);
|
||||
aq_data->frz_protect_state = ENABLE;
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_AIR_TEMP, MSG_AIR_TEMP_LEN) == 0)
|
||||
{
|
||||
aq_data->air_temp = atoi(msg + MSG_AIR_TEMP_LEN);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_POOL_TEMP, MSG_POOL_TEMP_LEN) == 0)
|
||||
{
|
||||
aq_data->pool_temp = atoi(msg + MSG_POOL_TEMP_LEN);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_SPA_TEMP, MSG_SPA_TEMP_LEN) == 0)
|
||||
{
|
||||
aq_data->spa_temp = atoi(msg + MSG_SPA_TEMP_LEN);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
}
|
||||
// NSF If get water temp rather than pool or spa in some cases, then we are in Pool OR Spa ONLY mode
|
||||
else if (strncasecmp(msg, MSG_WATER_TEMP, MSG_WATER_TEMP_LEN) == 0)
|
||||
{
|
||||
aq_data->pool_temp = atoi(msg + MSG_WATER_TEMP_LEN);
|
||||
aq_data->spa_temp = atoi(msg + MSG_WATER_TEMP_LEN);
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_WATER_TEMP1_SET) != NULL)
|
||||
{
|
||||
aq_data->pool_htr_set_point = atoi(message + 28);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_WATER_TEMP2_SET) != NULL)
|
||||
{
|
||||
aq_data->spa_htr_set_point = atoi(message + 27);
|
||||
|
||||
if (aq_data->temp_units == UNKNOWN)
|
||||
setUnits(msg, aq_data);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_SERVICE_ACTIVE) != NULL)
|
||||
{
|
||||
if (aq_data->service_mode_state == OFF)
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n");
|
||||
aq_data->service_mode_state = ON;
|
||||
msg_loop |= MSG_SERVICE;
|
||||
//service_msg_count = 0;
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_TIMEOUT_ACTIVE) != NULL)
|
||||
{
|
||||
if (aq_data->service_mode_state == OFF)
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n");
|
||||
aq_data->service_mode_state = FLASH;
|
||||
msg_loop |= MSG_TIMEOUT;
|
||||
//service_msg_count = 0;
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_ACTIVATED) != NULL)
|
||||
{
|
||||
msg_loop |= MSG_FREEZE;
|
||||
aq_data->frz_protect_state = ON;
|
||||
//freeze_msg_count = 0;
|
||||
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI
|
||||
}
|
||||
/* // Not sure when to do with these for the moment, so no need to compile in the test.
|
||||
else if (stristr(msg, LNG_MSG_CHEM_FEED_ON) != NULL) {
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_CHEM_FEED_OFF) != NULL) {
|
||||
}
|
||||
*/
|
||||
else if (msg[2] == '/' && msg[5] == '/' && msg[8] == ' ')
|
||||
{ // date in format '08/29/16 MON'
|
||||
strcpy(aq_data->date, msg);
|
||||
}
|
||||
else if (stristr(msg, MSG_SWG_PCT) != NULL)
|
||||
{
|
||||
if (strncasecmp(msg, MSG_SWG_PCT, MSG_SWG_PCT_LEN) == 0 && strncasecmp(msg, "AQUAPURE HRS", 12) != 0) {
|
||||
changeSWGpercent(aq_data, atoi(msg + MSG_SWG_PCT_LEN));
|
||||
}
|
||||
else if (strncasecmp(msg, "AQUAPURE HRS", 12) != 0 && strncasecmp(msg, "SET AQUAPURE", 12) != 0)
|
||||
{
|
||||
if (strcasestr(msg, MSG_SWG_NO_FLOW) != NULL)
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_NO_FLOW);
|
||||
else if (strcasestr(msg, MSG_SWG_LOW_SALT) != NULL)
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_LOW_SALT);
|
||||
else if (strcasestr(msg, MSG_SWG_HIGH_SALT) != NULL)
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_HI_SALT);
|
||||
else if (strcasestr(msg, MSG_SWG_FAULT) != NULL)
|
||||
setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_GENFAULT);
|
||||
//setSWGdeviceStatus(aq_data, ALLBUTTON, SWG_STATUS_CHECK_PCB);
|
||||
|
||||
// Any of these messages want to display.
|
||||
strcpy(aq_data->last_display_message, msg);
|
||||
|
||||
msg_loop |= MSG_SWG_DEVICE;
|
||||
}
|
||||
msg_loop |= MSG_SWG;
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_SWG_PPM, MSG_SWG_PPM_LEN) == 0)
|
||||
{
|
||||
aq_data->swg_ppm = atoi(msg + MSG_SWG_PPM_LEN);
|
||||
msg_loop |= MSG_SWG;
|
||||
}
|
||||
else if ((msg[1] == ':' || msg[2] == ':') && msg[strlen(msg) - 1] == 'M')
|
||||
{ // time in format '9:45 AM'
|
||||
strcpy(aq_data->time, msg);
|
||||
// Setting time takes a long time, so don't try until we have all other programmed data.
|
||||
if (_initWithRS == true && strlen(aq_data->date) > 1 && checkAqualinkTime() != true)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", aq_data->time, aq_data->date);
|
||||
aq_programmer(AQ_SET_TIME, NULL, aq_data);
|
||||
}
|
||||
else if (_initWithRS == false || _aqconfig_.sync_panel_time == false)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", aq_data->time, aq_data->date);
|
||||
}
|
||||
else if (_initWithRS == true)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", aq_data->time, aq_data->date);
|
||||
}
|
||||
// If we get a time message before REV, the controller didn't see us as we started too quickly.
|
||||
/* Don't need to check this anymore with the check for probe before startup.
|
||||
if (_gotREV == false)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Getting control panel information\n", msg);
|
||||
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, aq_data);
|
||||
_gotREV = true; // Force it to true just incase we don't understand the model#
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (strstr(msg, " REV ") != NULL || strstr(msg, " REV. ") != NULL)
|
||||
{ // '8157 REV MMM'
|
||||
// A master firmware revision message.
|
||||
strcpy(aq_data->version, msg);
|
||||
rsm_get_revision(aq_data->revision, aq_data->version, strlen(aq_data->version));
|
||||
//_gotREV = true;
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel version %s\n", aq_data->version);
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel revision %s\n", aq_data->revision);
|
||||
if (_initWithRS == false)
|
||||
{
|
||||
//LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n");
|
||||
queueGetProgramData(ALLBUTTON, aq_data);
|
||||
//queueGetExtendedProgramData(ALLBUTTON, aq_data, _aqconfig_.use_panel_aux_labels);
|
||||
_initWithRS = true;
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, " TURNS ON") != NULL)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Program data '%s'\n", msg);
|
||||
}
|
||||
else if (_aqconfig_.override_freeze_protect == TRUE && strncasecmp(msg, "Press Enter* to override Freeze Protection with", 47) == 0)
|
||||
{
|
||||
//send_cmd(KEY_ENTER, aq_data);
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, aq_data);
|
||||
aq_send_allb_cmd(KEY_ENTER);
|
||||
}
|
||||
// Process any button states (fake LED) for RS12 and above keypads
|
||||
// Text will be button label on or off ie Aux_B2 off or WaterFall off
|
||||
|
||||
#ifdef AQ_RS16
|
||||
//else if ( _aqconfig_.rs_panel_size >= 16 && (rs16 = RS16_endswithLEDstate(msg)) != 0 )
|
||||
else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg, aq_data)) != 0 )
|
||||
{
|
||||
msg_loop |= rs16;
|
||||
// Do nothing, just stop other else if statments executing
|
||||
// make sure we also display the message.
|
||||
// Note we only get ON messages here, Off messages will not be sent if something else turned it off
|
||||
// use the Onetouch or iAqua equiptment page for off.
|
||||
strcpy(aq_data->last_display_message, msg);
|
||||
}
|
||||
#endif
|
||||
else if (((msg[4] == ':') || (msg[6] == ':')) && (strncasecmp(msg, "AUX", 3) == 0) )
|
||||
{ // Should probable check we are in programming mode.
|
||||
// 'Aux3: No Label'
|
||||
// 'Aux B1: No Label'
|
||||
int labelid;
|
||||
int ni = 3;
|
||||
if (msg[4] == 'B') { ni = 5; }
|
||||
labelid = atoi(msg + ni);
|
||||
if (labelid > 0 && _aqconfig_.use_panel_aux_labels == true)
|
||||
{
|
||||
if (ni == 5)
|
||||
labelid = labelid + 8;
|
||||
else
|
||||
labelid = labelid + 1;
|
||||
// Aux1: on panel = Button 3 in aqualinkd (button 2 in array)
|
||||
if (strncasecmp(msg+ni+3, "No Label", 8) != 0) {
|
||||
aq_data->aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2));
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label);
|
||||
} else {
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", aq_data->aqbuttons[labelid].name, aq_data->aqbuttons[labelid].label);
|
||||
}
|
||||
//aq_data->aqbuttons[labelid + 1].label = cleanalloc(msg + 5);
|
||||
}
|
||||
}
|
||||
// BOOST POOL 23:59 REMAINING
|
||||
else if ( (strncasecmp(msg, "BOOST POOL", 10) == 0) && (strcasestr(msg, "REMAINING") != NULL) ) {
|
||||
// Ignore messages if in programming mode. We get one of these turning off for some strange reason.
|
||||
if (in_programming_mode(aq_data) == false) {
|
||||
snprintf(aq_data->boost_msg, 6, "%s", &msg[11]);
|
||||
aq_data->boost_duration = rsm_HHMM2min(aq_data->boost_msg);
|
||||
aq_data->boost = true;
|
||||
msg_loop |= MSG_BOOST;
|
||||
msg_loop |= MSG_SWG;
|
||||
//convert_boost_to_duration(aq_data->boost_msg)
|
||||
//if (aq_data->ar_swg_status != SWG_STATUS_ON) {aq_data->ar_swg_status = SWG_STATUS_ON;}
|
||||
if (aq_data->swg_percent != 101) {changeSWGpercent(aq_data, 101);}
|
||||
//boost_msg_count = 0;
|
||||
//if (aq_data->active_thread.thread_id == 0)
|
||||
strcpy(aq_data->last_display_message, msg); // Also display the message on web UI if not in programming mode
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg);
|
||||
//aq_data->display_message = msg;
|
||||
//if (in_programming_mode(aq_data) == false && aq_data->simulate_panel == false &&
|
||||
if (in_programming_mode(aq_data) == false &&
|
||||
stristr(msg, "JANDY AquaLinkRS") == NULL &&
|
||||
//stristr(msg, "PUMP O") == NULL &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
|
||||
strncasecmp(msg, "PUMP O", 6) != 0 &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
|
||||
stristr(msg, "MAINTAIN") == NULL && // Catch 'MAINTAIN TEMP IS OFF'
|
||||
stristr(msg, "0 PSI") == NULL /* // Catch some erronious message on test harness
|
||||
stristr(msg, "CLEANER O") == NULL &&
|
||||
stristr(msg, "SPA O") == NULL &&
|
||||
stristr(msg, "AUX") == NULL*/
|
||||
)
|
||||
{ // Catch all AUX1 AUX5 messages
|
||||
//aq_data->display_last_message = true;
|
||||
strcpy(aq_data->last_display_message, msg);
|
||||
//rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
|
||||
}
|
||||
}
|
||||
|
||||
// Send every message if we are in simulate panel mode
|
||||
//if (aq_data->simulate_panel)
|
||||
// strcpy(aq_data->last_display_message, msg);
|
||||
//rsm_strncpy(aq_data->last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
|
||||
//ascii(aq_data->last_display_message, msg);
|
||||
|
||||
|
||||
//LOG(ALLB_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop);
|
||||
|
||||
// We processed the next message, kick any threads waiting on the message.
|
||||
//printf ("Message kicking\n");
|
||||
|
||||
|
||||
kick_aq_program_thread(aq_data, ALLBUTTON);
|
||||
}
|
||||
|
||||
bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
bool rtn = false;
|
||||
//static unsigned char last_packet[AQ_MAXPKTLEN];
|
||||
static unsigned char last_checksum;
|
||||
static char message[AQ_MSGLONGLEN + 1];
|
||||
static int processing_long_msg = 0;
|
||||
|
||||
// Check packet against last check if different.
|
||||
// Should only use the checksum, not whole packet since it's status messages.
|
||||
/*
|
||||
if ( packet[PKT_CMD] == CMD_STATUS && (memcmp(packet, last_packet, length) == 0))
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length);
|
||||
return rtn;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(last_packet, packet, length);
|
||||
aq_data->last_packet_type = packet[PKT_CMD];
|
||||
rtn = true;
|
||||
}
|
||||
*/
|
||||
|
||||
aq_data->last_packet_type = packet[PKT_CMD];
|
||||
|
||||
|
||||
if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(aq_data) )
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_checksum = packet[length-3];
|
||||
rtn = true;
|
||||
}
|
||||
|
||||
if (processing_long_msg > 0 && packet[PKT_CMD] != CMD_MSG_LONG)
|
||||
{
|
||||
processing_long_msg = 0;
|
||||
//LOG(ALLB_LOG,LOG_ERR, "RS failed to receive complete long message, received '%s'\n",message);
|
||||
//LOG(ALLB_LOG,LOG_DEBUG, "RS didn't finished receiving of MSG_LONG '%s'\n",message);
|
||||
processMessage(message, aq_data);
|
||||
}
|
||||
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length);
|
||||
|
||||
switch (packet[PKT_CMD])
|
||||
{
|
||||
case CMD_ACK:
|
||||
//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);
|
||||
memcpy(aq_data->raw_status, packet + 4, AQ_PSTLEN);
|
||||
processLEDstate(aq_data);
|
||||
if (aq_data->aqbuttons[PUMP_INDEX].led->state == OFF)
|
||||
{
|
||||
aq_data->pool_temp = TEMP_UNKNOWN;
|
||||
aq_data->spa_temp = TEMP_UNKNOWN;
|
||||
//aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
|
||||
}
|
||||
else if (aq_data->aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
//aq_data->spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
|
||||
aq_data->spa_temp = TEMP_UNKNOWN;
|
||||
}
|
||||
else if (aq_data->aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
aq_data->pool_temp = TEMP_UNKNOWN;
|
||||
}
|
||||
|
||||
// COLOR MODE programming relies on state changes, so let any threads know
|
||||
//if (aq_data->active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) {
|
||||
if ( in_light_programming_mode(aq_data) ) {
|
||||
kick_aq_program_thread(aq_data, ALLBUTTON);
|
||||
}
|
||||
break;
|
||||
case CMD_MSG:
|
||||
case CMD_MSG_LONG:
|
||||
{
|
||||
int index = packet[PKT_DATA]; // Will get 0x00 for complete message, 0x01 for start on long message 0x05 last of long message
|
||||
//printf("RSM received message at index %d '%.*s'\n",index,AQ_MSGLEN,(char *)packet + PKT_DATA + 1);
|
||||
if (index <= 1){
|
||||
memset(message, 0, AQ_MSGLONGLEN + 1);
|
||||
//strncpy(message, (char *)packet + PKT_DATA + 1, AQ_MSGLEN);
|
||||
rsm_strncpy(message, packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
processing_long_msg = index;
|
||||
//LOG(ALLB_LOG,LOG_ERR, "Message %s\n",message);
|
||||
} else {
|
||||
//strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (char *)packet + PKT_DATA + 1, AQ_MSGLEN);
|
||||
//rsm_strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
rsm_strncpy(&message[( (index-1) * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
//LOG(ALLB_LOG,LOG_ERR, "Long Message %s\n",message);
|
||||
if (++processing_long_msg != index) {
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "Long message index %d doesn't match buffer %d\n",index,processing_long_msg);
|
||||
//printf("RSM Long message index %d doesn't match buffer %d\n",index,processing_long_msg);
|
||||
}
|
||||
#ifdef PROCESS_INCOMPLETE_MESSAGES
|
||||
kick_aq_program_thread(aq_data, ALLBUTTON);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (index == 0 || index == 5) {
|
||||
//printf("RSM process message '%s'\n",message);
|
||||
|
||||
// MOVED FROM LINE 701 see if less errors
|
||||
//kick_aq_program_thread(aq_data, ALLBUTTON);
|
||||
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message);
|
||||
processMessage(message, aq_data); // This will kick thread
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case CMD_PROBE:
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS Received PROBE length %d.\n", length);
|
||||
//LOG(ALLB_LOG,LOG_INFO, "Synch'ing with Aqualink master device...\n");
|
||||
rtn = false;
|
||||
break;
|
||||
case CMD_MSG_LOOP_ST:
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Received message loop start\n");
|
||||
processMessageReset(aq_data);
|
||||
rtn = false;
|
||||
break;
|
||||
default:
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Received unknown packet, 0x%02hhx\n", packet[PKT_CMD]);
|
||||
rtn = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef ALLBUTTON_H_
|
||||
#define ALLBUTTON_H_
|
||||
|
||||
|
||||
|
||||
bool process_allbutton_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data);
|
||||
|
||||
#endif //ALLBUTTON_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
#ifndef ALLBUTTON_PROGRAMMER_H_
|
||||
#define ALLBUTTON_PROGRAMMER_H_
|
||||
|
||||
|
||||
void *set_allbutton_pool_heater_temps( void *ptr );
|
||||
void *set_allbutton_spa_heater_temps( void *ptr );
|
||||
void *set_allbutton_freeze_heater_temps( void *ptr );
|
||||
void *set_allbutton_time( void *ptr );
|
||||
void *get_allbutton_pool_spa_heater_temps( void *ptr );
|
||||
void *get_allbutton_programs( void *ptr );
|
||||
void *get_allbutton_freeze_protect_temp( void *ptr );
|
||||
void *get_allbutton_diag_model( void *ptr );
|
||||
void *get_allbutton_aux_labels( void *ptr );
|
||||
//void *threadded_send_cmd( void *ptr );
|
||||
void *set_allbutton_light_programmode( void *ptr );
|
||||
void *set_allbutton_light_colormode( void *ptr );
|
||||
void *set_allbutton_SWG( void *ptr );
|
||||
void *set_allbutton_boost( void *ptr );
|
||||
|
||||
unsigned char pop_allb_cmd(struct aqualinkdata *aq_data);
|
||||
|
||||
|
||||
|
||||
void aq_send_allb_cmd(unsigned char cmd);
|
||||
|
||||
#endif //ALLBUTTON_PROGRAMMER_H_
|
128
aq_panel.c
128
aq_panel.c
|
@ -23,6 +23,7 @@
|
|||
#include "aq_panel.h"
|
||||
#include "serialadapter.h"
|
||||
#include "aq_timer.h"
|
||||
#include "allbutton_aq_programmer.h"
|
||||
|
||||
void initPanelButtons(struct aqualinkdata *aqdata, bool rspda, int size, bool combo, bool dual);
|
||||
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button);
|
||||
|
@ -627,20 +628,22 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
|
|||
// since allbutton (default) is stateless, and rssaadapter is statefull, use rssaadapter for any domoricz requests
|
||||
set_aqualink_rssadapter_aux_state(deviceIndex, isON);
|
||||
} else {
|
||||
aq_send_cmd(button->code);
|
||||
aq_send_allb_cmd(button->code);
|
||||
}
|
||||
// Pre set device to state, next status will correct if state didn't take, but this will stop multiple ON messages setting on/off
|
||||
#ifdef PRESTATE_ONOFF
|
||||
if ((button->code == KEY_POOL_HTR || button->code == KEY_SPA_HTR ||
|
||||
button->code == KEY_SOLAR_HTR) &&
|
||||
isON > 0) {
|
||||
button->led->state = ENABLE; // if heater and set to on, set pre-status to enable.
|
||||
//#ifdef PRESTATE_ONOFF
|
||||
if (_aqconfig_.device_pre_state) {
|
||||
if ((button->code == KEY_POOL_HTR || button->code == KEY_SPA_HTR ||
|
||||
button->code == KEY_SOLAR_HTR) &&
|
||||
isON > 0) {
|
||||
button->led->state = ENABLE; // if heater and set to on, set pre-status to enable.
|
||||
//_aqualink_data->updated = true;
|
||||
} else if (isRSSA_ENABLED || ((button->special_mask & PROGRAM_LIGHT) != PROGRAM_LIGHT)) {
|
||||
button->led->state = (isON == false ? OFF : ON); // as long as it's not programmable light , pre-set to on/off
|
||||
} else if (isRSSA_ENABLED || ((button->special_mask & PROGRAM_LIGHT) != PROGRAM_LIGHT)) {
|
||||
button->led->state = (isON == false ? OFF : ON); // as long as it's not programmable light , pre-set to on/off
|
||||
//_aqualink_data->updated = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -781,114 +784,7 @@ bool panel_device_request(struct aqualinkdata *aqdata, action_type type, int dev
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
bool create_panel_request(struct aqualinkdata *aqdata, netRequest requester, int buttonIndex, int value, bool timer) {
|
||||
|
||||
// if value = 0 is OFF,
|
||||
// if value = 1 is ON if (timer = false).
|
||||
// if value > 0 (timer should be true, and vaue is duration).
|
||||
|
||||
if ((_aqualink_data->aqbuttons[buttonIndex].led->state == OFF && value == 0) ||
|
||||
(value > 0 && (_aqualink_data->aqbuttons[buttonIndex].led->state == ON || _aqualink_data->aqbuttons[buttonIndex].led->state == FLASH ||
|
||||
_aqualink_data->aqbuttons[buttonIndex].led->state == ENABLE))) {
|
||||
LOG(NET_LOG, LOG_INFO, "%s: received '%s' for '%s', already '%s', Ignoring\n", actionName[requester], (value == 0 ? "OFF" : "ON"), _aqualink_data->aqbuttons[buttonIndex].name, (value == 0 ? "OFF" : "ON"));
|
||||
//return false;
|
||||
} else {
|
||||
LOG(NET_LOG, LOG_INFO, "%s: received '%s' for '%s', turning '%s'\n", actionName[requester], (value == 0 ? "OFF" : "ON"), _aqualink_data->aqbuttons[buttonIndex].name, (value == 0 ? "OFF" : "ON"));
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL) {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d", buttonIndex, (value == 0 ? OFF : ON));
|
||||
aq_programmer(AQ_PDA_DEVICE_ON_OFF, msg, _aqualink_data);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Check for panel programmable light. if so simple ON isn't going to work well
|
||||
// Could also add "light mode" check, as this is only valid for panel configured light not aqualinkd configured light.
|
||||
if ((_aqualink_data->aqbuttons[buttonIndex].special_mask & PROGRAM_LIGHT) == PROGRAM_LIGHT && _aqualink_data->aqbuttons[buttonIndex].led->state == OFF) {
|
||||
// OK Programable light, and no light mode selected. Now let's work out best way to turn it on. serial_adapter protocol will to it without questions,
|
||||
// all other will require programmig.
|
||||
if (isRSSA_ENABLED) {
|
||||
set_aqualink_rssadapter_aux_state(buttonIndex, true);
|
||||
} else {
|
||||
set_light_mode("0", buttonIndex); // 0 means use current light mode
|
||||
}
|
||||
} else {
|
||||
aq_send_cmd(_aqualink_data->aqbuttons[buttonIndex].code);
|
||||
}
|
||||
// Pre set device to state, next status will correct if state didn't take, but this will stop multiple ON messages setting on/off
|
||||
#ifdef PRESTATE_ONOFF
|
||||
if ((_aqualink_data->aqbuttons[buttonIndex].code == KEY_POOL_HTR || _aqualink_data->aqbuttons[buttonIndex].code == KEY_SPA_HTR ||
|
||||
_aqualink_data->aqbuttons[buttonIndex].code == KEY_SOLAR_HTR) &&
|
||||
value > 0) {
|
||||
_aqualink_data->aqbuttons[buttonIndex].led->state = ENABLE; // if heater and set to on, set pre-status to enable.
|
||||
//_aqualink_data->updated = true;
|
||||
} else if (isRSSA_ENABLED || ((_aqualink_data->aqbuttons[buttonIndex].special_mask & PROGRAM_LIGHT) != PROGRAM_LIGHT)) {
|
||||
_aqualink_data->aqbuttons[buttonIndex].led->state = (value == 0 ? OFF : ON); // as long as it's not programmable light , pre-set to on/off
|
||||
//_aqualink_data->updated = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// If it's a timer, start the timer
|
||||
if (timer) {
|
||||
start_timer(_aqualink_data, &_aqualink_data->aqbuttons[buttonIndex], value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void create_program_request(netRequest requester, action_type type, int value, int id) // id is only valid for PUMP RPM
|
||||
{
|
||||
if (_aqualink_data->unactioned.type != NO_ACTION && type != _aqualink_data->unactioned.type)
|
||||
LOG(NET_LOG,LOG_ERR, "%s: About to overwrite unactioned panel program\n",actionName[requester]);
|
||||
|
||||
if (type == POOL_HTR_SETOINT || type == SPA_HTR_SETOINT || type == FREEZE_SETPOINT || type == SWG_SETPOINT ) {
|
||||
_aqualink_data->unactioned.value = setpoint_check(type, value, _aqualink_data);
|
||||
if (value != _aqualink_data->unactioned.value)
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: requested setpoint value %d is invalid, change to %d\n",actionName[requester], value, _aqualink_data->unactioned.value);
|
||||
} else if (type == PUMP_RPM) {
|
||||
//_aqualink_data->unactioned.value = RPM_check(_aqualink_data->pumps[id].pumpType , value, _aqualink_data);
|
||||
_aqualink_data->unactioned.value = value;
|
||||
//if (value != _aqualink_data->unactioned.value)
|
||||
// LOG(NET_LOG,LOG_NOTICE, "%s: requested Pump value %d is invalid, change to %d\n",actionName[requester], value, _aqualink_data->unactioned.value);
|
||||
} else if (type == PUMP_VSPROGRAM) {
|
||||
//_aqualink_data->unactioned.value = value;
|
||||
//if (value != _aqualink_data->unactioned.value)
|
||||
LOG(NET_LOG,LOG_ERR, "%s: requested Pump vsp program is not implimented yet\n",actionName[requester], value, _aqualink_data->unactioned.value);
|
||||
} else {
|
||||
// SWG_BOOST & PUMP_RPM
|
||||
_aqualink_data->unactioned.value = value;
|
||||
}
|
||||
|
||||
_aqualink_data->unactioned.type = type;
|
||||
_aqualink_data->unactioned.id = id; // This is only valid for pump.
|
||||
|
||||
if (requester == NET_MQTT) // We can get multiple MQTT requests from some, so this will wait for last one to come in.
|
||||
time(&_aqualink_data->unactioned.requested);
|
||||
else
|
||||
_aqualink_data->unactioned.requested = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef AQ_PDA
|
||||
void create_PDA_on_off_request(aqkey *button, bool isON)
|
||||
{
|
||||
int i;
|
||||
char msg[PTHREAD_ARG];
|
||||
|
||||
for (i=0; i < _aqualink_data->total_buttons; i++) {
|
||||
if (_aqualink_data->aqbuttons[i].code == button->code) {
|
||||
sprintf(msg, "%-5d%-5d", i, (isON? ON : OFF));
|
||||
aq_programmer(AQ_PDA_DEVICE_ON_OFF, msg, _aqualink_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
2109
aq_programmer.c
2109
aq_programmer.c
File diff suppressed because it is too large
Load Diff
|
@ -41,6 +41,7 @@ typedef enum emulation_type{
|
|||
|
||||
typedef enum {
|
||||
AQP_NULL = -1,
|
||||
// ********* Generic Programming options, these are Allbutton by Default
|
||||
AQ_GET_POOL_SPA_HEATER_TEMPS,
|
||||
AQ_GET_FREEZE_PROTECT_TEMP,
|
||||
AQ_SET_TIME,
|
||||
|
@ -48,24 +49,30 @@ typedef enum {
|
|||
AQ_SET_SPA_HEATER_TEMP,
|
||||
AQ_SET_FRZ_PROTECTION_TEMP,
|
||||
AQ_GET_DIAGNOSTICS_MODEL,
|
||||
//AQ_SEND_CMD,
|
||||
AQ_GET_PROGRAMS,
|
||||
AQ_SET_LIGHTPROGRAM_MODE,
|
||||
AQ_SET_LIGHTCOLOR_MODE,
|
||||
AQ_SET_SWG_PERCENT,
|
||||
AQ_PDA_DEVICE_STATUS,
|
||||
AQ_PDA_DEVICE_ON_OFF,
|
||||
AQ_GET_AUX_LABELS,
|
||||
AQ_SET_BOOST,
|
||||
AQ_SET_PUMP_RPM,
|
||||
AQ_SET_PUMP_VS_PROGRAM,
|
||||
// ******** Delimiter make sure to change MAX/MIN below
|
||||
// NSF Need to add Specific ALL Button ones here
|
||||
// ******** Delimiter make sure to change MAX/MIN below
|
||||
// NSF Need to add ALL Specific PDA ones here
|
||||
// ******** PDA Delimiter make sure to change MAX/MIN below
|
||||
AQ_PDA_INIT,
|
||||
AQ_PDA_WAKE_INIT,
|
||||
// ******** Delimiter make sure to change MAX/MIN below
|
||||
AQ_PDA_DEVICE_STATUS,
|
||||
AQ_PDA_DEVICE_ON_OFF,
|
||||
AQ_PDA_AUX_LABELS,
|
||||
AQ_PDA_SET_BOOST,
|
||||
AQ_PDA_SET_SWG_PERCENT,
|
||||
AQ_PDA_GET_AUX_LABELS,
|
||||
AQ_PDA_SET_POOL_HEATER_TEMPS,
|
||||
AQ_PDA_SET_SPA_HEATER_TEMPS,
|
||||
AQ_PDA_SET_FREEZE_PROTECT_TEMP,
|
||||
AQ_PDA_SET_TIME,
|
||||
AQ_PDA_GET_POOL_SPA_HEATER_TEMPS,
|
||||
AQ_PDA_GET_FREEZE_PROTECT_TEMP,
|
||||
// ******** OneTouch Delimiter make sure to change MAX/MIN below
|
||||
AQ_SET_ONETOUCH_PUMP_RPM,
|
||||
AQ_SET_ONETOUCH_MACRO,
|
||||
AQ_GET_ONETOUCH_SETPOINTS,
|
||||
|
@ -76,7 +83,7 @@ typedef enum {
|
|||
AQ_SET_ONETOUCH_TIME,
|
||||
AQ_SET_ONETOUCH_BOOST,
|
||||
AQ_SET_ONETOUCH_SWG_PERCENT,
|
||||
// ******** Delimiter make sure to change MAX/MIN below
|
||||
// ******** iAqalink Touch Delimiter make sure to change MAX/MIN below
|
||||
AQ_SET_IAQTOUCH_PUMP_RPM,
|
||||
AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM,
|
||||
AQ_GET_IAQTOUCH_VSP_ASSIGNMENT,
|
||||
|
@ -91,7 +98,7 @@ typedef enum {
|
|||
AQ_SET_IAQTOUCH_SET_TIME,
|
||||
AQ_SET_IAQTOUCH_DEVICE_ON_OFF,
|
||||
AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE,
|
||||
// ******** Delimiter make sure to change MAX/MIN below
|
||||
// ******** RS Serial Adapter Delimiter make sure to change MAX/MIN below
|
||||
AQ_GET_RSSADAPTER_SETPOINTS,
|
||||
AQ_SET_RSSADAPTER_POOL_HEATER_TEMP,
|
||||
AQ_SET_RSSADAPTER_SPA_HEATER_TEMP,
|
||||
|
@ -103,11 +110,11 @@ typedef enum {
|
|||
#define AQP_GENERIC_MIN AQ_GET_POOL_SPA_HEATER_TEMPS
|
||||
#define AQP_GENERIC_MAX AQ_SET_PUMP_VS_PROGRAM
|
||||
|
||||
#define AQP_ALLBUTTON_MIN AQP_NULL
|
||||
#define AQP_ALLBUTTONL_MAX AQP_NULL
|
||||
#define AQP_ALLBUTTON_MIN AQ_GET_POOL_SPA_HEATER_TEMPS
|
||||
#define AQP_ALLBUTTONL_MAX AQ_SET_BOOST
|
||||
|
||||
#define AQP_PDA_MIN AQ_PDA_INIT
|
||||
#define AQP_PDA_MAX AQ_PDA_WAKE_INIT
|
||||
#define AQP_PDA_MAX AQ_SET_ONETOUCH_SWG_PERCENT
|
||||
|
||||
#define AQP_ONETOUCH_MIN AQ_SET_ONETOUCH_PUMP_RPM
|
||||
#define AQP_ONETOUCH_MAX AQ_SET_ONETOUCH_SWG_PERCENT
|
||||
|
@ -145,10 +152,10 @@ bool in_iaqt_programming_mode(struct aqualinkdata *aq_data);
|
|||
bool in_swg_programming_mode(struct aqualinkdata *aq_data);
|
||||
bool in_light_programming_mode(struct aqualinkdata *aq_data);
|
||||
bool in_allb_programming_mode(struct aqualinkdata *aq_data);
|
||||
void aq_send_cmd(unsigned char cmd);
|
||||
//void aq_send_cmd(unsigned char cmd);
|
||||
void queueGetProgramData(emulation_type source_type, struct aqualinkdata *aq_data);
|
||||
//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);
|
||||
|
@ -164,7 +171,7 @@ void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl);
|
|||
//void *set_aqualink_time( void *ptr );
|
||||
//void *get_aqualink_pool_spa_heater_temps( void *ptr );
|
||||
|
||||
int get_aq_cmd_length();
|
||||
//int get_aq_cmd_length();
|
||||
int setpoint_check(int type, int value, struct aqualinkdata *aqdata);
|
||||
int RPM_check(pump_type type, int value, struct aqualinkdata *aqdata);
|
||||
//int RPM_check(int type, int value, struct aqualinkdata *aqdata);
|
||||
|
|
61
aq_serial.c
61
aq_serial.c
|
@ -61,7 +61,68 @@ static struct timespec last_serial_read_time;
|
|||
void send_packet(int fd, unsigned char *packet, int length);
|
||||
//unsigned char getProtocolType(unsigned char* packet);
|
||||
|
||||
emulation_type getJandyDeviceType(unsigned char ID) {
|
||||
|
||||
// Using emulation_type from aqprogrammer. At some point may merge into one
|
||||
// and call device type
|
||||
|
||||
if (ID >= 0x08 && ID <= 0x0B)
|
||||
return ALLBUTTON;
|
||||
if (ID >= 0x40 && ID <= 0x43)
|
||||
return ONETOUCH;
|
||||
if (ID >= 0x48 && ID <= 0x4B)
|
||||
return RSSADAPTER;
|
||||
if (ID >= 0x60 && ID <= 0x63)
|
||||
return AQUAPDA;
|
||||
if (ID >= 0x30 && ID <= 0x33)
|
||||
return IAQTOUCH;
|
||||
|
||||
/*
|
||||
if (ID >= 0x00 && ID <= 0x03)
|
||||
return MASTER;
|
||||
if (ID >= 0x50 && ID <= 0x53)
|
||||
return SWG;
|
||||
if (ID >= 0x20 && ID <= 0x23)
|
||||
return SPA_R;
|
||||
if (ID >= 0x38 && ID <= 0x3B)
|
||||
return LX_HEATER;
|
||||
if (ID >= 0x58 && ID <= 0x5B)
|
||||
return PC_DOCK;
|
||||
if (ID >= 0x68 && ID <= 0x6B)
|
||||
return JXI_HEATER;
|
||||
//if (ID >= 0x70 && ID <= 0x73)
|
||||
if (ID >= 0x78 && ID <= 0x7B)
|
||||
return EPUMP;
|
||||
if (ID >= 0x80 && ID <= 0x83)
|
||||
return CHEM;
|
||||
//if (ID == 0x08)
|
||||
// return KEYPAD;
|
||||
*/
|
||||
return SIM_NONE;
|
||||
}
|
||||
|
||||
const char *getJandyDeviceName(emulation_type etype) {
|
||||
switch(etype){
|
||||
case ALLBUTTON:
|
||||
return "AllButton";
|
||||
break;
|
||||
case ONETOUCH:
|
||||
return "OneTouch";
|
||||
break;
|
||||
case RSSADAPTER:
|
||||
return "RS SerialAdapter";
|
||||
break;
|
||||
case IAQTOUCH:
|
||||
return "iAqualinkTouch";
|
||||
break;
|
||||
case AQUAPDA:
|
||||
return "PDA";
|
||||
break;
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char* get_pentair_packet_type(unsigned char* packet , int length)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <termios.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "aq_programmer.h" // Need this for function getJandyDeviceType due to enum defined their.
|
||||
emulation_type getJandyDeviceType(unsigned char ID);
|
||||
const char *getJandyDeviceName(emulation_type etype);
|
||||
|
||||
#define CONNECTION_ERROR "ERROR No connection to RS control panel"
|
||||
#ifdef AQ_MANAGER
|
||||
#define CONNECTION_RUNNING_SLOG "Running serial_logger, this will take some time"
|
||||
|
|
12
aq_timer.c
12
aq_timer.c
|
@ -136,9 +136,7 @@ void *timer_worker( void *ptr )
|
|||
if ((tmthread->button->special_mask & PROGRAM_LIGHT) == PROGRAM_LIGHT && in_light_programming_mode(tmthread->aq_data)) {
|
||||
LOG(TIMR_LOG, LOG_NOTICE, "Not turning on '%s' as programmer is\n",tmthread->button->name);
|
||||
} else {
|
||||
// crap way to do this, need to use net_service logic in teh future, but should never actually get here
|
||||
LOG(TIMR_LOG, LOG_NOTICE, "turning on '%s'\n",tmthread->button->name);
|
||||
//aq_send_cmd(tmthread->button->code);
|
||||
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER);
|
||||
}
|
||||
}
|
||||
|
@ -166,15 +164,7 @@ void *timer_worker( void *ptr )
|
|||
|
||||
if (tmthread->button->led->state != OFF) {
|
||||
LOG(TIMR_LOG, LOG_INFO, "Timer waking turning '%s' off\n",tmthread->button->name);
|
||||
/*
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL)
|
||||
create_PDA_on_off_request(tmthread->button, false);
|
||||
else
|
||||
#endif
|
||||
aq_send_cmd(tmthread->button->code);
|
||||
*/
|
||||
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER);
|
||||
panel_device_request(tmthread->aq_data, ON_OFF, tmthread->deviceIndex, false, NET_TIMER);
|
||||
} else {
|
||||
LOG(TIMR_LOG, LOG_INFO, "Timer waking '%s' is already off\n",tmthread->button->name);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
// The below will change state of devices before that are actually set on the control panel, this helps
|
||||
// with duplicate messages that come in quick succession that can catch the state before it happens.
|
||||
#define PRESTATE_ONOFF
|
||||
//#define PRESTATE_ONOFF
|
||||
#define PRESTATE_SWG_SETPOINT
|
||||
//#define PRESTATE_HEATER_SETPOINT // This one is not implimented yet
|
||||
|
||||
|
|
787
aqualinkd.c
787
aqualinkd.c
|
@ -43,6 +43,8 @@
|
|||
#include "pda_aq_programmer.h"
|
||||
#include "packetLogger.h"
|
||||
#include "devices_jandy.h"
|
||||
#include "allbutton.h"
|
||||
#include "allbutton_aq_programmer.h"
|
||||
#include "onetouch.h"
|
||||
#include "onetouch_aq_programmer.h"
|
||||
#include "iaqtouch.h"
|
||||
|
@ -125,44 +127,7 @@ void intHandler(int sig_num)
|
|||
#endif
|
||||
}
|
||||
|
||||
void processLEDstate()
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
int byte;
|
||||
int bit;
|
||||
|
||||
for (byte = 0; byte < 5; byte++)
|
||||
{
|
||||
for (bit = 0; bit < 8; bit += 2)
|
||||
{
|
||||
if (((_aqualink_data.raw_status[byte] >> (bit + 1)) & 1) == 1)
|
||||
_aqualink_data.aqualinkleds[i].state = FLASH;
|
||||
else if (((_aqualink_data.raw_status[byte] >> bit) & 1) == 1)
|
||||
_aqualink_data.aqualinkleds[i].state = ON;
|
||||
else
|
||||
_aqualink_data.aqualinkleds[i].state = OFF;
|
||||
|
||||
//LOG(AQUA_LOG,LOG_DEBUG,"Led %d state %d",i+1,_aqualink_data.aqualinkleds[i].state);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// Reset enabled state for heaters, as they take 2 led states
|
||||
if (_aqualink_data.aqualinkleds[POOL_HTR_LED_INDEX - 1].state == OFF && _aqualink_data.aqualinkleds[POOL_HTR_LED_INDEX].state == ON)
|
||||
_aqualink_data.aqualinkleds[POOL_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
|
||||
if (_aqualink_data.aqualinkleds[SPA_HTR_LED_INDEX - 1].state == OFF && _aqualink_data.aqualinkleds[SPA_HTR_LED_INDEX].state == ON)
|
||||
_aqualink_data.aqualinkleds[SPA_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
|
||||
if (_aqualink_data.aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state == OFF && _aqualink_data.aqualinkleds[SOLAR_HTR_LED_INDEX].state == ON)
|
||||
_aqualink_data.aqualinkleds[SOLAR_HTR_LED_INDEX - 1].state = ENABLE;
|
||||
/*
|
||||
for (i=0; i < TOTAL_BUTTONS; i++) {
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "%s = %d", _aqualink_data.aqbuttons[i].name, _aqualink_data.aqualinkleds[i].state);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Should move to panel.
|
||||
bool checkAqualinkTime()
|
||||
{
|
||||
static time_t last_checked = 0;
|
||||
|
@ -270,672 +235,6 @@ bool checkAqualinkTime()
|
|||
}
|
||||
|
||||
|
||||
void setUnits(char *msg)
|
||||
{
|
||||
char buf[AQ_MSGLEN*3];
|
||||
|
||||
rsm_strncpy(buf, (unsigned char *)msg, AQ_MSGLEN*3, AQ_MSGLONGLEN);
|
||||
|
||||
//ascii(buf, msg);
|
||||
LOG(AQUA_LOG,LOG_DEBUG, "Getting temp units from message '%s', looking at '%c'\n", buf, buf[strlen(buf) - 1]);
|
||||
|
||||
if (msg[strlen(msg) - 1] == 'F')
|
||||
_aqualink_data.temp_units = FAHRENHEIT;
|
||||
else if (msg[strlen(msg) - 1] == 'C')
|
||||
_aqualink_data.temp_units = CELSIUS;
|
||||
else
|
||||
_aqualink_data.temp_units = UNKNOWN;
|
||||
|
||||
LOG(AQUA_LOG,LOG_INFO, "Temp Units set to %d (F=0, C=1, Unknown=2)\n", _aqualink_data.temp_units);
|
||||
}
|
||||
|
||||
// Defined as int16_t so 16 bits to mask
|
||||
#define MSG_FREEZE (1 << 0) // 1
|
||||
#define MSG_SERVICE (1 << 1) // 1
|
||||
#define MSG_SWG (1 << 2)
|
||||
#define MSG_BOOST (1 << 3)
|
||||
#define MSG_TIMEOUT (1 << 4)
|
||||
#define MSG_RS13BUTTON (1 << 5)
|
||||
#define MSG_RS14BUTTON (1 << 6)
|
||||
#define MSG_RS15BUTTON (1 << 7)
|
||||
#define MSG_RS16BUTTON (1 << 8)
|
||||
#define MSG_BATTERY_LOW (1 << 9)
|
||||
#define MSG_SWG_DEVICE (1 << 10)
|
||||
/*
|
||||
#define SET_FLAG(n, f) ((n) |= (f))
|
||||
#define CHK_FLAG(n, f) ((n) & (f))
|
||||
*/
|
||||
#ifdef AQ_RS16
|
||||
int16_t RS16_endswithLEDstate(char *msg)
|
||||
{
|
||||
char *sp;
|
||||
int i;
|
||||
aqledstate state = LED_S_UNKNOWN;
|
||||
|
||||
//if (_aqconfig_.rs_panel_size < 16)
|
||||
if (PANEL_SIZE() < 16)
|
||||
return false;
|
||||
|
||||
sp = strrchr(msg, ' ');
|
||||
|
||||
if( sp == NULL )
|
||||
return false;
|
||||
|
||||
if (strncasecmp(sp, " on", 3) == 0)
|
||||
state = ON;
|
||||
else if (strncasecmp(sp, " off", 4) == 0)
|
||||
state = OFF;
|
||||
else if (strncasecmp(sp, " enabled", 8) == 0) // Total guess, need to check
|
||||
state = ENABLE;
|
||||
else if (strncasecmp(sp, " no idea", 8) == 0) // need to figure out these states
|
||||
state = FLASH;
|
||||
|
||||
if (state == LED_S_UNKNOWN)
|
||||
return false;
|
||||
|
||||
// Only need to start at Aux B5->B8 (12-15)
|
||||
// Loop over only aqdata->aqbuttons[13] to aqdata->aqbuttons[16]
|
||||
for (i = _aqualink_data.rs16_vbutton_start; i <= _aqualink_data.rs16_vbutton_end; i++) {
|
||||
//TOTAL_BUTTONS
|
||||
if ( stristr(msg, _aqualink_data.aqbuttons[i].label) != NULL) {
|
||||
_aqualink_data.aqbuttons[i].led->state = state;
|
||||
LOG(AQUA_LOG,LOG_INFO, "Set %s to %d\n", _aqualink_data.aqbuttons[i].label, _aqualink_data.aqbuttons[i].led->state);
|
||||
// Return true should be the result, but in the if we want to continue to display message
|
||||
//return true;
|
||||
if (i == 13)
|
||||
return MSG_RS13BUTTON;
|
||||
else if (i == 14)
|
||||
return MSG_RS14BUTTON;
|
||||
else if (i == 15)
|
||||
return MSG_RS15BUTTON;
|
||||
else if (i == 16)
|
||||
return MSG_RS16BUTTON;
|
||||
else
|
||||
{
|
||||
LOG(AQUA_LOG,LOG_ERR, "RS16 Button Set error %s to %d, %d is out of scope\n", _aqualink_data.aqbuttons[i].label, _aqualink_data.aqbuttons[i].led->state, i);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void _processMessage(char *message, bool reset);
|
||||
|
||||
void processMessage(char *message)
|
||||
{
|
||||
_processMessage(message, false);
|
||||
}
|
||||
void processMessageReset()
|
||||
{
|
||||
_processMessage(NULL, true);
|
||||
}
|
||||
void _processMessage(char *message, bool reset)
|
||||
{
|
||||
char *msg;
|
||||
static bool _initWithRS = false;
|
||||
//static bool _gotREV = false;
|
||||
//static int freeze_msg_count = 0;
|
||||
//static int service_msg_count = 0;
|
||||
//static int swg_msg_count = 0;
|
||||
//static int boost_msg_count = 0;
|
||||
static int16_t msg_loop = 0;
|
||||
static aqledstate default_frz_protect_state = OFF;
|
||||
// NSF replace message with msg
|
||||
#ifdef AQ_RS16
|
||||
int16_t rs16;
|
||||
#endif
|
||||
|
||||
//msg = stripwhitespace(message);
|
||||
//strcpy(_aqualink_data.last_message, msg);
|
||||
//LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
|
||||
|
||||
|
||||
|
||||
// Check long messages in this if/elseif block first, as some messages are similar.
|
||||
// ie "POOL TEMP" and "POOL TEMP IS SET TO" so want correct match first.
|
||||
//
|
||||
|
||||
//if (stristr(msg, "JANDY AquaLinkRS") != NULL) {
|
||||
if (!reset) {
|
||||
msg = stripwhitespace(message);
|
||||
strcpy(_aqualink_data.last_message, msg);
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Message :- '%s'\n", msg);
|
||||
// Just set this to off, it will re-set since it'll be the only message we get if on
|
||||
_aqualink_data.service_mode_state = OFF;
|
||||
} else {
|
||||
//_aqualink_data.display_message = NULL;
|
||||
_aqualink_data.last_display_message[0] = ' ';
|
||||
_aqualink_data.last_display_message[1] = '\0';
|
||||
|
||||
// Anything that wasn't on during the last set of messages, turn off
|
||||
if ((msg_loop & MSG_FREEZE) != MSG_FREEZE)
|
||||
_aqualink_data.frz_protect_state = default_frz_protect_state;
|
||||
|
||||
if ((msg_loop & MSG_SERVICE) != MSG_SERVICE &&
|
||||
(msg_loop & MSG_TIMEOUT) != MSG_TIMEOUT ) {
|
||||
_aqualink_data.service_mode_state = OFF; // IF we get this message then Service / Timeout is off
|
||||
}
|
||||
|
||||
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && _aqualink_data.swg_led_state != LED_S_UNKNOWN) {
|
||||
// No Additional SWG devices messages like "no flow"
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && _aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF )
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_OFF);
|
||||
else
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_ON);
|
||||
}
|
||||
|
||||
// If no AQUAPURE message, either (no SWG, it's set 0, or it's off).
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && _aqualink_data.swg_led_state != LED_S_UNKNOWN ) {
|
||||
if (_aqualink_data.swg_percent != 0 || _aqualink_data.swg_led_state == ON) {
|
||||
// Something is wrong here. Let's check pump, if on set SWG to 0, if off turn SWE off
|
||||
if ( _aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF) {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
|
||||
setSWGoff(&_aqualink_data);
|
||||
} else {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is on so setting SWG to 0%%\n");
|
||||
changeSWGpercent(&_aqualink_data, 0);
|
||||
}
|
||||
} else if (isIAQT_ENABLED == false && isONET_ENABLED == false && READ_RSDEV_SWG == false ) {
|
||||
//We have no other way to read SWG %=0, so turn SWG on with pump
|
||||
if ( _aqualink_data.aqbuttons[PUMP_INDEX].led->state == ON) {
|
||||
LOG(ALLB_LOG,LOG_INFO, "No AQUAPURE message in cycle, pump is off so setting SWG to off\n");
|
||||
//changeSWGpercent(&_aqualink_data, 0);
|
||||
setSWGenabled(&_aqualink_data);
|
||||
}
|
||||
}
|
||||
// NSF Need something to catch startup when SWG=0 so we set it to enabeled.
|
||||
// when other ways/protocols to detect SWG=0 are turned off.
|
||||
}
|
||||
/*
|
||||
// AQUAPURE=0 we never get that message on ALLBUTTON so don't turn off unless filter pump if off
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && _aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF ) {
|
||||
//_aqualink_data.ar_swg_status = SWG_STATUS_OFF;
|
||||
setSWGoff(&_aqualink_data);
|
||||
}
|
||||
*/
|
||||
if ((msg_loop & MSG_BOOST) != MSG_BOOST) {
|
||||
_aqualink_data.boost = false;
|
||||
_aqualink_data.boost_msg[0] = '\0';
|
||||
_aqualink_data.boost_duration = 0;
|
||||
//if (_aqualink_data.swg_percent >= 101)
|
||||
// _aqualink_data.swg_percent = 0;
|
||||
}
|
||||
|
||||
if ((msg_loop & MSG_BATTERY_LOW) != MSG_BATTERY_LOW)
|
||||
_aqualink_data.battery = OK;
|
||||
|
||||
#ifdef AQ_RS16
|
||||
//if ( _aqconfig_.rs_panel_size >= 16) {
|
||||
//if ( (int)PANEL_SIZE >= 16) { // NSF No idea why this fails on RS-4, but it does. Come back and find out why
|
||||
if ( PANEL_SIZE() >= 16 ) {
|
||||
//printf("Panel size %d What the fuck am I doing here\n",PANEL_SIZE());
|
||||
if ((msg_loop & MSG_RS13BUTTON) != MSG_RS13BUTTON)
|
||||
_aqualink_data.aqbuttons[13].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS14BUTTON) != MSG_RS14BUTTON)
|
||||
_aqualink_data.aqbuttons[14].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS15BUTTON) != MSG_RS15BUTTON)
|
||||
_aqualink_data.aqbuttons[15].led->state = OFF;
|
||||
if ((msg_loop & MSG_RS16BUTTON) != MSG_RS16BUTTON)
|
||||
_aqualink_data.aqbuttons[16].led->state = OFF;
|
||||
}
|
||||
#endif
|
||||
msg_loop = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stristr(msg, LNG_MSG_BATTERY_LOW) != NULL)
|
||||
{
|
||||
_aqualink_data.battery = LOW;
|
||||
msg_loop |= MSG_BATTERY_LOW;
|
||||
strcpy(_aqualink_data.last_display_message, msg); // Also display the message on web UI
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_POOL_TEMP_SET) != NULL)
|
||||
{
|
||||
//LOG(AQUA_LOG,LOG_DEBUG, "**************** pool htr long message: %s", &message[20]);
|
||||
_aqualink_data.pool_htr_set_point = atoi(message + 20);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_SPA_TEMP_SET) != NULL)
|
||||
{
|
||||
//LOG(AQUA_LOG,LOG_DEBUG, "spa htr long message: %s", &message[19]);
|
||||
_aqualink_data.spa_htr_set_point = atoi(message + 19);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_SET) != NULL)
|
||||
{
|
||||
//LOG(AQUA_LOG,LOG_DEBUG, "frz protect long message: %s", &message[28]);
|
||||
_aqualink_data.frz_protect_set_point = atoi(message + 28);
|
||||
_aqualink_data.frz_protect_state = ENABLE;
|
||||
default_frz_protect_state = ENABLE;
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_AIR_TEMP, MSG_AIR_TEMP_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.air_temp = atoi(msg + MSG_AIR_TEMP_LEN);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_POOL_TEMP, MSG_POOL_TEMP_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.pool_temp = atoi(msg + MSG_POOL_TEMP_LEN);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_SPA_TEMP, MSG_SPA_TEMP_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.spa_temp = atoi(msg + MSG_SPA_TEMP_LEN);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
}
|
||||
// NSF If get water temp rather than pool or spa in some cases, then we are in Pool OR Spa ONLY mode
|
||||
else if (strncasecmp(msg, MSG_WATER_TEMP, MSG_WATER_TEMP_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.pool_temp = atoi(msg + MSG_WATER_TEMP_LEN);
|
||||
_aqualink_data.spa_temp = atoi(msg + MSG_WATER_TEMP_LEN);
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_WATER_TEMP1_SET) != NULL)
|
||||
{
|
||||
_aqualink_data.pool_htr_set_point = atoi(message + 28);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_WATER_TEMP2_SET) != NULL)
|
||||
{
|
||||
_aqualink_data.spa_htr_set_point = atoi(message + 27);
|
||||
|
||||
if (_aqualink_data.temp_units == UNKNOWN)
|
||||
setUnits(msg);
|
||||
|
||||
if (isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
changePanelToMode_Only();
|
||||
LOG(ALLB_LOG,LOG_ERR, "AqualinkD set to 'Combo Pool & Spa' but detected 'Only Pool OR Spa' panel, please change config\n");
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_SERVICE_ACTIVE) != NULL)
|
||||
{
|
||||
if (_aqualink_data.service_mode_state == OFF)
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Service Mode\n");
|
||||
_aqualink_data.service_mode_state = ON;
|
||||
msg_loop |= MSG_SERVICE;
|
||||
//service_msg_count = 0;
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_TIMEOUT_ACTIVE) != NULL)
|
||||
{
|
||||
if (_aqualink_data.service_mode_state == OFF)
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AqualinkD set to Timeout Mode\n");
|
||||
_aqualink_data.service_mode_state = FLASH;
|
||||
msg_loop |= MSG_TIMEOUT;
|
||||
//service_msg_count = 0;
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_FREEZE_PROTECTION_ACTIVATED) != NULL)
|
||||
{
|
||||
msg_loop |= MSG_FREEZE;
|
||||
_aqualink_data.frz_protect_state = ON;
|
||||
//freeze_msg_count = 0;
|
||||
strcpy(_aqualink_data.last_display_message, msg); // Also display the message on web UI
|
||||
}
|
||||
/* // Not sure when to do with these for the moment, so no need to compile in the test.
|
||||
else if (stristr(msg, LNG_MSG_CHEM_FEED_ON) != NULL) {
|
||||
}
|
||||
else if (stristr(msg, LNG_MSG_CHEM_FEED_OFF) != NULL) {
|
||||
}
|
||||
*/
|
||||
else if (msg[2] == '/' && msg[5] == '/' && msg[8] == ' ')
|
||||
{ // date in format '08/29/16 MON'
|
||||
strcpy(_aqualink_data.date, msg);
|
||||
}
|
||||
else if (stristr(msg, MSG_SWG_PCT) != NULL)
|
||||
{
|
||||
if (strncasecmp(msg, MSG_SWG_PCT, MSG_SWG_PCT_LEN) == 0 && strncasecmp(msg, "AQUAPURE HRS", 12) != 0) {
|
||||
changeSWGpercent(&_aqualink_data, atoi(msg + MSG_SWG_PCT_LEN));
|
||||
}
|
||||
else if (strncasecmp(msg, "AQUAPURE HRS", 12) != 0 && strncasecmp(msg, "SET AQUAPURE", 12) != 0)
|
||||
{
|
||||
if (strcasestr(msg, MSG_SWG_NO_FLOW) != NULL)
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_NO_FLOW);
|
||||
else if (strcasestr(msg, MSG_SWG_LOW_SALT) != NULL)
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_LOW_SALT);
|
||||
else if (strcasestr(msg, MSG_SWG_HIGH_SALT) != NULL)
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_HI_SALT);
|
||||
else if (strcasestr(msg, MSG_SWG_FAULT) != NULL)
|
||||
setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_GENFAULT);
|
||||
//setSWGdeviceStatus(&_aqualink_data, ALLBUTTON, SWG_STATUS_CHECK_PCB);
|
||||
|
||||
// Any of these messages want to display.
|
||||
strcpy(_aqualink_data.last_display_message, msg);
|
||||
|
||||
msg_loop |= MSG_SWG_DEVICE;
|
||||
}
|
||||
msg_loop |= MSG_SWG;
|
||||
}
|
||||
else if (strncasecmp(msg, MSG_SWG_PPM, MSG_SWG_PPM_LEN) == 0)
|
||||
{
|
||||
_aqualink_data.swg_ppm = atoi(msg + MSG_SWG_PPM_LEN);
|
||||
msg_loop |= MSG_SWG;
|
||||
}
|
||||
else if ((msg[1] == ':' || msg[2] == ':') && msg[strlen(msg) - 1] == 'M')
|
||||
{ // time in format '9:45 AM'
|
||||
strcpy(_aqualink_data.time, msg);
|
||||
// Setting time takes a long time, so don't try until we have all other programmed data.
|
||||
if (_initWithRS == true && strlen(_aqualink_data.date) > 1 && checkAqualinkTime() != true)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "RS time is NOT accurate '%s %s', re-setting on controller!\n", _aqualink_data.time, _aqualink_data.date);
|
||||
aq_programmer(AQ_SET_TIME, NULL, &_aqualink_data);
|
||||
}
|
||||
else if (_initWithRS == false || _aqconfig_.sync_panel_time == false)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS time '%s %s' not checking\n", _aqualink_data.time, _aqualink_data.date);
|
||||
}
|
||||
else if (_initWithRS == true)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS time is accurate '%s %s'\n", _aqualink_data.time, _aqualink_data.date);
|
||||
}
|
||||
// If we get a time message before REV, the controller didn't see us as we started too quickly.
|
||||
/* Don't need to check this anymore with the check for probe before startup.
|
||||
if (_gotREV == false)
|
||||
{
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Getting control panel information\n", msg);
|
||||
aq_programmer(AQ_GET_DIAGNOSTICS_MODEL, NULL, &_aqualink_data);
|
||||
_gotREV = true; // Force it to true just incase we don't understand the model#
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (strstr(msg, " REV ") != NULL || strstr(msg, " REV. ") != NULL)
|
||||
{ // '8157 REV MMM'
|
||||
// A master firmware revision message.
|
||||
strcpy(_aqualink_data.version, msg);
|
||||
rsm_get_revision(_aqualink_data.revision, _aqualink_data.version, strlen(_aqualink_data.version));
|
||||
//_gotREV = true;
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel version %s\n", _aqualink_data.version);
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Control Panel revision %s\n", _aqualink_data.revision);
|
||||
if (_initWithRS == false)
|
||||
{
|
||||
//LOG(ALLBUTTON,LOG_NOTICE, "Standard protocol initialization complete\n");
|
||||
queueGetProgramData(ALLBUTTON, &_aqualink_data);
|
||||
//queueGetExtendedProgramData(ALLBUTTON, &_aqualink_data, _aqconfig_.use_panel_aux_labels);
|
||||
_initWithRS = true;
|
||||
}
|
||||
}
|
||||
else if (stristr(msg, " TURNS ON") != NULL)
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "Program data '%s'\n", msg);
|
||||
}
|
||||
else if (_aqconfig_.override_freeze_protect == TRUE && strncasecmp(msg, "Press Enter* to override Freeze Protection with", 47) == 0)
|
||||
{
|
||||
//send_cmd(KEY_ENTER, aq_data);
|
||||
//aq_programmer(AQ_SEND_CMD, (char *)KEY_ENTER, &_aqualink_data);
|
||||
aq_send_cmd(KEY_ENTER);
|
||||
}
|
||||
// Process any button states (fake LED) for RS12 and above keypads
|
||||
// Text will be button label on or off ie Aux_B2 off or WaterFall off
|
||||
|
||||
#ifdef AQ_RS16
|
||||
//else if ( _aqconfig_.rs_panel_size >= 16 && (rs16 = RS16_endswithLEDstate(msg)) != 0 )
|
||||
else if (PANEL_SIZE() >= 16 && (rs16 = RS16_endswithLEDstate(msg)) != 0 )
|
||||
{
|
||||
msg_loop |= rs16;
|
||||
// Do nothing, just stop other else if statments executing
|
||||
// make sure we also display the message.
|
||||
// Note we only get ON messages here, Off messages will not be sent if something else turned it off
|
||||
// use the Onetouch or iAqua equiptment page for off.
|
||||
strcpy(_aqualink_data.last_display_message, msg);
|
||||
}
|
||||
#endif
|
||||
else if (((msg[4] == ':') || (msg[6] == ':')) && (strncasecmp(msg, "AUX", 3) == 0) )
|
||||
{ // Should probable check we are in programming mode.
|
||||
// 'Aux3: No Label'
|
||||
// 'Aux B1: No Label'
|
||||
int labelid;
|
||||
int ni = 3;
|
||||
if (msg[4] == 'B') { ni = 5; }
|
||||
labelid = atoi(msg + ni);
|
||||
if (labelid > 0 && _aqconfig_.use_panel_aux_labels == true)
|
||||
{
|
||||
if (ni == 5)
|
||||
labelid = labelid + 8;
|
||||
else
|
||||
labelid = labelid + 1;
|
||||
// Aux1: on panel = Button 3 in aqualinkd (button 2 in array)
|
||||
if (strncasecmp(msg+ni+3, "No Label", 8) != 0) {
|
||||
_aqualink_data.aqbuttons[labelid].label = prittyString(cleanalloc(msg+ni+2));
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s label set to '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label);
|
||||
} else {
|
||||
LOG(ALLB_LOG,LOG_NOTICE, "AUX ID %s has no control panel label using '%s'\n", _aqualink_data.aqbuttons[labelid].name, _aqualink_data.aqbuttons[labelid].label);
|
||||
}
|
||||
//_aqualink_data.aqbuttons[labelid + 1].label = cleanalloc(msg + 5);
|
||||
}
|
||||
}
|
||||
// BOOST POOL 23:59 REMAINING
|
||||
else if ( (strncasecmp(msg, "BOOST POOL", 10) == 0) && (strcasestr(msg, "REMAINING") != NULL) ) {
|
||||
// Ignore messages if in programming mode. We get one of these turning off for some strange reason.
|
||||
if (in_programming_mode(&_aqualink_data) == false) {
|
||||
snprintf(_aqualink_data.boost_msg, 6, "%s", &msg[11]);
|
||||
_aqualink_data.boost_duration = rsm_HHMM2min(_aqualink_data.boost_msg);
|
||||
_aqualink_data.boost = true;
|
||||
msg_loop |= MSG_BOOST;
|
||||
msg_loop |= MSG_SWG;
|
||||
//convert_boost_to_duration(_aqualink_data.boost_msg)
|
||||
//if (_aqualink_data.ar_swg_status != SWG_STATUS_ON) {_aqualink_data.ar_swg_status = SWG_STATUS_ON;}
|
||||
if (_aqualink_data.swg_percent != 101) {changeSWGpercent(&_aqualink_data, 101);}
|
||||
//boost_msg_count = 0;
|
||||
//if (_aqualink_data.active_thread.thread_id == 0)
|
||||
strcpy(_aqualink_data.last_display_message, msg); // Also display the message on web UI if not in programming mode
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "Ignoring '%s'\n", msg);
|
||||
//_aqualink_data.display_message = msg;
|
||||
//if (in_programming_mode(&_aqualink_data) == false && _aqualink_data.simulate_panel == false &&
|
||||
if (in_programming_mode(&_aqualink_data) == false &&
|
||||
stristr(msg, "JANDY AquaLinkRS") == NULL &&
|
||||
//stristr(msg, "PUMP O") == NULL &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
|
||||
strncasecmp(msg, "PUMP O", 6) != 0 &&// Catch 'PUMP ON' and 'PUMP OFF' but not 'PUMP WILL TURN ON'
|
||||
stristr(msg, "MAINTAIN") == NULL && // Catch 'MAINTAIN TEMP IS OFF'
|
||||
stristr(msg, "0 PSI") == NULL /* // Catch some erronious message on test harness
|
||||
stristr(msg, "CLEANER O") == NULL &&
|
||||
stristr(msg, "SPA O") == NULL &&
|
||||
stristr(msg, "AUX") == NULL*/
|
||||
)
|
||||
{ // Catch all AUX1 AUX5 messages
|
||||
//_aqualink_data.display_last_message = true;
|
||||
strcpy(_aqualink_data.last_display_message, msg);
|
||||
//rsm_strncpy(_aqualink_data.last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
|
||||
}
|
||||
}
|
||||
|
||||
// Send every message if we are in simulate panel mode
|
||||
//if (_aqualink_data.simulate_panel)
|
||||
// strcpy(_aqualink_data.last_display_message, msg);
|
||||
//rsm_strncpy(_aqualink_data.last_display_message, (unsigned char *)msg, AQ_MSGLONGLEN, AQ_MSGLONGLEN);
|
||||
//ascii(_aqualink_data.last_display_message, msg);
|
||||
|
||||
|
||||
//LOG(ALLB_LOG,LOG_INFO, "RS Message loop :- '%d'\n", msg_loop);
|
||||
|
||||
// We processed the next message, kick any threads waiting on the message.
|
||||
//printf ("Message kicking\n");
|
||||
|
||||
|
||||
kick_aq_program_thread(&_aqualink_data, ALLBUTTON);
|
||||
}
|
||||
|
||||
bool process_packet(unsigned char *packet, int length)
|
||||
{
|
||||
bool rtn = false;
|
||||
//static unsigned char last_packet[AQ_MAXPKTLEN];
|
||||
static unsigned char last_checksum;
|
||||
static char message[AQ_MSGLONGLEN + 1];
|
||||
static int processing_long_msg = 0;
|
||||
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "process_packer()\n", length);
|
||||
|
||||
// Check packet against last check if different.
|
||||
// Should only use the checksum, not whole packet since it's status messages.
|
||||
/*
|
||||
if ( packet[PKT_CMD] == CMD_STATUS && (memcmp(packet, last_packet, length) == 0))
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length);
|
||||
return rtn;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(last_packet, packet, length);
|
||||
_aqualink_data.last_packet_type = packet[PKT_CMD];
|
||||
rtn = true;
|
||||
}
|
||||
*/
|
||||
|
||||
_aqualink_data.last_packet_type = packet[PKT_CMD];
|
||||
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL)
|
||||
{
|
||||
if (isPDA_IAQT) {
|
||||
return false;
|
||||
}
|
||||
return process_pda_packet(packet, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( packet[PKT_CMD] == CMD_STATUS && packet[length-3] == last_checksum && ! in_programming_mode(&_aqualink_data) )
|
||||
{
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received duplicate, ignoring.\n", length);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_checksum = packet[length-3];
|
||||
rtn = true;
|
||||
}
|
||||
|
||||
if (processing_long_msg > 0 && packet[PKT_CMD] != CMD_MSG_LONG)
|
||||
{
|
||||
processing_long_msg = 0;
|
||||
//LOG(AQUA_LOG,LOG_ERR, "RS failed to receive complete long message, received '%s'\n",message);
|
||||
//LOG(AQUA_LOG,LOG_DEBUG, "RS didn't finished receiving of MSG_LONG '%s'\n",message);
|
||||
processMessage(message);
|
||||
}
|
||||
|
||||
LOG(ALLB_LOG,LOG_DEBUG_SERIAL, "RS Received packet type 0x%02hhx length %d.\n", packet[PKT_CMD], length);
|
||||
|
||||
switch (packet[PKT_CMD])
|
||||
{
|
||||
case CMD_ACK:
|
||||
//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);
|
||||
memcpy(_aqualink_data.raw_status, packet + 4, AQ_PSTLEN);
|
||||
processLEDstate();
|
||||
if (_aqualink_data.aqbuttons[PUMP_INDEX].led->state == OFF)
|
||||
{
|
||||
_aqualink_data.pool_temp = TEMP_UNKNOWN;
|
||||
_aqualink_data.spa_temp = TEMP_UNKNOWN;
|
||||
//_aqualink_data.spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
|
||||
}
|
||||
else if (_aqualink_data.aqbuttons[SPA_INDEX].led->state == OFF && isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
//_aqualink_data.spa_temp = _aqconfig_.report_zero_spa_temp?-18:TEMP_UNKNOWN;
|
||||
_aqualink_data.spa_temp = TEMP_UNKNOWN;
|
||||
}
|
||||
else if (_aqualink_data.aqbuttons[SPA_INDEX].led->state == ON && isSINGLE_DEV_PANEL != true)
|
||||
{
|
||||
_aqualink_data.pool_temp = TEMP_UNKNOWN;
|
||||
}
|
||||
|
||||
// COLOR MODE programming relies on state changes, so let any threads know
|
||||
//if (_aqualink_data.active_thread.ptype == AQ_SET_LIGHTPROGRAM_MODE) {
|
||||
if ( in_light_programming_mode(&_aqualink_data) ) {
|
||||
kick_aq_program_thread(&_aqualink_data, ALLBUTTON);
|
||||
}
|
||||
break;
|
||||
case CMD_MSG:
|
||||
case CMD_MSG_LONG:
|
||||
{
|
||||
int index = packet[PKT_DATA]; // Will get 0x00 for complete message, 0x01 for start on long message 0x05 last of long message
|
||||
//printf("RSM received message at index %d '%.*s'\n",index,AQ_MSGLEN,(char *)packet + PKT_DATA + 1);
|
||||
if (index <= 1){
|
||||
memset(message, 0, AQ_MSGLONGLEN + 1);
|
||||
//strncpy(message, (char *)packet + PKT_DATA + 1, AQ_MSGLEN);
|
||||
rsm_strncpy(message, packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
processing_long_msg = index;
|
||||
//LOG(ALLB_LOG,LOG_ERR, "Message %s\n",message);
|
||||
} else {
|
||||
//strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (char *)packet + PKT_DATA + 1, AQ_MSGLEN);
|
||||
//rsm_strncpy(&message[(processing_long_msg * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
rsm_strncpy(&message[( (index-1) * AQ_MSGLEN)], (unsigned char *)packet + PKT_DATA + 1, AQ_MSGLONGLEN, AQ_MSGLEN);
|
||||
//LOG(ALLB_LOG,LOG_ERR, "Long Message %s\n",message);
|
||||
if (++processing_long_msg != index) {
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "Long message index %d doesn't match buffer %d\n",index,processing_long_msg);
|
||||
//printf("RSM Long message index %d doesn't match buffer %d\n",index,processing_long_msg);
|
||||
}
|
||||
#ifdef PROCESS_INCOMPLETE_MESSAGES
|
||||
kick_aq_program_thread(&_aqualink_data, ALLBUTTON);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (index == 0 || index == 5) {
|
||||
//printf("RSM process message '%s'\n",message);
|
||||
|
||||
// MOVED FROM LINE 701 see if less errors
|
||||
//kick_aq_program_thread(&_aqualink_data, ALLBUTTON);
|
||||
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "Processing Message - '%s'\n",message);
|
||||
processMessage(message); // This will kick thread
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case CMD_PROBE:
|
||||
LOG(ALLB_LOG,LOG_DEBUG, "RS Received PROBE length %d.\n", length);
|
||||
//LOG(AQUA_LOG,LOG_INFO, "Synch'ing with Aqualink master device...\n");
|
||||
rtn = false;
|
||||
break;
|
||||
case CMD_MSG_LOOP_ST:
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Received message loop start\n");
|
||||
processMessageReset();
|
||||
rtn = false;
|
||||
break;
|
||||
default:
|
||||
LOG(ALLB_LOG,LOG_INFO, "RS Received unknown packet, 0x%02hhx\n", packet[PKT_CMD]);
|
||||
rtn = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
void action_delayed_request()
|
||||
{
|
||||
|
@ -1344,6 +643,9 @@ int startup(char *self, char *cfgFile)
|
|||
if (_aqconfig_.frame_delay > 0)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "RS485 Frame delay = %dms\n", _aqconfig_.frame_delay);
|
||||
|
||||
if (!_aqconfig_.device_pre_state) // Default is on, so only disply if off.
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Preset Device State = %s\n", bool2text(_aqconfig_.device_pre_state));
|
||||
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
if (_aqconfig_.thread_netservices)
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Thread Network Services = %s\n", bool2text(_aqconfig_.thread_netservices));
|
||||
|
@ -1416,7 +718,7 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type
|
|||
{
|
||||
switch (source) {
|
||||
case ALLBUTTON:
|
||||
send_extended_ack(rs_fd, (packet_buffer[PKT_CMD]==CMD_MSG_LONG?ACK_SCREEN_BUSY_SCROLL:ACK_NORMAL), pop_aq_cmd(&_aqualink_data));
|
||||
send_extended_ack(rs_fd, (packet_buffer[PKT_CMD]==CMD_MSG_LONG?ACK_SCREEN_BUSY_SCROLL:ACK_NORMAL), pop_allb_cmd(&_aqualink_data));
|
||||
//DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AllButton Emulation type Processed packet in");
|
||||
break;
|
||||
case RSSADAPTER:
|
||||
|
@ -1453,7 +755,7 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type
|
|||
LOG(PDA_LOG,LOG_DEBUG, "PDA Aqualink daemon in sleep mode\n");
|
||||
return;
|
||||
} else {
|
||||
send_extended_ack(rs_fd, ACK_PDA, pop_aq_cmd(&_aqualink_data));
|
||||
send_extended_ack(rs_fd, ACK_PDA, pop_pda_cmd(&_aqualink_data));
|
||||
}
|
||||
//DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"PDA Emulation type Processed packet in");
|
||||
break;
|
||||
|
@ -1903,56 +1205,43 @@ void main_loop()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (packet_length > 0 && packet_buffer[PKT_DEST] == _aqconfig_.device_id && getProtocolType(packet_buffer) == JANDY)
|
||||
// Process and packets of devices we are acting as
|
||||
if (packet_length > 0 && getProtocolType(packet_buffer) == JANDY &&
|
||||
(packet_buffer[PKT_DEST] == _aqconfig_.device_id ||
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.rssa_device_id ||
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id ))
|
||||
{
|
||||
if (getLogLevel(AQUA_LOG) >= LOG_DEBUG) {
|
||||
LOG(AQUA_LOG,LOG_DEBUG, "RS received packet of type %s length %d\n", get_packet_type(packet_buffer, packet_length), packet_length);
|
||||
//logPacketRead(packet_buffer, packet_length);
|
||||
}
|
||||
_aqualink_data.updated = process_packet(packet_buffer, packet_length);
|
||||
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL) {
|
||||
// If we are in simulator mode, the sim has already send the ack
|
||||
if (isPDA_IAQT) {
|
||||
//printf("****PDA IAQT Code\n");
|
||||
switch(getJandyDeviceType(packet_buffer[PKT_DEST])){
|
||||
case ALLBUTTON:
|
||||
_aqualink_data.updated = process_allbutton_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ALLBUTTON);
|
||||
break;
|
||||
case RSSADAPTER:
|
||||
_aqualink_data.updated = process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, RSSADAPTER);
|
||||
break;
|
||||
case IAQTOUCH:
|
||||
_aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
_aqualink_data.updated = true; // FORCE UPDATE SINCE THIS IS NOT WORKING YET
|
||||
caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH);
|
||||
if (checkAqualinkTime() == false) // Need to do this better.
|
||||
{aq_programmer(AQ_SET_TIME, NULL, &_aqualink_data);}
|
||||
}
|
||||
else /*if (_aqualink_data.simulator_active == SIM_NONE)*/ {
|
||||
break;
|
||||
case ONETOUCH:
|
||||
_aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH);
|
||||
break;
|
||||
case AQUAPDA:
|
||||
_aqualink_data.updated = process_pda_packet(packet_buffer, packet_length);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, AQUAPDA);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
#ifdef AQ_TM_DEBUG
|
||||
char message[128];
|
||||
sprintf(message,"%s Emulation Processed packet in",getJandyDeviceName(getJandyDeviceType(packet_buffer[PKT_DEST])));
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,message);
|
||||
#endif
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ALLBUTTON);
|
||||
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AllButton Emulation Processed packet in");
|
||||
}
|
||||
else if (packet_length > 0 && isRSSA_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.rssa_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
_aqualink_data.updated = process_rssadapter_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, RSSADAPTER);
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"SerialAdapter Emulation Processed packet in");
|
||||
}
|
||||
#ifdef AQ_ONETOUCH
|
||||
else if (packet_length > 0 && isONET_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
_aqualink_data.updated = process_onetouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, ONETOUCH);
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"OneTouch Emulation Processed packet in");
|
||||
}
|
||||
#endif
|
||||
#ifdef AQ_IAQTOUCH
|
||||
else if (packet_length > 0 && isIAQT_ENABLED && packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id && getProtocolType(packet_buffer) == JANDY) {
|
||||
_aqualink_data.updated = process_iaqtouch_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, IAQTOUCH);
|
||||
DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AquaTouch Emulation Processed packet in");
|
||||
}
|
||||
#endif
|
||||
//else if (packet_length > 0 && _aqconfig_.read_all_devices == true)
|
||||
// Process any packets to readonly devices.
|
||||
else if (packet_length > 0 && _aqconfig_.read_RS485_devmask > 0)
|
||||
{
|
||||
if (getProtocolType(packet_buffer) == JANDY)
|
||||
|
|
7
config.c
7
config.c
|
@ -148,6 +148,7 @@ void init_parameters (struct aqconfig * parms)
|
|||
parms->enable_scheduler = true;
|
||||
parms->ftdi_low_latency = true;
|
||||
parms->frame_delay = 0;
|
||||
parms->device_pre_state = true;
|
||||
|
||||
generate_mqtt_id(parms->mqtt_ID, MQTT_ID_LEN);
|
||||
}
|
||||
|
@ -635,7 +636,11 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
} else if (strncasecmp (param, "rs485_frame_delay", 17) == 0) {
|
||||
_aqconfig_.frame_delay = strtoul(value, NULL, 10);
|
||||
rtn=true;
|
||||
}
|
||||
} else if (strncasecmp (param, "device_pre_state", 16) == 0) {
|
||||
_aqconfig_.device_pre_state = text2bool(value);
|
||||
rtn=true;
|
||||
}
|
||||
|
||||
else if (strncasecmp(param, "button_", 7) == 0) {
|
||||
// Check we have inichalized panel information, if not use any settings we may have
|
||||
if (_aqconfig_.paneltype_mask == 0)
|
||||
|
|
1
config.h
1
config.h
|
@ -100,6 +100,7 @@ struct aqconfig
|
|||
bool enable_scheduler;
|
||||
bool ftdi_low_latency;
|
||||
int frame_delay;
|
||||
bool device_pre_state;
|
||||
#ifdef AQ_NO_THREAD_NETSERVICE
|
||||
int rs_poll_speed; // Need to remove
|
||||
bool thread_netservices; // Need to remove
|
||||
|
|
|
@ -114,6 +114,10 @@ bool processPentairPacket(unsigned char *packet, int packet_length, struct aqual
|
|||
/*
|
||||
VSP Pump Status.
|
||||
|
||||
Mode 0=local control, 1=remote control
|
||||
DriveState = no idea
|
||||
Pressure Curve = see manual
|
||||
Status = below
|
||||
(packet[PEN_HI_B_STATUS] * 256) + packet[PEN_LO_B_STATUS];
|
||||
|
||||
// Below was pulled from another project. 0 doesn;t seem to be accurate.
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script to build arm64 & amd64 containers that are published to docker.io
|
||||
#
|
||||
# This should never be used, unless you want to deploy AqualinkD docker containers to docer.io
|
||||
# It's here incase someone taked over this repo because I'm no longer around
|
||||
#
|
||||
|
||||
IMAGE=aqualinkd
|
||||
|
@ -54,6 +57,9 @@ if echo $DOCKER_TAGS | grep -q $VERSION; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Login first
|
||||
# cat ~sf/.docker.token | docker login --username sfeakes --password-stdin
|
||||
|
||||
echo "Building Docker container for $IMAGE using branch $VERSION"
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 \
|
||||
--file Dockerfile.buildx \
|
||||
|
|
21
hassio.c
21
hassio.c
|
@ -105,6 +105,10 @@ const char *HASSIO_SWG_DISCOVER = "{"
|
|||
"}";
|
||||
|
||||
// Use Fan for VSP
|
||||
// Need to change the max / min. These do NOT lomit the slider in hassio, only the MQTT limits.
|
||||
// So the 0-100% should be 600-3450 RPM and 15-130 GPM (ie 1% would = 600 & 0%=off)
|
||||
// (value-600) / (3450-600) * 100
|
||||
// (value) / 100 * (3450-600) + 600
|
||||
const char *HASSIO_VSP_DISCOVER = "{"
|
||||
"\"device\": {" HASS_DEVICE "},"
|
||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||
|
@ -119,10 +123,10 @@ const char *HASSIO_VSP_DISCOVER = "{"
|
|||
"\"payload_off\": \"0\","
|
||||
"\"percentage_command_topic\": \"%s/%s/%s/set\"," // aqualinkd,filter_pump , RPM|GPM
|
||||
"\"percentage_state_topic\": \"%s/%s/%s\"," // aqualinkd,filter_pump , RPM|GPM
|
||||
"\"percentage_value_template\": \"{{ ((value | float(0) / %d) * 100) | int }}\"," // 3450|130
|
||||
"\"percentage_command_template\": \"{{ ((value | float(0) / 100) * %d) | int }}\"," // 3450|130
|
||||
"\"percentage_value_template\": \"{{ (((value | float(0) - %d) / %d) * 100) | int }}\"," // 600, (3450-600)
|
||||
"\"percentage_command_template\": \"{{ ((value | float(0) / 100) * %d) + %d | int }}\"," // (3450-130), 600
|
||||
"\"speed_range_max\": \"100\","
|
||||
"\"speed_range_min\": \"%d\"," // 18|12 600rpm|15gpm
|
||||
"\"speed_range_min\": \"0\"," // 18|12 600rpm|15gpm
|
||||
"\"qos\": 1,"
|
||||
"\"retain\": false"
|
||||
"}";
|
||||
|
@ -414,17 +418,19 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
|
|||
// VSP Pumps
|
||||
for (i=0; i < aqdata->num_pumps; i++) {
|
||||
int maxspeed=3450; // Min is 600
|
||||
int percent_min=18; // 600 as % of max
|
||||
int minspeed=600; // 600 as % of max
|
||||
char units[4];
|
||||
sprintf(units, "RPM");
|
||||
|
||||
if ( aqdata->pumps[i].pumpType == VFPUMP ) {
|
||||
maxspeed=130; // Min is 15
|
||||
percent_min=12; // 15 as % of max
|
||||
minspeed=15; // 15 as % of max
|
||||
sprintf(units, "GPM");
|
||||
}
|
||||
// Create a FAN for pump against the button it' assigned to
|
||||
// In the future maybe change this to the pump# or change the sensors to button???
|
||||
// Need to change the max / min. These do NOT lomit the slider in hassio, only the MQTT limits.
|
||||
// So the 0-100% should be 600-3450 RPM and 15-130 GPM (ie 1% would = 600 & 0%=off)
|
||||
sprintf(msg, HASSIO_VSP_DISCOVER,
|
||||
_aqconfig_.mqtt_aq_topic,
|
||||
aqdata->pumps[i].button->name,units,
|
||||
|
@ -434,9 +440,8 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
|
|||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,
|
||||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,units,
|
||||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,units,
|
||||
maxspeed,
|
||||
maxspeed,
|
||||
percent_min);
|
||||
minspeed, (maxspeed - minspeed),
|
||||
(maxspeed - minspeed), minspeed);
|
||||
|
||||
sprintf(topic, "%s/fan/aqualinkd/aqualinkd_%s_%s/config", _aqconfig_.mqtt_hass_discover_topic, aqdata->pumps[i].button->name, units);
|
||||
send_mqtt(nc, topic, msg);
|
||||
|
|
|
@ -836,6 +836,7 @@ void *get_aqualink_iaqtouch_freezeprotect( void *ptr )
|
|||
int frz = rsm_atoi(iaqtGetMessageLine(0));
|
||||
if (frz >= 0) {
|
||||
aq_data->frz_protect_set_point = frz;
|
||||
aq_data->frz_protect_state = ON;
|
||||
LOG(IAQT_LOG,LOG_NOTICE, "IAQ Touch Freeze Protection setpoint %d\n",frz);
|
||||
}
|
||||
|
||||
|
|
|
@ -1041,10 +1041,6 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
} else if (strncmp(ri1, "simcmd", 10) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
simulator_send_cmd((unsigned char)value);
|
||||
return uActioned;
|
||||
/*
|
||||
} else if (strncmp(ri1, "rawcommand", 10) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
aq_send_cmd((unsigned char)value);
|
||||
return uActioned;*/
|
||||
#ifdef AQ_MANAGER
|
||||
} else if (strncmp(ri1, "aqmanager", 9) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
return uAQmanager;
|
||||
|
@ -1740,18 +1736,6 @@ void action_domoticz_mqtt_message(struct mg_connection *nc, struct mg_mqtt_messa
|
|||
LOG(NET_LOG,LOG_INFO, "MQTT: DZ: received '%s' for '%s', turning '%s'\n", (nvalue==DZ_OFF?"OFF":"ON"), _aqualink_data->aqbuttons[i].name,(nvalue==DZ_OFF?"OFF":"ON"));
|
||||
//create_panel_request(NET_DZMQTT, i, (nvalue == DZ_OFF?0:1), false);
|
||||
panel_device_request(_aqualink_data, ON_OFF, i, (nvalue == DZ_OFF?0:1), NET_DZMQTT);
|
||||
/*
|
||||
#ifdef AQ_PDA
|
||||
if (isPDA_PANEL) {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d",i, (nvalue == DZ_OFF?OFF:ON) );
|
||||
aq_programmer(AQ_PDA_DEVICE_ON_OFF, msg, _aqualink_data);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
aq_send_cmd(_aqualink_data->aqbuttons[i].code);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
break; // no need to continue in for loop, we found button.
|
||||
|
|
1
pda.c
1
pda.c
|
@ -810,6 +810,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
static bool equiptment_update_loop = false;
|
||||
static bool read_equiptment_menu = false;
|
||||
|
||||
_aqualink_data->last_packet_type = packet[PKT_CMD];
|
||||
|
||||
process_pda_menu_packet(packet, length, in_programming_mode(_aqualink_data));
|
||||
|
||||
|
|
|
@ -51,8 +51,122 @@ bool loopover_devices(struct aqualinkdata *aq_data);
|
|||
bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charlimit);
|
||||
bool select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool waitForNextMenu);
|
||||
|
||||
bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data);
|
||||
bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data);
|
||||
|
||||
static pda_type _PDA_Type;
|
||||
|
||||
//#define USE_ALLBUTTON_QUEUE
|
||||
|
||||
#ifndef USE_ALLBUTTON_QUEUE
|
||||
/* Forcing all these to allbutton for the moment */
|
||||
void waitfor_queue2empty();
|
||||
void send_cmd(unsigned char cmd);
|
||||
unsigned char pop_allb_cmd(struct aqualinkdata *aq_data);
|
||||
int get_allb_queue_length();
|
||||
|
||||
void waitfor_pda_queue2empty() {
|
||||
waitfor_queue2empty();
|
||||
}
|
||||
void send_pda_cmd(unsigned char cmd) {
|
||||
send_cmd(cmd);
|
||||
}
|
||||
unsigned char pop_pda_cmd(struct aqualinkdata *aq_data){
|
||||
return pop_allb_cmd(aq_data);
|
||||
}
|
||||
int get_pda_queue_length(){
|
||||
return get_allb_queue_length();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Use out own queue.
|
||||
// This is NOT working correctly, need to come back and fix
|
||||
|
||||
#define MAX_STACK 20
|
||||
int _pda_cmdstack_place = 0;
|
||||
unsigned char _pda_cmd_queue[MAX_STACK];
|
||||
unsigned char _pda_command = NUL;
|
||||
|
||||
bool waitfor_pda_queue2empty();
|
||||
|
||||
int get_pda_queue_length(){
|
||||
return _pda_cmdstack_place;
|
||||
}
|
||||
|
||||
bool push_pda_cmd(unsigned char cmd) {
|
||||
_pda_command = cmd;
|
||||
/*
|
||||
if (_pda_cmdstack_place < MAX_STACK) {
|
||||
_pda_cmd_queue[_pda_cmdstack_place] = cmd;
|
||||
_pda_cmdstack_place++;
|
||||
} else {
|
||||
LOG(PDA_LOG, LOG_ERR, "Command queue overflow, too many unsent commands to RS control panel\n");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
void send_pda_cmd(unsigned char cmd) {
|
||||
if (waitfor_pda_queue2empty()) {
|
||||
push_pda_cmd(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char pop_pda_cmd(struct aqualinkdata *aq_data)
|
||||
{
|
||||
unsigned char cmd = NUL;
|
||||
|
||||
if (_pda_command != NUL && aq_data->last_packet_type == CMD_STATUS) {
|
||||
cmd = _pda_command;
|
||||
_pda_command = NUL;
|
||||
}
|
||||
/*
|
||||
// Only send commands on status messages
|
||||
if (get_pda_queue_length() > 0 && aq_data->last_packet_type == CMD_STATUS) {
|
||||
cmd = _pda_cmd_queue[0];
|
||||
_pda_cmdstack_place--;
|
||||
LOG(PDA_LOG, LOG_DEBUG_SERIAL, "RS SEND cmd '0x%02hhx'\n", cmd);
|
||||
memmove(&_pda_cmd_queue[0], &_pda_cmd_queue[1], sizeof(unsigned char) * _pda_cmdstack_place ) ;
|
||||
}
|
||||
*/
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
bool waitfor_pda_queue2empty() {
|
||||
int i=0;
|
||||
|
||||
if (_pda_command != NUL) {
|
||||
LOG(PDA_LOG, LOG_DEBUG, "Waiting for queue to empty\n");
|
||||
}
|
||||
|
||||
while ( (_pda_command != NUL) && ( i++ < PROGRAMMING_POLL_COUNTER) ) {
|
||||
delay(100);
|
||||
}
|
||||
/*
|
||||
if (get_pda_queue_length() > 0) {
|
||||
LOG(PDA_LOG, LOG_DEBUG, "Waiting for queue to empty\n");
|
||||
}
|
||||
|
||||
while ( (get_pda_queue_length() > 0) && ( i++ < PROGRAMMING_POLL_COUNTER) ) {
|
||||
delay(100);
|
||||
}
|
||||
*/
|
||||
if (i >= PROGRAMMING_POLL_COUNTER) {
|
||||
LOG(PDA_LOG, LOG_ERR, "Send command Queue did not empty, timeout\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Each RS message / call to this function is around 0.2 seconds apart
|
||||
//#define MAX_ACK_FOR_THREAD 200 // ~40 seconds (Init takes 30)
|
||||
|
@ -141,7 +255,7 @@ bool loopover_devices(struct aqualinkdata *aq_data) {
|
|||
|
||||
// Should look for message "ALL OFF", that's end of device list.
|
||||
for (i=0; i < 18 && (index = pda_find_m_index("ALL OFF")) == -1 ; i++) {
|
||||
send_cmd(KEY_PDA_DOWN);
|
||||
send_pda_cmd(KEY_PDA_DOWN);
|
||||
//waitForMessage(aq_data, NULL, 1);
|
||||
waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_MSG_LONG,8);
|
||||
}
|
||||
|
@ -180,7 +294,7 @@ bool find_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, int charli
|
|||
if (strncasecmp(pda_m_line(9)," ^^ MORE", 10) == 0) {
|
||||
int j;
|
||||
for(j=0; j < 20; j++) {
|
||||
send_cmd(KEY_PDA_DOWN);
|
||||
send_pda_cmd(KEY_PDA_DOWN);
|
||||
//delay(500);
|
||||
//wait_for_empty_cmd_buffer();
|
||||
//waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,2);
|
||||
|
@ -285,26 +399,26 @@ 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))) {
|
||||
cnt = i - min_index + max_index - index + 1;
|
||||
for (i=0; i < cnt; i++) {
|
||||
waitfor_queue2empty();
|
||||
send_cmd(KEY_PDA_UP);
|
||||
waitfor_pda_queue2empty();
|
||||
send_pda_cmd(KEY_PDA_UP);
|
||||
}
|
||||
} else {
|
||||
for (i=pda_m_hlightindex(); i < index; i++) {
|
||||
waitfor_queue2empty();
|
||||
send_cmd(KEY_PDA_DOWN);
|
||||
waitfor_pda_queue2empty();
|
||||
send_pda_cmd(KEY_PDA_DOWN);
|
||||
}
|
||||
}
|
||||
} else if (i > index) {
|
||||
if ((min_index != -1) && ((i - index) > (index - min_index + max_index - i + 1))) {
|
||||
cnt = i - min_index + max_index - index + 1;
|
||||
for (i=0; i < cnt; i++) {
|
||||
waitfor_queue2empty();
|
||||
send_cmd(KEY_PDA_UP);
|
||||
waitfor_pda_queue2empty();
|
||||
send_pda_cmd(KEY_PDA_UP);
|
||||
}
|
||||
} else {
|
||||
for (i=pda_m_hlightindex(); i > index; i--) {
|
||||
waitfor_queue2empty();
|
||||
send_cmd(KEY_PDA_UP);
|
||||
waitfor_pda_queue2empty();
|
||||
send_pda_cmd(KEY_PDA_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +439,7 @@ bool _select_pda_menu_item(struct aqualinkdata *aq_data, char *menuText, bool wa
|
|||
//int matchType = loose?-1:1;
|
||||
int matchType = loose?-1:strlen(menuText); // NSF Not way to check this. (release 2.2.0 introduced this with the line above)
|
||||
if ( find_pda_menu_item(aq_data, menuText, matchType) ) {
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
|
||||
LOG(PDA_LOG,LOG_DEBUG, "PDA Device programmer selected menu item '%s'\n",menuText);
|
||||
if (waitForNextMenu)
|
||||
|
@ -353,7 +467,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
|
||||
if (pda_m_type() == PM_FW_VERSION) {
|
||||
LOG(PDA_LOG,LOG_DEBUG, "goto_pda_menu at FW version menu\n");
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
if (! waitForPDAnextMenu(aq_data)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "PDA Device programmer wait for next menu failed\n");
|
||||
}
|
||||
|
@ -366,14 +480,14 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
while (ret && (pda_m_type() != menu) && cnt <= 5) {
|
||||
switch (menu) {
|
||||
case PM_HOME:
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
break;
|
||||
case PM_EQUIPTMENT_CONTROL:
|
||||
if (pda_m_type() == PM_HOME) {
|
||||
ret = select_pda_menu_item(aq_data, "EQUIPMENT ON/OFF", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
break;
|
||||
|
@ -383,7 +497,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_MAIN) {
|
||||
ret = select_pda_menu_item(aq_data, "PALM OPTIONS", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
break;
|
||||
|
@ -396,7 +510,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_SYSTEM_SETUP) {
|
||||
ret = select_pda_menu_item(aq_data, "LABEL AUX", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
} else {
|
||||
|
@ -410,7 +524,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_MAIN) {
|
||||
ret = select_pda_menu_item(aq_data, "SYSTEM SETUP", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
} else {
|
||||
|
@ -426,7 +540,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_SYSTEM_SETUP) {
|
||||
ret = select_pda_menu_item(aq_data, "FREEZE PROTECT", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
} else {
|
||||
|
@ -439,7 +553,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_MAIN) {
|
||||
ret = select_pda_menu_item(aq_data, "SET AquaPure", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
break;
|
||||
|
@ -450,7 +564,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
ret = select_pda_menu_item_loose(aq_data, "BOOST", true);
|
||||
//ret = select_pda_menu_item(aq_data, "BOOST", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
//printf("****MENU SELECT RETURN %d*****\n",ret);
|
||||
|
@ -471,7 +585,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
//waitForPDAMessageTypesOrMenu(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS,20,"press ANY key",8);
|
||||
}
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
break;
|
||||
|
@ -481,7 +595,7 @@ bool goto_pda_menu(struct aqualinkdata *aq_data, pda_menu_type menu) {
|
|||
} else if (pda_m_type() == PM_MAIN) {
|
||||
ret = select_pda_menu_item(aq_data, "SET TIME", true);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
ret = waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
break;
|
||||
|
@ -541,23 +655,23 @@ void *set_aqualink_PDA_device_on_off( void *ptr )
|
|||
}
|
||||
|
||||
// NSF Added this since DEBUG hitting wrong command
|
||||
//waitfor_queue2empty();
|
||||
//waitfor_pda_queue2empty();
|
||||
|
||||
if ( find_pda_menu_item(aq_data, device_name, 13) ) {
|
||||
if (aq_data->aqbuttons[device].led->state != state) {
|
||||
//printf("*** Select State ***\n");
|
||||
LOG(PDA_LOG,LOG_INFO, "PDA Device On/Off, found device '%s', changing state\n",aq_data->aqbuttons[device].label,state);
|
||||
force_queue_delete(); // NSF This is a bad thing to do. Need to fix this
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
while (get_aq_cmd_length() > 0) { delay(500); }
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
while (get_pda_queue_length() > 0) { delay(500); }
|
||||
// If you are turning on a heater there will be a sub menu to set temp
|
||||
if ((state == ON) && ((device == aq_data->pool_heater_index) || (device == aq_data->spa_heater_index))) {
|
||||
if (! waitForPDAnextMenu(aq_data)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - waitForPDAnextMenu\n",
|
||||
aq_data->aqbuttons[device].label);
|
||||
} else {
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
while (get_aq_cmd_length() > 0) { delay(500); }
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
while (get_pda_queue_length() > 0) { delay(500); }
|
||||
if (!waitForPDAMessageType(aq_data,CMD_PDA_HIGHLIGHT,20)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "PDA Device On/Off: %s on - wait for CMD_PDA_HIGHLIGHT\n",
|
||||
aq_data->aqbuttons[device].label);
|
||||
|
@ -640,7 +754,7 @@ void *set_aqualink_PDA_init( void *ptr )
|
|||
//printf("****** Version '%s' ********\n",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
|
||||
//send_cmd(KEY_PDA_BACK);
|
||||
//send_pda_cmd(KEY_PDA_BACK);
|
||||
//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)) {
|
||||
|
@ -657,12 +771,12 @@ void *set_aqualink_PDA_init( void *ptr )
|
|||
}
|
||||
*/
|
||||
// Get heater setpoints
|
||||
if (! get_PDA_aqualink_pool_spa_heater_temps(aq_data)) {
|
||||
if (! _get_PDA_aqualink_pool_spa_heater_temps(aq_data)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "PDA Init :- Error getting heater setpoints\n");
|
||||
}
|
||||
|
||||
// Get freeze protect setpoint, AquaPalm doesn't have freeze protect in menu.
|
||||
if (_PDA_Type != AQUAPALM && ! get_PDA_freeze_protect_temp(aq_data)) {
|
||||
if (_PDA_Type != AQUAPALM && ! _get_PDA_freeze_protect_temp(aq_data)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "PDA Init :- Error getting freeze setpoints\n");
|
||||
}
|
||||
|
||||
|
@ -702,7 +816,7 @@ void *set_aqualink_PDA_wakeinit( void *ptr )
|
|||
}
|
||||
|
||||
|
||||
bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data) {
|
||||
bool _get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data) {
|
||||
|
||||
if ( _PDA_Type == PDA) {
|
||||
if (! goto_pda_menu(aq_data, PM_FREEZE_PROTECT)) {
|
||||
|
@ -710,7 +824,7 @@ bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data) {
|
|||
}
|
||||
/* select the freeze protect temp to see which devices are enabled by freeze
|
||||
protect */
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
return waitForPDAnextMenu(aq_data);
|
||||
} else {
|
||||
LOG(PDA_LOG,LOG_INFO, "In PDA AquaPalm mode, freezepoints not supported\n");
|
||||
|
@ -718,7 +832,7 @@ bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data) {
|
|||
}
|
||||
}
|
||||
|
||||
bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data) {
|
||||
bool _get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data) {
|
||||
|
||||
// Get heater setpoints
|
||||
if (! goto_pda_menu(aq_data, PM_SET_TEMP)) {
|
||||
|
@ -732,6 +846,30 @@ bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void *get_PDA_aqualink_pool_spa_heater_temps( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_POOL_SPA_HEATER_TEMPS);
|
||||
_get_PDA_aqualink_pool_spa_heater_temps(aq_data);
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *get_PDA_freeze_protect_temp( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_FREEZE_PROTECT_TEMP);
|
||||
_get_PDA_freeze_protect_temp(aq_data);
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool waitForPDAMessageHighlight(struct aqualinkdata *aq_data, int highlighIndex, int numMessageReceived)
|
||||
{
|
||||
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageHighlight index %d\n",highlighIndex);
|
||||
|
@ -818,7 +956,7 @@ bool waitForPDAMessageTypesOrMenu(struct aqualinkdata *aq_data, unsigned char mt
|
|||
{
|
||||
if (gotmenu == false && line > 0 && text != NULL) {
|
||||
if (stristr(pda_m_line(line), text) != NULL) {
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
gotmenu = true;
|
||||
LOG(PDA_LOG,LOG_DEBUG, "waitForPDAMessageTypesOrMenu saw '%s' and line %d\n",text,line);
|
||||
}
|
||||
|
@ -884,48 +1022,74 @@ bool set_PDA_numeric_field_value(struct aqualinkdata *aq_data, int val, int cur_
|
|||
if (val < cur_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) {
|
||||
send_cmd(KEY_PDA_DOWN);
|
||||
send_pda_cmd(KEY_PDA_DOWN);
|
||||
}
|
||||
} else if (val > cur_val) {
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : raise from %d to %d\n", select_label, cur_val, val);
|
||||
for (i = cur_val; i < val; i=i+step) {
|
||||
send_cmd(KEY_PDA_UP);
|
||||
send_pda_cmd(KEY_PDA_UP);
|
||||
}
|
||||
} else {
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : already at %d\n", select_label, val);
|
||||
}
|
||||
|
||||
send_cmd(KEY_PDA_SELECT);
|
||||
send_pda_cmd(KEY_PDA_SELECT);
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Numeric selector %s value : set to %d\n", select_label, val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val) {
|
||||
//bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val) {
|
||||
void *set_PDA_aqualink_SWG_setpoint(void *ptr) {
|
||||
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_SWG_PERCENT);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
val = setpoint_check(SWG_SETPOINT, val, aq_data);
|
||||
|
||||
if (! goto_pda_menu(aq_data, PM_AQUAPURE)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error finding SWG setpoints menu\n");
|
||||
return false;
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
// wait for menu to display to capture current value with process_pda_packet_msg_long_SWG
|
||||
waitForPDAMessageTypes(aq_data,CMD_PDA_HIGHLIGHT,CMD_PDA_HIGHLIGHTCHARS, 10);
|
||||
|
||||
/*
|
||||
if (pda_find_m_index("SET POOL") < 0) {
|
||||
// Single Setpoint Screen
|
||||
return set_PDA_numeric_field_value(aq_data, val, -1, NULL, 5);
|
||||
} else if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) {
|
||||
set_PDA_numeric_field_value(aq_data, val, -1, NULL, 5);
|
||||
} else*/ if (aq_data->aqbuttons[SPA_INDEX].led->state != OFF) {
|
||||
// Dual Setpoint Screen with SPA mode enabled
|
||||
// :TODO: aq_data should have 2 swg_precent values and GUI should be updated to
|
||||
// display and modify both values.
|
||||
return set_PDA_numeric_field_value(aq_data, val, -1, "SET SPA", 5);
|
||||
set_PDA_numeric_field_value(aq_data, val, -1, "SET SPA", 5);
|
||||
} else {
|
||||
// Dual Setpoint Screen with SPA mode disabled
|
||||
return set_PDA_numeric_field_value(aq_data, val, -1, "SET POOL", 5);
|
||||
set_PDA_numeric_field_value(aq_data, val, -1, "SET POOL", 5);
|
||||
}
|
||||
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val)
|
||||
//bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val)
|
||||
void *set_PDA_aqualink_boost(void *ptr)
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_BOOST);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
|
||||
if (! goto_pda_menu(aq_data, PM_BOOST)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error finding BOOST menu\n");
|
||||
return false;
|
||||
|
@ -948,9 +1112,14 @@ bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val)
|
|||
select_pda_menu_item_loose(aq_data, "STOP", false);
|
||||
}
|
||||
|
||||
return true;
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, bool isPool) {
|
||||
char label[10];
|
||||
int cur_val;
|
||||
|
@ -975,7 +1144,7 @@ bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, boo
|
|||
|
||||
if (val == cur_val) {
|
||||
LOG(PDA_LOG,LOG_INFO, "PDA %s setpoint : temp already %d\n", label, val);
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -989,26 +1158,92 @@ bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, boo
|
|||
return true;
|
||||
}
|
||||
|
||||
bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int val) {
|
||||
void *set_aqualink_PDA_pool_heater_temps( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
//char *name;
|
||||
//char *menu_name;
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_POOL_HEATER_TEMPS);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
val = setpoint_check(POOL_HTR_SETOINT, val, aq_data);
|
||||
|
||||
set_PDA_aqualink_heater_setpoint(aq_data, val, true);
|
||||
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
void *set_aqualink_PDA_spa_heater_temps( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
//char *name;
|
||||
//char *menu_name;
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_SPA_HEATER_TEMPS);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
val = setpoint_check(SPA_HTR_SETOINT, val, aq_data);
|
||||
|
||||
set_PDA_aqualink_heater_setpoint(aq_data, val, false);
|
||||
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int val) {
|
||||
void *set_aqualink_PDA_freeze_protectsetpoint( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_FREEZE_PROTECT_TEMP);
|
||||
|
||||
int val = atoi((char*)threadCtrl->thread_args);
|
||||
|
||||
val = setpoint_check(FREEZE_SETPOINT, val, aq_data);
|
||||
|
||||
if (_PDA_Type != PDA) {
|
||||
LOG(PDA_LOG,LOG_INFO, "In PDA AquaPalm mode, freezepoints not supported\n");
|
||||
return false;
|
||||
//return false;
|
||||
} else if (! goto_pda_menu(aq_data, PM_FREEZE_PROTECT)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error finding freeze protect setpoints menu\n");
|
||||
return false;
|
||||
//return false;
|
||||
} else if (! set_PDA_numeric_field_value(aq_data, val, aq_data->frz_protect_set_point, NULL, 1)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error failed to set freeze protect temp value\n");
|
||||
return false;
|
||||
//return false;
|
||||
} else {
|
||||
return waitForPDAnextMenu(aq_data);
|
||||
waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool set_PDA_aqualink_time(struct aqualinkdata *aq_data) {
|
||||
//bool set_PDA_aqualink_time(struct aqualinkdata *aq_data)
|
||||
void *set_PDA_aqualink_time( void *ptr )
|
||||
{
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_SET_TIME);
|
||||
|
||||
if (! goto_pda_menu(aq_data, PM_SET_TIME)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error finding set time menu\n");
|
||||
return false;
|
||||
goto f_end;
|
||||
}
|
||||
struct tm tm;
|
||||
struct tm panel_tm;
|
||||
|
@ -1034,12 +1269,12 @@ Debug: PDA: PDA Menu Line 9 = to continue.
|
|||
if (strptime(pda_m_line(2), "%t%D %a", &panel_tm) == NULL) {
|
||||
LOG(PDA_LOG,LOG_ERR, "set_PDA_aqualink_time read date (%.*s) failed\n",
|
||||
AQ_MSGLEN, pda_m_line(2));
|
||||
return false;
|
||||
goto f_end;
|
||||
}
|
||||
if (strptime(pda_m_line(3), "%t%I:%M %p", &panel_tm) == NULL) {
|
||||
LOG(PDA_LOG,LOG_ERR, "set_PDA_aqualink_time read time (%.*s) failed\n",
|
||||
AQ_MSGLEN, pda_m_line(3));
|
||||
return false;
|
||||
goto f_end;
|
||||
}
|
||||
panel_tm.tm_isdst = tm.tm_isdst;
|
||||
panel_tm.tm_sec = 0;
|
||||
|
@ -1065,13 +1300,26 @@ Debug: PDA: PDA Menu Line 9 = to continue.
|
|||
}
|
||||
|
||||
waitForPDAnextMenu(aq_data);
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
return true;
|
||||
f_end:
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Test ine this.
|
||||
bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data) {
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
//bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data) {
|
||||
void *get_PDA_aqualink_aux_labels( void *ptr ) {
|
||||
|
||||
struct programmingThreadCtrl *threadCtrl;
|
||||
threadCtrl = (struct programmingThreadCtrl *) ptr;
|
||||
#ifdef BETA_PDA_AUTOLABEL
|
||||
struct aqualinkdata *aq_data = threadCtrl->aq_data;
|
||||
|
||||
waitForSingleThreadOrTerminate(threadCtrl, AQ_PDA_GET_AUX_LABELS);
|
||||
|
||||
int i=0;
|
||||
char label[10];
|
||||
|
||||
|
@ -1079,19 +1327,29 @@ bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data) {
|
|||
|
||||
if (! goto_pda_menu(aq_data, PM_AUX_LABEL)) {
|
||||
LOG(PDA_LOG,LOG_ERR, "Error finding aux label menu\n");
|
||||
return false;
|
||||
goto f_end;
|
||||
}
|
||||
|
||||
for (i=1;i<8;i++) {
|
||||
sprintf(label, "AUX%d",i);
|
||||
select_pda_menu_item(aq_data, label, true);
|
||||
send_cmd(KEY_PDA_BACK);
|
||||
send_pda_cmd(KEY_PDA_BACK);
|
||||
waitForPDAnextMenu(aq_data);
|
||||
}
|
||||
|
||||
// Read first page of devices and make some assumptions.
|
||||
|
||||
waitfor_pda_queue2empty();
|
||||
goto_pda_menu(aq_data, PM_HOME);
|
||||
|
||||
f_end:
|
||||
|
||||
#else
|
||||
LOG(PDA_LOG,LOG_INFO, "Finding PDA labels, (NOT IMPLIMENTED)\n");
|
||||
#endif
|
||||
return true;
|
||||
|
||||
cleanAndTerminateThread(threadCtrl);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -7,30 +7,51 @@ typedef enum pda_type {
|
|||
PDA
|
||||
} pda_type;
|
||||
|
||||
|
||||
|
||||
//void waitfor_pda_queue2empty();
|
||||
//void send_pda_cmd(unsigned char cmd);
|
||||
//unsigned char pop_pda_cmd(struct aqualinkdata *aq_data);
|
||||
|
||||
|
||||
unsigned char pop_pda_cmd(struct aqualinkdata *aq_data);
|
||||
|
||||
|
||||
void *get_aqualink_PDA_device_status( void *ptr );
|
||||
void *set_aqualink_PDA_device_on_off( void *ptr );
|
||||
void *set_aqualink_PDA_wakeinit( void *ptr );
|
||||
void *set_aqualink_PDA_init( void *ptr );
|
||||
|
||||
bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, bool isPool);
|
||||
bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val);
|
||||
bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int val);
|
||||
|
||||
bool get_PDA_aqualink_pool_spa_heater_temps(struct aqualinkdata *aq_data);
|
||||
bool get_PDA_freeze_protect_temp(struct aqualinkdata *aq_data);
|
||||
|
||||
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_time(struct aqualinkdata *aq_data);
|
||||
//bool set_PDA_aqualink_heater_setpoint(struct aqualinkdata *aq_data, int val, bool isPool);
|
||||
//bool set_PDA_aqualink_SWG_setpoint(struct aqualinkdata *aq_data, int val);
|
||||
void *set_PDA_aqualink_SWG_setpoint(void *ptr);
|
||||
//bool set_PDA_aqualink_freezeprotect_setpoint(struct aqualinkdata *aq_data, int val);
|
||||
|
||||
|
||||
void *set_aqualink_PDA_pool_heater_temps( void *ptr );
|
||||
void *set_aqualink_PDA_spa_heater_temps( void *ptr );
|
||||
|
||||
void *set_aqualink_PDA_freeze_protectsetpoint( void *ptr );
|
||||
|
||||
//bool get_PDA_aqualink_aux_labels(struct aqualinkdata *aq_data);
|
||||
void *get_PDA_aqualink_aux_labels( void *ptr );
|
||||
void *get_PDA_aqualink_pool_spa_heater_temps( void *ptr );
|
||||
|
||||
//bool set_PDA_aqualink_boost(struct aqualinkdata *aq_data, bool val);
|
||||
void *set_PDA_aqualink_boost(void *ptr);
|
||||
|
||||
//bool set_PDA_aqualink_time(struct aqualinkdata *aq_data);
|
||||
void *set_PDA_aqualink_time( void *ptr );
|
||||
|
||||
/*
|
||||
// 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);
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -41,7 +41,7 @@
|
|||
#define SLOG_MAX 80
|
||||
#define PACKET_MAX 600
|
||||
|
||||
#define VERSION "serial_logger V2.2"
|
||||
#define VERSION "serial_logger V2.3"
|
||||
|
||||
/*
|
||||
typedef enum used {
|
||||
|
@ -64,6 +64,7 @@ struct aqconfig _aqconfig_;
|
|||
|
||||
char _panelType[AQ_MSGLEN];
|
||||
char _panelRev[AQ_MSGLEN];
|
||||
bool _panelPDA = false;
|
||||
|
||||
typedef struct serial_id_log {
|
||||
unsigned char ID;
|
||||
|
@ -259,15 +260,17 @@ char* canUseExtended(unsigned char ID) {
|
|||
return " <-- can use for Aqualinkd (PDA mode only)";
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ID == _goodONETID[i])
|
||||
if (ID == _goodONETID[i] && _panelPDA == false)
|
||||
return " <-- can use for Aqualinkd (Extended Device ID)";
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ID == _goodIAQTID[i])
|
||||
if (ID == _goodIAQTID[i] && _panelPDA == false)
|
||||
return " <-- can use for Aqualinkd (Prefered Extended Device ID)";
|
||||
else if (ID == _goodIAQTID[i] && _panelPDA == true)
|
||||
return " <-- can use for Aqualinkd (PDA mode Expermental only)";
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (ID == _goodRSSAID[i])
|
||||
if (ID == _goodRSSAID[i] && _panelPDA == false)
|
||||
return " <-- can use for Aqualinkd (RSSA ID)";
|
||||
}
|
||||
return "";
|
||||
|
@ -294,6 +297,10 @@ void getPanelInfo(int rs_fd, unsigned char *packet_buffer, int packet_length)
|
|||
else if (msgcnt == 3)
|
||||
rsm_strncpy(_panelType, packet_buffer+4, AQ_MSGLEN, packet_length-5);
|
||||
}
|
||||
|
||||
if (_panelType[1] == 'P' && _panelType[2] == 'D') { // PDA Panel
|
||||
_panelPDA = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_LOGGER
|
||||
|
@ -395,7 +402,8 @@ int main(int argc, char *argv[]) {
|
|||
_aqconfig_.log_protocol_packets = false;
|
||||
_aqconfig_.log_raw_bytes = false;
|
||||
_aqconfig_.ftdi_low_latency = true;
|
||||
|
||||
_aqconfig_.frame_delay = 10;
|
||||
|
||||
printf("AqualinkD %s\n",VERSION);
|
||||
|
||||
if (getuid() != 0) {
|
||||
|
@ -742,16 +750,21 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
|
|||
if (slog[i].inuse == true)
|
||||
continue;
|
||||
|
||||
if (canUseAllB(slog[i].ID) && (mainID == 0x00 || canUsePDA(mainID)))
|
||||
mainID = slog[i].ID;
|
||||
if (canUsePDA(slog[i].ID) && mainID == 0x00)
|
||||
mainID = slog[i].ID;
|
||||
else if (canUseRSSA(slog[i].ID) && rssaID == 0x00)
|
||||
rssaID = slog[i].ID;
|
||||
else if (canUseONET(slog[i].ID) && extID == 0x00)
|
||||
extID = slog[i].ID;
|
||||
else if (canUseIQAT(slog[i].ID) && (extID == 0x00 || canUseONET(extID)))
|
||||
extID = slog[i].ID;
|
||||
if (!_panelPDA) {
|
||||
if (canUseAllB(slog[i].ID) && (mainID == 0x00 || canUsePDA(mainID)))
|
||||
mainID = slog[i].ID;
|
||||
if (canUsePDA(slog[i].ID) && mainID == 0x00)
|
||||
mainID = slog[i].ID;
|
||||
else if (canUseRSSA(slog[i].ID) && rssaID == 0x00)
|
||||
rssaID = slog[i].ID;
|
||||
else if (canUseONET(slog[i].ID) && extID == 0x00)
|
||||
extID = slog[i].ID;
|
||||
else if (canUseIQAT(slog[i].ID) && (extID == 0x00 || canUseONET(extID)))
|
||||
extID = slog[i].ID;
|
||||
} else {
|
||||
if (canUsePDA(slog[i].ID) && mainID == 0x00)
|
||||
mainID = slog[i].ID;
|
||||
}
|
||||
|
||||
}
|
||||
LOG(RSSD_LOG, LOG_NOTICE, "Suggested aqualinkd.conf values\n");
|
||||
|
|
600
time.out
600
time.out
|
@ -1,600 +0,0 @@
|
|||
Debug: RS Serial: Time 0.59 sec (59437865 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10919058 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09934119 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17965098 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07933240 ns)
|
||||
Debug: RS Serial: Time 0.461 sec (461889391 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09914193 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12930179 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10946132 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09939767 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17943857 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07940721 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64939477 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10928577 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12945622 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10947262 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09933341 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17954134 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08930290 ns)
|
||||
Debug: RS Serial: Time 0.462 sec (462875126 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09888860 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13926859 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09938878 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09944415 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17948098 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08928735 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63899667 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09912563 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13953320 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09915989 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10925226 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950732 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08952531 ns)
|
||||
Debug: RS Serial: Time 0.463 sec (463932706 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09847991 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26916220 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10896133 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13942969 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09941396 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10936465 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16949028 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08924216 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60934255 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09926545 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13953173 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09950711 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10964539 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16895881 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09923582 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62950690 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10915410 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08929772 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61924307 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09953915 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10931521 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16944009 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09926138 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64950808 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09962155 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13942839 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09942452 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10958058 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16946065 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09959840 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62955707 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10928058 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12953307 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09964488 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10953502 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16963398 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09928804 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62947318 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10940836 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12956233 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951229 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10973298 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16955713 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09937285 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62953874 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10948465 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13001954 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09878953 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10947780 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950287 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09959118 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62957096 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10920910 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12954474 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09957785 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10964909 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16956398 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09937174 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62955911 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10948725 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12963122 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09961488 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10959539 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16977398 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09938285 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62952077 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10960335 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08950568 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61954767 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09911304 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10956409 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16949916 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08947049 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60954568 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10936910 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12932900 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09938508 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10954113 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17947356 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08962345 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62951132 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952335 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12948751 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958507 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10960836 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17951505 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08956660 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62955818 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10947558 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26958849 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09946081 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13959357 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960452 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10964298 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16952806 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08948679 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60949513 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952150 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12959880 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09914638 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10998871 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17910320 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08955735 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62945910 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10948447 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12948047 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09968544 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10951947 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17954745 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08956530 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62948540 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10942132 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12948047 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10968613 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09963081 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17976170 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08932920 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62911503 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10918299 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08979567 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61869176 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10947576 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09915619 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16978526 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08879903 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60951160 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10942909 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12960380 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10966909 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951470 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17932227 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08941919 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26955311 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10954798 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12942789 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10948835 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08945197 ns)
|
||||
Debug: RS Serial: Time 0.20 sec (20949360 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17943226 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08946067 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63960775 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10913318 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12917493 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10946299 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26928274 ns)
|
||||
Debug: RS Serial: Time 0.21 sec (21964687 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17912819 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08932956 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63955423 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10957150 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12970251 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10945946 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08956326 ns)
|
||||
Debug: RS Serial: Time 0.20 sec (20955138 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950249 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08960919 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63963645 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10888226 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12945381 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10956668 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26977737 ns)
|
||||
Debug: RS Serial: Time 0.21 sec (21913652 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16960749 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08963160 ns)
|
||||
Debug: RS Serial: Time 0.58 sec (58983336 ns)
|
||||
Debug: RS Serial: Time 0.59 sec (59798410 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949113 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12950807 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10965502 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08950308 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56934902 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16948379 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08948920 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63964015 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10923613 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12964380 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10966834 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08948160 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55974795 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17899339 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07947795 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63953088 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950705 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26956774 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10946520 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12958547 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10959909 ns)
|
||||
Debug: RS Serial: Time 0.11 sec (11952904 ns)
|
||||
Debug: RS Serial: Time 0.29 sec (29952536 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07956998 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56971586 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16958749 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08926976 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64950139 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09956932 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12959806 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950780 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08973660 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55932351 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17944337 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07929203 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64952825 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09947155 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12967861 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10944669 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08961622 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55952758 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17959504 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07957979 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64946380 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09957081 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08939826 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62950982 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09932896 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08957881 ns)
|
||||
Debug: RS Serial: Time 0.57 sec (57945210 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17946670 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07953146 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64951064 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09931507 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13962690 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09952655 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08954586 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55958628 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17960688 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07940239 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64956972 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09948414 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13958449 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09950989 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08959456 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55951739 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17958781 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07946813 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64950843 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09931544 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13960153 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09932026 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08953790 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56936087 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16937657 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07935943 ns)
|
||||
Debug: RS Serial: Time 0.64 sec (64948231 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09945636 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13959468 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09954081 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08962900 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56932216 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16941009 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08957512 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63936255 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09941100 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13965709 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09954877 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09957118 ns)
|
||||
Debug: RS Serial: Time 0.53 sec (53915639 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56952901 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16936731 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08956567 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63943291 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10953464 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12934992 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09957988 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09955784 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55954812 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950694 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08957622 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63929495 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09942340 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26963661 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10923465 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13946375 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09961062 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949909 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16969656 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08943326 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60968084 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10937539 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13962727 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960117 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949094 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16965619 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09946006 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61952171 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09956173 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13966301 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09916786 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10940465 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950268 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960228 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62949871 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949465 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12961750 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09963228 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950687 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16960082 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10965057 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61975671 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10953205 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13970652 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951747 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10961612 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16967730 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960154 ns)
|
||||
Debug: RS Serial: Time 0.55 sec (55971960 ns)
|
||||
Debug: RS Serial: Time 0.59 sec (59976903 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10865374 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12969361 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951432 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950965 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16968248 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09949525 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63948142 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950279 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12967139 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09945340 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10963446 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16951823 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09954821 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62933925 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10968260 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12949417 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09927155 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10961927 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16960156 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09962507 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62961332 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10936427 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12958121 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09964284 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950539 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17964632 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08959067 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62951721 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10951575 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12960435 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960376 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10954335 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17966503 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08958474 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62948628 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949557 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12956973 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09954210 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10961260 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17958355 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08960067 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62950962 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10958428 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12953121 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09960839 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10963112 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17952577 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08959826 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56948529 ns)
|
||||
Debug: RS Serial: Time 0.59 sec (59926588 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10955390 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12957565 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09955562 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10960908 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17951744 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08960141 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63951734 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10936946 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26958068 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09965431 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13952486 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10957872 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09955636 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16971174 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08945715 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60953805 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950538 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12958824 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952298 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09959821 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17958651 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08954381 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62965257 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10987685 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13912913 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10962889 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09956784 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17967743 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08954418 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61943300 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10946076 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12978861 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10939983 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09964173 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17944596 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08950974 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62930203 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10943113 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12958861 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952464 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09963228 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17939133 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08942252 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62952035 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10927391 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12926880 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10967834 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09975746 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17951632 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08948752 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56967676 ns)
|
||||
Debug: RS Serial: Time 0.59 sec (59935680 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950779 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12944862 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10960853 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09956192 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17951707 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08961789 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63955585 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10931872 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12948917 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10956612 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12961009 ns)
|
||||
Debug: RS Serial: Time 0.14 sec (14953610 ns)
|
||||
Debug: RS Serial: Time 0.58 sec (58959462 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16947230 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60946193 ns)
|
||||
Debug: RS Serial: Time 0.15 sec (15944661 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08958196 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17959984 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07943683 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63952381 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10937317 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12942417 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10962556 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09957154 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17952521 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08951067 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62959071 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10950094 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12934899 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952667 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09959858 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17954077 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08962159 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62939721 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10942816 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12959899 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10961631 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09955654 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17953836 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08963103 ns)
|
||||
Debug: RS Serial: Time 0.463 sec (463943040 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09827139 ns)
|
||||
Debug: RS Serial: Time 0.26 sec (26962290 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10934576 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13962782 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09950506 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09961524 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17949096 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07956053 ns)
|
||||
Debug: RS Serial: Time 0.61 sec (61962779 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951617 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13972985 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09955191 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958969 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17941484 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08965603 ns)
|
||||
Debug: RS Serial: Time 0.456 sec (456883334 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60906415 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09942321 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13948523 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09968969 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10943297 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16966099 ns)
|
||||
Debug: RS Serial: Time 0.07 sec (07948850 ns)
|
||||
Debug: RS Serial: Time 0.65 sec (65949703 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958173 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13952671 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958247 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10955316 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16963174 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09943673 ns)
|
||||
Debug: RS Serial: Time 0.462 sec (462892078 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09931192 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13954004 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09947118 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10959760 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16959600 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09944598 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62906089 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10943853 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12963416 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09963190 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10972389 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16950100 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958599 ns)
|
||||
Debug: RS Serial: Time 0.462 sec (462882870 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10930908 ns)
|
||||
Debug: RS Serial: Time 0.25 sec (25963554 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949278 ns)
|
||||
Debug: RS Serial: Time 0.13 sec (13953541 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09961061 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10958760 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16948063 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08962863 ns)
|
||||
Debug: RS Serial: Time 0.60 sec (60960246 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10957204 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12939269 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09962654 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10958890 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16956989 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09951117 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62961347 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10934427 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12942750 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09958136 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10938797 ns)
|
||||
Debug: RS Serial: Time 0.16 sec (16941693 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09944488 ns)
|
||||
Debug: RS Serial: Time 0.56 sec (56941841 ns)
|
||||
Debug: RS Serial: Time 0.59 sec (59923845 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10970241 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12940046 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09943876 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10956186 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17965576 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08946196 ns)
|
||||
Debug: RS Serial: Time 0.63 sec (63949564 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10936205 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12953786 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09962654 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949778 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17961446 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08945474 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62968049 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10937816 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12966361 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09959969 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10949667 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17956002 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08957418 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62947735 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10951334 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12962417 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09944617 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10962556 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17945354 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08963603 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62971198 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10948297 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12955416 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09965950 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10952464 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17963298 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08954437 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62976476 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10942890 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12954083 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10891113 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09956728 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17952372 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08953196 ns)
|
||||
Debug: RS Serial: Time 0.62 sec (62958087 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10947223 ns)
|
||||
Debug: RS Serial: Time 0.12 sec (12998156 ns)
|
||||
Debug: RS Serial: Time 0.10 sec (10908947 ns)
|
||||
Debug: RS Serial: Time 0.09 sec (09944839 ns)
|
||||
Debug: RS Serial: Time 0.17 sec (17942521 ns)
|
||||
Debug: RS Serial: Time 0.08 sec (08954029 ns)
|
Loading…
Reference in New Issue