mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-29 19:39:07 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b0ec39759 |
@@ -751,7 +751,7 @@ bool readHanPort() {
|
|||||||
debugD("Frame dump (%db):", len);
|
debugD("Frame dump (%db):", len);
|
||||||
debugPrint(buf, 0, len);
|
debugPrint(buf, 0, len);
|
||||||
}
|
}
|
||||||
if(hc != NULL && Debug.isActive(RemoteDebug::DEBUG)) {
|
if(hc != NULL && Debug.isActive(RemoteDebug::VERBOSE)) {
|
||||||
debugD("System title:");
|
debugD("System title:");
|
||||||
debugPrint(hc->system_title, 0, 8);
|
debugPrint(hc->system_title, 0, 8);
|
||||||
debugD("Initialization vector:");
|
debugD("Initialization vector:");
|
||||||
@@ -764,7 +764,7 @@ bool readHanPort() {
|
|||||||
len = 0;
|
len = 0;
|
||||||
while(hanSerial->available()) hanSerial->read();
|
while(hanSerial->available()) hanSerial->read();
|
||||||
if(pos > 0) {
|
if(pos > 0) {
|
||||||
debugI("Valid data, start at byte %d", pos);
|
debugD("Valid data, start at byte %d", pos);
|
||||||
data = IEC6205675(((char *) (buf)) + pos, meterState.getMeterType(), meterConfig.distributionSystem, timestamp, hc);
|
data = IEC6205675(((char *) (buf)) + pos, meterState.getMeterType(), meterConfig.distributionSystem, timestamp, hc);
|
||||||
} else {
|
} else {
|
||||||
if(Debug.isActive(RemoteDebug::WARNING)) {
|
if(Debug.isActive(RemoteDebug::WARNING)) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "DnbCurrParser.h"
|
#include "DnbCurrParser.h"
|
||||||
|
#include "Arduino.h"
|
||||||
#include "HardwareSerial.h"
|
#include "HardwareSerial.h"
|
||||||
|
|
||||||
float DnbCurrParser::getValue() {
|
float DnbCurrParser::getValue() {
|
||||||
@@ -35,7 +36,22 @@ size_t DnbCurrParser::write(uint8_t byte) {
|
|||||||
}
|
}
|
||||||
} else if(byte == '>') {
|
} else if(byte == '>') {
|
||||||
buf[pos++] = byte;
|
buf[pos++] = byte;
|
||||||
if(strncmp(buf, "<Obs", 4) == 0) {
|
if(strncmp(buf, "<Series", 7) == 0) {
|
||||||
|
for(int i = 0; i < pos; i++) {
|
||||||
|
if(strncmp(buf+i, "UNIT_MULT=\"", 11) == 0) {
|
||||||
|
pos = i + 11;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 16; i++) {
|
||||||
|
uint8_t b = buf[pos+i];
|
||||||
|
if(b == '"') {
|
||||||
|
buf[pos+i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scale = String(buf+pos).toInt();
|
||||||
|
} else if(strncmp(buf, "<Obs", 4) == 0) {
|
||||||
for(int i = 0; i < pos; i++) {
|
for(int i = 0; i < pos; i++) {
|
||||||
if(strncmp(buf+i, "OBS_VALUE=\"", 11) == 0) {
|
if(strncmp(buf+i, "OBS_VALUE=\"", 11) == 0) {
|
||||||
pos = i + 11;
|
pos = i + 11;
|
||||||
@@ -49,7 +65,7 @@ size_t DnbCurrParser::write(uint8_t byte) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value = String(buf+pos).toFloat();
|
value = String(buf+pos).toFloat() / pow(10, scale);
|
||||||
}
|
}
|
||||||
pos = 0;
|
pos = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public:
|
|||||||
size_t write(uint8_t);
|
size_t write(uint8_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t scale = 0;
|
||||||
float value = 1.0;
|
float value = 1.0;
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|||||||
@@ -4,17 +4,16 @@
|
|||||||
#include "TimeLib.h"
|
#include "TimeLib.h"
|
||||||
#include "DnbCurrParser.h"
|
#include "DnbCurrParser.h"
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP32)
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <esp_task_wdt.h>
|
||||||
#elif defined(ESP32) // ARDUINO_ARCH_ESP32
|
|
||||||
#include <HTTPClient.h>
|
|
||||||
#else
|
|
||||||
#warning "Unsupported board type"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EntsoeApi::EntsoeApi(RemoteDebug* Debug) {
|
EntsoeApi::EntsoeApi(RemoteDebug* Debug) {
|
||||||
debugger = Debug;
|
debugger = Debug;
|
||||||
|
|
||||||
|
client.setInsecure();
|
||||||
|
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||||
|
|
||||||
// Entso-E uses CET/CEST
|
// Entso-E uses CET/CEST
|
||||||
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};
|
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};
|
||||||
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};
|
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};
|
||||||
@@ -26,6 +25,7 @@ void EntsoeApi::setup(EntsoeConfig& config) {
|
|||||||
this->config = new EntsoeConfig();
|
this->config = new EntsoeConfig();
|
||||||
}
|
}
|
||||||
memcpy(this->config, &config, sizeof(config));
|
memcpy(this->config, &config, sizeof(config));
|
||||||
|
lastCurrencyFetch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* EntsoeApi::getToken() {
|
char* EntsoeApi::getToken() {
|
||||||
@@ -79,7 +79,6 @@ float EntsoeApi::getValueForHour(time_t cur, uint8_t hour) {
|
|||||||
bool EntsoeApi::loop() {
|
bool EntsoeApi::loop() {
|
||||||
if(strlen(getToken()) == 0)
|
if(strlen(getToken()) == 0)
|
||||||
return false;
|
return false;
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
uint64_t now = millis64();
|
uint64_t now = millis64();
|
||||||
if(now < 10000) return false; // Grace period
|
if(now < 10000) return false; // Grace period
|
||||||
@@ -121,15 +120,23 @@ bool EntsoeApi::loop() {
|
|||||||
d2.Year+1970, d2.Month, d2.Day, 23, 00,
|
d2.Year+1970, d2.Month, d2.Day, 23, 00,
|
||||||
config->area, config->area);
|
config->area, config->area);
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
ESP.wdtFeed();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for today\n");
|
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for today\n");
|
||||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
||||||
EntsoeA44Parser* a44 = new EntsoeA44Parser();
|
EntsoeA44Parser* a44 = new EntsoeA44Parser();
|
||||||
if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) {
|
if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) {
|
||||||
today = a44;
|
today = a44;
|
||||||
ret = true;
|
return true;
|
||||||
} else if(a44 != NULL) {
|
} else if(a44 != NULL) {
|
||||||
delete a44;
|
delete a44;
|
||||||
today = NULL;
|
today = NULL;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,23 +158,29 @@ bool EntsoeApi::loop() {
|
|||||||
d2.Year+1970, d2.Month, d2.Day, 23, 00,
|
d2.Year+1970, d2.Month, d2.Day, 23, 00,
|
||||||
config->area, config->area);
|
config->area, config->area);
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
ESP.wdtFeed();
|
||||||
|
#endif
|
||||||
|
|
||||||
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for tomorrow\n");
|
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for tomorrow\n");
|
||||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
||||||
EntsoeA44Parser* a44 = new EntsoeA44Parser();
|
EntsoeA44Parser* a44 = new EntsoeA44Parser();
|
||||||
if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) {
|
if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) {
|
||||||
tomorrow = a44;
|
tomorrow = a44;
|
||||||
ret = true;
|
return true;
|
||||||
} else if(a44 != NULL) {
|
} else if(a44 != NULL) {
|
||||||
delete a44;
|
delete a44;
|
||||||
tomorrow = NULL;
|
tomorrow = NULL;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntsoeApi::retrieve(const char* url, Stream* doc) {
|
bool EntsoeApi::retrieve(const char* url, Stream* doc) {
|
||||||
WiFiClientSecure client;
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/bearssl-client-secure-class.html#mfln-or-maximum-fragment-length-negotiation-saving-ram
|
// https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/bearssl-client-secure-class.html#mfln-or-maximum-fragment-length-negotiation-saving-ram
|
||||||
/* Rumor has it that a client cannot request a lower max_fragment_length, so I guess thats why the following does not work.
|
/* Rumor has it that a client cannot request a lower max_fragment_length, so I guess thats why the following does not work.
|
||||||
@@ -185,13 +198,15 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) {
|
|||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
client.setInsecure();
|
|
||||||
|
|
||||||
HTTPClient https;
|
|
||||||
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
|
||||||
|
|
||||||
if(https.begin(client, url)) {
|
if(https.begin(client, url)) {
|
||||||
printD("Connection established");
|
printD("Connection established");
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
ESP.wdtFeed();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
if(!client.getMFLNStatus()) {
|
if(!client.getMFLNStatus()) {
|
||||||
@@ -204,6 +219,13 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int status = https.GET();
|
int status = https.GET();
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
ESP.wdtFeed();
|
||||||
|
#endif
|
||||||
|
|
||||||
if(status == HTTP_CODE_OK) {
|
if(status == HTTP_CODE_OK) {
|
||||||
printD("Receiving data");
|
printD("Receiving data");
|
||||||
https.writeToStream(doc);
|
https.writeToStream(doc);
|
||||||
@@ -241,15 +263,25 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) {
|
|||||||
uint64_t now = millis64();
|
uint64_t now = millis64();
|
||||||
if(lastCurrencyFetch == 0 || now - lastCurrencyFetch > (SECS_PER_HOUR * 1000)) {
|
if(lastCurrencyFetch == 0 || now - lastCurrencyFetch > (SECS_PER_HOUR * 1000)) {
|
||||||
char url[256];
|
char url[256];
|
||||||
snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.%s.SP?lastNObservations=1",
|
|
||||||
from,
|
|
||||||
to
|
|
||||||
);
|
|
||||||
|
|
||||||
DnbCurrParser p;
|
DnbCurrParser p;
|
||||||
|
|
||||||
|
snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", from);
|
||||||
|
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Retrieving %s to NOK conversion\n", from);
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
||||||
if(retrieve(url, &p)) {
|
if(retrieve(url, &p)) {
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) got exchange rate %.4f\n", p.getValue());
|
||||||
currencyMultiplier = p.getValue();
|
currencyMultiplier = p.getValue();
|
||||||
|
if(strncmp(to, "NOK", 3) != 0) {
|
||||||
|
snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", to);
|
||||||
|
if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Retrieving %s to NOK conversion\n", to);
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url);
|
||||||
|
if(retrieve(url, &p)) {
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) got exchange rate %.4f\n", p.getValue());
|
||||||
|
currencyMultiplier /= p.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) Resulting currency multiplier: %.4f\n", currencyMultiplier);
|
||||||
lastCurrencyFetch = now;
|
lastCurrencyFetch = now;
|
||||||
}
|
}
|
||||||
return currencyMultiplier;
|
return currencyMultiplier;
|
||||||
|
|||||||
@@ -7,6 +7,14 @@
|
|||||||
#include "EntsoeA44Parser.h"
|
#include "EntsoeA44Parser.h"
|
||||||
#include "AmsConfiguration.h"
|
#include "AmsConfiguration.h"
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
#elif defined(ESP32) // ARDUINO_ARCH_ESP32
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
#else
|
||||||
|
#warning "Unsupported board type"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ENTSOE_DEFAULT_MULTIPLIER 1.00
|
#define ENTSOE_DEFAULT_MULTIPLIER 1.00
|
||||||
#define SSL_BUF_SIZE 512
|
#define SSL_BUF_SIZE 512
|
||||||
|
|
||||||
@@ -24,6 +32,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
RemoteDebug* debugger;
|
RemoteDebug* debugger;
|
||||||
EntsoeConfig* config = NULL;
|
EntsoeConfig* config = NULL;
|
||||||
|
WiFiClientSecure client;
|
||||||
|
HTTPClient https;
|
||||||
|
|
||||||
uint64_t midnightMillis = 0;
|
uint64_t midnightMillis = 0;
|
||||||
uint64_t lastTodayFetch = 0;
|
uint64_t lastTodayFetch = 0;
|
||||||
|
|||||||
@@ -498,12 +498,21 @@ void AmsWebServer::configWifiHtml() {
|
|||||||
|
|
||||||
html.replace("{s}", wifi.ssid);
|
html.replace("{s}", wifi.ssid);
|
||||||
html.replace("{p}", wifi.psk);
|
html.replace("{p}", wifi.psk);
|
||||||
html.replace("{st}", strlen(wifi.ip) > 0 ? "checked" : "");
|
if(strlen(wifi.ip) > 0) {
|
||||||
html.replace("{i}", wifi.ip);
|
html.replace("{st}", "checked");
|
||||||
html.replace("{g}", wifi.gateway);
|
html.replace("{i}", wifi.ip);
|
||||||
html.replace("{sn}", wifi.subnet);
|
html.replace("{g}", wifi.gateway);
|
||||||
html.replace("{d1}", wifi.dns1);
|
html.replace("{sn}", wifi.subnet);
|
||||||
html.replace("{d2}", wifi.dns2);
|
html.replace("{d1}", wifi.dns1);
|
||||||
|
html.replace("{d2}", wifi.dns2);
|
||||||
|
} else {
|
||||||
|
html.replace("{st}", "");
|
||||||
|
html.replace("{i}", WiFi.localIP().toString());
|
||||||
|
html.replace("{g}", WiFi.gatewayIP().toString());
|
||||||
|
html.replace("{sn}", WiFi.subnetMask().toString());
|
||||||
|
html.replace("{d1}", WiFi.dnsIP().toString());
|
||||||
|
html.replace("{d2}", "");
|
||||||
|
}
|
||||||
html.replace("{h}", wifi.hostname);
|
html.replace("{h}", wifi.hostname);
|
||||||
html.replace("{m}", wifi.mdns ? "checked" : "");
|
html.replace("{m}", wifi.mdns ? "checked" : "");
|
||||||
|
|
||||||
@@ -783,7 +792,8 @@ void AmsWebServer::dataJson() {
|
|||||||
mqtt == NULL ? 0 : (int) mqtt->lastError(),
|
mqtt == NULL ? 0 : (int) mqtt->lastError(),
|
||||||
price == ENTSOE_NO_VALUE ? "null" : String(price, 2).c_str(),
|
price == ENTSOE_NO_VALUE ? "null" : String(price, 2).c_str(),
|
||||||
time(nullptr),
|
time(nullptr),
|
||||||
meterState->getMeterType()
|
meterState->getMeterType(),
|
||||||
|
meterConfig->distributionSystem
|
||||||
);
|
);
|
||||||
|
|
||||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||||
@@ -1269,6 +1279,7 @@ void AmsWebServer::handleSave() {
|
|||||||
strcpy(entsoe.currency, server.arg("ecu").c_str());
|
strcpy(entsoe.currency, server.arg("ecu").c_str());
|
||||||
entsoe.multiplier = server.arg("em").toFloat() * 1000;
|
entsoe.multiplier = server.arg("em").toFloat() * 1000;
|
||||||
config->setEntsoeConfig(entsoe);
|
config->setEntsoeConfig(entsoe);
|
||||||
|
eapi->setup(entsoe);
|
||||||
}
|
}
|
||||||
|
|
||||||
printI("Saving configuration now...");
|
printI("Saving configuration now...");
|
||||||
@@ -1564,6 +1575,7 @@ void AmsWebServer::firmwareUpload() {
|
|||||||
server.send(500, "text/plain", "500: couldn't create file");
|
server.send(500, "text/plain", "500: couldn't create file");
|
||||||
} else {
|
} else {
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
|
esp_task_wdt_delete(NULL);
|
||||||
esp_task_wdt_deinit();
|
esp_task_wdt_deinit();
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
ESP.wdtDisable();
|
ESP.wdtDisable();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
var nextVersion;
|
var nextVersion;
|
||||||
var im, em;
|
var im, em;
|
||||||
|
var ds = 0;
|
||||||
|
|
||||||
// Price plot
|
// Price plot
|
||||||
var pp;
|
var pp;
|
||||||
@@ -231,9 +232,9 @@ $(function() {
|
|||||||
// For wifi
|
// For wifi
|
||||||
$('#st').on('change', function() {
|
$('#st').on('change', function() {
|
||||||
if($(this).is(':checked')) {
|
if($(this).is(':checked')) {
|
||||||
$('#i').show();
|
$('.sip').prop('disabled', false);
|
||||||
} else {
|
} else {
|
||||||
$('#i').hide();
|
$('.sip').prop('disabled', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#st').trigger('change');
|
$('#st').trigger('change');
|
||||||
@@ -597,12 +598,6 @@ var fetch = function() {
|
|||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
}).done(function(json) {
|
}).done(function(json) {
|
||||||
retrycount = 0;
|
retrycount = 0;
|
||||||
if(im) {
|
|
||||||
$(".SimpleMeter").hide();
|
|
||||||
im.show();
|
|
||||||
em.show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var id in json) {
|
for(var id in json) {
|
||||||
var str = json[id];
|
var str = json[id];
|
||||||
@@ -622,6 +617,8 @@ var fetch = function() {
|
|||||||
$('.ju').html(moment.duration(parseInt(json.u), 'seconds').humanize());
|
$('.ju').html(moment.duration(parseInt(json.u), 'seconds').humanize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds = parseInt(json.ds);
|
||||||
|
|
||||||
var kib = parseInt(json.m)/1000;
|
var kib = parseInt(json.m)/1000;
|
||||||
$('.jm').html(kib.toFixed(1));
|
$('.jm').html(kib.toFixed(1));
|
||||||
if(kib > 32) {
|
if(kib > 32) {
|
||||||
@@ -677,6 +674,14 @@ var fetch = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(vp) {
|
if(vp) {
|
||||||
|
switch(ds) {
|
||||||
|
case 1:
|
||||||
|
vo.title = 'Voltage between';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vo.title = 'Phase voltage';
|
||||||
|
break;
|
||||||
|
}
|
||||||
var c = 0;
|
var c = 0;
|
||||||
var t = 0;
|
var t = 0;
|
||||||
var r = 1;
|
var r = 1;
|
||||||
@@ -686,21 +691,21 @@ var fetch = function() {
|
|||||||
t += u1;
|
t += u1;
|
||||||
c++;
|
c++;
|
||||||
var pct = (Math.max(parseFloat(json.u1)-195.5, 1)*100/69);
|
var pct = (Math.max(parseFloat(json.u1)-195.5, 1)*100/69);
|
||||||
arr[r++] = ['L1', u1, "color: " + voltcol(pct) + ";opacity: 0.9;", u1 + "V"];
|
arr[r++] = [ds == 1 ? 'L1-L2' : 'L1', u1, "color: " + voltcol(pct) + ";opacity: 0.9;", u1 + "V"];
|
||||||
}
|
}
|
||||||
if(json.u2) {
|
if(json.u2) {
|
||||||
var u2 = parseFloat(json.u2);
|
var u2 = parseFloat(json.u2);
|
||||||
t += u2;
|
t += u2;
|
||||||
c++;
|
c++;
|
||||||
var pct = (Math.max(parseFloat(json.u2)-195.5, 1)*100/69);
|
var pct = (Math.max(parseFloat(json.u2)-195.5, 1)*100/69);
|
||||||
arr[r++] = ['L2', u2, "color: " + voltcol(pct) + ";opacity: 0.9;", u2 + "V"];
|
arr[r++] = [ds == 1 ? 'L1-L3' : 'L2', u2, "color: " + voltcol(pct) + ";opacity: 0.9;", u2 + "V"];
|
||||||
}
|
}
|
||||||
if(json.u3) {
|
if(json.u3) {
|
||||||
var u3 = parseFloat(json.u3);
|
var u3 = parseFloat(json.u3);
|
||||||
t += u3;
|
t += u3;
|
||||||
c++;
|
c++;
|
||||||
var pct = (Math.max(parseFloat(json.u3)-195.5, 1)*100/69);
|
var pct = (Math.max(parseFloat(json.u3)-195.5, 1)*100/69);
|
||||||
arr[r++] = ['L3', u3, "color: " + voltcol(pct) + ";opacity: 0.9;", u3 + "V"];
|
arr[r++] = [ds == 1 ? 'L2-L3' : 'L3', u3, "color: " + voltcol(pct) + ";opacity: 0.9;", u3 + "V"];
|
||||||
}
|
}
|
||||||
v = t/c;
|
v = t/c;
|
||||||
if(v > 0) {
|
if(v > 0) {
|
||||||
@@ -710,6 +715,14 @@ var fetch = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ap && json.mf) {
|
if(ap && json.mf) {
|
||||||
|
switch(ds) {
|
||||||
|
case 1:
|
||||||
|
ao.title = 'Current between';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ao.title = 'Phase current';
|
||||||
|
break;
|
||||||
|
}
|
||||||
var a = 0;
|
var a = 0;
|
||||||
var r = 1;
|
var r = 1;
|
||||||
var arr = [['Phase', 'Amperage', { role: 'style' }, { role: 'annotation' }]];
|
var arr = [['Phase', 'Amperage', { role: 'style' }, { role: 'annotation' }]];
|
||||||
@@ -717,19 +730,19 @@ var fetch = function() {
|
|||||||
var i1 = parseFloat(json.i1);
|
var i1 = parseFloat(json.i1);
|
||||||
a = Math.max(a, i1);
|
a = Math.max(a, i1);
|
||||||
var pct = (parseFloat(json.i1)/parseInt(json.mf))*100;
|
var pct = (parseFloat(json.i1)/parseInt(json.mf))*100;
|
||||||
arr[r++] = ['L1', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i1 + "A"];
|
arr[r++] = [ds == 1 ? 'L1-L2' : 'L1', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i1 + "A"];
|
||||||
}
|
}
|
||||||
if(json.i2) {
|
if(json.i2) {
|
||||||
var i2 = parseFloat(json.i2);
|
var i2 = parseFloat(json.i2);
|
||||||
a = Math.max(a, i2);
|
a = Math.max(a, i2);
|
||||||
var pct = (parseFloat(json.i2)/parseInt(json.mf))*100;
|
var pct = (parseFloat(json.i2)/parseInt(json.mf))*100;
|
||||||
arr[r++] = ['L2', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i2 + "A"];
|
arr[r++] = [ds == 1 ? 'L1-L3' : 'L2', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i2 + "A"];
|
||||||
}
|
}
|
||||||
if(json.i3) {
|
if(json.i3) {
|
||||||
var i3 = parseFloat(json.i3);
|
var i3 = parseFloat(json.i3);
|
||||||
a = Math.max(a, i3);
|
a = Math.max(a, i3);
|
||||||
var pct = (parseFloat(json.i3)/parseInt(json.mf))*100;
|
var pct = (parseFloat(json.i3)/parseInt(json.mf))*100;
|
||||||
arr[r++] = ['L3', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i3 + "A"];
|
arr[r++] = [ds == 1 ? 'L2-L3' : 'L3', pct, "color: " + ampcol(pct) + ";opacity: 0.9;", i3 + "A"];
|
||||||
}
|
}
|
||||||
if(a > 0) {
|
if(a > 0) {
|
||||||
aa = google.visualization.arrayToDataTable(arr);
|
aa = google.visualization.arrayToDataTable(arr);
|
||||||
|
|||||||
@@ -32,5 +32,6 @@
|
|||||||
"me" : %d,
|
"me" : %d,
|
||||||
"p" : %s,
|
"p" : %s,
|
||||||
"c" : %lu,
|
"c" : %lu,
|
||||||
"mt" : %d
|
"mt" : %d,
|
||||||
|
"ds" : %d
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">IP</span>
|
<span class="input-group-text">IP</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="i" class="form-control" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{i}"/>
|
<input type="text" name="i" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{i}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-lg-4 form-group">
|
<div class="col-xl-3 col-lg-4 form-group">
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">Subnet</span>
|
<span class="input-group-text">Subnet</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="sn" class="form-control" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{sn}"/>
|
<input type="text" name="sn" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{sn}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-lg-4 form-group">
|
<div class="col-xl-3 col-lg-4 form-group">
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">Gateway</span>
|
<span class="input-group-text">Gateway</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="g" class="form-control" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{g}"/>
|
<input type="text" name="g" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{g}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-4 col-lg-5 form-group">
|
<div class="col-xl-4 col-lg-5 form-group">
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">DNS 1</span>
|
<span class="input-group-text">DNS 1</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="d1" class="form-control" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{d1}"/>
|
<input type="text" name="d1" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{d1}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-4 col-lg-5 form-group">
|
<div class="col-xl-4 col-lg-5 form-group">
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text">DNS 2</span>
|
<span class="input-group-text">DNS 2</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="d2" class="form-control" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{d2}"/>
|
<input type="text" name="d2" class="form-control sip" pattern="\d?\d?\d.\d?\d?\d.\d?\d?\d.\d?\d?\d" value="{d2}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user