Files
Neptune_W01/data/index.html

410 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:image/gif;base64,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">
<title>Конфигурация</title>
<style>
* {
margin: 0;
padding: 0;
font-size: 16px;
}
html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
body{
background-color: #4f4f4f;
}
h1 {
font-size: 40px;
line-height: 50px;
color: #1655f5
}
h3 {
font-size: 24px;
font-weight: normal;
margin-top: 5px;
margin-bottom: 5px;
}
h4 {
padding-top: 5px;
padding-bottom: 5px;
}
p{
font-size: 20px;
padding-top: 5px;
padding-bottom: 5px;
}
select{
font-size:24px;
width: 100%;
}
input[type="text"],input[type="number"],input[type="password"]
{
font-size:24px;
width: 100%;
}
.wifi_list{
width: 100%;
cursor: pointer;
background-color: #ffffff;
border-bottom: 1px solid #000000;
}
.content1 {
width: 100%;
max-width: 400px;
margin-left: auto;
margin-right: auto;
background-color: lightblue;
}
.content2 {
width: 95%;
margin-left: auto;
margin-right: auto;
}
.counter {
position: sticky;
top: 8px;
font-weight: bold;
color: #f53410;
}
.button{
background-color: #4CAF50;
border: none;
color: white;
padding: 16px 40px;
text-decoration: none;
font-size: 30px;
margin: 2px;
cursor: pointer;
border-radius: 20px;
}
.lock {
width:16px;
height:24px;
background: url('data:image/gif;base64,R0lGODlhEAAYAIQWADVMdVlhbIF5YGqDuo6AXWuDummEumqEumuEu6WOVrmjc7qkcrukccKna9erSdesSey3Q/K6QfK7QPK7QfO7QfK8QgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAB8ALAAAAAAQABgAAAVf4CeOQzmM6FiY5pGKbHyiLCIaZkGXr7nPv2DKR+INjTBkEfghCj8LBaMxqVobDMXiY+16rZHKdzwRk89dSCIBQVcTAEDCPRHEBXQ7AO8mxAl0DgEBD3SGhxSGElx0iyEAOw==') no-repeat;
}
.field{
font-size:24px;
}
.restore_box
{
width: 24px;
height: 23px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAXCAYAAAARIY8tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAMzQAADM0B9/0h3QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGkSURBVEiJtdUxSFVRGAfwn+WgQaJN4dRUBPnGl5BDNQQNYQjR0tIS4RLtEVlIjQYFtWRTDW01RQSiEUhtBW3hIAkaFBSk2fM5XKXzzjvvvXPD/vDBOff+z/87/+/e850u1DXiIS4H80GM4iQOYB9+YBFv8QIftEE9igeB8GOsJThxzKBaJsE5fMsQDqOGO9gVindpLtEcjsVEfME8VtCHCg5vaYR4igvYaOVgI5q/wYkW7g9iOrHmdkhqZ/tmwkkKZ/Az2uRIpwR3MRBFT5skp/EnWP8+x0Ec1zo4uRfxh3Psl8GkwsU2zu90giXMBvPqTicgqD0OdWOqxOL5DM73YNzTjaslEuSgLxiv/Y8SVYLx51ak+PjnYgC//P1N78eE3biBJ/+Y4JbGc3AqfLkfr4OXV0qKH9XY2j+K2kxFo70aLmWKV/E12v1oinhRc3t4puiaKfQryhJfSo+2CamPOYHr0bM63m3FMvbiCI5rboAvcRarLTYFxvE74aZTTKO3nXCIIbzKFP6EsZRIzv8+pLgChxVX5B6sY0HROp4rylJLLd4ExpG2mIQ1Ut0AAAAASUVORK5CYII=");
background-repeat: no-repeat;
margin-left: 5px;
cursor: pointer;
}
</style>
<script>
var g_ticks=999;
function delChild(obj)
{
if (typeof obj === 'string' || obj instanceof String)
obj=document.getElementById(obj);
if(obj!=null)
{
while(true)
{
let c=obj.firstChild;
if(c!=null) obj.removeChild(c); else break;
}
}
return false;
}
function updateFields(){
if(document.getElementById("mqtt_protocol").value=="tls") {
document.getElementById("fingerprint").style.display = "block";
}else{ //tcp
document.getElementById("fingerprint").style.display = "none";
}
}
function loadData(){
let req = new XMLHttpRequest();
req.onreadystatechange = function(req)
{
return function()
{
if (req.readyState == 4)
{
let obj=JSON.parse(req.responseText);
document.getElementById("ssid").value=obj.ssid;
document.getElementById("pass").value=obj.pass;
document.getElementById("uuid").value=obj.uuid;
document.getElementById("mqtt_protocol").value=obj.mqtt_protocol;
document.getElementById("mqtt_host").value=obj.mqtt_host;
document.getElementById("mqtt_port").value=obj.mqtt_port;
document.getElementById("mqtt_fingerprint").value=obj.mqtt_fingerprint;
document.getElementById("mqtt_topic").value=obj.mqtt_topic;
document.getElementById("mqtt_user").value=obj.mqtt_user;
document.getElementById("mqtt_pass").value=obj.mqtt_pass;
updateFields();
updateSensors();
}
}
}(req);
req.open("GET",'/data/',true);
req.send();
}
function updateSensors(){
let req = new XMLHttpRequest();
req.onreadystatechange = function(req)
{
return function()
{
if (req.readyState == 4)
{
let obj=JSON.parse(req.responseText);
g_ticks = obj.ticks;
if(obj.cold!=null){ document.getElementById("cold").innerHTML=obj.cold; }else{
document.getElementById("cold").innerHTML="___";
}
if(obj.hot!=null){ document.getElementById("hot").innerHTML=obj.hot; }else{
document.getElementById("hot").innerHTML="___";
}
if(obj.leak) {
document.getElementById("leak").innerHTML = "обнаружена";
document.getElementById("leak").style.color='darkred';
}else {
document.getElementById("leak").innerHTML = "не обнаружена";
document.getElementById("leak").style.color='black';
}
if(obj.volt!=null){
document.getElementById("volt_cnt").style.display='table-row';
let p;
if(obj.volt==300) p=0;
else p=Math.round(((obj.volt-300)/(420-300))*100);
if(p<0) p=0;
if(p>100) p=100;
document.getElementById("volt").innerHTML=p+"%";
}else{
document.getElementById("volt_cnt").style.display='none';
}
if(obj.tmpr!=null){
document.getElementById("tmpr_cnt").style.display='table-row';
document.getElementById("tmpr").innerHTML=obj.tmpr+"°C";
}else{
document.getElementById("tmpr_cnt").style.display='none';
}
let networks = document.getElementById("networks");
delChild(networks);
obj.networks.sort((a, b) => a.strength < b.strength ? 1 : -1);
for(let i=0;i<obj.networks.length;i++)
{
let quality;
if(obj.networks[i].strength <= -100)
quality = 0;
else if(obj.networks[i].strength >= -50)
quality = 100;
else
quality = 2 * (obj.networks[i].strength + 100);
let radio=`<table class="wifi_list" style="width: 100%;" onclick="document.getElementById('ssid').value='{name}'; document.getElementById('ch{id}').checked=true;"><tr><td style="width: 20px;"><input id="ch{id}" type="radio" name="radio" {checked}></td><td style="font-family:Verdana,sans-serif;">{name}</td><td class="divTableCell" style="width: 18px;"><div {lock}></div></td><td style="width: 45px;">{quality}%</td></tr></table>`;
radio = radio.replaceAll('{id}',i);
radio = radio.replaceAll('{name}',obj.networks[i].name.substring(0,22));
if(obj.networks[i].name==document.getElementById("ssid").value)
radio = radio.replace('{checked}','checked="checked"');
else
radio = radio.replace('{checked}','');
if(obj.networks[i].lock!=7)
radio = radio.replace('{lock}','class="lock"');
radio = radio.replaceAll('{quality}',quality);
let div = document.createElement('div');
div.innerHTML=radio;
networks.appendChild(div);
}
}
}
}(req);
req.open("GET",'/sensors/',true);
req.send();
}
function sendData() {
let formData = new FormData();
formData.append("ssid", document.getElementById("ssid").value);
formData.append("pass", document.getElementById("pass").value);
formData.append("hot", document.getElementById("newhot").value);
formData.append("cold", document.getElementById("newcold").value);
//formData.append("uuid", document.getElementById("uuid").value);
formData.append("mqtt_protocol", document.getElementById("mqtt_protocol").value);
formData.append("mqtt_host", document.getElementById("mqtt_host").value);
formData.append("mqtt_port", document.getElementById("mqtt_port").value);
formData.append("mqtt_fingerprint", document.getElementById("mqtt_fingerprint").value);
formData.append("mqtt_topic", document.getElementById("mqtt_topic").value);
formData.append("mqtt_user", document.getElementById("mqtt_user").value);
formData.append("mqtt_pass", document.getElementById("mqtt_pass").value);
let xhr = new XMLHttpRequest();
xhr.open("POST","/save/");
xhr.send(formData);
xhr.onload = function() {
if (xhr.status != 200) {
alert(`Ошибка ${xhr.status}: ${xhr.statusText}`);
} else {
//alert(`Готово, получили ${xhr.response.length} байт = `+xhr.response);
if(xhr.response!='ok') {
alert("Ошибка при записи, обновите страницу и попробуйте ещё раз.");
location.reload();
}else {
alert("Данные записаны.");
location.reload();
}
document.getElementById("newhot").value="";
document.getElementById("newcold").value="";
}
};
xhr.onerror = function() {
alert("Запрос не удался");
};
}
window.onload = function () {
document.getElementById("mqtt_protocol").onchange=updateFields;
loadData();
setInterval(function () {
if(g_ticks>0) {
updateSensors();
}
}, 5000);
setInterval(function () {
if(g_ticks>0) {
if(g_ticks!=999) {
document.getElementById("timerId").innerText = g_ticks;
g_ticks--;
}
if (g_ticks==0) {
alert('Нептун заснул.');
location.reload();
}
}
}, 1000);
document.getElementById("chbox").checked=false;
};
</script>
</head>
<body>
<div class="content1"><div class="content2">
<h1>Настройка</h1>
<p class="counter">Устройство заснёт через: <a id="timerId">___</a> секунд</p>
<h3>Выберите свою Wi-Fi сеть</h3>
<div id="networks" style="width: 100%; height: 150px; overflow-y: scroll; background-color: #e9e9e9; border-width: 1px;border-color: #4f4f4f; border-style: solid;">
</div>
<h3>Точка доступа</h3>
<input id="ssid" name="ssid" type="text" size="40">
<h3>Пароль</h3>
<input id="pass" name="pass" type="password" size="40">
<p>
Для проверки работоспособности спустите не меньше 4х литров воды
</p>
<h4>Текущее показание холодной воды</h4>
<h4 id="cold" style="color: darkblue;">___</h4>
<h3>Новое показание холодной воды</h3>
<table style="width: 100%;">
<tr>
<td>
<input class="it" id="newcold" min="0" max="99999999" step="1" type="number" autocomplete="off">
</td>
<td>
Литры
</td>
</tr>
</table>
<h4>Текущее показание горячей воды</h4>
<h4 id="hot" style="color: darkred;">___</h4>
<h3>Новое показание горячей воды</h3>
<table style="width: 100%;">
<tr>
<td>
<input class="it" id="newhot" min="0" max="99999999" step="1" type="number" autocomplete="off">
</td>
<td>
Литры
</td>
</tr>
</table>
<table style="width: 100%;">
<tr style="width: 100%;"><td style="text-align:left;">Протечка:</td><td id="leak" style="width: 50px;text-align:right;white-space: nowrap;">___</td></tr>
<tr id="volt_cnt" style="display: none;"><td style="text-align:left; width: 90%;">Заряд аккумулятора:</td><td id="volt" style="width: 50px;text-align:right;">___</td></tr>
<tr id="tmpr_cnt" style="display: none;"><td style="text-align:left; width: 90%;">Температура:</td><td id="tmpr" style="width: 50px;text-align:right;">___</td></tr>
</table>
<p>
<input id="chbox" name="chbox" style="width:20px;height:20px;" onclick="if(this.checked) document.getElementById('settings').style.display='block'; else document.getElementById('settings').style.display='none';" type="checkbox">
<label for="chbox" style="font-size:20px;">Дополнительные настройки</label>
</p>
<div id="settings" style="display: none;">
<p>Адрес MQTT сервера(брокера)</p>
<table>
<tr><td>соед.</td><td>хост</td><td>порт</td><td></td></tr>
<tr>
<td><select name="mqtt_protocol" id="mqtt_protocol" style="width:80px;"><option value="tcp">TCP</option><option value="tls">TCP(TLS)</option></select></td>
<td><input id="mqtt_host" name="mqtt_host" type="text" size="40"></td>
<td><input id="mqtt_port" name="mqtt_port" type="text" size="40" style="width:60px;"></td>
<td><div class="restore_box" onclick="document.getElementById('mqtt_protocol').value='tcp'; document.getElementById('mqtt_host').value='observer.kz'; document.getElementById('mqtt_port').value='1883'; updateFields(); "></div></td>
</tr>
</table>
<div id="fingerprint" style="display: none;">
<p>Отпечаток сертификата</p>
<input id="mqtt_fingerprint" name="mqtt_fingerprint" type="text" size="61" value="">
</div>
<p>Топик</p>
<table style="width: 100%;">
<tr>
<td>
<input id="mqtt_topic" name="mqtt_topic" type="text" size="40" value="home/water/main">
</td>
<td>
<div class="restore_box" onclick="document.getElementById('mqtt_topic').value='home/water/main';"></div>
</td>
</tr>
</table>
<p>Логин</p>
<input id="mqtt_user" name="mqtt_user" type="text" size="40" value="">
<p>Пароль</p>
<input id="mqtt_pass" name="mqtt_pass" type="password" size="40" value="">
<p>Уникальный ID клиента</p>
<input id="uuid" name="uuid" type="text" size="40" disabled="disabled">
</div>
<br>
<button class="button" onclick="sendData();">Сохранить</button>
<br><br>
</div></div>
</body>
</html>