diff --git a/lib/AmsMqttHandler/src/AmsMqttHandler.cpp b/lib/AmsMqttHandler/src/AmsMqttHandler.cpp index 44001488..f97e824d 100644 --- a/lib/AmsMqttHandler/src/AmsMqttHandler.cpp +++ b/lib/AmsMqttHandler/src/AmsMqttHandler.cpp @@ -166,7 +166,7 @@ bool AmsMqttHandler::connected() { bool AmsMqttHandler::loop() { bool ret = mqtt.loop(); - delay(10); + delay(10); // Needed to preserve power. After adding this, the voltage is super smooth on a HAN powered device yield(); #if defined(ESP32) esp_task_wdt_reset(); diff --git a/lib/HwTools/include/HwTools.h b/lib/HwTools/include/HwTools.h index 80f54d34..0627e3f1 100644 --- a/lib/HwTools/include/HwTools.h +++ b/lib/HwTools/include/HwTools.h @@ -67,7 +67,9 @@ private: bool ledInvert, rgbInvert; uint8_t vccPin, vccGnd_r, vccVcc_r; float vccOffset, vccMultiplier; + float vcc = 3.3; // Last known Vcc float maxVcc = 3.25; // Best to have this close to max as a start, in case Pow-U reboots and starts off with a low voltage, we dont want that to be perceived as max + unsigned long lastVccRead = 0; uint16_t analogRange = 1024; AdcConfig voltAdc, tempAdc; diff --git a/lib/HwTools/src/HwTools.cpp b/lib/HwTools/src/HwTools.cpp index 20e0466b..049e9d0f 100644 --- a/lib/HwTools/src/HwTools.cpp +++ b/lib/HwTools/src/HwTools.cpp @@ -654,8 +654,12 @@ bool HwTools::writeLedPin(uint8_t color, uint8_t state) { } bool HwTools::isVoltageOptimal(float range) { - if(boardType >= 5 && boardType <= 7 && maxVcc > 2.8) { // Pow-* - float vcc = getVcc(); + if(boardType >= 1 && boardType <= 8 && maxVcc > 2.8) { // BUS-Power boards + unsigned long now = millis(); + if(now - lastVccRead > 250) { + vcc = getVcc(); + lastVccRead = now; + } if(vcc > 3.4 || vcc < 2.8) { maxVcc = 0; // Voltage is outside the operating range, we have to assume voltage is OK } else if(vcc > maxVcc) { diff --git a/src/AmsToMqttBridge.cpp b/src/AmsToMqttBridge.cpp index ffec7664..1eb9592a 100644 --- a/src/AmsToMqttBridge.cpp +++ b/src/AmsToMqttBridge.cpp @@ -215,7 +215,6 @@ void connectToNetwork(); void toggleSetupMode(); void postConnect(); void MQTT_connect(); -void handleNtpChange(); void handleDataSuccess(AmsData* data); void handleTemperature(unsigned long now); void handleSystem(unsigned long now); @@ -223,11 +222,27 @@ void handleButton(unsigned long now); void handlePriceService(unsigned long now); void handleClear(unsigned long now); void handleUiLanguage(); -void handleEnergyAccountingChanged(); -bool handleVoltageCheck(); +void handleEnergyAccounting(); bool readHanPort(); void errorBlink(); +void handleUpdater(); +char ntpServerName[64] = ""; +void handleNtp(); +#if defined(ESP8266) +void handleMdns(); +#endif +#if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS) +void handleEnergySpeedometer(); +#endif +#if defined(AMS_CLOUD) +void handleCloud(); +#endif +void handleMqtt(); +void handleWebserver(); +void handleSmartConfig(); +void handleMeterConfig(); + uint8_t pulses = 0; void onPulse(); @@ -500,7 +515,6 @@ void setup() { if(config.hasConfig()) { config.print(&Debug); connectToNetwork(); - handleNtpChange(); ds.load(); } else { debugI_P(PSTR("No configuration, booting AP")); @@ -552,6 +566,9 @@ uint64_t lastErrorBlink = 0; unsigned long lastVoltageCheck = 0; int lastError = 0; +bool vccLevel1 = true; +bool vccLevel2 = true; + void loop() { unsigned long now = millis(); unsigned long start = now; @@ -569,7 +586,7 @@ void loop() { errorBlink(); } - // Only do normal stuff if we're not booted as AP + // Only do normal stuff if we're not booted into setup mode if (!setupMode) { if (ch != NULL && !ch->isConnected()) { if(networkConnected) { @@ -588,120 +605,50 @@ void loop() { if(!networkConnected) { postConnect(); } - if(config.isNtpChanged()) { - handleNtpChange(); - } - #if defined ESP8266 - if(mdnsEnabled) { - start = millis(); - MDNS.update(); - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to update mDNS"), millis()-start); - } - } - #endif - if (mqttEnabled || config.isMqttChanged()) { - if(mqttHandler == NULL || !mqttHandler->connected() || config.isMqttChanged()) { - if(mqttHandler != NULL && config.isMqttChanged()) { - mqttHandler->disconnect(); - } - MQTT_connect(); - config.ackMqttChange(); - } - } else if(mqttHandler != NULL) { - mqttHandler->disconnect(); - } + handleUpdater(); - #if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS) - if(sysConfig.energyspeedometer == 7) { - if(!meterState.getMeterId().isEmpty()) { - if(energySpeedometer == NULL) { - uint16_t chipId; - #if defined(ESP32) - chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF; - #else - chipId = ESP.getChipId(); - #endif - strcpy(energySpeedometerConfig.clientId, (String("ams") + String(chipId, HEX)).c_str()); - energySpeedometer = new JsonMqttHandler(energySpeedometerConfig, &Debug, (char*) commonBuffer, &hw, &ds, &updater); - energySpeedometer->setCaVerification(false); - } - if(!energySpeedometer->connected()) { - lwmqtt_err_t err = energySpeedometer->lastError(); - if(err > 0) - debugE_P(PSTR("Energyspeedometer connector reporting error (%d)"), err); - energySpeedometer->connect(); - energySpeedometer->publishSystem(&hw, ps, &ea); - } - energySpeedometer->loop(); - delay(10); - } - } else if(energySpeedometer != NULL) { - if(energySpeedometer->connected()) { - energySpeedometer->disconnect(); - energySpeedometer->loop(); - } else { - delete energySpeedometer; - energySpeedometer = NULL; - } - } - #endif - - try { + // Only do these tasks if we have super-smooth voltage + if(hw.isVoltageOptimal(0.1)) { + handleNtp(); + #if defined(ESP8266) + handleMdns(); + #endif + #if defined(ESP32) + #if defined(ENERGY_SPEEDOMETER_PASS) + handleEnergySpeedometer(); + #endif + #endif handlePriceService(now); - } catch(const std::exception& e) { - debugE_P(PSTR("Exception in PriceService loop (%s)"), e.what()); - } - start = millis(); - ws.loop(); - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to handle web"), millis()-start); + #if defined(AMS_CLOUD) + handleCloud(); + #endif + handleUiLanguage(); + vccLevel1 = true; + } else if(vccLevel1) { + vccLevel1 = false; + debugW_P(PSTR("Vcc below level 1")); } - if(mqttHandler != NULL) { - start = millis(); - mqttHandler->loop(); - delay(10); // Needed to preserve power. After adding this, the voltage is super smooth on a HAN powered device - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to handle mqtt"), millis()-start); + // Only do these task if we have smooth voltage + if(hw.isVoltageOptimal(0.2)) { + handleMqtt(); + vccLevel2 = true; + } else if(vccLevel2) { + vccLevel2 = false; + debugW_P(PSTR("Vcc below level 2")); + } + + handleWebserver(); + + #if defined(ESP32) + // At this point, if the voltage is not optimal, disconnect from WiFi to preserve power + if(!hw.isVoltageOptimal(0.35)) { + if(WiFi.getMode() == WIFI_STA) { + debugW_P(PSTR("Vcc dropped below limit, disconnecting WiFi for 5 seconds to preserve power")); + ch->disconnect(5000); } } - - #if defined(_CLOUDCONNECTOR_H) - if(config.isCloudChanged()) { - CloudConfig cc; - if(config.getCloudConfig(cc) && cc.enabled) { - if(cloud == NULL) { - cloud = new CloudConnector(&Debug); - } - NtpConfig ntp; - config.getNtpConfig(ntp); - if(cloud->setup(cc, meterConfig, sysConfig, ntp, &hw, &rdc, ps)) { - config.setCloudConfig(cc); - } - cloud->setConnectionHandler(ch); - - PriceServiceConfig price; - config.getPriceServiceConfig(price); - cloud->setPriceConfig(price); - - EnergyAccountingConfig *eac = ea.getConfig(); - cloud->setEnergyAccountingConfig(*eac); - - ws.setCloud(cloud); - } else if(cloud != NULL) { - delete cloud; - cloud = NULL; - } - config.ackCloudConfig(); - } - if(cloud != NULL) { - cloud->update(meterState, ea); - } #endif #if defined(ZMART_CHARGE) @@ -762,45 +709,255 @@ void loop() { debugW_P(PSTR("Used %dms to handle firmware updater"), end-start); } } - #if defined(ESP32) - if(now - lastVoltageCheck > 1000) { - start = millis(); - handleVoltageCheck(); - end = millis(); - lastVoltageCheck = now; - if(end-start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to handle language update"), end-start); - } - } - #endif } else { - if(WiFi.smartConfigDone()) { - debugI_P(PSTR("Smart config DONE!")); - - NetworkConfig network; - config.getNetworkConfig(network); - strcpy(network.ssid, WiFi.SSID().c_str()); - strcpy(network.psk, WiFi.psk().c_str()); - network.mode = 1; - network.mdns = true; - config.setNetworkConfig(network); - - SystemConfig sys; - config.getSystemConfig(sys); - sys.userConfigured = true; - sys.dataCollectionConsent = 0; - config.setSystemConfig(sys); - config.save(); - - delay(1000); - ESP.restart(); - } + handleSmartConfig(); if(dnsServer != NULL) { dnsServer->processNextRequest(); } ws.loop(); } + handleMeterConfig(); + handleEnergyAccounting(); + + try { + start = millis(); + if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { + end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to read HAN port (true)"), millis()-start); + } + if(hw.isVoltageOptimal(0.1)) { + handleTemperature(now); + handleSystem(now); + } + hw.setBootSuccessful(true); + } else { + end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to read HAN port (false)"), millis()-start); + } + } + if(millis() - meterState.getLastUpdateMillis() > 1800000 && !ds.isHappy(time(nullptr))) { + handleClear(now); + } + } catch(const std::exception& e) { + debugE_P(PSTR("Exception in readHanPort (%s)"), e.what()); + meterState.setLastError(METER_ERROR_EXCEPTION); + } + + delay(10); // Needed for auto modem sleep + start = millis(); + #if defined(ESP32) + esp_task_wdt_reset(); + #elif defined(ESP8266) + ESP.wdtFeed(); + #endif + yield(); + + end = millis(); + if(end-start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to feed WDT"), end-start); + } + + if(end-now > SLOW_PROC_TRIGGER_MS*2) { + debugW_P(PSTR("loop() used %dms"), end-now); + } +} + +void handleUpdater() { + unsigned long start = millis(); + updater.loop(); + if(updater.isUpgradeInformationChanged()) { + UpgradeInformation upinfo; + updater.getUpgradeInformation(upinfo); + config.setUpgradeInformation(upinfo); + updater.ackUpgradeInformationChanged(); + if(mqttHandler != NULL) + mqttHandler->publishFirmware(); + + if(upinfo.errorCode == AMS_UPDATE_ERR_SUCCESS_SIGNAL) { + debugW_P(PSTR("Rebooting to firmware version %s"), upinfo.toVersion); + upinfo.errorCode == AMS_UPDATE_ERR_SUCCESS_CONFIRMED; + config.setUpgradeInformation(upinfo); + delay(1000); + ESP.restart(); + } + } + unsigned long end = millis(); + if(end-start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to handle firmware updater"), end-start); + } +} + +void handleNtp() { + if(config.isNtpChanged()) { + NtpConfig ntp; + if(config.getNtpConfig(ntp)) { + tz = resolveTimezone(ntp.timezone); + if(ntp.enable && strlen(ntp.server) > 0) { + strcpy(ntpServerName, ntp.server); + } else if(ntp.enable) { + strcpy(ntpServerName, "pool.ntp.org"); + } else { + memset(ntpServerName, 0, 64); + } + configTime(tz->toLocal(0), tz->toLocal(JULY1970)-JULY1970, ntpServerName, "", ""); + sntp_servermode_dhcp(ntp.enable && ntp.dhcp ? 1 : 0); // Not implemented on ESP32? + ntpEnabled = ntp.enable; + + ws.setTimezone(tz); + ds.setTimezone(tz); + ea.setTimezone(tz); + ps->setTimezone(tz); + } + + config.ackNtpChange(); + } +} + +#if defined(ESP8266) +void handleMdns() { + if(mdnsEnabled) { + unsigned long start = millis(); + MDNS.update(); + unsigned long end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to update mDNS"), millis()-start); + } + } +} +#endif + +#if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS) +void handleEnergySpeedometer() { + if(sysConfig.energyspeedometer == 7) { + if(!meterState.getMeterId().isEmpty()) { + if(energySpeedometer == NULL) { + uint16_t chipId; + #if defined(ESP32) + chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF; + #else + chipId = ESP.getChipId(); + #endif + strcpy(energySpeedometerConfig.clientId, (String("ams") + String(chipId, HEX)).c_str()); + energySpeedometer = new JsonMqttHandler(energySpeedometerConfig, &Debug, (char*) commonBuffer, &hw, &ds, &updater); + energySpeedometer->setCaVerification(false); + } + if(!energySpeedometer->connected()) { + lwmqtt_err_t err = energySpeedometer->lastError(); + if(err > 0) + debugE_P(PSTR("Energyspeedometer connector reporting error (%d)"), err); + energySpeedometer->connect(); + energySpeedometer->publishSystem(&hw, ps, &ea); + } + energySpeedometer->loop(); + delay(10); + } + } else if(energySpeedometer != NULL) { + if(energySpeedometer->connected()) { + energySpeedometer->disconnect(); + energySpeedometer->loop(); + } else { + delete energySpeedometer; + energySpeedometer = NULL; + } + } +} +#endif + +#if defined(AMS_CLOUD) +void handleCloud() { + if(config.isCloudChanged()) { + CloudConfig cc; + if(config.getCloudConfig(cc) && cc.enabled) { + if(cloud == NULL) { + cloud = new CloudConnector(&Debug); + } + NtpConfig ntp; + config.getNtpConfig(ntp); + if(cloud->setup(cc, meterConfig, sysConfig, ntp, &hw, &rdc, ps)) { + config.setCloudConfig(cc); + } + cloud->setConnectionHandler(ch); + + PriceServiceConfig price; + config.getPriceServiceConfig(price); + cloud->setPriceConfig(price); + + EnergyAccountingConfig *eac = ea.getConfig(); + cloud->setEnergyAccountingConfig(*eac); + + ws.setCloud(cloud); + } else if(cloud != NULL) { + delete cloud; + cloud = NULL; + } + config.ackCloudConfig(); + } + if(cloud != NULL) { + cloud->update(meterState, ea); + } +} +#endif + +void handleMqtt() { + if (mqttEnabled || config.isMqttChanged()) { + if(mqttHandler == NULL || !mqttHandler->connected() || config.isMqttChanged()) { + if(mqttHandler != NULL && config.isMqttChanged()) { + mqttHandler->disconnect(); + } + MQTT_connect(); + config.ackMqttChange(); + } + } else if(mqttHandler != NULL) { + mqttHandler->disconnect(); + } + + if(mqttHandler != NULL) { + unsigned long start = millis(); + mqttHandler->loop(); + unsigned long end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to handle mqtt"), millis()-start); + } + } +} + +void handleWebserver() { + unsigned long start = millis(); + ws.loop(); + unsigned long end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to handle web"), millis()-start); + } +} + +void handleSmartConfig() { + if(WiFi.smartConfigDone()) { + debugI_P(PSTR("Smart config DONE!")); + + NetworkConfig network; + config.getNetworkConfig(network); + strcpy(network.ssid, WiFi.SSID().c_str()); + strcpy(network.psk, WiFi.psk().c_str()); + network.mode = 1; + network.mdns = true; + config.setNetworkConfig(network); + + SystemConfig sys; + config.getSystemConfig(sys); + sys.userConfigured = true; + sys.dataCollectionConsent = 0; + config.setSystemConfig(sys); + config.save(); + + delay(1000); + ESP.restart(); + } +} + +void handleMeterConfig() { if(config.isMeterChanged()) { config.getMeterConfig(meterConfig); if(meterConfig.source == METER_SOURCE_GPIO) { @@ -874,54 +1031,10 @@ void loop() { ws.setMeterConfig(meterConfig.distributionSystem, meterConfig.mainFuse, meterConfig.productionCapacity); config.ackMeterChanged(); } - - if(config.isEnergyAccountingChanged()) { - handleEnergyAccountingChanged(); - } - try { - start = millis(); - if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to read HAN port (true)"), millis()-start); - } - handleTemperature(now); - handleSystem(now); - hw.setBootSuccessful(true); - } else { - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to read HAN port (false)"), millis()-start); - } - } - if(millis() - meterState.getLastUpdateMillis() > 1800000 && !ds.isHappy(time(nullptr))) { - handleClear(now); - } - } catch(const std::exception& e) { - debugE_P(PSTR("Exception in readHanPort (%s)"), e.what()); - meterState.setLastError(METER_ERROR_EXCEPTION); - } - - delay(10); // Needed for auto modem sleep - start = millis(); - #if defined(ESP32) - esp_task_wdt_reset(); - #elif defined(ESP8266) - ESP.wdtFeed(); - #endif - yield(); - - end = millis(); - if(end-start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to feed WDT"), end-start); - } - - if(end-now > SLOW_PROC_TRIGGER_MS*2) { - debugW_P(PSTR("loop() used %dms"), end-now); - } } void handleUiLanguage() { + unsigned long start = millis(); if(config.isUiLanguageChanged()) { debugD_P(PSTR("Language has changed")); if(LittleFS.begin()) { @@ -971,6 +1084,10 @@ void handleUiLanguage() { config.ackUiLanguageChange(); } + unsigned long end = millis(); + if(end-start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to handle language update"), end-start); + } } void handleClear(unsigned long now) { @@ -984,42 +1101,18 @@ void handleClear(unsigned long now) { } } -void handleEnergyAccountingChanged() { - EnergyAccountingConfig *eac = ea.getConfig(); - config.getEnergyAccountingConfig(*eac); - ea.setup(&ds, eac); - config.ackEnergyAccountingChange(); - #if defined(_CLOUDCONNECTOR_H) - if(cloud != NULL) { - cloud->setEnergyAccountingConfig(*eac); - } - #endif -} - -char ntpServerName[64] = ""; - -void handleNtpChange() { - NtpConfig ntp; - if(config.getNtpConfig(ntp)) { - tz = resolveTimezone(ntp.timezone); - if(ntp.enable && strlen(ntp.server) > 0) { - strcpy(ntpServerName, ntp.server); - } else if(ntp.enable) { - strcpy(ntpServerName, "pool.ntp.org"); - } else { - memset(ntpServerName, 0, 64); +void handleEnergyAccounting() { + if(config.isEnergyAccountingChanged()) { + EnergyAccountingConfig *eac = ea.getConfig(); + config.getEnergyAccountingConfig(*eac); + ea.setup(&ds, eac); + config.ackEnergyAccountingChange(); + #if defined(AMS_CLOUD) + if(cloud != NULL) { + cloud->setEnergyAccountingConfig(*eac); } - configTime(tz->toLocal(0), tz->toLocal(JULY1970)-JULY1970, ntpServerName, "", ""); - sntp_servermode_dhcp(ntp.enable && ntp.dhcp ? 1 : 0); // Not implemented on ESP32? - ntpEnabled = ntp.enable; - - ws.setTimezone(tz); - ds.setTimezone(tz); - ea.setTimezone(tz); - ps->setTimezone(tz); + #endif } - - config.ackNtpChange(); } void handleSystem(unsigned long now) { @@ -1060,17 +1153,6 @@ void handleSystem(unsigned long now) { } } -bool handleVoltageCheck() { - if(!hw.isVoltageOptimal()) { - if(WiFi.getMode() == WIFI_STA) { - debugW_P(PSTR("Vcc dropped below limit, disconnecting WiFi for 5 seconds to preserve power")); - ch->disconnect(5000); - } - return false; - } - return true; -} - void handleTemperature(unsigned long now) { unsigned long start, end; if(now - lastTemperatureRead > 15000) { @@ -1090,51 +1172,55 @@ void handleTemperature(unsigned long now) { } void handlePriceService(unsigned long now) { - unsigned long start, end; - if(ps != NULL && ntpEnabled) { - start = millis(); - if(ps->loop() && mqttHandler != NULL) { - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to update prices"), millis()-start); - } - + try { + unsigned long start, end; + if(ps != NULL && ntpEnabled) { start = millis(); - mqttHandler->publishPrices(ps); - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to publish prices to MQTT"), millis()-start); - } - } else { - end = millis(); - if(end - start > SLOW_PROC_TRIGGER_MS) { - debugW_P(PSTR("Used %dms to handle price API"), millis()-start); - } - } - } - - if(config.isPriceServiceChanged()) { - PriceServiceConfig price; - if(config.getPriceServiceConfig(price) && price.enabled && strlen(price.area) > 0) { - if(ps == NULL) { - ps = new PriceService(&Debug); - ea.setPriceService(ps); - ws.setPriceService(ps); - #if defined(_CLOUDCONNECTOR_H) - if(cloud != NULL) { - cloud->setPriceConfig(price); + if(ps->loop() && mqttHandler != NULL) { + end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to update prices"), millis()-start); + } + + start = millis(); + mqttHandler->publishPrices(ps); + end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to publish prices to MQTT"), millis()-start); + } + } else { + end = millis(); + if(end - start > SLOW_PROC_TRIGGER_MS) { + debugW_P(PSTR("Used %dms to handle price API"), millis()-start); } - #endif } - ps->setup(price); - } else if(ps != NULL) { - delete ps; - ps = NULL; - ws.setPriceService(NULL); } - ws.setPriceSettings(price.area, price.currency); - config.ackPriceServiceChange(); - ea.setCurrency(price.currency); + + if(config.isPriceServiceChanged()) { + PriceServiceConfig price; + if(config.getPriceServiceConfig(price) && price.enabled && strlen(price.area) > 0) { + if(ps == NULL) { + ps = new PriceService(&Debug); + ea.setPriceService(ps); + ws.setPriceService(ps); + #if defined(_CLOUDCONNECTOR_H) + if(cloud != NULL) { + cloud->setPriceConfig(price); + } + #endif + } + ps->setup(price); + } else if(ps != NULL) { + delete ps; + ps = NULL; + ws.setPriceService(NULL); + } + ws.setPriceSettings(price.area, price.currency); + config.ackPriceServiceChange(); + ea.setCurrency(price.currency); + } + } catch(const std::exception& e) { + debugE_P(PSTR("Exception in PriceService loop (%s)"), e.what()); } } @@ -1206,7 +1292,7 @@ void connectToNetwork() { return; } lastConnectRetry = millis(); - if(!handleVoltageCheck()) { + if(!hw.isVoltageOptimal(0.1) && (millis() - lastConnectRetry) < 60000) { debugW_P(PSTR("Voltage is not high enough to reconnect")); return; } @@ -1359,20 +1445,18 @@ void handleDataSuccess(AmsData* data) { if(!setupMode && !hw.ledBlink(LED_GREEN, 1)) hw.ledBlink(LED_INTERNAL, 1); - if(mqttHandler != NULL) { + if(mqttHandler != NULL && hw.isVoltageOptimal(0.2)) { #if defined(ESP32) esp_task_wdt_reset(); #elif defined(ESP8266) ESP.wdtFeed(); #endif yield(); - if(mqttHandler->publish(data, &meterState, &ea, ps)) { - delay(10); - } + mqttHandler->publish(data, &meterState, &ea, ps); } #if defined(ESP32) && defined(ENERGY_SPEEDOMETER_PASS) - if(energySpeedometer != NULL && energySpeedometer->publish(&meterState, &meterState, &ea, ps)) { - delay(10); + if(energySpeedometer != NULL && hw.isVoltageOptimal(0.1)) { + energySpeedometer->publish(&meterState, &meterState, &ea, ps); } #endif