diff --git a/include/YaSolR.h b/include/YaSolR.h index b17b2ce..f35fc8f 100644 --- a/include/YaSolR.h +++ b/include/YaSolR.h @@ -89,11 +89,14 @@ extern Mycila::JSY* jsy; extern Mycila::Task* jsyTask; extern Mycila::TaskManager* jsyTaskManager; +// DS18 +extern Mycila::DS18* ds18O1; +extern Mycila::DS18* ds18O2; +extern Mycila::DS18* ds18Sys; +extern Mycila::Task* ds18Task; + extern Mycila::Dimmer dimmerO1; extern Mycila::Dimmer dimmerO2; -extern Mycila::DS18 ds18O1; -extern Mycila::DS18 ds18O2; -extern Mycila::DS18 ds18Sys; extern Mycila::EasyDisplay display; extern Mycila::HA::Discovery haDiscovery; extern Mycila::MQTT mqtt; @@ -116,7 +119,6 @@ extern Mycila::Task dashboardUpdateTask; extern Mycila::Task debugTask; extern Mycila::Task displayCarouselTask; extern Mycila::Task displayTask; -extern Mycila::Task ds18Task; extern Mycila::Task lightsTask; extern Mycila::Task loggingTask; extern Mycila::Task networkStartTask; @@ -148,12 +150,13 @@ extern float yasolr_frequency(); extern void yasolr_boot(); extern void yasolr_configure(); extern void yasolr_divert(); -extern void yasolr_http(); extern void yasolr_event_listeners(); +extern void yasolr_http(); +extern void yasolr_mqtt_subscribers(); extern void yasolr_rest_api(); -extern void yasolr_start_jsy(); +extern void yasolr_start_ds18(); extern void yasolr_start_jsy_remote_listener(); -extern void yasolr_mqtt_subscribers(); +extern void yasolr_start_jsy(); enum class DisplayKind { DISPLAY_HOME = 1, diff --git a/src/Website.cpp b/src/Website.cpp index 9fffe74..49b5dcc 100644 --- a/src/Website.cpp +++ b/src/Website.cpp @@ -858,7 +858,7 @@ void YaSolR::Website::initCards() { const bool bypass1Possible = dimmer1Enabled || output1RelayEnabled; const bool autoDimmer1Activated = config.getBool(KEY_ENABLE_OUTPUT1_AUTO_DIMMER); const bool autoBypass1Activated = config.getBool(KEY_ENABLE_OUTPUT1_AUTO_BYPASS); - const bool output1TempEnabled = (config.getBool(KEY_ENABLE_OUTPUT1_DS18) && ds18O1.isEnabled()) || config.isEmpty(KEY_OUTPUT1_TEMPERATURE_MQTT_TOPIC); + const bool output1TempEnabled = (config.getBool(KEY_ENABLE_OUTPUT1_DS18) && ds18O1 && ds18O1->isEnabled()) || config.isEmpty(KEY_OUTPUT1_TEMPERATURE_MQTT_TOPIC); const bool pzem1Enabled = config.getBool(KEY_ENABLE_OUTPUT1_PZEM) && pzemO1.isEnabled(); const char* output1Days = config.get(KEY_OUTPUT1_DAYS); @@ -904,7 +904,7 @@ void YaSolR::Website::initCards() { const bool bypass2Possible = dimmer2Enabled || output2RelayEnabled; const bool autoDimmer2Activated = config.getBool(KEY_ENABLE_OUTPUT2_AUTO_DIMMER); const bool autoBypass2Activated = config.getBool(KEY_ENABLE_OUTPUT2_AUTO_BYPASS); - const bool output2TempEnabled = (config.getBool(KEY_ENABLE_OUTPUT2_DS18) && ds18O2.isEnabled()) || !config.isEmpty(KEY_OUTPUT2_TEMPERATURE_MQTT_TOPIC); + const bool output2TempEnabled = (config.getBool(KEY_ENABLE_OUTPUT2_DS18) && ds18O2 && ds18O2->isEnabled()) || !config.isEmpty(KEY_OUTPUT2_TEMPERATURE_MQTT_TOPIC); const bool pzem2Enabled = config.getBool(KEY_ENABLE_OUTPUT2_PZEM) && pzemO2.isEnabled(); const char* output2Days = config.get(KEY_OUTPUT2_DAYS); @@ -1190,7 +1190,7 @@ void YaSolR::Website::updateCards() { _routerResistance.setValue(routerMetrics.resistance); _routerEnergy.setValue(routerMetrics.energy); _gridPower.setValue(gridMetrics.power); - _routerDS18State.setValue(ds18Sys.getTemperature().value_or(0.0f)); + _routerDS18State.setValue(ds18Sys ? ds18Sys->getTemperature().value_or(0.0f) : 0); // output 1 @@ -1283,12 +1283,12 @@ void YaSolR::Website::updateCards() { _status(_jsy, KEY_ENABLE_JSY, jsy && jsy->isEnabled(), jsy && jsy->isConnected(), YASOLR_LBL_110); _status(_mqtt, KEY_ENABLE_MQTT, mqtt.isEnabled(), mqtt.isConnected(), mqtt.getLastError() ? mqtt.getLastError() : YASOLR_LBL_113); _status(_output1Dimmer, KEY_ENABLE_OUTPUT1_DIMMER, dimmerO1.isEnabled(), pulseAnalyzer.isOnline(), pulseAnalyzer.isEnabled() ? YASOLR_LBL_110 : YASOLR_LBL_179); - _status(_output1DS18, KEY_ENABLE_OUTPUT1_DS18, ds18O1.isEnabled(), ds18O1.getLastTime() > 0, YASOLR_LBL_114); + _status(_output1DS18, KEY_ENABLE_OUTPUT1_DS18, ds18O1 && ds18O1->isEnabled(), ds18O1 && ds18O1->getLastTime() > 0, YASOLR_LBL_114); _status(_output1PZEM, KEY_ENABLE_OUTPUT1_PZEM, pzemO1.isEnabled(), pzemO1.isConnected() && pzemO1.getDeviceAddress() == YASOLR_PZEM_ADDRESS_OUTPUT1, pzemO1.isConnected() ? YASOLR_LBL_180 : YASOLR_LBL_110); _status(_output2Dimmer, KEY_ENABLE_OUTPUT2_DIMMER, dimmerO2.isEnabled(), pulseAnalyzer.isOnline(), pulseAnalyzer.isEnabled() ? YASOLR_LBL_110 : YASOLR_LBL_179); - _status(_output2DS18, KEY_ENABLE_OUTPUT2_DS18, ds18O2.isEnabled(), ds18O2.getLastTime() > 0, YASOLR_LBL_114); + _status(_output2DS18, KEY_ENABLE_OUTPUT2_DS18, ds18O2 && ds18O2->isEnabled(), ds18O2 && ds18O2->getLastTime() > 0, YASOLR_LBL_114); _status(_output2PZEM, KEY_ENABLE_OUTPUT2_PZEM, pzemO2.isEnabled(), pzemO2.isConnected() && pzemO2.getDeviceAddress() == YASOLR_PZEM_ADDRESS_OUTPUT2, pzemO2.isConnected() ? YASOLR_LBL_180 : YASOLR_LBL_110); - _status(_routerDS18, KEY_ENABLE_DS18_SYSTEM, ds18Sys.isEnabled(), ds18Sys.getLastTime() > 0, YASOLR_LBL_114); + _status(_routerDS18, KEY_ENABLE_DS18_SYSTEM, ds18Sys && ds18Sys->isEnabled(), ds18Sys && ds18Sys->getLastTime() > 0, YASOLR_LBL_114); _status(_zcd, KEY_ENABLE_ZCD, pulseAnalyzer.isEnabled(), pulseAnalyzer.isOnline(), YASOLR_LBL_110); #endif } diff --git a/src/fn/yasolr_configure.cpp b/src/fn/yasolr_configure.cpp index e21b1ee..9565e9f 100644 --- a/src/fn/yasolr_configure.cpp +++ b/src/fn/yasolr_configure.cpp @@ -116,14 +116,6 @@ void yasolr_configure() { if (config.getBool(KEY_ENABLE_LIGHTS)) lights.begin(config.getLong(KEY_PIN_LIGHTS_GREEN), config.getLong(KEY_PIN_LIGHTS_YELLOW), config.getLong(KEY_PIN_LIGHTS_RED)); - // DS18 - if (config.getBool(KEY_ENABLE_DS18_SYSTEM)) - ds18Sys.begin(config.getLong(KEY_PIN_ROUTER_DS18)); - if (config.getBool(KEY_ENABLE_OUTPUT1_DS18)) - ds18O1.begin(config.getLong(KEY_PIN_OUTPUT1_DS18)); - if (config.getBool(KEY_ENABLE_OUTPUT2_DS18)) - ds18O2.begin(config.getLong(KEY_PIN_OUTPUT2_DS18)); - // Electricity: Relays if (config.getBool(KEY_ENABLE_OUTPUT1_RELAY)) bypassRelayO1.begin(config.getLong(KEY_PIN_OUTPUT1_RELAY), config.isEqual(KEY_OUTPUT1_RELAY_TYPE, YASOLR_RELAY_TYPE_NC) ? Mycila::RelayType::NC : Mycila::RelayType::NO); @@ -184,8 +176,6 @@ void yasolr_configure() { debugTask.setInterval(20 * Mycila::TaskDuration::SECONDS); displayTask.setEnabled(display.isEnabled()); displayTask.setInterval(500 * Mycila::TaskDuration::MILLISECONDS); - ds18Task.setEnabled(ds18Sys.isEnabled() || ds18O1.isEnabled() || ds18O2.isEnabled()); - ds18Task.setInterval(10 * Mycila::TaskDuration::SECONDS); lightsTask.setInterval(200 * Mycila::TaskDuration::MILLISECONDS); networkManagerTask.setInterval(200 * Mycila::TaskDuration::MILLISECONDS); relayTask.setEnabledWhen([]() { return !router.isCalibrationRunning() && (routerRelay1.isAutoRelayEnabled() || routerRelay2.isAutoRelayEnabled()); }); @@ -213,7 +203,6 @@ void yasolr_configure() { dashboardUpdateTask.setManager(coreTaskManager); debugTask.setManager(coreTaskManager); displayTask.setManager(coreTaskManager); - ds18Task.setManager(coreTaskManager); lightsTask.setManager(coreTaskManager); loggingTask.setManager(coreTaskManager); networkStartTask.setManager(coreTaskManager); diff --git a/src/fn/yasolr_event_listeners.cpp b/src/fn/yasolr_event_listeners.cpp index d4fc358..161da58 100644 --- a/src/fn/yasolr_event_listeners.cpp +++ b/src/fn/yasolr_event_listeners.cpp @@ -227,27 +227,6 @@ void yasolr_event_listeners() { mqttPublishTask.requestEarlyRun(); }); - ds18Sys.listen([](float temperature, bool changed) { - if (changed) { - logger.info(TAG, "Router Temperature changed to %.02f °C", temperature); - mqttPublishTask.requestEarlyRun(); - } - }); - ds18O1.listen([](float temperature, bool changed) { - output1.temperature().update(temperature); - if (changed) { - logger.info(TAG, "Output 1 Temperature changed to %.02f °C", temperature); - mqttPublishTask.requestEarlyRun(); - } - }); - ds18O2.listen([](float temperature, bool changed) { - output2.temperature().update(temperature); - if (changed) { - logger.info(TAG, "Output 2 Temperature changed to %.02f °C", temperature); - mqttPublishTask.requestEarlyRun(); - } - }); - pzemO1.setCallback([](const Mycila::PZEM::EventType eventType) { if (eventType == Mycila::PZEM::EventType::EVT_READ) { grid.pzemMetrics().update({ diff --git a/src/fn/yasolr_rest_api.cpp b/src/fn/yasolr_rest_api.cpp index e660f67..23c1566 100644 --- a/src/fn/yasolr_rest_api.cpp +++ b/src/fn/yasolr_rest_api.cpp @@ -45,21 +45,24 @@ void yasolr_rest_api() { // output 1 output1.toJson(root["router"]["output1"].to(), voltage); dimmerO1.dimmerToJson(root["router"]["output1"]["dimmer"].to()); - ds18O1.toJson(root["router"]["output1"]["ds18"].to()); + if (ds18O1) + ds18O1->toJson(root["router"]["output1"]["ds18"].to()); pzemO1.toJson(root["router"]["output1"]["pzem"].to()); bypassRelayO1.toJson(root["router"]["output1"]["relay"].to()); // output 2 output2.toJson(root["router"]["output2"].to(), voltage); dimmerO2.dimmerToJson(root["router"]["output2"]["dimmer"].to()); - ds18O2.toJson(root["router"]["output2"]["ds18"].to()); + if (ds18O2) + ds18O2->toJson(root["router"]["output2"]["ds18"].to()); pzemO2.toJson(root["router"]["output2"]["pzem"].to()); bypassRelayO2.toJson(root["router"]["output2"]["relay"].to()); // system JsonObject system = root["system"].to(); Mycila::System::toJson(system); - ds18Sys.toJson(system["ds18"].to()); + if (ds18Sys) + ds18Sys->toJson(system["ds18"].to()); lights.toJson(system["leds"].to()); // stack @@ -363,7 +366,11 @@ void yasolr_rest_api() { root["lights"] = lights.toString(); root["relay1"] = YASOLR_STATE(relay1.isOn()); root["relay2"] = YASOLR_STATE(relay2.isOn()); - root["temperature"] = ds18Sys.getTemperature().value_or(0); + if (ds18Sys) { + float t = ds18Sys->getTemperature().value_or(NAN); + if (!isnanf(t)) + root["temperature"] = t; + } float virtual_grid_power = grid.getPower().orElse(NAN) - routerMeasurements.power; if (!isnanf(virtual_grid_power)) root["virtual_grid_power"] = virtual_grid_power; diff --git a/src/fn/yasolr_start_ds18_system.cpp b/src/fn/yasolr_start_ds18_system.cpp new file mode 100644 index 0000000..882340a --- /dev/null +++ b/src/fn/yasolr_start_ds18_system.cpp @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + * Copyright (C) 2023-2024 Mathieu Carbou + */ +#include + +Mycila::DS18* ds18O1; +Mycila::DS18* ds18O2; +Mycila::DS18* ds18Sys; +Mycila::Task* ds18Task; + +void yasolr_start_ds18() { + if (config.getBool(KEY_ENABLE_DS18_SYSTEM)) { + if (!ds18Sys) { + ds18Sys = new Mycila::DS18(); + ds18Sys->listen([](float temperature, bool changed) { + if (changed) { + logger.info(TAG, "Router Temperature changed to %.02f °C", temperature); + mqttPublishTask.requestEarlyRun(); + } + }); + } + ds18Sys->begin(config.getLong(KEY_PIN_ROUTER_DS18)); + } + + if (config.getBool(KEY_ENABLE_OUTPUT1_DS18)) { + if (!ds18O1) { + ds18O1 = new Mycila::DS18(); + ds18O1->listen([](float temperature, bool changed) { + output1.temperature().update(temperature); + if (changed) { + logger.info(TAG, "Output 1 Temperature changed to %.02f °C", temperature); + mqttPublishTask.requestEarlyRun(); + } + }); + } + ds18O1->begin(config.getLong(KEY_PIN_OUTPUT1_DS18)); + } + + if (config.getBool(KEY_ENABLE_OUTPUT2_DS18)) { + if (!ds18O2) { + ds18O2 = new Mycila::DS18(); + ds18O2->listen([](float temperature, bool changed) { + output2.temperature().update(temperature); + if (changed) { + logger.info(TAG, "Output 2 Temperature changed to %.02f °C", temperature); + mqttPublishTask.requestEarlyRun(); + } + }); + ds18O2 = new Mycila::DS18(); + } + ds18O2->begin(config.getLong(KEY_PIN_OUTPUT2_DS18)); + } + + if (ds18Sys || ds18O1 || ds18O2) { + ds18Task = new Mycila::Task("DS18", [](void* params) { + if (ds18Sys) { + ds18Sys->read(); + yield(); + } + if (ds18O1) { + ds18O1->read(); + yield(); + } + if (ds18O2) { + ds18O2->read(); + yield(); + } + }); + ds18Task->setInterval(10 * Mycila::TaskDuration::SECONDS); + ds18Task->setManager(coreTaskManager); + } +}; diff --git a/src/main.cpp b/src/main.cpp index 86e1559..588a66f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,9 +23,6 @@ YaSolR::Website website; // hardware Mycila::Dimmer dimmerO1; Mycila::Dimmer dimmerO2; -Mycila::DS18 ds18O1; -Mycila::DS18 ds18O2; -Mycila::DS18 ds18Sys; Mycila::EasyDisplay display(YASOLR_DISPLAY_LINES, YASOLR_DISPLAY_LINE_SIZE, 4, u8g2_font_6x12_tf); Mycila::HA::Discovery haDiscovery; Mycila::MQTT mqtt; @@ -52,6 +49,7 @@ void setup() { yasolr_rest_api(); yasolr_mqtt_subscribers(); yasolr_start_jsy(); + yasolr_start_ds18(); logger.info(TAG, "Initializing dashboard"); website.initLayout(); diff --git a/src/tasks/displayTask.cpp b/src/tasks/displayTask.cpp index bd918da..b7a8897 100644 --- a/src/tasks/displayTask.cpp +++ b/src/tasks/displayTask.cpp @@ -107,8 +107,8 @@ Mycila::Task displayTask("Display", [](void* params) { display.home.printf("NTP Time: %02u:%02u\n", timeInfo.tm_hour, timeInfo.tm_min); else display.home.printf("NTP Time: --:--\n"); - if (ds18Sys.isEnabled()) - display.home.printf("Temperature: %4.1f ", ds18Sys.getTemperature().value_or(0)); + if (ds18Sys && ds18Sys->isEnabled()) + display.home.printf("Temperature: %4.1f ", ds18Sys->getTemperature().value_or(0)); else display.home.printf("Temperature: --.- "); display.home.printf("\xb0"); diff --git a/src/tasks/ds18Task.cpp b/src/tasks/ds18Task.cpp deleted file mode 100644 index 8ea5aba..0000000 --- a/src/tasks/ds18Task.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -/* - * Copyright (C) 2023-2024 Mathieu Carbou - */ -#include - -Mycila::Task ds18Task("DS18", [](void* params) { - ds18Sys.read(); - yield(); - ds18O1.read(); - yield(); - ds18O2.read(); - yield(); -}); diff --git a/src/tasks/loggingTask.cpp b/src/tasks/loggingTask.cpp index 8d8b137..8117a0d 100644 --- a/src/tasks/loggingTask.cpp +++ b/src/tasks/loggingTask.cpp @@ -22,7 +22,8 @@ Mycila::Task loggingTask("Logging", Mycila::TaskType::ONCE, [](void* params) { // Enable profiling for some FOREVER tasks dashboardUpdateTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); debugTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); - ds18Task.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); + if (ds18Task) + ds18Task->enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); displayTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); if (jsyTask) jsyTask->enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); @@ -31,7 +32,8 @@ Mycila::Task loggingTask("Logging", Mycila::TaskType::ONCE, [](void* params) { } else { dashboardUpdateTask.disableProfiling(); debugTask.disableProfiling(); - ds18Task.disableProfiling(); + if (ds18Task) + ds18Task->disableProfiling(); displayTask.disableProfiling(); if (jsyTask) jsyTask->disableProfiling(); @@ -41,7 +43,8 @@ Mycila::Task loggingTask("Logging", Mycila::TaskType::ONCE, [](void* params) { // Log execution time for some "ONCE" tasks dashboardInitTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); - ds18Task.setCallback(debug ? LOG_EXEC_TIME : nullptr); + if (ds18Task) + ds18Task->setCallback(debug ? LOG_EXEC_TIME : nullptr); haDiscoveryTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); mqttConfigTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); mqttPublishConfigTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); diff --git a/src/tasks/mqttPublishTask.cpp b/src/tasks/mqttPublishTask.cpp index 414189e..f5d763c 100644 --- a/src/tasks/mqttPublishTask.cpp +++ b/src/tasks/mqttPublishTask.cpp @@ -67,7 +67,8 @@ Mycila::Task mqttPublishTask("MQTT", [](void* params) { mqtt.publish(baseTopic + "/router/power", std::to_string(routerMeasurements.power)); mqtt.publish(baseTopic + "/router/relay1", YASOLR_STATE(relay1.isOn())); mqtt.publish(baseTopic + "/router/relay2", YASOLR_STATE(relay2.isOn())); - mqtt.publish(baseTopic + "/router/temperature", std::to_string(ds18Sys.getTemperature().value_or(0))); + if (ds18Sys) + mqtt.publish(baseTopic + "/router/temperature", std::to_string(ds18Sys->getTemperature().value_or(0))); mqtt.publish(baseTopic + "/router/thdi", isnan(routerMeasurements.thdi) ? "0" : std::to_string(routerMeasurements.thdi)); mqtt.publish(baseTopic + "/router/virtual_grid_power", std::to_string(gridMetrics.power - routerMeasurements.power)); yield();