Dynamic temperature page

This commit is contained in:
Gunnar Skjold 2020-09-05 11:10:36 +02:00
parent a332e38b97
commit 04271accc1
8 changed files with 141 additions and 95 deletions

View File

@ -22,10 +22,7 @@
#include "root/upload_html.h"
#include "root/delete_html.h"
#include "root/reset_html.h"
#include "root/temperature_head_html.h"
#include "root/temperature_row_html.h"
#include "root/temperature_none_html.h"
#include "root/temperature_foot_html.h"
#include "root/temperature_html.h"
#include "base64.h"
@ -43,6 +40,7 @@ void AmsWebServer::setup(AmsConfiguration* config, MQTTClient* mqtt) {
server.on("/application.js", HTTP_GET, std::bind(&AmsWebServer::applicationJs, this));
server.on("/temperature", HTTP_GET, std::bind(&AmsWebServer::temperature, this));
server.on("/temperature", HTTP_POST, std::bind(&AmsWebServer::temperaturePost, this));
server.on("/temperature.json", HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this));
server.on("/config-meter", HTTP_GET, std::bind(&AmsWebServer::configMeterHtml, this));
server.on("/config-wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config-mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this));
@ -133,76 +131,73 @@ void AmsWebServer::temperature() {
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
String html;
int c = hw->getTempSensorCount();
int num = 8;
int start = server.hasArg("start") && !server.arg("start").isEmpty() ? server.arg("start").toInt() : 0;
int end = min(start + num, c);
for(int i = start; i < end; i++) {
TempSensorData* data = hw->getTempSensorData(i);
String row = String((const __FlashStringHelper*) TEMPERATURE_ROW_HTML);
row.replace("${index}", String(i-start, DEC));
row.replace("${address}", toHex(data->address, 8));
row.replace("${name}", data->name);
row.replace("${common}", data->common ? "checked" : "");
row.replace("${value}", data->lastRead > -85 ? String(data->lastRead, 1) : "N/A");
html += row;
}
if(c == 0) {
html += String((const __FlashStringHelper*) TEMPERATURE_NONE_HTML);
}
if(start > 0 || end < c) {
html += "<div class=\"row\"><div class=\"col-6\">";
if(start > 0) {
html += "<a href=\"?start=";
html += String(start-num, DEC);
html += "\" class=\"btn btn-sm btn-outline-secondary\">previous</a>";
}
html += "</div><div class=\"col-6 text-right\">";
if(end < c) {
html += "<a href=\"?start=";
html += String(end, DEC);
html += "\" class=\"btn btn-sm btn-outline-secondary\">next</a>";
}
html += "</div></div>";
}
server.setContentLength(html.length() + HEAD_HTML_LEN + TEMPERATURE_HEAD_HTML_LEN + FOOT_HTML_LEN + TEMPERATURE_FOOT_HTML_LEN);
server.setContentLength(HEAD_HTML_LEN + TEMPERATURE_HTML_LEN + FOOT_HTML_LEN);
server.send_P(200, "text/html", HEAD_HTML);
server.sendContent_P(TEMPERATURE_HEAD_HTML);
server.sendContent(html);
server.sendContent_P(TEMPERATURE_FOOT_HTML);
server.sendContent_P(TEMPERATURE_HTML);
server.sendContent_P(FOOT_HTML);
}
void AmsWebServer::temperaturePost() {
int start = server.hasArg("start") && !server.arg("start").isEmpty() ? server.arg("start").toInt() : 0;
for(int i = 0; i < 4; i++) {
printD("Saving temperature sensors...");
for(int i = 0; i < 32; i++) {
if(!server.hasArg("sensor" + String(i, DEC))) break;
String address = server.arg("sensor" + String(i, DEC));
String name = server.arg("sensor" + String(i, DEC) + "name");
String name = server.arg("sensor" + String(i, DEC) + "name").substring(0,16);
bool common = server.hasArg("sensor" + String(i, DEC) + "common") && server.arg("sensor" + String(i, DEC) + "common") == "true";
if(debugger->isActive(RemoteDebug::DEBUG)) {
debugger->printf("Addr: %s, name: %s\n", address.c_str(), name.c_str());
}
config->updateTempSensorConfig(fromHex(address, 8), name.c_str(), common);
delay(1);
}
if(config->save()) {
server.sendHeader("Location", String("/temperature?start=") + String(start, DEC), true);
printD("Successfully saved temperature sensors");
server.sendHeader("Location", String("/temperature"), true);
server.send (302, "text/plain", "");
uint8_t c = config->getTempSensorCount();
for(int i = 0; i < c; i++) {
TempSensorConfig* tsc = config->getTempSensorConfig(i);
hw->confTempSensor(tsc->address, tsc->name, tsc->common);
delay(1);
}
}
}
void AmsWebServer::temperatureJson() {
printD("Serving /temperature.json over http...");
if(!checkSecurity(2))
return;
int count = hw->getTempSensorCount();
StaticJsonDocument<4096> json;
json["c"] = count;
JsonArray sensors = json.createNestedArray("s");
for(int i = 0; i < count; i++) {
TempSensorData* data = hw->getTempSensorData(i);
JsonObject obj = sensors.createNestedObject();
obj["i"] = i;
obj["a"] = toHex(data->address, 8);
obj["n"] = String(data->name).substring(0,16);
obj["v"] = String(data->lastRead, 2);
obj["c"] = data->common;
delay(1);
}
String jsonStr;
serializeJson(json, jsonStr);
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "-1");
server.setContentLength(jsonStr.length());
server.send(200, "application/json", jsonStr);
}
void AmsWebServer::indexHtml() {
printD("Serving /index.html over http...");

View File

@ -62,6 +62,7 @@ private:
void applicationJs();
void temperature();
void temperaturePost();
void temperatureJson();
void configMeterHtml();
void configWifiHtml();
void configMqttHtml();

View File

@ -106,6 +106,7 @@ $(function() {
});
$('#ntpEnable').trigger('change');
// Navbar
switch(window.location.pathname) {
case '/temperature':
$('#config-temp-link').addClass('active');
@ -133,6 +134,7 @@ $(function() {
break;
}
// Check for software upgrade
var swv = $('#swVersion')
if(meters.length > 0 && swv.length == 1 && swv.text() != "SNAPSHOT") {
var v = swv.text().substring(1).split('.');
@ -191,6 +193,12 @@ $(function() {
}
});
}
// Temperature
var tt = $('#temp-template');
if(tt.length > 0) {
setTimeout(loadTempSensors, 500);
}
});
var setStatus = function(id, status) {
@ -356,3 +364,40 @@ var upgrade = function() {
}
}
}
var loadTempSensors = function() {
$.ajax({
url: '/temperature.json',
timeout: 10000,
dataType: 'json',
}).done(function(json) {
if($('#loading').length > 0) {
$('#loading').hide();
var list = $('#sensors');
if(json.c > 0) {
list.empty();
var temp = $.trim($('#temp-template').html());
$.each(json.s, function(i, o) {
var item = temp.replace(/{{index}}/ig, o.i);
var item = item.replace(/{{address}}/ig, o.a);
var item = item.replace(/{{name}}/ig, o.n);
var item = item.replace(/{{value}}/ig, o.v > -50 && o.v < 127 ? o.v : "N/A");
var item = item.replace(/{{common}}/ig, o.c ? "checked" : "");
list.append(item);
});
} else {
$('#notemp').show();
}
} else {
$.each(json.s, function(i, o) {
$('#temp-'+o.i).html(o.v > -50 && o.v < 127 ? o.v : "N/A");
});
}
setTimeout(loadTempSensors, 10000);
}).fail(function() {
setTimeout(loadTempSensors, 60000);
$('#loading').hide();
$('#error').show();
});
}

