1737 lines
53 KiB
HTML
1737 lines
53 KiB
HTML
<!--
|
|
Written By: Robert Zmrzli robert@zmrinc.com
|
|
my_devices.html
|
|
Ver 2.32
|
|
-->
|
|
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>WellPlugs Administrator</title>
|
|
<style>
|
|
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
}
|
|
div.helper {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0px;
|
|
}
|
|
.full-height {
|
|
height: 80%;
|
|
}
|
|
input[type="text"] {
|
|
font-size: 12px;
|
|
}
|
|
select.devs_in_depl {
|
|
width: 100px;
|
|
}
|
|
/*IE FIX */
|
|
select#devs_in_depl {
|
|
width: 100px;
|
|
}
|
|
select:focus#devs_in_depl {
|
|
width: 100px\9;
|
|
}
|
|
.small-button {
|
|
border: none;
|
|
color: white;
|
|
padding: 1px 1px;
|
|
text-align: center;
|
|
display: inline-block;
|
|
font-size: 12px;
|
|
margin: 1px 1px;
|
|
cursor: pointer;
|
|
background-color: #00A000;
|
|
height: 24px;
|
|
width: 100px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 2px #999;
|
|
}
|
|
.small-button:hover {
|
|
background-color: #808080;
|
|
font-color: #0000ff
|
|
}
|
|
.small-button:active {
|
|
background-color: #00ff00;
|
|
box-shadow: 0 4px #666;
|
|
transform: translateY(2px);
|
|
}
|
|
.wider-button {
|
|
border: none;
|
|
color: white;
|
|
padding: 1px 1px;
|
|
text-align: center;
|
|
display: inline-block;
|
|
font-size: 12px;
|
|
margin: 1px 1px;
|
|
cursor: pointer;
|
|
background-color: #00A000;
|
|
height: 24px;
|
|
width: 80px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 2px #999;
|
|
}
|
|
.container {
|
|
display: flex;
|
|
height: 360px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.box {
|
|
margin: 10px;
|
|
}
|
|
|
|
.table-container {
|
|
position: relative;
|
|
height: calc(100vh - 670px); /* Subtract top panel + boxes + margins */
|
|
min-height: 200px;
|
|
overflow: auto;
|
|
border: 1px solid #ddd;
|
|
}
|
|
|
|
.table-header {
|
|
position: sticky;
|
|
top: 0;
|
|
background-color: white;
|
|
z-index: 1;
|
|
}
|
|
|
|
.table-body {
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
#devices {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
#devices th, #devices td {
|
|
padding: 8px;
|
|
border: 1px solid #ddd;
|
|
}
|
|
|
|
.x_panel {
|
|
position: relative;
|
|
width: 100%;
|
|
margin-bottom: 10px;
|
|
padding: 10px;
|
|
background: #fff;
|
|
border: 1px solid #E6E9ED;
|
|
}
|
|
|
|
/* Bottom panel takes remaining space */
|
|
.row:last-child .x_panel {
|
|
/* Calculate height as viewport height minus top margin and approximate top panel height */
|
|
height: calc(100vh - 180px);
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Adjust the content area inside bottom panel */
|
|
.x_panel:last-child .x_content {
|
|
height: calc(100% - 50px); /* Subtract header height */
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Remove any height settings from other elements */
|
|
.x_content {
|
|
padding: 0 5px;
|
|
}
|
|
|
|
/* Ensure the form in the top panel stays compact */
|
|
#selectorsDiv {
|
|
padding: 10px 0;
|
|
}
|
|
|
|
#devices tbody {
|
|
/* Ensure tbody can scroll */
|
|
overflow: auto;
|
|
}
|
|
|
|
#devices th {
|
|
background-color: #f8f8f8;
|
|
}
|
|
|
|
/* Ensure inputs and content align properly */
|
|
#devices td input[type="text"] {
|
|
width: 90%;
|
|
border: none;
|
|
text-align: center;
|
|
background: transparent;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* Add some spacing for the scrollbar */
|
|
.table-container::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
.table-container::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
}
|
|
|
|
.table-container::-webkit-scrollbar-thumb {
|
|
background: #888;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.table-container::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
|
|
/* Adjust table container position and height */
|
|
#devslist {
|
|
position: relative;
|
|
width: 100%;
|
|
}
|
|
|
|
.wrapper {
|
|
position: relative;
|
|
height: auto;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
.spinner {
|
|
display: inline-block;
|
|
width: 20px;
|
|
height: 20px;
|
|
border: 3px solid rgba(0,0,0,.3);
|
|
border-radius: 50%;
|
|
border-top-color: #000;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
</style>
|
|
<meta charset="UTF-8" />
|
|
<!--[if lt IE 9]>
|
|
<script src="http://bellacon.com/js/src/excanvas/excanvas_text.js"></script>
|
|
<script src="http://bellacon.com/js/src/excanvas/canvas.text.js"></script>
|
|
<![endif]-->
|
|
|
|
<script src= 'https://eluxnetworks.net/js/src/teechart.js'; type="text/javascript"></script>
|
|
<script
|
|
src='https://eluxnetworks.net/js/src/teechart-extras.js'
|
|
type="text/javascript"
|
|
></script>
|
|
<script src= 'https://eluxnetworks.net/js/src/jquery-2.1.3.js' type="text/javascript"></script>
|
|
<script src='https://eluxnetworks.net/js/src/demo.js' type="text/javascript"></script>
|
|
<!-- Bootstrap -->
|
|
<link
|
|
href = 'https://eluxnetworks.net/js/3rd_party/bootstrap/dist/css/bootstrap.min.css'
|
|
rel="stylesheet"
|
|
/>
|
|
<!-- Font Awesome -->
|
|
<link
|
|
href='https://eluxnetworks.net/js/3rd_party/font-awesome-4.6.3/css/font-awesome.min.css'
|
|
rel="stylesheet"
|
|
/>
|
|
<!-- NProgress -->
|
|
<!-- Custom Theme Style -->
|
|
<link href='https://eluxnetworks.net/js/3rd_party/build/css/custom.min.css' rel='stylesheet' />
|
|
<link rel="stylesheet" type="text/css" href='https://eluxnetworks.net/js/src/demo.css' />
|
|
<script src='https://eluxnetworks.net/js/src/date.format.js' type="text/javascript"></script>
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
|
/>
|
|
<script
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js"
|
|
type="text/javascript"
|
|
></script>
|
|
<script src="https://cdn.jsdelivr.net/pako/1.0.3/pako.min.js"></script>
|
|
<script type="text/javascript">
|
|
var MAXESChart;
|
|
var AsChart;
|
|
var sensed_value_glob = 0;
|
|
var tim_value_glob = 0;
|
|
var chart_index_glob = 0;
|
|
var MAX_POINTS = 3600;
|
|
var start_time = Date.now();
|
|
var GLOB_HEIGHT = "100";
|
|
var fresh = true;
|
|
var secs_in_day = 86400;
|
|
var signature = "my_devices.htm" + start_time.toString();
|
|
|
|
var token = localStorage.getItem('token') || '0';
|
|
var user_name = localStorage.getItem('user_name') || '';
|
|
var user_id = localStorage.getItem('user_id') || '0';
|
|
var key = localStorage.getItem('key') || '0';
|
|
var client = "";
|
|
|
|
var Indexes = {
|
|
Maximums_RAW_max_val: 0,
|
|
Maximums_RAW_a: 1,
|
|
Maximums_RAW_b: 2,
|
|
Maximums_RAW_c: 3,
|
|
};
|
|
|
|
const baseURL = window.location.origin;
|
|
const api_url = `${baseURL}/function/well-api`;
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initializePage);
|
|
} else {
|
|
initializePage();
|
|
}
|
|
|
|
function initializePage() {
|
|
window.draw = function() {
|
|
console.log("Initializing...");
|
|
try {
|
|
ShowDeployment(false);
|
|
DeploymentChange();
|
|
SelDesel();
|
|
MAXESChart = new Tee.Chart("canvas1");
|
|
privileges = localStorage.getItem('privileges');
|
|
console.log(privileges);
|
|
if (parseInt(privileges) >0) {
|
|
document.getElementById("WELL_ID").readOnly = true;
|
|
//document.getElementById("GroupPanel").style.display = 'none';
|
|
document.getElementById("details1").style.display = 'none';
|
|
//document.getElementById("single_info").style.left = '440px';
|
|
//document.getElementById("deployment_info").style.left = '960px';
|
|
//document.getElementById("deployment_info1").style.left = '870px';
|
|
}
|
|
else {
|
|
document.getElementById("WELL_ID").readOnly = false;
|
|
//document.getElementById("GroupPanel").style.visibility = 'visible';
|
|
document.getElementById("details1").style.display = 'visible';
|
|
//document.getElementById("single_info").style.left = '540px';
|
|
//document.getElementById("deployment_info").style.left = '1160px';
|
|
//document.getElementById("deployment_info1").style.left = '1260px';
|
|
}
|
|
ConnectMQTT();
|
|
resize();
|
|
} catch(err) {
|
|
console.error("Error in draw function:", err);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function sendToBackend(topicl, send_what) {
|
|
// Once a connection has been made, make a subscription and send a message.
|
|
console.log("sendToBackend "+topicl+":" + send_what);
|
|
|
|
if (topicl.substr(topicl.length - 4) == "_cmp") {
|
|
//var djson = new TextDecoder("utf-8").encode(send_what);
|
|
var compressedJSON = pako.deflate(send_what);
|
|
//var message.payloadBytes= compressedJSON;
|
|
message = new Paho.MQTT.Message(compressedJSON);
|
|
message.destinationName = topicl;
|
|
}
|
|
else {
|
|
message = new Paho.MQTT.Message(send_what);
|
|
message.destinationName = topicl;
|
|
}
|
|
client.send(message);
|
|
}
|
|
|
|
async function RequestFilteredDevices(group_id, deployment_id, location, is_fresh) {
|
|
|
|
const formData = new URLSearchParams();
|
|
formData.append('function', "request_devices");
|
|
formData.append('token', token);
|
|
formData.append('user_name', user_name);
|
|
formData.append('group_id', group_id);
|
|
formData.append('deployment_id', deployment_id);
|
|
formData.append('location', location);
|
|
formData.append('fresh', is_fresh);
|
|
|
|
data = await SubmitForm(formData);
|
|
if (data.status !== "200 OK") {
|
|
alert('Bad response from API!');
|
|
return;
|
|
|
|
}
|
|
|
|
matching_devices = data["devices"];
|
|
|
|
var doc = document;
|
|
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
for (var i = rowCount - 1; i > 0; i--) {
|
|
table.deleteRow(i);
|
|
}
|
|
let topics = [];
|
|
now_time = parseInt(Date.now()/1000);
|
|
|
|
for (i = 0; i < matching_devices.length; i++) {
|
|
|
|
age = now_time - matching_devices[i][3];
|
|
var tr = doc.createElement("tr");
|
|
if (age < 300)
|
|
tr.style.backgroundColor = "#90FFD7";
|
|
else
|
|
tr.style.backgroundColor = "";
|
|
|
|
// <th scope="row">568</th>
|
|
// <td style="text-align:center">283</td>
|
|
// <td style="text-align:center"><a href="google.com">64B70888F8C0</a></td>
|
|
// <td style="text-align:center">1722361900</td>
|
|
// <td style="text-align:center">?</td>
|
|
// <td style="text-align:center">None</td>
|
|
// <td style="text-align:center"><a href="#" onclick="OpenDeployment('23')" title="Daisy Nguyen">23</a></td>
|
|
// <td style="text-align:center"><input type="checkbox" onchange="IsItSingle();"></td>
|
|
|
|
|
|
var th = doc.createElement("th");
|
|
th.scope = "row";
|
|
th.style="text-align:center";
|
|
th.innerHTML = matching_devices[i][0];
|
|
tr.appendChild(th);
|
|
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
td.innerHTML = matching_devices[i][1];
|
|
tr.appendChild(td);
|
|
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
mac = matching_devices[i][2];
|
|
//cell_content = "<a href=\"/?user_id="+user_id+"&user_id="+user_id+"&token="+token+"&MAC="+mac+"\" target=\"_blank\">"+mac+"</a>"
|
|
cell_content = '<a href="#" onclick="OpenDevice(\''+mac+'\')">'+mac+'</a>';
|
|
topics.push("/"+mac)
|
|
//console.log(td.outerHTML);
|
|
//http://192.168.1.22:5002/?user=john&key=mykey&MAC=716798E056AC
|
|
td.innerHTML = cell_content;
|
|
tr.appendChild(td);
|
|
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
if (matching_devices[i][3] == 0){
|
|
age_string = "No data";
|
|
}
|
|
else {
|
|
age_string = ShowAge(age);
|
|
}
|
|
|
|
td.innerHTML = age_string;
|
|
tr.appendChild(td);
|
|
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
td.innerHTML = matching_devices[i][4];
|
|
tr.appendChild(td);
|
|
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
if( matching_devices[i][5] == "All") {
|
|
td.innerHTML = "";
|
|
}
|
|
else {
|
|
td.innerHTML = matching_devices[i][5];
|
|
}
|
|
tr.appendChild(td);
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
cell_content = '<a href="#" onclick="OpenDeployment(\''+matching_devices[i][6]+'\')">'+matching_devices[i][6]+'</a>';
|
|
td.innerHTML = cell_content;
|
|
tr.appendChild(td);
|
|
|
|
var ch = doc.createElement("input");
|
|
ch.type = "checkbox";
|
|
ch.onchange=function(){IsItSingle();};
|
|
var td = doc.createElement("td");
|
|
td.style="text-align:center";
|
|
td.appendChild(ch);
|
|
tr.appendChild(td);
|
|
table.appendChild(tr);
|
|
// <td style="text-align:center"><input type="checkbox" onchange="IsItSingle();"></td>
|
|
|
|
}
|
|
IsItSingle();
|
|
qos = 1;
|
|
if (client !=""){
|
|
// Subscribe to each topic individually
|
|
for (let i = 0; i < topics.length; i++) {
|
|
try {
|
|
client.subscribe(topics[i], {qos: qos});
|
|
console.log(`Subscribed to ${topics[i]} with QoS: ${qos}`);
|
|
} catch (error) {
|
|
console.error(`Error subscribing to ${topics[i]}:`, error);
|
|
}
|
|
}
|
|
}
|
|
//doc.getElementById("here_table").appendChild(table);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function SubmitForm(formData) {
|
|
|
|
console.log(formData.toString());
|
|
const response = await fetch(api_url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
},
|
|
mode: 'cors',
|
|
body: formData.toString()
|
|
});
|
|
|
|
if (response.ok) {
|
|
const text = await response.text();
|
|
console.log(text);
|
|
if(text.includes("Log-Out")) {
|
|
LogOut();
|
|
}
|
|
else {
|
|
try {
|
|
data = JSON.parse(text);
|
|
return data;
|
|
}
|
|
catch {
|
|
data = {
|
|
ok: 0
|
|
}
|
|
return data;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
//console.log(await response.json());
|
|
data = {
|
|
ok: 0
|
|
}
|
|
return data;
|
|
}
|
|
}
|
|
|
|
async function RequestDeploymentProximity(deployment_id, time) {
|
|
|
|
const formData = new URLSearchParams();
|
|
formData.append('function', "request_proximity");
|
|
formData.append('token', token);
|
|
formData.append('user_name', user_name);
|
|
formData.append('time', time);
|
|
formData.append('deployment_id', deployment_id);
|
|
|
|
data = await SubmitForm(formData);
|
|
if (data.status !== "200 OK") {
|
|
alert('Bad response from API!');
|
|
return;
|
|
|
|
}
|
|
//return;
|
|
|
|
well_ids = data["proximity"];
|
|
if (well_ids.length > 0) {
|
|
SetOptions('Proximity', well_ids);
|
|
}
|
|
}
|
|
|
|
function CopyDeploymentProximity() {
|
|
|
|
$("#Proximity").empty();
|
|
var oldSel = $("#Proximity").get(0);
|
|
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
for (var i = 1; i < rowCount; i++) {
|
|
cell = table.rows[i].cells[0];
|
|
if(cell.innerText.length > 0) {
|
|
|
|
var opt = document.createElement('option');
|
|
opt.text = cell.innerText;
|
|
opt.value = cell.innerText;
|
|
oldSel.add(opt, null);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
function WriteDeploymentProximity() {
|
|
// timee = Date.now();
|
|
// //user = document.getElementById("user").value;
|
|
// key = document.getElementById("ps").value;
|
|
// deployment = document.getElementById("Deployments").value;
|
|
// proximity_string = "";
|
|
// var proximity_list = $("#Proximity").get(0);
|
|
|
|
|
|
// if(proximity_list.length > 0){
|
|
// proximity_string = proximity_list[0].innerText;
|
|
// for (i = 1; i < proximity_list.length; i++)
|
|
// {
|
|
// proximity_string = proximity_string +","+proximity_list[i].innerText;
|
|
// }
|
|
|
|
// }
|
|
|
|
// var obj = {
|
|
// function: "write_proximity",
|
|
// deployment: deployment,
|
|
// proximity_string: proximity_string,
|
|
// time:timee,
|
|
// user_name:user_name,
|
|
// ps:key,
|
|
// signature:signature
|
|
// };
|
|
// var json = JSON.stringify(obj);
|
|
// sendToBackend("/wellget_cmp", json);
|
|
}
|
|
|
|
function RequestFWsUpdate(device_settings) {
|
|
// timee = Date.now();
|
|
// user = document.getElementById("user").value;
|
|
// key = document.getElementById("ps").value;
|
|
// group = document.getElementById("group_id").value;
|
|
// deployment = document.getElementById("Deployments").value;
|
|
// locationn = document.getElementById("Locations").value;
|
|
// //lets prevent FW updates to devices lower than 200
|
|
// var table = document.getElementById("devices");
|
|
// var rowCount = table.rows.length;
|
|
// //If all are enabled, request group update, othervise request d
|
|
// which_tags = [];
|
|
// all_selected = true;
|
|
// for (var i = 1; i < rowCount; i++) {
|
|
|
|
// cell = table.rows[i].cells[8];
|
|
// checkm = cell.children[0];
|
|
// if (checkm.checked) {
|
|
// cell = table.rows[i].cells[0];
|
|
// device_id = parseInt(cell.innerText);
|
|
// if (device_id >= 200){ //Prevent updates to older devices
|
|
// MAC = table.rows[i].cells[1].innerText;
|
|
// //FW = table.rows[i].cells[3].childNodes[0].data;
|
|
// var tag_info = MAC;
|
|
// which_tags.push(tag_info);
|
|
// }
|
|
// }
|
|
// else {
|
|
// all_selected = false;
|
|
// }
|
|
// }
|
|
|
|
// var obj = {
|
|
// function: "update_fws",
|
|
// group: group,
|
|
// deployment: deployment,
|
|
// location: locationn,
|
|
// time:timee,
|
|
// user:user,
|
|
// ps:key,
|
|
// signature:signature,
|
|
// device_settings:device_settings,
|
|
// which_tags: which_tags,
|
|
// all_selected:all_selected
|
|
// };
|
|
|
|
// var json = JSON.stringify(obj);
|
|
// sendToBackend("/wellget_cmp", json);
|
|
}
|
|
|
|
|
|
function RequestDevsUpdate(device_settings) {
|
|
// timee = Date.now();
|
|
// user = document.getElementById("user").value;
|
|
// key = document.getElementById("ps").value;
|
|
// group = document.getElementById("group_id").value;
|
|
// deployment = document.getElementById("Deployments").value;
|
|
// locationn = document.getElementById("Locations").value;
|
|
|
|
// var table = document.getElementById("devices");
|
|
// var rowCount = table.rows.length;
|
|
// //If all are enabled, request group update, othervise request d
|
|
// which_tags = [];
|
|
// all_selected = true;
|
|
// for (var i = 1; i < rowCount; i++) {
|
|
// cell = table.rows[i].cells[8];
|
|
// checkm = cell.children[0];
|
|
// if (checkm.checked) {
|
|
// MAC = table.rows[i].cells[1].innerText;
|
|
// //FW = table.rows[i].cells[3].childNodes[0].data;
|
|
// var tag_info = MAC;
|
|
// which_tags.push(tag_info);
|
|
// }
|
|
// else {
|
|
// all_selected = false;
|
|
// };
|
|
// }
|
|
|
|
// var obj = {
|
|
// function: "update_devices",
|
|
// group: group,
|
|
// deployment: deployment,
|
|
// location: locationn,
|
|
// time:timee,
|
|
// user:user,
|
|
// ps:key,
|
|
// signature:signature,
|
|
// device_settings:device_settings,
|
|
// which_tags: which_tags,
|
|
// all_selected:all_selected
|
|
// };
|
|
|
|
// var json = JSON.stringify(obj);
|
|
// sendToBackend("/wellget_cmp", json);
|
|
}
|
|
|
|
async function DoRefresh() {
|
|
//Lets determine db_file,from_time, to_time from selected options
|
|
|
|
btn = document.getElementById("set_device_s");
|
|
|
|
group_id = document.getElementById("group_id").value;
|
|
deployment_id = document.getElementById("Deployments").value;
|
|
locations = document.getElementById("Locations").value;
|
|
|
|
RequestFilteredDevices(group_id, deployment_id, locations, fresh);
|
|
}
|
|
|
|
function ShowDeployment(do_show) {
|
|
var x = document.getElementById("deployment_info");
|
|
var x1 = document.getElementById("deployment_info1");
|
|
|
|
if (do_show == true) {
|
|
x.style.display = "block";
|
|
x1.style.display = "block";
|
|
} else {
|
|
x.style.display = "none";
|
|
x1.style.display = "none";
|
|
}
|
|
}
|
|
|
|
|
|
function DeploymentChange() {
|
|
deployment = document.getElementById("Deployments").value;
|
|
if(deployment == "0" || deployment == "-1" || deployment == "All" || deployment == "") {
|
|
ShowDeployment(false);
|
|
}
|
|
else {
|
|
ShowDeployment(true);
|
|
time = new Date().getTime();
|
|
RequestDeploymentProximity(deployment, time);
|
|
}
|
|
|
|
}
|
|
|
|
function resize() {
|
|
var body = document.body;
|
|
var count = 0;
|
|
//h = Math.min( window.innerHeight, document.body.clientHeight )
|
|
h = window.innerHeight;
|
|
try {
|
|
if (MAXESChart.canvas.clientHeight > 0) count = count + 1;
|
|
if (AsChart.canvas.clientHeight > 0) count = count + 1;
|
|
} catch (err) {
|
|
count = 3;
|
|
}
|
|
|
|
//var devlist = document.getElementById("devslist");
|
|
//devlist.offsetHeight = 50;
|
|
|
|
//how many are visible
|
|
|
|
GLOB_HEIGHT = (h - 2 * 100) / count;
|
|
|
|
//var devs_table = document.getElementById("devslist");
|
|
//devs_table.height = 100%;
|
|
|
|
try {
|
|
MAXESChart.canvas.height = 100;//GLOB_HEIGHT;
|
|
|
|
MAXESChart.canvas.width = body.clientWidth;
|
|
|
|
MAXESChart.bounds.width = MAXESChart.canvas.width - 100;
|
|
MAXESChart.bounds.height = MAXESChart.canvas.height;
|
|
//changeTheme(MAXESChart, "minimal");
|
|
//changeTheme(AsChart, "minimal");
|
|
} catch (err) {}
|
|
}
|
|
|
|
function GraphUpdate(which_Graph, tim_value, sensed_value, series_index) {
|
|
//sensed_value_glob =
|
|
function newData(now) {
|
|
if (!now) now = new Date().getTime();
|
|
}
|
|
if (document.getElementById("live-check").checked == false) {
|
|
which_Graph = "";
|
|
}
|
|
switch (which_Graph) {
|
|
case "PressuresChart":
|
|
chart_index_glob = 0;
|
|
|
|
series = PressuresChart.series.items[series_index];
|
|
|
|
var d = series.data.values,
|
|
x = series.data.x,
|
|
t,
|
|
l = d.length;
|
|
|
|
d[l] = sensed_value;
|
|
x[l] = 1000 * tim_value;
|
|
|
|
if (l > MAX_POINTS) {
|
|
d.shift();
|
|
x.shift();
|
|
}
|
|
|
|
changeTheme(PressuresChart, "minimal");
|
|
PressuresChart.draw();
|
|
requestAnimFrame(newData, PressuresChart, 1);
|
|
|
|
break;
|
|
case "TemperaturesChart":
|
|
chart_index_glob = 2;
|
|
series = TemperaturesChart.series.items[series_index];
|
|
|
|
var d = series.data.values,
|
|
x = series.data.x,
|
|
t,
|
|
l = d.length;
|
|
|
|
d[l] = sensed_value;
|
|
x[l] = 1000 * tim_value;
|
|
|
|
if (l > MAX_POINTS) {
|
|
d.shift();
|
|
x.shift();
|
|
}
|
|
|
|
changeTheme(TemperaturesChart, "minimal");
|
|
TemperaturesChart.draw();
|
|
requestAnimFrame(newData, TemperaturesChart, 1);
|
|
break;
|
|
case "AirQualsChart":
|
|
chart_index_glob = 1;
|
|
series = AirQualsChart.series.items[series_index];
|
|
|
|
var d = series.data.values,
|
|
x = series.data.x,
|
|
t,
|
|
l = d.length;
|
|
|
|
d[l] = sensed_value;
|
|
x[l] = 1000 * tim_value;
|
|
|
|
if (l > MAX_POINTS) {
|
|
d.shift();
|
|
x.shift();
|
|
}
|
|
|
|
changeTheme(AirQualsChart, "minimal");
|
|
AirQualsChart.draw();
|
|
requestAnimFrame(newData, AirQualsChart, 1);
|
|
break;
|
|
case "HumidChart":
|
|
chart_index_glob = 3;
|
|
series = HumidChart.series.items[series_index];
|
|
|
|
var d = series.data.values,
|
|
x = series.data.x,
|
|
t,
|
|
l = d.length;
|
|
|
|
d[l] = sensed_value;
|
|
x[l] = 1000 * tim_value;
|
|
|
|
if (l > MAX_POINTS) {
|
|
d.shift();
|
|
x.shift();
|
|
}
|
|
|
|
changeTheme(HumidChart, "minimal");
|
|
//HumidChart.draw();
|
|
requestAnimFrame(newData, HumidChart, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
function showTutorial(name) {
|
|
document.myform.stage.value = name;
|
|
}
|
|
|
|
function ConnectMQTT() {
|
|
// Configure host and port correctly for WSS
|
|
const hostname = "mqtt.eluxnetworks.net";
|
|
const port = 443; // Use standard HTTPS port for Traefik
|
|
const topic = "/wellget"; // You need to define the topic, it was missing
|
|
|
|
console.log(`Connecting to: ${hostname} on port ${port} using WebSocket`);
|
|
|
|
// Create a client instance with the working path
|
|
client = new Paho.MQTT.Client(
|
|
hostname,
|
|
port,
|
|
"/wss", // Updated to use the working WebSocket path
|
|
signature // Your client ID
|
|
);
|
|
|
|
// Set callback handlers
|
|
client.onConnectionLost = onConnectionLost;
|
|
client.onMessageArrived = onMessageArrived;
|
|
|
|
// Connection options - removing any invalid properties
|
|
const options = {
|
|
useSSL: true, // Always use SSL since we're connecting through Traefik on HTTPS
|
|
userName: user_name,
|
|
password: key,
|
|
onSuccess: onConnect,
|
|
onFailure: function(err) {
|
|
console.log("Connection failed: " + err.errorMessage);
|
|
// Explicit reconnect with exponential backoff
|
|
setTimeout(function() {
|
|
console.log("Attempting to reconnect...");
|
|
client.connect(options);
|
|
}, 2000); // Wait 2 seconds before reconnecting
|
|
},
|
|
keepAliveInterval: 30
|
|
};
|
|
|
|
// Called when the client connects
|
|
function onConnect() {
|
|
console.log("onConnect");
|
|
|
|
let message = new Paho.MQTT.Message("Hello");
|
|
message.destinationName = topic;
|
|
client.send(message);
|
|
|
|
var from_time = 0; // Dummy, not used with "latest"
|
|
var to_time = 0;
|
|
db_file = "latest";
|
|
if (fresh == true) {
|
|
// Request only first time
|
|
groups = "0"; // Document.getElementById("group_id").value;
|
|
deployments = "0"; // Document.getElementById("Deployments").value;
|
|
locations = "0"; // Document.getElementById("Locations").value;
|
|
//RequestFilteredDevices(groups, deployments, locations, fresh);
|
|
//client.subscribe("/well_cmp" + signature); console.log("Subscribed to: /well_cmp" + signature);
|
|
|
|
fresh = false;
|
|
}
|
|
}
|
|
|
|
// Called when the client loses its connection
|
|
function onConnectionLost(responseObject) {
|
|
if (responseObject.errorCode !== 0) {
|
|
console.log("onConnectionLost:" + responseObject.errorMessage);
|
|
client.connect({
|
|
onSuccess: onConnect,
|
|
userName: user_name,
|
|
password: key,
|
|
useSSL: true // Always use SSL since we're connecting through Traefik
|
|
});
|
|
}
|
|
}
|
|
|
|
function onMessageArrived(message) {
|
|
|
|
}
|
|
|
|
// Attempt connection - only call connect ONCE
|
|
console.log("Attempting to connect to MQTT broker...");
|
|
try {
|
|
console.log(options);
|
|
client.connect(options);
|
|
} catch (err) {
|
|
console.log("Connection attempt failed:", err);
|
|
}
|
|
}
|
|
|
|
function ProcessClick(func_name) {
|
|
|
|
showTutorial("");
|
|
switch (func_name) {
|
|
|
|
case "save":
|
|
|
|
|
|
timee = Date.now();
|
|
|
|
|
|
//Lets find name of deployment
|
|
sel = document.getElementById("Deployments");
|
|
name = sel.options[sel.selectedIndex].text;
|
|
|
|
proximity_string = "";
|
|
var proximity_list = $("#Proximity").get(0);
|
|
|
|
|
|
if(proximity_list.length > 0){
|
|
proximity_string = proximity_list[0].innerText;
|
|
for (i = 1; i < proximity_list.length; i++)
|
|
{
|
|
proximity_string = proximity_string +","+proximity_list[i].innerText;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
var obj = {
|
|
function: "save_deployments",
|
|
time:timee,
|
|
user_id:user_id,
|
|
token:token,
|
|
deployments:document.getElementById("Deployments").innerHTML,
|
|
deployment:document.getElementById("Deployments").value,
|
|
deployment_name:name,
|
|
deployment_owner_id:"1",
|
|
proximity:proximity_string,
|
|
visible_to:""
|
|
};
|
|
var json = JSON.stringify(obj);
|
|
sendToBackend("/wellget_cmp", json);
|
|
|
|
}
|
|
}
|
|
|
|
function moveUp(selectId) {
|
|
var selectList = document.getElementById(selectId);
|
|
var selectOptions = selectList.getElementsByTagName('option');
|
|
for (var i = 1; i < selectOptions.length; i++) {
|
|
var opt = selectOptions[i];
|
|
if (opt.selected) {
|
|
selectList.removeChild(opt);
|
|
selectList.insertBefore(opt, selectOptions[i - 1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function moveDown(selectId) {
|
|
var selectList = document.getElementById(selectId);
|
|
var selectOptions = selectList.getElementsByTagName('option');
|
|
for (var i = selectOptions.length - 2; i >= 0; i--) {
|
|
var opt = selectOptions[i];
|
|
if (opt.selected) {
|
|
var nextOpt = selectOptions[i + 1];
|
|
opt = selectList.removeChild(opt);
|
|
nextOpt = selectList.replaceChild(opt, nextOpt);
|
|
selectList.insertBefore(nextOpt, opt);
|
|
}
|
|
}
|
|
}
|
|
|
|
function ShowAge(seconds) {
|
|
var minutes = Math.floor(seconds/60);
|
|
var hours = Math.floor(minutes/60);
|
|
var days = Math.floor(hours/24);
|
|
|
|
|
|
if(seconds >=0) {
|
|
hours = hours-(days*24);
|
|
minutes = minutes-(days*24*60)-(hours*60);
|
|
seconds = seconds-(days*24*60*60)-(hours*60*60)-(minutes*60);
|
|
if (days > 0) {
|
|
report = days.toString()+" d "+hours.toString()+" h "+minutes.toString()+" m "+parseInt(seconds).toString() +" s";
|
|
}
|
|
else if(hours > 0) {
|
|
report = hours.toString()+" h "+minutes.toString()+" m "+parseInt(seconds).toString() +" s";
|
|
}
|
|
else if(minutes > 0) {
|
|
report = minutes.toString()+" m "+parseInt(seconds).toString() +" s";
|
|
}
|
|
else{
|
|
report = parseInt(seconds).toString() +" s";
|
|
}
|
|
return(report);
|
|
}
|
|
else {
|
|
return("0 s");
|
|
}
|
|
}
|
|
|
|
function AddGroup() {
|
|
|
|
var x = document.getElementById("group_id");
|
|
var old_values = $("#group_id").children('option').map(function(i, e){
|
|
return e.value || e.innerText;
|
|
}).get();
|
|
|
|
new_element = $("#NewGroup").val();
|
|
if( $.inArray(new_element, old_values) == -1 ) {
|
|
$("#group_id").append(
|
|
"<option value='" + new_element + "'>" + new_element + "</option>"
|
|
);
|
|
$("#group_id").val(new_element);
|
|
}
|
|
else {
|
|
alert("Group already exists!");
|
|
}
|
|
}
|
|
function AddDeployment() {
|
|
|
|
var x = document.getElementById("Deployments");
|
|
var old_values = $("#Deployments").children('option').map(function(i, e){
|
|
return e.innerText;
|
|
}).get();
|
|
|
|
new_element = $("#NewDeployment").val();
|
|
|
|
if (new_element == "Change_me"){
|
|
alert("Assign new name!");
|
|
}
|
|
else {
|
|
|
|
if (new_element.length < 3){
|
|
alert("Minimum length of deployment name is 3 characters!");
|
|
}
|
|
else {
|
|
if( $.inArray(new_element, old_values) == -1 ) {
|
|
$("#Deployments").append(
|
|
"<option value='" + new_element + "'>" + new_element + "</option>"
|
|
);
|
|
$("#Deployments").val(new_element);
|
|
}
|
|
else {
|
|
alert("Deployment already exists!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function SelDesel() {
|
|
|
|
var x = document.getElementById("AllSel");
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
|
|
for (var i = 1; i < rowCount; i++) {
|
|
cell = table.rows[i].cells[7];
|
|
checkm = cell.children[0];
|
|
checkm.checked=x.checked;
|
|
}
|
|
IsItSingle();
|
|
}
|
|
|
|
function IsItSingle() {
|
|
|
|
var x = document.getElementById("AllSel");
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
var sel_count = 0;
|
|
var x = document.getElementById("caption");
|
|
for (var i = 1; i < rowCount; i++) {
|
|
cell = table.rows[i].cells[7];
|
|
MAC = table.rows[i].cells[2].innerText;
|
|
checkm = cell.children[0];
|
|
if (checkm.checked) {
|
|
sel_count +=1;
|
|
x.innerHTML = MAC;
|
|
}
|
|
if (sel_count != 1)
|
|
x.innerHTML = "Settings";
|
|
}
|
|
|
|
if (sel_count ==1)
|
|
ShowSingle(true);
|
|
else
|
|
ShowSingle(false);
|
|
}
|
|
|
|
function DeleteCreds(){
|
|
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
showTutorial("Deleting WiFi Credentials...");
|
|
//If all are enabled, request group update, othervise request d
|
|
which_tags = [];
|
|
all_selected = true;
|
|
for (var i = 1; i < rowCount; i++) {
|
|
cell = table.rows[i].cells[8];
|
|
checkm = cell.children[0];
|
|
if (checkm.checked) {
|
|
MAC = table.rows[i].cells[1].innerText;
|
|
//FW = table.rows[i].cells[4].childNodes[0].data;
|
|
var tag_info = MAC;
|
|
which_tags.push(tag_info);
|
|
}
|
|
else {
|
|
all_selected = false;
|
|
}
|
|
}
|
|
|
|
if (which_tags.length == 1) {
|
|
var obj = {
|
|
function: "erase_wifi",
|
|
time:timee,
|
|
user_id:user_id,
|
|
token:token,
|
|
which_tags: which_tags,
|
|
};
|
|
var json = JSON.stringify(obj);
|
|
sendToBackend("/wellget_cmp", json);
|
|
}
|
|
else {
|
|
alert("Only 1 device can be selected");
|
|
}
|
|
|
|
}
|
|
|
|
function ReadDevice() {
|
|
|
|
var table = document.getElementById("devices");
|
|
var rowCount = table.rows.length;
|
|
showTutorial("Reading device...");
|
|
//If all are enabled, request group update, othervise request d
|
|
which_tags = [];
|
|
all_selected = true;
|
|
for (var i = 1; i < rowCount; i++) {
|
|
cell = table.rows[i].cells[8];
|
|
checkm = cell.children[0];
|
|
if (checkm.checked) {
|
|
MAC = table.rows[i].cells[1].innerText;
|
|
//FW = table.rows[i].cells[4].childNodes[0].data;
|
|
var tag_info = MAC;
|
|
which_tags.push(tag_info);
|
|
}
|
|
else {
|
|
all_selected = false;
|
|
}
|
|
}
|
|
|
|
if (which_tags.length == 1) {
|
|
var obj = {
|
|
function: "read_device",
|
|
time:timee,
|
|
user_id:user_id,
|
|
token:token,
|
|
which_tags: which_tags
|
|
};
|
|
var json = JSON.stringify(obj);
|
|
sendToBackend("/wellget_cmp", json);
|
|
}
|
|
else {
|
|
alert("Only 1 device can be selected");
|
|
}
|
|
}
|
|
|
|
function WriteDevice() {
|
|
var par_table = document.getElementById("settings");
|
|
var par_rowCount = par_table.rows.length;
|
|
device_settings = {};
|
|
for (var i = 1; i < par_rowCount; i++) {
|
|
sensor_settings = {};
|
|
sensor_name = par_table.rows[i].cells[0].innerText;
|
|
sensor_settings["ut"] = par_table.rows[i].cells[1].childNodes[0].value;
|
|
sensor_settings["dt"] = par_table.rows[i].cells[2].childNodes[0].value;
|
|
sensor_settings["lp"] = par_table.rows[i].cells[3].childNodes[0].value;
|
|
sensor_settings["pn"] = par_table.rows[i].cells[4].childNodes[0].value;
|
|
sensor_settings["sn"] = par_table.rows[i].cells[5].childNodes[0].value;
|
|
sensor_settings["ee"] = par_table.rows[i].cells[6].childNodes[0].value;
|
|
device_settings[sensor_name] = sensor_settings;
|
|
}
|
|
device_settings["fw_v"] = document.getElementById("FWs").value;
|
|
//device_settings["led_s"] = document.getElementById("LEDSchemas").value;
|
|
|
|
device_settings["BLEScanPeriod"] = document.getElementById("BLEScanPeriod").value;
|
|
device_settings["BLEScanDuration"] = document.getElementById("BLEScanDuration").value;
|
|
device_settings["TemperatureOffset"] = document.getElementById("TemperatureOffset").value;
|
|
device_settings["RadarThreshold"] = document.getElementById("RadarThreshold").value;
|
|
|
|
device_settings["S2FSR"] = document.getElementById("S2FSR").value;
|
|
device_settings["reporting_period_s"] = document.getElementById("reporting_period_s").value;
|
|
|
|
device_settings["NCRE"] = document.getElementById("NCRE").value;
|
|
device_settings["e_key"] = document.getElementById("e_key").value;
|
|
device_settings["description"] = document.getElementById("DESCRIPTION").value;
|
|
device_settings["close_to"] = document.getElementById("CLOSETO").value;
|
|
device_settings["owner_id"] = document.getElementById("Owners").value;
|
|
device_settings["wifis"] = document.getElementById("WIFISSID").value;
|
|
device_settings["wifi_pass"] = document.getElementById("WIFIPASS").value;
|
|
device_settings["led_schema"] = document.getElementById("LEDPATTERN").value;
|
|
device_settings["other"] = document.getElementById("OTHER").value;
|
|
|
|
RequestDevsUpdate(device_settings);
|
|
}
|
|
|
|
function OpenDeployment(some_id){
|
|
variable_frame = parent.document.getElementById('variable_frame');
|
|
url = api_url + '/api?name=deployment_edit&deployment_id='+some_id+'&token='+token+'&user_name='+user_name;
|
|
variable_frame.src = url;
|
|
}
|
|
|
|
function OpenDevice(mac){
|
|
try {
|
|
const variable_frame = parent.document.getElementById('variable_frame');
|
|
if (!variable_frame) {
|
|
console.error('variable_frame not found');
|
|
return;
|
|
}
|
|
const url = `${api_url}/api?name=device_edit&mac=${mac}&token=${token}&user_name=${user_name}`;
|
|
variable_frame.src = url;
|
|
} catch (error) {
|
|
console.error('Error in OpenDevice:', error);
|
|
}
|
|
}
|
|
|
|
|
|
function FindDevices() {
|
|
|
|
showTutorial("Looking for new devices...");
|
|
timee = Date.now();
|
|
user_id = document.getElementById("user_id").value;
|
|
token = document.getElementById("token").value;
|
|
var obj = {
|
|
function: "find_devices",
|
|
time:timee,
|
|
user_id:user_id,
|
|
token:token
|
|
};
|
|
var json = JSON.stringify(obj);
|
|
sendToBackend("/wellget_cmp", json);
|
|
|
|
}
|
|
|
|
function SetFirmwares(){
|
|
showTutorial("Setting firmwares...");
|
|
var par_table = document.getElementById("settings");
|
|
var par_rowCount = par_table.rows.length;
|
|
device_settings = {};
|
|
|
|
device_settings["fw_v"] = document.getElementById("FWs").value;
|
|
|
|
RequestFWsUpdate(device_settings);
|
|
}
|
|
|
|
function SetDevices() {
|
|
|
|
showTutorial("Setting devices...");
|
|
var par_table = document.getElementById("settings");
|
|
var par_rowCount = par_table.rows.length;
|
|
device_settings = {};
|
|
for (var i = 1; i < par_rowCount; i++) {
|
|
sensor_settings = {};
|
|
sensor_name = par_table.rows[i].cells[0].innerText;
|
|
sensor_settings["ut"] = par_table.rows[i].cells[1].childNodes[0].value;
|
|
sensor_settings["dt"] = par_table.rows[i].cells[2].childNodes[0].value;
|
|
sensor_settings["lp"] = par_table.rows[i].cells[3].childNodes[0].value;
|
|
sensor_settings["pn"] = par_table.rows[i].cells[4].childNodes[0].value;
|
|
sensor_settings["sn"] = par_table.rows[i].cells[5].childNodes[0].value;
|
|
sensor_settings["ee"] = par_table.rows[i].cells[6].childNodes[0].value;
|
|
device_settings[sensor_name] = sensor_settings;
|
|
}
|
|
//Dont set FW here, there is separate function for it!
|
|
//device_settings["fw_v"] = document.getElementById("FWs").value;
|
|
//device_settings["led_s"] = document.getElementById("LEDSchemas").value;
|
|
|
|
device_settings["BLEScanPeriod"] = document.getElementById("BLEScanPeriod").value;
|
|
device_settings["BLEScanDuration"] = document.getElementById("BLEScanDuration").value;
|
|
device_settings["TemperatureOffset"] = document.getElementById("TemperatureOffset").value;
|
|
device_settings["RadarThreshold"] = document.getElementById("RadarThreshold").value;
|
|
|
|
|
|
device_settings["S2FSR"] = document.getElementById("S2FSR").value;
|
|
device_settings["reporting_period_s"] = document.getElementById("reporting_period_s").value;
|
|
device_settings["NCRE"] = document.getElementById("NCRE").value;
|
|
device_settings["e_key"] = document.getElementById("e_key").value;
|
|
device_settings["FWs"] = document.getElementById("FWs").value;
|
|
btn = document.getElementById("set_device_s");
|
|
if (btn.innerText == "Set Device") { //single
|
|
|
|
device_settings["id"] = document.getElementById("DEVICE_ID").value;
|
|
device_settings["description"] = document.getElementById("DESCRIPTION").value;
|
|
device_settings["close_to"] = document.getElementById("CLOSETO").value;
|
|
device_settings["owner_id"] = document.getElementById("Owners").value;
|
|
device_settings["wifis"] = document.getElementById("WIFISSID").value;
|
|
device_settings["wifi_pass"] = document.getElementById("WIFIPASS").value;
|
|
device_settings["led_schema"] = document.getElementById("LEDPATTERN").value;
|
|
device_settings["other"] = document.getElementById("OTHER").value;
|
|
}
|
|
|
|
RequestDevsUpdate(device_settings);
|
|
}
|
|
|
|
function ShowSingle(do_show) {
|
|
var x = document.getElementById("single_info");
|
|
btn = document.getElementById("set_device_s");
|
|
if (do_show == true) {
|
|
x.style.display = "block";
|
|
btn.innerText = "Set Device";
|
|
} else {
|
|
x.style.display = "none";
|
|
btn.innerText = "Set Devices";
|
|
var x = document.getElementById("caption");
|
|
x.innerHTML = "Settings";
|
|
|
|
}
|
|
}
|
|
|
|
|
|
function GenerateDeploymentLink(desiredLink) {
|
|
document.getElementById('deployment_link').setAttribute('href',desiredLink);
|
|
document.getElementById('deployment_link').setAttribute('target',"_blank");
|
|
}
|
|
|
|
function SetOptions(select_id, select_list) {
|
|
// Get the select element
|
|
const selectElement = document.getElementById(select_id);
|
|
|
|
// Clear existing options
|
|
selectElement.innerHTML = '';
|
|
|
|
// Check if select element exists
|
|
if (!selectElement) {
|
|
console.error(`Select element with id '${select_id}' not found`);
|
|
return;
|
|
}
|
|
|
|
// Ensure select_list is an array
|
|
if (!Array.isArray(select_list)) {
|
|
console.error('select_list must be an array');
|
|
return;
|
|
}
|
|
|
|
// Process each item in the list
|
|
select_list.forEach(item => {
|
|
// Create new option element
|
|
const option = document.createElement('option');
|
|
|
|
// Convert item to string to handle numbers or other types
|
|
const itemStr = String(item);
|
|
|
|
// Check if item contains comma
|
|
if (itemStr.includes(',')) {
|
|
// Split on comma and trim whitespace
|
|
const [value, display] = itemStr.split(',').map(str => str.trim());
|
|
option.value = value;
|
|
option.textContent = value;
|
|
} else {
|
|
// Use same value for both
|
|
option.value = itemStr;
|
|
option.textContent = itemStr;
|
|
}
|
|
|
|
// Add option to select element
|
|
selectElement.appendChild(option);
|
|
});
|
|
}
|
|
|
|
function OpenMap() {
|
|
// Sample data to post
|
|
deployment_id = document.getElementById("Deployments").value;
|
|
if(deployment_id == "0") return;
|
|
const data = {
|
|
function: "get_deployment",
|
|
user_id: user_id,
|
|
user_name: user_name,
|
|
token: token,
|
|
deployment_id: deployment_id
|
|
};
|
|
|
|
// Create a form dynamically
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = api_url;
|
|
form.target = '_blank'; // This makes it open in new tab
|
|
|
|
// Add hidden fields for the data
|
|
for (const key in data) {
|
|
const hiddenField = document.createElement('input');
|
|
hiddenField.type = 'hidden';
|
|
hiddenField.name = key;
|
|
hiddenField.value = data[key];
|
|
form.appendChild(hiddenField);
|
|
}
|
|
|
|
// Add form to document and submit it
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
|
|
// Clean up the form
|
|
document.body.removeChild(form);
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body onresize="resize()" onload="draw()">
|
|
<div
|
|
class="wrapper"
|
|
style="margin: 0 auto; width: 100%; left: 0; top: 0; position: absolute"
|
|
></div>
|
|
<div class="fixed" role="main">
|
|
<div class="row">
|
|
<div class="x_panel">
|
|
<div class="x_title">
|
|
<h2> Options <span class="smallLetters">Filter by:</span> </h2>
|
|
<ul class="nav navbar-right panel_toolbox">
|
|
<li> <a class="collapse-link" onclick="showHide(this);"
|
|
><i class="fa fa-chevron-up"></i
|
|
></a> </li>
|
|
<li> <a class="close-link"><i class="fa fa-close"></i></a> </li>
|
|
</ul>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div class="x_content">
|
|
<button class="small-button" onclick="DoRefresh()">Filter</button>
|
|
<button id="openNodeRed" class="small-button">Node Red</button>
|
|
<button id="AlarmSettings" class="small-button">Alarm Settings</button>
|
|
|
|
<div id="loadingIndicator" style="display:none; margin-top: 10px;">
|
|
<span>Loading Node-RED...</span>
|
|
<div class="spinner" style="display: inline-block; width: 20px; height: 20px; border: 3px solid rgba(0,0,0,.3); border-radius: 50%; border-top-color: #000; animation: spin 1s linear infinite;"></div>
|
|
</div>
|
|
|
|
<div id = "GroupPanel" style="visibility: hidden; width:20%;Text-align:center;float:left;"> Group:
|
|
<select name="group_id" id="group_id" size="1">
|
|
<option value="All">All</option>
|
|
<option value="0">0</option>
|
|
<option value="EyeTech">EyeTech</option>
|
|
</select>
|
|
<button class="small-button" onclick="AddGroup()">New</button>
|
|
<input type="text" id="NewGroup" name="NewGroup" title="New Group #" value="New Group" size="10">
|
|
</div>
|
|
<div id = "OtherPanel" style="width:50%;Text-align:center;float:left;"> Deployment:
|
|
<select name="Deployments" id="Deployments" onchange="DeploymentChange()" size="1">
|
|
###INSTALLS###
|
|
</select>
|
|
<!---
|
|
<button class="small-button" title="Create new Deployment with name specified to the right" onclick="AddDeployment()">New</button>
|
|
<input type="text" id="NewDeployment" name="NewDeployment" title="New Deployment (address), mimum 3 characters long" value="Change_me" size="10">
|
|
<button class="small-button" title="Save Deployments" onclick="ProcessClick('save')">Save</button>
|
|
--->
|
|
Location:
|
|
<select name="Locations" id="Locations" size="1">
|
|
<option value="All">All</option>
|
|
<option value="Bathroom">Bathroom</option>
|
|
<option value="Kitchen">Kitchen</option>
|
|
<option value="Dining Room">Dining Room</option>
|
|
<option value="Bedroom">Bedroom</option>
|
|
<option value="Living Room">Living Room</option>
|
|
<option value="Hallway">Hallway</option>
|
|
<option value="Office">Office</option>
|
|
<option value="Conference Room">Conference Room</option>
|
|
<option value="Outside">Outside</option>
|
|
<option value="Attic">Attic</option>
|
|
<option value="Basement">Basement</option>
|
|
<option value="Garage">Garage</option>
|
|
<option value="Other">Other</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="x_panel">
|
|
<div class="x_title">
|
|
<h2><span id="naslov" class="smallLetters">Parameters</span></h2>
|
|
<ul class="nav navbar-right panel_toolbox">
|
|
<li> <a class="collapse-link" onclick="showHide(this)"
|
|
><i class="fa fa-chevron-up"></i
|
|
></a> </li>
|
|
</ul>
|
|
|
|
|
|
<div class="clearfix"></div>
|
|
<h2 id="caption">Settings</h2>
|
|
|
|
</div>
|
|
<div class="x_content">
|
|
<div style="position: relative; height: 100vh;">
|
|
<div class="container">
|
|
<div class="box" id = "left_panel" style="width: 460px; height: 360px;">
|
|
LED pattern:
|
|
<input name="LEDPATTERN" type="text" id="LEDPATTERN" style="text-align:center" value="00112233445566778899AA" size="20">
|
|
|
|
<br>
|
|
<br>
|
|
Scan BLE every [s]:
|
|
<input style="text-align:center" type="text" name="BLEScanPeriod" id="BLEScanPeriod" size="3">
|
|
for [s]:
|
|
<input style="text-align:center" type="text" name="BLEScanDuration" id="BLEScanDuration" size="3">
|
|
<br><br>
|
|
R threshold:
|
|
<input style="text-align:center" type="text" name="RadarThreshold" id="RadarThreshold" size="3">
|
|
<br><br>
|
|
|
|
Reporting period [s]:
|
|
<input style="text-align:center" type="text" name="reporting_period_s" id="reporting_period_s" size="3">
|
|
<br>
|
|
<br>
|
|
|
|
<button title="Writes device parameters to DB!" class="wider-button" id="set_device_s" onclick="SetDevices()">Set Devices</button>
|
|
<button title="Reports data found in DB including latest updates!" class="wider-button" id="find_new_s" onclick="FindDevices()">Received?</button>
|
|
</div>
|
|
<div class = "box" id="single_info" style="width: 460px; height: 360px;"> Well ID:
|
|
<input style="text-align:center" type="text" name="WELL_ID" id="WELL_ID" size="4">
|
|
Time Zone:
|
|
<input style="text-align:center" type="text" name="time_zone" id="time_zone" size="6">
|
|
<br>
|
|
<br>
|
|
<p>Description:
|
|
<textarea name="DESCRIPTION" id="DESCRIPTION" rows="1" cols="100"></textarea>
|
|
<br>
|
|
<div id = "details1">
|
|
<br>
|
|
SSID(s):
|
|
<input style="text-align:center" type="text" name="WIFISSID" id="WIFISSID" size="16">
|
|
<br>
|
|
Pass:
|
|
<input style="text-align:center" type="text" name="WIFIPASS" id="WIFIPASS" size="26">
|
|
<button class="wider-button" id="delete_CR_s" onclick="DeleteCreds()">Delete</button>
|
|
<br>
|
|
<br>
|
|
</div>
|
|
</p>
|
|
<button class="wider-button" id="read_device_s" onclick="ReadDevice()">Read Device</button>
|
|
</div>
|
|
<div class="box" id="deplink" style="width: 460px; height: 360px;">
|
|
<a id="deployment_link" href="#" onclick="OpenMap(); return false;">Devices In Deployment (Well Id's):</a>
|
|
<div id="deployment_info">
|
|
<div style="display: flex; gap: 20px;">
|
|
<select class="devs_in_depl" name="Proximity" id="Proximity" style="position: relative; left: 30px; top: 10px;" size="10">
|
|
<option value="3">3</option>
|
|
<option value="37">37</option>
|
|
<option value="42">42</option>
|
|
</select>
|
|
<div id="deployment_info1" style="position: relative; left: 30px; top: 10px;">
|
|
<button class="wider-button" id="move_up" title="Move selected item up" onclick="moveUp('Proximity');">Up</button>
|
|
<br>
|
|
<button class="wider-button" id="move_down" title="Move selected item down" onclick="moveDown('Proximity');">Down</button>
|
|
<br>
|
|
<button class="wider-button" id="read_proximity" title="Retrieve proximity of devices" onclick="DeploymentChange();">Read</button>
|
|
<br>
|
|
<button class="wider-button" id="write_proximity" title="Store proximity of devices" onclick="WriteDeploymentProximity();">Write</button>
|
|
<br>
|
|
<button class="wider-button" id="copy_proximity" title="Copy all visible devices to proximity list" onclick="CopyDeploymentProximity();">Copy</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="devslist" style="position: relative; left: 0px; margin-top: 20px; width: 100%;">
|
|
|
|
<h2>Devices</h2>
|
|
<div class="table-container">
|
|
<table name="devices" id="devices">
|
|
<thead class="table-header">
|
|
<tr>
|
|
<th style="text-align:center" scope="col">Id</th>
|
|
<th style="text-align:center" scope="col">Well Id</th>
|
|
<th style="text-align:center" scope="col">MAC</th>
|
|
<th style="text-align:center" scope="col">Last Message</th>
|
|
<th style="text-align:center" scope="col">Location</th>
|
|
<th style="text-align:center" scope="col">Description</th>
|
|
<th style="text-align:center" scope="col">Deployment</th>
|
|
<th style="text-align:center" scope="col">Enable change
|
|
<input type="checkbox" id="AllSel" onchange="SelDesel();"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody name="devices_body" id="devices_body">
|
|
###ROWS###
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="helper" style="position: absolute; left: 400px; top: 24px; height: 50px; width: 200px;">
|
|
<form name = "myform">
|
|
<input type = "text" name = "stage" size = "32" style="border:0"/>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
document.getElementById('openNodeRed').addEventListener('click', async function() {
|
|
// Get the base URL of the current page
|
|
const baseUrl = window.location.protocol + '//' + window.location.host;
|
|
|
|
// Show loading indicator
|
|
const loadingIndicator = document.getElementById('loadingIndicator');
|
|
loadingIndicator.style.display = 'block';
|
|
|
|
// Variables needed for API calls
|
|
const apiEndpoint = baseUrl + '/function/well-api/api';
|
|
|
|
try {
|
|
// First API call to request Node-RED
|
|
const formData = new URLSearchParams();
|
|
formData.append('function', 'request_node_red');
|
|
formData.append('user_name', user_name);
|
|
formData.append('token', token);
|
|
|
|
const requestResponse = await fetch(apiEndpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
},
|
|
body: formData.toString()
|
|
});
|
|
|
|
const requestData = await requestResponse.json();
|
|
|
|
if (requestData.ok !== 1) {
|
|
throw new Error('Failed to request Node-RED');
|
|
}
|
|
|
|
// Poll for port number
|
|
let port = 0;
|
|
let attempts = 0;
|
|
const maxAttempts = 15; // Allow up to 15 seconds
|
|
|
|
const checkPort = async function() {
|
|
attempts++;
|
|
|
|
const formData = new URLSearchParams();
|
|
formData.append('function', 'get_node_red_port');
|
|
formData.append('user_name', user_name);
|
|
formData.append('token', token);
|
|
|
|
const portResponse = await fetch(apiEndpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
},
|
|
body: formData.toString()
|
|
});
|
|
|
|
|
|
const portData = await portResponse.json();
|
|
|
|
port = parseInt(portData.port, 10);
|
|
|
|
// Check if the result is a valid number
|
|
if (isNaN(port)) {
|
|
// Handle invalid input
|
|
port = 0; // Provide a default port value
|
|
}
|
|
|
|
|
|
if (port === 0 && attempts < maxAttempts) {
|
|
// Continue polling
|
|
setTimeout(checkPort, 1000);
|
|
} else if (port > 0) {
|
|
// We have a port, open Node-RED
|
|
loadingIndicator.style.display = 'none';
|
|
window.open(`${baseUrl.replace(/:\d+$/, '')}:${port}/?access_token=${token}&username=${user_name}`, '_blank');
|
|
} else {
|
|
// Max attempts reached, show error
|
|
loadingIndicator.style.display = 'none';
|
|
alert('Could not start Node-RED. Please try again later.');
|
|
}
|
|
};
|
|
|
|
// Start polling
|
|
checkPort();
|
|
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
loadingIndicator.style.display = 'none';
|
|
alert('An error occurred: ' + error.message);
|
|
}
|
|
});
|
|
|
|
function openAlarmSettings() {
|
|
// You can change this URL to any website you want to open
|
|
window.open('https://eluxnetworks.net/shared/alarms.html', '_blank');
|
|
}
|
|
|
|
|
|
document.getElementById('AlarmSettings').addEventListener('click', async function() {
|
|
openAlarmSettings();
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|