Refactor & Code Cleanup

pull/319/head
sfeakes 2024-06-14 17:11:57 -05:00
parent 40e2c38ce0
commit 60e6541d09
31 changed files with 2867 additions and 3614 deletions

View File

@ -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"]

View File

@ -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

697
allbutton.c Normal file
View File

@ -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;
}

8
allbutton.h Normal file
View File

@ -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_

1359
allbutton_aq_programmer.c Normal file

File diff suppressed because it is too large Load Diff

26
allbutton_aq_programmer.h Normal file
View File

@ -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_

View File

@ -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
*/

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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)
{

View File

@ -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"

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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 \

View File

@ -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);

View File

@ -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);
}

View File

@ -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
View File

@ -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));

View File

@ -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;
}
/*

View File

@ -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.

View File

@ -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
View File

@ -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)

View File

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