mirror of https://github.com/sfeakes/AqualinkD.git
2.4.1 (Dev 0.2)
parent
d447c13777
commit
32f3d8b042
11
Makefile
11
Makefile
|
@ -31,7 +31,8 @@ CC_AMD64 = x86_64-linux-gnu-gcc
|
|||
#LIBS := -lpthread -lm
|
||||
#LIBS := -l pthread -l m
|
||||
#LIBS := -l pthread -l m -static # Take out -static, just for dev
|
||||
LIBS := -lpthread -lm
|
||||
# from documentation -lrt would be needed for glibc 2.17 & prior (debug clock realtime messages), but seems to be needed for armhf 2.24
|
||||
LIBS := -lpthread -lm -lrt
|
||||
|
||||
# Standard compile flags
|
||||
GCCFLAGS = -Wall -O3
|
||||
|
@ -222,10 +223,18 @@ release:
|
|||
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make buildrelease
|
||||
$(info Binaries for release have been built)
|
||||
|
||||
quick:
|
||||
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make quickbuild
|
||||
$(info Binaries for release have been built)
|
||||
|
||||
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
|
||||
buildrelease: clean armhf arm64
|
||||
$(shell cd release && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
|
||||
# This is run inside container Dockerfile.releaseBinariies (aqualinkd-releasebin)
|
||||
quickbuild: armhf arm64
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
|
||||
|
||||
# Rules to pass to make.
|
||||
all: $(MAIN) $(SLOG)
|
||||
|
|
|
@ -10,8 +10,25 @@
|
|||
# docker run -it --mount type=bind,source=./build,target=/build aqualinkd-releasebin bash
|
||||
#
|
||||
# clean method
|
||||
# docker system prune
|
||||
# docker system prune
|
||||
#
|
||||
# armhf =
|
||||
# COLLECT_GCC=arm-linux-gnueabihf-gcc
|
||||
# COLLECT_LTO_WRAPPER=/opt/cross-pi-gcc/libexec/gcc/arm-linux-gnueabihf/6.3.0/lto-wrapper
|
||||
# Target: arm-linux-gnueabihf
|
||||
# Configured with: ../gcc-6.3.0/configure --prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib --enable-linker-build-id
|
||||
# Thread model: posix
|
||||
# gcc version 6.3.0 (GCC)
|
||||
# GLIBC version 2.24
|
||||
#
|
||||
# arm64 =
|
||||
# COLLECT_GCC=aarch64-linux-gnu-gcc
|
||||
# COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/8/lto-wrapper
|
||||
# Target: aarch64-linux-gnu
|
||||
# Configured with: ../src/configure -v --with-pkgversion='Debian 8.3.0-2' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --disable-libphobos --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include
|
||||
# Thread model: posix
|
||||
# gcc version 8.3.0 (Debian 8.3.0-2)
|
||||
# GLIBC 2.28-10+deb10u3
|
||||
#####################################
|
||||
|
||||
FROM debian:buster
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,6 +25,7 @@
|
|||
#include "aq_timer.h"
|
||||
#include "allbutton_aq_programmer.h"
|
||||
#include "rs_msg_utils.h"
|
||||
#include "iaqualink.h"
|
||||
|
||||
void initPanelButtons(struct aqualinkdata *aqdata, bool rspda, int size, bool combo, bool dual);
|
||||
void programDeviceLightMode(struct aqualinkdata *aqdata, int value, int button);
|
||||
|
@ -351,8 +352,19 @@ aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex) {
|
|||
if (strlen(label) <= 0) {
|
||||
button->label = name;
|
||||
} else {
|
||||
button->label = label;
|
||||
button->label = label;
|
||||
}
|
||||
// These 3 vbuttons have a button code on iaqualink protocol, so use that for rssd_code.
|
||||
if (strncasecmp (button->label, "ALL OFF", 7) == 0) {
|
||||
button->rssd_code = IAQ_ALL_OFF;
|
||||
} else if (strncasecmp (button->label, "Spa Mode", 8) == 0) {
|
||||
button->rssd_code = IAQ_SPA_MODE;
|
||||
} else if (strncasecmp (button->label, "Clean Mode", 10) == 0) {
|
||||
button->rssd_code = IAQ_CLEAN_MODE;
|
||||
} else {
|
||||
button->rssd_code = NUL;
|
||||
}
|
||||
|
||||
button->code = NUL;
|
||||
button->dz_idx = DZ_NULL_IDX;
|
||||
button->special_mask |= VIRTUAL_BUTTON; // Could change to special mask vbutton
|
||||
|
@ -614,6 +626,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
|
|||
aqdata->aqbuttons[index].code = KEY_POOL_HTR;
|
||||
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
|
||||
aqdata->aqbuttons[index].special_mask = 0;
|
||||
aqdata->aqbuttons[index].rssd_code = RS_SA_POOLHT;
|
||||
index++;
|
||||
|
||||
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[17-1];
|
||||
|
@ -623,6 +636,7 @@ void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo
|
|||
aqdata->aqbuttons[index].code = KEY_SPA_HTR;
|
||||
aqdata->aqbuttons[index].dz_idx = DZ_NULL_IDX;
|
||||
aqdata->aqbuttons[index].special_mask = 0;
|
||||
aqdata->aqbuttons[index].rssd_code = RS_SA_SPAHT;
|
||||
index++;
|
||||
|
||||
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[19-1];
|
||||
|
@ -743,7 +757,8 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
|
|||
{
|
||||
aqkey *button = &aqdata->aqbuttons[deviceIndex];
|
||||
|
||||
if (button->special_mask & VIRTUAL_BUTTON && button->special_mask & VS_PUMP) {
|
||||
//if ( button->special_mask & VIRTUAL_BUTTON && button->special_mask & VS_PUMP) {
|
||||
if ( isVS_PUMP(button->special_mask) && isVBUTTON(button->special_mask)) {
|
||||
// Virtual Button with VSP is always on.
|
||||
LOG(PANL_LOG, LOG_INFO, "received '%s' for '%s', virtual pump is always on, ignoring", (isON == false ? "OFF" : "ON"), button->name);
|
||||
button->led->state = ON;
|
||||
|
@ -763,9 +778,14 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
|
|||
// AqualinkTouch in PDA mode, we can program light. (if turing off, use standard AQ_PDA_DEVICE_ON_OFF below)
|
||||
programDeviceLightMode(aqdata, (isON?0:-1), deviceIndex); // -1 means off 0 means use current light mode
|
||||
} else {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d", deviceIndex, (isON == false ? OFF : ON));
|
||||
aq_programmer(AQ_PDA_DEVICE_ON_OFF, msg, aqdata);
|
||||
// If we are using AqualinkTouch with iAqualink enabled, we can send button on/off much faster using that.
|
||||
if ( isPDA_IAQT && isIAQL_ACTIVE) {
|
||||
set_iaqualink_aux_state(button, isON);
|
||||
} else {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d", deviceIndex, (isON == false ? OFF : ON));
|
||||
aq_programmer(AQ_PDA_DEVICE_ON_OFF, msg, aqdata);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
|
@ -776,28 +796,36 @@ bool setDeviceState(struct aqualinkdata *aqdata, int deviceIndex, bool isON, req
|
|||
// 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(deviceIndex, true);
|
||||
set_aqualink_rssadapter_aux_state(button, true);
|
||||
} else {
|
||||
//set_light_mode("0", deviceIndex); // 0 means use current light mode
|
||||
programDeviceLightMode(aqdata, 0, deviceIndex); // 0 means use current light mode
|
||||
}
|
||||
} else if (button->special_mask & VIRTUAL_BUTTON) {
|
||||
} else if (isVBUTTON(button->special_mask)) {
|
||||
// Virtual buttons only supported with Aqualink Touch
|
||||
LOG(PANL_LOG, LOG_NOTICE, "********** %s code=0x%02hhx iaq enabled=%s *****\n",button->name, button->rssd_code, isIAQT_ENABLED?"Yes":"No");
|
||||
if (isIAQT_ENABLED) {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d", deviceIndex, (isON == false ? OFF : ON));
|
||||
aq_programmer(AQ_SET_IAQTOUCH_DEVICE_ON_OFF, msg, aqdata);
|
||||
// If it's one of the pre-defined onces & iaqualink is enabled, we can set it easile with button.
|
||||
if ( isIAQL_ACTIVE && button->rssd_code != NUL)
|
||||
{
|
||||
set_iaqualink_aux_state(button, isON);
|
||||
} else {
|
||||
char msg[PTHREAD_ARG];
|
||||
sprintf(msg, "%-5d%-5d", deviceIndex, (isON == false ? OFF : ON));
|
||||
aq_programmer(AQ_SET_IAQTOUCH_DEVICE_ON_OFF, msg, aqdata);
|
||||
}
|
||||
} else {
|
||||
LOG(PANL_LOG, LOG_ERR, "Can only use Aqualink Touch protocol for Virtual Buttons");
|
||||
}
|
||||
} else if ( source == NET_DZMQTT && isRSSA_ENABLED ) {
|
||||
// Domoticz has a bad habbit of resending the same state back to us, when we use the PRESTATE_ONOFF option
|
||||
// since allbutton (default) is stateless, and rssaadapter is statefull, use rssaadapter for any domoricz requests
|
||||
set_aqualink_rssadapter_aux_state(deviceIndex, isON);
|
||||
set_aqualink_rssadapter_aux_state(button, isON);
|
||||
} else if (button->special_mask & PROGRAM_LIGHT && isRSSA_ENABLED) {
|
||||
// If off and program light, use the RS serial adapter since that is overiding the state now.
|
||||
set_aqualink_rssadapter_aux_state(deviceIndex, isON);
|
||||
set_aqualink_rssadapter_aux_state(button, isON);
|
||||
} else {
|
||||
//set_iaqualink_aux_state(button, isON);
|
||||
aq_send_allb_cmd(button->code);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,13 @@ aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex);
|
|||
#define isIAQT_ENABLED ((_aqconfig_.paneltype_mask & RSP_IAQT) == RSP_IAQT)
|
||||
#define isRSSA_ENABLED ((_aqconfig_.paneltype_mask & RSP_RSSA) == RSP_RSSA)
|
||||
#define isEXTP_ENABLED ((_aqconfig_.paneltype_mask & RSP_EXT_PROG) == RSP_EXT_PROG)
|
||||
|
||||
#define isIAQL_ACTIVE ((_aqconfig_.extended_device_id2 != NUL))
|
||||
|
||||
#define isVS_PUMP(mask) ((mask & VS_PUMP) == VS_PUMP)
|
||||
#define isVBUTTON(mask) ((mask & VIRTUAL_BUTTON) == VIRTUAL_BUTTON)
|
||||
#define isPLIGHT(mask) ((mask & PROGRAM_LIGHT) == PROGRAM_LIGHT)
|
||||
|
||||
int PANEL_SIZE();
|
||||
//
|
||||
//#define PANEL_SIZE PANEL_SIZE()
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "color_lights.h"
|
||||
#include "config.h"
|
||||
#include "devices_jandy.h"
|
||||
#include "iaqualink.h"
|
||||
|
||||
#ifdef AQ_DEBUG
|
||||
#include <time.h>
|
||||
|
@ -585,8 +586,16 @@ void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_dat
|
|||
return;
|
||||
}
|
||||
pda_reset_sleep();
|
||||
} else if (isPDA_PANEL && isPDA_IAQT)
|
||||
}
|
||||
else if (isPDA_PANEL && isPDA_IAQT)
|
||||
{
|
||||
if (isIAQL_ACTIVE) { // if we have iAqualink and AqualinkTouch active on PDA, use iAqualink for setpoints.
|
||||
if (r_type == AQ_SET_POOL_HEATER_TEMP) {
|
||||
type = AQ_SET_IAQLINK_POOL_HEATER_TEMP;
|
||||
} else if (r_type == AQ_SET_SPA_HEATER_TEMP) {
|
||||
type = AQ_SET_IAQLINK_SPA_HEATER_TEMP;
|
||||
}
|
||||
}
|
||||
if ( get_programming_mode(type) != IAQTOUCH) {
|
||||
LOG(PROG_LOG, LOG_ERR, "Selected Programming mode '%s' '%d' not supported with PDA control panel in iAqualinkTouch mode\n",ptypeName(type),type);
|
||||
return;
|
||||
|
@ -629,6 +638,14 @@ void _aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_dat
|
|||
increase_aqualink_rssadapter_spa_setpoint(args, aq_data);
|
||||
return; // No need to create this as thread.
|
||||
break;
|
||||
case AQ_SET_IAQLINK_POOL_HEATER_TEMP:
|
||||
set_iaqualink_heater_setpoint(atoi(args), true);
|
||||
return; // No need to create this as thread.
|
||||
break;
|
||||
case AQ_SET_IAQLINK_SPA_HEATER_TEMP:
|
||||
set_iaqualink_heater_setpoint(atoi(args), false);
|
||||
return; // No need to create this as thread.
|
||||
break;
|
||||
default:
|
||||
// Should check that _prog_functions[type] is valid.
|
||||
if( pthread_create( &programmingthread->thread_id , NULL , _prog_functions[type], (void*)programmingthread) < 0) {
|
||||
|
@ -821,43 +838,50 @@ const char *ptypeName(program_type type)
|
|||
#endif
|
||||
#ifdef AQ_IAQTOUCH
|
||||
case AQ_SET_IAQTOUCH_PUMP_VS_PROGRAM:
|
||||
return "Set iAqualink Touch Pump VS Program";
|
||||
return "Set AqualinkTouch Touch Pump VS Program";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_PUMP_RPM:
|
||||
return "Set iAqualink Touch Pump RPM";
|
||||
return "Set AqualinkTouch Touch Pump RPM";
|
||||
break;
|
||||
case AQ_GET_IAQTOUCH_VSP_ASSIGNMENT:
|
||||
return "Get iAqualink Touch Pump Assignment";
|
||||
return "Get AqualinkTouch Touch Pump Assignment";
|
||||
break;
|
||||
case AQ_GET_IAQTOUCH_SETPOINTS:
|
||||
return "Get iAqualink Touch Setpoints";
|
||||
return "Get AqualinkTouch Touch Setpoints";
|
||||
break;
|
||||
case AQ_GET_IAQTOUCH_FREEZEPROTECT:
|
||||
return "Get iAqualink Touch Freezeprotect";
|
||||
return "Get AqualinkTouch Touch Freezeprotect";
|
||||
break;
|
||||
case AQ_GET_IAQTOUCH_AUX_LABELS:
|
||||
return "Get iAqualink AUX Labels";
|
||||
return "Get AqualinkTouch AUX Labels";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SWG_PERCENT:
|
||||
return "Set iAqualink SWG Percent";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SWG_BOOST:
|
||||
return "Set iAqualink Boost";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SPA_HEATER_TEMP:
|
||||
return "Set iAqualink Spa Heater";
|
||||
return "Set AqualinkTouch SWG Percent";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_POOL_HEATER_TEMP:
|
||||
return "Set iAqualink Pool Heater";
|
||||
return "Set AqualinkTouch Pool Heater";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SET_TIME:
|
||||
return "Set iAqualink Set Time";
|
||||
return "Set AqualinkTouch Set Time";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_DEVICE_ON_OFF:
|
||||
return "Set iAqualink Device On/Off";
|
||||
return "Set AqualinkTouch Device On/Off";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE:
|
||||
return "Set iAqualink Light Color (using panel)";
|
||||
return "Set AqualinkTouch Light Color (using panel)";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SWG_BOOST:
|
||||
return "Set AqualinkTouch Boost";
|
||||
break;
|
||||
case AQ_SET_IAQTOUCH_SPA_HEATER_TEMP:
|
||||
return "Set AqualinkTouch Spa Heater";
|
||||
break;
|
||||
// These to same as above, but on the iAqualink protocol, not AqualinkTouch protocol
|
||||
case AQ_SET_IAQLINK_POOL_HEATER_TEMP:
|
||||
return "Set iAqualink Pool Heater";
|
||||
break;
|
||||
case AQ_SET_IAQLINK_SPA_HEATER_TEMP:
|
||||
return "Set iAqualink Pool Heater";
|
||||
break;
|
||||
#endif
|
||||
#ifdef AQ_PDA
|
||||
|
|
|
@ -94,10 +94,12 @@ typedef enum {
|
|||
AQ_GET_IAQTOUCH_AUX_LABELS,
|
||||
AQ_SET_IAQTOUCH_SWG_PERCENT,
|
||||
AQ_SET_IAQTOUCH_SWG_BOOST,
|
||||
AQ_SET_IAQTOUCH_POOL_HEATER_TEMP,
|
||||
AQ_SET_IAQTOUCH_SPA_HEATER_TEMP,
|
||||
AQ_SET_IAQTOUCH_SET_TIME,
|
||||
AQ_SET_IAQTOUCH_DEVICE_ON_OFF,
|
||||
AQ_SET_IAQTOUCH_POOL_HEATER_TEMP,
|
||||
AQ_SET_IAQTOUCH_SPA_HEATER_TEMP,
|
||||
AQ_SET_IAQLINK_POOL_HEATER_TEMP, // Same as above but using iAqualink not AqualinkTouch
|
||||
AQ_SET_IAQLINK_SPA_HEATER_TEMP, // Same as above but using iAqualink not AqualinkTouch
|
||||
AQ_SET_IAQTOUCH_LIGHTCOLOR_MODE,
|
||||
// ******** RS Serial Adapter Delimiter make sure to change MAX/MIN below
|
||||
AQ_GET_RSSADAPTER_SETPOINTS,
|
||||
|
|
|
@ -56,7 +56,7 @@ int _blocking_fds = -1;
|
|||
|
||||
static struct termios _oldtio;
|
||||
|
||||
static struct timespec last_serial_read_time;
|
||||
static struct timespec _last_serial_read_time;
|
||||
|
||||
void send_packet(int fd, unsigned char *packet, int length);
|
||||
//unsigned char getProtocolType(unsigned char* packet);
|
||||
|
@ -224,7 +224,10 @@ const char* get_jandy_packet_type(unsigned char* packet , int length)
|
|||
return "iAq pMessage";
|
||||
break;
|
||||
case CMD_IAQ_PAGE_BUTTON:
|
||||
return "iAq pButton";
|
||||
if (packet[PKT_DEST] == 0x00) // To master is iAqualink2 send command
|
||||
return "iAqualnk sendCmd";
|
||||
else
|
||||
return "iAq pButton";
|
||||
break;
|
||||
case CMD_IAQ_POLL:
|
||||
return "iAq Poll";
|
||||
|
@ -254,7 +257,7 @@ const char* get_jandy_packet_type(unsigned char* packet , int length)
|
|||
return "iAq Main status";
|
||||
break;
|
||||
case CMD_IAQ_1TOUCH_STATUS:
|
||||
return "iAq 1Touch status";
|
||||
return "iAq 1Tch status";
|
||||
break;
|
||||
case CMD_IAQ_AUX_STATUS:
|
||||
return "iAq AUX status";
|
||||
|
@ -841,13 +844,14 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
struct timespec min_frame_wait_time;
|
||||
struct timespec frame_wait_time;
|
||||
struct timespec remainder_time;
|
||||
//struct timespec diff;
|
||||
|
||||
min_frame_wait_time.tv_sec = 0;
|
||||
min_frame_wait_time.tv_nsec = _aqconfig_.frame_delay * 1000000;
|
||||
|
||||
do {
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
timespec_subtract(&elapsed_time, &now, &last_serial_read_time);
|
||||
timespec_subtract(&elapsed_time, &now, &_last_serial_read_time);
|
||||
if (timespec_subtract(&frame_wait_time, &min_frame_wait_time, &elapsed_time)) {
|
||||
break;
|
||||
}
|
||||
|
@ -910,7 +914,7 @@ void send_packet(int fd, unsigned char *packet, int length)
|
|||
//if (_aqconfig_.frame_delay > 0) {
|
||||
#ifndef SERIAL_LOGGER
|
||||
if (_aqconfig_.frame_delay > 0) {
|
||||
timespec_subtract(&elapsed_time, &now, &last_serial_read_time);
|
||||
timespec_subtract(&elapsed_time, &now, &_last_serial_read_time);
|
||||
LOG(RSTM_LOG, LOG_DEBUG, "Time from recv to %s send is %.3f sec\n",
|
||||
(_blocking_mode?"blocking":"non-blocking"),
|
||||
roundf3(timespec2float(&elapsed_time)));
|
||||
|
@ -1000,6 +1004,8 @@ int get_packet_lograw(int fd, unsigned char* packet)
|
|||
}
|
||||
int _get_packet(int fd, unsigned char* packet, bool rawlog)
|
||||
*/
|
||||
|
||||
|
||||
int get_packet(int fd, unsigned char* packet)
|
||||
{
|
||||
unsigned char byte = 0x00;
|
||||
|
@ -1192,20 +1198,25 @@ int get_packet(int fd, unsigned char* packet)
|
|||
return AQSERR_2SMALL;
|
||||
}
|
||||
|
||||
//if (_aqconfig_.frame_delay > 0) {
|
||||
|
||||
if (_aqconfig_.frame_delay > 0 || getLogLevel(RSTM_LOG) >= LOG_DEBUG) {
|
||||
clock_gettime(CLOCK_REALTIME, &packet_end_time);
|
||||
if (getLogLevel(RSTM_LOG) >= LOG_DEBUG) {
|
||||
timespec_subtract(&packet_elapsed, &packet_end_time, &last_serial_read_time);
|
||||
timespec_subtract(&packet_elapsed, &packet_end_time, &_last_serial_read_time);
|
||||
/*
|
||||
LOG(RSTM_LOG, LOG_NOTICE, "Start sec=%ld nsec=%ld\n",_last_serial_read_time.tv_sec,_last_serial_read_time.tv_nsec);
|
||||
LOG(RSTM_LOG, LOG_NOTICE, "End sec=%ld nsec=%ld\n",packet_end_time.tv_sec,packet_end_time.tv_nsec);
|
||||
LOG(RSTM_LOG, LOG_NOTICE, "Elapsed sec=%ld nsec=%ld Time between packets (%.3f sec)\n",packet_elapsed.tv_sec,packet_elapsed.tv_nsec, roundf3(timespec2float(&packet_elapsed)) );
|
||||
*/
|
||||
LOG(RSTM_LOG, LOG_DEBUG, "Time between packets (%.3f sec)\n", roundf3(timespec2float(&packet_elapsed)) );
|
||||
|
||||
}
|
||||
if (_aqconfig_.frame_delay > 0) {
|
||||
memcpy(&last_serial_read_time, &packet_end_time, sizeof(struct timespec));
|
||||
}
|
||||
//if (_aqconfig_.frame_delay > 0) {
|
||||
memcpy(&_last_serial_read_time, &packet_end_time, sizeof(struct timespec));
|
||||
//}
|
||||
}
|
||||
|
||||
//clock_gettime(CLOCK_REALTIME, &last_serial_read_time);
|
||||
//clock_gettime(CLOCK_REALTIME, &_last_serial_read_time);
|
||||
//}
|
||||
//LOG(RSSD_LOG,LOG_DEBUG_SERIAL, "Serial read %d bytes\n",index);
|
||||
if (_aqconfig_.log_protocol_packets || getLogLevel(RSSD_LOG) >= LOG_DEBUG_SERIAL)
|
||||
|
@ -1214,6 +1225,8 @@ int get_packet(int fd, unsigned char* packet)
|
|||
return index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else // PLAYBACKMODE
|
||||
|
||||
// Need to re-write this if we ever use playback mode again. Pull info from aq_serial.old.c
|
||||
|
|
|
@ -57,6 +57,12 @@ const char *getJandyDeviceName(emulation_type etype);
|
|||
#define JANDY_DEC_CHEM_MIN 128 // 0x80
|
||||
#define JANDY_DEC_CHEM_MAX 131 // 0x83
|
||||
|
||||
#define JANDY_DEV_IAQLN_MIN 0xa0 //
|
||||
#define JANDY_DEV_IAQLN_MAX 0xa3 // 0
|
||||
|
||||
#define JANDY_DEV_AQLNK_MIN 0x30 //
|
||||
#define JANDY_DEV_AQLNK_MAX 0x33 // 0
|
||||
|
||||
/*
|
||||
//===== Device ID's =====//
|
||||
//=========================================================================//
|
||||
|
@ -127,6 +133,7 @@ DEV_UNKNOWN_MASK = 0xF8; // Unknown mask, used to reset values
|
|||
//#define AQ_MAXPKTLEN 128 // Max 79 bytes so far, so 128 is a guess at the moment, just seen large packets from iAqualink
|
||||
//#define AQ_MAXPKTLEN 256 // Still getting this at 128, so temp increase to 256 and print message over 128 in aq_serial.c
|
||||
#define AQ_MAXPKTLEN 512 // Still getting this at 128, so temp increase to 256 and print message over 128 in aq_serial.c
|
||||
#define AQ_MAXPKTLEN_SEND 32 // Out biggest send buffer
|
||||
#define AQ_PSTLEN 5
|
||||
#define AQ_MSGLEN 16
|
||||
#define AQ_MSGLONGLEN 128
|
||||
|
|
|
@ -745,6 +745,9 @@ int startup(char *self, char *cfgFile)
|
|||
/* Point of this is to sent ack as quickly as possible, all checks should be done prior to calling this.*/
|
||||
void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type source)
|
||||
{
|
||||
unsigned char *cmd;
|
||||
int size;
|
||||
|
||||
switch (source) {
|
||||
case ALLBUTTON:
|
||||
send_extended_ack(rs_fd, (packet_buffer[PKT_CMD]==CMD_MSG_LONG?ACK_SCREEN_BUSY_SCROLL:ACK_NORMAL), pop_allb_cmd(&_aqualink_data));
|
||||
|
@ -770,15 +773,21 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type
|
|||
if (packet_buffer[PKT_CMD] != CMD_IAQ_CTRL_READY)
|
||||
send_extended_ack(rs_fd, ACK_IAQ_TOUCH, pop_iaqt_cmd(packet_buffer[PKT_CMD]));
|
||||
else {
|
||||
unsigned char *cmd;
|
||||
int size = ref_iaqt_control_cmd(&cmd);
|
||||
size = ref_iaqt_control_cmd(&cmd);
|
||||
send_jandy_command(rs_fd, cmd, size);
|
||||
rem_iaqt_control_cmd(cmd);
|
||||
}
|
||||
//DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AquaTouch Emulation type Processed packet in");
|
||||
break;
|
||||
case IAQUALNK:
|
||||
send_iaqualink_ack(rs_fd, packet_buffer);
|
||||
//send_iaqualink_ack(rs_fd, packet_buffer);
|
||||
size = get_iaqualink_cmd(packet_buffer[PKT_CMD], &cmd);
|
||||
if (size == 2){
|
||||
send_extended_ack(rs_fd, cmd[0], cmd[1]);
|
||||
} else {
|
||||
send_jandy_command(rs_fd, cmd, size);
|
||||
}
|
||||
remove_iaqualink_cmd();
|
||||
break;
|
||||
#endif
|
||||
#ifdef AQ_PDA
|
||||
|
|
|
@ -418,6 +418,7 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
rtn=true;
|
||||
} else if (strncasecmp(param, "enable_iaqualink", 16) == 0) {
|
||||
_aqconfig_.enable_iaqualink = text2bool(value);
|
||||
_aqconfig_.read_RS485_devmask &= ~READ_RS485_IAQUALNK; // This should not be set if we are reading dieectly so turn off mask
|
||||
rtn=true;
|
||||
#endif
|
||||
} else if (strncasecmp(param, "panel_type_size", 15) == 0) {
|
||||
|
@ -596,6 +597,17 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
else
|
||||
_aqconfig_.read_RS485_devmask &= ~READ_RS485_JAN_CHEM;
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "read_RS485_iAqualink", 20) == 0) {
|
||||
/* This should not be used with enable_iaqualink */
|
||||
if (text2bool(value)) {
|
||||
if (_aqconfig_.enable_iaqualink)
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, 'read_RS485_iAqualink' is not valid when 'enable_iaqualink=yes', ignoring read_RS485_iAqualink!\n");
|
||||
else
|
||||
_aqconfig_.read_RS485_devmask |= READ_RS485_IAQUALNK;
|
||||
} else {
|
||||
_aqconfig_.read_RS485_devmask &= ~READ_RS485_IAQUALNK;
|
||||
}
|
||||
rtn=true;
|
||||
} else if (strncasecmp (param, "use_panel_aux_labels", 20) == 0) {
|
||||
_aqconfig_.use_panel_aux_labels = text2bool(value);
|
||||
rtn=true;
|
||||
|
@ -709,7 +721,7 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
int num = strtoul(param + 15, NULL, 10);
|
||||
if (_aqconfig_.paneltype_mask == 0) {
|
||||
// ERROR the vbutton will be irnored.
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, Panel type mush be definied before adding a virtual_button, ignored setting : %s",param);
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, Panel type must be definied before adding a virtual_button, ignored setting : %s",param);
|
||||
//} else if (_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33 ) {
|
||||
// LOG(AQUA_LOG,LOG_WARNING, "Config error, extended_device_id must on of the folowing (0x30,0x31,0x32,0x33), ignored setting : %s",param);
|
||||
} else if (strncasecmp(param + 17, "_label", 6) == 0) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#define READ_RS485_JAN_JXI (1 << 3) // Jandy JX & LXi heater
|
||||
#define READ_RS485_JAN_LX (1 << 4) // Jandy LX heater
|
||||
#define READ_RS485_JAN_CHEM (1 << 5) // Jandy Chemical Feeder
|
||||
#define READ_RS485_IAQUALNK (1 << 6) // Read iAqualink messages
|
||||
|
||||
#define MAX_RSSD_LOG_FILTERS 4
|
||||
|
||||
|
@ -125,6 +126,7 @@ struct aqconfig _aqconfig_;
|
|||
#define READ_RSDEV_JXI ((_aqconfig_.read_RS485_devmask & READ_RS485_JAN_JXI) == READ_RS485_JAN_JXI)
|
||||
#define READ_RSDEV_LX ((_aqconfig_.read_RS485_devmask & READ_RS485_JAN_LX) == READ_RS485_JAN_LX)
|
||||
#define READ_RSDEV_CHEM ((_aqconfig_.read_RS485_devmask & READ_RS485_JAN_CHEM) == READ_RS485_JAN_CHEM)
|
||||
#define READ_RSDEV_iAQLNK ((_aqconfig_.read_RS485_devmask & READ_RS485_IAQUALNK) == READ_RS485_IAQUALNK)
|
||||
|
||||
#define isPDA_IAQT (_aqconfig_.device_id == 0x33)
|
||||
//#define isPDA ((_aqconfig_.paneltype_mask & RSP_PDA) == RSP_PDA)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "utils.h"
|
||||
#include "aq_mqtt.h"
|
||||
#include "packetLogger.h"
|
||||
#include "iaqualink.h"
|
||||
|
||||
/*
|
||||
All button errors
|
||||
|
@ -111,6 +112,11 @@ bool processJandyPacket(unsigned char *packet_buffer, int packet_length, struct
|
|||
rtn = processPacketToJandyChemFeeder(packet_buffer, packet_length, aqdata);
|
||||
previous_packet_to = packet_buffer[PKT_DEST];
|
||||
}
|
||||
else if (READ_RSDEV_iAQLNK && packet_buffer[PKT_DEST] >= JANDY_DEV_AQLNK_MIN && packet_buffer[PKT_DEST] <= JANDY_DEV_AQLNK_MAX
|
||||
&& packet_buffer[PKT_DEST] != _aqconfig_.extended_device_id) // We would have already read extended_device_id frame
|
||||
{
|
||||
process_iAqualinkStatusPacket(packet_buffer, packet_length, aqdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
interestedInNextAck = DRS_NONE;
|
||||
|
|
|
@ -238,9 +238,9 @@ int char2iaqtRSset(unsigned char* packetbuffer, char *msg, int msg_len)
|
|||
return ++bcnt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void createDeviceUpdatePacket() {
|
||||
unsigned char packets[AQ_MAXPKTLEN];
|
||||
unsigned char packets[AQ_MAXPKTLEN_SEND];
|
||||
int cnt;
|
||||
|
||||
packets[0] = DEV_MASTER;
|
||||
|
@ -257,6 +257,7 @@ void createDeviceUpdatePacket() {
|
|||
|
||||
//send_jandy_command(NULL, packets, cnt);
|
||||
}
|
||||
*/
|
||||
|
||||
void processPageMessage(unsigned char *message, int length)
|
||||
{
|
||||
|
@ -1041,10 +1042,15 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd
|
|||
LOG(IAQT_LOG,LOG_DEBUG, "STARTUP Message\n");
|
||||
|
||||
if (_aqconfig_.enable_iaqualink) {
|
||||
LOG(IAQT_LOG,LOG_DEBUG, "Enabling iAqualink Protocol\n");
|
||||
|
||||
// Below will not send 0x29 since queueGetProgramData takes presidance,
|
||||
//iaqt_queue_cmd(0x29);
|
||||
_aqconfig_.extended_device_id2 = _aqconfig_.extended_device_id + 112; // 0x70 in dec
|
||||
if (isPDA_PANEL) {
|
||||
_aqconfig_.extended_device_id2 = _aqconfig_.device_id + 112;
|
||||
} else {
|
||||
_aqconfig_.extended_device_id2 = _aqconfig_.extended_device_id + 112; // 0x70 in dec
|
||||
}
|
||||
LOG(IAQT_LOG,LOG_NOTICE, "Enabling iAqualink Protocol on 0x%02hhx\n",_aqconfig_.extended_device_id2);
|
||||
}
|
||||
//LOG(IAQT_LOG,LOG_ERR, "STARTUP REMOVED GET PANEL DATA FOR TESTING\n");
|
||||
queueGetProgramData(IAQTOUCH, aq_data);
|
||||
|
@ -1117,10 +1123,11 @@ if not programming && poll packet {
|
|||
|
||||
if (probesSinceLastPageCMD > 3) {
|
||||
// Seems to be a bug with wifi device ghosting command on/off, kind-a looks like our page commands don;t take sometimes so wait.
|
||||
// This didn;t fix issue, but see
|
||||
iaqt_queue_cmd(nextPageRequestKey);
|
||||
probesSinceLastPageCMD=0;
|
||||
} else {
|
||||
LOG(IAQT_LOG, LOG_NOTICE, "Waiting to send next page cnt %d\n",probesSinceLastPageCMD);
|
||||
LOG(IAQT_LOG, LOG_INFO, "Waiting to send next page cnt %d\n",probesSinceLastPageCMD);
|
||||
}
|
||||
}
|
||||
} else if (in_programming_mode(aq_data) == true) {
|
||||
|
|
|
@ -132,7 +132,7 @@ void send_aqt_cmd(unsigned char cmd)
|
|||
*
|
||||
*/
|
||||
|
||||
unsigned char _iaqt_control_cmd[AQ_MAXPKTLEN];
|
||||
unsigned char _iaqt_control_cmd[AQ_MAXPKTLEN_SEND];
|
||||
int _iaqt_control_cmd_len;
|
||||
|
||||
|
||||
|
@ -153,7 +153,7 @@ int ref_iaqt_control_cmd(unsigned char **cmd)
|
|||
|
||||
void rem_iaqt_control_cmd(unsigned char *cmd)
|
||||
{
|
||||
memset(_iaqt_control_cmd, 0, AQ_MAXPKTLEN * sizeof(unsigned char));
|
||||
memset(_iaqt_control_cmd, 0, AQ_MAXPKTLEN_SEND * sizeof(unsigned char));
|
||||
_iaqt_control_cmd_len = 0;
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ typedef enum {icct_setrpm, icct_settime, icct_setdate} iaqtControlCmdYype;
|
|||
|
||||
// Type is always 0 at the moment, haven't found any
|
||||
void queue_iaqt_control_command(iaqtControlCmdYype type, int num) {
|
||||
//unsigned char packets[AQ_MAXPKTLEN];
|
||||
//unsigned char packets[AQ_MAXPKTLEN_SEND];
|
||||
//int cnt;
|
||||
|
||||
if (waitfor_iaqt_ctrl_queue2empty() == false)
|
||||
|
|
|
@ -20,122 +20,488 @@
|
|||
|
||||
#include "aq_serial.h"
|
||||
#include "aqualink.h"
|
||||
#include "iaqualink.h"
|
||||
#include "packetLogger.h"
|
||||
#include "aq_serial.h"
|
||||
#include "serialadapter.h"
|
||||
#include "rs_msg_utils.h"
|
||||
|
||||
bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
#define IAQUA_QLEN 20
|
||||
|
||||
typedef struct iaqulnkcmd
|
||||
{
|
||||
unsigned char command[20];
|
||||
int length;
|
||||
} iaqualink_cmd;
|
||||
|
||||
iaqualink_cmd _iqaua_queue[IAQUA_QLEN];
|
||||
unsigned char _std_cmd[2];
|
||||
int _iaqua_q_length = 0;
|
||||
bool _aqua_last_cmdfrom_queue = false;
|
||||
|
||||
bool push_iaqualink_cmd(unsigned char *cmd, int length) {
|
||||
if (_iaqua_q_length >= IAQUA_QLEN ) {
|
||||
LOG(IAQL_LOG,LOG_ERR, "Queue overflow, last command ignored!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(_iqaua_queue[_iaqua_q_length].command, cmd, length);
|
||||
_iqaua_queue[_iaqua_q_length].length = length;
|
||||
_iaqua_q_length++;
|
||||
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Queue cmd, size %d, queu length=%d\n",length, _iaqua_q_length);
|
||||
|
||||
//LOG(IAQL_LOG,LOG_DEBUG, "Added to message queue, position %d 0x%02hhx|0x%02hhx|0x%02hhx|0x%02hhx\n",_rssa_q_length-1,_rssa_queue[_rssa_q_length-1][0],_rssa_queue[_rssa_q_length-1][1],_rssa_queue[_rssa_q_length-1][2],_rssa_queue[_rssa_q_length-1][3]);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//unsigned char *get_iaqualink_cmd(unsigned char source_message_type, unsigned char *dest_message, int *len) {
|
||||
int get_iaqualink_cmd(unsigned char source_message_type, unsigned char **dest_message) {
|
||||
|
||||
//LOG(IAQL_LOG, LOG_INFO, "Caculating cmd\n");
|
||||
|
||||
_aqua_last_cmdfrom_queue = false;
|
||||
|
||||
_std_cmd[0] = source_message_type;
|
||||
_std_cmd[1] = 0x00;
|
||||
*dest_message = _std_cmd;
|
||||
int len = 2;
|
||||
|
||||
if (source_message_type == 0x73 && _iaqua_q_length > 0)
|
||||
{ // Send big/long message
|
||||
if ( _iqaua_queue[0].length >= 19 ) {
|
||||
*dest_message = _iqaua_queue[0].command;
|
||||
len = _iqaua_queue[0].length;
|
||||
_aqua_last_cmdfrom_queue = true;
|
||||
} else {
|
||||
LOG(IAQL_LOG,LOG_WARNING,"Next command in queue is not full command, ignoring\n");
|
||||
}
|
||||
}
|
||||
else if (source_message_type == 0x53 && _iaqua_q_length > 0)
|
||||
{ // Send small command
|
||||
if ( _iqaua_queue[0].length <= 2 ) {
|
||||
*dest_message = _iqaua_queue[0].command;
|
||||
len = _iqaua_queue[0].length;
|
||||
_aqua_last_cmdfrom_queue = true;
|
||||
} else {
|
||||
LOG(IAQL_LOG,LOG_WARNING,"Next command in queue is too large, ignoring\n");
|
||||
}
|
||||
}
|
||||
|
||||
//LOG(IAQL_LOG, LOG_INFO, "Return cmd size %d\n",len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void remove_iaqualink_cmd() {
|
||||
if (_iaqua_q_length > 0 && _aqua_last_cmdfrom_queue == true) {
|
||||
LOG(IAQL_LOG,LOG_DEBUG, "Remove from message queue, length %d\n",_iaqua_q_length-1);
|
||||
memmove(&_iqaua_queue[0], &_iqaua_queue[1], (sizeof(iaqualink_cmd)) * _iaqua_q_length);
|
||||
_iaqua_q_length--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char iAqalnkDevID(aqkey *button) {
|
||||
|
||||
// For the 3 actual vbuttons that exist, we have already set their codes so just return it with no conversion
|
||||
if ( ((button->special_mask & VIRTUAL_BUTTON) == VIRTUAL_BUTTON) && button->rssd_code != NUL ) {
|
||||
return button->rssd_code;
|
||||
}
|
||||
|
||||
switch (button->rssd_code) {
|
||||
case RS_SA_PUMP:
|
||||
return IAQ_PUMP;
|
||||
break;
|
||||
case RS_SA_SPA:
|
||||
return IAQ_SPA;
|
||||
break;
|
||||
case RS_SA_POOLHT:
|
||||
return IAQ_POOL_HTR;
|
||||
break;
|
||||
case RS_SA_SPAHT:
|
||||
return IAQ_SPA_HTR;
|
||||
break;
|
||||
case RS_SA_AUX1:
|
||||
return IAQ_AUX1;
|
||||
break;
|
||||
case RS_SA_AUX2:
|
||||
return IAQ_AUX2;
|
||||
break;
|
||||
case RS_SA_AUX3:
|
||||
return IAQ_AUX3;
|
||||
break;
|
||||
case RS_SA_AUX4:
|
||||
return IAQ_AUX4;
|
||||
break;
|
||||
case RS_SA_AUX5:
|
||||
return IAQ_AUX5;
|
||||
break;
|
||||
case RS_SA_AUX6:
|
||||
return IAQ_AUX6;
|
||||
break;
|
||||
case RS_SA_AUX7:
|
||||
return IAQ_AUX7;
|
||||
break;
|
||||
case RS_SA_AUX8:
|
||||
return IAQ_AUXB1;
|
||||
break;
|
||||
case RS_SA_AUX9:
|
||||
return IAQ_AUXB2;
|
||||
break;
|
||||
case RS_SA_AUX10:
|
||||
return IAQ_AUXB3;
|
||||
break;
|
||||
case RS_SA_AUX11:
|
||||
return IAQ_AUXB4;
|
||||
break;
|
||||
case RS_SA_AUX12:
|
||||
return IAQ_AUXB5;
|
||||
break;
|
||||
case RS_SA_AUX13:
|
||||
return IAQ_AUXB6;
|
||||
break;
|
||||
case RS_SA_AUX14:
|
||||
return IAQ_AUXB7;
|
||||
break;
|
||||
case RS_SA_AUX15:
|
||||
return IAQ_AUXB8;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
||||
void lastchecksum(unsigned char *packet, int length){
|
||||
static unsigned char last70checksum = 0x00;
|
||||
static unsigned char last71checksum = 0x00;
|
||||
static unsigned char last72checksum = 0x00;
|
||||
|
||||
switch (packet[PKT_CMD]){
|
||||
case 0x70:
|
||||
if (last70checksum != packet[length-3] && last70checksum != 0x00) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x70 *******\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
}
|
||||
last70checksum = packet[length-3];
|
||||
break;
|
||||
case 0x71:
|
||||
if (last71checksum != packet[length-3] && last71checksum != 0x00) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x71 *******\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
}
|
||||
last71checksum = packet[length-3];
|
||||
break;
|
||||
case 0x72:
|
||||
if (last72checksum != packet[length-3] && last72checksum != 0x00) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"******* CHECKSUM CHANGED for 0x72 *******\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
}
|
||||
last72checksum = packet[length-3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (! _aqconfig_.enable_iaqualink) {
|
||||
return true;
|
||||
}
|
||||
|
||||
All taken from panel Yg, but only heater setpoints seem to work.
|
||||
Only setpoints seem to work,
|
||||
|
||||
RPM to 2750
|
||||
Bit 6 = 0x5e
|
||||
Bit 10 * 256 + Bit 11
|
||||
Bit 7 or 9 probably pump index.
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0a|0xbe|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xd5|0x10|0x03|
|
||||
|
||||
RPM to 2995
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x5e|0x04|0x00|0x01|0x0b|0xb3|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xcb|0x10|0x03|
|
||||
|
||||
SWG 50%
|
||||
Byte 6 = 0x19
|
||||
Byte 7 = 50%
|
||||
Byte 9 & 10 ????
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x32|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0e|0x10|0x03|
|
||||
|
||||
SWG 51%
|
||||
Byte 7 = 51%
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x19|0x33|0x00|0x18|0x01|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x0f|0x10|0x03|
|
||||
|
||||
Spa Setpoint 102
|
||||
Byte 6 = 0x06
|
||||
Byte 8 = 0x66=102
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x06|0x00|0x66|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x16|0x10|0x03|
|
||||
|
||||
Pool Setpoint 72
|
||||
Byte 6 = 0x05
|
||||
Byte 8 = 0x48=72
|
||||
HEX: 0x10|0x02|0x00|0x24|0x73|0x01|0x05|0x00|0x48|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0x00|0xf7|0x10|0x03|
|
||||
|
||||
*/
|
||||
if (packet[PKT_DEST] == _aqconfig_.extended_device_id2)
|
||||
{
|
||||
// Packets sent to iAqualink protocol
|
||||
// debuglogPacket(IAQL_LOG, packet, length, true, true);
|
||||
|
||||
unsigned char _cmd_readyCommand[] = {0x3f, 0x20};
|
||||
unsigned char _fullcmd[] = {0x00, 0x24, 0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
void set_iaqualink_aux_state(aqkey *button, bool isON) {
|
||||
|
||||
_fullcmd[4] = iAqalnkDevID(button);
|
||||
|
||||
if (_fullcmd[4] != 0xFF) {
|
||||
push_iaqualink_cmd(_cmd_readyCommand, 2);
|
||||
push_iaqualink_cmd(_fullcmd, 19);
|
||||
} else {
|
||||
LOG(IAQL_LOG, LOG_ERR, "Couldn't find iaqualink keycode for button %s\n",button->label);
|
||||
}
|
||||
else if (packet[PKT_DEST] == _aqconfig_.extended_device_id)
|
||||
|
||||
}
|
||||
|
||||
void set_iaqualink_heater_setpoint(int value, bool isPool) {
|
||||
|
||||
|
||||
if (isPool) {
|
||||
_fullcmd[4] = 0x05;
|
||||
} else {
|
||||
_fullcmd[4] = 0x06;
|
||||
}
|
||||
|
||||
// Should check value is valid here.
|
||||
_fullcmd[6] = value;
|
||||
|
||||
push_iaqualink_cmd(_cmd_readyCommand, 2);
|
||||
push_iaqualink_cmd(_fullcmd, 19);
|
||||
}
|
||||
|
||||
/*
|
||||
Status packets are requested on iAqualink ID 0xA? but received on AqualinkTouch ID 0x3?
|
||||
They are also sent when iAqualink is connected and a device changes.
|
||||
So good to catch in PDA mode when a physical iAqualink device is connected to PDA panel.
|
||||
packet has cmd of 0x70, 0x71, 0x72
|
||||
*/
|
||||
bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS)
|
||||
{
|
||||
// Packets sent to AqualinkTouch that iAqualink requested.
|
||||
if (packet[PKT_CMD] == CMD_IAQ_MAIN_STATUS)
|
||||
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true);
|
||||
int startIndex = 4 + 1;
|
||||
int numberBytes = packet[4];
|
||||
int offsetIndex = startIndex + numberBytes;
|
||||
bool foundSpaSP = false;
|
||||
bool foundWaterTemp = false;
|
||||
bool foundAirTemp = false;
|
||||
|
||||
for (int i = 0; i <= numberBytes; i++)
|
||||
{
|
||||
debuglogPacket(IAQT_LOG, packet, length, true, true);
|
||||
int startIndex = 4+1;
|
||||
int numberBytes = packet[4];
|
||||
int offsetIndex = startIndex+numberBytes;
|
||||
bool got_0x1d = false;
|
||||
int byteType = packet[5 + i];
|
||||
int byte = packet[offsetIndex + i];
|
||||
char *label;
|
||||
|
||||
for (int i=0; i <= numberBytes; i++) {
|
||||
int byteType = packet[5 + i];
|
||||
int byte = packet[offsetIndex+i];
|
||||
char *label;
|
||||
|
||||
// Some panels have blanks for the last 3 buys, the first of which is "water temp" (not sure on others 0x20, 0x21)
|
||||
// So if we saw 0x1d break loop if not force next as water temp.
|
||||
if (got_0x1d && i == numberBytes){break;}
|
||||
else if (i == numberBytes){byteType=0x1d;}
|
||||
|
||||
if (byteType==0)
|
||||
label="Filter Pump ";
|
||||
else if (byteType==1)
|
||||
label="Pool Heater "; // 0x01=on&heating, 0x03=ena
|
||||
else if (byteType==2)
|
||||
label="Spa ";
|
||||
else if (byteType==3)
|
||||
label="Spa Heater "; // 0x01=on&heating, 0x03=ena
|
||||
else if (byteType==6)
|
||||
label="Pool Htr setpoint";
|
||||
else if (byteType==8 || byteType==9 ) // 8 usually, also get 9 & 14 (different spa/heater modes not sorted out yet. 14 sometimes blank as well)
|
||||
label="Spa Htr setpoint ";
|
||||
else if (byteType==12)
|
||||
label="Water Temp ";
|
||||
else if (byteType==15) // 0x0f
|
||||
label="Air Temp ";
|
||||
else if (byteType == 0x1d || i == numberBytes) {// Last 3 bytes don't have type on some panels
|
||||
label="Water Temp ";
|
||||
got_0x1d = true;
|
||||
}
|
||||
else
|
||||
label=" ";
|
||||
|
||||
LOG(IAQT_LOG, LOG_NOTICE,"Aqualink2 - %-17s = %3d | index=%d type=(%0.2d 0x%02hhx) value=0x%02hhx offset=%d\n", label, byte, i, byteType, byteType, byte, (offsetIndex + i));
|
||||
}
|
||||
LOG(IAQT_LOG, LOG_NOTICE, "Status from other protocols Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d, WaterTemp=%d, AirTemp=%d\n",
|
||||
aq_data->aqbuttons[0].led->state == OFF ? "Off" : "On ",
|
||||
aq_data->aqbuttons[1].led->state == OFF ? "Off" : "On ",
|
||||
aq_data->swg_percent,
|
||||
aq_data->pumps[0].rpm,
|
||||
aq_data->pool_htr_set_point,
|
||||
aq_data->spa_htr_set_point,
|
||||
(aq_data->aqbuttons[1].led->state==OFF?aq_data->pool_temp:aq_data->spa_temp),
|
||||
aq_data->air_temp);
|
||||
}
|
||||
else if (packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS)
|
||||
{
|
||||
debuglogPacket(IAQT_LOG, packet, length, true, true);
|
||||
int numLabels = packet[4];
|
||||
int start = numLabels+4+1;
|
||||
|
||||
if (numLabels == 1) {
|
||||
LOG(IAQT_LOG, LOG_NOTICE,"**** !!! haven't decoded above packet yet !!! *****\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numLabels; i++)
|
||||
// Some panels have blanks for the last 3 buys, the first of which is "water temp" (not sure on others 0x20, 0x21)
|
||||
// So if we saw 0x1d break loop if not force next as water temp.
|
||||
if (foundWaterTemp && i == numberBytes)
|
||||
{
|
||||
int status=packet[start];
|
||||
int length=packet[start+1];
|
||||
int byteType = packet[5 + i];
|
||||
LOG(IAQT_LOG, LOG_NOTICE, "Aqualink2 - %-15.*s = %s | index %d type=(%0.2d 0x%02hhx) status=0x%02hhx start=%d length=%d\n",length,&packet[start+2],(status == 0x00 ? "Off" : "On "),i,byteType,byteType,status,start,length);
|
||||
start=start+packet[start+1]+2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (packet[PKT_CMD] == CMD_IAQ_AUX_STATUS)
|
||||
{
|
||||
debuglogPacket(IAQT_LOG, packet, length, true, true);
|
||||
// Look at notes in iaqualink.c for how this packet is made up
|
||||
int start = packet[4];
|
||||
start = start + 5;
|
||||
for (int i = start; i < length - 3; i = i)
|
||||
else if (i == numberBytes)
|
||||
{
|
||||
int status = i;
|
||||
int labelstart = status + 5;
|
||||
int labellen = packet[status + 4];
|
||||
if (labelstart + labellen < length)
|
||||
{
|
||||
LOG(IAQT_LOG, LOG_NOTICE, "Aqualink2 - %-15.*s = %s | bit1=0x%02hhx bit2=0x%02hhx bit3=0x%02hhx bit4=0x%02hhx\n", labellen, &packet[labelstart], (packet[status] == 0x00 ? "Off" : "On "), packet[status], packet[status + 1], packet[status + 2], packet[status + 3]);
|
||||
}
|
||||
i = labelstart + labellen;
|
||||
byteType = 0x1d;
|
||||
}
|
||||
|
||||
if (byteType == 0) {
|
||||
label = "Filter Pump ";
|
||||
} else if (byteType == 1) {
|
||||
label = "Pool Heater "; // 0x01=on&heating, 0x03=ena
|
||||
} else if (byteType == 2) {
|
||||
label = "Spa ";
|
||||
} else if (byteType == 3) {
|
||||
label = "Spa Heater "; // 0x01=on&heating, 0x03=ena
|
||||
} else if (byteType == 6) {
|
||||
label = "Pool Htr setpoint";
|
||||
} else if (byteType == 8 || byteType == 9) {// 8 usually, also get 9 & 14 (different spa/heater modes not sorted out yet. 14 sometimes blank as well)
|
||||
label = "Spa Htr setpoint ";
|
||||
foundSpaSP=true;
|
||||
} else if ( (/*byteType == 14 ||*/ byteType == 12) && foundSpaSP==false && byte != 0) {
|
||||
label = "Spa Htr setpoint ";
|
||||
} else if ( (byteType == 14 || byteType == 15 || byteType == 26) && byte != 0 && byte != 255 && foundAirTemp == false ) {// 0x0f
|
||||
label = "Air Temp "; // we also see this as 14 (RS16) ONLY
|
||||
foundAirTemp = true;
|
||||
} else if ( (byteType == 27 || byteType == 28 || byteType == 29) && byte != 0 && byte != 255 && foundWaterTemp == false) {
|
||||
// Last 3 bytes don't have type on some panels
|
||||
label = "Water Temp ";
|
||||
foundWaterTemp = true;
|
||||
}
|
||||
else
|
||||
label = " ";
|
||||
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "%-17s = %3d | index=%d type=(%0.2d 0x%02hhx) value=0x%02hhx offset=%d\n", label, byte, i, byteType, byteType, byte, (offsetIndex + i));
|
||||
}
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Status from other protocols Pump %s, Spa %s, SWG %d, PumpRPM %d, PoolSP=%d, SpaSP=%d, WaterTemp=%d, AirTemp=%d\n",
|
||||
aq_data->aqbuttons[0].led->state == OFF ? "Off" : "On ",
|
||||
aq_data->aqbuttons[1].led->state == OFF ? "Off" : "On ",
|
||||
aq_data->swg_percent,
|
||||
aq_data->pumps[0].rpm,
|
||||
aq_data->pool_htr_set_point,
|
||||
aq_data->spa_htr_set_point,
|
||||
(aq_data->aqbuttons[1].led->state == OFF ? aq_data->pool_temp : aq_data->spa_temp),
|
||||
aq_data->air_temp);
|
||||
}
|
||||
else if (packet[PKT_CMD] == CMD_IAQ_1TOUCH_STATUS)
|
||||
{
|
||||
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true);
|
||||
int numLabels = packet[4];
|
||||
int start = numLabels + 4 + 1;
|
||||
|
||||
if (numLabels == 1)
|
||||
{
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "**** !!! haven't decoded above packet yet !!! *****\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numLabels; i++)
|
||||
{
|
||||
int status = packet[start];
|
||||
int length = packet[start + 1];
|
||||
int byteType = packet[5 + i];
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "%-15.*s = %s | index %d type=(%0.2d 0x%02hhx) status=0x%02hhx start=%d length=%d\n", length, &packet[start + 2], (status == 0x00 ? "Off" : "On "), i, byteType, byteType, status, start, length);
|
||||
// Check against virtual onetouch buttons.
|
||||
for (int bi=aq_data->virtual_button_start ; bi < aq_data->total_buttons ; bi++) {
|
||||
if (rsm_strcmp((char *)&packet[start + 2], aq_data->aqbuttons[bi].label) == 0) {
|
||||
//LOG(IAQL_LOG, LOG_NOTICE, "Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On "));
|
||||
// == means doesn;t match, RS 1=on 0=off / LED enum 1=off 0=on
|
||||
if (aq_data->aqbuttons[bi].led->state == status) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(status == 0x00 ? "Off" : "On "));
|
||||
aq_data->aqbuttons[bi].led->state = (status == 0x00 ? OFF:ON);
|
||||
aq_data->updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
start = start + packet[start + 1] + 2;
|
||||
}
|
||||
}
|
||||
else if (packet[PKT_CMD] == CMD_IAQ_AUX_STATUS)
|
||||
{
|
||||
logPacket(IAQL_LOG, LOG_NOTICE, packet, length, true);
|
||||
// Look at notes in iaqualink.c for how this packet is made up
|
||||
// Since this is so similar to above CMD_IAQ_1TOUCH_STATUS, we should look at using same logic for both.
|
||||
int start = packet[4];
|
||||
start = start + 5;
|
||||
for (int i = start; i < length - 3; i = i)
|
||||
{
|
||||
int status = i;
|
||||
int labelstart = status + 5;
|
||||
int labellen = packet[status + 4];
|
||||
if (labelstart + labellen < length)
|
||||
{
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "%-15.*s = %s | bit1=0x%02hhx bit2=0x%02hhx bit3=0x%02hhx bit4=0x%02hhx\n", labellen, &packet[labelstart], (packet[status] == 0x00 ? "Off" : "On "), packet[status], packet[status + 1], packet[status + 2], packet[status + 3]);
|
||||
}
|
||||
if (isPDA_PANEL) {
|
||||
for (int bi=2 ; bi < aq_data->total_buttons ; bi++) {
|
||||
if (rsm_strcmp((char *)&packet[labelstart], aq_data->aqbuttons[bi].label) == 0) {
|
||||
if (aq_data->aqbuttons[bi].led->state == packet[status]) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Updated Status for %s is %s\n",aq_data->aqbuttons[bi].label,(packet[status] == 0x00 ? "Off" : "On "));
|
||||
aq_data->aqbuttons[bi].led->state = (packet[status] == 0x00 ? OFF:ON);
|
||||
aq_data->updated = true;
|
||||
}
|
||||
//LOG(IAQL_LOG, LOG_NOTICE, "Match %s to %.*s state(aqd=%d pnl=%d)\n",aq_data->aqbuttons[bi].label, labellen, (char *)&packet[labelstart], aq_data->aqbuttons[bi].led->state, packet[status]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = labelstart + labellen;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
|
||||
lastchecksum(packet, length);
|
||||
|
||||
unsigned char cmd_getMainstatus[] = {0x3f, 0x08};
|
||||
unsigned char cmd_getTouchstatus[] = {0x3f, 0x10};
|
||||
unsigned char cmd_getAuxstatus[] = {0x3f, 0x18};
|
||||
//unsigned char cmd_readyCommand[] = {0x3f, 0x20};
|
||||
//unsigned char fullcmd[] = {0x00, 0x24, 0x73, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
// byte 4 is ID. 0x00 pump, 0x02 spa etc
|
||||
|
||||
|
||||
if (packet[PKT_DEST] == _aqconfig_.extended_device_id2)
|
||||
{
|
||||
static int cnt = 0;
|
||||
//static unsigned char ID = 0;
|
||||
//static cur_swg = 0;
|
||||
|
||||
if (packet[PKT_CMD] == 0x53)
|
||||
{
|
||||
cnt++;
|
||||
if (cnt == 20) {
|
||||
cnt=0;
|
||||
push_iaqualink_cmd(cmd_getMainstatus, 2);
|
||||
push_iaqualink_cmd(cmd_getTouchstatus, 2);
|
||||
push_iaqualink_cmd(cmd_getAuxstatus, 2);
|
||||
/*
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"********** Send %d 0x%02hhx ************\n",ID,ID);
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
|
||||
_fullcmd[4] = ID++;
|
||||
push_iaqualink_cmd(_cmd_readyCommand, 2);
|
||||
push_iaqualink_cmd(_fullcmd, 19);
|
||||
|
||||
push_iaqualink_cmd(cmd_getMainstatus, 2);
|
||||
push_iaqualink_cmd(cmd_getTouchstatus, 2);
|
||||
push_iaqualink_cmd(cmd_getAuxstatus, 2);
|
||||
|
||||
push_iaqualink_cmd(_cmd_readyCommand, 2);
|
||||
push_iaqualink_cmd(_fullcmd, 19);
|
||||
*/
|
||||
|
||||
//fullcmd[4] = ID;
|
||||
//fullcmd[4] = ID;
|
||||
//fullcmd[5] = 0x32;
|
||||
|
||||
//fullcmd[7] = ID;
|
||||
//fullcmd[8] = 0x01;
|
||||
|
||||
|
||||
//set_iaqualink_heater_setpoint(50, true);
|
||||
|
||||
//push_iaqualink_cmd(cmd_getMainstatus, 2);
|
||||
//push_iaqualink_cmd(cmd_getTouchstatus, 2);
|
||||
//push_iaqualink_cmd(cmd_getAuxstatus, 2);
|
||||
/*
|
||||
if (aq_data->swg_percent != cur_swg && cur_swg != 0) {
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"********** SWG Changed to %d ************\n",aq_data->swg_percent);
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"*****************************************\n");
|
||||
exit(0);
|
||||
}
|
||||
cur_swg = aq_data->swg_percent;
|
||||
LOG(IAQL_LOG, LOG_NOTICE,"******* QUEUE SWG Comand of %d | 0x%02hhx *************\n",ID,ID);
|
||||
ID++;*/
|
||||
|
||||
}
|
||||
}
|
||||
// Packets sent to iAqualink protocol
|
||||
// debuglogPacket(IAQL_LOG, packet, length, true, true);
|
||||
}
|
||||
else if (packet[PKT_DEST] == _aqconfig_.extended_device_id || (isPDA_PANEL && packet[PKT_DEST] == _aqconfig_.device_id) )
|
||||
{
|
||||
process_iAqualinkStatusPacket(packet, length, aq_data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DONOTCOMPILE
|
||||
|
||||
// This is onle here temporarly until we figure out the protocol.
|
||||
void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
|
||||
{
|
||||
|
@ -164,14 +530,13 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
|
|||
else if (packet_buffer[PKT_CMD] == 0x53)
|
||||
{
|
||||
static int cnt = 0;
|
||||
/*
|
||||
cnt++;
|
||||
if (cnt == 10)
|
||||
{
|
||||
cnt = 5;
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Sent accept pButton\n");
|
||||
//cnt = 5;
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Sent accept next packet Comand\n");
|
||||
send_extended_ack(rs_fd, 0x3f, 0x20);
|
||||
}*/
|
||||
cnt++;
|
||||
}
|
||||
if (cnt == 20)
|
||||
{
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Sending get status\n");
|
||||
|
@ -200,17 +565,20 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
|
|||
}
|
||||
else if (packet_buffer[PKT_CMD] == 0x73)
|
||||
{
|
||||
static int id = 33;
|
||||
static int id = 10;
|
||||
// unsigned char pb1[] = {PCOL_JANDY,0x10,0x02,0x00,0x24,0x73,0x01,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x10,0x03,0x00};
|
||||
// unsigned char pb2[] = {PCOL_JANDY,0x10,0x02,0x00,0x24,0x73,0x01,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x10,0x03,0x00};
|
||||
// 0x21 turns on filter_pump and aux 1
|
||||
unsigned char pb3[] = {0x00, 0x24, 0x73, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
//unsigned char pb3[] = {0x00, 0x24, 0x73, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
unsigned char swg[] = {0x00, 0x24, 0x73, 0x01, 0x19, 0x32, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
//unsigned char swg[] = {0x00, 0x24, 0x73, 0x01, 0x19, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
unsigned char rpm[] = {0x00,0x24,0x73,0x01,0x5e,0x04,0x00,0x01,0x0a,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd5,0x10,0x03};
|
||||
//pb3[4] = id++;
|
||||
//swg[5] = ++id;
|
||||
|
||||
pb3[4] = id++;
|
||||
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "Sent pButton dec=%d hex=0x%02hhx\n", pb3[4], pb3[4]);
|
||||
LOG(IAQL_LOG, LOG_NOTICE, "*** Sending SWG dec=%d hex=0x%02hhx\n", swg[5], swg[5]);
|
||||
// send_packet(rs_fd, pb2, 25);
|
||||
send_jandy_command(rs_fd, pb3, 19);
|
||||
send_jandy_command(rs_fd, swg, 19);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -218,6 +586,7 @@ void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer)
|
|||
send_extended_ack(rs_fd, packet_buffer[PKT_CMD], 0x00);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
----
|
||||
|
@ -395,3 +764,23 @@ Debug: RS Serial: Read Jandy packet To 0xa1 of type Unknown '0x52' | HEX:
|
|||
Debug: RS Serial: Write Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
|
||||
Debug: RS Serial: Read Jandy packet To 0xa1 of type iAqalnk Poll | HEX: 0x10|0x02|0xa1|0x53|0x06|0x10|0x03|
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
0x10|0x02|0x31|0x72|0x0f|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|0x09|0x0a|0x0b|0x0c|0x0d|0x0e|0x0f|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x31|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x32|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x33|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x34|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x35|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x36|0x01|0x01|0x00|0x00|0x04|0x41|0x75|0x78|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x31|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x32|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x33|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x34|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x35|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x36|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x37|0x00|0x01|0x00|0x00|0x06|0x41|0x75|0x78|0x20|0x42|0x38|0x70|0x10|0x03|
|
||||
|
||||
|
||||
Only panel (RS8)
|
||||
Air index 3 type 15 (pump off)
|
||||
Air index 3 type 14 (pump off)
|
||||
Air index 3 type 8 (pump on)
|
||||
Water index 5 type 15 (pump on)
|
||||
Temp2 ndex 8 type 20
|
||||
always 1 | index=4 type=(15 0x0f)
|
||||
|
||||
Comb0
|
||||
Spa setpoint index 8 type 14
|
||||
Air index 8 type 26
|
||||
*/
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
|
||||
#ifndef AQ_IAQUALINK_H_
|
||||
#define AQ_IAQUALINK_H_
|
||||
|
||||
void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer);
|
||||
//void send_iaqualink_ack(int rs_fd, unsigned char *packet_buffer);
|
||||
|
||||
int get_iaqualink_cmd(unsigned char source_message_type, unsigned char **dest_message);
|
||||
void remove_iaqualink_cmd();
|
||||
|
||||
bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data);
|
||||
bool process_iAqualinkStatusPacket(unsigned char *packet, int length, struct aqualinkdata *aq_data);
|
||||
|
||||
|
||||
void set_iaqualink_aux_state(aqkey *button, bool isON);
|
||||
void set_iaqualink_heater_setpoint(int value, bool isPool);
|
||||
|
||||
// Send the below commands to turn on/off (toggle)
|
||||
// This is the button in pButton. (byte 6 in below)
|
||||
|
@ -15,23 +22,44 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink
|
|||
#define IAQ_SPA 0x02
|
||||
#define IAQ_SPA_HTR 0x03
|
||||
//....... some missing ....
|
||||
#define IAQ_ALL_OFF 0x10 // Not sure on this
|
||||
#define IAQ_SPA_MODE 0x11
|
||||
#define IAQ_CLEAN_MODE 0x12
|
||||
|
||||
#define IAD_SWG 0x19
|
||||
//....... some missing ....
|
||||
#define IAQ_AUX1 0x21
|
||||
#define IAQ_AUX2 0x22
|
||||
#define IAQ_AUX3 0x23
|
||||
#define IAQ_AUX4 0x24
|
||||
#define IAQ_AUX5 0x25
|
||||
#define IAQ_AUX6 0x26
|
||||
#define IAQ_AUX7 0x27
|
||||
#define IAQ_AUXB1 0x28
|
||||
#define IAQ_AUXB2 0x29
|
||||
#define IAQ_AUXB3 0x2a
|
||||
#define IAQ_AUXB4 0x2b
|
||||
#define IAQ_AUXB5 0x2c
|
||||
#define IAQ_AUXB6 0x2d
|
||||
#define IAQ_AUXB7 0x2e
|
||||
#define IAQ_AUXB8 0x2f
|
||||
#define IAQ_AUX1 0x21 //0x25 RS16 & 12 // AUX5
|
||||
#define IAQ_AUX2 0x22 //0x26 RS16
|
||||
#define IAQ_AUX3 0x23 //0x27 RS16
|
||||
#define IAQ_AUX4 0x24 //0x28 RS16
|
||||
#define IAQ_AUX5 0x25 //0x29 RS16
|
||||
#define IAQ_AUX6 0x26 //0x2a RS16
|
||||
#define IAQ_AUX7 0x27 //0x2b RS16
|
||||
#define IAQ_AUXB1 0x28 //0x2c RS16
|
||||
#define IAQ_AUXB2 0x29 //0x2d RS16
|
||||
#define IAQ_AUXB3 0x2a //0x2e RS16
|
||||
#define IAQ_AUXB4 0x2b //0x2f RS16
|
||||
#define IAQ_AUXB5 0x2c //0x30 RS16
|
||||
#define IAQ_AUXB6 0x2d //0x31 RS16
|
||||
#define IAQ_AUXB7 0x2e //0x32 RS16
|
||||
#define IAQ_AUXB8 0x2f //0x33 RS16
|
||||
/*
|
||||
#define IAQ_AUX1 0x25 //0x25 RS16 & 12 // AUX5
|
||||
#define IAQ_AUX2 0x26 //0x26 RS16
|
||||
#define IAQ_AUX3 0x27 //0x27 RS16
|
||||
#define IAQ_AUX4 0x28 //0x28 RS16
|
||||
#define IAQ_AUX5 0x29 //0x29 RS16
|
||||
#define IAQ_AUX6 0x2a //0x2a RS16
|
||||
#define IAQ_AUX7 0x2b //0x2b RS16
|
||||
#define IAQ_AUXB1 0x2c //0x2c RS16
|
||||
#define IAQ_AUXB2 0x2d //0x2d RS16
|
||||
#define IAQ_AUXB3 0x2e //0x2e RS16
|
||||
#define IAQ_AUXB4 0x2f //0x2f RS16
|
||||
#define IAQ_AUXB5 0x30 //0x30 RS16
|
||||
#define IAQ_AUXB6 0x31 //0x31 RS16
|
||||
#define IAQ_AUXB7 0x32 //0x32 RS16
|
||||
#define IAQ_AUXB8 0x33 //0x33 RS16
|
||||
*/
|
||||
//... Looks like there are C & D buttons
|
||||
/* I got this when sending dec=53 hex=0x35 as the button, all of a sudden got extra buttons in the aux status message send to AqualinkTouch protocol
|
||||
Not sure on ordering BUT dec=57 hex=0x39 = button D2 / dec=58 hex=0x3a = D3
|
||||
|
@ -65,6 +93,8 @@ Notice: iAQ Touch: Label Aux D8 = On
|
|||
#define IAQ_PUMP_RPM 0x5e
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
|
|
@ -1402,7 +1402,7 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
found = true;
|
||||
//create_panel_request(from, i, value, istimer);
|
||||
LOG(NET_LOG,LOG_INFO, "%d: MATCH %s to topic %.*s\n",from,_aqualink_data->aqbuttons[i].name,uri_length, URI);
|
||||
LOG(NET_LOG,LOG_INFO, "ri1=%s, length=%d char@=%c\n",ri1,strlen(_aqualink_data->aqbuttons[i].label),ri1[strlen(_aqualink_data->aqbuttons[i].label)] );
|
||||
LOG(NET_LOG,LOG_INFO, "ri1=%s, length=%d char at len=%c\n",ri1,strlen(_aqualink_data->aqbuttons[i].label),ri1[strlen(_aqualink_data->aqbuttons[i].label)] );
|
||||
panel_device_request(_aqualink_data, atype, i, value, from);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,11 +88,17 @@ void logPacketError(unsigned char *packet_buffer, int packet_length) {
|
|||
_logPacket(RSSD_LOG, packet_buffer, packet_length, true, false, true);
|
||||
}
|
||||
|
||||
/* This should never be used in production */
|
||||
void debuglogPacket(logmask_t from, unsigned char *packet_buffer, int packet_length, bool is_read, bool forcelog) {
|
||||
if ( forcelog == true || getLogLevel(from) >= LOG_DEBUG )
|
||||
_logPacket(from, packet_buffer, packet_length, false, forcelog, is_read);
|
||||
}
|
||||
|
||||
void logPacket(logmask_t from, int level, unsigned char *packet_buffer, int packet_length, bool is_read) {
|
||||
if ( getLogLevel(from) >= level )
|
||||
_logPacket(from, packet_buffer, packet_length, false, false, is_read);
|
||||
}
|
||||
|
||||
bool RSSD_LOG_filter_match(unsigned char ID) {
|
||||
for (int i=0; i < MAX_RSSD_LOG_FILTERS; i++) {
|
||||
if (_aqconfig_.RSSD_LOG_filter[i] != NUL && _aqconfig_.RSSD_LOG_filter[i] == ID) {
|
||||
|
|
|
@ -20,10 +20,11 @@ void logPacketRead(unsigned char *packet_buffer, int packet_length);
|
|||
void logPacketWrite(unsigned char *packet_buffer, int packet_length);
|
||||
void logPacketError(unsigned char *packet_buffer, int packet_length);
|
||||
void logPacketByte(unsigned char *byte);
|
||||
|
||||
// Only use for manual debugging
|
||||
//void debuglogPacket(unsigned char *packet_buffer, int packet_length);
|
||||
void debuglogPacket(logmask_t from, unsigned char *packet_buffer, int packet_length, bool is_read, bool forcelog);
|
||||
void logPacket(logmask_t from, int level, unsigned char *packet_buffer, int packet_length, bool is_read) ;
|
||||
int beautifyPacket(char *buff, int buff_size, unsigned char *packet_buffer, int packet_length, bool is_read);
|
||||
|
||||
// Only use for manual debugging
|
||||
void debuglogPacket(logmask_t from, unsigned char *packet_buffer, int packet_length, bool is_read, bool forcelog);
|
||||
|
||||
|
||||
#endif //PACKETLOGGER_H_
|
28
source/pda.c
28
source/pda.c
|
@ -152,13 +152,21 @@ void equiptment_update_cycle(int eqID) {
|
|||
LOG(PDA_LOG,LOG_DEBUG, "Start new equipment cycle bitmask 0x%04x\n",
|
||||
update_equiptment_bitmask);
|
||||
|
||||
for (i=0; i < _aqualink_data->total_buttons - 2 ; i++) { // total_buttons - 2 because we don't get heaters in this cycle
|
||||
if (pda_m_type() == PM_EQUIPTMENT_STATUS) {
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Full equiptment update\n");
|
||||
} else {
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Main menu equiptment update (4 devices)\n");
|
||||
}
|
||||
|
||||
for (i=0; i < _aqualink_data->total_buttons - 3 ; i++) { // total_buttons - 3 because we don't get heaters in this cycle
|
||||
//for (i=0; i < _aqualink_data->total_buttons; i++) { // total_buttons - 2 because we don't get heaters in this cycle
|
||||
if ((update_equiptment_bitmask & (1 << (i))) != (1 << (i))) {
|
||||
if (_aqualink_data->aqbuttons[i].led->state != OFF) {
|
||||
_aqualink_data->aqbuttons[i].led->state = OFF;
|
||||
_aqualink_data->updated = true;
|
||||
LOG(PDA_LOG,LOG_DEBUG, "Turn off equipment id %d %s not seen in last cycle\n", i, _aqualink_data->aqbuttons[i].name);
|
||||
}
|
||||
//LOG(PDA_LOG,LOG_DEBUG, "Thick id %d %s total = %d\n", i, _aqualink_data->aqbuttons[i].name, _aqualink_data->total_buttons);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,6 +820,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
int index = -1;
|
||||
static bool equiptment_update_loop = false;
|
||||
static bool read_equiptment_menu = false;
|
||||
static int time_msg_cnt = 0;
|
||||
|
||||
_aqualink_data->last_packet_type = packet[PKT_CMD];
|
||||
|
||||
|
@ -829,6 +838,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
break;
|
||||
|
||||
case CMD_STATUS:
|
||||
//LOG(PDA_LOG,LOG_DEBUG, "**** PDA Menu type %d ****\n", pda_m_type());
|
||||
_aqualink_data->last_display_message[0] = '\0';
|
||||
if (equiptment_update_loop == false && pda_m_type() == PM_EQUIPTMENT_STATUS)
|
||||
{
|
||||
|
@ -866,6 +876,21 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
case CMD_MSG_LONG:
|
||||
msg = (char *)packet + PKT_DATA + 1;
|
||||
index = packet[PKT_DATA] & 0xF;
|
||||
|
||||
// When nothing is on, all we see it time updated, so count them and if we get 2 in a row, everyting is off.
|
||||
if (packet[PKT_DATA] == 0x40) { // 0x40 is ID for time.
|
||||
time_msg_cnt++;
|
||||
LOG(PDA_LOG,LOG_DEBUG, "**** Time message count %d ****\n",time_msg_cnt);
|
||||
if ( time_msg_cnt >= 2) {
|
||||
equiptment_update_cycle(-1);
|
||||
}
|
||||
if (time_msg_cnt >= (INT8_MAX -10)){
|
||||
time_msg_cnt=2;
|
||||
}
|
||||
} else {
|
||||
time_msg_cnt = 0;
|
||||
}
|
||||
|
||||
if (packet[PKT_DATA] == 0x82)
|
||||
{ // Air & Water temp is always this ID
|
||||
process_pda_packet_msg_long_temp(msg);
|
||||
|
@ -873,6 +898,7 @@ bool process_pda_packet(unsigned char *packet, int length)
|
|||
else if (packet[PKT_DATA] == 0x40)
|
||||
{ // Time is always on this ID
|
||||
process_pda_packet_msg_long_time(msg);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -942,10 +942,13 @@ int _serial_logger(int rs_fd, char *port_name, int logPackets, int logLevel, boo
|
|||
return 0;
|
||||
}
|
||||
|
||||
#include "timespec_subtract.h"
|
||||
|
||||
|
||||
|
||||
|
||||
int sl_timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y)
|
||||
{
|
||||
return timespec_subtract(result,x,y);
|
||||
}
|
||||
/*
|
||||
int sl_timespec_subtract (struct timespec *result, const struct timespec *x, const struct timespec *y)
|
||||
{
|
||||
struct timespec tmp;
|
||||
|
@ -972,7 +975,7 @@ int sl_timespec_subtract (struct timespec *result, const struct timespec *x, con
|
|||
|
||||
return x->tv_sec < tmp.tv_sec;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ void queue_aqualink_rssadapter_setpoint(unsigned char typeID, int val) {
|
|||
}
|
||||
|
||||
/* NSF Need to delete this and use aqbuttonp[].rssd_code */
|
||||
unsigned char devID(int bIndex) {
|
||||
unsigned char RSSAdevID(int bIndex) {
|
||||
// pool = 0; spa = 1; aux1 = 2 etc
|
||||
// rssa pool / spa are different. aux1 = 21 (0x15) then goes up from their in order.
|
||||
|
||||
|
@ -141,13 +141,20 @@ void set_aqualink_rssadapter_aux_extended_state(const aqkey *button, const unsig
|
|||
rssadapter_device_state(button->rssd_code, state);
|
||||
}
|
||||
|
||||
void set_aqualink_rssadapter_aux_state(const aqkey *button, bool turnOn)
|
||||
{
|
||||
LOG(RSSA_LOG,LOG_DEBUG, "Turning button %s %s\n",button->label,(turnOn?"On":"Off"));
|
||||
|
||||
rssadapter_device_state( button->rssd_code, (turnOn?RS_SA_ON:RS_SA_OFF) );
|
||||
}
|
||||
/*
|
||||
void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn)
|
||||
{
|
||||
LOG(RSSA_LOG,LOG_DEBUG, "Turning button %d %s\n",buttonIndex,(turnOn?"On":"Off"));
|
||||
|
||||
rssadapter_device_state( devID(buttonIndex), (turnOn?RS_SA_ON:RS_SA_OFF) );
|
||||
rssadapter_device_state( RSSAdevID(buttonIndex), (turnOn?RS_SA_ON:RS_SA_OFF) );
|
||||
}
|
||||
|
||||
*/
|
||||
void increase_aqualink_rssadapter_pool_setpoint(char *args, struct aqualinkdata *aqdata) {
|
||||
int val = atoi(args);
|
||||
val = setpoint_check(POOL_HTR_SETOINT, aqdata->pool_htr_set_point + val, aqdata);
|
||||
|
@ -264,7 +271,7 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
|
|||
get_aqualink_rssadapter_colorlight_statuses(aq_data);
|
||||
}
|
||||
#endif
|
||||
if (cnt == 0 || cnt >= 250) {
|
||||
if (cnt == 0 || cnt >= 100) {
|
||||
LOG(RSSA_LOG,LOG_INFO, "Queue device update requests\n");
|
||||
|
||||
if (cnt == 0) {
|
||||
|
|
|
@ -10,7 +10,8 @@ bool process_rssadapter_packet(unsigned char *packet, int length, struct aqualin
|
|||
//void rssadapter_device_on(unsigned char devID);
|
||||
//void rssadapter_device_off(unsigned char devID);
|
||||
|
||||
void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn);
|
||||
//void set_aqualink_rssadapter_aux_state(int buttonIndex, bool turnOn);
|
||||
void set_aqualink_rssadapter_aux_state(const aqkey *button, bool turnOn);
|
||||
//void set_aqualink_rssadapter_aux_extended_state(int buttonIndex, const unsigned char state);
|
||||
void set_aqualink_rssadapter_aux_extended_state(const aqkey *button, const unsigned char state);
|
||||
void get_aqualink_rssadapter_setpoints();
|
||||
|
|
|
@ -335,7 +335,7 @@ const char* logmask2name(logmask_t from)
|
|||
return "Serial Log:";
|
||||
break;
|
||||
case IAQL_LOG:
|
||||
return "iAqualink: ";
|
||||
return "iAqualink2: ";
|
||||
break;
|
||||
case AQUA_LOG:
|
||||
default:
|
||||
|
@ -490,11 +490,17 @@ void test(int msg_level, char *msg)
|
|||
void addDebugLogMask(logmask_t flag)
|
||||
{
|
||||
_logforcemask |= flag;
|
||||
|
||||
if (flag == IAQT_LOG) // If AQTouch add iAqualink
|
||||
_logforcemask |= IAQL_LOG;
|
||||
}
|
||||
|
||||
void removeDebugLogMask(logmask_t flag)
|
||||
{
|
||||
_logforcemask &= ~flag;
|
||||
|
||||
if (flag == IAQT_LOG) // If AQTouch remove iAqualink
|
||||
_logforcemask &= ~IAQL_LOG;
|
||||
}
|
||||
|
||||
void clearDebugLogMask()
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
#define AQUALINKD_NAME "Aqualink Daemon"
|
||||
#define AQUALINKD_SHORT_NAME "AqualinkD"
|
||||
#define AQUALINKD_VERSION "2.4.1 (Dev 0.1)"
|
||||
#define AQUALINKD_VERSION "2.4.1 (Dev 0.2)"
|
||||
|
|
Loading…
Reference in New Issue