mirror of https://github.com/sfeakes/AqualinkD.git
parent
ac23a76d29
commit
95161f76ac
24
README.md
24
README.md
|
|
@ -10,6 +10,8 @@ Binaries are supplied for Raspberry Pi both 32 & 64 bit OS, Has been, and can be
|
|||
If you like this project, you can buy me a cup of coffee :)
|
||||
<br>
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SEGN9UNS38TXJ)
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
## AqualinkD new home
|
||||
|
|
@ -79,7 +81,7 @@ Designed to mimic AqualinkRS devices, used to fully configure the master control
|
|||
|
||||
## All Web interfaces.
|
||||
* http://aqualink.ip/ <- (Standard WEB UI
|
||||
* http://aqualink.ip/simple.html <- (Simple opion if you don't like the above)
|
||||
<!--* http://aqualink.ip/simple.html <- (Simple opion if you don't like the above)-->
|
||||
* http://aqualink.ip/simulator.html <- (Displays all simulators in one page with tabs)
|
||||
* http://aqualink.ip/aqmanager.html <- (Manage AqualinkD configuration & runtime)
|
||||
* http://aqualink.ip/allbutton_sim.html <- (All Button Simulator)
|
||||
|
|
@ -136,6 +138,20 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* Use set_allbutton_light_dimmer for all lights (ie color lights)
|
||||
|
||||
-->
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
# <span style="color: red;">Notice</span>
|
||||
|
||||
AqualinkD will soon be dropping support for OS's older than debian bullseye. (GLIBC 2.31 will be minimum).
|
||||
|
||||
AqualinkD will be moving over to github hosted runners for compiling, currently AqualinkD is using self hosted. This means supporting old OS releases like Stretch is not worth it. AqualinkD will still be tested and support local compiling on old OS's, just the binaries in the release packages will be for bullseye and newer
|
||||
<hr>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
# Updates in 3.0.0 (dev)
|
||||
* WARNING V3.0 has undergone a significant amount code changes and refactoring, there may be issues.
|
||||
* Serial optimization for AqualinkD HAT.
|
||||
|
|
@ -143,7 +159,9 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* web/config.js is now web/config.json any custom settings will need to be migrated.
|
||||
* Added example plugin of how to get HomeAssistant devices to show up in AqualinkD UI.
|
||||
* upgraded network library ( HTTP(S), MQTT(S), WS )
|
||||
* Added support for HTTPS and MQTTS
|
||||
* Added support for HTTPS and MQTTS.
|
||||
* HTTPS is for two way auth only, ie You create your own cert and load on both AqualinkD server and all client devices.
|
||||
* Example script to generate HTTPS certificates is in (./extras/generate-certs.sh)
|
||||
* Optimized updates to MQTT, web sockets & WebUI (only update when absolutely necessary)
|
||||
* Added options to force upgrades in aqmanager. (add ?upgrade or ?devupgrade to url to enable upgrade button)
|
||||
* MQTT Discovery for all supporting hubs (HomeAssistant Domoticz Hubitat OpenHAB etc)
|
||||
|
|
@ -156,12 +174,12 @@ NEED TO FIX FOR THIS RELEASE.
|
|||
* Changed caching of HTTP server. (Better for UI config updates)
|
||||
* Autoconfigure will now get panel size/type for panels that support PC-Dock interface.
|
||||
* Autoconfigure will *try* to work for PDA panels.
|
||||
* Added example script to generate HTTPS certificates. (./extras/generate-certs.sh)
|
||||
* Cleaned up exit & errors when running as daemon and docker.
|
||||
* Fixed issues with external sensors and homekit.
|
||||
* Added preliminary support for Jandy Infinite water color lights
|
||||
- Need to finish off :-
|
||||
* HAT serial optimizations broke some USB serial adapters
|
||||
* SWG not auto finding
|
||||
|
||||
|
||||
# Updates in 2.6.11 (Sept 14 2025)
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -34,7 +34,7 @@ _logfile=""
|
|||
_frommake=$FALSE
|
||||
_ignorearch=$FALSE
|
||||
_nosystemd=$FALSE
|
||||
_ignoreglibc=$TRUE
|
||||
_ignoreglibc=$FALSE
|
||||
|
||||
log()
|
||||
{
|
||||
|
|
@ -250,7 +250,9 @@ fi
|
|||
|
||||
# V3.0.0 uses config.json not config.js
|
||||
if [ -f "$WEBLocation/config.js" ]; then
|
||||
log "AqualinkD web config is old, please migrate and settings from $WEBLocation/config.js to $WEBLocation/config.json"
|
||||
if [ ! -f "$WEBLocation/config.json" ]; then
|
||||
log "AqualinkD web config is old, please migrate and settings from $WEBLocation/config.js to $WEBLocation/config.json"
|
||||
fi
|
||||
fi
|
||||
# V2.3.9 & V2.6.0 has kind-a breaking change for config.js, so check existing and rename if needed
|
||||
# we added Aux_V? to the button list
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -256,7 +256,10 @@ void _processMessage(char *message, struct aqualinkdata *aqdata, bool reset)
|
|||
aqdata->service_mode_state = OFF; // IF we get this message then Service / Timeout is off
|
||||
}
|
||||
|
||||
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) && aqdata->swg_led_state != LED_S_UNKNOWN) {
|
||||
// Removed aqdata->swg_led_state check from below if, so SWG can be found if read_SWG_rs584 is off.
|
||||
// May want to add options like (isIAQT_ENABLED == false && isONET_ENABLED == false && READ_RSDEV_SWG == false )
|
||||
// Then remove the aqdata->swg_led_state check
|
||||
if ( ((msg_loop & MSG_SWG_DEVICE) != MSG_SWG_DEVICE) /*&& aqdata->swg_led_state != LED_S_UNKNOWN*/) {
|
||||
// No Additional SWG devices messages like "no flow"
|
||||
if ((msg_loop & MSG_SWG) != MSG_SWG && aqdata->aqbuttons[PUMP_INDEX].led->state == OFF )
|
||||
setSWGdeviceStatus(aqdata, ALLBUTTON, SWG_STATUS_OFF);
|
||||
|
|
|
|||
|
|
@ -185,10 +185,10 @@ const char* get_jandy_packet_type(const unsigned char* packet , int length)
|
|||
return "GetID";
|
||||
break;
|
||||
case CMD_PERCENT:
|
||||
return "AR %%";
|
||||
return "SWG %%";
|
||||
break;
|
||||
case CMD_PPM:
|
||||
return "AR PPM";
|
||||
return "SWG PPM";
|
||||
break;
|
||||
case CMD_PDA_0x05:
|
||||
return "PDA Unknown";
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ FILE *aq_open_file(char *filename, bool *ro_root, bool *created_file)
|
|||
remount_root_ro(*ro_root);
|
||||
}
|
||||
|
||||
LOG(AQUA_LOG, LOG_INFO, "Open file %s for writing\n",filename);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +139,8 @@ bool copy_file(const char *source_path, const char *destination_path)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool run_aqualinkd_upgrade(uint8_t type)
|
||||
//bool run_aqualinkd_upgrade(uint8_t type)
|
||||
bool run_aqualinkd_upgrade(char *version)
|
||||
{
|
||||
int pipe_curl_to_bash[2];
|
||||
pid_t pid_curl, pid_bash;
|
||||
|
|
@ -146,12 +149,18 @@ bool run_aqualinkd_upgrade(uint8_t type)
|
|||
char *bash_args[] = {"bash", "-s", "--", "", NULL};
|
||||
int status_curl, status_bash;
|
||||
|
||||
/*
|
||||
if (isMASK_SET(type, CHECKONLY)) {
|
||||
bash_args[3] = "check";
|
||||
} else {
|
||||
|
||||
if (isMASK_SET(type, INSTALLDEVRELEASE)) {
|
||||
bash_args[3] = "development";
|
||||
}
|
||||
}*/
|
||||
|
||||
if (version != NULL) {
|
||||
bash_args[3] = version;
|
||||
}
|
||||
|
||||
if (pipe(pipe_curl_to_bash) == -1)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
FILE *aq_open_file( char *filename, bool *ro_root, bool* created_file);
|
||||
bool aq_close_file(FILE *file, bool ro_root);
|
||||
bool copy_file(const char *source_path, const char *destination_path);
|
||||
bool run_aqualinkd_upgrade(uint8_t type);
|
||||
//bool run_aqualinkd_upgrade(uint8_t type);
|
||||
bool run_aqualinkd_upgrade(char *version);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -249,11 +249,11 @@ typedef enum panel_vsp_status
|
|||
#define ERROR_SERIAL ( 1 << 9 )
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#define INSTALLDEVRELEASE ( 1 << 0 )
|
||||
#define UPDATERELEASE ( 1 << 1 )
|
||||
#define CHECKONLY ( 1 << 3 )
|
||||
|
||||
*/
|
||||
typedef struct pumpd
|
||||
{
|
||||
int rpm;
|
||||
|
|
@ -437,6 +437,7 @@ struct aqualinkdata
|
|||
//char version[AQ_MSGLEN*2]; // Will be replaced by below in future
|
||||
//char revision[AQ_MSGLEN]; // Will be replaced by below in future
|
||||
uint8_t updatetype;
|
||||
char *upgrade_version;
|
||||
// The below 4 are set (sometimes) but not used yet
|
||||
char panel_rev[AQ_MSGLEN]; // From panel
|
||||
char panel_cpu[AQ_MSGLEN]; // From panel
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ bool isAqualinkDStopping() {
|
|||
void intHandler(int sig_num)
|
||||
{
|
||||
if (sig_num == SIGRUPGRADE) {
|
||||
if (! run_aqualinkd_upgrade(_aqualink_data.updatetype)) {
|
||||
if (! run_aqualinkd_upgrade(_aqualink_data.upgrade_version)) {
|
||||
LOG(AQUA_LOG,LOG_ERR, "AqualinkD upgrade failed!\n");
|
||||
}
|
||||
return; // Let the upgrade process terminate us.
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ bool processPacketFromSWG(unsigned char *packet, int packet_length, struct aqual
|
|||
changedAnything = true;
|
||||
SET_DIRTY(aqdata->is_dirty);
|
||||
}
|
||||
// logMessage(LOG_DEBUG, "Read SWG PPM %d from ID 0x%02hhx\n", aqdata.swg_ppm, SWG_DEV_ID);
|
||||
// LOG(LOG_DEBUG, "Read SWG PPM %d from ID 0x%02hhx\n", aqdata.swg_ppm, SWG_DEV_ID);
|
||||
}
|
||||
|
||||
return changedAnything;
|
||||
|
|
@ -334,8 +334,11 @@ void setSWGdeviceStatus(struct aqualinkdata *aqdata, emulation_type requester, u
|
|||
// return;
|
||||
//}
|
||||
|
||||
//LOG(DJAN_LOG, LOG_DEBUG, "Set SWG device state to '0x%02hhx', request from %d\n", aqdata->ar_swg_device_status, requester);
|
||||
|
||||
|
||||
if ((aqdata->ar_swg_device_status == status) || (last_status == status)) {
|
||||
//LOG(DJAN_LOG, LOG_DEBUG, "Set SWG device state to '0x%02hhx', request from %d\n", aqdata->ar_swg_device_status, requester);
|
||||
LOG(DJAN_LOG, LOG_DEBUG, "Set SWG device state to '0x%02hhx', request from %d (no change)\n", aqdata->ar_swg_device_status, requester);
|
||||
return;
|
||||
}
|
||||
last_status = status;
|
||||
|
|
@ -382,7 +385,7 @@ void setSWGdeviceStatus(struct aqualinkdata *aqdata, emulation_type requester, u
|
|||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
//printf("************ Set SWG device state to '0x%02hhx', request from %d, LED state = %d\n", aqdata->ar_swg_device_status, requester, aqdata->swg_led_state);
|
||||
LOG(DJAN_LOG, LOG_DEBUG, "Set SWG device state to '0x%02hhx', request from %d, LED state = %d\n", aqdata->ar_swg_device_status, requester, aqdata->swg_led_state);
|
||||
}
|
||||
|
||||
|
|
@ -457,8 +460,11 @@ void setSWGpercent(struct aqualinkdata *aqdata, int percent) {
|
|||
if (aqdata->swg_led_state == OFF || (aqdata->swg_led_state == ENABLE && ! isSWGDeviceErrorState(aqdata->ar_swg_device_status)) ) // Don't change ENABLE / FLASH
|
||||
SET_IF_CHANGED(aqdata->swg_led_state, ON, aqdata->is_dirty);
|
||||
|
||||
if (aqdata->ar_swg_device_status == SWG_STATUS_UNKNOWN)
|
||||
if (aqdata->ar_swg_device_status == SWG_STATUS_UNKNOWN)
|
||||
SET_IF_CHANGED(aqdata->ar_swg_device_status, SWG_STATUS_ON, aqdata->is_dirty);
|
||||
|
||||
if (aqdata->swg_led_state == LED_S_UNKNOWN)
|
||||
SET_IF_CHANGED(aqdata->swg_led_state, ON, aqdata->is_dirty);
|
||||
|
||||
} if ( aqdata->swg_percent == 0 ) {
|
||||
if (aqdata->swg_led_state == ON)
|
||||
|
|
@ -466,6 +472,10 @@ void setSWGpercent(struct aqualinkdata *aqdata, int percent) {
|
|||
|
||||
if (aqdata->ar_swg_device_status == SWG_STATUS_UNKNOWN)
|
||||
SET_IF_CHANGED(aqdata->ar_swg_device_status, SWG_STATUS_ON, aqdata->is_dirty); // Maybe this should be off
|
||||
|
||||
if (aqdata->swg_led_state == LED_S_UNKNOWN)
|
||||
SET_IF_CHANGED(aqdata->swg_led_state, ENABLE, aqdata->is_dirty);
|
||||
|
||||
}
|
||||
|
||||
LOG(DJAN_LOG, LOG_DEBUG, "Set SWG %% to %d, LED=%d, FullStatus=0x%02hhx\n", aqdata->swg_percent, aqdata->swg_led_state, aqdata->ar_swg_device_status);
|
||||
|
|
|
|||
|
|
@ -656,6 +656,11 @@ int build_aqualink_aqmanager_JSON(struct aqualinkdata *aqdata, char* buffer, int
|
|||
|
||||
length += sprintf(buffer+length, ",\"aqualinkd_version\":\"%s\"",AQUALINKD_VERSION);
|
||||
|
||||
length += sprintf(buffer+length, ",\"panel_type_full\":\"%s\"",getPanelString());
|
||||
length += sprintf(buffer+length, ",\"panel_type\":\"%s\"",getShortPanelString());
|
||||
length += sprintf(buffer+length, ",\"panel_revision\":\"%s %s\"",aqdata->panel_cpu, aqdata->panel_rev );//8157 REV MMM",
|
||||
|
||||
|
||||
|
||||
/*
|
||||
length += sprintf(buffer+length, ",\"panel_type\":\"%s\"",getPanelString());
|
||||
|
|
@ -1204,7 +1209,7 @@ int json_cfg_element(char* buffer, int size, const char *name, const void *value
|
|||
if (isMASKSET(config_mask, CFG_FORCE_RESTART)) {
|
||||
adv_size += sprintf(adv+adv_size,",\"force_restart\": \"yes\"");
|
||||
if ( strcmp(name, CFG_N_panel_type) == 0 ) {
|
||||
adv_size += sprintf(adv+adv_size,",\"force_restart_msg\": \"If you panel_type, you must save and reload config for correct config options to show, and must also restart AqualinkD once finished!\"");
|
||||
adv_size += sprintf(adv+adv_size,",\"force_restart_msg\": \"If you change panel_type, you must save and reload config for correct config options to show!\\nYou must also restart AqualinkD once finished!\"");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1109,7 +1109,19 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
} else if (strncmp(ri1, "restart", 7) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received restart request!\n");
|
||||
raise(SIGRESTART);
|
||||
return uActioned;
|
||||
return uActioned;
|
||||
} else if (strncmp(ri1, "installrelease", 14) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
if (ri2 != NULL) {
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received install release request, %s\n",ri2);
|
||||
_aqualink_data->upgrade_version = malloc( (sizeof(char*) * strlen(ri2)) + 1);
|
||||
snprintf(_aqualink_data->upgrade_version, strlen(ri2)+1, ri2);
|
||||
} else {
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received install release request, but no version named, using latest!\n");
|
||||
_aqualink_data->upgrade_version = "latest";
|
||||
}
|
||||
raise(SIGRUPGRADE);
|
||||
return uActioned;
|
||||
/*
|
||||
} else if (strncmp(ri1, "upgrade", 7) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received upgrade request!\n");
|
||||
setMASK(_aqualink_data->updatetype, UPDATERELEASE);
|
||||
|
|
@ -1120,6 +1132,7 @@ uriAtype action_URI(request_source from, const char *URI, int uri_length, float
|
|||
setMASK(_aqualink_data->updatetype, INSTALLDEVRELEASE);
|
||||
raise(SIGRUPGRADE);
|
||||
return uActioned;
|
||||
*/
|
||||
} else if (strncmp(ri1, "seriallogger", 12) == 0 && from == NET_WS) { // Only valid from websocket.
|
||||
LOG(NET_LOG,LOG_NOTICE, "Received request to run serial_logger!\n");
|
||||
//LOG(NET_LOG,LOG_NOTICE, "Received request ri1=%s, ri2=%s, ri3=%s value=%f\n",ri1,ri2,ri3,value);
|
||||
|
|
@ -1857,6 +1870,7 @@ void action_websocket_request(struct mg_connection *nc, struct mg_ws_message *wm
|
|||
DEBUG_TIMER_STOP(tid, NET_LOG, "action_websocket_request() save_config_js took");
|
||||
ws_send(nc, message);
|
||||
}
|
||||
break;
|
||||
case uSaveWebConfig:
|
||||
{
|
||||
DEBUG_TIMER_START(&tid);
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
#define AQUALINKD_SHORT_NAME "AqualinkD"
|
||||
|
||||
// Use Magor . Minor . Patch
|
||||
#define AQUALINKD_VERSION "3.0.0 (beta 1)"
|
||||
#define AQUALINKD_VERSION "3.0.0 (beta 2)"
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
<style>
|
||||
:root {
|
||||
--max-config-height: 870px;
|
||||
|
||||
--max-config-table-height: 730px;
|
||||
--aqualinkd-scale: 0.75;
|
||||
--aqualinkd-container: 265px;
|
||||
--aqualinkd-iframe: 350px; /* Seems backwards, but the way the iframe scales the iframe need to be the same amount bigger 350*0.75*/
|
||||
|
|
@ -112,11 +112,11 @@
|
|||
background-color: rgb(221, 221, 221);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
th {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
*/
|
||||
#title {
|
||||
background-color: rgb(200, 200, 200);
|
||||
font-weight: 600;
|
||||
|
|
@ -134,7 +134,7 @@
|
|||
text-decoration: none;
|
||||
margin: 2px 2px 2px 2px;
|
||||
min-width: 70px;
|
||||
border-radius: 70px;
|
||||
border-radius: 6px;
|
||||
height: 20px;
|
||||
/*max-width: 120px;*/
|
||||
}
|
||||
|
|
@ -222,7 +222,8 @@
|
|||
|
||||
.toggle-switch {
|
||||
display: inline-block;
|
||||
background: #ccc;
|
||||
/*background: #ccc;*/
|
||||
background: #ebebeb;
|
||||
border-radius: 16px;
|
||||
width: 35px;
|
||||
height: 18px;
|
||||
|
|
@ -238,7 +239,9 @@
|
|||
|
||||
.toggle-switch:before {
|
||||
display: block;
|
||||
background: linear-gradient(to bottom, #fff 0%, #eee 100%);
|
||||
/*background: linear-gradient(to bottom, #fff 0%, #ccc 100%);*/
|
||||
/*background: linear-gradient(to bottom, #fff 0%, #e6e6e6 100%);*/
|
||||
background: linear-gradient(to bottom, #fff 0%, #979696 100%);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
|
||||
width: 15px;
|
||||
|
|
@ -250,8 +253,10 @@
|
|||
}
|
||||
|
||||
.toggle:hover .toggle-switch:before {
|
||||
background: linear-gradient(to bottom, #fff 0%, #fff 100%);
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
|
||||
/*background: linear-gradient(to bottom, #fff 0%, #fff 100%);*/
|
||||
/*background: linear-gradient(to bottom, #979696 0%, #fff 100%);*/
|
||||
background: linear-gradient(to bottom, #e7e7e7 0%, #747373 100%);
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.toggle-checkbox:checked+.toggle-switch {
|
||||
|
|
@ -306,7 +311,8 @@
|
|||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.2s ease-out;
|
||||
background-color: #f1f1f1;
|
||||
/*background-color: #f1f1f1;*/
|
||||
background-color: rgb(211,211,211,211);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
|
@ -322,22 +328,39 @@
|
|||
|
||||
/*height: 100vw;*/
|
||||
}
|
||||
|
||||
.config_pane_scrollable {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: var(--max-config-table-height);
|
||||
resize: vertical;
|
||||
|
||||
}
|
||||
.config_pane_scrollable table {
|
||||
/*background-color: #e7e7e7;*/
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
.config_options_pane {
|
||||
position: relative; /* required for top right close button only */
|
||||
background-color: var(--options_pane_background);
|
||||
border: 2px solid var(--options_pane_bordercolor);
|
||||
border-radius: 20px;
|
||||
border-radius: 10px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 700px;
|
||||
/*max-height: 870px;*/
|
||||
max-height: var(--max-config-height);
|
||||
/*
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow-y: auto;*/
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
/*
|
||||
.config_options_added {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
*/
|
||||
.web_config_options {
|
||||
top: 10px;
|
||||
position: fixed;
|
||||
|
|
@ -347,18 +370,21 @@
|
|||
width: 100vw;
|
||||
/*height: 100vw;*/
|
||||
}
|
||||
/*
|
||||
.web_config_options_pane {
|
||||
position: relative;
|
||||
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;
|
||||
}
|
||||
overflow-y: hidden;
|
||||
}*/
|
||||
.web_config_textarea {
|
||||
width:90%;
|
||||
/*height:700px;*/
|
||||
|
|
@ -388,34 +414,95 @@
|
|||
height: 18px !important;
|
||||
}
|
||||
|
||||
.config_pane_close_button {
|
||||
font-size: 10px !important;
|
||||
font-weight: bold !important;
|
||||
/*color: var(--body_text);*/
|
||||
/*background-color: #7f8385 !important;*/
|
||||
border: none !important;
|
||||
color: rgb(0, 0, 0) !important;
|
||||
padding: 2px 2px !important;
|
||||
text-decoration: none !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
min-width: 18px !important;
|
||||
border-radius: 2px !important;
|
||||
height: 18px !important;
|
||||
|
||||
}
|
||||
|
||||
.config_pane_close_button_contaner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding-top: 5px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.valid_json {
|
||||
background-color: var(--options_pane_background);
|
||||
}
|
||||
.invalid_json {
|
||||
background-color: rgb(255, 100, 0);
|
||||
}
|
||||
|
||||
.textarea-container {
|
||||
display: flex; /* Or display: grid; grid-template-columns: 1fr 1fr; */
|
||||
gap: 0px; /* Optional: adds space between textareas */
|
||||
}
|
||||
.web_config_textarea {
|
||||
width:90%;
|
||||
/*height:700px;*/
|
||||
height:var(--web-config-textarea-height);
|
||||
box-sizing: border-box;
|
||||
/*resize: vertical;*/
|
||||
resize: none;
|
||||
outline: none;
|
||||
font-family: monospace;
|
||||
}
|
||||
.web_config_numbers {
|
||||
width:5%;
|
||||
height:var(--web-config-textarea-height);
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: right;
|
||||
font-family: monospace;
|
||||
}
|
||||
.configTable {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#alertOverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black */
|
||||
z-index: 999;
|
||||
}
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
#alertCustomDialog {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
}
|
||||
#alertCustomDialog {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/*background-color: rgb(240, 240, 240);*/
|
||||
background-color: #2b2b2b;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
border: 1px solid #989898;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -464,7 +551,9 @@
|
|||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function () {
|
||||
this.classList.toggle("active");
|
||||
|
||||
var content = this.nextElementSibling;
|
||||
//console.log(content);
|
||||
if (content.style.maxHeight) {
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
|
|
@ -588,10 +677,10 @@
|
|||
_last_message_element = element;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
function update_status(data) {
|
||||
}
|
||||
|
||||
*/
|
||||
function setloglevel(caller) {
|
||||
//console.log(caller.id);
|
||||
var id = parseInt(caller.id.split('_')[1]);
|
||||
|
|
@ -758,6 +847,7 @@
|
|||
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.documentElement.style.setProperty('--max-config-table-height', (h-140)+'px');
|
||||
|
||||
document.getElementById("config_options").classList.remove("hide");
|
||||
document.getElementById("config_options_pane").classList.remove("hide");
|
||||
|
|
@ -1448,7 +1538,7 @@
|
|||
const newRow = configtable.insertRow();
|
||||
const cell1 = newRow.insertCell();
|
||||
cell1.colSpan = 3;
|
||||
cell1.style.fontSize = "small";
|
||||
cell1.style.fontSize = "x-small";
|
||||
cell1.textContent=_confighelp[obj.toString()];
|
||||
if (! hideLineSeperator) {
|
||||
//newRow.style.borderBottom = "1px solid black";
|
||||
|
|
@ -1536,9 +1626,11 @@
|
|||
if ( _AlertsShown[key] == undefined || _AlertsShown[key] == false) {
|
||||
_AlertsShown[key] = true;
|
||||
if ("force_restart_msg" in _config[key]) {
|
||||
alert(_config[key].force_restart_msg);
|
||||
//alert(_config[key].force_restart_msg);
|
||||
timedAlert(_config[key].force_restart_msg, 0);
|
||||
} else {
|
||||
alert("If you change "+key+" You will need to restart AqualinkD after saving config!");
|
||||
//alert("If you change "+key+" You will need to restart AqualinkD after saving config!");
|
||||
timedAlert("If you change "+key+" You will need to restart AqualinkD after saving config!", 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1589,15 +1681,21 @@
|
|||
disablebutton("upgrade");
|
||||
}
|
||||
}*/
|
||||
//alert(data.type+" r="+data.panel_revision+", t="+data.panel_type);
|
||||
if (data['version']) {
|
||||
document.getElementById("panelversion").innerHTML = data['version'];
|
||||
}
|
||||
else if (data['panel_revision']) {
|
||||
document.getElementById("panelversion").innerHTML = data['panel_revision'];
|
||||
}
|
||||
|
||||
if (data['panel_type']) {
|
||||
document.getElementById("paneltype").innerHTML = data['panel_type'];
|
||||
}
|
||||
if (data['status']) {
|
||||
update_status_message(data['status']);
|
||||
}
|
||||
|
||||
/*
|
||||
if (data['status'] == " ") {
|
||||
document.getElementById("statusmsg").innerHTML = "Connected";
|
||||
|
|
@ -1613,12 +1711,22 @@
|
|||
//console.log("Height="+h);
|
||||
document.documentElement.style.setProperty('--max-config-height', (h-50)+'px');
|
||||
|
||||
document.documentElement.style.setProperty('--web-config-textarea-height', (h-160)+'px');
|
||||
document.documentElement.style.setProperty('--web-config-textarea-height', (h-180)+'px');
|
||||
|
||||
document.getElementById("web_config_options").classList.remove("hide");
|
||||
document.getElementById("web_config_options_pane").classList.remove("hide");
|
||||
|
||||
|
||||
// Link the scroll for the two text areas.
|
||||
const textarea1 = document.getElementById('webconfig-json-input');
|
||||
const textarea2 = document.getElementById('web_config_numbers');
|
||||
textarea1.addEventListener('scroll', () => {
|
||||
textarea2.scrollTop = textarea1.scrollTop;
|
||||
textarea2.scrollLeft = textarea1.scrollLeft;
|
||||
});/* // web_config_numbers doesn't have a scroll bar, so no need.
|
||||
textarea2.addEventListener('scroll', () => {
|
||||
textarea1.scrollTop = textarea2.scrollTop;
|
||||
textarea1.scrollLeft = textarea2.scrollLeft;
|
||||
});*/
|
||||
|
||||
const jsonInput = document.getElementById('webconfig-json-input');
|
||||
|
||||
|
|
@ -1658,8 +1766,8 @@
|
|||
|
||||
function saveWebConfig() {
|
||||
if (!webconfig_validateAndDisplay()) {
|
||||
alert("bad web config, please validate");
|
||||
//timedAlert("bad web config, please validate", 5);
|
||||
//alert("bad web config, please validate");
|
||||
aqdAlert("bad web config, please validate");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1681,7 +1789,6 @@
|
|||
const resultArea = document.getElementById('validation-result');
|
||||
const jsonString = jsonInput.value;
|
||||
|
||||
|
||||
// Clear previous results
|
||||
resultArea.className = '';
|
||||
resultArea.textContent = '';
|
||||
|
|
@ -1693,6 +1800,7 @@
|
|||
// If parsing succeeds, format the JSON nicely (pretty print)
|
||||
const prettyJsonString = JSON.stringify(jsonObject, null, 2);
|
||||
|
||||
addWebConfigLineNumber(prettyJsonString);
|
||||
// Update the text area with the pretty-printed JSON
|
||||
jsonInput.value = prettyJsonString;
|
||||
|
||||
|
|
@ -1703,7 +1811,7 @@
|
|||
return true;
|
||||
} catch (error) {
|
||||
// If parsing fails, catch the error
|
||||
|
||||
addWebConfigLineNumber(jsonString);
|
||||
// Display error message
|
||||
resultArea.classList.add('invalid_json');
|
||||
// The error object provides useful information about where the syntax error is
|
||||
|
|
@ -1712,6 +1820,26 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function countLines(str) {
|
||||
// Split the string by common line break sequences:
|
||||
// \r\n (Windows), \r (old Mac), or \n (Unix/Linux)
|
||||
const lines = str.split(/\r\n|\r|\n/);
|
||||
return lines.length;
|
||||
}
|
||||
|
||||
function addWebConfigLineNumber(str) {
|
||||
const lineNumbers = document.getElementById('web_config_numbers');
|
||||
const total = countLines(str) + 50;
|
||||
|
||||
let numberString = "";
|
||||
|
||||
// Start at line number 2 so the JSON error line numbers match
|
||||
for (let i = 1; i <= total; i++) {
|
||||
numberString += i + "\n";
|
||||
}
|
||||
lineNumbers.value = numberString;
|
||||
}
|
||||
|
||||
async function updateWebConfigFromMaster() {
|
||||
let masterJSON;
|
||||
// Get new master
|
||||
|
|
@ -1995,7 +2123,7 @@
|
|||
update_status_message(data.message);
|
||||
} else if (data.type == 'aqmanager') {
|
||||
setAqManagerOptions(data);
|
||||
//update_status(data);
|
||||
update_status(data);
|
||||
} else if (data.type == 'devices') {
|
||||
//update_device(data);
|
||||
} else if (data.type == 'status') {
|
||||
|
|
@ -2149,6 +2277,12 @@
|
|||
//cmd.uri = "rawcommand"
|
||||
switch (source.id) {
|
||||
case "upgrade":
|
||||
getVersions();
|
||||
aqdAlert("Loading");
|
||||
//let dlg = document.getElementById("alertDialogHeader");
|
||||
//dlg.innerHTML='<input type="list"
|
||||
return;
|
||||
/*
|
||||
if (source.getAttribute("upgrade_type") == "dev") {
|
||||
if (confirm("Are you sure you want to proceed installing AqualinkD to Dev version '"+_latestDevVersionAvailable+"'' ?")) {
|
||||
//console.log("Upgrading to dev release");
|
||||
|
|
@ -2166,8 +2300,15 @@
|
|||
}
|
||||
cmd.uri = "upgrade"
|
||||
}
|
||||
*/
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
break;
|
||||
case "installVersion":
|
||||
let version = document.getElementById("selectedrelease").value;
|
||||
cmd.uri = "installrelease/"+version
|
||||
cmd.value = version;
|
||||
update_log_message("***** AqualinkD upgrade in progress *****");
|
||||
break;
|
||||
case "restart":
|
||||
cmd.uri = "restart"
|
||||
// NEED TO REGET aqmanager after restart.
|
||||
|
|
@ -2209,6 +2350,73 @@
|
|||
send_command(cmd);
|
||||
}
|
||||
|
||||
const VERSION_URL = "https://api.github.com/repos/aqualinkd/AqualinkD/releases"
|
||||
let _aqualinkVersions = {};
|
||||
|
||||
function populateVersionSelection(caller=null) {
|
||||
if (caller && caller.checked)
|
||||
pre = true;
|
||||
else
|
||||
pre = false;
|
||||
|
||||
try {
|
||||
let dlg_head = document.getElementById("alertDialogHeader");
|
||||
let dlg_msg = document.getElementById("alertDialogMessage");
|
||||
|
||||
let dropdown = '<select id="selectedrelease" name="version selection">';
|
||||
//for (const versionNumber of _aqualinkVersions) {
|
||||
for (const [versionNumber, details] of Object.entries(_aqualinkVersions)) {
|
||||
//alert(versionNumber);
|
||||
if (pre || _aqualinkVersions[versionNumber].prerelease === false) {
|
||||
dropdown += '<option value="'+versionNumber+'">'+versionNumber+'</option>';
|
||||
}
|
||||
}
|
||||
dropdown += '</select>';
|
||||
dropdown += ' Include Dev Releases<input type="checkbox" onchange="populateVersionSelection(this)" name="prerelease" value="PreRelease" '+(pre==true?"checked":"")+'/>';
|
||||
dropdown += '<br><input type="button" id="installVersion" onclick="send(this);aqdAlertClose();" value="Install"/>';
|
||||
dlg_head.innerHTML = dropdown;
|
||||
dlg_msg.innerText = "Select a version to install"
|
||||
|
||||
} catch (e){
|
||||
alert("load error "+e);
|
||||
}
|
||||
|
||||
//alert("loaded");
|
||||
}
|
||||
|
||||
async function getVersions() {
|
||||
|
||||
try {
|
||||
// Fetch the file from the specified path (make sure config.json exists)
|
||||
const response = await fetch(VERSION_URL, { cache: 'no-store' });
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Get the response as plain text
|
||||
const versions = await response.text();
|
||||
const versionObject = JSON.parse(versions);
|
||||
|
||||
for (const release of versionObject) {
|
||||
if (!release.assets || release.prerelease == "true" || release.assets.length === 0) {
|
||||
continue;
|
||||
}
|
||||
const downloadUrl = release.assets[0].browser_download_url;
|
||||
if (downloadUrl) {
|
||||
_aqualinkVersions[release.tag_name] = {};
|
||||
_aqualinkVersions[release.tag_name].url = downloadUrl;
|
||||
_aqualinkVersions[release.tag_name].prerelease = release.prerelease;
|
||||
}
|
||||
}
|
||||
|
||||
populateVersionSelection();
|
||||
|
||||
} catch (error) {
|
||||
console.error('There was a problem fetching the config file:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function getLatestVersion(url="https://api.github.com/repos/AqualinkD/AqualinkD/releases/latest", tryagain=true) {
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
|
|
@ -2245,21 +2453,27 @@
|
|||
xmlhttp.setRequestHeader("Accept","application/vnd.github.raw");
|
||||
xmlhttp.send();
|
||||
}
|
||||
/*
|
||||
|
||||
function aqdAlert(message) {
|
||||
document.getElementById("alertDialogHeader").innerText = '';
|
||||
document.getElementById('alertDialogMessage').innerText = message;
|
||||
document.getElementById('alertOverlay').style.display = 'block';
|
||||
document.getElementById('alertCustomDialog').style.display = 'block';
|
||||
}
|
||||
|
||||
function aqdAlertClose() {
|
||||
document.getElementById("alertDialogHeader").innerText = '';
|
||||
document.getElementById('alertOverlay').style.display = 'none';
|
||||
document.getElementById('alertCustomDialog').style.display = 'none';
|
||||
}
|
||||
|
||||
function timedAlert(message, timeout) {
|
||||
document.getElementById('alertDialogMessage').innerText = message;
|
||||
document.getElementById('alertOverlay').style.display = 'block';
|
||||
document.getElementById('alertCustomDialog').style.display = 'block';
|
||||
|
||||
// Set a timeout to automatically close the dialog
|
||||
setTimeout(closeAlert, timeout * 1000);
|
||||
aqdAlert(message);
|
||||
// Set a timeout to automatically close the dialog
|
||||
if (timeout > 0)
|
||||
setTimeout(aqdAlertClose, timeout * 1000);
|
||||
}
|
||||
|
||||
function closeAlert() {
|
||||
document.getElementById('alertOverlay').style.display = 'none';
|
||||
document.getElementById('alertCustomDialog').style.display = 'none';
|
||||
}
|
||||
*/
|
||||
</script>
|
||||
|
||||
<body onload="init();init_collapsible();">
|
||||
|
|
@ -2271,7 +2485,8 @@
|
|||
</div>
|
||||
<div class="inner">
|
||||
<div class="commands">
|
||||
<table border='0' id="deviceList">
|
||||
|
||||
<table border='0' id="deviceList" style="width: 100%;">
|
||||
<tr style="title">
|
||||
<td colspan="2" style="title" align="center"><label id="title"> AqualinkD Managment
|
||||
Console </label></th>
|
||||
|
|
@ -2294,6 +2509,7 @@
|
|||
</tr>
|
||||
-->
|
||||
</table>
|
||||
|
||||
<button class="collapsible" id="systembutton">System Information</button>
|
||||
<div class="content" id="system">
|
||||
<table border='0'>
|
||||
|
|
@ -2401,11 +2617,15 @@
|
|||
</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="xx" class="config_options_pane" >-->
|
||||
<div id="config_options_pane" class="config_options_pane hide">
|
||||
<table id="config_table" border="0" cellpadding="1px" width="100%" style="border-collapse: collapse;">
|
||||
<div class="config_pane_close_button_contaner">
|
||||
<input class="config_pane_close_button" type="button" onclick="closeconfig();" value="x"></input>
|
||||
</div>
|
||||
<table id="config_table_outer" border="0" cellpadding="1px" width="100%" class="configTable">
|
||||
<tbody><tr class="options_title">
|
||||
<th colspan="3"><span>AqualinkD Configuration</span>
|
||||
</th>
|
||||
<th colspan="3"><span>AqualinkD Configuration</span></th>
|
||||
<!--<td><input class="config_option_deletebutton" type="button" onclick="closeconfig(this);" value="x"></input></td>-->
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="3">
|
||||
|
|
@ -2415,38 +2635,55 @@
|
|||
<span class="toggle-label">Show Advanced Options</span>
|
||||
</label>
|
||||
</td>
|
||||
<!--
|
||||
<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>
|
||||
|
||||
<tr colspan="3">
|
||||
<td style="padding-left: 10px; padding-right: 10px">
|
||||
<div class="config_pane_scrollable">
|
||||
<table style="border-left: 1px solid black; border-right: 1px solid black;" id="config_table" border="0" cellpadding="1px" width="100%" class="configTable">
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr colspan="3"><td>
|
||||
|
||||
<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>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--</div>-->
|
||||
</div>
|
||||
|
||||
<div id="web_config_options" class="web_config_options hide" style="display: flex;">
|
||||
<div id="web_config_options_pane" class="web_config_options_pane hide">>
|
||||
<!--<div class="inner">END</div>-->
|
||||
<table id="config_table" border="0" cellpadding="1px" width="100%" style="border-collapse: collapse;">
|
||||
<div id="web_config_options_pane" class="config_options_pane hide">
|
||||
|
||||
<div class="config_pane_close_button_contaner">
|
||||
<input class="config_pane_close_button" type="button" onclick="closeWebConfig();" value="x"></input>
|
||||
</div>
|
||||
|
||||
<!--<table id="config_table" border="0" cellpadding="1px" width="100%" style="border-collapse: collapse;">-->
|
||||
<table id="config_table" border="0" cellpadding="1px" width="100%" class="configTable">
|
||||
<tbody><tr class="options_title">
|
||||
<th colspan="3" style="padding: 10px;"><span>AqualinkD Web Configuration</span></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="3">
|
||||
<textarea class="web_config_textarea" id="webconfig-json-input" placeholder="Loading configuration..."></textarea>
|
||||
<td align="center" colspan="3">
|
||||
<div class="textarea-container">
|
||||
<textarea class="web_config_numbers" id="web_config_numbers" readonly></textarea>
|
||||
<textarea class="web_config_textarea" id="webconfig-json-input" placeholder="Loading configuration..."></textarea>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -2473,13 +2710,17 @@
|
|||
</div>
|
||||
<!--<iframe src='about:blank' id="logdownload"></iframe>-->
|
||||
</div>
|
||||
<!--
|
||||
|
||||
<div id="alertOverlay" style="display: none;"></div>
|
||||
<div id="alertCustomDialog" style="display: none;">
|
||||
<div style="text-align: left; font-size: small; color:#8e8e8e;">AqualinkD</div>
|
||||
<div id="alertDialogHeader"></div>
|
||||
<p id="alertDialogMessage"></p>
|
||||
<button onclick="closeAlert()">Close</button>
|
||||
<hr>
|
||||
<!--<button onclick="aqdAlertClose()">Close</button>-->
|
||||
<input type="button" onclick="aqdAlertClose()" value="Close"/>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"external_script": "/HA_tilePlugin.js",
|
||||
"background_image": {
|
||||
"url": "-hk/background.jpg",
|
||||
"url": "hk/background.jpg",
|
||||
"url_reload": 0
|
||||
},
|
||||
"colors": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,303 @@
|
|||
{
|
||||
"external_script": "/HA_tilePlugin.js",
|
||||
"background_image": {
|
||||
"url": "hk/background.jpg",
|
||||
"url_reload": 0
|
||||
},
|
||||
"colors": {
|
||||
"body_background": "#EBEBEB",
|
||||
"body_text": "#000000",
|
||||
"options_pane_background": "#F5F5F5",
|
||||
"options_pane_bordercolor": "#7C7C7C",
|
||||
"options_slider_highlight": "#2196F3",
|
||||
"options_slider_lowlight": "#D3D3D3",
|
||||
"head_background": "#2B6A8F",
|
||||
"head_text": "#FFFFFF",
|
||||
"error_background": "#8F2B2B",
|
||||
"tile_background": "#DCDCDC",
|
||||
"tile_text": "#6E6E6E",
|
||||
"tile_on_background": "#FFFFFF",
|
||||
"tile_on_text": "#000000",
|
||||
"tile_status_text": "#575757",
|
||||
"value_tile_normal_color": "#049FF8",
|
||||
"value_tile_normal_color_": "#4ec400ff",
|
||||
"value_tile_attention_color": "#FF8000",
|
||||
"value_tile_outofrange_color": "#FF6400",
|
||||
"options_radio_highlight": "#2196F3",
|
||||
"options_radio_lowlight": "#D3D3D3",
|
||||
"tile_icon_background_color_heat": "rgb(255, 123, 0)",
|
||||
"tile_icon_background_color_cool": "rgb(4, 159, 248)",
|
||||
"tile_icon_background_color_enabled": "rgb(78, 196, 0)",
|
||||
"tile_icon_background_color_disabled": "rgb(110, 110, 110)"
|
||||
},
|
||||
"devices": {
|
||||
"Filter_Pump": {
|
||||
"display": "true"
|
||||
},
|
||||
"Spa": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_1": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_2": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_3": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_4": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_5": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_6": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_7": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B1": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B2": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B3": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B4": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B5": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B6": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B7": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_B8": {
|
||||
"display": "true"
|
||||
},
|
||||
"Pool_Heater": {
|
||||
"display": "true"
|
||||
},
|
||||
"Spa_Heater": {
|
||||
"display": "true"
|
||||
},
|
||||
"SWG": {
|
||||
"display": "true"
|
||||
},
|
||||
"SWG/PPM": {
|
||||
"display": "true"
|
||||
},
|
||||
"SWG/Percent": {
|
||||
"display": "false"
|
||||
},
|
||||
"SWG/Boost": {
|
||||
"display": "false"
|
||||
},
|
||||
"Temperature/Air": {
|
||||
"display": "true"
|
||||
},
|
||||
"Temperature/Pool": {
|
||||
"display": "true"
|
||||
},
|
||||
"Temperature/Spa": {
|
||||
"display": "true"
|
||||
},
|
||||
"Pool_Water": {
|
||||
"display": "true"
|
||||
},
|
||||
"Spa_Water": {
|
||||
"display": "true"
|
||||
},
|
||||
"Freeze_Protect": {
|
||||
"display": "true"
|
||||
},
|
||||
"CHEM/pH": {
|
||||
"display": "true"
|
||||
},
|
||||
"CHEM/ORP": {
|
||||
"display": "true"
|
||||
},
|
||||
"Solar_Heater": {
|
||||
"display": "true"
|
||||
},
|
||||
"Extra_Aux": {
|
||||
"display": "true"
|
||||
},
|
||||
"Chiller": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V1": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V2": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V3": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V4": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V5": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V6": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V7": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V8": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V9": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V10": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V11": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V12": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V13": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V14": {
|
||||
"display": "true"
|
||||
},
|
||||
"Aux_V15": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S1": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S2": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S3": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S4": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S5": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S6": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S7": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S8": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S9": {
|
||||
"display": "true"
|
||||
},
|
||||
"Sensor/Aux_S10": {
|
||||
"display": "true"
|
||||
}
|
||||
},
|
||||
"slider_range": {
|
||||
"heater_slider_min": 36,
|
||||
"heater_slider_max": 104,
|
||||
"timer_slider_min": 0,
|
||||
"timer_slider_max": 120,
|
||||
"timer_slider_step": 1
|
||||
},
|
||||
"tile_thresholds": {
|
||||
"SWG/PPM": {
|
||||
"outofrange": {
|
||||
"min": 2600,
|
||||
"max": 3500,
|
||||
"mintext": "Add Salt"
|
||||
},
|
||||
"attention": {
|
||||
"min": 2700,
|
||||
"max": 3400,
|
||||
"mintext": "Add Salt"
|
||||
}
|
||||
},
|
||||
"CHEM/pH": {
|
||||
"outofrange": {
|
||||
"min": 7,
|
||||
"max": 8
|
||||
},
|
||||
"attention": {
|
||||
"min": 7.2,
|
||||
"max": 7.8,
|
||||
"mintext": "Low",
|
||||
"maxtext": "High"
|
||||
}
|
||||
},
|
||||
"CHEM/ORP": {
|
||||
"outofrange": {
|
||||
"min": 560,
|
||||
"max": 900
|
||||
},
|
||||
"attention": {
|
||||
"min": 650,
|
||||
"max": 850,
|
||||
"mintext": "Low",
|
||||
"maxtext": "High"
|
||||
}
|
||||
}
|
||||
},
|
||||
"swg_status": {
|
||||
"0": "On",
|
||||
"1": "No flow",
|
||||
"2": "Low salt",
|
||||
"4": "High salt",
|
||||
"8": "Clean cell",
|
||||
"9": "Turning off",
|
||||
"16": "High current",
|
||||
"32": "Low volts",
|
||||
"64": "Low temp",
|
||||
"128": "Check PCB",
|
||||
"253": "General Fault",
|
||||
"254": "Unknown",
|
||||
"255": "Off"
|
||||
},
|
||||
"tile_settings": {
|
||||
"turn_off_sensortiles": "true",
|
||||
"show_vsp_gpm": "true",
|
||||
"disable_off_icon_background": "true"
|
||||
},
|
||||
"EXAMPLE_colors_dark": {
|
||||
"body_background": "#121212",
|
||||
"body_text": "#FFFFFF",
|
||||
"options_pane_background": "#1E1E1E",
|
||||
"options_pane_bordercolor": "#555555",
|
||||
"options_slider_highlight": "#64B5F6",
|
||||
"options_slider_lowlight": "#555555",
|
||||
"head_background": "#004d7a",
|
||||
"head_text": "#FFFFFF",
|
||||
"error_background": "#b00020",
|
||||
"tile_background": "#333333",
|
||||
"tile_text": "#AAAAAA",
|
||||
"tile_on_background": "#BBBBBB",
|
||||
"tile_on_text": "#000000",
|
||||
"tile_status_text": "#888888",
|
||||
"value_tile_normal_color": "#049FF8",
|
||||
"value_tile_normal_color_": "#69F0AE",
|
||||
"value_tile_attention_color": "#FFB74D",
|
||||
"value_tile_outofrange_color": "#FF8A65",
|
||||
"options_radio_highlight": "#64B5F6",
|
||||
"options_radio_lowlight": "#555555",
|
||||
"tile_icon_background_color_heat": "rgb(255, 123, 0)",
|
||||
"tile_icon_background_color_cool": "rgb(4, 159, 248)",
|
||||
"tile_icon_background_color_enabled": "rgb(78, 196, 0)",
|
||||
"tile_icon_background_color_disabled": "rgb(110, 110, 110)"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
var _confighelp = {};
|
||||
_confighelp["listen_address"]="Address for webserver to listen to eg http://0.0.0.0:80 To accept all HTTP requests. Do not change unless you know exactly what you are doing. HTTPS is restricted for two way auth only"
|
||||
_confighelp["https_cert_dir"]="For two way auth only. Directory where crt.pem, key.pem & optional ca.pem are located"
|
||||
_confighelp["serial_port"]="Device of your RS465 adapter, examples /dev/ttyUSB1, /dev/ttyS2, /dev/serial0"
|
||||
_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 ZZZZ (XX=RS or PD, N=Circuits, ZZZ=Combo or Only or Dual)";
|
||||
_confighelp["device_id"]="The id of the AqualinkD to use, use serial_logger to find ID's. If your panel is a PDA only model then PDA device ID is 0x60. set to device_id to 0xFF for to autoconfigure all this section";
|
||||
_confighelp["mqtt_address"]="MQTT address has to be set to ip:port enable MQTT"
|
||||
_confighelp["mqtt_address"]="MQTT address has to be set to ip:port enable MQTT ig mqtt://192.168.1.99:1883"
|
||||
_confighelp["read_RS485_swg"]="Read device information directly from RS485 bus"
|
||||
_confighelp["force_swg"]="Force any devices to be active at startup. Must set these for Home Assistant integration"
|
||||
_confighelp["enable_scheduler"]="AqualinkD's internal scheduler"
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
--options_slider_highlight: #2196F3;
|
||||
--options_slider_lowlight: #d3d3d3;
|
||||
--options_slider_height: 20px;
|
||||
--options_button_background: rgb(192, 192, 192);
|
||||
--head_background: rgb(43, 106, 143);
|
||||
--head_text: #fff;
|
||||
--error_background: rgb(143, 43, 43);
|
||||
|
|
@ -480,9 +481,11 @@
|
|||
|
||||
.options_button {
|
||||
color: var(--body_text);
|
||||
background-color: var(--options_button_background);
|
||||
font-family: var(--fonts);
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.option_text {
|
||||
|
|
@ -927,6 +930,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Simply loop over each key/value in color jason array and set that property adding -- to the beginning of key
|
||||
function setColors() {
|
||||
if ( _config?.colors ) {
|
||||
const rootElement = document.documentElement;
|
||||
|
||||
Object.entries(_config.colors).forEach(([key, value]) => {
|
||||
//console.log(`Key (Color Variable): ${key}, Value (Color Code): ${value}`);
|
||||
//console.log(key+ " " +document.documentElement.style.getPropertyValue('--' + key)+" | "+window.getComputedStyle(document.documentElement).getPropertyValue('--' + key));
|
||||
if (window.getComputedStyle(rootElement).getPropertyValue('--'+key) && _config?.colors[key]) {
|
||||
document.documentElement.style.setProperty('--'+key, value);
|
||||
} else {
|
||||
console.log(`Invalid config (Color Variable): ${key}, Value : ${value}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// The above replaces the below. Below is safer, but needs modification every time we add a property.
|
||||
/*
|
||||
function setProp(name) {
|
||||
//if ( _config?.colors[name] !== undefined ) {
|
||||
if ( _config?.colors && _config?.colors[name] ) {
|
||||
|
|
@ -936,10 +958,7 @@
|
|||
//console.log("Missing Color "+name);
|
||||
}
|
||||
}
|
||||
|
||||
function setColors() {
|
||||
//return;
|
||||
|
||||
setProp("body_background");
|
||||
setProp("body_text");
|
||||
setProp("options_pane_background");
|
||||
|
|
@ -959,9 +978,13 @@
|
|||
setProp("tile_text");
|
||||
setProp("tile_background");
|
||||
setProp("tile_on_background");
|
||||
|
||||
}
|
||||
|
||||
setProp("tile_icon_background_color_heat");
|
||||
setProp("tile_icon_background_color_cool");
|
||||
setProp("tile_icon_background_color_enabled");
|
||||
setProp("tile_icon_background_color_disabled");
|
||||
}
|
||||
*/
|
||||
function setSizeSpecifics() {
|
||||
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
|
||||
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
|
|
@ -2314,13 +2337,16 @@
|
|||
if ( ! cs_createJSON() ) {
|
||||
return // This stops pane from closing.
|
||||
}
|
||||
} else if (type == 'setpoint_freeze') {
|
||||
if (sp_value != slider.value)
|
||||
setThermostatSetpoint(id, slider.value);
|
||||
} else if (type == 'simulator') {
|
||||
} else {
|
||||
var value = slider.value;
|
||||
if (state == (tile.getAttribute('status') == 'off'))
|
||||
setTileState(id, state);
|
||||
if (sp_value != slider.value)
|
||||
setThermostatSetpoint(id, slider.value)
|
||||
setThermostatSetpoint(id, slider.value);
|
||||
}
|
||||
|
||||
if (typeof tm_slider !== 'undefined' && tm_slider != null) {
|
||||
|
|
@ -3136,6 +3162,8 @@
|
|||
if (value != null) {
|
||||
_cmd.value = value;
|
||||
}
|
||||
//console.log("Send cmd "+JSON.stringify(_cmd));
|
||||
//console.trace("Tracing");
|
||||
socket_di.send(JSON.stringify(_cmd));
|
||||
|
||||
if ( _link_spa_and_heater && cmd == "Spa_Mode" ) {
|
||||
|
|
@ -3145,6 +3173,7 @@
|
|||
if (value != null) {
|
||||
ncmd.value = value;
|
||||
}
|
||||
//console.log("Send spa cmd "+JSON.stringify(ncmd));
|
||||
socket_di.send(JSON.stringify(ncmd));
|
||||
}
|
||||
}
|
||||
|
|
@ -3167,7 +3196,8 @@
|
|||
message.uri = id+"/brightness/set";
|
||||
else
|
||||
message.uri = id+"/setpoint/set";
|
||||
//console.log("Send value back "+temperature.parameter+" "+temperature.value);
|
||||
|
||||
//console.log("Send setpoint "+JSON.stringify(message));
|
||||
socket_di.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue