mirror of https://github.com/sfeakes/AqualinkD.git
Version 2.4.1
parent
2d717fbe74
commit
e3dc3dbabb
2
Makefile
2
Makefile
|
@ -98,7 +98,7 @@ ifeq ($(AQ_ONETOUCH), true)
|
|||
endif
|
||||
|
||||
ifeq ($(AQ_IAQTOUCH), true)
|
||||
SRCS := $(SRCS) iaqtouch.c iaqtouch_aq_programmer.c
|
||||
SRCS := $(SRCS) iaqtouch.c iaqtouch_aq_programmer.c iaqualink.c
|
||||
AQ_FLAGS := $(AQ_FLAGS) -D AQ_IAQTOUCH
|
||||
endif
|
||||
|
||||
|
|
19
README.md
19
README.md
|
@ -114,15 +114,22 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
|
|||
|
||||
<!--
|
||||
NEED TO FIX FOR THIS RELEASE.
|
||||
***** FIX NET_SERVICES.C action_uri() spa and spa_mode get confused. check EVERY strncmp
|
||||
* MQTT filter_pump/percent/set, maybe add max/min to pump config. / print protocol on startup
|
||||
* Pump by name and not ID. clean up code
|
||||
* look at using 0x00 for no exit on serial errors / startup
|
||||
* DONE look at using 0x00 for no exit on serial errors / startup
|
||||
* DONE look at virtual button support
|
||||
* vbuton will need the PDA on iAQT protocol working.
|
||||
* change dimmer to % from steps. (will make HASIO & Homekit easier)
|
||||
* add config for homekit_f (panel in F homekin in C), F to F or C to C is fine.
|
||||
* deprecate extended_device_id_programming
|
||||
* show error is vbutton and no extended_device_id
|
||||
# Updates in 2.3.9
|
||||
* deprecate (hide and default to yes) extended_device_id_programming
|
||||
* Move following to main and not config.c - show error is vbutton and no extended_device_id, vbutton w/ pump can be onetouch.
|
||||
* check panel version reported against config.
|
||||
# Updates in 2.4.1
|
||||
|
||||
# install.sh change spa_mode to spa in config.js
|
||||
# DONE change hassio.c to use rpm speed/percent
|
||||
# pickup speed faster on iaqualinktouch after change
|
||||
-->
|
||||
|
||||
# Updates in 2.4.1 (under development)
|
||||
|
@ -130,6 +137,10 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* This is faster, more reliable and does not intefear with the physical PDA device (like existing implimentation)
|
||||
* Please consider this very much BETA at the moment.
|
||||
* use `device_id=0x33` in aqualinkd.conf
|
||||
* Added MQTT vsp_pump/speed/set for setting speed (RPM/GPM) by %, for automation hubs.
|
||||
* cleaned up code for spa_mode and spa for newer pannels.
|
||||
* Allow VSP to be asigned to virtual button.
|
||||
* Fixed bug with timer not starting.
|
||||
|
||||
# Updates in Release 2.4.0
|
||||
* <b>WARNING</b> Breaking change if you use dimmer (please change button_??_lightMode from 6 to 10)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -269,7 +269,7 @@ use_panel_aux_labels=no
|
|||
# Below are settings for standard buttons on RS-8 Combo panel used as example.
|
||||
button_01_label=Filter Pump
|
||||
|
||||
button_02_label=Spa Mode
|
||||
button_02_label=Spa
|
||||
|
||||
button_03_label=Cleaner
|
||||
|
||||
|
@ -305,4 +305,4 @@ button_12_label=Solar Heater
|
|||
#virtual_button_02_label=Clean Mode
|
||||
#virtual_button_03_label = OneTouch 4
|
||||
#virtual_button_04_label = OneTouch 5
|
||||
#virtual_button_05_label = OneTouch 6
|
||||
#virtual_button_05_label = OneTouch 6
|
||||
|
|
|
@ -132,8 +132,8 @@ fi
|
|||
# V2.3.9 has kind-a breaking change for config.js, so check existing and rename if needed
|
||||
# we added Aux_V? to the button list
|
||||
if [ -f "$WEBLocation/config.js" ]; then
|
||||
# Test is if has AUX_V1 in file
|
||||
if ! grep -q Aux_V1 $WEBLocation/config.js; then
|
||||
# Test is if has AUX_V1 in file AND "Spa" is in file (Spa_mode changed to Spa)
|
||||
if ! grep -q 'Aux_V1' $WEBLocation/$file || ! grep -q '"Spa"' $WEBLocation/$file; then
|
||||
dateext=`date +%Y%m%d_%H_%M_%S`
|
||||
echo "AqualinkD web config is old, making copy to $WEBLocation/config.js.$dateext"
|
||||
echo "Please make changes to new version $WEBLocation/config.js"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -53,6 +53,7 @@
|
|||
#define PUMP_MODE_TOPIC "/Mode"
|
||||
#define PUMP_STATUS_TOPIC "/Status"
|
||||
#define PUMP_PPC_TOPIC "/PPC"
|
||||
#define PUMP_SPEED_TOPIC "/Speed"
|
||||
|
||||
#define LIGHT_PROGRAM_TOPIC "/program"
|
||||
/*
|
||||
|
|
|
@ -360,6 +360,32 @@ aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex) {
|
|||
return button;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
//{{ (((value | float(0) - %d) / %d) * 100) | int }} - minspeed, (maxspeed - minspeed),
|
||||
//{{ ((value | float(0) / 100) * %d) + %d | int }} - (maxspeed - minspeed), minspeed)
|
||||
|
||||
int getPumpSpeedAsPercent(pump_detail *pump) {
|
||||
int pValue = pump->pumpType==VFPUMP?pump->gpm:pump->rpm;
|
||||
|
||||
if (pValue < pump->minSpeed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Below will return 0% if pump is at min, so return max (caculation, 1)
|
||||
return AQ_MAX( (int)((float)(pValue - pump->minSpeed) / (float)(pump->maxSpeed - pump->minSpeed) * 100) + 0.5, 1);
|
||||
}
|
||||
|
||||
int convertPumpPercentToSpeed(pump_detail *pump, int pValue) {
|
||||
if (pValue >= 100)
|
||||
return pump->maxSpeed;
|
||||
else if (pValue <= 0)
|
||||
return pump->minSpeed;
|
||||
|
||||
return ( ((float)(pValue / (float)100) * (pump->maxSpeed - pump->minSpeed) + pump->minSpeed)) + 0.5;
|
||||
}
|
||||
|
||||
// 4,6,8,10,12,14
|
||||
void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo, bool dual) {
|
||||
|
@ -717,6 +743,13 @@ 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) {
|
||||
// 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;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((button->led->state == OFF && isON == false) ||
|
||||
(isON > 0 && (button->led->state == ON || button->led->state == FLASH ||
|
||||
button->led->state == ENABLE))) {
|
||||
|
|
|
@ -62,6 +62,9 @@ void addPanelIAQTouchInterface();
|
|||
void addPanelRSserialAdapterInterface();
|
||||
void changePanelToExtendedIDProgramming();
|
||||
|
||||
int getPumpSpeedAsPercent(pump_detail *pump);
|
||||
int convertPumpPercentToSpeed(pump_detail *pump, int value); // This is probable only needed internally
|
||||
|
||||
uint16_t getPanelSupport( char *rev_string, int rev_len);
|
||||
|
||||
aqkey *addVirtualButton(struct aqualinkdata *aqdata, char *label, int vindex);
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef enum emulation_type{
|
|||
ONETOUCH,
|
||||
IAQTOUCH,
|
||||
AQUAPDA, // AQUAPALM and PDA are taken as specific type.
|
||||
IAQUALNK, // iAqualink (wifi extra ID)
|
||||
JANDY_DEVICE, // Very rarley used.
|
||||
SIMULATOR
|
||||
} emulation_type;
|
||||
|
|
|
@ -76,6 +76,8 @@ emulation_type getJandyDeviceType(unsigned char ID) {
|
|||
return AQUAPDA;
|
||||
if (ID >= 0x30 && ID <= 0x33)
|
||||
return IAQTOUCH;
|
||||
if (ID >= 0xa0 && ID <= 0xa3)
|
||||
return IAQUALNK;
|
||||
|
||||
/*
|
||||
if (ID >= 0x00 && ID <= 0x03)
|
||||
|
@ -286,6 +288,10 @@ const char* get_jandy_packet_type(unsigned char* packet , int length)
|
|||
return "LXi status";
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
return "iAqalnk Poll";
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(buf, "Unknown '0x%02hhx'", packet[PKT_CMD]);
|
||||
return buf;
|
||||
|
|
|
@ -232,7 +232,7 @@ DEV_UNKNOWN_MASK = 0xF8; // Unknown mask, used to reset values
|
|||
#endif
|
||||
|
||||
#define BTN_PUMP "Filter_Pump"
|
||||
#define BTN_SPA "Spa_Mode"
|
||||
#define BTN_SPA "Spa"
|
||||
#define BTN_AUX1 "Aux_1"
|
||||
#define BTN_AUX2 "Aux_2"
|
||||
#define BTN_AUX3 "Aux_3"
|
||||
|
|
|
@ -88,6 +88,7 @@ void start_timer(struct aqualinkdata *aq_data, /*aqkey *button,*/ int deviceInde
|
|||
tmthread->thread_id = 0;
|
||||
tmthread->duration_min = duration;
|
||||
tmthread->next = NULL;
|
||||
tmthread->started_at = time(0); // This will get reset once we actually start. But need it here incase someone calls get_timer_left() before we start
|
||||
|
||||
if( pthread_create( &tmthread->thread_id , NULL , timer_worker, (void*)tmthread) < 0) {
|
||||
LOG(TIMR_LOG, LOG_ERR, "could not create timer thread for button '%s'\n",button->name);
|
||||
|
|
|
@ -68,6 +68,12 @@ bool checkAqualinkTime(); // Only need to externalise this for PDA
|
|||
|
||||
bool isVirtualButtonEnabled();
|
||||
|
||||
#define PUMP_RPM_MAX 3450
|
||||
#define PUMP_RPM_MIN 600
|
||||
#define PUMP_GPM_MAX 130
|
||||
#define PUMP_GPM_MIN 15
|
||||
|
||||
|
||||
enum {
|
||||
FAHRENHEIT,
|
||||
CELSIUS,
|
||||
|
@ -179,6 +185,8 @@ typedef struct pumpd
|
|||
int rpm;
|
||||
int gpm;
|
||||
int watts;
|
||||
int maxSpeed; // Max rpm or gpm depending on pump
|
||||
int minSpeed;
|
||||
unsigned char pumpID;
|
||||
int pumpIndex;
|
||||
char pumpName[PUMP_NAME_LENGTH];
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "onetouch_aq_programmer.h"
|
||||
#include "iaqtouch.h"
|
||||
#include "iaqtouch_aq_programmer.h"
|
||||
#include "iaqualink.h"
|
||||
#include "version.h"
|
||||
#include "rs_msg_utils.h"
|
||||
#include "serialadapter.h"
|
||||
|
@ -697,6 +698,12 @@ int startup(char *self, char *cfgFile)
|
|||
LOG(AQUA_LOG,LOG_NOTICE, "Config BTN %-13s = label %-15s | %s\n",
|
||||
_aqualink_data.aqbuttons[i].name, _aqualink_data.aqbuttons[i].label, ext);
|
||||
}
|
||||
|
||||
if ( ((_aqualink_data.aqbuttons[i].special_mask & VIRTUAL_BUTTON) == VIRTUAL_BUTTON) &&
|
||||
((_aqualink_data.aqbuttons[i].special_mask & VS_PUMP ) != VS_PUMP) &&
|
||||
(_aqconfig_.extended_device_id < 0x30 || _aqconfig_.extended_device_id > 0x33 ) ){
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Config error, extended_device_id must be on of the folowing (0x30,0x31,0x32,0x33) to use virtual button : '%s'",_aqualink_data.aqbuttons[i].label);
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (i=0; i < _aqualink_data.total_buttons; i++)
|
||||
|
@ -766,6 +773,41 @@ void caculate_ack_packet(int rs_fd, unsigned char *packet_buffer, emulation_type
|
|||
}
|
||||
//DEBUG_TIMER_STOP(_rs_packet_timer,AQUA_LOG,"AquaTouch Emulation type Processed packet in");
|
||||
break;
|
||||
case IAQUALNK:
|
||||
/*
|
||||
Probe | HEX: 0x10|0x02|0xa3|0x00|0xb5|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x00|0x00|0x13|0x10|0x03|
|
||||
Unknown '0x61' | HEX: 0x10|0x02|0xa3|0x61|0x00|0x00|0x00|0x04|0x00|0x27|0x41|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x61|0x00|0x74|0x10|0x03|
|
||||
Unknown '0x50' | HEX: 0x10|0x02|0xa3|0x50|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x20|0x00|0x25|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x50|0x00|0x63|0x10|0x03|
|
||||
Unknown '0x51' | HEX: 0x10|0x02|0xa3|0x51|0x00|0x06|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x51|0x00|0x64|0x10|0x03|
|
||||
Unknown '0x59' | HEX: 0x10|0x02|0xa3|0x59|0x00|0x0e|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x59|0x00|0x6c|0x10|0x03|
|
||||
Unknown '0x52' | HEX: 0x10|0x02|0xa3|0x52|0x00|0x07|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x52|0x00|0x65|0x10|0x03|
|
||||
Unknown '0x53' | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
|
||||
Ack | HEX: 0x10|0x02|0x00|0x01|0x3f|0x00|0x52|0x10|0x03|
|
||||
Use byte 3 as return ack, except for 0x53=0x3f
|
||||
*/
|
||||
if (packet_buffer[PKT_CMD] == 0x53) {
|
||||
/*
|
||||
static int cnt=0;
|
||||
if (cnt++ > 10) {
|
||||
cnt=0;
|
||||
LOG(IAQL_LOG,LOG_NOTICE, "Sending get bigass packet\n");
|
||||
send_extended_ack(rs_fd, 0x3f, 0x18);
|
||||
} else*/ {
|
||||
// Use 0x3f
|
||||
send_extended_ack(rs_fd, 0x3f, 0x00);
|
||||
}
|
||||
send_jandy_command(rs_fd, get_rssa_cmd(packet_buffer[PKT_CMD]), 4);
|
||||
} else {
|
||||
// Use packet_buffer[PKT_CMD]
|
||||
send_extended_ack(rs_fd, packet_buffer[PKT_CMD], 0x00);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef AQ_PDA
|
||||
case AQUAPDA:
|
||||
|
@ -879,7 +921,8 @@ void main_loop()
|
|||
pthread_mutex_init(&_aqualink_data.active_thread.thread_mutex, NULL);
|
||||
pthread_cond_init(&_aqualink_data.active_thread.thread_cond, NULL);
|
||||
|
||||
for (i=0; i < MAX_PUMPS; i++) {
|
||||
//for (i=0; i < MAX_PUMPS; i++) {
|
||||
for (i=0; i < _aqualink_data.num_pumps; i++) {
|
||||
_aqualink_data.pumps[i].rpm = TEMP_UNKNOWN;
|
||||
_aqualink_data.pumps[i].gpm = TEMP_UNKNOWN;
|
||||
_aqualink_data.pumps[i].watts = TEMP_UNKNOWN;
|
||||
|
@ -888,6 +931,15 @@ void main_loop()
|
|||
_aqualink_data.pumps[i].status = TEMP_UNKNOWN;
|
||||
_aqualink_data.pumps[i].pStatus = PS_OFF;
|
||||
_aqualink_data.pumps[i].pressureCurve = TEMP_UNKNOWN;
|
||||
|
||||
if (_aqualink_data.pumps[i].maxSpeed <= 0) {
|
||||
_aqualink_data.pumps[i].maxSpeed = (_aqualink_data.pumps[i].pumpType==VFPUMP?PUMP_GPM_MAX:PUMP_RPM_MAX);
|
||||
}
|
||||
if (_aqualink_data.pumps[i].minSpeed <= 0) {
|
||||
_aqualink_data.pumps[i].minSpeed = (_aqualink_data.pumps[i].pumpType==VFPUMP?PUMP_GPM_MIN:PUMP_RPM_MIN);
|
||||
}
|
||||
|
||||
//printf("arrayindex=%d, pump=%d, min=%d, max=%d\n",i,_aqualink_data.pumps[i].pumpIndex, _aqualink_data.pumps[i].minSpeed ,_aqualink_data.pumps[i].maxSpeed);
|
||||
}
|
||||
|
||||
for (i=0; i < MAX_LIGHTS; i++) {
|
||||
|
@ -1241,10 +1293,14 @@ void main_loop()
|
|||
}
|
||||
|
||||
// Process and packets of devices we are acting as
|
||||
if (packet_length > 0 && getProtocolType(packet_buffer) == JANDY &&
|
||||
if (packet_length > 0 && getProtocolType(packet_buffer) == JANDY && packet_buffer[PKT_DEST] != 0x00 &&
|
||||
(packet_buffer[PKT_DEST] == _aqconfig_.device_id ||
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.rssa_device_id ||
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id ))
|
||||
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id ||
|
||||
packet_buffer[PKT_DEST] == _aqconfig_.extended_device_id2
|
||||
#endif
|
||||
))
|
||||
{
|
||||
switch(getJandyDeviceType(packet_buffer[PKT_DEST])){
|
||||
case ALLBUTTON:
|
||||
|
@ -1267,6 +1323,10 @@ void main_loop()
|
|||
_aqualink_data.updated = process_pda_packet(packet_buffer, packet_length);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, AQUAPDA);
|
||||
break;
|
||||
case IAQUALNK:
|
||||
_aqualink_data.updated = process_iaqualink_packet(packet_buffer, packet_length, &_aqualink_data);
|
||||
caculate_ack_packet(rs_fd, packet_buffer, IAQUALNK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
159
source/config.c
159
source/config.c
|
@ -47,6 +47,8 @@
|
|||
|
||||
char *generate_mqtt_id(char *buf, int len);
|
||||
pump_detail *getpump(struct aqualinkdata *aqdata, int button);
|
||||
bool populatePumpData(struct aqualinkdata *aqdata, char *pumpcfg ,aqkey *button, char *value);
|
||||
pump_detail *getPumpFromButtonID(struct aqualinkdata *aqdata, aqkey *button);
|
||||
|
||||
struct tmpPanelInfo {
|
||||
int size;
|
||||
|
@ -403,9 +405,11 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
// Has to be before the below.
|
||||
_aqconfig_.extended_device_id_programming = text2bool(value);
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "extended_device_id", 9) == 0) {
|
||||
} else if (strncasecmp(param, "extended_device_id", 18) == 0) {
|
||||
_aqconfig_.extended_device_id = strtoul(cleanalloc(value), NULL, 16);
|
||||
//_config_parameters.onetouch_device_id != 0x00
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param, "enable_iaqualink", 16) == 0) {
|
||||
_aqconfig_.enable_iaqualink = text2bool(value);
|
||||
rtn=true;
|
||||
#endif
|
||||
} else if (strncasecmp(param, "panel_type_size", 15) == 0) {
|
||||
|
@ -682,63 +686,25 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
LOG(AQUA_LOG,LOG_ERR, "Config error, (colored|programmable) Lights limited to %d, ignoring %s'\n",MAX_LIGHTS,param);
|
||||
}
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpID", 7) == 0) {
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
pump->pumpID = strtoul(cleanalloc(value), NULL, 16);
|
||||
//if ( (int)pump->pumpID <= PENTAIR_DEC_PUMP_MAX) {
|
||||
if ( (int)pump->pumpID >= PENTAIR_DEC_PUMP_MIN && (int)pump->pumpID <= PENTAIR_DEC_PUMP_MAX) {
|
||||
pump->prclType = PENTAIR;
|
||||
} else {
|
||||
pump->prclType = JANDY;
|
||||
//pump->pumpType = EPUMP; // For testing let the interface set this
|
||||
}
|
||||
} else {
|
||||
} else if (strncasecmp(param + 9, "_pump", 5) == 0) {
|
||||
|
||||
if ( ! populatePumpData(aqdata, param + 10, &aqdata->aqbuttons[num], value) )
|
||||
{
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring : %s",MAX_PUMPS,param);
|
||||
}
|
||||
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpIndex", 10) == 0) { //button_01_pumpIndex=1
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
pump->pumpIndex = strtoul(value, NULL, 10);
|
||||
} else {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring : %s",MAX_PUMPS,param);
|
||||
}
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpType", 9) == 0) {
|
||||
// This is not documented, as it's prefered for AqualinkD to find the pump type.
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
if ( stristr(value, "Pentair VS") != 0)
|
||||
pump->pumpType = VSPUMP;
|
||||
else if ( stristr(value, "Pentair VF") != 0)
|
||||
pump->pumpType = VFPUMP;
|
||||
else if ( stristr(value, "Jandy ePump") != 0)
|
||||
pump->pumpType = EPUMP;
|
||||
} else {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring : %s",MAX_PUMPS,param);
|
||||
}
|
||||
rtn=true;
|
||||
} else if (strncasecmp(param + 9, "_pumpName", 9) == 0) { //button_01_pumpIndex=1
|
||||
pump_detail *pump = getpump(aqdata, num);
|
||||
if (pump != NULL) {
|
||||
//pump->pumpName = cleanalloc(value);
|
||||
strncpy(pump->pumpName ,cleanwhitespace(value), PUMP_NAME_LENGTH-1);
|
||||
} else {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring : %s",MAX_PUMPS,param);
|
||||
}
|
||||
rtn=true;
|
||||
}
|
||||
#if defined AQ_IAQTOUCH
|
||||
}
|
||||
//#if defined AQ_IAQTOUCH
|
||||
} else if (strncasecmp(param, "virtual_button_", 15) == 0) {
|
||||
rtn=true;
|
||||
rtn=true;
|
||||
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);
|
||||
} 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 (_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) {
|
||||
int num = strtoul(param + 15, NULL, 10);
|
||||
char *label = cleanalloc(value);
|
||||
aqkey *button = addVirtualButton(aqdata, label, num);
|
||||
if (button != NULL) {
|
||||
|
@ -746,15 +712,102 @@ bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value) {
|
|||
} else {
|
||||
LOG(AQUA_LOG,LOG_WARNING, "Error with '%s', total buttons=%d, config has %d already, ignoring!\n",param, TOTAL_BUTTONS, aqdata->total_buttons+1);
|
||||
}
|
||||
} else if (strncasecmp(param + 17, "_pump", 5) == 0) {
|
||||
char *vbname = malloc(sizeof(char*) * 10);
|
||||
snprintf(vbname, 9, "%s%d", BTN_VAUX, num);
|
||||
aqkey *vbutton = NULL;
|
||||
for (int i = aqdata->virtual_button_start; i < aqdata->total_buttons; i++) {
|
||||
//printf("Checking %s agasinsdt %s\n",aqdata->aqbuttons[i].name, vbname);
|
||||
if ( strcmp( aqdata->aqbuttons[i].name, vbname) == 0 ) {
|
||||
vbutton = &aqdata->aqbuttons[i];
|
||||
vbutton->led->state = ON; //Virtual pump is always on
|
||||
if ( ! populatePumpData(aqdata, param + 18, vbutton, value) )
|
||||
{
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, VSP Pumps limited to %d, ignoring : %s",MAX_PUMPS,param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vbutton == NULL) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "Config error, could not find vitrual button for `%s`",param);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
// pumpcfg is pointer to pumpIndex, pumpName, pumpType pumpID, (ie pull off button_??_ or vurtual_button_??_)
|
||||
bool populatePumpData(struct aqualinkdata *aqdata, char *pumpcfg ,aqkey *button, char *value)
|
||||
{
|
||||
|
||||
pump_detail *pump = getPumpFromButtonID(aqdata, button);
|
||||
if (pump == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncasecmp(pumpcfg, "pumpIndex", 9) == 0) {
|
||||
pump->pumpIndex = strtoul(value, NULL, 10);
|
||||
} else if (strncasecmp(pumpcfg, "pumpType", 8) == 0) {
|
||||
if ( stristr(value, "Pentair VS") != 0)
|
||||
pump->pumpType = VSPUMP;
|
||||
else if ( stristr(value, "Pentair VF") != 0)
|
||||
pump->pumpType = VFPUMP;
|
||||
else if ( stristr(value, "Jandy ePump") != 0)
|
||||
pump->pumpType = EPUMP;
|
||||
} else if (strncasecmp(pumpcfg, "pumpName", 8) == 0) {
|
||||
strncpy(pump->pumpName ,cleanwhitespace(value), PUMP_NAME_LENGTH-1);
|
||||
} else if (strncasecmp(pumpcfg, "pumpID", 6) == 0) {
|
||||
pump->pumpID = strtoul(cleanalloc(value), NULL, 16);
|
||||
if ( (int)pump->pumpID >= PENTAIR_DEC_PUMP_MIN && (int)pump->pumpID <= PENTAIR_DEC_PUMP_MAX) {
|
||||
pump->prclType = PENTAIR;
|
||||
} else {
|
||||
pump->prclType = JANDY;
|
||||
}
|
||||
} else if (strncasecmp(pumpcfg, "pumpMaxSpeed", 12) == 0) {
|
||||
pump->maxSpeed = strtoul(value, NULL, 10);
|
||||
} else if (strncasecmp(pumpcfg, "pumpMinSpeed", 12) == 0) {
|
||||
pump->minSpeed = strtoul(value, NULL, 10);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pump_detail *getPumpFromButtonID(struct aqualinkdata *aqdata, aqkey *button)
|
||||
{
|
||||
int pi;
|
||||
|
||||
// Does it exist
|
||||
for (pi=0; pi < aqdata->num_pumps; pi++) {
|
||||
if (aqdata->pumps[pi].button == button) {
|
||||
return &aqdata->pumps[pi];
|
||||
}
|
||||
}
|
||||
|
||||
// Create new entry
|
||||
if (aqdata->num_pumps < MAX_PUMPS) {
|
||||
//printf ("Creating pump %d\n",button);
|
||||
button->special_mask |= VS_PUMP;
|
||||
aqdata->pumps[aqdata->num_pumps].button = button;
|
||||
aqdata->pumps[aqdata->num_pumps].pumpType = PT_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].rpm = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].watts = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].gpm = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].pStatus = PS_OFF;
|
||||
aqdata->pumps[aqdata->num_pumps].pumpIndex = 0;
|
||||
aqdata->pumps[aqdata->num_pumps].maxSpeed = TEMP_UNKNOWN;
|
||||
aqdata->pumps[aqdata->num_pumps].minSpeed = TEMP_UNKNOWN;
|
||||
//pumpType
|
||||
aqdata->pumps[aqdata->num_pumps].pumpName[0] = '\0';
|
||||
aqdata->num_pumps++;
|
||||
return &aqdata->pumps[aqdata->num_pumps-1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
pump_detail *getpump(struct aqualinkdata *aqdata, int button)
|
||||
{
|
||||
//static int _pumpindex = 0;
|
||||
|
@ -788,7 +841,7 @@ pump_detail *getpump(struct aqualinkdata *aqdata, int button)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void init_config()
|
||||
{
|
||||
|
|
|
@ -44,7 +44,9 @@ struct aqconfig
|
|||
int16_t paneltype_mask;
|
||||
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
||||
unsigned char extended_device_id;
|
||||
unsigned char extended_device_id2;
|
||||
bool extended_device_id_programming;
|
||||
bool enable_iaqualink;
|
||||
#endif
|
||||
bool deamonize;
|
||||
#ifndef AQ_MANAGER // Need to uncomment and clean up referances in future.
|
||||
|
|
|
@ -127,9 +127,8 @@ 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) / %d) * 100) | int }}\"," // 600, (3450-600)
|
||||
"\"percentage_value_template\": \"{%% if value | float(0) > %d %%} {{ (((value | float(0) - %d) / %d) * 100) | int }}{%% else %%} 1{%% endif %%}\"," // min,min,(max-min)
|
||||
"\"percentage_command_template\": \"{{ ((value | float(0) / 100) * %d) + %d | int }}\"," // (3450-130), 600
|
||||
//"\"percentage_value_template\": \"{%% if value | float(0) > %d %%} {{ (((value | float(0) - %d) / %d) * 100) | int }}{%% else %%} 1{%% endif %%}\"," // min,min,(max-min)
|
||||
//"\"percentage_command_template\": \"{{ ((value | float(0) / 100) * %d) + %d | int }}\"," // (3450-130), 600
|
||||
"\"speed_range_max\": 100,"
|
||||
"\"speed_range_min\": 1," // 18|12 600rpm|15gpm
|
||||
"\"qos\": 1,"
|
||||
|
@ -469,20 +468,9 @@ 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 minspeed=600; // 600 as % of max
|
||||
char units[4];
|
||||
sprintf(units, "RPM");
|
||||
|
||||
if ( aqdata->pumps[i].pumpType == VFPUMP ) {
|
||||
maxspeed=130; // Min is 15
|
||||
minspeed=15; // 15 as % of max
|
||||
sprintf(units, "GPM");
|
||||
}
|
||||
char units[] = "Speed";
|
||||
// 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,
|
||||
|
@ -491,9 +479,7 @@ 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,
|
||||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,units,
|
||||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,units,
|
||||
minspeed, minspeed, (maxspeed - minspeed),
|
||||
(maxspeed - minspeed), minspeed);
|
||||
_aqconfig_.mqtt_aq_topic,aqdata->pumps[i].button->name,units);
|
||||
|
||||
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);
|
||||
|
|
|
@ -1000,6 +1000,13 @@ bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkd
|
|||
//printf("***** iAqualink Touch STARTUP Message ******* \n");
|
||||
if (gotInit == false) {
|
||||
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
|
||||
}
|
||||
//LOG(IAQT_LOG,LOG_ERR, "STARTUP REMOVED GET PANEL DATA FOR TESTING\n");
|
||||
queueGetProgramData(IAQTOUCH, aq_data);
|
||||
gotInit = true;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Shaun Feakes - All rights reserved
|
||||
*
|
||||
* You may use redistribute and/or modify this code under the terms of
|
||||
* the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation. For the terms of this license,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* You are free to use this software under the terms of the GNU General
|
||||
* Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* https://github.com/sfeakes/aqualinkd
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "aq_serial.h"
|
||||
#include "aqualink.h"
|
||||
#include "packetLogger.h"
|
||||
|
||||
bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
|
||||
//debuglogPacket(IAQL_LOG, packet, length, true, true);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,7 +1,16 @@
|
|||
|
||||
|
||||
bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Read Jandy packet To 0xa3 of type Unknown '0x53' | HEX: 0x10|0x02|0xa3|0x53|0x08|0x10|0x03|
|
||||
Read Jandy packet To 0x00 of type Ack | HEX: 0x10|0x02|0x00|0x01|0x3f|0x00|0x52|0x10|0x03|
|
||||
|
||||
|
||||
Below get's sent to AqualinkTouch with iAqualink is enabled.
|
||||
End of message is board cpu and panel type.
|
||||
Read Jandy packet To 0x33 of type Unknown '0x70' | HEX: 0x10|0x02|0x33|0x70|0x0d|0x00|0x01|0x02|0x03|0x05|0x06|0x07|0x0e|0x0f|0x1a|0x1d|0x20|0x21|0x00|0x00|0x00|0x00|0x00|0x48|0x00|0x66|0x00|0x50|0x00|0x00|0x00|0xff|0x42|0x30|0x33|0x31|0x36|0x38|0x32|0x33|0x20|0x52|0x53|0x2d|0x34|0x20|0x43|0x6f|0x6d|0x62|0x6f|0x00|0x00|0x4b|0x10|0x03|
|
||||
|
||||
*/
|
|
@ -75,6 +75,7 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc);
|
|||
#endif
|
||||
|
||||
void reset_last_mqtt_status();
|
||||
bool uri_strcmp(const char *uri, const char *string);
|
||||
|
||||
//static const char *s_http_port = "8080";
|
||||
static struct mg_serve_http_opts _http_server_opts;
|
||||
|
@ -914,11 +915,17 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
_last_mqtt_aqualinkdata.pumps[i].rpm = _aqualink_data->pumps[i].rpm;
|
||||
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_RPM_TOPIC, _aqualink_data->pumps[i].rpm);
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_RPM_TOPIC, _aqualink_data->pumps[i].rpm);
|
||||
if (_aqualink_data->pumps[i].pumpType == EPUMP || _aqualink_data->pumps[i].pumpType == VSPUMP) {
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_SPEED_TOPIC, getPumpSpeedAsPercent(&_aqualink_data->pumps[i]));
|
||||
}
|
||||
}
|
||||
if (_aqualink_data->pumps[i].gpm != TEMP_UNKNOWN && _aqualink_data->pumps[i].gpm != _last_mqtt_aqualinkdata.pumps[i].gpm) {
|
||||
_last_mqtt_aqualinkdata.pumps[i].gpm = _aqualink_data->pumps[i].gpm;
|
||||
//send_mqtt_aux_msg(nc, PUMP_TOPIC, i+1, PUMP_GPH_TOPIC, _aqualink_data->pumps[i].gph);
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_GPM_TOPIC, _aqualink_data->pumps[i].gpm);
|
||||
if (_aqualink_data->pumps[i].pumpType == VFPUMP) {
|
||||
send_mqtt_aux_msg(nc, _aqualink_data->pumps[i].button->name, PUMP_SPEED_TOPIC, getPumpSpeedAsPercent(&_aqualink_data->pumps[i]));
|
||||
}
|
||||
}
|
||||
if (_aqualink_data->pumps[i].watts != TEMP_UNKNOWN && _aqualink_data->pumps[i].watts != _last_mqtt_aqualinkdata.pumps[i].watts) {
|
||||
_last_mqtt_aqualinkdata.pumps[i].watts = _aqualink_data->pumps[i].watts;
|
||||
|
@ -1254,7 +1261,7 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
rtn = uBad;
|
||||
}
|
||||
// Action a pump RPM/GPM message
|
||||
} else if ((ri3 != NULL && ((strncasecmp(ri2, "RPM", 3) == 0) || (strncasecmp(ri2, "GPM", 3) == 0) || (strncasecmp(ri2, "VSP", 3) == 0)) && (strncasecmp(ri3, "set", 3) == 0))) {
|
||||
} else if ((ri3 != NULL && ((strncasecmp(ri2, "RPM", 3) == 0) || (strncasecmp(ri2, "GPM", 3) == 0) || (strncasecmp(ri2, "Speed", 5) == 0) || (strncasecmp(ri2, "VSP", 3) == 0)) && (strncasecmp(ri3, "set", 3) == 0))) {
|
||||
found = false;
|
||||
// Is it a pump index or pump name
|
||||
if (strncmp(ri1, "Pump_", 5) == 0) { // Pump by number
|
||||
|
@ -1274,9 +1281,15 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
return uBad;
|
||||
}
|
||||
} else {
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d %s to %d\n",actionName[from],pumpIndex+1, (strncasecmp(ri2, "GPM", 3) == 0)?"GPM":"RPM", round(value));
|
||||
if (strncasecmp(ri2, "Speed", 5) == 0) {
|
||||
int val = convertPumpPercentToSpeed(&_aqualink_data->pumps[i], round(value));
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d Speed to %d%%, using %s of %d\n",actionName[from],pumpIndex+1, round(value), (_aqualink_data->pumps[i].pumpType==VFPUMP?"GPM":"RPM" ) ,val);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, pumpIndex, val, from);
|
||||
} else {
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d %s to %d\n",actionName[from],pumpIndex+1, (strncasecmp(ri2, "GPM", 3) == 0)?"GPM":"RPM", round(value));
|
||||
//create_program_request(from, PUMP_RPM, round(value), pumpIndex);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, pumpIndex, round(value), from);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, pumpIndex, round(value), from);
|
||||
}
|
||||
}
|
||||
//_aqualink_data->unactioned.type = PUMP_RPM;
|
||||
//_aqualink_data->unactioned.value = round(value);
|
||||
|
@ -1287,7 +1300,8 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
}
|
||||
} else { // Pump by button name
|
||||
for (i=0; i < _aqualink_data->total_buttons ; i++) {
|
||||
if (strncmp(ri1, _aqualink_data->aqbuttons[i].name, strlen(_aqualink_data->aqbuttons[i].name)) == 0 ){
|
||||
//if (strncmp(ri1, _aqualink_data->aqbuttons[i].name, strlen(_aqualink_data->aqbuttons[i].name)) == 0 ){
|
||||
if ( uri_strcmp(ri1, _aqualink_data->aqbuttons[i].name)) {
|
||||
int pi;
|
||||
for (pi=0; pi < _aqualink_data->num_pumps; pi++) {
|
||||
if (_aqualink_data->pumps[pi].button == &_aqualink_data->aqbuttons[i]) {
|
||||
|
@ -1304,9 +1318,15 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
return uBad;
|
||||
}
|
||||
} else {
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d %s to %d\n",actionName[from], pi+1, (strncasecmp(ri2, "GPM", 3) == 0)?"GPM":"RPM", round(value));
|
||||
if (strncasecmp(ri2, "Speed", 5) == 0) {
|
||||
int val = convertPumpPercentToSpeed(&_aqualink_data->pumps[pi], round(value));
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d Speed to %d%%, using %s of %d\n",actionName[from],_aqualink_data->pumps[pi].pumpIndex, round(value), (_aqualink_data->pumps[i].pumpType==VFPUMP?"GPM":"RPM" ) ,val);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, _aqualink_data->pumps[pi].pumpIndex, val, from);
|
||||
} else {
|
||||
LOG(NET_LOG,LOG_NOTICE, "%s: request to change pump %d %s to %d\n",actionName[from], pi+1, (strncasecmp(ri2, "GPM", 3) == 0)?"GPM":"RPM", round(value));
|
||||
//create_program_request(from, PUMP_RPM, round(value), _aqualink_data->pumps[pi].pumpIndex);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, _aqualink_data->pumps[pi].pumpIndex, round(value), from);
|
||||
panel_device_request(_aqualink_data, PUMP_RPM, _aqualink_data->pumps[pi].pumpIndex, round(value), from);
|
||||
}
|
||||
}
|
||||
//_aqualink_data->unactioned.type = PUMP_RPM;
|
||||
//_aqualink_data->unactioned.value = round(value);
|
||||
|
@ -1363,13 +1383,15 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
|
||||
for (i=0; i < _aqualink_data->total_buttons && found==false; i++) {
|
||||
// If Label = "Spa", "Spa_Heater" will turn on "Spa", so need to check '/' on label as next character
|
||||
if (strncmp(ri1, _aqualink_data->aqbuttons[i].name, strlen(_aqualink_data->aqbuttons[i].name)) == 0 ||
|
||||
(strncmp(ri1, _aqualink_data->aqbuttons[i].label, strlen(_aqualink_data->aqbuttons[i].label)) == 0 && ri1[strlen(_aqualink_data->aqbuttons[i].label)] == '/'))
|
||||
//if (strncmp(ri1, _aqualink_data->aqbuttons[i].name, strlen(_aqualink_data->aqbuttons[i].name)) == 0 ||
|
||||
// (strncmp(ri1, _aqualink_data->aqbuttons[i].label, strlen(_aqualink_data->aqbuttons[i].label)) == 0 && ri1[strlen(_aqualink_data->aqbuttons[i].label)] == '/'))
|
||||
if ( uri_strcmp(ri1, _aqualink_data->aqbuttons[i].name) || uri_strcmp(ri1, _aqualink_data->aqbuttons[i].label) )
|
||||
{
|
||||
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)] );
|
||||
panel_device_request(_aqualink_data, atype, i, value, from);
|
||||
//LOG(NET_LOG,LOG_INFO, "%s: MATCH %s to topic %.*s\n",from,_aqualink_data->aqbuttons[i].name,uri_length, URI);
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
|
@ -1387,6 +1409,28 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
return rtn;
|
||||
}
|
||||
|
||||
/*
|
||||
Quicker and more accurate for us than normal strncmp, since we check for the trailing / at right position
|
||||
check Spa against uri /Spa/set /Spa_mode/set / Spa_heater/set
|
||||
*/
|
||||
bool uri_strcmp(const char *uri, const char *string) {
|
||||
int i;
|
||||
int len = strlen(string);
|
||||
|
||||
// Check the trailing / on length first.
|
||||
if (uri[len] != '/') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now check all characters
|
||||
for (i=0; i < len; i++) {
|
||||
if ( uri[i] != string[i] ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg) {
|
||||
char *rtnmsg;
|
||||
|
|
|
@ -334,6 +334,9 @@ const char* logmask2name(logmask_t from)
|
|||
case SLOG_LOG:
|
||||
return "Serial Log:";
|
||||
break;
|
||||
case IAQL_LOG:
|
||||
return "iAqualink :";
|
||||
break;
|
||||
case AQUA_LOG:
|
||||
default:
|
||||
return "AqualinkD: ";
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef int32_t logmask_t;
|
|||
#define DBGT_LOG (1 << 14) // Debug Timer
|
||||
|
||||
#define SLOG_LOG (1 << 15) // Serial_Logger
|
||||
#define IAQL_LOG (1 << 16) // iAqualink
|
||||
|
||||
#define TIMR_LOG SCHD_LOG
|
||||
#define PANL_LOG PROG_LOG
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// http://aqualink.ip.address/api/devices
|
||||
var devices = [
|
||||
"Filter_Pump",
|
||||
"Spa_Mode",
|
||||
"Spa",
|
||||
"Aux_1",
|
||||
"Aux_2",
|
||||
"Aux_3",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
./switch-off.png
|
|
@ -0,0 +1 @@
|
|||
./switch-on.png
|
Loading…
Reference in New Issue