AqualinkD/web/aqmanager.html

1725 lines
62 KiB
HTML
Raw Permalink Normal View History

2023-06-23 20:16:30 +00:00
<!DOCTYPE html>
<html lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1252'>
<title>AqualinkD Managment Console</title>
<meta name='viewport' content='width=device-width'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<meta name='apple-mobile-web-app-status-bar-style' content='black'>
<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">
2025-01-28 23:45:53 +00:00
<script type="text/javascript" src="confighelp.js"></script>
2023-06-23 20:16:30 +00:00
<style>
2025-01-28 23:45:53 +00:00
:root {
--max-config-height: 870px;
}
2023-06-23 20:16:30 +00:00
html {}
body {
font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
font-weight: 300;
background-color: white;
color: #000000;
margin: 0 !important;
padding: 0 !important;
}
.wrapper {
display: grid;
grid-template-columns: 300px 1fr;
grid-gap: 1rem;
}
.inner {
/*padding: 1rem;*/
display: flex;
align-items: center;
justify-content: center;
/*border: 1px solid red;*/
align-items: flex-start;
}
.aqualinkd {
grid-column: 1 / -1;
}
.commands {
/*padding: 1rem;*/
/*display: grid;*/
align-items: center;
justify-content: center;
/*border: 1px solid red;*/
row-gap: 20px;
2024-08-25 23:31:58 +00:00
/*overflow-y: scroll; this only works if we know the height, we can caculate but not important at moment */
2023-06-23 20:16:30 +00:00
}
2025-01-28 23:45:53 +00:00
.configpopup {
top: 10px;
/*left: 10px;*/
position: fixed;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
/*
height: 100%;
*/
}
2023-06-23 20:16:30 +00:00
/*
.loglevelstitle {
background-color: rgb(221, 221, 221);
}
.debugmaskstitle {
background-color: rgb(221, 221, 221);
}
*/
table {
background-color: rgb(221, 221, 221);
padding: 10px;
}
th {
background-color: white;
}
#title {
background-color: rgb(200, 200, 200);
font-weight: 600;
}
input[type=button],
input[type=submit],
input[type=reset] {
/*background-color: rgb(165, 165, 165);*/
background-color: #4CAAD9;
border: none;
color: rgb(0, 0, 0);
padding: 2px 2px;
text-decoration: none;
margin: 2px 2px 2px 2px;
min-width: 70px;
border-radius: 70px;
height: 20px;
/*max-width: 120px;*/
}
.disablebutton {
background-color: #ccc !important;
color: #777 !important;
}
.disabletoggle {
color: #777 !important;
}
2024-06-10 22:27:01 +00:00
.statusmsg {}
2023-06-23 20:16:30 +00:00
.error {
background-color: rgb(255, 0, 0) !important;
font-weight: 600;
}
.logmsgerror {
color: rgb(255, 0, 0) !important;
}
2024-06-10 22:27:01 +00:00
.newversion {
background-color: rgb(148, 195, 233) !important;
}
2023-06-23 20:16:30 +00:00
.hidden {
display: none;
}
.commands {
vertical-align: top;
}
.loglevels {}
.logcontainer {
font-family: monospace;
height: 510px;
width: 100%;
overflow: auto;
display: flex;
flex-direction: column-reverse;
background-color: #2b2b2b;
color: white;
2023-07-08 16:14:44 +00:00
white-space: pre;
2023-06-23 20:16:30 +00:00
}
.toggle {
cursor: pointer;
display: inline-block;
margin: 1px 1px 1px 1px;
}
.logtoggle {
width: 130px;
}
.toggle-switch {
display: inline-block;
background: #ccc;
border-radius: 16px;
width: 35px;
height: 18px;
position: relative;
vertical-align: middle;
transition: background 0.25s;
}
.toggle-switch:before,
.toggle-switch:after {
content: "";
}
.toggle-switch:before {
display: block;
background: linear-gradient(to bottom, #fff 0%, #eee 100%);
border-radius: 50%;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
width: 15px;
height: 15px;
position: absolute;
top: 2px;
left: 2px;
transition: left 0.25s;
}
.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);
}
.toggle-checkbox:checked+.toggle-switch {
/*background: #56c080;*/
background: #4CAAD9;
}
.toggle-checkbox:checked+.toggle-switch:before {
left: 19px;
}
.toggle-checkbox {
position: absolute;
visibility: hidden;
}
.toggle-label {
margin-left: 5px;
position: relative;
top: 2px;
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
/*padding: 18px;*/
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 16px;
}
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.content {
display: grid;
/*padding: 0 18px;*/
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
background-color: #f1f1f1;
font-size: 14px;
}
2025-01-28 23:45:53 +00:00
/* 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;
}
*/
2023-06-23 20:16:30 +00:00
</style>
<script type='text/javascript'>
var _panel_size = 6;
var _panel_set = 0;
2024-06-10 22:27:01 +00:00
var _latestVersionAvailable = 0;
2024-08-31 23:01:12 +00:00
var _rssd_logmask = 0;
2024-09-01 17:00:42 +00:00
const RSSD_MASK_ID = 512; // Must match RSSD_LOG in utils.c
2023-06-23 20:16:30 +00:00
2025-03-09 22:39:41 +00:00
_addedBlankLightProgram = false;
_addedBlankSensor = false;
_addedBlankVirtualButton = false;
var _config = {};
// if loading confighelp.js failes, create a blank variable that it creates.
if (typeof _confighelp === 'undefined') {
var _confighelp = {};
}
2023-06-23 20:16:30 +00:00
function init_collapsible() {
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
// open up the system information collapsable content
document.getElementById("systembutton").dispatchEvent(new Event('click'));
// disable the download log button on startup
2023-06-24 00:38:59 +00:00
//disablebutton("downloadlog");
2023-07-08 16:14:44 +00:00
//disabletoggle("logfile");
2023-06-23 20:16:30 +00:00
//disabletoggle("seriallog");
}
function disablebutton(id) {
2024-06-10 22:27:01 +00:00
//console.log("disable " + id);
2023-06-23 20:16:30 +00:00
var button = document.getElementById(id);
if (button) {
button.disabled = true;
button.classList.add("disablebutton");
}
}
function enablebutton(id) {
2024-06-10 22:27:01 +00:00
//console.log("enable " + id);
2023-06-23 20:16:30 +00:00
var button = document.getElementById(id);
if (button) {
button.disabled = false;
button.classList.remove("disablebutton");
}
}
function disabletoggle(id) {
disablebutton(id);
try {
document.getElementById(id).parentNode.classList.add("disabletoggle");
} catch (e) { console.log("error " + e) }
}
function enabletoggle(id) {
enablebutton(id);
try {
document.getElementById(id).parentNode.classList.remove("disabletoggle");
} catch (e) { console.log("error " + e) }
}
function tohex(value) {
var rtn = parseInt(value).toString(16);
if (rtn.length <= 1)
return "0x0" + rtn;
else
return "0x" + rtn;
}
function todec(value) {
let number = parseInt(value, 16);
return number;
}
var last_message_element = null;
2023-07-08 16:14:44 +00:00
var log_element_count = 0;
const LOGS2DISPLAY = 500;
2023-06-23 20:16:30 +00:00
function update_log_message(message) {
var element = document.createElement("div");
if (message.startsWith("Error:")) {
element.classList.add("logmsgerror");
}
2023-07-08 16:14:44 +00:00
var logcontainer = document.getElementById("logs");
if (log_element_count >= LOGS2DISPLAY) {
2024-06-10 22:27:01 +00:00
try {
console.log("Removing " + logcontainer.lastElementChild.innerHTML);
logcontainer.lastElementChild.remove();
} catch (e) {
console.log("ERROR Removing log '" + logcontainer.lastElementChild.innerHTML + "'");
log_element_count++;
}
2023-07-08 16:14:44 +00:00
} else {
2024-06-10 22:27:01 +00:00
log_element_count++;
2023-07-08 16:14:44 +00:00
}
2023-06-23 20:16:30 +00:00
element.appendChild(document.createTextNode(message));
2023-07-08 16:14:44 +00:00
logcontainer.insertBefore(element, last_message_element);
2023-06-23 20:16:30 +00:00
last_message_element = element;
}
function update_status(data) {
}
function setloglevel(caller) {
//console.log(caller.id);
var id = parseInt(caller.id.split('_')[1]);
var msg = {
uri: "setloglevel",
value: id
};
send_command(msg);
}
function setlogmask(caller) {
2024-08-31 23:01:12 +00:00
//console.log(caller.id);
2023-06-23 20:16:30 +00:00
var id = parseInt(caller.id.split('_')[1]);
var addremove = "";
if (caller.checked) {
addremove = "addlogmask";
} else {
addremove = "removelogmask";
}
var msg = {
uri: addremove,
value: id
};
2024-08-31 23:01:12 +00:00
// If it's RSSD logmask, and we have filter, append that to the uri.
if (caller.id == _rssd_logmask ) {
var filter = document.getElementById("rssd_filter").value;
if (filter) {
if (addremove == "addlogmask") {
msg.uri = msg.uri + "/" + filter;
}
}
}
2023-06-23 20:16:30 +00:00
send_command(msg);
}
function setlogfile(caller) {
var msg = {};
2023-07-08 16:14:44 +00:00
/*
if (caller.id == "logfile") {
2023-06-23 20:16:30 +00:00
var startstop = "";
if (caller.checked) {
startstop = "start";
} else {
startstop = "stop";
}
msg = {
2023-07-08 16:14:44 +00:00
uri: "logfile/" + startstop,
2023-06-23 20:16:30 +00:00
value: 0
};
} else if (caller.id == "cleanlog") {
msg = {
2023-07-08 16:14:44 +00:00
uri: "logfile/clean",
2023-06-23 20:16:30 +00:00
value: 0
};
2023-07-08 16:14:44 +00:00
} else*/
if (caller.id == "downloadlog") {
2024-06-10 22:27:01 +00:00
2023-06-23 20:16:30 +00:00
//window.location = '/api/debug/download';
2023-07-08 16:14:44 +00:00
downloadFile('/api/logfile/download', document.getElementById("logsize").value);
2023-06-23 20:16:30 +00:00
return;
}
send_command(msg);
}
2023-06-24 00:38:59 +00:00
function downloadFile(filePath, lines) {
2025-01-28 23:45:53 +00:00
//console.log("Lines=" + lines);
2024-06-10 22:27:01 +00:00
var link = document.createElement('a');
link.href = filePath + "/" + lines;
//link.download = filePath.substr(filePath.lastIndexOf('/') + 1);
link.download = "aqualinkd.log"
link.click();
// Can't get a form post to cleanly download, and "a download" above can only do get. So add value
/*
var form = document.createElement('form');
form.setAttribute("style", "display: none;");
form.method='POST';
form.action=filePath;
form.target='aqd'; // Set trget to iframe "aqd"(aqualinkd), this stops WS for resetting
element=document.createElement('INPUT');
element.name='value';
element.value=lines;
form.appendChild(element);
document.body.appendChild(form);
form.submit();
*/
2023-06-23 20:16:30 +00:00
}
function settoggle(id, onoff) {
var element = document.getElementById(id);
if (onoff == "on") {
element.checked = true;
//console.log("set " + element.id + " on");
} else {
element.checked = false;
//console.log("set " + element.id + " off");
}
}
2024-08-31 23:01:12 +00:00
function checkboxClick(caller) {
try {
if (caller.id == "slog_debug") {
if (caller.checked) {
document.getElementById("slog_ids").disabled = true;
} else {
document.getElementById("slog_ids").disabled = false;
}
}
} catch (Error) { }
}
2025-01-28 23:45:53 +00:00
function editconfig(caller) {
var msg = {
uri: "config"
};
send_command(msg);
}
function saveconfig(caller) {
2025-03-09 22:39:41 +00:00
var json_ordered = {
uri: "config/set",
values: {}
2025-01-28 23:45:53 +00:00
};
2025-03-09 22:39:41 +00:00
2025-01-28 23:45:53 +00:00
for (var obj in _config) {
2025-03-09 22:39:41 +00:00
2025-01-28 23:45:53 +00:00
if (_config[obj].value !== undefined) {
2025-03-09 22:39:41 +00:00
//if (_config[obj].value) {
json_ordered.values[obj] = _config[obj].value;
//}
} else if (obj.toString().startsWith("button_") || obj.toString().startsWith("virtual_button_") || obj.toString().startsWith("sensor_") ) {
for (var obj1 in _config[obj]) {
if (obj1.toString() != "advanced") {
//if (_config[obj][obj1].value) {
json_ordered.values[obj1] = _config[obj][obj1].value;
//}
}
}
2025-01-28 23:45:53 +00:00
}
}
2025-03-09 22:39:41 +00:00
//console.log(json_ordered);
send_command(json_ordered);
2025-01-28 23:45:53 +00:00
closeconfig();
}
2025-03-09 22:39:41 +00:00
function clearconfigtable() {
2025-01-28 23:45:53 +00:00
const configtable = document.getElementById("config_table");
2025-03-09 22:39:41 +00:00
while (configtable.rows.length > 2) {
configtable.deleteRow(2); // Delete the first data row (index 1)
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
}
function closeconfig() {
clearconfigtable();
2025-01-28 23:45:53 +00:00
document.getElementById("config_options").classList.add("hide");
document.getElementById("config_options_pane").classList.add("hide");
}
2025-03-09 22:39:41 +00:00
function resetConfig(caller) {
clearconfigtable();
populateconfigtable();
}
2025-01-28 23:45:53 +00:00
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");
2025-03-09 22:39:41 +00:00
populateconfigtable(data);
}
function addConfigRow(hideLineSeperator, data, obj, row=-1) {
const configtable = document.getElementById("config_table");
const newRow = configtable.insertRow(row);
/*
if (row==null) {
2025-01-28 23:45:53 +00:00
const newRow = configtable.insertRow();
2025-03-09 22:39:41 +00:00
} else {
newRow = row;
}*/
2025-01-28 23:45:53 +00:00
2025-03-09 22:39:41 +00:00
if (!hideLineSeperator) {
//newRow.style.borderBottom = "1px solid black";
newRow.style.borderTop = "1px solid black";
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
//console.log(data[obj]["valid values"]+" == "+ obj["valid values"]);
//console.log(data[obj].value+" == "+ obj.value);
2025-01-28 23:45:53 +00:00
2025-03-09 22:39:41 +00:00
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) {
2025-01-28 23:45:53 +00:00
//console.log(data[obj]["valid values"]);
const input = document.createElement("select");
array = data[obj]["valid values"];
for (var i = 0; i < array.length; i++) {
2025-03-09 22:39:41 +00:00
var option = document.createElement("option");
option.value = array[i];
option.text = array[i];
if (array[i].toUpperCase() == data[obj].value.toUpperCase()) {
option.selected = true;
}
input.setAttribute('key', obj.toString());
input.addEventListener('change', cfgValueChanged);
input.appendChild(option);
2025-01-28 23:45:53 +00:00
}
cell2.appendChild(input);
2025-03-09 22:39:41 +00:00
} else if (data[obj].type == "string") {
2025-01-28 23:45:53 +00:00
const input = document.createElement("input");
2025-03-09 22:39:41 +00:00
input.type = "text";
if (data[obj].value != "(null)") {
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";
if (data[obj].value != -999) {
input.value = data[obj].value;
}
input.size = 4;
input.step = 1;
2025-01-28 23:45:53 +00:00
input.setAttribute('key', obj.toString());
input.addEventListener('change', cfgValueChanged);
cell2.appendChild(input);
2025-03-09 22:39:41 +00:00
} else if (data[obj].type == "float") {
2025-01-28 23:45:53 +00:00
const input = document.createElement("input");
2025-03-09 22:39:41 +00:00
input.type = "number";
2025-01-28 23:45:53 +00:00
input.value = data[obj].value;
input.size = 4;
2025-03-09 22:39:41 +00:00
input.step = 0.01;
2025-01-28 23:45:53 +00:00
input.setAttribute('key', obj.toString());
input.addEventListener('change', cfgValueChanged);
cell2.appendChild(input);
2025-03-09 22:39:41 +00:00
} else if (data[obj].type == "hex") {
2025-01-28 23:45:53 +00:00
const input = document.createElement("input");
2025-03-09 22:39:41 +00:00
input.type = "text";
2025-01-28 23:45:53 +00:00
input.value = data[obj].value;
input.size = 4;
input.setAttribute('key', obj.toString());
input.addEventListener('change', cfgValueChanged);
cell2.appendChild(input);
2025-03-09 22:39:41 +00:00
} else {
2025-01-28 23:45:53 +00:00
cell2.textContent = data[obj].value;
2025-03-09 22:39:41 +00:00
}
}
function addButtonOptionRow(key=0, isVirtual) {
//if ( isVirtual == true && key == 0 ) {
// if (_addedBlankVirtualButton == true) {
// return;
// }
// key = 1
//}
const buttonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "lightMode"];
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "onetouchID"];
const configtable = document.getElementById("config_table");
const newRow = configtable.insertRow();
var cell1 = newRow.insertCell();
var cell2 = newRow.insertCell();
var cell3 = newRow.insertCell();
cell1.style.paddingLeft = "20px";
cell1.style.fontSize = "small";
cell2.style.fontSize = "small";
cell3.style.fontSize = "small";
var blist = isVirtual?virtButtonTypelist:buttonTypelist;
var options = "";
for (const index in blist ) {
if (!_config[key][key+"_"+blist[index]]) {
options=options+'<option value="'+blist[index]+'">'+blist[index]+'</option>';
}
}
cell1.innerHTML = 'Add <select id="add_button_type"><option value="" selected="true"></option>'+options+'</select>';
cell1.setAttribute('button_key', key);
cell1.addEventListener('change', cfgAddButtonOption);
//if ( isVirtual == true ){
// _addedBlankVirtualButton = true;
//}
}
function addLightProgramRow(num=0, row=-1){
//console.log("addLightProgramRow( "+num+" )");
if ( num == 0 ) {
if (_addedBlankLightProgram == true) {
return;
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
//num = 1
}
if (num >= _config.max_light_programs) {
console.log("MAX LIGHTS REACHED");
_addedBlankLightProgram = true;
return;
}
const configtable = document.getElementById("config_table");
if (num == 0) {
var newRow = configtable.insertRow();
var cell1 = newRow.insertCell();
cell1.colSpan = 3;
cell1.style.fontSize = "small";
cell1.style.paddingLeft = "5px";
cell1.innerHTML = "Custom Light Programs";
cell1.style.borderTop = "1px solid black";
}
var newRow = configtable.insertRow(row);
var cell1 = newRow.insertCell();
var cell2 = newRow.insertCell();
var cell3 = newRow.insertCell();
cell1.style.paddingLeft = "20px";
key = 'light_program_'+String(num+1).padStart(2, '0')
cell1.innerHTML = 'Add '+key;
cell1.setAttribute('label', key);
const input = document.createElement("input");
input.type = "text";
//input.setAttribute('light_program_key', key);
input.setAttribute('key', key);
input.addEventListener('change', cfgAddLightProgram);
//input.addEventListener('change', cfgValueUnhide);
cell2.appendChild(input);
//cell1.setAttribute('button_key', key);
//cell1.addEventListener('change', cfgAddButtonOption);
_addedBlankLightProgram = true;
}
function addVirtualButtonRow(num=0, row=-1){
if ( num == 0 ) {
if (_addedBlankVirtualButton == true) {
return;
2025-01-28 23:45:53 +00:00
}
}
2025-03-09 22:39:41 +00:00
num++;
if (num >= _config.max_vbuttons) {
console.log("MAX VIRTUAL BUTTONS REACHED");
_addedBlankVirtualButton = true;
return;
}
const virtButtonTypelist = ["pumpIndex", "pumpID", "pumpType", "pumpName", "onetouchID"];
const configtable = document.getElementById("config_table");
vbname="virtual_button_"+String(num).padStart(2, '0');
vblabel=vbname+"_label";
newRow = configtable.insertRow();
2025-01-28 23:45:53 +00:00
var cell1 = newRow.insertCell();
cell1.colSpan = 3;
2025-03-09 22:39:41 +00:00
cell1.style.fontSize = "small";
cell1.style.paddingLeft = "5px";
cell1.innerHTML = vbname + " ( <b>Aux_V"+num+"</b> )";
cell1.style.borderTop = "1px solid black";
2025-01-28 23:45:53 +00:00
newRow = configtable.insertRow();
2025-03-09 22:39:41 +00:00
//newRow.style.borderTop = "1px solid black";
var cell1 = newRow.insertCell();
2025-01-28 23:45:53 +00:00
var cell2 = newRow.insertCell();
var cell3 = newRow.insertCell();
2025-03-09 22:39:41 +00:00
cell1.style.paddingLeft = "20px";
cell1.textContent = vblabel;
const input = document.createElement("input");
input.type = "text";
input.setAttribute('key', vblabel);
//input.addEventListener('change', cfgValueChanged);
input.addEventListener('change', cfgValueUnhide);
cell2.appendChild(input);
///////////
newRow = configtable.insertRow();
//newRow.style.hide = true;
newRow.style.display = 'none';
cell1 = newRow.insertCell();
cell2 = newRow.insertCell();
cell3 = newRow.insertCell();
2025-01-28 23:45:53 +00:00
2025-03-09 22:39:41 +00:00
cell1.style.paddingLeft = "20px";
cell1.style.fontSize = "small";
cell2.style.fontSize = "small";
cell3.style.fontSize = "small";
var options = "";
for (const index in virtButtonTypelist ) {
options=options+'<option value="'+virtButtonTypelist[index]+'">'+virtButtonTypelist[index]+'</option>';
}
cell1.innerHTML = 'Add <select id="add_button_type"><option value="" selected="true"></option>'+options+'</select>';
cell1.setAttribute('button_key', vbname);
cell1.addEventListener('change', cfgAddButtonOption);
_addedBlankVirtualButton = true;
}
function cfgValueUnhide(event) {
var key = event.srcElement.getAttribute('key');
var value = event.srcElement.value;
if (key.startsWith("virtual_button_") ) {
var js = {};
var jso = {};
js.value=value;
js.type="string";
js.advanced="no";
jso[key] = js;
_config[key.slice(0, 17)] = jso;
console.log(_config);
}
console.log("cfgValueUnhide key="+key+" value="+value);
event.target.removeEventListener('change', cfgValueUnhide);
event.target.addEventListener('change', cfgValueChanged);
// Show the next table row.
event.target.parentNode.parentNode.nextSibling.style.display = '';
if (key.startsWith("sensor_") ) {
event.srcElement.parentNode.parentNode.childNodes[0].innerHTML = key;
event.target.parentNode.parentNode.nextSibling.nextSibling.style.display = '';
}
2025-01-28 23:45:53 +00:00
2025-03-09 22:39:41 +00:00
console.log(event);
}
function addSensorRow(num=0, row=-1){
if ( num == 0 ) {
if (_addedBlankSensor == true) {
return;
}
//num = 1
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
if (num >= _config.max_sensors) {
console.log("MAX SENSORS REACHED");
_addedBlankSensor = true;
return;
}
const configtable = document.getElementById("config_table");
if (num == 0) {
var newRow = configtable.insertRow();
var cell1 = newRow.insertCell();
cell1.colSpan = 3;
cell1.style.fontSize = "small";
cell1.style.paddingLeft = "5px";
cell1.innerHTML = "Sensors";
cell1.style.borderTop = "1px solid black";
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
var newRow = configtable.insertRow(row);
2025-01-28 23:45:53 +00:00
2025-03-09 22:39:41 +00:00
if (num != 0) {
newRow.style.borderTop = "1px solid black";
}
key = 'sensor_'+String(num+1).padStart(2, '0');
// Add sensor_xx_path row
var cell1 = newRow.insertCell();
var cell2 = newRow.insertCell();
//var cell3 = newRow.insertCell();
cell1.style.paddingLeft = "20px";
cell1.innerHTML = "<small>Add</small> "+key+"_path";
var input = document.createElement("input");
input.type = "text";
input.setAttribute('key', key+"_path");
input.setAttribute('root_key', key);
input.id = key+"_path";
input.addEventListener('change', cfgAddSensor);
input.addEventListener('change', cfgValueUnhide);
cell2.appendChild(input);
// Add sensor_xx_label row
if (row != -1){row++};
newRow = configtable.insertRow(row);
newRow.style.display = 'none';
cell1 = newRow.insertCell();
cell2 = newRow.insertCell();
//cell3 = newRow.insertCell();
cell1.style.paddingLeft = "20px";
cell1.innerHTML = key+"_label";
input = document.createElement("input");
input.type = "text";
input.setAttribute('key', key+"_label");
input.setAttribute('root_key', key);
input.id = key+"_label";
input.addEventListener('change', cfgAddSensor);
cell2.appendChild(input);
// Add sensor_xx_factor row
if (row != -1){row++};
newRow = configtable.insertRow(row);
newRow.style.display = 'none';
cell1 = newRow.insertCell();
cell2 = newRow.insertCell();
//cell3 = newRow.insertCell();
cell1.style.paddingLeft = "20px";
cell1.innerHTML = key+"_factor";
input = document.createElement("input");
input.type = "number";
input.size = 4;
input.step = 0.01;
input.setAttribute('key', key+"_factor");
input.setAttribute('root_key', key);
input.id = key+"_factor";
input.addEventListener('change', cfgAddSensor);
cell2.appendChild(input);
_addedBlankSensor = true;
}
function cfgAddButtonOption(event) {
var type = event.srcElement.value;
var key = event.srcElement.parentNode.getAttribute('button_key');
for (var obj in _config) {
if (obj.toString() == key) {
var js = {};
js.advanced = "no";
switch(type) {
case "pumpIndex":
case "lightMode":
case "onetouchID":
js.type = "int";
break;
case "pumpID":
js.type = "hex";
break;
case "pumpType":
js.type = "string";
let validvalues = ["", "JANDY ePUMP", "Pentair VS", "Pentair VF"];
js['valid values'] = validvalues;
break;
case "pumpName":
js.type = "string";
break;
}
js.value = "";
_config[obj][key+"_"+type] = js;
break;
}
}
const configtable = document.getElementById("config_table");
for (let i = 0; i < configtable.rows.length; i++) {
if(configtable.rows[i].cells[0].getAttribute('button_key') !== null) {
if(configtable.rows[i].cells[0].getAttribute('button_key') == key) {
addConfigRow(true, _config[obj], key+"_"+type, i);
break;
}
}
}
}
function cfgAddLightProgram(event){
var value = event.srcElement.value;
var key = event.srcElement.getAttribute('key');
//console.log(key + " = "+ value);
event.srcElement.parentNode.parentNode.childNodes[0].innerHTML = key;
//event.target.innerHTML = key;
//event.srcElement.parentNode.parentNode.childNodes[1].childNodes[0].removeEventListener('change', cfgAddLightProgram);
//event.srcElement.parentNode.parentNode.childNodes[1].childNodes[0].addEventListener('change', cfgValueChanged);
event.target.removeEventListener('change', cfgAddLightProgram);
event.target.addEventListener('change', cfgValueChanged);
var js = {};
js.advanced = "yes";
js.type = "string";
js.value = value;
_config[key] = js;
//console.log(_config);
const configtable = document.getElementById("config_table");
for (let i = 0; i < configtable.rows.length; i++) {
if(configtable.rows[i].cells[0].getAttribute('label') !== null) {
//console.log(configtable.rows[i].cells[0].innerHTML+" test= "+key);
if(configtable.rows[i].cells[0].getAttribute('label') == key) {
addLightProgramRow(parseInt(key.match(/[0-9]+/)), i+1);
break;
}
}
}
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
function cfgAddSensor(event){
var value = event.srcElement.value;
var key = event.srcElement.getAttribute('key');
var root_key = event.srcElement.getAttribute('root_key');
console.log(key + " = "+ value);
//event.srcElement.parentNode.parentNode.childNodes[1].childNodes[0].removeEventListener('change', cfgAddLightProgram);
//event.srcElement.parentNode.parentNode.childNodes[1].childNodes[0].addEventListener('change', cfgValueChanged);
event.target.removeEventListener('change', cfgAddSensor);
event.target.addEventListener('change', cfgValueChanged);
var js = {};
js.advanced = "yes";
if (key.endsWith("_factor")) {
js.type = "float";
} else {
js.type = "string";
}
js.value = value;
//_config[key] = js;
if (_config[root_key]) {
console.log("Json exists");
_config[root_key][key] = js;
} else {
console.log("Json not exists");
jsobj={};
jsobj.advanced="yes";
jsobj[key] = js;
_config[root_key] = jsobj
}
console.log(_config);
// If all 3 have an entry, add another sensor
if ( (document.getElementById(root_key+"_path").value) &&
(document.getElementById(root_key+"_label").value) &&
(document.getElementById(root_key+"_factor").value)) {
const configtable = document.getElementById("config_table");
for (let i = 0; i < configtable.rows.length; i++) {
try{
console.log(configtable.rows[i].cells[0].innerHTML);
if(configtable.rows[i].cells[0].innerHTML == key) {
addSensorRow( parseInt(key.match(/[0-9]+/)), i+1 )
break;
}
} catch (e){}
}
}
2025-01-28 23:45:53 +00:00
}
2023-06-23 20:16:30 +00:00
2025-03-09 22:39:41 +00:00
function populateconfigtable(data=null) {
_addedBlankLightProgram = false;
_addedBlankSensor = false;
_addedBlankVirtualButton = false;
2025-01-28 23:45:53 +00:00
const configtable = document.getElementById("config_table");
2025-03-09 22:39:41 +00:00
showAdvanced = document.getElementById("show_advanced").checked;
//console.log (data);
if (data != null)
_config = data;
var lastKey = "";
//var lastBtnNum = 0;
//var lastSenNum = 0;
//var vBtnCnt = 0;
var maxSensor = 0;
var maxLightProgramName = 0;
for (var obj in _config) {
var hideLineSeperator = false;
if (!showAdvanced && _config[obj].advanced == "yes") {
continue;
}
// Basic groupings by first letter change
if ( lastKey.charAt(0) == obj.toString().charAt(0) ) {
hideLineSeperator = true;
}
// More advanced groupings
if (obj.toString().includes("device_id") && lastKey.includes("device_id") ) {
hideLineSeperator = true;
} else if (obj.toString().includes("light_program_") ) {
hideLineSeperator = true;
if (obj.toString().includes("light_program_01") ) {
hideLineSeperator = false;
}
const num = parseInt(obj.toString().match(/[0-9]+/));
if (num > maxLightProgramName)
maxLightProgramName = num;
}
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 (! hideLineSeperator) {
//newRow.style.borderBottom = "1px solid black";
newRow.style.borderTop = "1px solid black";
hideLineSeperator = true;
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
}
if (lastKey.startsWith("light_program_") && ! obj.toString().startsWith("light_program_") ) {
addLightProgramRow(parseInt(lastKey.match(/[0-9]+/)));
} else if (lastKey.startsWith("sensor_") && ! obj.toString().startsWith("sensor_") ) {
addSensorRow(parseInt(lastKey.match(/[0-9]+/)));
} else if (lastKey.startsWith("virtual_button_") && ! obj.toString().startsWith("virtual_button_") ) {
addVirtualButtonRow(parseInt(lastKey.match(/[0-9]+/)));
}
if (_config[obj].value !== undefined) {
addConfigRow(hideLineSeperator, _config, obj);
} else if (obj.toString().startsWith("button_") || obj.toString().startsWith("virtual_button_") ) {
var hide=false;
for (var obj1 in _config[obj]) {
if (obj1.toString() == "default") {
const newRow = configtable.insertRow();
const cell1 = newRow.insertCell();
cell1.colSpan = 3;
cell1.style.fontSize = "small";
cell1.style.paddingLeft = "5px";
cell1.innerHTML = obj.toString() + " ( <b>" +_config[obj]["default"] + "</b> )";
cell1.style.borderTop = "1px solid black";
hide=true;
} else if (obj1.toString() != "advanced") {
addConfigRow(hide, _config[obj], obj1);
hide=true;
}
}
addButtonOptionRow(obj.toString(), !obj.toString().startsWith("button_"));
} else if (obj.toString().startsWith("sensor_")) {
var hide=false;
for (var obj1 in _config[obj]) {
if (obj1.toString() != "advanced") {
addConfigRow(hide, _config[obj], obj1);
hide=true;
}
}
} else {
//console.log("UNDIFINED " + obj.toString() + " = " + _config[obj].value);
}
lastKey = obj.toString();
}
if (showAdvanced) {
addLightProgramRow();
addSensorRow();
}
addVirtualButtonRow();
}
function cfgValueChanged(event) {
var key = event.srcElement.getAttribute('key');
var value = event.srcElement.value;
console.log("Config set "+key+" to "+value)
try {
_config[key].value = value;
} catch (exception) {
console.log("Error setting cfg");
//console.error(exception);
if (key.startsWith("button_") ) {
_config[key.slice(0, 9)][key].value = value
} else if (key.startsWith("virtual_button_") ) {
_config[key.slice(0, 17)][key].value = value
} else if (key.startsWith("sensor_") ) {
_config[key.slice(0, 9)][key].value = value
}
2025-01-28 23:45:53 +00:00
}
2025-03-09 22:39:41 +00:00
console.log(_config);
2025-01-28 23:45:53 +00:00
}
2023-06-23 20:16:30 +00:00
function update_status(data) {
/*
read panel_message, panel_type, version, aqualinkd_version
*/
if (data['aqualinkd_version']) {
2024-06-10 22:27:01 +00:00
document.getElementById("aqualinkdversion").innerHTML = data['aqualinkd_version'];
if (data['aqualinkd_version'] == _latestVersionAvailable ) {
document.getElementById("latesversionavailable").classList.add("hidden");
} else {
document.getElementById("latesversionavailable").classList.add("newversion");
}
2023-06-23 20:16:30 +00:00
}
if (data['version']) {
2024-06-10 22:27:01 +00:00
document.getElementById("panelversion").innerHTML = data['version'];
2023-06-23 20:16:30 +00:00
}
if (data['panel_type']) {
2024-06-10 22:27:01 +00:00
document.getElementById("paneltype").innerHTML = data['panel_type'];
2023-06-23 20:16:30 +00:00
}
if (data['status']) {
update_status_message(data['status']);
}
/*
if (data['status'] == " ") {
document.getElementById("statusmsg").innerHTML = "Connected";
} else if (data['status'] != " ") {
document.getElementById("statusmsg").innerHTML = data['status'];
}
*/
}
2024-06-10 22:27:01 +00:00
function update_status_message(message, error = false) {
try {
if (error || message.substring(0, 5).toLowerCase() == "error")
document.getElementById("statusmsg").classList.add("error");
else
document.getElementById("statusmsg").classList.remove("error");
if (message == " ") {
document.getElementById("statusmsg").innerHTML = "Connected";
} else if (message != " ") {
document.getElementById("statusmsg").innerHTML = message;
}
} catch (Error) { }
2023-06-23 20:16:30 +00:00
}
function setAqManagerOptions(data) {
/*
read deamonized logging2file logfilename debugmasks[] loglevels[]
if logfilename=NULL we can turn on/off logging to file.
logging2file will tell us if it's currently on or off
*/
2024-06-10 22:27:01 +00:00
if (data['deamonized'] == 'off') {
//console.log("deamonized=" + data['deamonized'] + " Need to rename Restart to Reload");
disablebutton("restart");
2023-06-23 20:16:30 +00:00
}
2025-01-28 23:45:53 +00:00
if (data['config_editor'] == 'yes') {
enablebutton("editconfig");
} else {
disablebutton("editconfig");
}
2024-06-10 22:27:01 +00:00
/*
if (data['logfilename'] == "(null)")
enabletoggle("logfile");
else
disabletoggle("logfile");
*/
/*
if (data['logfileready'] == "on") {
enablebutton("downloadlog");
enablebutton("cleanlog");
} else {
disablebutton("downloadlog");
disablebutton("cleanlog");
}
*/
2023-06-23 20:16:30 +00:00
var eCommands = document.getElementById("loglevels");
for (var obj in data['loglevels']) {
//console.log(data['loglevels'][obj].name);
var element_id = "loglevel_" + data['loglevels'][obj].id;
var element = document.getElementById(element_id);
if (!element) {
element = document.createElement('label');
element.classList.add('toggle');
element.classList.add('logtoggle');
element.innerHTML = '<input class="toggle-checkbox" type="checkbox" id="' + element_id + '" onclick="setloglevel(this);">' +
'<div class="toggle-switch"></div>' +
'<span class="toggle-label">' + data['loglevels'][obj].name + '</span>';
eCommands.appendChild(element);
}
settoggle(element_id, data['loglevels'][obj].set);
}
var eCommands = document.getElementById("debugmasks");
for (var obj in data['debugmasks']) {
var element_id = "debugmask_" + data['debugmasks'][obj].id;
var element = document.getElementById(element_id);
if (!element) {
element = document.createElement('label');
element.classList.add('toggle');
element.classList.add('logtoggle');
element.innerHTML = '<input class="toggle-checkbox" type="checkbox" id="' + element_id + '" onclick="setlogmask(this);">' +
'<div class="toggle-switch"></div>' +
'<span class="toggle-label">' + data['debugmasks'][obj].name + '</span>';
eCommands.appendChild(element);
2024-08-31 23:01:12 +00:00
2024-09-01 17:00:42 +00:00
//if ( data['debugmasks'][obj].name.substr(0,9) == "RS Serial" ) {
// _rssd_logmask = element_id;
if ( data['debugmasks'][obj].id == RSSD_MASK_ID) {
2024-08-31 23:01:12 +00:00
_rssd_logmask = element_id;
element = document.createElement('div');
element.style.marginTop = '1px';
element.style.marginBottom = '2px'; // = 'style="margin-left: 5px';
2024-09-17 22:48:06 +00:00
element.innerHTML = '<input id="rssd_filter" type="text" value="" size="10" maxlength="19">&nbsp;RS Serial Filter <font size="-2">(Eg 0x10 0x0a)</font></input>';
2024-08-31 23:01:12 +00:00
eCommands.appendChild(element);
2024-09-17 22:48:06 +00:00
var filterentry = document.getElementById("rssd_filter");
filterentry.value = "";
for (var id in data['debugmasks'][obj].filters) {
2025-01-28 23:45:53 +00:00
//console.log("Filter "+data['debugmasks'][obj].filters[id]);
2024-09-17 22:48:06 +00:00
if (data['debugmasks'][obj].filters[id] != "0x00") {
if (filterentry.value.length == 0) {
filterentry.value = data['debugmasks'][obj].filters[id];
} else {
filterentry.value = filterentry.value+" "+data['debugmasks'][obj].filters[id];
}
}
2024-09-01 17:00:42 +00:00
}
2024-08-31 23:01:12 +00:00
}
2023-06-23 20:16:30 +00:00
}
settoggle(element_id, data['debugmasks'][obj].set);
}
2024-08-31 23:01:12 +00:00
2023-06-23 20:16:30 +00:00
}
function get_appropriate_ws_url() {
var pcol;
var u = document.URL;
/*
* We open the websocket encrypted if this page came on an
* https:// url itself, otherwise unencrypted
*/
if (u.substring(0, 5) == "https") {
pcol = "wss://";
u = u.substr(8);
} else {
pcol = "ws://";
if (u.substring(0, 4) == "http")
u = u.substr(7);
}
u = u.split('/');
//alert (pcol + u[0] + ":6500");
return pcol + u[0];
}
/* dumb increment protocol */
var socket_di;
function startWebsockets() {
socket_di = new WebSocket(get_appropriate_ws_url());
try {
socket_di.onopen = function () {
// success!
start_manager();
//get_devices();
}
socket_di.onmessage = function got_packet(msg) {
//document.getElementById("status").classList.remove("error");
//console.log(msg.data);
var data
try {
data = JSON.parse(msg.data);
}
catch (error) {
console.error(error);
console.log(msg.data);
}
if (data.logmsg) {
update_log_message(data.logmsg);
} else if (data.na_message) {
set_unavailable(data.na_message);
} else if (data.message) {
update_status_message(data.message);
} else if (data.type == 'aqmanager') {
setAqManagerOptions(data);
//update_status(data);
} else if (data.type == 'devices') {
//update_device(data);
} else if (data.type == 'status') {
update_status(data);
} else if (data.type == 'aux_labels') {
//set_labels(data);
2025-01-28 23:45:53 +00:00
} else if (data.type == 'config') {
showConfig(data);
2023-06-23 20:16:30 +00:00
}
}
socket_di.onclose = function () {
// something went wrong
//document.getElementById("status").innerHTML = ' !!! Connection error !!! '
//document.getElementById("status").classList.add("error");
// Try to reconnect every 5 seconds.
update_status_message(' !!! Connection error !!! ', true);
setTimeout(function () {
startWebsockets();
}, 5000);
}
} catch (exception) {
alert('<p>Error' + exception);
}
}
function send_command(cmd) {
2025-01-28 23:45:53 +00:00
//console.log("Send " + JSON.stringify(cmd));
2023-06-23 20:16:30 +00:00
socket_di.send(JSON.stringify(cmd));
}
function start_manager() {
var msg = {
//command: "simulator"
uri: "aqmanager"
};
socket_di.send(JSON.stringify(msg));
}
function get_devices() {
var msg = {
uri: "devices"
};
socket_di.send(JSON.stringify(msg));
}
/*
function reset() {
socket_di.send("reset\n");
}
*/
function init() {
startWebsockets();
2024-06-10 22:27:01 +00:00
getLatestVersion();
2023-06-23 20:16:30 +00:00
}
function set_unavailable(message) {
2024-06-10 22:27:01 +00:00
2023-06-23 20:16:30 +00:00
console.log("!!! NOT Available !!!");
2024-06-10 22:27:01 +00:00
update_log_message("!!! AqualinkD Manager " + message + " !!!");
2023-06-23 20:16:30 +00:00
const demoClasses = document.querySelectorAll('.inner');
demoClasses.forEach(element => {
element.style.opacity = 0.2;
2024-06-10 22:27:01 +00:00
console.log('Element ' + element);
2023-06-23 20:16:30 +00:00
});
disablebutton("restart");
disablebutton("seriallog");
disablebutton("downloadlog");
2023-07-08 16:14:44 +00:00
//disabletoggle("logfile");
2023-06-23 20:16:30 +00:00
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
// Remove event listeners from Element by cloning it.
coll[i].replaceWith(coll[i].cloneNode(true));
}
//disabletoggle("seriallog");
}
function send(source) {
//console.log("from" + source.id);
var cmd = {};
//cmd.uri = "rawcommand"
switch (source.id) {
case "restart":
cmd.uri = "restart"
// NEED TO REGET aqmanager after restart.
break;
case "debugstart":
cmd.uri = "debug/start"
break;
case "debugstop":
cmd.uri = "debug/stop"
break;
case "seriallog":
cmd.uri = "seriallogger"
break;
2024-08-25 23:31:58 +00:00
case "seriallogWoptions":
var ids = document.getElementById("slog_ids").value;
if ( ids.length == 0 )
ids='--';
cmd.uri = "seriallogger/"+ids+"/"+document.getElementById("slog_debug").checked;
cmd.value = document.getElementById("slog_packets").value
2024-08-31 23:01:12 +00:00
//console.log("Command = "+cmd);
2024-08-25 23:31:58 +00:00
//console.log("Packets=" + document.getElementById("slog_packets").value );
//console.log("IDs=" + document.getElementById("slog_ids").value );
//console.log("ListQueriedID=" + document.getElementById("slog_ids_queried").checked );
//console.log("debug=" + document.getElementById("slog_debug").checked );
//return; // REMOVE
break;
2023-06-23 20:16:30 +00:00
default:
alert("Unknown button");
return;
break;
}
send_command(cmd);
}
2024-06-10 22:27:01 +00:00
function getLatestVersion() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var JS = JSON.parse(this.responseText);
_latestVersionAvailable = JS.tag_name.replace(/[^\d.-]/g, '');
document.getElementById("latestaqualinkdversion").innerHTML = _latestVersionAvailable;
}
};
xmlhttp.open("GET", "https://api.github.com/repos/sfeakes/AqualinkD/releases/latest", true);
xmlhttp.send();
}
2023-06-23 20:16:30 +00:00
</script>
<body onload="init();init_collapsible();">
<div class="wrapper">
2025-01-28 23:45:53 +00:00
2023-06-23 20:16:30 +00:00
<div class="aqualinkd">
<iframe id="aqd" src="/" width="100%" height="350px"></iframe>
</div>
<div class="inner">
<div class="commands">
<table border='0' id="deviceList">
<tr style="title">
<td colspan="2" style="title" align="center"><label id="title">&nbsp;&nbsp;AqualinkD Managment
Console&nbsp;&nbsp;</label></th>
</tr>
<tr>
2024-06-10 22:27:01 +00:00
<td colspan="2" align="center"><label id="statusmsg" class="statusmsg">status</label></td>
2023-06-23 20:16:30 +00:00
</tr>
2024-08-25 23:31:58 +00:00
<tr>
<td colspan="2" align="center"><input id="restart" type="button" onclick="send(this);" value="Restart AqualinkD"></td>
</tr>
<!--
2023-06-23 20:16:30 +00:00
<tr>
<td align="center">
<input id="restart" type="button" onclick="send(this);" value="Restart AqualinkD">
</td>
<td>
<input id="seriallog" type="button" onclick="send(this);" value="Run Serial Logger">
</td>
</tr>
2024-08-25 23:31:58 +00:00
-->
2023-06-23 20:16:30 +00:00
</table>
<button class="collapsible" id="systembutton">System Information</button>
<div class="content" id="system">
<table border='0'>
<tr>
<td>AqualinkD version:</td>
<td id="aqualinkdversion"></td>
</tr>
2024-06-10 22:27:01 +00:00
<tr id="latesversionavailable">
<td>Latest version:</td>
<td id="latestaqualinkdversion"></td>
</tr>
2023-06-23 20:16:30 +00:00
<tr>
<td>Panel version:</td>
<td id="panelversion"></td>
</tr>
<tr>
<td>Panel type:</td>
<td id="paneltype"></td>
</tr>
</table>
</div>
<!--&nbsp;-->
<button class="collapsible">Log Levels</button>
<div class="content" id="loglevels">
<!-- Will be populated on load -->
</div>
<button class="collapsible">Log File</button>
2024-08-25 23:31:58 +00:00
<div class="content" id="logfile">
2023-06-24 00:38:59 +00:00
<!--
2023-07-08 16:14:44 +00:00
<label class="toggle logtoggle"><input class="toggle-checkbox" type="checkbox" id="logfile"
2023-06-23 20:16:30 +00:00
onclick="setlogfile(this);">
<div class="toggle-switch"></div><span class="toggle-label">Log to file</span>
</label>
2023-06-24 00:38:59 +00:00
-->
2024-06-10 22:27:01 +00:00
<table border='0'>
<tr>
<td>
<input id="downloadlog" type="button" onclick="setlogfile(this);"
value="Download logfile"></input>
</td>
<td>
<input id="logsize" type="text" value="1000" size="5">#lines</input>
</td>
</tr>
</table>
2023-06-23 20:16:30 +00:00
</div>
<!--&nbsp;-->
<button class="collapsible">Debug Masks</button>
<div class="debugmasks content" id="debugmasks">
<!-- Will be populated on load -->
</div>
2024-08-25 23:31:58 +00:00
<button class="collapsible">Serial Logger</button>
<div class="content" id="seriallogger">
<table border='0'>
<tr>
<td colspan="2" align="center"><input id="seriallogWoptions" type="button" onclick="send(this);" value="Run Serial Logger"></td>
</tr>
<tr>
<td>#Packets</td>
<td><input id="slog_packets" type="text" value="800" size="5"></input></td>
</tr>
<tr>
<td>ID's <font size="-2">(Eg 0x08 0x10)</font></td>
<td><input id="slog_ids" type="text" value="" size="15"></input></td>
</tr>
<tr>
<td>Debug</td>
2024-08-31 23:01:12 +00:00
<td><input id="slog_debug" type="checkbox" onclick="checkboxClick(this)"></input></td>
2024-08-25 23:31:58 +00:00
</tr>
<tr>
<td colspan="2" align="center">AqualinkD will be disabled while running</td>
</tr>
</table>
</div>
2023-06-23 20:16:30 +00:00
<button class="collapsible">Config</button>
<div class="content" id="config">
2025-01-28 23:45:53 +00:00
<table border='0'>
<tr>
<td align="center">
<input id="editconfig" type="button" onclick="editconfig(this);"
value="edit config"></input>
</td>
</tr>
</table>
2023-06-23 20:16:30 +00:00
</div>
</div>
</div>
<div class="inner">
<div class="logcontainer" id="logs">
<!--<div class="inner">END</div>-->
</div>
</div>
2025-01-28 23:45:53 +00:00
<!-- <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>
2025-03-09 22:39:41 +00:00
<td align="center" colspan="3">
<label>
<input class="toggle-checkbox" type="checkbox" id="show_advanced" onclick="resetConfig(this);">
<div class="toggle-switch"></div>
<span class="toggle-label">Show&nbsp;Advanced&nbsp;Options</span>
</label>
</td>
<!--
2025-01-28 23:45:53 +00:00
<td align="right" width="50%">
Key
</td>
<td align="left" width="50%">
Value
</td>
2025-03-09 22:39:41 +00:00
-->
2025-01-28 23:45:53 +00:00
</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>
2024-06-10 22:27:01 +00:00
<!--<iframe src='about:blank' id="logdownload"></iframe>-->
2023-06-23 20:16:30 +00:00
</div>
</body>
</html>