mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-14 15:54:47 +00:00
Continued work with v1.1.0
- Merge branch 'low_power' into dev-v1.1.0 - Corrected accumulated import/export from Aidon - Added VCC and RSSI to MQTT messages Changes in UI: - New top navbar - Show VCC and WiFi information - Show MQTT error messages - Show ESP, HAN, WiFi and MQTT status badge - Show accumulated Import/export
This commit is contained in:
commit
0ea21991ea
@ -28,8 +28,8 @@ void HanConfigAp::setup(int accessPointButtonPin, configuration* config, Stream*
|
||||
// Assign pin for boot as AP
|
||||
pinMode(accessPointButtonPin, INPUT_PULLUP);
|
||||
|
||||
// Test if we're holding down the AP pin, over 5 seconds
|
||||
int time = millis() + 5000;
|
||||
// Test if we're holding down the AP pin, over 1 second
|
||||
int time = millis() + 1000;
|
||||
print("Press the AP button now to boot as access point");
|
||||
while (millis() < time)
|
||||
{
|
||||
@ -55,8 +55,8 @@ void HanConfigAp::setup(int accessPointButtonPin, configuration* config, Stream*
|
||||
WiFi.mode(WIFI_OFF);
|
||||
delay(2000);
|
||||
|
||||
WiFi.softAP(AP_SSID);
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAP(AP_SSID);
|
||||
|
||||
/* Setup the DNS server redirecting all the domains to this IP */
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
|
||||
@ -102,10 +102,10 @@ static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanR
|
||||
|
||||
if (listSize >= (int)Aidon::List3PhaseLong)
|
||||
{
|
||||
data["tPI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveImportEnergy);
|
||||
data["tPO"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveExportEnergy);
|
||||
data["tQI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy);
|
||||
data["tQO"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveExportEnergy);
|
||||
data["tPI"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveImportEnergy)) / 100;
|
||||
data["tPO"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveExportEnergy)) / 100;
|
||||
data["tQI"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy)) / 100;
|
||||
data["tQO"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveExportEnergy)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,10 +126,10 @@ static void hanToJsonAidon1phase(int listSize, JsonObject& data, HanReader& hanR
|
||||
|
||||
if (listSize >= (int)Aidon::List1PhaseLong)
|
||||
{
|
||||
data["tPI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveImportEnergy);
|
||||
data["tPO"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveExportEnergy);
|
||||
data["tQI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy);
|
||||
data["tQO"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveExportEnergy);
|
||||
data["tPI"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveImportEnergy)) / 100;
|
||||
data["tPO"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveExportEnergy)) / 100;
|
||||
data["tQI"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy)) / 100;
|
||||
data["tQO"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveExportEnergy)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,10 +154,10 @@ static void hanToJsonAidon3phaseIT(int listSize, JsonObject& data, HanReader& ha
|
||||
|
||||
if (listSize >= (int)Aidon::List3PhaseITLong)
|
||||
{
|
||||
data["tPI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy);
|
||||
data["tPO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy);
|
||||
data["tQI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy);
|
||||
data["tQO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy);
|
||||
data["tPI"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy)) / 100;
|
||||
data["tPO"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy)) / 100;
|
||||
data["tQI"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy)) / 100;
|
||||
data["tQO"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveExportEnergy)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
Author: roarf
|
||||
*/
|
||||
|
||||
#if defined(ESP8266)
|
||||
ADC_MODE(ADC_VCC);
|
||||
#endif
|
||||
|
||||
#include "AmsToMqttBridge.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <MQTT.h>
|
||||
@ -59,8 +63,25 @@ void setup() {
|
||||
if (debugger) {
|
||||
debugger->println("");
|
||||
debugger->println("Started...");
|
||||
#if defined(ESP8266)
|
||||
debugger->print("Voltage: ");
|
||||
debugger->print(ESP.getVcc());
|
||||
debugger->println("mV");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ESP8266)
|
||||
if (ESP.getVcc() < 2800) {
|
||||
if(debugger) {
|
||||
debugger->print("Voltage is too low: ");
|
||||
debugger->print(ESP.getVcc());
|
||||
debugger->println("mV");
|
||||
debugger->flush();
|
||||
}
|
||||
ESP.deepSleep(10000000); //Deep sleep to allow output cap to charge up
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flash the LED, to indicate we can boot as AP now
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
led_on();
|
||||
@ -99,7 +120,7 @@ void setup() {
|
||||
// Compensate for the known Kaifa bug
|
||||
hanReader.compensateFor09HeaderBug = (config.meterType == 1);
|
||||
|
||||
ws.setup(&config, debugger);
|
||||
ws.setup(&config, debugger, &mqtt);
|
||||
}
|
||||
|
||||
// the loop function runs over and over again until power down or reset
|
||||
@ -123,8 +144,16 @@ void loop() {
|
||||
}
|
||||
} else {
|
||||
// Continously flash the LED when AP mode
|
||||
if (millis() / 1000 % 2 == 0) led_on();
|
||||
if (millis() / 50 % 64 == 0) led_on();
|
||||
else led_off();
|
||||
|
||||
#if defined(ESP8266)
|
||||
// Make sure there is enough power to run
|
||||
delay(max(10, 3500-ESP.getVcc()));
|
||||
#else
|
||||
delay(10);
|
||||
#endif
|
||||
|
||||
}
|
||||
readHanPort();
|
||||
ws.loop();
|
||||
@ -208,6 +237,12 @@ void readHanPort() {
|
||||
json["id"] = WiFi.macAddress();
|
||||
json["up"] = millis();
|
||||
json["t"] = time;
|
||||
#if defined(ESP8266)
|
||||
json["vcc"] = ((double) ESP.getVcc()) / 1000;
|
||||
#endif
|
||||
float rssi = WiFi.RSSI();
|
||||
rssi = isnan(rssi) ? -100.0 : rssi;
|
||||
json["rssi"] = rssi;
|
||||
|
||||
// Add a sub-structure to the json object,
|
||||
// to keep the data from the meter itself
|
||||
@ -400,6 +435,9 @@ void sendMqttData(String data)
|
||||
json["id"] = WiFi.macAddress();
|
||||
json["up"] = millis();
|
||||
json["data"] = data;
|
||||
#if defined(ESP8266)
|
||||
json["vcc"] = ((double) ESP.getVcc()) / 1000;
|
||||
#endif
|
||||
|
||||
// Stringify the json
|
||||
String msg;
|
||||
|
||||
@ -14,9 +14,10 @@ ESP8266WebServer server(80);
|
||||
WebServer server(80);
|
||||
#endif
|
||||
|
||||
void AmsWebServer::setup(configuration* config, Stream* debugger) {
|
||||
void AmsWebServer::setup(configuration* config, Stream* debugger, MQTTClient* mqtt) {
|
||||
this->config = config;
|
||||
this->debugger = debugger;
|
||||
this->mqtt = mqtt;
|
||||
|
||||
server.on("/", std::bind(&AmsWebServer::indexHtml, this));
|
||||
server.on("/configuration", std::bind(&AmsWebServer::configurationHtml, this));
|
||||
@ -59,7 +60,6 @@ void AmsWebServer::setJson(StaticJsonDocument<500> json) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(maxPwr == 0 && config->hasConfig() && config->fuseSize > 0 && config->distSys > 0) {
|
||||
int volt = config->distSys == 2 ? 400 : 230;
|
||||
if(u2 > 0) {
|
||||
@ -68,6 +68,13 @@ void AmsWebServer::setJson(StaticJsonDocument<500> json) {
|
||||
maxPwr = config->fuseSize * 230;
|
||||
}
|
||||
}
|
||||
|
||||
if(json["data"].containsKey("tPI")) {
|
||||
tpi = json["data"]["tPI"].as<double>();
|
||||
tpo = json["data"]["tPO"].as<double>();
|
||||
tqi = json["data"]["tQI"].as<double>();
|
||||
tqo = json["data"]["tQO"].as<double>();
|
||||
}
|
||||
} else {
|
||||
if(u1 > 0) {
|
||||
json["data"]["U1"] = u1;
|
||||
@ -81,6 +88,12 @@ void AmsWebServer::setJson(StaticJsonDocument<500> json) {
|
||||
json["data"]["U3"] = u3;
|
||||
json["data"]["I3"] = i3;
|
||||
}
|
||||
if(tpi > 0) {
|
||||
json["data"]["tPI"] = tpi;
|
||||
json["data"]["tPO"] = tpo;
|
||||
json["data"]["tQI"] = tqi;
|
||||
json["data"]["tQO"] = tqo;
|
||||
}
|
||||
}
|
||||
this->json = json;
|
||||
}
|
||||
@ -136,6 +149,24 @@ void AmsWebServer::indexHtml() {
|
||||
html.replace("${data.I3}", u3 > 0 ? String(i3, 1) : "");
|
||||
html.replace("${display.P3}", u3 > 0 ? "" : "none");
|
||||
|
||||
html.replace("${data.tPI}", tpi > 0 ? String(tpi, 1) : "");
|
||||
html.replace("${data.tPO}", tpi > 0 ? String(tpo, 1) : "");
|
||||
html.replace("${data.tQI}", tpi > 0 ? String(tqi, 1) : "");
|
||||
html.replace("${data.tQO}", tpi > 0 ? String(tqo, 1) : "");
|
||||
html.replace("${display.accumulative}", tpi > 0 ? "" : "none");
|
||||
|
||||
double vcc = 0;
|
||||
#if defined(ESP8266)
|
||||
vcc = ((double) ESP.getVcc()) / 1000;
|
||||
#endif
|
||||
html.replace("${vcc}", vcc > 0 ? String(vcc, 2) : "");
|
||||
|
||||
float rssi = WiFi.RSSI();
|
||||
rssi = isnan(rssi) ? -100.0 : rssi;
|
||||
html.replace("${wifi.rssi}", vcc > 0 ? String(rssi, 0) : "");
|
||||
html.replace("${wifi.channel}", WiFi.channel() > 0 ? String(WiFi.channel()) : "");
|
||||
html.replace("${wifi.ssid}", !WiFi.SSID().isEmpty() ? String(WiFi.SSID()) : "");
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
server.sendHeader("Expires", "-1");
|
||||
@ -209,8 +240,10 @@ void AmsWebServer::dataJson() {
|
||||
if(!checkSecurity(2))
|
||||
return;
|
||||
|
||||
StaticJsonDocument<500> json;
|
||||
|
||||
String jsonStr;
|
||||
if(!json.isNull()) {
|
||||
if(!this->json.isNull() && this->json.containsKey("data")) {
|
||||
println(" json has data");
|
||||
|
||||
int maxPwr = this->maxPwr;
|
||||
@ -222,17 +255,91 @@ void AmsWebServer::dataJson() {
|
||||
}
|
||||
}
|
||||
|
||||
json["maxPower"] = maxPwr;
|
||||
json["pct"] = min(p*100/maxPwr, 100);
|
||||
json["meterType"] = config->meterType;
|
||||
json["currentMillis"] = millis();
|
||||
json["up"] = this->json["up"];
|
||||
json["t"] = this->json["t"];
|
||||
json["data"] = this->json["data"];
|
||||
|
||||
serializeJson(json, jsonStr);
|
||||
json["pct"] = min(p*100/maxPwr, 100);
|
||||
} else {
|
||||
json["pct"] = -1;
|
||||
println(" json is empty");
|
||||
jsonStr = "{}";
|
||||
}
|
||||
|
||||
unsigned long now = millis();
|
||||
json["id"] = WiFi.macAddress();
|
||||
json["maxPower"] = maxPwr;
|
||||
json["meterType"] = config->meterType;
|
||||
json["currentMillis"] = now;
|
||||
|
||||
double vcc = 0;
|
||||
#if defined(ESP8266)
|
||||
vcc = ((double) ESP.getVcc()) / 1000;
|
||||
#endif
|
||||
json["vcc"] = vcc;
|
||||
|
||||
json.createNestedObject("wifi");
|
||||
float rssi = WiFi.RSSI();
|
||||
rssi = isnan(rssi) ? -100.0 : rssi;
|
||||
json["wifi"]["ssid"] = WiFi.SSID();
|
||||
json["wifi"]["channel"] = (int) WiFi.channel();
|
||||
json["wifi"]["rssi"] = rssi;
|
||||
|
||||
json.createNestedObject("status");
|
||||
|
||||
String espStatus;
|
||||
if(vcc == 0) {
|
||||
espStatus = "secondary";
|
||||
} else if(vcc > 3.1) {
|
||||
espStatus = "success";
|
||||
} else if(vcc > 2.8) {
|
||||
espStatus = "warning";
|
||||
} else {
|
||||
espStatus = "danger";
|
||||
}
|
||||
json["status"]["esp"] = espStatus;
|
||||
|
||||
unsigned long lastHan = json.isNull() ? 0 : json["up"].as<unsigned long>();
|
||||
String hanStatus;
|
||||
if(config->meterType == 0) {
|
||||
hanStatus = "secondary";
|
||||
} else if(now - lastHan < 15000) {
|
||||
hanStatus = "success";
|
||||
} else if(now - lastHan < 30000) {
|
||||
hanStatus = "warning";
|
||||
} else {
|
||||
hanStatus = "danger";
|
||||
}
|
||||
json["status"]["han"] = hanStatus;
|
||||
|
||||
String wifiStatus;
|
||||
if(!config->ssid) {
|
||||
wifiStatus = "secondary";
|
||||
} else if(rssi > -75) {
|
||||
wifiStatus = "success";
|
||||
} else if(rssi > -95) {
|
||||
wifiStatus = "warning";
|
||||
} else {
|
||||
wifiStatus = "danger";
|
||||
}
|
||||
json["status"]["wifi"] = wifiStatus;
|
||||
|
||||
String mqttStatus;
|
||||
if(!config->mqttHost) {
|
||||
mqttStatus = "secondary";
|
||||
} else if(mqtt->connected()) {
|
||||
mqttStatus = "success";
|
||||
} else if(mqtt->lastError() == 0) {
|
||||
mqttStatus = "warning";
|
||||
} else {
|
||||
mqttStatus = "danger";
|
||||
}
|
||||
json["status"]["mqtt"] = mqttStatus;
|
||||
|
||||
json.createNestedObject("mqtt");
|
||||
json["mqtt"]["lastError"] = (int) mqtt->lastError();
|
||||
|
||||
serializeJson(json, jsonStr);
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
server.sendHeader("Expires", "-1");
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define _AMSWEBSERVER_h
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <MQTT.h>
|
||||
#include "configuration.h"
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
@ -22,17 +23,18 @@
|
||||
|
||||
class AmsWebServer {
|
||||
public:
|
||||
void setup(configuration* config, Stream* debugger);
|
||||
void setup(configuration* config, Stream* debugger, MQTTClient* mqtt);
|
||||
void loop();
|
||||
void setJson(StaticJsonDocument<500> json);
|
||||
|
||||
private:
|
||||
configuration* config;
|
||||
Stream* debugger;
|
||||
MQTTClient* mqtt;
|
||||
StaticJsonDocument<500> json;
|
||||
int maxPwr;
|
||||
int p;
|
||||
double u1, u2, u3, i1, i2, i3;
|
||||
double u1, u2, u3, i1, i2, i3, tpi, tpo, tqi, tqo;
|
||||
|
||||
#if defined(ESP8266)
|
||||
ESP8266WebServer server;
|
||||
|
||||
166
web/index.html
166
web/index.html
@ -13,6 +13,13 @@
|
||||
background-color: var(--purple);
|
||||
}
|
||||
|
||||
.navbar .navbar-nav-svg {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.GaugeMeter {
|
||||
position: Relative;
|
||||
text-align: Center;
|
||||
@ -56,16 +63,40 @@
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<main role="main" class="container">
|
||||
<div class="d-flex align-items-center p-3 my-2 text-white-50 bg-purple rounded shadow">
|
||||
<div class="lh-100">
|
||||
<h6 class="mb-0 text-white lh-100">AMS reader</h6>
|
||||
<small>${version}</small>
|
||||
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bg-purple rounded mt-2">
|
||||
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/meter">Meter</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/wifi">WiFi</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/mqtt">MQTT</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="/config/web">Web</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-row ml-md-auto d-md-flex">
|
||||
<div id="esp" class="d-none m-2">ESP</div>
|
||||
<div id="han" class="d-none m-2">HAN</div>
|
||||
<div id="wifi" class="d-none m-2">WiFi</div>
|
||||
<div id="mqtt" class="d-none m-2">MQTT</div>
|
||||
</div>
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/gskjold/AmsToMqttBridge" target="_blank" rel="noopener" aria-label="GitHub"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg></a>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-4">Current meter values</h6>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<div id="P" class="SimpleMeter">
|
||||
${data.P} W
|
||||
@ -87,32 +118,68 @@
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div id="P1" class="row" style="display: ${display.P1}">
|
||||
<div class="col-md-3">
|
||||
<div id="U1-row" class="row" style="display: ${display.P1}">
|
||||
<div class="col-2">P1</div>
|
||||
<div class="col-5 text-right"><span id="U1">${data.U1}</span> V</div>
|
||||
<div class="col-5 text-right"><span id="I1">${data.I1}</span> A</div>
|
||||
</div>
|
||||
<div id="P2" class="row" style="display: ${display.P2}">
|
||||
<div id="U2-row" class="row" style="display: ${display.P2}">
|
||||
<div class="col-2">P2</div>
|
||||
<div class="col-5 text-right"><span id="U2">${data.U2}</span> V</div>
|
||||
<div class="col-5 text-right"><span id="I2">${data.I2}</span> A</div>
|
||||
</div>
|
||||
<div id="P3" class="row" style="display: ${display.P3}">
|
||||
<div id="U3-row" class="row" style="display: ${display.P3}">
|
||||
<div class="col-2">P3</div>
|
||||
<div class="col-5 text-right"><span id="U3">${data.U3}</span> V</div>
|
||||
<div class="col-5 text-right"><span id="I3">${data.I3}</span> A</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div id="tPI-row" class="row" style="display: ${display.accumulative}">
|
||||
<div class="col-6">Active in</div>
|
||||
<div class="col-6 text-right"><span id="tPI">${data.tPI}</span> kWh</div>
|
||||
</div>
|
||||
<div id="tPO-row" class="row" style="display: ${display.accumulative}">
|
||||
<div class="col-6">Active out</div>
|
||||
<div class="col-6 text-right"><span id="tPO">${data.tPO}</span> kWh</div>
|
||||
</div>
|
||||
<div id="tQI-row" class="row" style="display: ${display.accumulative}">
|
||||
<div class="col-6">Reactive in</div>
|
||||
<div class="col-6 text-right"><span id="tQI">${data.tQI}</span> kvarh</div>
|
||||
</div>
|
||||
<div id="tQO-row" class="row" style="display: ${display.accumulative}">
|
||||
<div class="col-6">Reactive out</div>
|
||||
<div class="col-6 text-right"><span id="tQO">${data.tQO}</span> kvarh</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<hr class="d-md-inline"/>
|
||||
<div class="row">
|
||||
<div class="col-6">Vcc</div>
|
||||
<div class="col-6 text-right"><span id="vcc">${vcc}</span> V</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">SSID</div>
|
||||
<div class="col-6 text-right"><span id="ssid">${wifi.ssid}</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">Channel</div>
|
||||
<div class="col-6 text-right"><span id="channel">${wifi.channel}</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">RSSI</div>
|
||||
<div class="col-6 text-right"><span id="rssi">${wifi.rssi}</span> dBm</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-1 mqtt-error-2 mqtt-error-5 mqtt-error-6 mqtt-error-7 mqtt-error-8 mqtt-error-9 mqtt-error-12">MQTT communication error (<span id="mqtt-lastError">-</span>)</div>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-3">MQTT failed to connect</div>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-4">MQTT network timeout</div>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-10">MQTT connection denied</div>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-11">MQTT failed to subscribe</div>
|
||||
<div class="d-none badge badge-danger mqtt-error mqtt-error-13">MQTT lost connection</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="https://github.com/gskjold/AmsToMqttBridge/releases" class="btn btn-outline-secondary">Release notes</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<a href="configuration" class="btn btn-primary">Configuration</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@ -124,12 +191,58 @@ var nextrefresh = wait;
|
||||
var fetch = function() {
|
||||
$.ajax({
|
||||
url: '/data.json',
|
||||
timeout: 10000,
|
||||
dataType: 'json',
|
||||
}).done(function(json) {
|
||||
$(".SimpleMeter").hide();
|
||||
var el = $(".GaugeMeter");
|
||||
el.show();
|
||||
var rate = 2500;
|
||||
|
||||
for(var id in json) {
|
||||
var str = json[id];
|
||||
if(typeof str === "object")
|
||||
continue;
|
||||
if(isNaN(str)) {
|
||||
$('#'+id).html(str);
|
||||
} else {
|
||||
var num = parseFloat(str);
|
||||
$('#'+id).html(num.toFixed(num < 0 ? 0 : num < 10 ? 2 : 1));
|
||||
}
|
||||
}0
|
||||
|
||||
if(json.status) {
|
||||
for(var id in json.status) {
|
||||
var badge = json.status[id];
|
||||
var item = $('#'+id);
|
||||
item.removeClass('d-none');
|
||||
item.removeClass (function (index, className) {
|
||||
return (className.match (/(^|\s)badge-\S+/g) || []).join(' ');
|
||||
});
|
||||
item.addClass('badge badge-'+badge);
|
||||
}
|
||||
}
|
||||
|
||||
if(json.mqtt) {
|
||||
$('.mqtt-error').addClass('d-none');
|
||||
$('.mqtt-error'+json.mqtt.lastError).removeClass('d-none');
|
||||
$('#mqtt-lastError').html(json.mqtt.lastError);
|
||||
}
|
||||
|
||||
if(json.wifi) {
|
||||
for(var id in json.wifi) {
|
||||
var str = json.wifi[id];
|
||||
dst = $('#'+id);
|
||||
if(isNaN(str)) {
|
||||
dst.html(str);
|
||||
} else {
|
||||
var num = parseFloat(str);
|
||||
dst.html(num.toFixed(0));
|
||||
$('#'+id+'-row').show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(json.data) {
|
||||
el.data('percent', json.pct);
|
||||
if(json.data.P) {
|
||||
@ -152,21 +265,10 @@ var fetch = function() {
|
||||
} else {
|
||||
var num = parseFloat(str);
|
||||
$('#'+id).html(num.toFixed(1));
|
||||
$('#'+id+'-row').show();
|
||||
}
|
||||
}
|
||||
|
||||
if(json.data.U1 > 0) {
|
||||
$('#P1').show();
|
||||
}
|
||||
|
||||
if(json.data.U2 > 0) {
|
||||
$('#P2').show();
|
||||
}
|
||||
|
||||
if(json.data.U3 > 0) {
|
||||
$('#P3').show();
|
||||
}
|
||||
|
||||
if(json.meterType == 3) {
|
||||
rate = 10000;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user