Support older config versions. Fixed css for AP mode. Some cleanup and changes to preserve power

This commit is contained in:
Gunnar Skjold 2020-02-16 20:09:29 +01:00
parent 227eb7b6ff
commit 4786735d4c
11 changed files with 509 additions and 221 deletions

View File

@ -205,13 +205,19 @@ void AmsConfiguration::setProductionCapacity(int productionCapacity) {
}
bool AmsConfiguration::hasConfig()
{
bool hasConfig = false;
bool AmsConfiguration::hasConfig() {
EEPROM.begin(EEPROM_SIZE);
hasConfig = EEPROM.read(EEPROM_CONFIG_ADDRESS) == EEPROM_CHECK_SUM;
int configVersion = EEPROM.read(EEPROM_CONFIG_ADDRESS);
EEPROM.end();
return hasConfig;
switch(configVersion) {
case 71:
case 72:
case 75:
case 80:
return true;
default:
return false;
}
}
bool AmsConfiguration::load() {
@ -220,80 +226,209 @@ bool AmsConfiguration::load() {
EEPROM.begin(EEPROM_SIZE);
int cs = EEPROM.read(address);
if (cs == EEPROM_CHECK_SUM)
{
char* temp;
address++;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
address += readString(address, &temp);
setWifiIp(temp);
address += readString(address, &temp);
setWifiGw(temp);
address += readString(address, &temp);
setWifiSubnet(temp);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure)
{
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
} else {
clearMqtt();
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMeterType(i);
address += readInt(address, &i);
setDistributionSystem(i);
address += readInt(address, &i);
setMainFuse(i);
address += readInt(address, &i);
setProductionCapacity(i);
ackWifiChange();
success = true;
}
address++;
switch(cs) {
case 71: // Same as 72
case 72:
success = loadConfig72(address);
break;
case 75:
success = loadConfig75(address);
break;
case 80:
success = loadConfig80(address);
break;
}
EEPROM.end();
return success;
}
bool AmsConfiguration::loadConfig72(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
byte b;
address += readByte(address, &b);
setMeterType(b);
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure) {
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
clearAuth();
setWifiIp("");
setWifiGw("");
setWifiSubnet("");
setMainFuse(0);
setProductionCapacity(0);
setDistributionSystem(0);
ackWifiChange();
return true;
}
bool AmsConfiguration::loadConfig75(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
byte b;
address += readByte(address, &b);
setMeterType(b);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
}
bool secure = false;
address += readBool(address, &secure);
if (secure) {
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMainFuse(i);
address += readByte(address, &b);
setDistributionSystem(b);
setWifiIp("");
setWifiGw("");
setWifiSubnet("");
setProductionCapacity(0);
ackWifiChange();
return true;
}
bool AmsConfiguration::loadConfig80(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
address += readString(address, &temp);
setWifiIp(temp);
address += readString(address, &temp);
setWifiGw(temp);
address += readString(address, &temp);
setWifiSubnet(temp);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure)
{
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
} else {
clearMqtt();
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMeterType(i);
address += readInt(address, &i);
setDistributionSystem(i);
address += readInt(address, &i);
setMainFuse(i);
address += readInt(address, &i);
setProductionCapacity(i);
ackWifiChange();
return true;
}
bool AmsConfiguration::save() {
int address = EEPROM_CONFIG_ADDRESS;

View File

@ -88,9 +88,13 @@ private:
int meterType, distributionSystem, mainFuse, productionCapacity;
const int EEPROM_SIZE = 512;
const byte EEPROM_CHECK_SUM = 80; // Used to check if config is stored. Change if structure changes
const int EEPROM_CHECK_SUM = 80; // Used to check if config is stored. Change if structure changes
const int EEPROM_CONFIG_ADDRESS = 0;
bool loadConfig72(int address);
bool loadConfig75(int address);
bool loadConfig80(int address);
int saveString(int pAddress, const char* pString);
int readString(int pAddress, char* pString[]);
int saveInt(int pAddress, int pValue);

View File

@ -19,12 +19,15 @@
#define AP_BUTTON_PIN 0
#if DEBUG_MODE
#define SOFTWARE_SERIAL 1
#if SOFTWARE_SERIAL
#include <SoftwareSerial.h>
SoftwareSerial *hanSerial = new SoftwareSerial(3);
#else
HardwareSerial *hanSerial = &Serial;
#endif
#else
HardwareSerial *hanSerial = &Serial;
#endif
// Build settings for Wemos Lolin D32
#elif defined(ARDUINO_LOLIN_D32)

View File

@ -44,8 +44,6 @@ Stream* debugger = NULL;
// The HAN Port reader, used to read serial data and decode DLMS
HanReader hanReader;
boolean hasTempSensor = false;
// the setup function runs once when you press reset or power the board
void setup() {
if(config.hasConfig()) {
@ -54,9 +52,18 @@ void setup() {
#if DEBUG_MODE
#if HW_ROARFRED
#if SOFTWARE_SERIAL
SoftwareSerial *ser = new SoftwareSerial(-1, 1);
ser->begin(115200, SWSERIAL_8N1);
debugger = ser;
#else
HardwareSerial *ser = &Serial;
if(config.getMeterType() == 3) {
ser->begin(2400, SERIAL_8N1);
} else {
ser->begin(2400, SERIAL_8E1);
}
#endif
#else
HardwareSerial *ser = &Serial;
ser->begin(115200, SERIAL_8N1);
@ -76,9 +83,7 @@ void setup() {
if (vcc > 0 && vcc < 3.1) {
if(debugger) {
debugger->print("Voltage is too low: ");
debugger->print(vcc);
debugger->println("mV");
debugger->println("Voltage is too low, sleeping");
debugger->flush();
}
ESP.deepSleep(10000000); //Deep sleep to allow output cap to charge up
@ -88,20 +93,15 @@ void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(AP_BUTTON_PIN, INPUT_PULLUP);
led_off();
WiFi.disconnect(true);
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_OFF);
if(debugger) {
if(hasTempSensor) {
debugger->println("Has temp sensor");
} else {
debugger->println("No temp sensor found");
}
}
if(config.hasConfig()) {
if(debugger) config.print(debugger);
WiFi_connect();
client = new WiFiClient();
} else {
if(debugger) {
@ -116,7 +116,6 @@ void setup() {
} else {
hanSerial->begin(2400, SWSERIAL_8E1);
}
#elif defined DEBUG_MODE
#else
if(config.getMeterType() == 3) {
hanSerial->begin(2400, SERIAL_8N1);
@ -143,14 +142,18 @@ bool longPressActive = false;
bool wifiConnected = false;
unsigned long lastTemperatureRead = 0;
double temperature = -127;
void loop() {
unsigned long now = millis();
if (digitalRead(AP_BUTTON_PIN) == LOW) {
if (buttonActive == false) {
buttonActive = true;
buttonTimer = millis();
buttonTimer = now;
}
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
if ((now - buttonTimer > longPressTime) && (longPressActive == false)) {
longPressActive = true;
swapWifiMode();
}
@ -165,6 +168,11 @@ void loop() {
}
}
if(now - lastTemperatureRead > 10000) {
temperature = hw.getTemperature();
lastTemperatureRead = now;
}
// Only do normal stuff if we're not booted as AP
if (WiFi.getMode() != WIFI_AP) {
// Turn off the LED
@ -181,29 +189,20 @@ void loop() {
}
if (!config.getMqttHost().isEmpty()) {
mqtt.loop();
yield();
delay(10);
if(!mqtt.connected() || config.isMqttChanged()) {
MQTT_connect();
}
} else if(mqtt.connected()) {
mqtt.disconnect();
yield();
}
}
} else {
dnsServer.processNextRequest();
// Continously flash the LED when AP mode
if (millis() / 50 % 64 == 0) led_on();
if (now / 50 % 64 == 0) led_on();
else led_off();
// Make sure there is enough power to run
double vcc = hw.getVcc();
if(vcc > 0) {
delay(max(10, 3500-(int)(vcc*1000)));
} else {
delay(10);
}
}
readHanPort();
ws.loop();
@ -239,7 +238,7 @@ void swapWifiMode() {
WiFi.mode(WIFI_OFF);
yield();
if (mode != WIFI_AP) {
if (mode != WIFI_AP || !config.hasConfig()) {
if(debugger) debugger->println("Swapping to AP mode");
WiFi.softAP("AMS2MQTT");
WiFi.mode(WIFI_AP);
@ -298,9 +297,8 @@ void readHanPort() {
float rssi = WiFi.RSSI();
rssi = isnan(rssi) ? -100.0 : rssi;
json["rssi"] = rssi;
double temp = hw.getTemperature();
if(temp != -127) {
json["temp"] = temp;
if(temperature != -127) {
json["temp"] = temperature;
}
// Add a sub-structure to the json object,
@ -406,6 +404,7 @@ void WiFi_connect() {
WiFi.enableAP(false);
WiFi.mode(WIFI_STA);
// WiFi.setOutputPower(0);
if(!config.getWifiIp().isEmpty()) {
IPAddress ip, gw, sn(255,255,255,0);
ip.fromString(config.getWifiIp());

View File

@ -23,10 +23,10 @@ void AmsWebServer::setup(AmsConfiguration* config, Stream* debugger, MQTTClient*
this->mqtt = mqtt;
server.on("/", std::bind(&AmsWebServer::indexHtml, this));
server.on("/config/meter", std::bind(&AmsWebServer::configMeterHtml, this));
server.on("/config/wifi", std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config/mqtt", std::bind(&AmsWebServer::configMqttHtml, this));
server.on("/config/web", std::bind(&AmsWebServer::configWebHtml, this));
server.on("/config-meter", std::bind(&AmsWebServer::configMeterHtml, this));
server.on("/config-wifi", std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config-mqtt", std::bind(&AmsWebServer::configMqttHtml, this));
server.on("/config-web", std::bind(&AmsWebServer::configWebHtml, this));
server.on("/boot.css", std::bind(&AmsWebServer::bootCss, this));
server.on("/gaugemeter.js", std::bind(&AmsWebServer::gaugemeterJs, this));
server.on("/data.json", std::bind(&AmsWebServer::dataJson, this));
@ -57,14 +57,15 @@ void AmsWebServer::setJson(StaticJsonDocument<1024> json) {
u3 = json["data"]["U3"].as<double>();
i3 = json["data"]["I3"].as<double>();
}
}
if(maxPwr == 0 && config->hasConfig() && config->getMainFuse() > 0 && config->getDistributionSystem() > 0) {
int volt = config->getDistributionSystem() == 2 ? 400 : 230;
if(u2 > 0) {
maxPwr = config->getMainFuse() * sqrt(3) * volt;
} else {
maxPwr = config->getMainFuse() * 230;
// Only way to determine if you have more than one phase is to run this code here
if(maxPwr == 0 && config->hasConfig() && config->getMainFuse() > 0 && config->getDistributionSystem() > 0) {
int volt = config->getDistributionSystem() == 2 ? 400 : 230;
if(u2 > 0) {
maxPwr = config->getMainFuse() * sqrt(3) * volt;
} else {
maxPwr = config->getMainFuse() * 230;
}
}
}
@ -302,8 +303,6 @@ void AmsWebServer::dataJson() {
String jsonStr;
if(!this->json.isNull() && this->json.containsKey("data")) {
println(" json has data");
int maxPwr = this->maxPwr;
if(maxPwr == 0) {
if(u2 > 0) {
@ -312,18 +311,20 @@ void AmsWebServer::dataJson() {
maxPwr = 10000;
}
}
int maxPrd = config->getProductionCapacity() * 1000;
json["up"] = this->json["up"];
json["t"] = this->json["t"];
json["data"] = this->json["data"];
json["p_pct"] = min(p*100/maxPwr, 100);
json["po_pct"] = min(po*100/maxPrd, 100);
json["p_pct"] = min(p*100/maxPwr, 100);
if(config->getProductionCapacity() > 0) {
int maxPrd = config->getProductionCapacity() * 1000;
json["po_pct"] = min(po*100/maxPrd, 100);
}
} else {
json["p_pct"] = -1;
json["po_pct"] = -1;
println(" json is empty");
json["p_pct"] = -1;
json["po_pct"] = -1;
}
unsigned long now = millis();

View File

@ -1,3 +1,15 @@
/* Common custom style */
.bg-purple {
background-color: var(--purple);
}
.navbar .navbar-nav-svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
/* Ripped necessary style from bootstrap 4.4.1 to make the page look good without internet access. Meant to be overridden by CSS from CDN */
:root {
--blue: #007bff;
@ -62,6 +74,9 @@ body {
.mb-0, .my-0 {
margin-bottom: 0!important;
}
.m-2 {
margin: .5rem!important;
}
.mb-2, .my-2 {
margin-bottom: .5rem!important;
}
@ -92,7 +107,8 @@ body {
}
.border-bottom {
border-bottom: 1px solid #dee2e6!important;
}.rounded {
}
.rounded {
border-radius: .25rem!important;
}
div {
@ -140,10 +156,6 @@ h1, h2, h3, h4, h5, h6 {
margin-right: -15px;
margin-left: -15px;
}
.d-flex {
display: -ms-flexbox!important;
display: flex!important;
}
.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto {
position: relative;
width: 100%;
@ -185,6 +197,22 @@ h1, h2, h3, h4, h5, h6 {
flex: 0 0 75%;
max-width: 75%;
}
.d-none {
display: none!important;
}
.d-flex {
display: -ms-flexbox!important;
display: flex!important;
}
.flex-row {
-ms-flex-direction: row!important;
flex-direction: row!important;
}
.flex-column {
-ms-flex-direction: column!important;
flex-direction: column!important;
}
a {
color: #007bff;
text-decoration: none;
@ -218,6 +246,92 @@ a {
background-color: #007bff;
border-color: #007bff;
}
.navbar {
position: relative;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: justify;
justify-content: space-between;
padding: .5rem 1rem;
}
.navbar-dark .navbar-brand {
color: #fff;
}
.navbar-expand {
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-ms-flex-pack: start;
justify-content: flex-start;
}
.navbar-nav {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.navbar-expand .navbar-nav {
-ms-flex-direction: row;
flex-direction: row;
}
.navbar-brand {
display: inline-block;
padding-top: .3125rem;
padding-bottom: .3125rem;
margin-right: 1rem;
font-size: 1.25rem;
line-height: inherit;
white-space: nowrap;
}
.navbar-dark .navbar-nav .nav-link {
color: rgba(255,255,255,.5);
}
.navbar-expand .navbar-nav .nav-link {
padding-right: .5rem;
padding-left: .5rem;
}
.navbar-nav .nav-link {
padding-right: 0;
padding-left: 0;
}
.nav-link {
display: block;
padding: .5rem 1rem;
}
.badge {
display: inline-block;
padding: .25em .4em;
font-size: 75%;
font-weight: 700;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25rem;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.badge-secondary {
color: #fff;
background-color: #6c757d;
}
.badge-success {
color: #fff;
background-color: #28a745;
}
.badge-warning {
color: #212529;
background-color: #ffc107;
}
.badge-danger {
color: #fff;
background-color: #dc3545;
}
.form-group {
margin-bottom: 1rem;
}
@ -256,6 +370,55 @@ input[type="radio"], input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
.input-group {
position: relative;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-align: stretch;
align-items: stretch;
width: 100%;
}
.input-group-append {
margin-left: -1px;
}
.input-group-append, .input-group-prepend {
display: -ms-flexbox;
display: flex;
}
.input-group>.input-group-append>.btn, .input-group>.input-group-append>.input-group-text, .input-group>.input-group-prepend:first-child>.btn:not(:first-child), .input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child), .input-group>.input-group-prepend:not(:first-child)>.btn, .input-group>.input-group-prepend:not(:first-child)>.input-group-text {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.input-group-text {
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
padding: .375rem .75rem;
margin-bottom: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #495057;
text-align: center;
white-space: nowrap;
background-color: #e9ecef;
border: 1px solid #ced4da;
border-radius: .25rem;
}
.input-group>.custom-select:not(:last-child), .input-group>.form-control:not(:last-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group>.custom-file, .input-group>.custom-select, .input-group>.form-control, .input-group>.form-control-plaintext {
position: relative;
-ms-flex: 1 1 0%;
flex: 1 1 0%;
min-width: 0;
margin-bottom: 0;
}
hr {
margin-top: 1rem;
margin-bottom: 1rem;
@ -265,6 +428,23 @@ hr {
height: 0;
overflow: visible;
}
ul {
display: block;
list-style-type: disc;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 40px;
}
li {
display: list-item;
text-align: -webkit-match-parent;
}
dl, ol, ul {
margin-top: 0;
margin-bottom: 1rem;
}
@media (min-width: 576px) {
.container, .container-sm {
@ -275,6 +455,11 @@ hr {
.container, .container-md, .container-sm {
max-width: 720px;
}
.col-md-3 {
-ms-flex: 0 0 25%;
flex: 0 0 25%;
max-width: 25%;
}
.col-md-4 {
-ms-flex: 0 0 33.333333%;
flex: 0 0 33.333333%;
@ -285,6 +470,17 @@ hr {
flex: 0 0 50%;
max-width: 50%;
}
.d-md-flex {
display: -ms-flexbox!important;
display: flex!important;
}
.flex-md-row {
-ms-flex-direction: row!important;
flex-direction: row!important;
}
.ml-md-auto, .mx-md-auto {
margin-left: auto!important;
}
}
@media (min-width: 992px) {
.container, .container-lg, .container-md, .container-sm {

View File

@ -6,18 +6,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="boot.css"/>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
<style>
.bg-purple {
background-color: var(--purple);
}
.navbar .navbar-nav-svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
</style>
</head>
<body class="bg-light">
<main role="main" class="container">
@ -26,16 +14,16 @@
<div class="navbar-nav-scroll">
<ul class="navbar-nav bd-navbar-nav flex-row">
<li class="nav-item">
<a class="nav-link active" href="/config/meter">Meter</a>
<a class="nav-link active" href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/wifi">WiFi</a>
<a class="nav-link " href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/mqtt">MQTT</a>
<a class="nav-link " href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/web">Web</a>
<a class="nav-link " href="/config-web">Web</a>
</li>
</ul>
</div>

View File

@ -7,18 +7,6 @@
<link rel="stylesheet" type="text/css" href="boot.css"/>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<style>
.bg-purple {
background-color: var(--purple);
}
.navbar .navbar-nav-svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
</style>
</head>
<body class="bg-light">
<main role="main" class="container">
@ -27,16 +15,16 @@
<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>
<a class="nav-link " href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/wifi">WiFi</a>
<a class="nav-link " href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/config/mqtt">MQTT</a>
<a class="nav-link active" href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/web">Web</a>
<a class="nav-link " href="/config-web">Web</a>
</li>
</ul>
</div>

View File

@ -7,18 +7,6 @@
<link rel="stylesheet" type="text/css" href="boot.css"/>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<style>
.bg-purple {
background-color: var(--purple);
}
.navbar .navbar-nav-svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
</style>
</head>
<body class="bg-light">
<main role="main" class="container">
@ -27,16 +15,16 @@
<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>
<a class="nav-link" href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/wifi">WiFi</a>
<a class="nav-link " href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/mqtt">MQTT</a>
<a class="nav-link " href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/config/web">Web</a>
<a class="nav-link active" href="/config-web">Web</a>
</li>
</ul>
</div>

View File

@ -7,18 +7,6 @@
<link rel="stylesheet" type="text/css" href="boot.css"/>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<style>
.bg-purple {
background-color: var(--purple);
}
.navbar .navbar-nav-svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
</style>
</head>
<body class="bg-light">
<main role="main" class="container">
@ -27,16 +15,16 @@
<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>
<a class="nav-link " href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/config/wifi">WiFi</a>
<a class="nav-link active" href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/mqtt">MQTT</a>
<a class="nav-link " href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/web">Web</a>
<a class="nav-link " href="/config-web">Web</a>
</li>
</ul>
</div>

View File

@ -10,17 +10,6 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="gaugemeter.js"></script>
<style>
.bg-purple {
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;
@ -69,16 +58,16 @@
<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>
<a class="nav-link " href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/wifi">WiFi</a>
<a class="nav-link " href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/mqtt">MQTT</a>
<a class="nav-link " href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config/web">Web</a>
<a class="nav-link " href="/config-web">Web</a>
</li>
</ul>
</div>
@ -218,7 +207,16 @@ pm.gaugeMeter({
append: "W"
});
var interval = 2500;
var setStatus = function(id, status) {
var item = $('#'+id);
item.removeClass('d-none');
item.removeClass (function (index, className) {
return (className.match (/(^|\s)badge-\S+/g) || []).join(' ');
});
item.addClass('badge badge-' + status);
};
var interval = 10000;
var fetch = function() {
$.ajax({
url: '/data.json',
@ -248,13 +246,7 @@ var fetch = function() {
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);
setStatus(id, json.status[id]);
}
}
@ -336,6 +328,8 @@ var fetch = function() {
}
setTimeout(fetch, interval);
}).fail(function() {
setTimeout(fetch, interval*4);
cm.gaugeMeter({
percent: 0,
text: "-",
@ -347,7 +341,11 @@ var fetch = function() {
text: "-",
append: "W"
});
setTimeout(fetch, interval*4);
setStatus("mqtt", "secondary");
setStatus("wifi", "secondary");
setStatus("han", "secondary");
setStatus("esp", "danger");
});
}
fetch();