mirror of https://github.com/sfeakes/AqualinkD.git
Dev update
parent
3b79c83d02
commit
7973213889
10
Makefile
10
Makefile
|
@ -83,7 +83,7 @@ endif
|
|||
# Main source files
|
||||
SRCS = aqualinkd.c utils.c config.c aq_serial.c aq_panel.c aq_programmer.c allbutton.c allbutton_aq_programmer.c net_services.c json_messages.c rs_msg_utils.c\
|
||||
devices_jandy.c packetLogger.c devices_pentair.c color_lights.c serialadapter.c aq_timer.c aq_scheduler.c web_config.c\
|
||||
serial_logger.c mongoose.c hassio.c simulator.c timespec_subtract.c
|
||||
serial_logger.c mongoose.c hassio.c simulator.c sensors.c timespec_subtract.c
|
||||
|
||||
|
||||
AQ_FLAGS =
|
||||
|
@ -227,6 +227,10 @@ quick:
|
|||
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make quickbuild
|
||||
$(info Binaries for release have been built)
|
||||
|
||||
debugbinaries:
|
||||
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make debugbuild
|
||||
$(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)
|
||||
|
@ -235,6 +239,10 @@ buildrelease: clean armhf arm64
|
|||
quickbuild: armhf arm64
|
||||
$(shell cd release && [ ! -f "./aqualinkd-armhf" ] && ln -s ./aqualinkd-armhf ./aqualinkd && ln -s ./serial_logger-armhf ./serial_logger)
|
||||
|
||||
debugbuild: CFLAGS = $(DFLAGS)
|
||||
debugbuild: 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)
|
||||
|
|
|
@ -132,6 +132,9 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
# Updates in 2.5.1
|
||||
* Added scheduling of pump after events (Power On, Freeze Protect, Boost)
|
||||
* Fixed HA bug for thermostats not converting to °C when HA is set to display °C.
|
||||
* Added support for monitoring SBC system sensors, like CPU / GPU / Board (CPU temp being most useful).
|
||||
* Reduced load on panel over AqualinkTouch protocol.
|
||||
* Fixed higher than normal CPU load when leaving aqmanager open and sending no messages (leaving aqmanager open for over 14days).
|
||||
|
||||
# Updates in 2.5.0
|
||||
* PDA panel Rev 6.0 or newer that do not have a Jandy iAqualink device attached can use the AqualinkTouch protocol rather than PDA protocol.
|
||||
|
|
|
@ -57,7 +57,7 @@ if echo $DOCKER_TAGS | grep -q $VERSION; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Login first
|
||||
# Login first Run as root not with sudo on my build machine.
|
||||
# cat ~/.docker.token | docker login --username sfeakes --password-stdin
|
||||
|
||||
echo "Building Docker container for $IMAGE using branch $VERSION"
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
PROCESSNAME=aqualinkd
|
||||
MYPID=`pidof $PROCESSNAME`
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
MYPID=$(pidof "$PROCESSNAME-arm64")
|
||||
if [ $? -ne 0 ]; then
|
||||
MYPID=$(pidof "$PROCESSNAME-armhf")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root"
|
||||
exit 1
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
PROCESSNAME=aqualinkd
|
||||
MYPID=`pidof $PROCESSNAME`
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
MYPID=$(pidof "$PROCESSNAME-arm64")
|
||||
if [ $? -ne 0 ]; then
|
||||
MYPID=$(pidof "$PROCESSNAME-armhf")
|
||||
fi
|
||||
fi
|
||||
|
||||
#if [[ $EUID -ne 0 ]]; then
|
||||
# echo "This script must be run as root"
|
||||
# exit 1
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -132,7 +132,8 @@ report_zero_spa_temp = yes
|
|||
#mqtt_dz_pub_topic = domoticz/in
|
||||
#mqtt_dz_sub_topic = domoticz/out
|
||||
#mqtt_aq_topic = aqualinkd
|
||||
#mqtt_hassio_discover_topic = homeassistant
|
||||
#mqtt_ha_discover_topic = homeassistant
|
||||
#mqtt_ha_discover_use_mac = no
|
||||
|
||||
# MQTT will only post updated information, this option AqualinkD will re-post all MQTT information every ~5 minutes.
|
||||
#mqtt_timed_update = no
|
||||
|
@ -151,6 +152,7 @@ report_zero_spa_temp = yes
|
|||
# dead.
|
||||
# ~40 and we will be replying too slowley, so keep below that.
|
||||
# 10~20 is about what most device reply in. But 0-4 works well.
|
||||
# Recomended to set to at least 4 for PDA panels.
|
||||
rs485_frame_delay = 0
|
||||
|
||||
# Get rid of the startup warning message about no low latency. BETTER option is to buy a better adapter.
|
||||
|
@ -322,3 +324,18 @@ button_12_label=Solar Heater
|
|||
#virtual_button_03_label = OneTouch 4
|
||||
#virtual_button_04_label = OneTouch 5
|
||||
#virtual_button_05_label = OneTouch 6
|
||||
|
||||
# Sensors.
|
||||
# All Raspberry Pi's (and most other SBC) report CPU temp. Most report to /sys/class/thermal/thermal_zone0/temp,
|
||||
# you can monitor these and AqualinkD will post the information to MQTT.
|
||||
# These will depend a lot on the board & OS you are running.
|
||||
# the "factor" is the number the sensor is multiplied by to get an accurate result. example below is (millidegrees Celsius to Celsius)
|
||||
|
||||
#sensor_01_path = /sys/class/thermal/thermal_zone0/temp
|
||||
#sensor_01_label = CPU
|
||||
#sensor_01_factor = 0.001
|
||||
|
||||
# Boards like Radxa Zero3 have others sensors like below.
|
||||
#sensor_02_path = /sys/class/thermal/thermal_zone1/temp
|
||||
#sensor_02_label = GPU
|
||||
#sensor_02_factor = 0.001
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -58,6 +58,8 @@
|
|||
#define LIGHT_PROGRAM_TOPIC "/program"
|
||||
#define LIGHT_DIMMER_VALUE_TOPIC "/brightness"
|
||||
|
||||
#define SENSOR_TOPIC "Sensor"
|
||||
|
||||
/*
|
||||
#define AIR_TEMPERATURE "Air"
|
||||
#define POOL_TEMPERATURE "Pool_Water"
|
||||
|
|
|
@ -185,13 +185,21 @@ setPanel("RS-8 Combo");
|
|||
char _panelString[60];
|
||||
void setPanelString()
|
||||
{
|
||||
snprintf(_panelString, sizeof(_panelString), "%s%s-%d %s%s%s",
|
||||
snprintf(_panelString, sizeof(_panelString), "%s%s-%s%d %s",
|
||||
isRS_PANEL?"RS":"",
|
||||
isPDA_PANEL?"PDA":"", // No need for both of these, but for error validation leave it in.
|
||||
isDUAL_EQPT_PANEL?"2/":"",
|
||||
PANEL_SIZE(),
|
||||
isDUAL_EQPT_PANEL?"Dual Equipment":(
|
||||
isCOMBO_PANEL?"Combo Pool/Spa":(isSINGLE_DEV_PANEL?"Only Pool/Spa":"")
|
||||
)
|
||||
);
|
||||
|
||||
/*
|
||||
isCOMBO_PANEL?"Combo Pool/Spa":"",
|
||||
isSINGLE_DEV_PANEL?"Pool/Spa Only":"",
|
||||
isDUAL_EQPT_PANEL?" Dual Equipment":"");
|
||||
*/
|
||||
}
|
||||
const char* getPanelString()
|
||||
{
|
||||
|
@ -407,6 +415,10 @@ int convertPumpPercentToSpeed(pump_detail *pump, int pValue) {
|
|||
// 4,6,8,10,12,14
|
||||
void initPanelButtons(struct aqualinkdata *aqdata, bool rs, int size, bool combo, bool dual) {
|
||||
|
||||
// Since we are resetting all special buttons here (.special_mask), we need to clean out the lights and pumps.
|
||||
aqdata->num_lights = 0;
|
||||
aqdata->num_pumps = 0;
|
||||
|
||||
int index = 0;
|
||||
aqdata->aqbuttons[index].led = &aqdata->aqualinkleds[7-1];
|
||||
aqdata->aqbuttons[index].led->state = LED_S_UNKNOWN;
|
||||
|
|
|
@ -107,10 +107,16 @@ int PANEL_SIZE();
|
|||
*/
|
||||
|
||||
|
||||
|
||||
// If we need to increase virtual buttons, then increase below.
|
||||
|
||||
// NEED TO FIX, IF WE CHANGE TO ANOTHING OTHER THAN 0 CORE DUMP (we also had "panel_type = RS-16 Combo" in config)
|
||||
#define VIRTUAL_BUTTONS 0
|
||||
|
||||
#ifndef AQ_RS16
|
||||
#define TOTAL_BUTTONS 12
|
||||
#define TOTAL_BUTTONS 12+VIRTUAL_BUTTONS
|
||||
#else
|
||||
#define TOTAL_BUTTONS 20
|
||||
#define TOTAL_BUTTONS 20+VIRTUAL_BUTTONS // Biggest jandy panel
|
||||
// This needs to be called AFTER and as well as initButtons
|
||||
void initButtons_RS16(struct aqualinkdata *aqdata);
|
||||
#endif
|
||||
|
|
|
@ -212,7 +212,7 @@ int build_schedules_js(char* buffer, int size)
|
|||
//char *regexString="([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s.*(\\/api\\/.*\\/set).* value=([0-9]+).*";
|
||||
|
||||
//char *regexString="([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s.*(\\/api\\/.*\\/set).* value=([0-9]+).*";
|
||||
char *regexString="(#{0,1})([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s.*(\\/api\\/.*\\/set).* value=([0-9]+).*";
|
||||
const char *regexString="(#{0,1})([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s.*(\\/api\\/.*\\/set).* value=([0-9]+).*";
|
||||
|
||||
//char *regexString="([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s([^\\s]+)\\s.*(/api/.*/set).*value=([0-9]+).*";
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdint.h>
|
||||
#include "aq_serial.h"
|
||||
#include "aq_programmer.h"
|
||||
#include "sensors.h"
|
||||
//#include "aq_panel.h" // Moved to later in file to overcome circular dependancy. (crappy I know)
|
||||
|
||||
|
||||
|
@ -65,6 +66,7 @@ bool checkAqualinkTime(); // Only need to externalise this for PDA
|
|||
|
||||
#define MAX_PUMPS 4
|
||||
#define MAX_LIGHTS 4
|
||||
#define MAX_SENSORS 4
|
||||
|
||||
bool isVirtualButtonEnabled();
|
||||
|
||||
|
@ -308,6 +310,9 @@ struct aqualinkdata
|
|||
volatile bool updated;
|
||||
char self[AQ_MSGLEN*2];
|
||||
|
||||
int num_sensors;
|
||||
external_sensor sensors[MAX_SENSORS];
|
||||
|
||||
#ifdef AQ_MANAGER
|
||||
volatile bool run_slogger;
|
||||
int slogger_packets;
|
||||
|
|
|
@ -396,6 +396,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
_aqualink_data.num_pumps = 0;
|
||||
_aqualink_data.num_lights = 0;
|
||||
_aqualink_data.num_sensors = 0;
|
||||
|
||||
#ifdef AQ_TM_DEBUG
|
||||
addDebugLogMask(DBGT_LOG);
|
||||
|
@ -656,7 +657,9 @@ int startup(char *self, char *cfgFile)
|
|||
LOG(AQUA_LOG,LOG_NOTICE, "Read Chem Feeder direct = %s\n", bool2text(READ_RSDEV_CHEM));
|
||||
|
||||
if (isAQS_START_PUMP_EVENT_ENABLED) {
|
||||
get_cron_pump_times();
|
||||
if (isAQS_USE_PUMP_TIME_FROM_CRON_ENABLED) {
|
||||
get_cron_pump_times();
|
||||
}
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Start Pump on events = %s %s %s\n",isAQS_POWER_ON_ENABED?"PowerON":"",AQS_FRZ_PROTECT_OFF?"FreezeProtect":"",AQS_BOOST_OFF?"Boost":"");
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Start Pump between times = %d:00 and %d:00\n",_aqconfig_.sched_chk_pumpon_hour,_aqconfig_.sched_chk_pumpoff_hour);
|
||||
} else {
|
||||
|
@ -725,6 +728,11 @@ int startup(char *self, char *cfgFile)
|
|||
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.num_sensors; i++)
|
||||
{
|
||||
LOG(AQUA_LOG,LOG_NOTICE, "Config Sensor %02d = label %-15s | %s\n", i+1, _aqualink_data.sensors[i].label, _aqualink_data.sensors[i].path);
|
||||
}
|
||||
/*
|
||||
for (i=0; i < _aqualink_data.total_buttons; i++)
|
||||
{
|
||||
|
@ -735,6 +743,10 @@ int startup(char *self, char *cfgFile)
|
|||
_aqualink_data.aqbuttons[i].rssd_code);
|
||||
}
|
||||
*/
|
||||
#ifdef CONFIG_EDITOR
|
||||
check_print_config(&_aqualink_data);
|
||||
writeCfg(&_aqualink_data);
|
||||
#endif
|
||||
|
||||
if (_aqconfig_.deamonize == true)
|
||||
{
|
||||
|
@ -945,6 +957,10 @@ void main_loop()
|
|||
_aqualink_data.lights[i].RSSDstate = OFF;
|
||||
}
|
||||
|
||||
for (i=0; i < _aqualink_data.num_sensors; i++) {
|
||||
_aqualink_data.sensors[i].value = TEMP_UNKNOWN;
|
||||
}
|
||||
|
||||
if (_aqconfig_.force_swg == true) {
|
||||
//_aqualink_data.ar_swg_device_status = SWG_STATUS_OFF;
|
||||
_aqualink_data.swg_led_state = OFF;
|
||||
|
@ -1174,6 +1190,7 @@ void main_loop()
|
|||
blank_read_reconnect = blank_read_reconnect * 50;
|
||||
#endif
|
||||
|
||||
int loopnum=0;
|
||||
blank_read = 0;
|
||||
// OK, Now go into infinate loop
|
||||
while (_keepRunning == true)
|
||||
|
@ -1375,6 +1392,15 @@ void main_loop()
|
|||
}
|
||||
}
|
||||
|
||||
if ( _aqualink_data.num_sensors > 0 && ++loopnum >= 200 ) {
|
||||
loopnum=0;
|
||||
for (int i=0; i < _aqualink_data.num_sensors; i++) {
|
||||
if (read_sensor(&_aqualink_data.sensors[i]) ) {
|
||||
_aqualink_data.updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//tcdrain(rs_fd); // Make sure buffer has been sent.
|
||||
//delay(10);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ Intelibright
|
|||
Haywood Universal Color
|
||||
|
||||
*/
|
||||
bool isShowMode(const char *mode);
|
||||
|
||||
/****** This list MUST be in order of clight_type enum *******/
|
||||
char *_color_light_options[NUMBER_LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS] =
|
||||
|
@ -170,11 +171,23 @@ bool set_aqualinkd_light_mode_name(char *name, int index, bool isShow)
|
|||
}
|
||||
}
|
||||
|
||||
// TODO NSF check isShow and add a custom one if needed
|
||||
_color_light_options[0][index] = name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *get_aqualinkd_light_mode_name(int index, bool *isShow)
|
||||
{
|
||||
// if index 1 is "1" then none are set.
|
||||
if ( strcmp(_color_light_options[0][1], "1") == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*isShow = isShowMode(_color_light_options[0][index]);
|
||||
return _color_light_options[0][index];
|
||||
}
|
||||
|
||||
const char *get_currentlight_mode_name(clight_detail light, emulation_type protocol)
|
||||
{
|
||||
/*
|
||||
|
@ -223,6 +236,9 @@ const char *light_mode_name(clight_type type, int index, emulation_type protocol
|
|||
|
||||
bool isShowMode(const char *mode)
|
||||
{
|
||||
if (mode == NULL)
|
||||
return false;
|
||||
|
||||
if (strcmp(mode, "Color Splash") == 0 ||
|
||||
strcmp(mode, "Slow Splash") == 0 ||
|
||||
strcmp(mode, "Fast Splash") == 0 ||
|
||||
|
|
|
@ -35,6 +35,7 @@ int build_color_light_jsonarray(int index, char* buffer, int size);
|
|||
void set_currentlight_value(clight_detail *light, int index);
|
||||
|
||||
bool set_aqualinkd_light_mode_name(char *name, int index, bool isShow);
|
||||
const char *get_aqualinkd_light_mode_name(int index, bool *isShow);
|
||||
|
||||
//char *_color_light_options_[LIGHT_COLOR_TYPES][LIGHT_COLOR_OPTIONS][LIGHT_COLOR_NAME];
|
||||
|
||||
|
|
1319
source/config.c
1319
source/config.c
File diff suppressed because it is too large
Load Diff
206
source/config.h
206
source/config.h
|
@ -6,6 +6,8 @@
|
|||
#include "aq_serial.h"
|
||||
#include "aqualink.h"
|
||||
|
||||
//#define CONFIG_DEV_TEST
|
||||
//#define CONFIG_EDITOR
|
||||
|
||||
//#define DEFAULT_LOG_LEVEL 10
|
||||
#define DEFAULT_LOG_LEVEL LOG_NOTICE
|
||||
|
@ -86,10 +88,15 @@ struct aqconfig
|
|||
//bool read_pentair_packets;
|
||||
uint8_t read_RS485_devmask;
|
||||
bool use_panel_aux_labels;
|
||||
|
||||
//uint8_t force_device_devmask; // should change the below to devmask
|
||||
|
||||
bool force_swg;
|
||||
bool force_ps_setpoints;
|
||||
bool force_frzprotect_setpoints;
|
||||
bool force_chem_feeder;
|
||||
|
||||
|
||||
//int swg_zero_ignore; // This can be removed since this was due to VSP that's been fixed.
|
||||
bool display_warnings_web;
|
||||
bool log_protocol_packets; // Read & Write as packets
|
||||
|
@ -105,7 +112,8 @@ struct aqconfig
|
|||
bool mqtt_timed_update;
|
||||
bool sync_panel_time;
|
||||
bool enable_scheduler;
|
||||
int16_t schedule_event_mask;
|
||||
int8_t schedule_event_mask; // Was int16_t, but no need
|
||||
//int16_t schedule_event_mask;
|
||||
//bool sched_chk_poweron;
|
||||
//bool sched_chk_freezeprotectoff;
|
||||
//bool sched_chk_boostoff;
|
||||
|
@ -138,6 +146,17 @@ struct aqconfig _aqconfig_;
|
|||
#define isPDA_IAQT (_aqconfig_.device_id == 0x33)
|
||||
//#define isPDA ((_aqconfig_.paneltype_mask & RSP_PDA) == RSP_PDA)
|
||||
|
||||
/*
|
||||
#define FORCE_SWG_SP (1 << 0)
|
||||
#define FORCE_POOLSPA_SP (1 << 1)
|
||||
#define FORCE_FREEZEPROTECT_SP (1 << 2)
|
||||
#define FORCE_CHEM_FEEDER (1 << 3)
|
||||
|
||||
#define ENABLE_SWG ((_aqconfig_.force_device_devmask & FORCE_SWG_SP) == FORCE_SWG_SP)
|
||||
#define ENABLE_HEATERs ((_aqconfig_.force_device_devmask & FORCE_POOLSPA_SP) == FORCE_POOLSPA_SP)
|
||||
#define ENABLE_FREEZEPROTECT ((_aqconfig_.force_device_devmask & FORCE_FREEZEPROTECT_SP) == FORCE_FREEZEPROTECT_SP)
|
||||
#define ENABLE_CHEM_FEEDER ((_aqconfig_.force_device_devmask & FORCE_CHEM_FEEDER) == FORCE_CHEM_FEEDER)
|
||||
*/
|
||||
|
||||
/*
|
||||
#ifndef CONFIG_C
|
||||
|
@ -159,6 +178,189 @@ void init_config();
|
|||
bool writeCfg (struct aqualinkdata *aqdata);
|
||||
bool setConfigValue(struct aqualinkdata *aqdata, char *param, char *value);
|
||||
bool mac(char *buf, int len, bool useDelimiter);
|
||||
char *cleanalloc(char*str);
|
||||
char *cleanalloc(char *str);
|
||||
char *ncleanalloc(char *str, int length);
|
||||
|
||||
const char *pumpType2String(pump_type ptype);
|
||||
|
||||
#ifdef CONFIG_EDITOR
|
||||
int save_config_js(const char* inBuf, int inSize, char* outBuf, int outSize);
|
||||
void check_print_config (struct aqualinkdata *aqdata);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEV_TEST) || defined(CONFIG_EDITOR)
|
||||
typedef enum cfg_value_type{
|
||||
CFG_STRING,
|
||||
CFG_INT,
|
||||
CFG_FLOAT,
|
||||
CFG_HEX,
|
||||
CFG_BOOL,
|
||||
CFG_BITMASK,
|
||||
CFG_SPECIAL
|
||||
} cfg_value_type;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_TEST
|
||||
typedef struct cfgParam {
|
||||
void *value_ptr;
|
||||
//int max_value; // Max length of string (maybe mad int as well)
|
||||
cfg_value_type value_type;
|
||||
char *name;
|
||||
char *valid_values;
|
||||
uint8_t mask;
|
||||
} cfgParam;
|
||||
|
||||
#ifndef CONFIG_C
|
||||
extern cfgParam _cfgParams[];
|
||||
extern int _numCfgParams;
|
||||
#else
|
||||
cfgParam _cfgParams[100];
|
||||
int _numCfgParams;
|
||||
#endif // CONFIG_C
|
||||
#endif // CONFIG_DEV_TEST
|
||||
|
||||
// Below are missed
|
||||
//RSSD_LOG_filter
|
||||
//debug_log_mask
|
||||
#define CFG_V_BOOL "[\"Yes\", \"No\"]"
|
||||
|
||||
#define CFG_N_serial_port "serial_port"
|
||||
#define CFG_C_serial_port 11
|
||||
#define CFG_N_log_level "log_level"
|
||||
#define CFG_V_log_level "[\"DEBUG\", \"INFO\", \"NOTICE\", \"WARNING\", \"ERROR\"]"
|
||||
#define CFG_C_log_level 9
|
||||
#define CFG_N_socket_port "socket_port"
|
||||
#define CFG_C_socket_port 11
|
||||
#define CFG_N_web_directory "web_directory"
|
||||
#define CFG_C_web_directory 13
|
||||
#define CFG_N_device_id "device_id"
|
||||
#define CFG_V_device_id "[\"0x0a\", \"0x0b\", \"0x09\", \"0x08\", \"0x60\", \"0xFF\"]"
|
||||
#define CFG_C_device_id 9
|
||||
#define CFG_N_rssa_device_id "rssa_device_id"
|
||||
#define CFG_V_rssa_device_id "[\"0x00\", \"0x48\", \"0xFF\"]"
|
||||
#define CFG_C_rssa_device_id 14
|
||||
|
||||
#define CFG_N_RSSD_LOG_filter "RSSD_LOG_filter"
|
||||
#define CFG_C_RSSD_LOG_filter 15
|
||||
|
||||
#define CFG_N_panel_type "panel_type"
|
||||
#define CFG_C_panel_type 10
|
||||
#define CFG_N_extended_device_id "extended_device_id"
|
||||
#define CFG_V_extended_device_id "[\"0x00\", \"0x30\", \"0x31\", \"0x32\", \"0x33\", \"0x40\", \"0x41\", \"0x42\", \"0x43\", \"0xFF\"]"
|
||||
#define CFG_C_extended_device_id 18
|
||||
|
||||
#define CFG_N_sync_panel_time "sync_panel_time"
|
||||
#define CFG_C_sync_panel_time 15
|
||||
|
||||
//#define CFG_N_extended_device_id2 "extended_device_id2"
|
||||
//#define CFG_C_extended_device_id2 20
|
||||
#define CFG_N_extended_device_id_programming "extended_device_id_programming"
|
||||
#define CFG_C_extended_device_id_programming 30
|
||||
#define CFG_N_enable_iaqualink "enable_iaqualink"
|
||||
#define CFG_C_enable_iaqualink 16
|
||||
#define CFG_N_log_file "log_file"
|
||||
#define CFG_C_log_file 8
|
||||
#define CFG_N_mqtt_aq_topic "mqtt_aq_topic"
|
||||
#define CFG_C_mqtt_aq_topic 13
|
||||
#define CFG_N_mqtt_server "mqtt_address"
|
||||
#define CFG_C_mqtt_server 12
|
||||
#define CFG_N_mqtt_user "mqtt_user"
|
||||
#define CFG_C_mqtt_user 9
|
||||
#define CFG_N_mqtt_passwd "mqtt_passwd"
|
||||
#define CFG_C_mqtt_passwd 11
|
||||
#define CFG_N_mqtt_hass_discover_topic "mqtt_ha_discover_topic"
|
||||
#define CFG_C_mqtt_hass_discover_topic 24
|
||||
#define CFG_N_mqtt_hass_discover_use_mac "mqtt_ha_discover_use_mac"
|
||||
#define CFG_C_mqtt_hass_discover_use_mac 27
|
||||
#define CFG_N_mqtt_timed_update "mqtt_timed_update"
|
||||
#define CFG_C_mqtt_timed_update 17
|
||||
//#define CFG_N_mqtt_ID "mqtt_ID"
|
||||
//#define CFG_C_mqtt_ID 7
|
||||
#define CFG_N_mqtt_dz_sub_topic "mqtt_dz_sub_topic"
|
||||
#define CFG_C_mqtt_dz_sub_topic 17
|
||||
#define CFG_N_mqtt_dz_pub_topic "mqtt_dz_pub_topic"
|
||||
#define CFG_C_mqtt_dz_pub_topic 17
|
||||
#define CFG_N_dzidx_air_temp "dzidx_air_temp"
|
||||
#define CFG_C_dzidx_air_temp 14
|
||||
#define CFG_N_dzidx_pool_water_temp "dzidx_pool_water_temp"
|
||||
#define CFG_C_dzidx_pool_water_temp 21
|
||||
#define CFG_N_dzidx_spa_water_temp "dzidx_spa_water_temp"
|
||||
#define CFG_C_dzidx_spa_water_temp 20
|
||||
#define CFG_N_dzidx_swg_percent "dzidx_SWG_percent"
|
||||
#define CFG_C_dzidx_swg_percent 17
|
||||
#define CFG_N_dzidx_swg_ppm "dzidx_SWG_PPM"
|
||||
#define CFG_C_dzidx_swg_ppm 13
|
||||
#define CFG_N_dzidx_swg_status "dzidx_SWG_Status"
|
||||
#define CFG_C_dzidx_swg_status 16
|
||||
#define CFG_N_light_programming_mode "light_programming_mode"
|
||||
#define CFG_C_light_programming_mode 22
|
||||
#define CFG_N_light_programming_initial_on "light_programming_initial_on"
|
||||
#define CFG_C_light_programming_initial_on 28
|
||||
#define CFG_N_light_programming_initial_off "light_programming_initial_off"
|
||||
#define CFG_C_light_programming_initial_off 29
|
||||
#define CFG_N_override_freeze_protect "override_freeze_protect"
|
||||
#define CFG_C_override_freeze_protect 23
|
||||
#define CFG_N_pda_sleep_mode "pda_sleep_mode"
|
||||
#define CFG_C_pda_sleep_mode 14
|
||||
#define CFG_N_convert_mqtt_temp "mqtt_convert_temp_to_c"
|
||||
#define CFG_C_convert_mqtt_temp 22
|
||||
#define CFG_N_convert_dz_temp "dz_convert_temp_to_c"
|
||||
#define CFG_C_convert_dz_temp 20
|
||||
#define CFG_N_report_zero_spa_temp "report_zero_spa_temp"
|
||||
#define CFG_C_report_zero_spa_temp 20
|
||||
#define CFG_N_report_zero_pool_temp "report_zero_pool_temp"
|
||||
#define CFG_C_report_zero_pool_temp 21
|
||||
#define CFG_N_read_RS485_devmask "read_RS485_devmask"
|
||||
#define CFG_C_read_RS485_devmask 18
|
||||
#define CFG_N_use_panel_aux_labels "use_panel_aux_labels"
|
||||
#define CFG_C_use_panel_aux_labels 20
|
||||
#define CFG_N_force_swg "force_swg"
|
||||
#define CFG_C_force_swg 9
|
||||
#define CFG_N_force_ps_setpoints "force_ps_setpoints"
|
||||
#define CFG_C_force_ps_setpoints 18
|
||||
#define CFG_N_force_frzprotect_setpoints "force_frzprotect_setpoints"
|
||||
#define CFG_C_force_frzprotect_setpoints 26
|
||||
#define CFG_N_force_chem_feeder "force_chem_feeder"
|
||||
#define CFG_C_force_chem_feeder 17
|
||||
#define CFG_N_display_warnings_web "display_warnings_web"
|
||||
#define CFG_C_display_warnings_web 20
|
||||
#define CFG_N_log_protocol_packets "log_protocol_packets"
|
||||
#define CFG_C_log_protocol_packets 20
|
||||
#define CFG_N_device_pre_state "device_pre_state"
|
||||
#define CFG_C_device_pre_state 16
|
||||
|
||||
#define CFG_N_read_RS485_swg "read_RS485_swg"
|
||||
#define CFG_C_read_RS485_swg 14
|
||||
#define CFG_N_read_RS485_ePump "read_RS485_ePump"
|
||||
#define CFG_C_read_RS485_ePump 16
|
||||
#define CFG_N_read_RS485_vsfPump "read_RS485_vsfPump"
|
||||
#define CFG_C_read_RS485_vsfPump 18
|
||||
#define CFG_N_read_RS485_JXi "read_RS485_JXi"
|
||||
#define CFG_C_read_RS485_JXi 14
|
||||
#define CFG_N_read_RS485_LX "read_RS485_LX"
|
||||
#define CFG_C_read_RS485_LX 13
|
||||
#define CFG_N_read_RS485_Chem "read_RS485_Chem"
|
||||
#define CFG_C_read_RS485_Chem 15
|
||||
#define CFG_N_read_RS485_iAqualink "read_RS485_iAqualink"
|
||||
#define CFG_C_read_RS485_iAqualink 20
|
||||
|
||||
|
||||
#define CFG_N_enable_scheduler "enable_scheduler"
|
||||
#define CFG_C_enable_scheduler 16
|
||||
#define CFG_N_scheduler_check_poweron "scheduler_check_poweron"
|
||||
#define CFG_C_scheduler_check_poweron 23
|
||||
#define CFG_N_scheduler_check_freezeprotectoff "scheduler_check_freezeprotectoff"
|
||||
#define CFG_C_scheduler_check_freezeprotectoff 32
|
||||
#define CFG_N_scheduler_check_boostoff "scheduler_check_boostoff"
|
||||
#define CFG_C_scheduler_check_boostoff 24
|
||||
#define CFG_N_scheduler_check_pumpon_hour "scheduler_check_pumpon_hour"
|
||||
#define CFG_C_scheduler_check_pumpon_hour 27
|
||||
#define CFG_N_scheduler_check_pumpoff_hour "scheduler_check_pumpoff_hour"
|
||||
#define CFG_C_scheduler_check_pumpoff_hour 28
|
||||
|
||||
#define CFG_N_ftdi_low_latency "ftdi_low_latency"
|
||||
#define CFG_C_ftdi_low_latency 16
|
||||
#define CFG_N_rs485_frame_delay "rs485_frame_delay"
|
||||
#define CFG_C_rs485_frame_delay 17
|
||||
|
||||
#endif
|
||||
|
|
|
@ -667,5 +667,17 @@ void publish_mqtt_hassio_discover(struct aqualinkdata *aqdata, struct mg_connect
|
|||
sprintf(msg, HASSIO_BATTERY_SENSOR_DISCOVER,connections,_aqconfig_.mqtt_aq_topic,BATTERY_STATE,BATTERY_STATE,_aqconfig_.mqtt_aq_topic,BATTERY_STATE);
|
||||
sprintf(topic, "%s/binary_sensor/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic,BATTERY_STATE);
|
||||
send_mqtt(nc, topic, msg);
|
||||
|
||||
for (i=0; i < aqdata->num_sensors; i++) {
|
||||
//sprintf(idbuf, "%s_%s","sensor",aqdata->sensors[i].label);
|
||||
sprintf(topic, "%s/%s",SENSOR_TOPIC,aqdata->sensors[i].label);
|
||||
rsm_char_replace(idbuf, topic, "/", "_");
|
||||
//sprintf(msg, HASSIO_SENSOR_DISCOVER,connections,_aqconfig_.mqtt_aq_topic,idbuf,aqdata->sensors[i].label,_aqconfig_.mqtt_aq_topic,topic, "°C", "mdi:thermometer");
|
||||
// Use HASSIO_TEMP_SENSOR_DISCOVER over HASSIO_SENSOR_DISCOVER since it has device class temperature and HA will convert automatically.
|
||||
sprintf(msg, HASSIO_TEMP_SENSOR_DISCOVER,connections,_aqconfig_.mqtt_aq_topic,idbuf,aqdata->sensors[i].label,_aqconfig_.mqtt_aq_topic,topic, "°C", "mdi:thermometer");
|
||||
|
||||
sprintf(topic, "%s/sensor/aqualinkd/aqualinkd_%s/config", _aqconfig_.mqtt_hass_discover_topic, idbuf);
|
||||
send_mqtt(nc, topic, msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -883,13 +883,26 @@ void processPage(struct aqualinkdata *aq_data)
|
|||
}
|
||||
}
|
||||
|
||||
#define REQUEST_STATUS_POLL_COUNT 10
|
||||
#define REQUEST_DEVICES_POLL_COUNT 30 // if _aqconfig_.enable_iaqualink=true then REQUEST_STATUS_POLL_COUNT will be used.
|
||||
// if enable_iaqualink this poll count can be increased if we sit on the device status page
|
||||
// all device status are quicker to update in enable_iaqualink, so leaves just pump/swg info to get.
|
||||
#define FULL_STATUS_POLL_COUNT 200 // We did have this at 20, but put too much load on panel, (couldn't program light)
|
||||
#define DEVICE_STATUS_POLL_COUNT 20 // This must be less than FULL_STATUS_POLL_COUNT
|
||||
|
||||
//#define REQUEST_DEVICES_POLL_COUNT 30 // if _aqconfig_.enable_iaqualink=true then REQUEST_STATUS_POLL_COUNT will be used.
|
||||
|
||||
static int _pollCnt;
|
||||
|
||||
// running through status while programming a lighgt seems to confuse the panel, so let
|
||||
// other people reset our poll count.
|
||||
void reset_iaqTouchPollCounter()
|
||||
{
|
||||
_pollCnt = 0;
|
||||
}
|
||||
|
||||
bool process_iaqtouch_packet(unsigned char *packet, int length, struct aqualinkdata *aq_data)
|
||||
{
|
||||
static bool gotInit = false;
|
||||
static int cnt = 0;
|
||||
//static int _pollCnt = 0;
|
||||
//static int probesSinceLastPageCMD=0;
|
||||
static bool gotStatus = true;
|
||||
static char message[AQ_MSGLONGLEN + 1];
|
||||
|
@ -1095,20 +1108,33 @@ if not programming && poll packet {
|
|||
else if status goto Home
|
||||
}
|
||||
increase counter
|
||||
|
||||
The above sits on device page.
|
||||
Should we sit on status page to get better updates of VSP/SWG? would make sence if iaqualink is enabeled
|
||||
since that gets all device updates quicker and cleaner.
|
||||
if we a PDA only, then sit on devices page.
|
||||
if iaqualink is not enabeled, still sit on status page.
|
||||
So why did I update this to sit on devices page???????????
|
||||
RS16 should also probably sit on devices page.
|
||||
}*/
|
||||
if (in_programming_mode(aq_data) == false) {
|
||||
//LOG(IAQT_LOG,LOG_DEBUG, "Poll counter = %d\n",_pollCnt);
|
||||
|
||||
if (_currentPage == IAQ_PAGE_HOME) {
|
||||
iaqt_queue_cmd(KEY_IAQTCH_HOMEP_KEY08); // This is "other devices on/off" page
|
||||
cnt = 0;
|
||||
_pollCnt = 0;
|
||||
}
|
||||
|
||||
//if ( (isPDA_PANEL || isVirtualButtonEnabled() || PANEL_SIZE() >= 16) && !in_iaqt_programming_mode(aq_data) ) {
|
||||
// Just sent Status Page request if none of the above are active
|
||||
//}
|
||||
// After we send devices page in above if statment, kick us through a loop of
|
||||
// devices devices1 devices2 devices2 status.
|
||||
// We probably only need to go over this loop if iaqualink2 is NOT enabled.
|
||||
// But may be better to simply increase FULL_STATUS_POLL_COUNT when it's not enabled.
|
||||
uint8_t nextPageRequestKey = KEY_IAQTCH_HOME;
|
||||
|
||||
if (cnt++ > REQUEST_STATUS_POLL_COUNT) {
|
||||
if (_pollCnt++ > FULL_STATUS_POLL_COUNT) {
|
||||
switch(_currentPage) {
|
||||
case IAQ_PAGE_DEVICES:
|
||||
case IAQ_PAGE_DEVICES_REV_Yg:
|
||||
|
@ -1132,27 +1158,22 @@ if not programming && poll packet {
|
|||
}
|
||||
|
||||
iaqt_queue_cmd(nextPageRequestKey);
|
||||
/*
|
||||
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_INFO, "Waiting to send next page cnt %d\n",probesSinceLastPageCMD);
|
||||
}
|
||||
*/
|
||||
|
||||
} else if ( (_pollCnt % DEVICE_STATUS_POLL_COUNT == 0) &&
|
||||
_currentPage == IAQ_PAGE_DEVICES || _currentPage == IAQ_PAGE_DEVICES_REV_Yg) {
|
||||
iaqt_queue_cmd(KEY_IAQTCH_STATUS); // This will force us to go to status, then it'll jump back to devices, then force status again
|
||||
}
|
||||
} else if (in_programming_mode(aq_data) == true) {
|
||||
// Set count to something close to max, so we will pull latest info once programming has finished.
|
||||
// This is good for VSP GPM programming as it takes number of seconds to register once finished programming.
|
||||
// -5 seems to be too quick for VSP/GPM so using 10
|
||||
cnt = REQUEST_STATUS_POLL_COUNT - 10;
|
||||
// This is probably not needed any more, since we grab status quite often now.
|
||||
_pollCnt = FULL_STATUS_POLL_COUNT - 10;
|
||||
}
|
||||
#else
|
||||
//LOG(IAQT_LOG,LOG_DEBUG, "poll count %d\n",cnt);
|
||||
//LOG(IAQT_LOG,LOG_DEBUG, "poll count %d\n",_pollCnt);
|
||||
// Load status page every 50 messages
|
||||
if (cnt++ > REQUEST_STATUS_POLL_COUNT && in_programming_mode(aq_data) == false ) {
|
||||
if (_pollCnt++ > FULL_STATUS_POLL_COUNT && in_programming_mode(aq_data) == false ) {
|
||||
if (isPDA_PANEL || PANEL_SIZE() >= 16) {
|
||||
iaqt_queue_cmd(KEY_IAQTCH_HOMEP_KEY08);
|
||||
} else {
|
||||
|
@ -1160,12 +1181,12 @@ if not programming && poll packet {
|
|||
}
|
||||
gotStatus = false; // Reset if we got status page, for fix panel bug.
|
||||
//aq_programmer(AQ_GET_IAQTOUCH_VSP_ASSIGNMENT, NULL, aq_data);
|
||||
cnt = 0;
|
||||
} else if (gotStatus == false && cnt > 3) {
|
||||
_pollCnt = 0;
|
||||
} else if (gotStatus == false && _pollCnt > 3) {
|
||||
// Fix bug with control panel where after a few hours status page disapears and you need to hit menu.
|
||||
LOG(IAQT_LOG,LOG_INFO, "Overcomming Jandy control panel bug, (missing status, goto menu)\n",cnt);
|
||||
LOG(IAQT_LOG,LOG_INFO, "Overcomming Jandy control panel bug, (missing status, goto menu)\n",_pollCnt);
|
||||
iaqt_queue_cmd(KEY_IAQTCH_HOME);
|
||||
cnt = REQUEST_STATUS_POLL_COUNT - 5;
|
||||
_pollCnt = FULL_STATUS_POLL_COUNT - 5;
|
||||
/*
|
||||
if (isPDA_PANEL) {
|
||||
iaqt_queue_cmd(KEY_IAQTCH_HOMEP_KEY08);
|
||||
|
@ -1179,7 +1200,7 @@ if not programming && poll packet {
|
|||
// Set count to something close to max, so we will pull latest info once programming has finished.
|
||||
// This is good for VSP GPM programming as it takes number of seconds to register once finished programming.
|
||||
// -5 seems to be too quick for VSP/GPM so using 10
|
||||
cnt = REQUEST_STATUS_POLL_COUNT - 10;
|
||||
_pollCnt = FULL_STATUS_POLL_COUNT - 10;
|
||||
}
|
||||
|
||||
// On poll no need to kick programming threads
|
||||
|
|
|
@ -481,7 +481,7 @@ bool process_iaqualink_packet(unsigned char *packet, int length, struct aqualink
|
|||
if (packet[PKT_CMD] == 0x53)
|
||||
{
|
||||
cnt++;
|
||||
if (cnt == 20) {
|
||||
if (cnt == 20) { // 20 is probably too low, should increase. (only RS16 and below)
|
||||
cnt=0;
|
||||
/*
|
||||
sendid=sendid==0x18?0x60:0x18;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "aq_programmer.h"
|
||||
#include "rs_msg_utils.h"
|
||||
#include "color_lights.h"
|
||||
#include "iaqualink.h"
|
||||
|
||||
//#define test_message "{\"type\": \"status\",\"version\": \"8157 REV MMM\",\"date\": \"09/01/16 THU\",\"time\": \"1:16 PM\",\"temp_units\": \"F\",\"air_temp\": \"96\",\"pool_temp\": \"86\",\"spa_temp\": \" \",\"battery\": \"ok\",\"pool_htr_set_pnt\": \"85\",\"spa_htr_set_pnt\": \"99\",\"freeze_protection\": \"off\",\"frz_protect_set_pnt\": \"0\",\"leds\": {\"pump\": \"on\",\"spa\": \"off\",\"aux1\": \"off\",\"aux2\": \"off\",\"aux3\": \"off\",\"aux4\": \"off\",\"aux5\": \"off\",\"aux6\": \"off\",\"aux7\": \"off\",\"pool_heater\": \"off\",\"spa_heater\": \"off\",\"solar_heater\": \"off\"}}"
|
||||
//#define test_labels "{\"type\": \"aux_labels\",\"aux1_label\": \"Cleaner\",\"aux2_label\": \"Waterfall\",\"aux3_label\": \"Spa Blower\",\"aux4_label\": \"Pool Light\",\"aux5_label\": \"Spa Light\",\"aux6_label\": \"Unassigned\",\"aux7_label\": \"Unassigned\"}"
|
||||
|
@ -539,6 +540,12 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
|
|||
|
||||
length += sprintf(buffer+length, "{\"type\": \"aqmanager\"");
|
||||
length += sprintf(buffer+length, ",\"deamonized\": \"%s\"", (_aqconfig_.deamonize?JSON_ON:JSON_OFF) );
|
||||
#ifdef CONFIG_EDITOR
|
||||
length += sprintf(buffer+length, ",\"config_editor\": \"yes\"");
|
||||
#else
|
||||
length += sprintf(buffer+length, ",\"config_editor\": \"no\"");
|
||||
#endif
|
||||
|
||||
/*
|
||||
length += sprintf(buffer+length, ",\"panel_type\":\"%s\"",getPanelString());
|
||||
length += sprintf(buffer+length, ",\"version\":\"%s\"",aqdata->version );//8157 REV MMM",
|
||||
|
@ -742,22 +749,18 @@ printf("Pump Type %d\n",aqdata->pumps[i].pumpType);
|
|||
length--;
|
||||
length += sprintf(buffer+length, "}");
|
||||
|
||||
/*
|
||||
for (i=0; i < aqdata->num_lights; i++)
|
||||
|
||||
length += sprintf(buffer+length, ",\"sensors\":{" );
|
||||
for (i=0; i < aqdata->num_sensors; i++)
|
||||
{
|
||||
length += sprintf(buffer+length, ",\"Plight_%d\":{\"name\":\"%s\",\"id\":\"%s\", \"type\":\"%d\", \"value\":\"%d\", \"state\":\"%s\"}",
|
||||
i+1,
|
||||
aqdata->lights[i].button->label,
|
||||
aqdata->lights[i].button->name,
|
||||
aqdata->lights[i].lightType,
|
||||
aqdata->lights[i].currentValue,
|
||||
LED2text(aqdata->lights[i].RSSDstate)
|
||||
);
|
||||
//printf("Sensor value %f %.2f\n",aqdata->sensors[i].value,aqdata->sensors[i].value);
|
||||
if (aqdata->sensors[i].value != TEMP_UNKNOWN) {
|
||||
length += sprintf(buffer+length, "\"%s\": \"%.2f\",", aqdata->sensors[i].label, aqdata->sensors[i].value );
|
||||
}
|
||||
}
|
||||
*/
|
||||
//if (buffer[length-1] == ',')
|
||||
// length--;
|
||||
//length += sprintf(buffer+length, "}");
|
||||
if (buffer[length-1] == ',')
|
||||
length--;
|
||||
length += sprintf(buffer+length, "}");
|
||||
|
||||
|
||||
length += sprintf(buffer+length, "}" );
|
||||
|
@ -1050,4 +1053,323 @@ bool parseJSONmqttrequest(const char *str, size_t len, int *idx, int *nvalue, ch
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
int json_cfg_element_OLD(char* buffer, int size, const char *name, const void *value, cfg_value_type type, char *valid_val) {
|
||||
int result = 0;
|
||||
|
||||
char valid_values[256];
|
||||
|
||||
if (valid_val != NULL) {
|
||||
sprintf(valid_values,",\"valid values\":%s",valid_val);
|
||||
}
|
||||
|
||||
switch(type){
|
||||
case CFG_INT:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%d\", \"type\":\"int\" %s}", name, *(int *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_STRING:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"string\" %s}", name, (char *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_BOOL:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"bool\" %s}", name, bool2text(*(bool *)value), (valid_val==NULL?"":valid_values));
|
||||
break;
|
||||
case CFG_HEX:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"0x%02hhx\", \"type\":\"hex\" %s}", name, *(unsigned char *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
}
|
||||
|
||||
if (result <= 0 || result >= size) {
|
||||
LOG(NET_LOG,LOG_ERR, "Buffer full in build_aqualink_config_JSON(), result truncated!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_EDITOR
|
||||
|
||||
int json_cfg_element(char* buffer, int size, const char *name, const void *value, cfg_value_type type, uint8_t mask, char *valid_val) {
|
||||
int result = 0;
|
||||
|
||||
char valid_values[256];
|
||||
|
||||
if (valid_val != NULL) {
|
||||
sprintf(valid_values,",\"valid values\":%s",valid_val);
|
||||
}
|
||||
|
||||
switch(type){
|
||||
case CFG_INT:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%d\", \"type\":\"int\" %s}", name, *(int *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_STRING:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"string\" %s}", name, *(char **)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_BOOL:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"bool\" %s}", name, bool2text(*(bool *)value), (valid_val==NULL?"":valid_values));
|
||||
break;
|
||||
case CFG_HEX:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"0x%02hhx\", \"type\":\"hex\" %s}", name, *(unsigned char *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_FLOAT:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%f\", \"type\":\"float\" %s}", name, *(float *)value, (valid_val==NULL?"":valid_values) );
|
||||
break;
|
||||
case CFG_BITMASK:
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"bool\" %s}", name, (*(uint8_t *)value & mask) == mask? bool2text(true):bool2text(false) ,CFG_V_BOOL );
|
||||
break;
|
||||
case CFG_SPECIAL:
|
||||
if (strncasecmp(name, CFG_N_log_level, strlen(CFG_N_log_level)) == 0) {
|
||||
//fprintf(fp, "%s=%s\n", _cfgParams[i].name, loglevel2cgn_name(_aqconfig_.log_level));
|
||||
//result = json_cfg_element(buffer+length, size-length, CFG_N_log_level, &stringptr, CFG_STRING, "[\"DEBUG\", \"INFO\", \"NOTICE\", \"WARNING\", \"ERROR\"]"));
|
||||
//stringptr = loglevel2cgn_name(_aqconfig_.log_level);
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"%s\", \"type\":\"string\" %s}",name,loglevel2cgn_name(*(int *)value), "[\"DEBUG\", \"INFO\", \"NOTICE\", \"WARNING\", \"ERROR\"]");
|
||||
} else {
|
||||
result = snprintf(buffer, size, ",\"%s\" : {\"value\":\"Something went wrong\", \"type\":\"string\"}",name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (result <= 0 || result >= size) {
|
||||
LOG(NET_LOG,LOG_ERR, "Buffer full in build_aqualink_config_JSON(), result truncated!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
const char *pumpType2String(pump_type ptype) {
|
||||
switch (ptype) {
|
||||
case EPUMP:
|
||||
return "JANDY ePUMP";
|
||||
break;
|
||||
case VSPUMP:
|
||||
return "Pentair VF";
|
||||
break;
|
||||
case VFPUMP:
|
||||
return "Pentair VS";
|
||||
break;
|
||||
case PT_UNKNOWN:
|
||||
default:
|
||||
return "unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_data)
|
||||
{
|
||||
memset(&buffer[0], 0, size);
|
||||
int length = 0;
|
||||
int result;
|
||||
int i;
|
||||
char buf[256];
|
||||
const char *stringptr;
|
||||
|
||||
if ((result = snprintf(buffer+length, size-length, "{\"type\": \"config\"")) < 0 || result >= size-length) {
|
||||
length += snprintf(buffer+length, size-length, "}");
|
||||
return length;
|
||||
} else {
|
||||
length += result;
|
||||
}
|
||||
|
||||
if ((result = snprintf(buffer+length, size-length, ",\"status\": \"!!!! NOT FULLY IMPLIMENTED YET !!!!\"")) < 0 || result >= size-length) {
|
||||
length += snprintf(buffer+length, size-length, "}");
|
||||
return length;
|
||||
} else {
|
||||
length += result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEV_TEST
|
||||
for (int i=0; i <= _numCfgParams; i++) {
|
||||
if ((result = json_cfg_element(buffer+length, size-length, _cfgParams[i].name, _cfgParams[i].value_ptr, _cfgParams[i].value_type, _cfgParams[i].mask, _cfgParams[i].valid_values)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TODO add custom light modes/colors
|
||||
|
||||
// TODO add RSSD LOG FILTERS
|
||||
|
||||
// TODO add devmask for reading RS485 external
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if ((result = json_cfg_element(buffer+length, size-length, "config_file", _aqconfig_.config_file, CFG_STRING, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
*/
|
||||
stringptr = getPanelString();
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_panel_type, &stringptr, CFG_STRING, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_device_id, &_aqconfig_.device_id, CFG_HEX, 0, "[\"0x0a\", \"0x0b\", \"0x09\", \"0x08\", \"0x60\", \"0xFF\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_rssa_device_id, &_aqconfig_.rssa_device_id, CFG_HEX, 0, "[\"0x00\", \"0x48\", \"0xFF\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
#if defined AQ_ONETOUCH || defined AQ_IAQTOUCH
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_extended_device_id, &_aqconfig_.extended_device_id, CFG_HEX, 0, "[\"0x00\", \"0x30\", \"0x31\", \"0x32\", \"0x33\", \"0x40\", \"0x41\", \"0x42\", \"0x43\", \"0xFF\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_extended_device_id, &_aqconfig_.extended_device_id_programming, CFG_BOOL, 0, "[\"YES\", \"NO\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_enable_iaqualink, &_aqconfig_.enable_iaqualink, CFG_BOOL, 0, "[\"YES\", \"NO\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
#endif
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_serial_port, &_aqconfig_.serial_port, CFG_STRING, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_socket_port, &_aqconfig_.socket_port, CFG_STRING, 0, NULL )) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
stringptr = loglevel2cgn_name(_aqconfig_.log_level);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_log_level, &stringptr, CFG_STRING, 0, "[\"DEBUG\", \"INFO\", \"NOTICE\", \"WARNING\", \"ERROR\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, CFG_N_web_directory, &_aqconfig_.web_directory, CFG_STRING, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, "sched_chk_pumpon_hour", &_aqconfig_.sched_chk_pumpon_hour, CFG_INT, 0, NULL )) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
|
||||
// OTHERS
|
||||
|
||||
|
||||
|
||||
// OTHERS
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, "force_swg", &_aqconfig_.force_swg, CFG_BOOL, 0, "[\"YES\", \"NO\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if ((result = json_cfg_element(buffer+length, size-length, "use_panel_aux_labels", &_aqconfig_.use_panel_aux_labels, CFG_BOOL, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
|
||||
// All buttons
|
||||
|
||||
for (i = 0; i < aq_data->total_buttons; i++)
|
||||
{
|
||||
char prefix[30];
|
||||
if (isVBUTTON(aq_data->aqbuttons[i].special_mask)) {
|
||||
sprintf(prefix,"virtual_button_%.2d",(i+1)-aq_data->virtual_button_start);
|
||||
} else {
|
||||
sprintf(prefix,"button_%.2d",i+1);
|
||||
}
|
||||
|
||||
sprintf(buf,"%s_label", prefix);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &aq_data->aqbuttons[i].label, CFG_STRING, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
|
||||
if (isVS_PUMP(aq_data->aqbuttons[i].special_mask))
|
||||
{
|
||||
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpIndex > 0) {
|
||||
sprintf(buf,"%s_pumpIndex", prefix);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpIndex, CFG_INT, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
|
||||
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpID != NUL) {
|
||||
sprintf(buf,"%s_pumpID", prefix);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpID, CFG_HEX, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
|
||||
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpName[0] != '\0') {
|
||||
sprintf(buf,"%s_pumpName", prefix);
|
||||
stringptr = ((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpName;
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &stringptr, CFG_STRING, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
|
||||
if (((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType != PT_UNKNOWN) {
|
||||
sprintf(buf,"%s_pumpType", prefix);
|
||||
stringptr = pumpType2String(((pump_detail *)aq_data->aqbuttons[i].special_mask_ptr)->pumpType);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &stringptr, CFG_STRING, 0, "[\"JANDY ePUMP\",\"Pentair VS\",\"Pentair VF\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
} else if (isPLIGHT(aq_data->aqbuttons[i].special_mask)) {
|
||||
if (((clight_detail *)aq_data->aqbuttons[i].special_mask_ptr)->lightType > 0) {
|
||||
sprintf(buf,"%s_lightMode", prefix);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &((clight_detail *)aq_data->aqbuttons[i].special_mask_ptr)->lightType, CFG_INT, 0, NULL)) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
} else if ( (isVBUTTON(aq_data->aqbuttons[i].special_mask) && aq_data->aqbuttons[i].rssd_code >= IAQ_ONETOUCH_1 && aq_data->aqbuttons[i].rssd_code <= IAQ_ONETOUCH_6 ) ) {
|
||||
sprintf(buf,"%s_onetouchID", prefix);
|
||||
int oID = (aq_data->aqbuttons[i].rssd_code - 15);
|
||||
if ((result = json_cfg_element(buffer+length, size-length, buf, &oID, CFG_INT, 0, "[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\"]")) <= 0)
|
||||
return length;
|
||||
else
|
||||
length += result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((result = snprintf(buffer+length, size-length, "}")) < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
length += result;
|
||||
}
|
||||
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -59,6 +59,7 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
|
|||
//int build_device_JSON(struct aqualinkdata *aqdata, int programable_switch1, int programable_switch2, char* buffer, int size, bool homekit);
|
||||
int build_device_JSON(struct aqualinkdata *aqdata, char* buffer, int size, bool homekit);
|
||||
int build_aqualink_simulator_packet_JSON(struct aqualinkdata *aqdata, char* buffer, int size);
|
||||
int build_aqualink_config_JSON(char* buffer, int size, struct aqualinkdata *aq_data);
|
||||
|
||||
#endif /* JSON_MESSAGES_H_ */
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ bool _broadcast_systemd_logmessages(bool aqMgrActive, bool reOpenStaleConnection
|
|||
size_t plen;
|
||||
int rtn;
|
||||
|
||||
while ( (rtn = sd_journal_next(journal)) > 0) // need to capture return of this
|
||||
while ( (rtn = sd_journal_next(journal)) > 0)
|
||||
{
|
||||
if (sd_journal_get_data(journal, "MESSAGE", &log, &len) < 0) {
|
||||
build_logmsg_JSON(msg, LOG_ERR, "Failed to get journal message", WS_LOG_LENGTH,29);
|
||||
|
@ -323,7 +323,7 @@ bool _broadcast_systemd_logmessages(bool aqMgrActive, bool reOpenStaleConnection
|
|||
}
|
||||
}
|
||||
if (rtn < 0) {
|
||||
build_logmsg_JSON(msg, LOG_ERR, "Failed to get seen to next journal message", WS_LOG_LENGTH,42);
|
||||
build_logmsg_JSON(msg, LOG_ERR, "Failed to seek to next journal message", WS_LOG_LENGTH,42);
|
||||
ws_send_logmsg(_mgr.active_connections, msg);
|
||||
sd_journal_close(journal);
|
||||
active = false;
|
||||
|
@ -339,6 +339,8 @@ bool _broadcast_systemd_logmessages(bool aqMgrActive, bool reOpenStaleConnection
|
|||
//LOG(NET_LOG, LOG_WARNING, "**** %d Too many blank reads, resetting!! ****\n",cnt);
|
||||
return _broadcast_systemd_logmessages(aqMgrActive, true);
|
||||
}
|
||||
cnt = 0; // Reset this so we don't keep hitting this when we don't print the message above.
|
||||
|
||||
//LOG(NET_LOG, LOG_WARNING, "**** Reset didn't work ****\n",cnt);
|
||||
//return false;
|
||||
}
|
||||
|
@ -975,10 +977,20 @@ void mqtt_broadcast_aqualinkstate(struct mg_connection *nc)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over sensors
|
||||
for (i=0; i < _aqualink_data->num_sensors; i++) {
|
||||
if ( _aqualink_data->sensors[i].value != TEMP_UNKNOWN && _last_mqtt_aqualinkdata.sensors[i].value != _aqualink_data->sensors[i].value) {
|
||||
char topic[50];
|
||||
sprintf(topic, "%s/%s", SENSOR_TOPIC, _aqualink_data->sensors[i].label);
|
||||
send_mqtt_float_msg(nc, topic, _aqualink_data->sensors[i].value);
|
||||
_last_mqtt_aqualinkdata.sensors[i].value = _aqualink_data->sensors[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef enum {uActioned, uBad, uDevices, uStatus, uHomebridge, uDynamicconf, uDebugStatus, uDebugDownload, uSimulator, uSchedules, uSetSchedules, uAQmanager, uLogDownload, uNotAvailable} uriAtype;
|
||||
typedef enum {uActioned, uBad, uDevices, uStatus, uHomebridge, uDynamicconf, uDebugStatus, uDebugDownload, uSimulator, uSchedules, uSetSchedules, uAQmanager, uLogDownload, uNotAvailable, uConfig, uSaveConfig} uriAtype;
|
||||
//typedef enum {NET_MQTT=0, NET_API, NET_WS, DZ_MQTT} netRequest;
|
||||
const char actionName[][5] = {"MQTT", "API", "WS", "DZ"};
|
||||
|
||||
|
@ -1067,6 +1079,10 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
return uSetSchedules;
|
||||
} else if (strncmp(ri1, "schedules", 9) == 0) {
|
||||
return uSchedules;
|
||||
} else if (strncmp(ri1, "config/set", 10) == 0) {
|
||||
return uSaveConfig;
|
||||
} else if (strncmp(ri1, "config", 6) == 0) {
|
||||
return uConfig;
|
||||
} else if (strncmp(ri1, "simulator", 9) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
if (ri2 != NULL && strncmp(ri2, "onetouch", 8) == 0) {
|
||||
start_simulator(_aqualink_data, ONETOUCH);
|
||||
|
@ -1678,7 +1694,7 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
DEBUG_TIMER_START(&tid2);
|
||||
int size = build_schedules_js(message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_schedules_js took");
|
||||
mg_send_head(nc, 200, size, CONTENT_JS);
|
||||
mg_send_head(nc, 200, size, CONTENT_JSON);
|
||||
mg_send(nc, message, size);
|
||||
}
|
||||
break;
|
||||
|
@ -1688,10 +1704,22 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
|||
DEBUG_TIMER_START(&tid2);
|
||||
int size = save_schedules_js(http_msg->body.p, http_msg->body.len, message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() save_schedules_js took");
|
||||
mg_send_head(nc, 200, size, CONTENT_JS);
|
||||
mg_send_head(nc, 200, size, CONTENT_JSON);
|
||||
mg_send(nc, message, size);
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_EDITOR
|
||||
case uConfig:
|
||||
{
|
||||
char message[JSON_BUFFER_SIZE];
|
||||
DEBUG_TIMER_START(&tid2);
|
||||
int size = build_aqualink_config_JSON(message, JSON_BUFFER_SIZE, _aqualink_data);
|
||||
DEBUG_TIMER_STOP(tid2, NET_LOG, "action_web_request() build_aqualink_config_JSON took");
|
||||
mg_send_head(nc, 200, size, CONTENT_JSON);
|
||||
mg_send(nc, message, size);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef AQ_MANAGER
|
||||
case uDebugStatus:
|
||||
{
|
||||
|
@ -1757,7 +1785,7 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
pda_reset_sleep();
|
||||
#endif
|
||||
|
||||
strncpy(buffer, (char *)wm->data, wm->size);
|
||||
strncpy(buffer, (char *)wm->data, MIN(wm->size, 99));
|
||||
buffer[wm->size] = '\0';
|
||||
|
||||
parseJSONrequest(buffer, &jsonkv);
|
||||
|
@ -1849,6 +1877,27 @@ void action_websocket_request(struct mg_connection *nc, struct websocket_message
|
|||
DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() save_schedules_js took");
|
||||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_EDITOR
|
||||
case uConfig:
|
||||
{
|
||||
DEBUG_TIMER_START(&tid);
|
||||
char message[JSON_BUFFER_SIZE];
|
||||
build_aqualink_config_JSON(message, JSON_BUFFER_SIZE, _aqualink_data);
|
||||
DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() build_aqualink_config_JSON took");
|
||||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
case uSaveConfig:
|
||||
{
|
||||
DEBUG_TIMER_START(&tid);
|
||||
char message[JSON_BUFFER_SIZE];
|
||||
save_config_js((char *)wm->data, wm->size, message, JSON_BUFFER_SIZE);
|
||||
DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() save_config_js took");
|
||||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case uBad:
|
||||
default:
|
||||
if (msg == NULL)
|
||||
|
@ -2080,6 +2129,10 @@ void reset_last_mqtt_status()
|
|||
_last_mqtt_aqualinkdata.lights[i].currentValue = TEMP_UNKNOWN;
|
||||
}
|
||||
|
||||
for (i=0; i < _aqualink_data->num_sensors; i++) {
|
||||
_last_mqtt_aqualinkdata.sensors[i].value = TEMP_UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void start_mqtt(struct mg_mgr *mgr) {
|
||||
|
|
|
@ -372,6 +372,8 @@ int rsm_strncmp(const char *haystack, const char *needle, int length)
|
|||
|
||||
char *rsm_char_replace(char *replaced , char *search, char *find, char *replace)
|
||||
{
|
||||
return rsm_nchar_replace(replaced, 0, search, find, replace);
|
||||
/*
|
||||
int len;
|
||||
int i;
|
||||
char *fp = find;
|
||||
|
@ -386,6 +388,30 @@ char *rsm_char_replace(char *replaced , char *search, char *find, char *replac
|
|||
}
|
||||
replaced[i] = '\0';
|
||||
|
||||
return replaced;
|
||||
*/
|
||||
}
|
||||
|
||||
char *rsm_nchar_replace(char *replaced, int replaced_len, char *search, char *find, char *replace)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
char *fp = find;
|
||||
char *rp = replace;
|
||||
|
||||
len = strlen(search);
|
||||
|
||||
if (replaced_len > 0)
|
||||
len = AQ_MIN(len, replaced_len);
|
||||
|
||||
for(i = 0; i < len; i++){
|
||||
if (search[i] == *fp)
|
||||
replaced[i] = *rp;
|
||||
else
|
||||
replaced[i] = search[i];
|
||||
}
|
||||
replaced[i] = '\0';
|
||||
|
||||
return replaced;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ float rsm_atof(const char* str);
|
|||
char *rsm_strncpycut(char *dest, const char *src, int dest_len, int src_len);
|
||||
//char *rsm_char_replace(char *replaced , char *search, const char find, const char replace);
|
||||
char *rsm_char_replace(char *replaced , char *search, char *find, char *replace);
|
||||
char *rsm_nchar_replace(char *replaced, int replaced_len, char *search, char *find, char *replace);
|
||||
int rsm_HHMM2min(char *message);
|
||||
|
||||
#endif //RS_MSG_UTILS_H_
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "sensors.h"
|
||||
#include "aqualink.h"
|
||||
|
||||
|
||||
/*
|
||||
read sensor value from ie /sys/class/thermal/thermal_zone0/temp
|
||||
|
||||
return true if current reading is different to last value stored
|
||||
*/
|
||||
|
||||
bool read_sensor(external_sensor *sensor) {
|
||||
|
||||
FILE *fp;
|
||||
float value;
|
||||
|
||||
fp = fopen(sensor->path, "r");
|
||||
if (fp == NULL) {
|
||||
LOGSystemError(errno, AQUA_LOG, sensor->path);
|
||||
LOG(AQUA_LOG,LOG_ERR, "Reading sensor %s %s\n",sensor->label, sensor->path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fscanf(fp, "%f", &value);
|
||||
fclose(fp);
|
||||
|
||||
// Convert usually from millidegrees Celsius to degrees Celsius
|
||||
//printf("Factor = %f - value %f\n",sensor->factor, value);
|
||||
//printf("Read Sensor value %f %.2f\n",value,value * sensor->factor);
|
||||
value = value * sensor->factor;
|
||||
//printf("Converted value %f\n",value);
|
||||
LOG(AQUA_LOG,LOG_DEBUG, "Read sensor %s value=%.2f\n",sensor->label, value);
|
||||
|
||||
if (sensor->value != value) {
|
||||
sensor->value = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef SENSORS_H_
|
||||
#define SENSORS_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct external_sensor{
|
||||
char *path;
|
||||
float factor;
|
||||
char *label;
|
||||
float value;
|
||||
} external_sensor;
|
||||
|
||||
bool read_sensor(external_sensor *sensor);
|
||||
|
||||
#endif
|
|
@ -286,6 +286,31 @@ const char* loglevel2name(int level)
|
|||
return elevel2text(level);
|
||||
}
|
||||
|
||||
const char* loglevel2cgn_name(int level)
|
||||
{
|
||||
switch(level) {
|
||||
case LOG_ERR:
|
||||
return "ERROR";
|
||||
break;
|
||||
case LOG_WARNING:
|
||||
return "WARNING";
|
||||
break;
|
||||
case LOG_NOTICE:
|
||||
return "NOTICE";
|
||||
break;
|
||||
case LOG_INFO:
|
||||
return "INFO";
|
||||
break;
|
||||
case LOG_DEBUG_SERIAL:
|
||||
return "DEBUG_SERIAL";
|
||||
break;
|
||||
case LOG_DEBUG:
|
||||
default:
|
||||
return "DEBUG";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char* logmask2name(logmask_t from)
|
||||
{
|
||||
switch (from) {
|
||||
|
|
|
@ -92,6 +92,7 @@ void clearDebugLogMask();
|
|||
bool isDebugLogMaskSet(logmask_t flag);
|
||||
const char* logmask2name(logmask_t mask);
|
||||
const char* loglevel2name(int level);
|
||||
const char* loglevel2cgn_name(int level);
|
||||
//#define logMessage(msg_level, format, ...) LOG (1, msg_level, format, ##__VA_ARGS__)
|
||||
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
#define AQUALINKD_SHORT_NAME "AqualinkD"
|
||||
|
||||
// Use Magor . Minor . Patch
|
||||
#define AQUALINKD_VERSION "2.5.1"
|
||||
#define AQUALINKD_VERSION "2.5.2 (dev)"
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
<meta name='apple-mobile-web-app-status-bar-style' content='black'>
|
||||
<link href="aqualinkd.png" rel="apple-touch-icon">
|
||||
<link href="aqualinkd.png" rel="icon">
|
||||
<script type="text/javascript" src="confighelp.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--max-config-height: 870px;
|
||||
}
|
||||
html {}
|
||||
|
||||
body {
|
||||
|
@ -53,6 +57,19 @@
|
|||
/*overflow-y: scroll; this only works if we know the height, we can caculate but not important at moment */
|
||||
}
|
||||
|
||||
.configpopup {
|
||||
top: 10px;
|
||||
/*left: 10px;*/
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100vw;
|
||||
/*
|
||||
height: 100%;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
.loglevelstitle {
|
||||
background-color: rgb(221, 221, 221);
|
||||
|
@ -239,6 +256,49 @@
|
|||
background-color: #f1f1f1;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* FOR CONFIG PUPUP */
|
||||
|
||||
.config_options {
|
||||
top: 10px;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100vw;
|
||||
|
||||
/*height: 100vw;*/
|
||||
}
|
||||
.config_options_pane {
|
||||
background-color: var(--options_pane_background);
|
||||
border: 2px solid var(--options_pane_bordercolor);
|
||||
border-radius: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 700px;
|
||||
/*max-height: 870px;*/
|
||||
max-height: var(--max-config-height);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.config_options_added {
|
||||
background-color: white;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0.0;
|
||||
}
|
||||
/*
|
||||
.helptxt {
|
||||
font-size: x-small;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
tr{
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
*/
|
||||
</style>
|
||||
|
||||
<script type='text/javascript'>
|
||||
|
@ -413,7 +473,7 @@
|
|||
}
|
||||
|
||||
function downloadFile(filePath, lines) {
|
||||
console.log("Lines=" + lines);
|
||||
//console.log("Lines=" + lines);
|
||||
|
||||
var link = document.createElement('a');
|
||||
link.href = filePath + "/" + lines;
|
||||
|
@ -460,7 +520,283 @@
|
|||
} catch (Error) { }
|
||||
}
|
||||
|
||||
var _config = {};
|
||||
|
||||
function editconfig(caller) {
|
||||
var msg = {
|
||||
uri: "config"
|
||||
};
|
||||
send_command(msg);
|
||||
}
|
||||
|
||||
function saveconfig(caller) {
|
||||
|
||||
var json = {
|
||||
uri: "config/set"
|
||||
};
|
||||
|
||||
var values = {}
|
||||
for (var obj in _config) {
|
||||
if (_config[obj].value !== undefined) {
|
||||
//json.values.push('"'+obj+'" : "'+_config[obj].value+'"' );
|
||||
//json.values.push(obj : _config[obj].value );
|
||||
values[obj] = _config[obj].value;
|
||||
}
|
||||
}
|
||||
json["values"] = values;
|
||||
|
||||
//console.log (JSON.stringify(json));
|
||||
|
||||
send_command(json);
|
||||
closeconfig();
|
||||
}
|
||||
|
||||
function closeconfig() {
|
||||
const configtable = document.getElementById("config_table");
|
||||
while (configtable.rows.length > 1) {
|
||||
configtable.deleteRow(1); // Delete the first data row (index 1)
|
||||
}
|
||||
|
||||
document.getElementById("config_options").classList.add("hide");
|
||||
document.getElementById("config_options_pane").classList.add("hide");
|
||||
}
|
||||
|
||||
function showConfig(data) {
|
||||
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
//console.log("Height="+h);
|
||||
document.documentElement.style.setProperty('--max-config-height', (h-30)+'px');
|
||||
|
||||
document.getElementById("config_options").classList.remove("hide");
|
||||
document.getElementById("config_options_pane").classList.remove("hide");
|
||||
const configtable = document.getElementById("config_table");
|
||||
//console.log (data);
|
||||
_config = data;
|
||||
var lastBtnNum = 1; // Use 1 so only hits if on button_02
|
||||
var vBtnCnt = 0;
|
||||
|
||||
for (var obj in data) {
|
||||
var isBtn = false;
|
||||
if (_confighelp[obj.toString()] !== undefined) {
|
||||
//console.log("FOUND HELP");
|
||||
//console.log(_confighelp[obj.toString()]);
|
||||
const newRow = configtable.insertRow();
|
||||
const cell1 = newRow.insertCell();
|
||||
cell1.colSpan = 3;
|
||||
cell1.style.fontSize = "small";
|
||||
cell1.textContent=_confighelp[obj.toString()];
|
||||
}
|
||||
|
||||
if (obj.toString().includes("button")) {
|
||||
isBtn = true;
|
||||
const num = parseInt(obj.toString().match(/[0-9]+/));
|
||||
//console.log("lastnum="+lastBtnNum+" num="+num);
|
||||
if (num && num != lastBtnNum) {
|
||||
const newRow = configtable.insertRow();
|
||||
newRow.style.borderBottom = "1px solid black";
|
||||
/*
|
||||
const cell1 = newRow.insertCell();
|
||||
const cell2 = newRow.insertCell();
|
||||
const cell3 = newRow.insertCell();
|
||||
//cell1.colSpan = 3;
|
||||
cell1.style.fontSize = "small";
|
||||
if (obj.toString().includes("virtual")) {
|
||||
vBtnCnt++;
|
||||
}
|
||||
if (vBtnCnt > 1) {
|
||||
cell1.textContent = "Add Virtual Button";
|
||||
} else {
|
||||
cell1.style.paddingLeft = "20px";
|
||||
cell1.textContent = "Add Button_"+lastBtnNum+"_??????";
|
||||
cell2.innerHTML = '<select key="button_'+lastBtnNum+'_ADD"><option value="" selected="true"></option><option value="pumpIndex">pumpIndex</option><option value="pumpID">pumpID</option><option value="pumpType">pumpType</option><option value="pumpName">pumpName</option><option value="lightMode">lightMode</option></select>';
|
||||
cell2.addEventListener('change', cfgButtonAdd);
|
||||
}*/
|
||||
lastBtnNum = num;
|
||||
}
|
||||
}
|
||||
|
||||
if (data[obj].value !== undefined) {
|
||||
//console.log(obj.toString() + " = " + data[obj].value);
|
||||
const newRow = configtable.insertRow();
|
||||
if (! isBtn) {
|
||||
newRow.style.borderBottom = "1px solid black";
|
||||
}
|
||||
const cell1 = newRow.insertCell();
|
||||
const cell2 = newRow.insertCell();
|
||||
const cell3 = newRow.insertCell();
|
||||
cell1.textContent = obj.toString();
|
||||
cell1.style.paddingLeft = "20px";
|
||||
cell3.textContent = " ";
|
||||
if (data[obj]["valid values"] !== undefined) {
|
||||
//console.log(data[obj]["valid values"]);
|
||||
const input = document.createElement("select");
|
||||
array = data[obj]["valid values"];
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var option = document.createElement("option");
|
||||
option.value = array[i];
|
||||
option.text = array[i];
|
||||
if (array[i] == data[obj].value) {
|
||||
option.selected = true;
|
||||
}
|
||||
input.setAttribute('key', obj.toString());
|
||||
input.addEventListener('change', cfgValueChanged);
|
||||
input.appendChild(option);
|
||||
}
|
||||
cell2.appendChild(input);
|
||||
} else if (data[obj].type == "string") {
|
||||
const input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.value = data[obj].value;
|
||||
input.setAttribute('key', obj.toString());
|
||||
input.addEventListener('change', cfgValueChanged);
|
||||
cell2.appendChild(input);
|
||||
} else if (data[obj].type == "int") {
|
||||
const input = document.createElement("input");
|
||||
input.type = "number";
|
||||
input.value = data[obj].value;
|
||||
input.size = 4;
|
||||
input.setAttribute('key', obj.toString());
|
||||
input.addEventListener('change', cfgValueChanged);
|
||||
cell2.appendChild(input);
|
||||
} else if (data[obj].type == "hex") {
|
||||
const input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.value = data[obj].value;
|
||||
input.size = 4;
|
||||
input.setAttribute('key', obj.toString());
|
||||
input.addEventListener('change', cfgValueChanged);
|
||||
cell2.appendChild(input);
|
||||
} else if (data[obj].type == "float") {
|
||||
console.log("NEED TO IMPLIMENT float about line 669");
|
||||
cell2.textContent = data[obj].value;
|
||||
} else {
|
||||
cell2.textContent = data[obj].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
//var jsonString= JSON.stringify(_config);
|
||||
//console.log (jsonString);
|
||||
|
||||
var newRow = configtable.insertRow();
|
||||
newRow.style.borderTop = "1px solid black";
|
||||
var cell1 = newRow.insertCell();
|
||||
cell1.colSpan = 3;
|
||||
cell1.textContent = "Add Button or Virtual Button";
|
||||
|
||||
newRow = configtable.insertRow();
|
||||
newRow.style.borderBottom = "1px solid black";
|
||||
cell1 = newRow.insertCell();
|
||||
var cell2 = newRow.insertCell();
|
||||
var cell3 = newRow.insertCell();
|
||||
|
||||
cell1.innerHTML = '<select id="button_type_ADD"><option value="" selected="true"></option><option value="button">button</option><option value="virtual_button">virtual button</option></select> \
|
||||
<input disabled id="button_number_ADD" type="number" min="1" max="30" size="2"></input> \
|
||||
<select disabled id="button_option_ADD"><option value="" selected="true">';
|
||||
cell1.addEventListener('change', cfgEnbleButtonOptions);
|
||||
//cell2.innerHTML = '<input disabled id="button_value_ADD">';
|
||||
cell2.innerHTML = '<div id="button_valuetype_ADD"></div>';
|
||||
cell2.addEventListener('change', cfgEnbleButtonOptions);
|
||||
cell3.innerHTML = '<input id="addButton" type="submit" value="Add" onClick="cfgButtonAdd()"></input>';
|
||||
//cell3.addEventListener('change', cfgEnbleButtonOptions);
|
||||
disablebutton("addButton");
|
||||
}
|
||||
|
||||
function cfgEnbleButtonOptions(event) {
|
||||
btnType = document.getElementById("button_type_ADD");
|
||||
btnNum = document.getElementById("button_number_ADD");
|
||||
btnOption = document.getElementById("button_option_ADD");
|
||||
btnValueType = document.getElementById("button_valuetype_ADD");
|
||||
|
||||
if (event.srcElement.id == "button_type_ADD"){
|
||||
btnNum.disabled = false;
|
||||
if (event.srcElement.value == "button") {
|
||||
btnNum.max=20;
|
||||
btnOption.innerHTML = '<option value="" selected="true"></option><option value="pumpIndex">pumpIndex</option><option value="pumpID">pumpID</option><option value="pumpType">pumpType</option><option value="pumpName">pumpName</option><option value="lightMode">lightMode</option>';
|
||||
} else if (event.srcElement.value == "virtual_button") {
|
||||
btnNum.max=10;
|
||||
btnOption.innerHTML = '<option value="" selected="true"></option><option value="pumpIndex">pumpIndex</option><option value="pumpID">pumpID</option><option value="pumpType">pumpType</option><option value="pumpName">pumpName</option><option value="onetouchID">onetouchID</option>';
|
||||
}
|
||||
} else if (event.srcElement.id == "button_number_ADD"){
|
||||
btnOption.disabled = false;
|
||||
} else if (event.srcElement.id == "button_option_ADD"){
|
||||
//btnValue.disabled = false;
|
||||
//console.log(event.srcElement.value);
|
||||
switch(event.srcElement.value) {
|
||||
case "pumpIndex":
|
||||
//btnValueType.innerHTML = '<select id="button_value_ADD"><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option></select>';
|
||||
btnValueType.innerHTML = '<input id="button_value_ADD" type="number" min="1" max="4" size="1"></input>';
|
||||
break;
|
||||
case "pumpID":
|
||||
btnValueType.innerHTML = '<input id="button_value_ADD" type="text" size="4" value="0x60"></imput>';
|
||||
break;
|
||||
case "pumpType":
|
||||
btnValueType.innerHTML = '<select id="button_value_ADD"><option value="JANDY ePUMP">JANDY ePUMP</option><option value="Pentair VS">Pentair VS</option><option value="Pentair VF">Pentair VF</option></select>';
|
||||
break;
|
||||
case "pumpName":
|
||||
btnValueType.innerHTML = '<input id="button_value_ADD" type="text"></imput>';
|
||||
break;
|
||||
case "lightMode":
|
||||
btnValueType.innerHTML = '<input id="button_value_ADD" type="number" min="1" max="11" size="2"></input>';
|
||||
break;
|
||||
case "onetouchID":
|
||||
btnValueType.innerHTML = '<input id="button_value_ADD" type="number" min="1" max="6" size="2"></input>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get this here since the previous statment can change it.
|
||||
btnValue = document.getElementById("button_value_ADD");
|
||||
|
||||
if (btnType.value != "" && btnNum.value != "" && btnOption.value != "" && btnValue && btnValue.value != "") {
|
||||
enablebutton("addButton");
|
||||
} else {
|
||||
disablebutton("addButton");
|
||||
}
|
||||
}
|
||||
|
||||
function cfgValueChanged(event) {
|
||||
//console.log("Config set "+event.srcElement.getAttribute('key')+" to "+event.srcElement.value)
|
||||
_config[event.srcElement.getAttribute('key')].value = event.srcElement.value;
|
||||
}
|
||||
|
||||
function cfgButtonAdd(){
|
||||
//console.log(document.getElementById("button_type_ADD").value);
|
||||
//console.log(document.getElementById("button_number_ADD").value);
|
||||
//console.log(document.getElementById("button_option_ADD").value);
|
||||
//console.log(document.getElementById("button_value_ADD").value);
|
||||
|
||||
var button = document.getElementById("button_type_ADD").value + "_" + ("0" + document.getElementById("button_number_ADD").value).slice (-2);
|
||||
var buttonName = button+"_"+document.getElementById("button_option_ADD").value;
|
||||
var buttonValue = document.getElementById("button_value_ADD").value;
|
||||
//console.log("Looking for "+button);
|
||||
const configtable = document.getElementById("config_table");
|
||||
var found=false;
|
||||
for (let i = 0; i < configtable.rows.length; i++) {
|
||||
try{
|
||||
if ( configtable.rows[i].cells[0].childNodes[0].nodeValue.includes(button) ) {
|
||||
//console.log("**** FOUND *****");
|
||||
found=true;
|
||||
} else if (found == true) {
|
||||
//console.log("** ADD HERE **");
|
||||
const newRow = configtable.insertRow(i);
|
||||
newRow.classList.add("config_options_added");
|
||||
var cell1 = newRow.insertCell();
|
||||
var cell2 = newRow.insertCell();
|
||||
var cell3 = newRow.insertCell();
|
||||
newRow.style.borderBottom = "1px solid black";
|
||||
cell1.style.paddingLeft = "20px";
|
||||
cell1.innerHTML = buttonName;
|
||||
cell2.innerHTML = buttonValue;
|
||||
//cell3.innerHTML = '<input id="addButton" type="submit" value="Delete" onClick="cfgButtonDelete()"></input>';
|
||||
var js = {};
|
||||
js.value = buttonValue
|
||||
_config[buttonName] = js;
|
||||
//console.log(_config);
|
||||
break;
|
||||
}
|
||||
//console.log(configtable.rows[i].cells[0].childNodes[0].nodeValue);
|
||||
} catch (e){}
|
||||
}
|
||||
}
|
||||
|
||||
function update_status(data) {
|
||||
/*
|
||||
|
@ -519,6 +855,11 @@
|
|||
//console.log("deamonized=" + data['deamonized'] + " Need to rename Restart to Reload");
|
||||
disablebutton("restart");
|
||||
}
|
||||
if (data['config_editor'] == 'yes') {
|
||||
enablebutton("editconfig");
|
||||
} else {
|
||||
disablebutton("editconfig");
|
||||
}
|
||||
|
||||
/*
|
||||
if (data['logfilename'] == "(null)")
|
||||
|
@ -577,7 +918,7 @@
|
|||
var filterentry = document.getElementById("rssd_filter");
|
||||
filterentry.value = "";
|
||||
for (var id in data['debugmasks'][obj].filters) {
|
||||
console.log("Filter "+data['debugmasks'][obj].filters[id]);
|
||||
//console.log("Filter "+data['debugmasks'][obj].filters[id]);
|
||||
if (data['debugmasks'][obj].filters[id] != "0x00") {
|
||||
if (filterentry.value.length == 0) {
|
||||
filterentry.value = data['debugmasks'][obj].filters[id];
|
||||
|
@ -651,6 +992,8 @@
|
|||
update_status(data);
|
||||
} else if (data.type == 'aux_labels') {
|
||||
//set_labels(data);
|
||||
} else if (data.type == 'config') {
|
||||
showConfig(data);
|
||||
}
|
||||
}
|
||||
socket_di.onclose = function () {
|
||||
|
@ -669,7 +1012,7 @@
|
|||
}
|
||||
|
||||
function send_command(cmd) {
|
||||
console.log("Send " + JSON.stringify(cmd));
|
||||
//console.log("Send " + JSON.stringify(cmd));
|
||||
socket_di.send(JSON.stringify(cmd));
|
||||
|
||||
}
|
||||
|
@ -786,6 +1129,7 @@
|
|||
|
||||
<body onload="init();init_collapsible();">
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="aqualinkd">
|
||||
<iframe id="aqd" src="/" width="100%" height="350px"></iframe>
|
||||
</div>
|
||||
|
@ -889,8 +1233,14 @@
|
|||
</div>
|
||||
<button class="collapsible">Config</button>
|
||||
<div class="content" id="config">
|
||||
<!-- Will be populated on load -->
|
||||
<label>Not Implimented</label>
|
||||
<table border='0'>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<input id="editconfig" type="button" onclick="editconfig(this);"
|
||||
value="edit config"></input>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -900,6 +1250,34 @@
|
|||
<!--<div class="inner">END</div>-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div id="config_options" class="config_options hide" style="display: flex;" onclick="closeconfig();"> -->
|
||||
<div id="config_options" class="config_options hide" style="display: flex;">
|
||||
<div id="config_options_pane" class="config_options_pane hide">
|
||||
<table id="config_table" border="0" cellpadding="1px" width="100%" style="border-collapse: collapse;">
|
||||
<tbody><tr class="options_title">
|
||||
<th colspan="3"><span>AqualinkD Configuration</span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="50%">
|
||||
Key
|
||||
</td>
|
||||
<td align="left" width="50%">
|
||||
Value
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table border="0" cellpadding="0px" width="100%"><tr>
|
||||
<td align="right" style="width:50%;padding-right: 10px;">
|
||||
<input id="saveconfig" type="button" onclick="saveconfig(this);" value="Save Config"></input>
|
||||
</td>
|
||||
<td align="left" style="width:50%;padding-left: 10px;">
|
||||
<input id="saveconfig" type="button" onclick="closeconfig(this);" value="Close (without saving)"></input>
|
||||
</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
</div>
|
||||
<!--<iframe src='about:blank' id="logdownload"></iframe>-->
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
let _confighelp = {};
|
||||
_confighelp["panel_type"]="Your RS panel type & size. ie 4, 6, 8, 12 or 16 relates to RS4, RS6, RS8, RS12 or RS16. Must be in format XX-N ???? (XX=RS or PD, N=Circuits, ????=Combo or Only or Dual)";
|
||||
_confighelp["device_id"]="The id of the AqualinkD to use. Valid RS ID's are 0x0a 0x0b 0x09 0x08. If your panel is a PDA only model then PDA device ID is 0x60. This HAS to be an ID that's not currently used by another device (like keypad), run serial_logger if unsure";
|
|
@ -2513,6 +2513,7 @@
|
|||
}
|
||||
function set_schedules(msg) {
|
||||
msg.uri = "schedules/set";
|
||||
//console.log(JSON.stringify(msg));
|
||||
socket_di.send(JSON.stringify(msg));
|
||||
//socket_di.send(msg);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue