diff --git a/src/AmsConfiguration.cpp b/src/AmsConfiguration.cpp index 96648bb9..4cdff6cc 100644 --- a/src/AmsConfiguration.cpp +++ b/src/AmsConfiguration.cpp @@ -743,7 +743,7 @@ bool AmsConfiguration::relocateConfig86() { } bool AmsConfiguration::relocateConfig87() { - MeterConfig87 meter87; + MeterConfig87 meter87 = {0,0,0,0,0,0,0}; MeterConfig meter; EEPROM.begin(EEPROM_SIZE); EEPROM.get(CONFIG_METER_START_87, meter87); diff --git a/src/AmsData.cpp b/src/AmsData.cpp index f3db56e8..e6d536bf 100644 --- a/src/AmsData.cpp +++ b/src/AmsData.cpp @@ -45,6 +45,12 @@ void AmsData::apply(AmsData& other) { this->l1PowerFactor = other.getL1PowerFactor(); this->l2PowerFactor = other.getL2PowerFactor(); this->l3PowerFactor = other.getL3PowerFactor(); + this->l1activeImportPower = other.getL1ActiveImportPower(); + this->l2activeImportPower = other.getL2ActiveImportPower(); + this->l3activeImportPower = other.getL3ActiveImportPower(); + this->l1activeExportPower = other.getL1ActiveExportPower(); + this->l2activeExportPower = other.getL2ActiveExportPower(); + this->l3activeExportPower = other.getL3ActiveExportPower(); case 3: this->meterTimestamp = other.getMeterTimestamp(); this->activeImportCounter = other.getActiveImportCounter(); @@ -161,6 +167,30 @@ float AmsData::getL3PowerFactor() { return this->l3PowerFactor; } +float AmsData::getL1ActiveImportPower() { + return this->l1activeImportPower; +} + +float AmsData::getL2ActiveImportPower() { + return this->l2activeImportPower; +} + +float AmsData::getL3ActiveImportPower() { + return this->l3activeImportPower; +} + +float AmsData::getL1ActiveExportPower() { + return this->l1activeExportPower; +} + +float AmsData::getL2ActiveExportPower() { + return this->l2activeExportPower; +} + +float AmsData::getL3ActiveExportPower() { + return this->l3activeExportPower; +} + double AmsData::getActiveImportCounter() { return this->activeImportCounter; } diff --git a/src/AmsData.h b/src/AmsData.h index 21d29827..9445472a 100644 --- a/src/AmsData.h +++ b/src/AmsData.h @@ -54,6 +54,14 @@ public: float getL2PowerFactor(); float getL3PowerFactor(); + float getL1ActiveImportPower(); + float getL2ActiveImportPower(); + float getL3ActiveImportPower(); + + float getL1ActiveExportPower(); + float getL2ActiveExportPower(); + float getL3ActiveExportPower(); + double getActiveImportCounter(); double getReactiveImportCounter(); double getActiveExportCounter(); @@ -71,6 +79,8 @@ protected: time_t meterTimestamp = 0; uint16_t activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0; float l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0; + float l1activeImportPower = 0, l2activeImportPower = 0, l3activeImportPower = 0; + float l1activeExportPower = 0, l2activeExportPower = 0, l3activeExportPower = 0; float powerFactor = 0, l1PowerFactor = 0, l2PowerFactor = 0, l3PowerFactor = 0; double activeImportCounter = 0, reactiveImportCounter = 0, activeExportCounter = 0, reactiveExportCounter = 0; bool threePhase = false, twoPhase = false, counterEstimated = false; diff --git a/src/AmsToMqttBridge.h b/src/AmsToMqttBridge.h index aa2e148a..477fbba2 100644 --- a/src/AmsToMqttBridge.h +++ b/src/AmsToMqttBridge.h @@ -1,7 +1,7 @@ #ifndef _AMSTOMQTTBRIDGE_H #define _AMSTOMQTTBRIDGE_H -#define WIFI_CONNECTION_TIMEOUT 30000; +#define WIFI_CONNECTION_TIMEOUT 30000 #define INVALID_BUTTON_PIN 0xFFFFFFFF diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index edf40b8d..f3fc6ed8 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -119,7 +119,6 @@ DLMSParser *dlmsParser = NULL; DSMRParser *dsmrParser = NULL; void setup() { - WiFiConfig wifi; Serial.begin(115200); if(!config.getGpioConfig(gpioConfig)) { @@ -243,7 +242,6 @@ void setup() { } Debug.setSerialEnabled(true); - DebugConfig debug; delay(1); float vcc = hw.getVcc(); @@ -433,6 +431,10 @@ void loop() { } } + if(now > 10000 && now - lastErrorBlink > 3000) { + errorBlink(); + } + // Only do normal stuff if we're not booted as AP if (WiFi.getMode() != WIFI_AP) { if (WiFi.status() != WL_CONNECTED) { @@ -503,10 +505,6 @@ void loop() { MDNS.update(); #endif - if(now > 10000 && now - lastErrorBlink > 3000) { - errorBlink(); - } - if (mqttEnabled || config.isMqttChanged()) { if(mqtt == NULL || !mqtt->connected() || config.isMqttChanged()) { MQTT_connect(); @@ -586,7 +584,7 @@ void loop() { if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { mqttHandler->publishTemperatures(&config, &hw); } - debugD("Used %d ms to update temperature", millis()-start); + debugD("Used %ld ms to update temperature", millis()-start); } if(now - lastSysupdate > 10000) { if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { @@ -720,22 +718,25 @@ void errorBlink() { if(lastError == 3) lastError = 0; lastErrorBlink = millis(); - for(;lastError < 3;lastError++) { - switch(lastError) { + while(lastError < 3) { + switch(lastError++) { case 0: if(lastErrorBlink - meterState.getLastUpdateMillis() > 30000) { + debugW("No HAN data received last 30s, single blink"); hw.ledBlink(LED_RED, 1); // If no message received from AMS in 30 sec, blink once return; } break; case 1: if(mqttEnabled && mqtt != NULL && mqtt->lastError() != 0) { + debugW("MQTT connection not available, double blink"); hw.ledBlink(LED_RED, 2); // If MQTT error, blink twice return; } break; case 2: if(WiFi.getMode() != WIFI_AP && WiFi.status() != WL_CONNECTED) { + debugW("WiFi not connected, tripe blink"); hw.ledBlink(LED_RED, 3); // If WiFi not connected, blink three times return; } @@ -822,6 +823,11 @@ bool readHanPort() { } if(pos == DATA_PARSE_INCOMPLETE) { return false; + } else if(pos == DATA_PARSE_UNKNOWN_DATA) { + len = len + hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len); + debugPrint(hanBuffer, 0, len); + len = 0; + return false; } if(pos == DATA_PARSE_INTERMEDIATE_SEGMENT) { @@ -980,17 +986,34 @@ void debugPrint(byte *buffer, int start, int length) { Debug.println(""); } -unsigned long wifiTimeout = WIFI_CONNECTION_TIMEOUT; unsigned long lastWifiRetry = -WIFI_CONNECTION_TIMEOUT; void WiFi_connect() { - if(millis() - lastWifiRetry < wifiTimeout) { - delay(50); - return; - } - lastWifiRetry = millis(); - if (WiFi.status() != WL_CONNECTED) { + if(WiFi.status() == WL_DISCONNECTED) { + if(millis() - lastWifiRetry < WIFI_CONNECTION_TIMEOUT) { + return; + } + } if(WiFi.getMode() != WIFI_OFF) { + switch(WiFi.status()) { + case WL_NO_SSID_AVAIL: + debugE("WiFi error, no SSID available"); + break; + case WL_CONNECT_FAILED: + debugE("WiFi error, connection failed"); + break; + case WL_CONNECTION_LOST: + debugE("WiFi error, connection lost"); + break; + #if defined(ESP8266) + case WL_WRONG_PASSWORD: + debugE("WiFi error, wrong password"); + break; + #endif + default: + debugE("WiFi error, %d", WiFi.status()); + break; + } if(wifiReconnectCount > 3) { ESP.restart(); return; @@ -1024,11 +1047,13 @@ void WiFi_connect() { WiFi.softAPdisconnect(true); WiFi.enableAP(false); WiFi.mode(WIFI_OFF); + #if defined(ESP8266) + WiFi.forceSleepBegin(); + #endif yield(); - wifiTimeout = 5000; return; } - wifiTimeout = WIFI_CONNECTION_TIMEOUT; + lastWifiRetry = millis(); WiFiConfig wifi; if(!config.getWiFiConfig(wifi) || strlen(wifi.ssid) == 0) { @@ -1116,16 +1141,16 @@ void WiFi_connect() { void mqttMessageReceived(String &topic, String &payload) { debugI("Received message for topic %s", topic.c_str() ); - if(meterConfig.source == METER_SOURCE_MQTT) { - DataParserContext ctx = {payload.length()/2}; - fromHex(hanBuffer, payload, ctx.length); - uint16_t pos = unwrapData(hanBuffer, ctx); + //if(meterConfig.source == METER_SOURCE_MQTT) { + //DataParserContext ctx = {static_cast(payload.length()/2)}; + //fromHex(hanBuffer, payload, ctx.length); + //uint16_t pos = unwrapData(hanBuffer, ctx); // TODO: Run through DLMS/DMSR parser and apply AmsData - } + //} } int16_t unwrapData(uint8_t *buf, DataParserContext &context) { - int16_t ret; + int16_t ret = 0; bool doRet = false; uint16_t end = BUF_SIZE_HAN; uint8_t tag = (*buf); @@ -1370,7 +1395,7 @@ void MQTT_connect() { #if defined(ESP8266) if(mqttSecureClient) { time_t epoch = time(nullptr); - debugD("Setting NTP time %i for secure MQTT connection", epoch); + debugD("Setting NTP time %lld for secure MQTT connection", epoch); mqttSecureClient->setX509Time(epoch); } #endif diff --git a/src/EnergyAccounting.cpp b/src/EnergyAccounting.cpp index d31441fb..87a0d252 100644 --- a/src/EnergyAccounting.cpp +++ b/src/EnergyAccounting.cpp @@ -57,7 +57,7 @@ bool EnergyAccounting::update(AmsData* amsData) { for(uint8_t i = 0; i < 5; i++) { debugger->printf("(EnergyAccounting) Peak hour from day %d: %d\n", data.peaks[i].day, data.peaks[i].value*10); } - debugger->printf("(EnergyAccounting) Loaded cost yesterday: %d, this month: %d, last month: %d\n", data.costYesterday / 10.0, data.costThisMonth, data.costLastMonth); + debugger->printf("(EnergyAccounting) Loaded cost yesterday: %.2f, this month: %d, last month: %d\n", data.costYesterday / 10.0, data.costThisMonth, data.costLastMonth); } init = true; } diff --git a/src/HwTools.cpp b/src/HwTools.cpp index 007c06a4..1b0a3b01 100644 --- a/src/HwTools.cpp +++ b/src/HwTools.cpp @@ -371,10 +371,10 @@ bool HwTools::ledOff(uint8_t color) { bool HwTools::ledBlink(uint8_t color, uint8_t blink) { for(int i = 0; i < blink; i++) { if(!ledOn(color)) return false; - delay(50); + delay(150); ledOff(color); - if(i != blink) - delay(50); + if(i != blink-1) + delay(250); } return true; } diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index 8ebe54f8..8a4ccab6 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -296,6 +296,38 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo l3PowerFactor = val; } + val = getNumber(AMS_OBIS_ACTIVE_IMPORT_L1, sizeof(AMS_OBIS_ACTIVE_IMPORT_L1), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l1activeImportPower = val; + } + val = getNumber(AMS_OBIS_ACTIVE_IMPORT_L2, sizeof(AMS_OBIS_ACTIVE_IMPORT_L2), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l2activeImportPower = val; + } + val = getNumber(AMS_OBIS_ACTIVE_IMPORT_L3, sizeof(AMS_OBIS_ACTIVE_IMPORT_L3), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l3activeImportPower = val; + } + + val = getNumber(AMS_OBIS_ACTIVE_EXPORT_L1, sizeof(AMS_OBIS_ACTIVE_EXPORT_L1), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l1activeExportPower = val; + } + val = getNumber(AMS_OBIS_ACTIVE_EXPORT_L2, sizeof(AMS_OBIS_ACTIVE_EXPORT_L2), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l2activeExportPower = val; + } + val = getNumber(AMS_OBIS_ACTIVE_EXPORT_L3, sizeof(AMS_OBIS_ACTIVE_EXPORT_L3), ((char *) (d))); + if (val != NOVALUE) { + listType = 4; + l3activeExportPower = val; + } + if(meterType == AmsTypeKamstrup) { if(listType >= 3) { activeImportCounter *= 10; @@ -336,12 +368,16 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo if(mid != NULL) { switch(mid->base.type) { case CosemTypeString: - memcpy(&meterId, mid->str.data, mid->str.length); + memcpy(str, mid->oct.data, mid->oct.length); + str[mid->oct.length] = 0x00; + meterId = String(str); meterId[mid->str.length] = 0; break; case CosemTypeOctetString: - memcpy(&meterId, mid->oct.data, mid->oct.length); - meterId[mid->oct.length] = 0; + memcpy(str, mid->str.data, mid->str.length); + str[mid->str.length] = 0x00; + meterId = String(str); + meterId[mid->str.length] = 0; break; } } diff --git a/src/IEC6205675.h b/src/IEC6205675.h index 3fb3df29..75cf0134 100644 --- a/src/IEC6205675.h +++ b/src/IEC6205675.h @@ -49,6 +49,12 @@ private: uint8_t AMS_OBIS_POWER_FACTOR_L1[4] = { 33, 7, 0, 255 }; uint8_t AMS_OBIS_POWER_FACTOR_L2[4] = { 53, 7, 0, 255 }; uint8_t AMS_OBIS_POWER_FACTOR_L3[4] = { 73, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_IMPORT_L1[4] = { 21, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_IMPORT_L2[4] = { 41, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_IMPORT_L3[4] = { 61, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_EXPORT_L1[4] = { 22, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_EXPORT_L2[4] = { 42, 7, 0, 255 }; + uint8_t AMS_OBIS_ACTIVE_EXPORT_L3[4] = { 62, 7, 0, 255 }; }; #endif diff --git a/src/LNG.cpp b/src/LNG.cpp index b5c9817b..f3ec7cd5 100644 --- a/src/LNG.cpp +++ b/src/LNG.cpp @@ -25,38 +25,38 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da if(descriptor->obis[3] == 7) { if(descriptor->obis[4] == 0) { o170 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } } else if(descriptor->obis[3] == 8) { if(descriptor->obis[4] == 0) { activeImportCounter = ntohl(item->dlu.data) / 1000.0; listType = listType >= 3 ? listType : 3; - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } else if(descriptor->obis[4] == 1) { o181 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } else if(descriptor->obis[4] == 2) { o182 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } } } else if(descriptor->obis[2] == 2) { if(descriptor->obis[3] == 7) { if(descriptor->obis[4] == 0) { o270 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } } else if(descriptor->obis[3] == 8) { if(descriptor->obis[4] == 0) { activeExportCounter = ntohl(item->dlu.data) / 1000.0; listType = listType >= 3 ? listType : 3; - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } else if(descriptor->obis[4] == 1) { o281 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } else if(descriptor->obis[4] == 2) { o282 = ntohl(item->dlu.data); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %d (dlu)", ntohl(item->dlu.data)); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu (dlu)", ntohl(item->dlu.data)); } } } else if(descriptor->obis[2] == 96) { diff --git a/src/Uptime.cpp b/src/Uptime.cpp index d3f739fd..65b5bd1d 100644 --- a/src/Uptime.cpp +++ b/src/Uptime.cpp @@ -1,5 +1,8 @@ #include "Uptime.h" +uint32_t _uptime_last_value = 0; +uint32_t _uptime_rollovers = 0; + uint64_t millis64() { uint32_t new_low32 = millis(); if (new_low32 < _uptime_last_value) _uptime_rollovers++; diff --git a/src/Uptime.h b/src/Uptime.h index 9b1a14a9..aeea9732 100644 --- a/src/Uptime.h +++ b/src/Uptime.h @@ -3,8 +3,6 @@ #include "Arduino.h" -static uint32_t _uptime_last_value = 0; -static uint32_t _uptime_rollovers = 0; uint64_t millis64(); #endif diff --git a/src/ams/DsmrParser.cpp b/src/ams/DsmrParser.cpp index 8ef8ef98..e6b006b1 100644 --- a/src/ams/DsmrParser.cpp +++ b/src/ams/DsmrParser.cpp @@ -4,7 +4,6 @@ int8_t DSMRParser::parse(uint8_t *buf, DataParserContext &ctx, bool verified) { uint16_t crcPos = 0; bool reachedEnd = verified; uint8_t lastByte = 0x00; - int c = 0; for(int pos = 0; pos < ctx.length; pos++) { uint8_t b = *(buf+pos); if(pos == 0 && b != '/') return DATA_PARSE_BOUNDRY_FLAG_MISSING; diff --git a/src/ams/GcmParser.cpp b/src/ams/GcmParser.cpp index 5ac92bfc..5f9e2bd5 100644 --- a/src/ams/GcmParser.cpp +++ b/src/ams/GcmParser.cpp @@ -27,7 +27,7 @@ int8_t GCMParser::parse(uint8_t *d, DataParserContext &ctx) { memcpy(ctx.system_title, ptr, systemTitleLength); memcpy(initialization_vector, ctx.system_title, systemTitleLength); - int len; + int len = 0; int headersize = 2 + systemTitleLength; ptr += systemTitleLength; if(((*ptr) & 0xFF) == 0x81) { diff --git a/src/ams/HdlcParser.cpp b/src/ams/HdlcParser.cpp index a82fd4bc..68a65ae1 100644 --- a/src/ams/HdlcParser.cpp +++ b/src/ams/HdlcParser.cpp @@ -5,8 +5,6 @@ int8_t HDLCParser::parse(uint8_t *d, DataParserContext &ctx) { int len; - uint8_t flag = *d; - uint8_t* ptr; if(ctx.length < 3) return DATA_PARSE_INCOMPLETE; diff --git a/src/ams/LlcParser.cpp b/src/ams/LlcParser.cpp index 3f348844..c6d41a56 100644 --- a/src/ams/LlcParser.cpp +++ b/src/ams/LlcParser.cpp @@ -1,7 +1,6 @@ #include "LlcParser.h" int8_t LLCParser::parse(uint8_t *buf, DataParserContext &ctx) { - LLCHeader* llc = (LLCHeader*) buf; ctx.length -= 3; return 3; } \ No newline at end of file diff --git a/src/ams/MbusParser.cpp b/src/ams/MbusParser.cpp index 731ffcaf..4a090da9 100644 --- a/src/ams/MbusParser.cpp +++ b/src/ams/MbusParser.cpp @@ -5,8 +5,6 @@ int8_t MBUSParser::parse(uint8_t *d, DataParserContext &ctx) { int headersize = 3; int footersize = 1; - uint8_t flag = *d; - uint8_t* ptr; // https://m-bus.com/documentation-wired/06-application-layer diff --git a/src/entsoe/DnbCurrParser.cpp b/src/entsoe/DnbCurrParser.cpp index c85dfb44..4c576ef1 100644 --- a/src/entsoe/DnbCurrParser.cpp +++ b/src/entsoe/DnbCurrParser.cpp @@ -22,7 +22,7 @@ void DnbCurrParser::flush() { } size_t DnbCurrParser::write(const uint8_t *buffer, size_t size) { - for(int i = 0; i < size; i++) { + for(size_t i = 0; i < size; i++) { write(buffer[i]); } return size; diff --git a/src/entsoe/EntsoeA44Parser.cpp b/src/entsoe/EntsoeA44Parser.cpp index c08b5cb0..c64cd145 100644 --- a/src/entsoe/EntsoeA44Parser.cpp +++ b/src/entsoe/EntsoeA44Parser.cpp @@ -5,6 +5,10 @@ EntsoeA44Parser::EntsoeA44Parser() { for(int i = 0; i < 24; i++) points[i] = ENTSOE_NO_VALUE; } +EntsoeA44Parser::~EntsoeA44Parser() { + +} + char* EntsoeA44Parser::getCurrency() { return currency; } @@ -35,7 +39,7 @@ void EntsoeA44Parser::flush() { } size_t EntsoeA44Parser::write(const uint8_t *buffer, size_t size) { - for(int i = 0; i < size; i++) { + for(size_t i = 0; i < size; i++) { write(buffer[i]); } return size; diff --git a/src/entsoe/EntsoeA44Parser.h b/src/entsoe/EntsoeA44Parser.h index 33154d63..55201a62 100644 --- a/src/entsoe/EntsoeA44Parser.h +++ b/src/entsoe/EntsoeA44Parser.h @@ -15,6 +15,7 @@ class EntsoeA44Parser: public Stream { public: EntsoeA44Parser(); + virtual ~EntsoeA44Parser(); char* getCurrency(); char* getMeasurementUnit(); diff --git a/src/entsoe/EntsoeApi.cpp b/src/entsoe/EntsoeApi.cpp index 793d024b..d92504f5 100644 --- a/src/entsoe/EntsoeApi.cpp +++ b/src/entsoe/EntsoeApi.cpp @@ -143,11 +143,11 @@ bool EntsoeApi::loop() { if(midnightMillis == 0) { uint32_t curDayMillis = (((((tm.Hour * 60) + tm.Minute) * 60) + tm.Second) * 1000); midnightMillis = now + (SECS_PER_DAY * 1000) - curDayMillis; - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Setting midnight millis %lu\n", midnightMillis); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Setting midnight millis %llu\n", midnightMillis); currentDay = tm.Day; return false; } else if(now > midnightMillis && currentDay != tm.Day) { - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Rotating price objects at %lu\n", t); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Rotating price objects at %lld\n", t); if(today != NULL) delete today; if(tomorrow != NULL) { today = tomorrow; diff --git a/src/mqtt/AmsMqttHandler.h b/src/mqtt/AmsMqttHandler.h index 4ec71634..109c2a8d 100644 --- a/src/mqtt/AmsMqttHandler.h +++ b/src/mqtt/AmsMqttHandler.h @@ -15,6 +15,7 @@ public: this->mqtt = mqtt; this->json = buf; }; + virtual ~AmsMqttHandler() {}; virtual bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea); virtual bool publishTemperatures(AmsConfiguration*, HwTools*); diff --git a/src/mqtt/HomeAssistantMqttHandler.cpp b/src/mqtt/HomeAssistantMqttHandler.cpp index ff273e3e..7880c254 100644 --- a/src/mqtt/HomeAssistantMqttHandler.cpp +++ b/src/mqtt/HomeAssistantMqttHandler.cpp @@ -6,6 +6,7 @@ #include "web/root/ha1_json.h" #include "web/root/ha2_json.h" #include "web/root/ha3_json.h" +#include "web/root/ha4_json.h" #include "web/root/jsonsys_json.h" #include "web/root/jsonprices_json.h" #include "web/root/hadiscover_json.h" @@ -34,7 +35,7 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En data->getActiveImportPower() ); mqtt->publish(topic + "/power", json); - } else if(data->getListType() >= 2) { // publish power counts and volts/amps + } else if(data->getListType() <= 3) { // publish power counts and volts/amps snprintf_P(json, BufferSize, HA3_JSON, data->getListId().c_str(), data->getMeterId().c_str(), @@ -48,6 +49,29 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En data->getL3Current(), data->getL1Voltage(), data->getL2Voltage(), + data->getL3Voltage() + ); + mqtt->publish(topic + "/power", json); + } else if(data->getListType() == 4) { // publish power counts and volts/amps/phase power and PF + snprintf_P(json, BufferSize, HA4_JSON, + data->getListId().c_str(), + data->getMeterId().c_str(), + meterModel.c_str(), + data->getActiveImportPower(), + data->getL1ActiveImportPower(), + data->getL2ActiveImportPower(), + data->getL3ActiveImportPower(), + data->getReactiveImportPower(), + data->getActiveExportPower(), + data->getL1ActiveExportPower(), + data->getL2ActiveExportPower(), + data->getL3ActiveExportPower(), + data->getReactiveExportPower(), + data->getL1Current(), + data->getL2Current(), + data->getL3Current(), + data->getL1Voltage(), + data->getL2Voltage(), data->getL3Voltage(), data->getPowerFactor() == 0 ? 1 : data->getPowerFactor(), data->getPowerFactor() == 0 ? 1 : data->getL1PowerFactor(), @@ -117,7 +141,7 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) { time_t now = time(nullptr); - float min1hr, min3hr, min6hr; + float min1hr = 0.0, min3hr = 0.0, min6hr = 0.0; int8_t min1hrIdx = -1, min3hrIdx = -1, min6hrIdx = -1; float min = INT16_MAX, max = INT16_MIN; float values[24]; @@ -167,7 +191,7 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) { } - char ts1hr[21]; + char ts1hr[24]; if(min1hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min1hrIdx); //Serial.printf("1hr: %d %lu\n", min1hrIdx, ts); @@ -175,7 +199,7 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts1hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts3hr[21]; + char ts3hr[24]; if(min3hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min3hrIdx); //Serial.printf("3hr: %d %lu\n", min3hrIdx, ts); @@ -183,7 +207,7 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts3hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts6hr[21]; + char ts6hr[24]; if(min6hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min6hrIdx); //Serial.printf("6hr: %d %lu\n", min6hrIdx, ts); @@ -263,13 +287,13 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, EntsoeApi* eapi, Energ peaks++; } snprintf_P(json, BufferSize, HADISCOVER_JSON, - FPSTR(sensor.name), - topic.c_str(), FPSTR(sensor.topic), + sensor.name, + topic.c_str(), sensor.topic, haUID.c_str(), uid.c_str(), haUID.c_str(), uid.c_str(), uom.c_str(), - FPSTR(sensor.path), - FPSTR(sensor.devcl), + sensor.path, + sensor.devcl, haUID.c_str(), haName.c_str(), haModel.c_str(), diff --git a/src/mqtt/HomeAssistantStatic.h b/src/mqtt/HomeAssistantStatic.h index 7428959a..8f781d6f 100644 --- a/src/mqtt/HomeAssistantStatic.h +++ b/src/mqtt/HomeAssistantStatic.h @@ -4,23 +4,29 @@ #include "Arduino.h" struct HomeAssistantSensor { - char* name; - char* topic; - char* path; - char* uom; - char* devcl; - char* stacl; + const char* name; + const char* topic; + const char* path; + const char* uom; + const char* devcl; + const char* stacl; }; -const uint8_t HA_SENSOR_COUNT PROGMEM = 50; +const uint8_t HA_SENSOR_COUNT PROGMEM = 60; HomeAssistantSensor HA_SENSORS[HA_SENSOR_COUNT] PROGMEM = { {"Status", "/state", "rssi", "dBm", "signal_strength", "\"measurement\""}, {"Supply volt", "/state", "vcc", "V", "voltage", "\"measurement\""}, {"Temperature", "/state", "temp", "C", "temperature", "\"measurement\""}, {"Active import", "/power", "P", "W", "power", "\"measurement\""}, + {"L1 active import", "/power", "P1", "W", "power", "\"measurement\""}, + {"L2 active import", "/power", "P2", "W", "power", "\"measurement\""}, + {"L3 active import", "/power", "P3", "W", "power", "\"measurement\""}, {"Reactive import", "/power", "Q", "VAr", "reactive_power", "\"measurement\""}, {"Active export", "/power", "PO", "W", "power", "\"measurement\""}, + {"L1 active export", "/power", "PO1", "W", "power", "\"measurement\""}, + {"L2 active export", "/power", "PO2", "W", "power", "\"measurement\""}, + {"L3 active export", "/power", "PO3", "W", "power", "\"measurement\""}, {"Reactive export", "/power", "QO", "VAr", "reactive_power", "\"measurement\""}, {"L1 current", "/power", "I1", "A", "current", "\"measurement\""}, {"L2 current", "/power", "I2", "A", "current", "\"measurement\""}, @@ -32,6 +38,10 @@ HomeAssistantSensor HA_SENSORS[HA_SENSOR_COUNT] PROGMEM = { {"Accumulated active export", "/energy", "tPO", "kWh", "energy", "\"total_increasing\""}, {"Accumulated reactive import","/energy", "tQI", "kVArh","energy", "\"total_increasing\""}, {"Accumulated reactive export","/energy", "tQO", "kVArh","energy", "\"total_increasing\""}, + {"Power factor", "/power", "PF", "", "power_factor", "\"measurement\""}, + {"L1 power factor", "/power", "PF1", "", "power_factor", "\"measurement\""}, + {"L2 power factor", "/power", "PF2", "", "power_factor", "\"measurement\""}, + {"L3 power factor", "/power", "PF3", "", "power_factor", "\"measurement\""}, {"Price current hour", "/prices", "prices['0']", "", "monetary", ""}, {"Price next hour", "/prices", "prices['1']", "", "monetary", ""}, {"Price in two hour", "/prices", "prices['2']", "", "monetary", ""}, diff --git a/src/mqtt/JsonMqttHandler.cpp b/src/mqtt/JsonMqttHandler.cpp index 6329b389..9448b762 100644 --- a/src/mqtt/JsonMqttHandler.cpp +++ b/src/mqtt/JsonMqttHandler.cpp @@ -111,8 +111,14 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou data->getMeterId().c_str(), meterModel.c_str(), data->getActiveImportPower(), + data->getL1ActiveImportPower(), + data->getL2ActiveImportPower(), + data->getL3ActiveImportPower(), data->getReactiveImportPower(), data->getActiveExportPower(), + data->getL1ActiveExportPower(), + data->getL2ActiveExportPower(), + data->getL3ActiveExportPower(), data->getReactiveExportPower(), data->getL1Current(), data->getL2Current(), @@ -143,8 +149,9 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou bool JsonMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) { int count = hw->getTempSensorCount(); - if(count < 2) + if(count < 2) { return false; + } snprintf(json, 24, "{\"temperatures\":{"); @@ -173,7 +180,7 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { time_t now = time(nullptr); - float min1hr, min3hr, min6hr; + float min1hr = 0.0, min3hr = 0.0, min6hr = 0.0; int8_t min1hrIdx = -1, min3hrIdx = -1, min6hrIdx = -1; float min = INT16_MAX, max = INT16_MIN; float values[24]; @@ -223,7 +230,7 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { } - char ts1hr[21]; + char ts1hr[24]; if(min1hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min1hrIdx); //Serial.printf("1hr: %d %lu\n", min1hrIdx, ts); @@ -231,7 +238,7 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts1hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts3hr[21]; + char ts3hr[24]; if(min3hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min3hrIdx); //Serial.printf("3hr: %d %lu\n", min3hrIdx, ts); @@ -239,7 +246,7 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts3hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts6hr[21]; + char ts6hr[24]; if(min6hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min6hrIdx); //Serial.printf("6hr: %d %lu\n", min6hrIdx, ts); diff --git a/src/mqtt/RawMqttHandler.cpp b/src/mqtt/RawMqttHandler.cpp index c6763ed3..19e6db44 100644 --- a/src/mqtt/RawMqttHandler.cpp +++ b/src/mqtt/RawMqttHandler.cpp @@ -11,6 +11,24 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin } switch(data->getListType()) { case 4: + if(full || meterState->getL1ActiveImportPower() != data->getL1ActiveImportPower()) { + mqtt->publish(topic + "/meter/import/l1", String(data->getL1ActiveImportPower(), 2)); + } + if(full || meterState->getL2ActiveImportPower() != data->getL2ActiveImportPower()) { + mqtt->publish(topic + "/meter/import/l2", String(data->getL2ActiveImportPower(), 2)); + } + if(full || meterState->getL3ActiveImportPower() != data->getL3ActiveImportPower()) { + mqtt->publish(topic + "/meter/import/l3", String(data->getL3ActiveImportPower(), 2)); + } + if(full || meterState->getL1ActiveExportPower() != data->getL1ActiveExportPower()) { + mqtt->publish(topic + "/meter/export/l1", String(data->getL1ActiveExportPower(), 2)); + } + if(full || meterState->getL2ActiveExportPower() != data->getL2ActiveExportPower()) { + mqtt->publish(topic + "/meter/export/l2", String(data->getL2ActiveExportPower(), 2)); + } + if(full || meterState->getL3ActiveExportPower() != data->getL3ActiveExportPower()) { + mqtt->publish(topic + "/meter/export/l3", String(data->getL3ActiveExportPower(), 2)); + } if(full || meterState->getPowerFactor() != data->getPowerFactor()) { mqtt->publish(topic + "/meter/powerfactor", String(data->getPowerFactor(), 2)); } @@ -106,7 +124,7 @@ bool RawMqttHandler::publishPrices(EntsoeApi* eapi) { time_t now = time(nullptr); - float min1hr, min3hr, min6hr; + float min1hr = 0.0, min3hr = 0.0, min6hr = 0.0; int8_t min1hrIdx = -1, min3hrIdx = -1, min6hrIdx = -1; float min = INT16_MAX, max = INT16_MIN; float values[34]; @@ -157,7 +175,7 @@ bool RawMqttHandler::publishPrices(EntsoeApi* eapi) { } - char ts1hr[21]; + char ts1hr[24]; if(min1hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min1hrIdx); //Serial.printf("1hr: %d %lu\n", min1hrIdx, ts); @@ -165,7 +183,7 @@ bool RawMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts1hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts3hr[21]; + char ts3hr[24]; if(min3hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min3hrIdx); //Serial.printf("3hr: %d %lu\n", min3hrIdx, ts); @@ -173,7 +191,7 @@ bool RawMqttHandler::publishPrices(EntsoeApi* eapi) { breakTime(ts, tm); sprintf(ts3hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char ts6hr[21]; + char ts6hr[24]; if(min6hrIdx > -1) { time_t ts = now + (SECS_PER_HOUR * min6hrIdx); //Serial.printf("6hr: %d %lu\n", min6hrIdx, ts); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index a02c7a83..21215df4 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -1015,7 +1015,7 @@ void AmsWebServer::handleSetup() { server.sendHeader("Location", String("/"), true); server.send (302, MIME_PLAIN, ""); } else { - SystemConfig sys { server.arg("board").toInt() }; + SystemConfig sys { static_cast(server.arg("board").toInt()) }; DebugConfig debugConfig; config->getDebugConfig(debugConfig); @@ -1085,6 +1085,16 @@ void AmsWebServer::handleSetup() { gpioConfig->vccResistorGnd = 22; gpioConfig->vccResistorVcc = 33; break; + case 7: // Pow-U+ + gpioConfig->hanPin = 16; + gpioConfig->apPin = 0; + gpioConfig->ledPinRed = 13; + gpioConfig->ledPinGreen = 14; + gpioConfig->ledRgbInverted = true; + gpioConfig->vccPin = 10; + gpioConfig->vccResistorGnd = 22; + gpioConfig->vccResistorVcc = 33; + break; case 101: // D1 gpioConfig->hanPin = 5; gpioConfig->apPin = 4; @@ -1285,11 +1295,11 @@ void AmsWebServer::handleSave() { if(server.hasArg("dc") && server.arg("dc") == "true") { printD("Received Domoticz config"); DomoticzConfig domo { - server.arg("elidx").toInt(), - server.arg("vl1idx").toInt(), - server.arg("vl2idx").toInt(), - server.arg("vl3idx").toInt(), - server.arg("cl1idx").toInt() + static_cast(server.arg("elidx").toInt()), + static_cast(server.arg("vl1idx").toInt()), + static_cast(server.arg("vl2idx").toInt()), + static_cast(server.arg("vl3idx").toInt()), + static_cast(server.arg("cl1idx").toInt()) }; config->setDomoticzConfig(domo); } @@ -1310,24 +1320,24 @@ void AmsWebServer::handleSave() { config->setWebConfig(webConfig); } - if(server.hasArg("gpioConfig") && server.arg("gpioConfig") == "true") { + if(server.hasArg("gc") && server.arg("gc") == "true") { printD("Received GPIO config"); - gpioConfig->hanPin = server.hasArg("hanPin") && !server.arg("hanPin").isEmpty() ? server.arg("hanPin").toInt() : 3; - gpioConfig->ledPin = server.hasArg("ledPin") && !server.arg("ledPin").isEmpty() ? server.arg("ledPin").toInt() : 0xFF; - gpioConfig->ledInverted = server.hasArg("ledInverted") && server.arg("ledInverted") == "true"; - gpioConfig->ledPinRed = server.hasArg("ledPinRed") && !server.arg("ledPinRed").isEmpty() ? server.arg("ledPinRed").toInt() : 0xFF; - gpioConfig->ledPinGreen = server.hasArg("ledPinGreen") && !server.arg("ledPinGreen").isEmpty() ? server.arg("ledPinGreen").toInt() : 0xFF; - gpioConfig->ledPinBlue = server.hasArg("ledPinBlue") && !server.arg("ledPinBlue").isEmpty() ? server.arg("ledPinBlue").toInt() : 0xFF; - gpioConfig->ledRgbInverted = server.hasArg("ledRgbInverted") && server.arg("ledRgbInverted") == "true"; - gpioConfig->apPin = server.hasArg("apPin") && !server.arg("apPin").isEmpty() ? server.arg("apPin").toInt() : 0xFF; - gpioConfig->tempSensorPin = server.hasArg("tempSensorPin") && !server.arg("tempSensorPin").isEmpty() ?server.arg("tempSensorPin").toInt() : 0xFF; - gpioConfig->tempAnalogSensorPin = server.hasArg("tempAnalogSensorPin") && !server.arg("tempAnalogSensorPin").isEmpty() ?server.arg("tempAnalogSensorPin").toInt() : 0xFF; - gpioConfig->vccPin = server.hasArg("vccPin") && !server.arg("vccPin").isEmpty() ? server.arg("vccPin").toInt() : 0xFF; - gpioConfig->vccOffset = server.hasArg("vccOffset") && !server.arg("vccOffset").isEmpty() ? server.arg("vccOffset").toFloat() * 100 : 0; - gpioConfig->vccMultiplier = server.hasArg("vccMultiplier") && !server.arg("vccMultiplier").isEmpty() ? server.arg("vccMultiplier").toFloat() * 1000 : 1000; - gpioConfig->vccBootLimit = server.hasArg("vccBootLimit") && !server.arg("vccBootLimit").isEmpty() ? server.arg("vccBootLimit").toFloat() * 10 : 0; - gpioConfig->vccResistorGnd = server.hasArg("vccResistorGnd") && !server.arg("vccResistorGnd").isEmpty() ? server.arg("vccResistorGnd").toInt() : 0; - gpioConfig->vccResistorVcc = server.hasArg("vccResistorVcc") && !server.arg("vccResistorVcc").isEmpty() ? server.arg("vccResistorVcc").toInt() : 0; + gpioConfig->hanPin = server.hasArg("h") && !server.arg("h").isEmpty() ? server.arg("h").toInt() : 3; + gpioConfig->ledPin = server.hasArg("l") && !server.arg("l").isEmpty() ? server.arg("l").toInt() : 0xFF; + gpioConfig->ledInverted = server.hasArg("i") && server.arg("i") == "true"; + gpioConfig->ledPinRed = server.hasArg("r") && !server.arg("r").isEmpty() ? server.arg("r").toInt() : 0xFF; + gpioConfig->ledPinGreen = server.hasArg("e") && !server.arg("e").isEmpty() ? server.arg("e").toInt() : 0xFF; + gpioConfig->ledPinBlue = server.hasArg("b") && !server.arg("b").isEmpty() ? server.arg("b").toInt() : 0xFF; + gpioConfig->ledRgbInverted = server.hasArg("n") && server.arg("n") == "true"; + gpioConfig->apPin = server.hasArg("a") && !server.arg("a").isEmpty() ? server.arg("a").toInt() : 0xFF; + gpioConfig->tempSensorPin = server.hasArg("t") && !server.arg("t").isEmpty() ?server.arg("t").toInt() : 0xFF; + gpioConfig->tempAnalogSensorPin = server.hasArg("m") && !server.arg("m").isEmpty() ?server.arg("m").toInt() : 0xFF; + gpioConfig->vccPin = server.hasArg("v") && !server.arg("v").isEmpty() ? server.arg("v").toInt() : 0xFF; + gpioConfig->vccOffset = server.hasArg("o") && !server.arg("o").isEmpty() ? server.arg("o").toFloat() * 100 : 0; + gpioConfig->vccMultiplier = server.hasArg("u") && !server.arg("u").isEmpty() ? server.arg("u").toFloat() * 1000 : 1000; + gpioConfig->vccBootLimit = server.hasArg("c") && !server.arg("c").isEmpty() ? server.arg("c").toFloat() * 10 : 0; + gpioConfig->vccResistorGnd = server.hasArg("d") && !server.arg("d").isEmpty() ? server.arg("d").toInt() : 0; + gpioConfig->vccResistorVcc = server.hasArg("s") && !server.arg("s").isEmpty() ? server.arg("s").toInt() : 0; config->setGpioConfig(*gpioConfig); } @@ -1366,8 +1376,8 @@ void AmsWebServer::handleSave() { NtpConfig ntp { server.hasArg("n") && server.arg("n") == "true", server.hasArg("nd") && server.arg("nd") == "true", - server.arg("o").toInt() / 10, - server.arg("so").toInt() / 10 + static_cast(server.arg("o").toInt() / 10), + static_cast(server.arg("so").toInt() / 10) }; strcpy(ntp.server, server.arg("ns").c_str()); config->setNtpConfig(ntp); @@ -1459,32 +1469,32 @@ void AmsWebServer::configGpioHtml() { String html = String((const __FlashStringHelper*) GPIO_HTML); #if defined(CONFIG_IDF_TARGET_ESP32S2) - html.replace("${gpio.max}", "44"); + html.replace("${g}", "44"); #elif defined(ESP32) - html.replace("${gpio.max}", "39"); + html.replace("${g}", "39"); #else - html.replace("${gpio.max}", "16"); + html.replace("${g}", "16"); #endif - html.replace("${options.han}", getSerialSelectOptions(gpioConfig->hanPin)); + html.replace("${h}", getSerialSelectOptions(gpioConfig->hanPin)); - html.replace("${config.ledPin}", gpioConfig->ledPin == 0xFF ? "" : String(gpioConfig->ledPin)); - html.replace("${config.ledInverted}", gpioConfig->ledInverted ? "checked" : ""); - html.replace("${config.ledPinRed}", gpioConfig->ledPinRed == 0xFF ? "" : String(gpioConfig->ledPinRed)); - html.replace("${config.ledPinGreen}", gpioConfig->ledPinGreen == 0xFF ? "" : String(gpioConfig->ledPinGreen)); - html.replace("${config.ledPinBlue}", gpioConfig->ledPinBlue == 0xFF ? "" : String(gpioConfig->ledPinBlue)); - html.replace("${config.ledRgbInverted}", gpioConfig->ledRgbInverted ? "checked" : ""); - html.replace("${config.apPin}", gpioConfig->apPin == 0xFF ? "" : String(gpioConfig->apPin)); - html.replace("${config.tempSensorPin}", gpioConfig->tempSensorPin == 0xFF ? "" : String(gpioConfig->tempSensorPin)); - html.replace("${config.tempAnalogSensorPin}", gpioConfig->tempAnalogSensorPin == 0xFF ? "" : String(gpioConfig->tempAnalogSensorPin)); - html.replace("${config.vccPin}", gpioConfig->vccPin == 0xFF ? "" : String(gpioConfig->vccPin)); + html.replace("${l}", gpioConfig->ledPin == 0xFF ? "" : String(gpioConfig->ledPin)); + html.replace("${i}", gpioConfig->ledInverted ? "checked" : ""); + html.replace("${r}", gpioConfig->ledPinRed == 0xFF ? "" : String(gpioConfig->ledPinRed)); + html.replace("${e}", gpioConfig->ledPinGreen == 0xFF ? "" : String(gpioConfig->ledPinGreen)); + html.replace("${b}", gpioConfig->ledPinBlue == 0xFF ? "" : String(gpioConfig->ledPinBlue)); + html.replace("${n}", gpioConfig->ledRgbInverted ? "checked" : ""); + html.replace("${a}", gpioConfig->apPin == 0xFF ? "" : String(gpioConfig->apPin)); + html.replace("${t}", gpioConfig->tempSensorPin == 0xFF ? "" : String(gpioConfig->tempSensorPin)); + html.replace("${m}", gpioConfig->tempAnalogSensorPin == 0xFF ? "" : String(gpioConfig->tempAnalogSensorPin)); + html.replace("${v}", gpioConfig->vccPin == 0xFF ? "" : String(gpioConfig->vccPin)); - html.replace("${config.vccOffset}", gpioConfig->vccOffset > 0 ? String(gpioConfig->vccOffset / 100.0, 2) : ""); - html.replace("${config.vccMultiplier}", gpioConfig->vccMultiplier > 0 ? String(gpioConfig->vccMultiplier / 1000.0, 2) : ""); - html.replace("${config.vccBootLimit}", gpioConfig->vccBootLimit > 0 ? String(gpioConfig->vccBootLimit / 10.0, 1) : ""); + html.replace("${o}", gpioConfig->vccOffset > 0 ? String(gpioConfig->vccOffset / 100.0, 2) : ""); + html.replace("${u}", gpioConfig->vccMultiplier > 0 ? String(gpioConfig->vccMultiplier / 1000.0, 2) : ""); + html.replace("${c}", gpioConfig->vccBootLimit > 0 ? String(gpioConfig->vccBootLimit / 10.0, 1) : ""); - html.replace("${config.vccResistorGnd}", gpioConfig->vccResistorGnd > 0 ? String(gpioConfig->vccResistorGnd) : ""); - html.replace("${config.vccResistorVcc}", gpioConfig->vccResistorVcc > 0 ? String(gpioConfig->vccResistorVcc) : ""); + html.replace("${d}", gpioConfig->vccResistorGnd > 0 ? String(gpioConfig->vccResistorGnd) : ""); + html.replace("${s}", gpioConfig->vccResistorVcc > 0 ? String(gpioConfig->vccResistorVcc) : ""); server.sendHeader(HEADER_CACHE_CONTROL, "no-cache, no-store, must-revalidate"); server.sendHeader("Pragma", "no-cache"); @@ -1597,21 +1607,21 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { } file = LittleFS.open(path, "w"); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("handleFileUpload Open file and write: %lu\n", upload.currentSize); + debugger->printf("handleFileUpload Open file and write: %u\n", upload.currentSize); } size_t written = file.write(upload.buf, upload.currentSize); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("handleFileUpload Written: %lu\n", written); + debugger->printf("handleFileUpload Written: %u\n", written); } } } else if(upload.status == UPLOAD_FILE_WRITE) { if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("handleFileUpload Writing: %lu\n", upload.currentSize); + debugger->printf("handleFileUpload Writing: %u\n", upload.currentSize); } if(file) { size_t written = file.write(upload.buf, upload.currentSize); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("handleFileUpload Written: %lu\n", written); + debugger->printf("handleFileUpload Written: %u\n", written); } delay(1); if(written != upload.currentSize) { @@ -2328,7 +2338,7 @@ void AmsWebServer::configFileDownload() { ds->getHourImport(23) )); if(day.activeExport > 0) { - server.sendContent(buf, snprintf(buf, BufferSize, " %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + server.sendContent(buf, snprintf(buf, BufferSize, " %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", day.activeExport, ds->getHourExport(0), ds->getHourExport(1), @@ -2397,7 +2407,7 @@ void AmsWebServer::configFileDownload() { ds->getDayImport(31) )); if(month.activeExport > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, " %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + server.sendContent(buf, snprintf_P(buf, BufferSize, " %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", month.activeExport, ds->getDayExport(1), ds->getDayExport(2), diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index 7136c698..4ce64d98 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -61,7 +61,11 @@ private: bool performRestart = false; bool performUpgrade = false; bool rebootForUpgrade = false; + #if defined(AMS2MQTT_FIRMWARE_URL) + String customFirmwareUrl = AMS2MQTT_FIRMWARE_URL; + #else String customFirmwareUrl; + #endif static const uint16_t BufferSize = 2048; char* buf; diff --git a/web/data.json b/web/data.json index 0581d6ac..a713055a 100644 --- a/web/data.json +++ b/web/data.json @@ -23,8 +23,8 @@ "v" : %.3f, "r" : %d, "t" : %.2f, - "u" : %lu, - "m" : %lu, + "u" : %u, + "m" : %u, "em" : %d, "hm" : %d, "wm" : %d, @@ -53,5 +53,5 @@ "p" : %.2f } }, - "c" : %lu + "c" : %u } \ No newline at end of file diff --git a/web/gpio.html b/web/gpio.html index 494667c9..5bdf308b 100644 --- a/web/gpio.html +++ b/web/gpio.html @@ -1,6 +1,6 @@
!!WARNING!!
Do not change anything here unless you know exactly what you are doing! Changing things here could cause the device to stop responding
- +
GPIO settings
@@ -8,18 +8,18 @@
HAN
- + ${h}
LED
- +
@@ -27,12 +27,12 @@
RGB
- - - + + +
@@ -40,31 +40,31 @@
AP button
- +
Temperature
- +
Analog temp
- +
Vcc
- +
GND resistor
- +
@@ -73,7 +73,7 @@
Vcc resistor
- +
@@ -82,19 +82,19 @@
Multiplier
- +
Offset
- +
Boot limit
- +
diff --git a/web/ha2.json b/web/ha2.json index 06ab3f26..53fe3841 100644 --- a/web/ha2.json +++ b/web/ha2.json @@ -3,5 +3,5 @@ "tPO" : %.2f, "tQI" : %.2f, "tQO" : %.2f, - "rtc" : %lu + "rtc" : %lld } diff --git a/web/ha3.json b/web/ha3.json index 41fad56b..8fa16c93 100644 --- a/web/ha3.json +++ b/web/ha3.json @@ -11,9 +11,5 @@ "I3" : %.2f, "U1" : %.2f, "U2" : %.2f, - "U3" : %.2f, - "PF" : %.2f, - "PF1" : %.2f, - "PF2" : %.2f, - "PF3" : %.2f + "U3" : %.2f } diff --git a/web/ha4.json b/web/ha4.json new file mode 100644 index 00000000..faee4724 --- /dev/null +++ b/web/ha4.json @@ -0,0 +1,25 @@ +{ + "lv" : "%s", + "id" : "%s", + "type" : "%s", + "P" : %d, + "P1" : %.2f, + "P2" : %.2f, + "P3" : %.2f, + "Q" : %d, + "PO" : %d, + "PO1" : %.2f, + "PO2" : %.2f, + "PO3" : %.2f, + "QO" : %d, + "I1" : %.2f, + "I2" : %.2f, + "I3" : %.2f, + "U1" : %.2f, + "U2" : %.2f, + "U3" : %.2f, + "PF" : %.2f, + "PF1" : %.2f, + "PF2" : %.2f, + "PF3" : %.2f +} diff --git a/web/head.html b/web/head.html index 5bad2571..ef742621 100644 --- a/web/head.html +++ b/web/head.html @@ -1,3 +1,4 @@ + diff --git a/web/json1.json b/web/json1.json index 70f74801..e38fb4b9 100644 --- a/web/json1.json +++ b/web/json1.json @@ -1,8 +1,8 @@ { "id" : "%s", "name" : "%s", - "up" : %lu, - "t" : %lu, + "up" : %u, + "t" : %lld, "vcc" : %.3f, "rssi": %d, "temp": %.2f, diff --git a/web/json2.json b/web/json2.json index b875ac11..44bde282 100644 --- a/web/json2.json +++ b/web/json2.json @@ -1,8 +1,8 @@ { "id" : "%s", "name" : "%s", - "up" : %lu, - "t" : %lu, + "up" : %u, + "t" : %lld, "vcc" : %.3f, "rssi": %d, "temp": %.2f, diff --git a/web/json3.json b/web/json3.json index 33d022ba..09961abe 100644 --- a/web/json3.json +++ b/web/json3.json @@ -1,8 +1,8 @@ { "id" : "%s", "name" : "%s", - "up" : %lu, - "t" : %lu, + "up" : %u, + "t" : %lld, "vcc" : %.3f, "rssi": %d, "temp": %.2f, @@ -24,7 +24,7 @@ "tPO" : %.3f, "tQI" : %.3f, "tQO" : %.3f, - "rtc" : %lu + "rtc" : %lld }, "realtime" : { "h" : %.2f, diff --git a/web/json4.json b/web/json4.json index 701c06f4..417c2eed 100644 --- a/web/json4.json +++ b/web/json4.json @@ -1,8 +1,8 @@ { "id" : "%s", "name" : "%s", - "up" : %lu, - "t" : %lu, + "up" : %u, + "t" : %lld, "vcc" : %.3f, "rssi": %d, "temp": %.2f, @@ -11,8 +11,14 @@ "id" : "%s", "type" : "%s", "P" : %d, + "P1" : %.2f, + "P2" : %.2f, + "P3" : %.2f, "Q" : %d, "PO" : %d, + "PO1" : %.2f, + "PO2" : %.2f, + "PO3" : %.2f, "QO" : %d, "I1" : %.2f, "I2" : %.2f, @@ -28,7 +34,7 @@ "tPO" : %.2f, "tQI" : %.2f, "tQO" : %.2f, - "rtc" : %lu + "rtc" : %lld }, "realtime" : { "h" : %.2f, diff --git a/web/setup.html b/web/setup.html index 65846332..87d047f9 100644 --- a/web/setup.html +++ b/web/setup.html @@ -26,6 +26,7 @@