diff --git a/src/AmsConfiguration.cpp b/src/AmsConfiguration.cpp index 5d8ec11a..14c21d8a 100644 --- a/src/AmsConfiguration.cpp +++ b/src/AmsConfiguration.cpp @@ -645,6 +645,14 @@ bool AmsConfiguration::hasConfig() { configVersion = 0; return false; } + case 93: + configVersion = -1; // Prevent loop + if(relocateConfig93()) { + configVersion = 94; + } else { + configVersion = 0; + return false; + } case EEPROM_CHECK_SUM: return true; default: @@ -775,8 +783,6 @@ bool AmsConfiguration::relocateConfig91() { } bool AmsConfiguration::relocateConfig92() { - saveToFs(); - WiFiConfig wifi; EEPROM.begin(EEPROM_SIZE); EEPROM.get(CONFIG_WIFI_START, wifi); @@ -797,6 +803,21 @@ bool AmsConfiguration::relocateConfig92() { return ret; } +bool AmsConfiguration::relocateConfig93() { + MeterConfig meter; + EEPROM.begin(EEPROM_SIZE); + EEPROM.get(CONFIG_METER_START_93, meter); + meter.wattageMultiplier = 0; + meter.voltageMultiplier = 0; + meter.amperageMultiplier = 0; + meter.accumulatedMultiplier = 0; + EEPROM.put(CONFIG_METER_START, meter); + EEPROM.put(EEPROM_CONFIG_ADDRESS, 94); + bool ret = EEPROM.commit(); + EEPROM.end(); + return ret; +} + bool AmsConfiguration::save() { EEPROM.begin(EEPROM_SIZE); EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM); diff --git a/src/AmsConfiguration.h b/src/AmsConfiguration.h index 793d6cc4..63d30f43 100644 --- a/src/AmsConfiguration.h +++ b/src/AmsConfiguration.h @@ -4,12 +4,12 @@ #include "Arduino.h" #define EEPROM_SIZE 1024*3 -#define EEPROM_CHECK_SUM 93 // Used to check if config is stored. Change if structure changes +#define EEPROM_CHECK_SUM 94 // Used to check if config is stored. Change if structure changes #define EEPROM_CONFIG_ADDRESS 0 #define EEPROM_TEMP_CONFIG_ADDRESS 2048 #define CONFIG_SYSTEM_START 8 -#define CONFIG_METER_START 224 +#define CONFIG_METER_START 32 #define CONFIG_GPIO_START 266 #define CONFIG_ENTSOE_START 290 #define CONFIG_WIFI_START 360 @@ -24,6 +24,7 @@ #define CONFIG_METER_START_87 784 #define CONFIG_ENTSOE_START_90 286 #define CONFIG_WIFI_START_91 16 +#define CONFIG_METER_START_93 224 struct SystemConfig { @@ -94,7 +95,11 @@ struct MeterConfig { uint8_t productionCapacity; uint8_t encryptionKey[16]; uint8_t authenticationKey[16]; -}; // 41 + uint16_t wattageMultiplier; + uint16_t voltageMultiplier; + uint16_t amperageMultiplier; + uint16_t accumulatedMultiplier; +}; // 49 struct MeterConfig87 { uint8_t type; @@ -259,6 +264,7 @@ private: bool relocateConfig90(); // 2.0.0 bool relocateConfig91(); // 2.0.2 bool relocateConfig92(); // 2.0.3 + bool relocateConfig93(); // 2.1 beta void saveToFs(); bool loadFromFs(uint8_t version); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index b5acd238..e07845f1 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -832,7 +832,7 @@ bool readHanPort() { len = 0; if(pos > 0) { debugD("Valid data, start at byte %d", pos); - data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), meterConfig.distributionSystem, timestamp, hc); + data = IEC6205675(((char *) (hanBuffer)) + pos, meterState.getMeterType(), &meterConfig, timestamp, hc); } else { if(Debug.isActive(RemoteDebug::WARNING)) { switch(pos) { diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index f970d29b..91417b91 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -2,7 +2,7 @@ #include "lwip/def.h" #include "Timezone.h" -IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distributionSystem, CosemDateTime packageTimestamp, HDLCConfig* hc) { +IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, CosemDateTime packageTimestamp, HDLCConfig* hc) { double val; char str[64]; @@ -360,12 +360,35 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution lastUpdateMillis = millis(); } + if(meterConfig->wattageMultiplier > 0) { + activeImportPower = activeImportPower > 0 ? activeImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0; + activeExportPower = activeExportPower > 0 ? activeExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0; + reactiveImportPower = reactiveImportPower > 0 ? reactiveImportPower * (meterConfig->wattageMultiplier / 1000.0) : 0; + reactiveExportPower = reactiveExportPower > 0 ? reactiveExportPower * (meterConfig->wattageMultiplier / 1000.0) : 0; + } + if(meterConfig->voltageMultiplier > 0) { + l1voltage = l1voltage > 0 ? l1voltage * (meterConfig->voltageMultiplier / 1000.0) : 0; + l2voltage = l2voltage > 0 ? l2voltage * (meterConfig->voltageMultiplier / 1000.0) : 0; + l3voltage = l3voltage > 0 ? l3voltage * (meterConfig->voltageMultiplier / 1000.0) : 0; + } + if(meterConfig->amperageMultiplier > 0) { + l1current = l1current > 0 ? l1current * (meterConfig->amperageMultiplier / 1000.0) : 0; + l2current = l2current > 0 ? l2current * (meterConfig->amperageMultiplier / 1000.0) : 0; + l3current = l3current > 0 ? l3current * (meterConfig->amperageMultiplier / 1000.0) : 0; + } + if(meterConfig->accumulatedMultiplier > 0) { + activeImportCounter = activeImportCounter > 0 ? activeImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0; + activeExportCounter = activeExportCounter > 0 ? activeExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0; + reactiveImportCounter = reactiveImportCounter > 0 ? reactiveImportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0; + reactiveExportCounter = reactiveExportCounter > 0 ? reactiveExportCounter * (meterConfig->accumulatedMultiplier / 1000.0) : 0; + } + threePhase = l1voltage > 0 && l2voltage > 0 && l3voltage > 0; if(!threePhase) twoPhase = (l1voltage > 0 && l2voltage > 0) || (l2voltage > 0 && l3voltage > 0) || (l3voltage > 0 && l1voltage > 0); // Special case for Norwegian IT/TT meters that does not report all values - if(distributionSystem == 1) { + if(meterConfig->distributionSystem == 1) { if(threePhase) { if(l2current == 0.0 && l1current > 0.0 && l3current > 0.0) { l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage; diff --git a/src/IEC6205675.h b/src/IEC6205675.h index dd573939..739d2160 100644 --- a/src/IEC6205675.h +++ b/src/IEC6205675.h @@ -3,6 +3,7 @@ #include "AmsData.h" #include "ams/hdlc.h" +#include "AmsConfiguration.h" #define NOVALUE 0xFFFFFFFF @@ -13,7 +14,7 @@ struct AmsOctetTimestamp { class IEC6205675 : public AmsData { public: - IEC6205675(const char* payload, uint8_t useMeterType, uint8_t distributionSystem, CosemDateTime packageTimestamp, HDLCConfig* hc); + IEC6205675(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, CosemDateTime packageTimestamp, HDLCConfig* hc); private: CosemData* getCosemDataAt(uint8_t index, const char* ptr); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 99de7a1f..f649f0f6 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -49,6 +49,7 @@ #include "root/energyprice_json.h" #include "root/thresholds_html.h" #include "root/configfile_html.h" +#include "root/meteradvanced_html.h" #include "base64.h" @@ -75,6 +76,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on("/temperature", HTTP_POST, std::bind(&AmsWebServer::temperaturePost, this)); server.on("/temperature.json", HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this)); server.on("/meter", HTTP_GET, std::bind(&AmsWebServer::configMeterHtml, this)); + server.on("/meteradvanced", HTTP_GET, std::bind(&AmsWebServer::configMeterAdvancedHtml, this)); server.on("/wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this)); server.on("/mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this)); server.on("/web", HTTP_GET, std::bind(&AmsWebServer::configWebHtml, this)); @@ -388,6 +390,29 @@ void AmsWebServer::configMeterHtml() { server.sendContent_P(FOOT_HTML); } +void AmsWebServer::configMeterAdvancedHtml() { + printD("Serving /meteradvanced.html over http..."); + + if(!checkSecurity(1)) + return; + + snprintf_P(buf, BufferSize, METERADVANCED_HTML, + meterConfig->wattageMultiplier / 1000.0, + meterConfig->voltageMultiplier / 1000.0, + meterConfig->amperageMultiplier / 1000.0, + meterConfig->accumulatedMultiplier / 1000.0 + ); + + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); + + server.setContentLength(strlen(buf) + HEAD_HTML_LEN + FOOT_HTML_LEN); + server.send_P(200, MIME_HTML, HEAD_HTML); + server.sendContent(buf); + server.sendContent_P(FOOT_HTML); +} + void AmsWebServer::configWifiHtml() { printD("Serving /wifi.html over http..."); @@ -1134,6 +1159,7 @@ void AmsWebServer::handleSave() { if(server.hasArg("mc") && server.arg("mc") == "true") { printD("Received meter config"); + config->getMeterConfig(*meterConfig); meterConfig->baud = server.arg("b").toInt(); meterConfig->parity = server.arg("c").toInt(); meterConfig->invert = server.hasArg("i") && server.arg("i") == "true"; @@ -1156,6 +1182,16 @@ void AmsWebServer::handleSave() { config->setMeterConfig(*meterConfig); } + if(server.hasArg("ma") && server.arg("ma") == "true") { + printD("Received meter advanced config"); + config->getMeterConfig(*meterConfig); + meterConfig->wattageMultiplier = server.arg("wm").toDouble() * 1000; + meterConfig->voltageMultiplier = server.arg("vm").toDouble() * 1000; + meterConfig->amperageMultiplier = server.arg("am").toDouble() * 1000; + meterConfig->accumulatedMultiplier = server.arg("cm").toDouble() * 1000; + config->setMeterConfig(*meterConfig); + } + if(server.hasArg("wc") && server.arg("wc") == "true") { printD("Received WiFi config"); WiFiConfig wifi; diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index 71b0f7bd..fed9ce9d 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -76,6 +76,7 @@ private: void temperaturePost(); void temperatureJson(); void configMeterHtml(); + void configMeterAdvancedHtml(); void configWifiHtml(); void configMqttHtml(); void configWebHtml(); diff --git a/web/domoticz.html b/web/domoticz.html index 428e48e0..fbc6d441 100644 --- a/web/domoticz.html +++ b/web/domoticz.html @@ -39,7 +39,7 @@