mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-05-01 05:59:24 +00:00
Even more v2.2
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,4 +16,5 @@ platformio-user.ini
|
|||||||
/.tmp
|
/.tmp
|
||||||
/*.zip
|
/*.zip
|
||||||
node_modules
|
node_modules
|
||||||
/gui/dist
|
/gui/dist
|
||||||
|
/scripts/*dev
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ protected:
|
|||||||
bool threePhase = false, twoPhase = false, counterEstimated = false;
|
bool threePhase = false, twoPhase = false, counterEstimated = false;
|
||||||
|
|
||||||
int8_t lastError = 0x00;
|
int8_t lastError = 0x00;
|
||||||
|
uint8_t lastErrorCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -216,9 +216,14 @@ bool AmsData::isTwoPhase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int8_t AmsData::getLastError() {
|
int8_t AmsData::getLastError() {
|
||||||
return lastError;
|
return lastErrorCount > 3 ? lastError : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmsData::setLastError(int8_t lastError) {
|
void AmsData::setLastError(int8_t lastError) {
|
||||||
this->lastError = lastError;
|
this->lastError = lastError;
|
||||||
|
if(lastError == 0) {
|
||||||
|
lastErrorCount = 0;
|
||||||
|
} else {
|
||||||
|
lastErrorCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "DnbCurrParser.h"
|
#include "DnbCurrParser.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "ams/GcmParser.h"
|
#include "GcmParser.h"
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
|
|||||||
@@ -193,9 +193,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="my-1">
|
<div class="my-1">
|
||||||
<label><input type="checkbox" name="pe" bind:checked={configuration.p.e} class="rounded mb-1"/> Enable price fetch from remote server</label>
|
<label><input type="checkbox" name="pe" value="true" bind:checked={configuration.p.e} class="rounded mb-1"/> Enable price fetch from remote server</label>
|
||||||
{#if configuration.p.e && sysinfo.chip != 'esp8266'}
|
{#if configuration.p.e && sysinfo.chip != 'esp8266'}
|
||||||
<br/><input name="pt" bind:value={configuration.p.t} type="text" class="in-s"/>
|
<br/><input name="pt" bind:value={configuration.p.t} type="text" class="in-s" placeholder="Optional, read docs"/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="my-1">
|
<div class="my-1">
|
||||||
@@ -443,7 +443,7 @@
|
|||||||
<option value={2}>Raw (full)</option>
|
<option value={2}>Raw (full)</option>
|
||||||
<option value={3}>Domoticz</option>
|
<option value={3}>Domoticz</option>
|
||||||
<option value={4}>HomeAssistant</option>
|
<option value={4}>HomeAssistant</option>
|
||||||
<option value={255}>Raw bytes</option>
|
<option value={255}>HEX dump</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -68,12 +68,12 @@
|
|||||||
<div class="cnt">
|
<div class="cnt">
|
||||||
<AccountingData data={data.ea} currency={prices.currency}/>
|
<AccountingData data={data.ea} currency={prices.currency}/>
|
||||||
</div>
|
</div>
|
||||||
{#if data && data.ea}
|
{#if data && data.pr && (data.pr.startsWith("10YNO") || data.pr == '10Y1001A1001A48H')}
|
||||||
<div class="cnt h-64">
|
<div class="cnt h-64">
|
||||||
<TariffPeakChart data={data.ea} />
|
<TariffPeakChart />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if prices.currency}
|
{#if (typeof data.p == "number") && !Number.isNaN(data.p)}
|
||||||
<div class="cnt xl:col-span-6 lg:col-span-3 md:col-span-3 sm:col-span-2 h-64">
|
<div class="cnt xl:col-span-6 lg:col-span-3 md:col-span-3 sm:col-span-2 h-64">
|
||||||
<PricePlot json={prices}/>
|
<PricePlot json={prices}/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public:
|
|||||||
void setTimezone(Timezone* tz);
|
void setTimezone(Timezone* tz);
|
||||||
void setMqttEnabled(bool);
|
void setMqttEnabled(bool);
|
||||||
void setEntsoeApi(EntsoeApi* eapi);
|
void setEntsoeApi(EntsoeApi* eapi);
|
||||||
|
void setPriceRegion(String);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RemoteDebug* debugger;
|
RemoteDebug* debugger;
|
||||||
@@ -59,6 +60,7 @@ private:
|
|||||||
bool performRestart = false;
|
bool performRestart = false;
|
||||||
bool performUpgrade = false;
|
bool performUpgrade = false;
|
||||||
bool rebootForUpgrade = false;
|
bool rebootForUpgrade = false;
|
||||||
|
String priceRegion;
|
||||||
|
|
||||||
static const uint16_t BufferSize = 2048;
|
static const uint16_t BufferSize = 2048;
|
||||||
char* buf;
|
char* buf;
|
||||||
@@ -89,6 +91,7 @@ private:
|
|||||||
void handleSave();
|
void handleSave();
|
||||||
void reboot();
|
void reboot();
|
||||||
void upgrade();
|
void upgrade();
|
||||||
|
void firmwareHtml();
|
||||||
void firmwarePost();
|
void firmwarePost();
|
||||||
void firmwareUpload();
|
void firmwareUpload();
|
||||||
void isAliveCheck();
|
void isAliveCheck();
|
||||||
|
|||||||
6
lib/SvelteUi/json/firmware.html
Normal file
6
lib/SvelteUi/json/firmware.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<form action="/firmware" enctype="multipart/form-data" method="post">
|
||||||
|
<input name="file" type="file" accept=".bin">
|
||||||
|
<button type="submit" class="">Upload</button>
|
||||||
|
</form>
|
||||||
|
</html>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "html/conf_thresholds_json.h"
|
#include "html/conf_thresholds_json.h"
|
||||||
#include "html/conf_debug_json.h"
|
#include "html/conf_debug_json.h"
|
||||||
#include "html/conf_gpio_json.h"
|
#include "html/conf_gpio_json.h"
|
||||||
|
#include "html/firmware_html.h"
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -74,6 +75,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter
|
|||||||
server.on(F("/save"), HTTP_POST, std::bind(&AmsWebServer::handleSave, this));
|
server.on(F("/save"), HTTP_POST, std::bind(&AmsWebServer::handleSave, this));
|
||||||
server.on(F("/reboot"), HTTP_POST, std::bind(&AmsWebServer::reboot, this));
|
server.on(F("/reboot"), HTTP_POST, std::bind(&AmsWebServer::reboot, this));
|
||||||
server.on(F("/upgrade"), HTTP_POST, std::bind(&AmsWebServer::upgrade, this));
|
server.on(F("/upgrade"), HTTP_POST, std::bind(&AmsWebServer::upgrade, this));
|
||||||
|
server.on(F("/firmware"), HTTP_GET, std::bind(&AmsWebServer::firmwareHtml, this));
|
||||||
server.on(F("/firmware"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::firmwareUpload, this));
|
server.on(F("/firmware"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::firmwareUpload, this));
|
||||||
server.on(F("/is-alive"), HTTP_GET, std::bind(&AmsWebServer::isAliveCheck, this));
|
server.on(F("/is-alive"), HTTP_GET, std::bind(&AmsWebServer::isAliveCheck, this));
|
||||||
|
|
||||||
@@ -223,8 +225,13 @@ void AmsWebServer::sysinfoJson() {
|
|||||||
WiFi.localIP().toString().c_str(),
|
WiFi.localIP().toString().c_str(),
|
||||||
WiFi.subnetMask().toString().c_str(),
|
WiFi.subnetMask().toString().c_str(),
|
||||||
WiFi.gatewayIP().toString().c_str(),
|
WiFi.gatewayIP().toString().c_str(),
|
||||||
|
#if defined(ESP8266)
|
||||||
dns1.isSet() ? dns1.toString().c_str() : "",
|
dns1.isSet() ? dns1.toString().c_str() : "",
|
||||||
dns2.isSet() ? dns2.toString().c_str() : "",
|
dns2.isSet() ? dns2.toString().c_str() : "",
|
||||||
|
#else
|
||||||
|
dns1.toString().c_str(),
|
||||||
|
dns2.toString().c_str(),
|
||||||
|
#endif
|
||||||
meterState->getMeterType(),
|
meterState->getMeterType(),
|
||||||
meterState->getMeterModel().c_str(),
|
meterState->getMeterModel().c_str(),
|
||||||
meterState->getMeterId().c_str()
|
meterState->getMeterId().c_str()
|
||||||
@@ -323,7 +330,7 @@ void AmsWebServer::dataJson() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float price = ENTSOE_NO_VALUE;
|
float price = ENTSOE_NO_VALUE;
|
||||||
if(eapi != NULL && strlen(eapi->getToken()) > 0)
|
if(eapi != NULL)
|
||||||
price = eapi->getValueForHour(0);
|
price = eapi->getValueForHour(0);
|
||||||
|
|
||||||
String peaks = "";
|
String peaks = "";
|
||||||
@@ -382,7 +389,7 @@ void AmsWebServer::dataJson() {
|
|||||||
ea->getCostThisMonth(),
|
ea->getCostThisMonth(),
|
||||||
ea->getProducedThisMonth(),
|
ea->getProducedThisMonth(),
|
||||||
ea->getIncomeThisMonth(),
|
ea->getIncomeThisMonth(),
|
||||||
eapi == NULL ? "" : eapi->getArea(),
|
priceRegion.c_str(),
|
||||||
meterState->getLastError(),
|
meterState->getLastError(),
|
||||||
(uint32_t) time(nullptr)
|
(uint32_t) time(nullptr)
|
||||||
);
|
);
|
||||||
@@ -1219,10 +1226,13 @@ void AmsWebServer::handleSave() {
|
|||||||
|
|
||||||
if(server.hasArg(F("p")) && server.arg(F("p")) == F("true")) {
|
if(server.hasArg(F("p")) && server.arg(F("p")) == F("true")) {
|
||||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received price API config"));
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received price API config"));
|
||||||
|
|
||||||
|
priceRegion = server.arg(F("pr"));
|
||||||
|
|
||||||
EntsoeConfig entsoe;
|
EntsoeConfig entsoe;
|
||||||
entsoe.enabled = server.hasArg(F("pe")) && server.arg(F("pe")) == F("true");
|
entsoe.enabled = server.hasArg(F("pe")) && server.arg(F("pe")) == F("true");
|
||||||
strcpy(entsoe.token, server.arg(F("pt")).c_str());
|
strcpy(entsoe.token, server.arg(F("pt")).c_str());
|
||||||
strcpy(entsoe.area, server.arg(F("pr")).c_str());
|
strcpy(entsoe.area, priceRegion.c_str());
|
||||||
strcpy(entsoe.currency, server.arg(F("pc")).c_str());
|
strcpy(entsoe.currency, server.arg(F("pc")).c_str());
|
||||||
entsoe.multiplier = server.arg(F("pm")).toFloat() * 1000;
|
entsoe.multiplier = server.arg(F("pm")).toFloat() * 1000;
|
||||||
config->setEntsoeConfig(entsoe);
|
config->setEntsoeConfig(entsoe);
|
||||||
@@ -1368,6 +1378,19 @@ void AmsWebServer::upgrade() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void AmsWebServer::firmwareHtml() {
|
||||||
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Serving /firmware.html over http..."));
|
||||||
|
|
||||||
|
server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE);
|
||||||
|
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
|
||||||
|
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
|
||||||
|
|
||||||
|
if(!checkSecurity(1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
server.setContentLength(FIRMWARE_HTML_LEN);
|
||||||
|
server.send_P(200, MIME_HTML, FIRMWARE_HTML);
|
||||||
|
}
|
||||||
|
|
||||||
void AmsWebServer::firmwarePost() {
|
void AmsWebServer::firmwarePost() {
|
||||||
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Handling firmware post..."));
|
if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Handling firmware post..."));
|
||||||
@@ -1610,4 +1633,8 @@ void AmsWebServer::tariffJson() {
|
|||||||
|
|
||||||
server.setContentLength(strlen(buf));
|
server.setContentLength(strlen(buf));
|
||||||
server.send(200, MIME_JSON, buf);
|
server.send(200, MIME_JSON, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AmsWebServer::setPriceRegion(String priceRegion) {
|
||||||
|
this->priceRegion = priceRegion;
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
extra_configs = platformio-user.ini
|
extra_configs = platformio-user.ini
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi
|
lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi
|
||||||
lib_ignore = OneWire
|
lib_ignore = OneWire
|
||||||
extra_scripts =
|
extra_scripts =
|
||||||
pre:scripts/addversion.py
|
pre:scripts/addversion.py
|
||||||
@@ -25,8 +25,6 @@ lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP826
|
|||||||
lib_ignore = ${common.lib_ignore}
|
lib_ignore = ${common.lib_ignore}
|
||||||
extra_scripts = ${common.extra_scripts}
|
extra_scripts = ${common.extra_scripts}
|
||||||
|
|
||||||
# Sticking to v2.0.3 because of #298
|
|
||||||
|
|
||||||
[env:esp32]
|
[env:esp32]
|
||||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip
|
platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ ADC_MODE(ADC_VCC);
|
|||||||
#include "IEC6205675.h"
|
#include "IEC6205675.h"
|
||||||
#include "LNG.h"
|
#include "LNG.h"
|
||||||
|
|
||||||
#include "ams/DataParsers.h"
|
#include "DataParsers.h"
|
||||||
#include "Timezones.h"
|
#include "Timezones.h"
|
||||||
|
|
||||||
uint8_t commonBuffer[BUF_SIZE_COMMON];
|
uint8_t commonBuffer[BUF_SIZE_COMMON];
|
||||||
@@ -201,11 +201,12 @@ void setup() {
|
|||||||
hw.ledBlink(LED_BLUE, 1);
|
hw.ledBlink(LED_BLUE, 1);
|
||||||
|
|
||||||
EntsoeConfig entsoe;
|
EntsoeConfig entsoe;
|
||||||
if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) {
|
if(config.getEntsoeConfig(entsoe) && entsoe.enabled && strlen(entsoe.area) > 0) {
|
||||||
eapi = new EntsoeApi(&Debug);
|
eapi = new EntsoeApi(&Debug);
|
||||||
eapi->setup(entsoe);
|
eapi->setup(entsoe);
|
||||||
ws.setEntsoeApi(eapi);
|
ws.setEntsoeApi(eapi);
|
||||||
}
|
}
|
||||||
|
ws.setPriceRegion(entsoe.area);
|
||||||
bool shared = false;
|
bool shared = false;
|
||||||
config.getMeterConfig(meterConfig);
|
config.getMeterConfig(meterConfig);
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
@@ -520,7 +521,7 @@ void loop() {
|
|||||||
|
|
||||||
if(config.isEntsoeChanged()) {
|
if(config.isEntsoeChanged()) {
|
||||||
EntsoeConfig entsoe;
|
EntsoeConfig entsoe;
|
||||||
if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) {
|
if(config.getEntsoeConfig(entsoe) && entsoe.enabled && strlen(entsoe.area) > 0) {
|
||||||
if(eapi == NULL) {
|
if(eapi == NULL) {
|
||||||
eapi = new EntsoeApi(&Debug);
|
eapi = new EntsoeApi(&Debug);
|
||||||
ea.setEapi(eapi);
|
ea.setEapi(eapi);
|
||||||
@@ -532,6 +533,7 @@ void loop() {
|
|||||||
eapi = NULL;
|
eapi = NULL;
|
||||||
ws.setEntsoeApi(NULL);
|
ws.setEntsoeApi(NULL);
|
||||||
}
|
}
|
||||||
|
ws.setPriceRegion(entsoe.area);
|
||||||
config.ackEntsoeChange();
|
config.ackEntsoeChange();
|
||||||
}
|
}
|
||||||
} catch(const std::exception& e) {
|
} catch(const std::exception& e) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "IEC6205621.h"
|
#include "IEC6205621.h"
|
||||||
#include "ams/crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
IEC6205621::IEC6205621(const char* p) {
|
IEC6205621::IEC6205621(const char* p) {
|
||||||
if(strlen(p) < 16)
|
if(strlen(p) < 16)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "IEC6205675.h"
|
#include "IEC6205675.h"
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "Timezone.h"
|
#include "Timezone.h"
|
||||||
#include "ams/ntohll.h"
|
#include "ntohll.h"
|
||||||
|
|
||||||
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx) {
|
IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx) {
|
||||||
double val;
|
double val;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "AmsData.h"
|
#include "AmsData.h"
|
||||||
#include "AmsConfiguration.h"
|
#include "AmsConfiguration.h"
|
||||||
#include "ams/DataParser.h"
|
#include "DataParser.h"
|
||||||
#include "ams/Cosem.h"
|
#include "Cosem.h"
|
||||||
|
|
||||||
#define NOVALUE 0xFFFFFFFF
|
#define NOVALUE 0xFFFFFFFF
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "LNG.h"
|
#include "LNG.h"
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "ams/ntohll.h"
|
#include "ntohll.h"
|
||||||
|
|
||||||
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
|
LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) {
|
||||||
LngHeader* h = (LngHeader*) payload;
|
LngHeader* h = (LngHeader*) payload;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "AmsData.h"
|
#include "AmsData.h"
|
||||||
#include "AmsConfiguration.h"
|
#include "AmsConfiguration.h"
|
||||||
#include "ams/DataParser.h"
|
#include "DataParser.h"
|
||||||
#include "ams/Cosem.h"
|
#include "Cosem.h"
|
||||||
#include "RemoteDebug.h"
|
#include "RemoteDebug.h"
|
||||||
|
|
||||||
struct LngHeader {
|
struct LngHeader {
|
||||||
|
|||||||
Reference in New Issue
Block a user