48
web/temperature.html Normal file
View File

@ -0,0 +1,48 @@
<script id="temp-template" type="template">
<div class="row mb-3">
<input type="hidden" name="sensor{{index}}" value="{{address}}"/>
<div class="col-xl-3 col-lg-4 col-sm-6">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Address</span>
</div>
<input name="sensor{{index}}address" type="text" class="form-control" value="{{address}}" maxlength="16" disabled/>
</div>
</div>
<div class="col-xl-4 col-lg-3 col-sm-6">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Name</span>
</div>
<input name="sensor{{index}}name" type="text" class="form-control" value="{{name}}" maxlength="16"/>
</div>
</div>
<div class="col-xl-3 col-lg-3 col-sm-6">
<div class="form-check">
<input name="sensor{{index}}common" class="form-check-input" type="checkbox" value="true" id="sensor{{index}}common" {{common}}>
<label class="form-check-label" for="sensor{{index}}common">Include in average</label>
</div>
</div>
<div class="col-xl-2 col-lg-2 col-sm-6">
<span id="temp-{{index}}">{{value}}</span> &deg;C
</div>
</div>
</script>
<form method="post">
<input type="hidden" name="tempConfig" value="true"/>
<div id="sensors" class="my-3 p-3 bg-white rounded shadow">
<div id="loading" class="alert alert-info">Loading temperature sensors</div>
<div id="notemp" class="alert alert-info" style="display: none;">No temperature sensors are configured or found</div>
<div id="error" class="alert alert-danger" style="display: none;">Error loading data</div>
</div>
<hr/>
<div class="row form-group">
<div class="col-6">
<a href="/" class="btn btn-outline-secondary">Back</a>
</div>
<div class="col-6 text-right">
<button class="btn btn-primary">Save</button>
</div>
</div>
</form>

View File

@ -1,11 +0,0 @@
</div>
<hr/>
<div class="row form-group">
<div class="col-6">
<a href="/" class="btn btn-outline-secondary">Back</a>
</div>
<div class="col-6 text-right">
<button class="btn btn-primary">Save</button>
</div>
</div>
</form>

View File

@ -1,3 +0,0 @@
<form method="post">
<input type="hidden" name="tempConfig" value="true"/>
<div class="my-3 p-3 bg-white rounded shadow">

View File

@ -1 +0,0 @@
<div class="alert alert-info">No temperature sensors is configured or found</div>

View File

@ -1,28 +0,0 @@
<input type="hidden" name="sensor${index}" value="${address}"/>
<div class="row mb-3">
<div class="col-xl-3 col-lg-4 col-sm-6">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Address</span>
</div>
<input name="sensor${index}address" type="text" class="form-control" value="${address}" maxlength="16" disabled/>
</div>
</div>
<div class="col-xl-4 col-lg-3 col-sm-6">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Name</span>
</div>
<input name="sensor${index}name" type="text" class="form-control" value="${name}" maxlength="32"/>
</div>
</div>
<div class="col-xl-3 col-lg-3 col-sm-6">
<div class="form-check">
<input name="sensor${index}common" class="form-check-input" type="checkbox" value="true" id="sensor${index}common" ${common}>
<label class="form-check-label" for="sensor${index}common">Include in average</label>
</div>
</div>
<div class="col-xl-2 col-lg-2 col-sm-6">
${value} °C
</div>
</div>