From ad2a2fc48d7bd4dbd194ca795d27f034284efa68 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 26 Nov 2024 23:20:54 +0100 Subject: [PATCH] ESP-DASH Pro NG --- include/YaSolR.h | 5 +- include/YaSolRDefines.h | 24 +- include/YaSolRWebsite.h | 173 ++++- include/i18n/en.h | 52 +- include/i18n/fr.h | 52 +- lib/ESPDASHPro | 2 +- platformio.ini | 7 +- src/Website.cpp | 1546 ++++++++++++++++++--------------------- src/init/Config.cpp | 5 +- src/init/Core.cpp | 3 +- src/init/Dashboard.cpp | 2 +- src/init/Debug.cpp | 5 +- src/init/Events.cpp | 3 +- src/init/REST.cpp | 4 +- src/main.cpp | 2 +- src/tasks/Dashboard.cpp | 6 +- src/tasks/Routing.cpp | 2 +- 17 files changed, 969 insertions(+), 924 deletions(-) diff --git a/include/YaSolR.h b/include/YaSolR.h index 4985bf27..0258f5df 100644 --- a/include/YaSolR.h +++ b/include/YaSolR.h @@ -85,7 +85,8 @@ extern Mycila::RouterRelay routerRelay2; extern Mycila::TrafficLight lights; extern Mycila::TaskManager coreTaskManager; -extern Mycila::Task dashboardTask; +extern Mycila::Task dashboardInitTask; +extern Mycila::Task dashboardUpdateTask; extern Mycila::Task debugTask; extern Mycila::Task networkConfigTask; extern Mycila::Task networkManagerTask; @@ -128,7 +129,7 @@ extern Mycila::Task routingTask; extern Mycila::Task bootTask; extern Mycila::Task initConfigTask; extern Mycila::Task initCoreTask; -extern Mycila::Task initDashboardCards; +extern Mycila::Task initDashboard; extern Mycila::Task initEventsTask; extern Mycila::Task initLoggingTask; extern Mycila::Task initMqttSubscribersTask; diff --git a/include/YaSolRDefines.h b/include/YaSolRDefines.h index 13a2ab21..0efc0cf7 100644 --- a/include/YaSolRDefines.h +++ b/include/YaSolRDefines.h @@ -45,25 +45,27 @@ #define YASOLR_ADMIN_USERNAME "admin" #define YASOLR_DISPLAY_LINE_SIZE 21 #define YASOLR_DISPLAY_LINES 5 +#define YASOLR_GRAPH_POINTS 120 +#define YASOLR_HIDDEN_PWD "********" #define YASOLR_MQTT_KEEPALIVE 60 +#define YASOLR_MQTT_MEASUREMENT_EXPIRATION 60000 +#define YASOLR_MQTT_SERVER_CERT_FILE "/mqtt-server.pem" #define YASOLR_MQTT_WILL_TOPIC "/status" +#define YASOLR_PID_D_MODE_1 YASOLR_PID_P_MODE_1 +#define YASOLR_PID_D_MODE_2 YASOLR_PID_P_MODE_2 +#define YASOLR_PID_IC_MODE_0 "0: Off" +#define YASOLR_PID_IC_MODE_1 "1: Clamp" +#define YASOLR_PID_IC_MODE_2 "2: Advanced" +#define YASOLR_PID_P_MODE_1 "1: On Error" +#define YASOLR_PID_P_MODE_2 "2: On Input" +#define YASOLR_PID_P_MODE_3 "3: Both" #define YASOLR_PZEM_ADDRESS_OUTPUT1 0x01 #define YASOLR_PZEM_ADDRESS_OUTPUT2 0x02 #define YASOLR_RELAY_TYPE_NC "NC" #define YASOLR_RELAY_TYPE_NO "NO" #define YASOLR_SERIAL_BAUDRATE 115200 #define YASOLR_WEEK_DAYS "sun,mon,tue,wed,thu,fri,sat" -#define YASOLR_GRAPH_POINTS 120 -#define YASOLR_PID_P_MODE_1 "1: On Error" -#define YASOLR_PID_P_MODE_2 "2: On Input" -#define YASOLR_PID_P_MODE_3 "3: Both" -#define YASOLR_PID_D_MODE_1 YASOLR_PID_P_MODE_1 -#define YASOLR_PID_D_MODE_2 YASOLR_PID_P_MODE_2 -#define YASOLR_PID_IC_MODE_0 "0: Off" -#define YASOLR_PID_IC_MODE_1 "1: Clamp" -#define YASOLR_PID_IC_MODE_2 "2: Advanced" -#define YASOLR_MQTT_MEASUREMENT_EXPIRATION 60000 -#define YASOLR_MQTT_SERVER_CERT_FILE "/mqtt-server.pem" +#define YASOLR_WEEK_DAYS_EMPTY "none" // UDP communication diff --git a/include/YaSolRWebsite.h b/include/YaSolRWebsite.h index 78597f75..7d44bab2 100644 --- a/include/YaSolRWebsite.h +++ b/include/YaSolRWebsite.h @@ -19,23 +19,160 @@ namespace YaSolR { void resetPID(); private: - void _boolConfig(Card& card, const char* key); - void _daysConfig(Card& card, const char* key); - void _floatConfig(Card& card, const char* key); - void _numConfig(Card& card, const char* key); - void _pinConfig(Card& card, const char* key); - void _passwordConfig(Card& card, const char* key); - void _sliderConfig(Card& card, const char* key); - void _percentageSlider(Card& card, const char* key); - void _textConfig(Card& card, const char* key); - - void _outputDimmerSlider(Card& card, Mycila::RouterOutput& output); - void _outputBypassSwitch(Card& card, Mycila::RouterOutput& output); - void _relaySwitch(Card& card, Mycila::RouterRelay& relay); - - void _pinout(Card& card, int32_t pin, std::unordered_map& pinout); - void _status(Card& card, const char* key, bool enabled, bool state = true, const char* err = ""); - void _temperature(Card& card, Mycila::DS18& sensor); - void _temperature(Card& card, Mycila::RouterOutput& output); + void _boolConfig(dash::SwitchCard& card, const char* key) { + card.onChange([key, &card, this](bool value) { + config.setBool(key, value); + card.setValue(config.getBool(key) ? 1 : 0); + dashboard.refresh(card); + }); + } + + void _daysConfig(dash::WeekCard& card, const char* key) { +#ifdef APP_MODEL_PRO + card.onChange([key, &card, this](const char* value) { + config.set(key, value[0] ? value : YASOLR_WEEK_DAYS_EMPTY); + card.setValue(value); + dashboard.refresh(card); + }); +#endif + } + + template , bool> = true> + void _numConfig(dash::TextInputCard& card, const char* key) { +#ifdef APP_MODEL_PRO + card.onChange([key, &card](const std::optional& value) { + if (value.has_value()) { + config.set(key, std::to_string(value.value())); + } else { + config.unset(key); + } + card.setValue(static_cast(config.getInt(key))); + dashboard.refresh(card); + }); +#endif + } + + template , bool> = true> + void _numConfig(dash::DropdownCard& card, const char* key) { +#ifdef APP_MODEL_PRO + card.onChange([key, &card](const T& value) { + config.set(key, std::to_string(value)); + card.setValue(config.getInt(key)); + dashboard.refresh(card); + }); +#endif + } + + void _pinConfig(dash::FeedbackTextInputCard& card, const char* key) { +#ifdef APP_MODEL_PRO + card.onChange([key, &card, this](const std::optional value) { + if (value.has_value()) { + config.set(key, std::to_string(value.value())); + } else { + config.unset(key); + } + card.setValue(config.getInt(key)); + initCards(); + dashboard.refresh(card); + }); +#endif + } + + void _passwordConfig(Card& card, const char* key) { +#ifdef APP_MODEL_PRO + card.attachCallback([key, &card, this](const char* value) { + if (value[0]) { + config.set(key, value); + } else { + config.unset(key); + } + card.update(config.isEmpty(key) ? "" : YASOLR_HIDDEN_PWD); + dashboard.refresh(card); + }); +#endif + } + + template , bool> = true> + void _sliderConfig(dash::SliderCard& card, const char* key) { + card.onChange([key, &card](const T& value) { + config.set(key, std::to_string(value)); + card.setValue(static_cast(config.getInt(key))); + dashboard.refresh(card); + }); + } + + void _textConfig(Card& card, const char* key) { +#ifdef APP_MODEL_PRO + card.attachCallback([key, &card](const char* value) { + config.set(key, value); + card.update(config.get(key)); + dashboard.refresh(card); + }); +#endif + } + + void _outputDimmerSlider(dash::SliderCard& card, Mycila::RouterOutput& output) { + card.onChange([&card, &output, this](float value) { + if (output.isDimmerEnabled()) { + output.setDimmerDutyCycle(value / 100); + } + card.setValue(output.getDimmerDutyCycle() * 100); + dashboard.refresh(card); + dashboardUpdateTask.requestEarlyRun(); + }); + } + + void _outputBypassSwitch(dash::SwitchCard& card, Mycila::RouterOutput& output) { + card.onChange([&card, &output, this](bool value) { + if (output.isBypassEnabled()) { + output.setBypass(value); + } + card.setValue(output.isBypassOn()); + dashboard.refresh(card); + dashboardUpdateTask.requestEarlyRun(); + }); + } + + void _relaySwitch(dash::SwitchCard& card, Mycila::RouterRelay& relay) { + card.onChange([&card, &relay, this](bool value) { + relay.tryRelayState(value); + card.setValue(relay.isOn()); + dashboard.refresh(card); + dashboardUpdateTask.requestEarlyRun(); + }); + } + + void _pinout(dash::FeedbackTextInputCard& card, const char* key, std::unordered_map*>& pinout) { + int32_t pin = config.getInt(key); + card.setValue(pin); + if (pin == GPIO_NUM_NC) { + card.setFeedback("(" YASOLR_LBL_115 ")", dash::Status::IDLE); + } else if (pinout.find(pin) != pinout.end()) { + pinout[pin]->setFeedback("(" YASOLR_LBL_153 ")", dash::Status::DANGER); + card.setFeedback("(" YASOLR_LBL_153 ")", dash::Status::DANGER); + } else if (!GPIO_IS_VALID_GPIO(pin)) { + pinout[pin] = &card; + card.setFeedback("(" YASOLR_LBL_154 ")", dash::Status::DANGER); + } else if (!GPIO_IS_VALID_OUTPUT_GPIO(pin)) { + pinout[pin] = &card; + card.setFeedback("(" YASOLR_LBL_155 ")", dash::Status::WARNING); + } else { + pinout[pin] = &card; + card.setFeedback("(" YASOLR_LBL_156 ")", dash::Status::SUCCESS); + } + } + + void _status(dash::FeedbackSwitchCard& card, const char* key, bool enabled, bool active = true, const char* err = "") { + const bool configEnabled = config.getBool(key); + card.setValue(configEnabled); + if (!configEnabled) + card.setFeedback(YASOLR_LBL_115, dash::Status::IDLE); + else if (!enabled) + card.setFeedback(YASOLR_LBL_124, dash::Status::DANGER); + else if (!active) + card.setFeedback(err, dash::Status::WARNING); + else + card.setFeedback(YASOLR_LBL_130, dash::Status::SUCCESS); + } }; } // namespace YaSolR diff --git a/include/i18n/en.h b/include/i18n/en.h index 83dc455e..e2761672 100644 --- a/include/i18n/en.h +++ b/include/i18n/en.h @@ -11,18 +11,18 @@ #define YASOLR_LBL_004 "Application: Manufacturer" #define YASOLR_LBL_005 "Device: Boot Count" #define YASOLR_LBL_006 "Device: Cores" -#define YASOLR_LBL_007 "Device: Heap Memory Total" -#define YASOLR_LBL_008 "Device: Heap Memory Usage" -#define YASOLR_LBL_009 "Device: Heap Memory Used" +#define YASOLR_LBL_007 "Device: Heap Memory Total (bytes)" +#define YASOLR_LBL_008 "Device: Heap Memory Usage (%)" +#define YASOLR_LBL_009 "Device: Heap Memory Used (bytes)" #define YASOLR_LBL_010 "Device: ID" #define YASOLR_LBL_011 "Device: Model" #define YASOLR_LBL_012 "Device: Revision" #define YASOLR_LBL_013 "Firmware: Build Hash" #define YASOLR_LBL_014 "Firmware: Build Timestamp" #define YASOLR_LBL_015 "Firmware: Filename" -#define YASOLR_LBL_016 "Grid: Energy" -#define YASOLR_LBL_017 "Grid: Energy Returned" -#define YASOLR_LBL_018 "Grid: Frequency" +#define YASOLR_LBL_016 "Grid: Energy (kWh)" +#define YASOLR_LBL_017 "Grid: Energy Returned (kWh)" +#define YASOLR_LBL_018 "Grid: Frequency (Hz)" #define YASOLR_LBL_019 YASOLR_LBL_087 ": Hostname" #define YASOLR_LBL_020 YASOLR_LBL_087 ": Interface" #define YASOLR_LBL_021 YASOLR_LBL_087 ": Access Point IP Address" @@ -32,8 +32,8 @@ #define YASOLR_LBL_025 YASOLR_LBL_087 ": WiFi IP Address" #define YASOLR_LBL_026 YASOLR_LBL_087 ": WiFi MAC Address" #define YASOLR_LBL_027 YASOLR_LBL_087 ": WiFi SSID" -#define YASOLR_LBL_028 YASOLR_LBL_087 ": WiFi RSSI" -#define YASOLR_LBL_029 YASOLR_LBL_087 ": WiFi Signal" +#define YASOLR_LBL_028 YASOLR_LBL_087 ": WiFi RSSI (dBm)" +#define YASOLR_LBL_029 YASOLR_LBL_087 ": WiFi Signal (%)" #define YASOLR_LBL_034 "Time" #define YASOLR_LBL_035 "Uptime" #define YASOLR_LBL_036 "Routed Power" @@ -62,11 +62,11 @@ #define YASOLR_LBL_059 "Energy" #define YASOLR_LBL_060 YASOLR_LBL_050 " Automatic Control" #define YASOLR_LBL_061 "Grid Excess Reserved" -#define YASOLR_LBL_062 YASOLR_LBL_050 " Limiter" -#define YASOLR_LBL_063 YASOLR_LBL_050 " " YASOLR_LBL_048 " Limiter" +#define YASOLR_LBL_062 YASOLR_LBL_050 " Power Limiter" +#define YASOLR_LBL_063 YASOLR_LBL_050 " " YASOLR_LBL_048 " Limiter (°C)" #define YASOLR_LBL_064 "Bypass Automatic Control" -#define YASOLR_LBL_065 "Bypass Start " YASOLR_LBL_048 -#define YASOLR_LBL_066 "Bypass Stop " YASOLR_LBL_048 +#define YASOLR_LBL_065 "Bypass Start " YASOLR_LBL_048 " (°C)" +#define YASOLR_LBL_066 "Bypass Stop " YASOLR_LBL_048 " (°C)" #define YASOLR_LBL_067 "Bypass Start Time" #define YASOLR_LBL_068 "Bypass Stop Time" #define YASOLR_LBL_069 "Bypass Week Days" @@ -124,7 +124,7 @@ #define YASOLR_LBL_120 "LED Yellow" #define YASOLR_LBL_121 "PZEM (TX) Serial RX" #define YASOLR_LBL_122 "PZEM (RX) Serial TX" -#define YASOLR_LBL_123 "Pending" +// #define YASOLR_LBL_123 "Pending" #define YASOLR_LBL_124 "Not started" #define YASOLR_LBL_125 "Zero-Cross Detection" #define YASOLR_LBL_126 "Hardware" @@ -140,10 +140,10 @@ #define YASOLR_LBL_138 YASOLR_LBL_070 " Relay (Bypass)" #define YASOLR_LBL_139 "Router DS18" #define YASOLR_LBL_140 YASOLR_LBL_126 " Config" -#define YASOLR_LBL_141 "Nominal Grid Frequency" +#define YASOLR_LBL_141 "Nominal Grid Frequency (Hz)" #define YASOLR_LBL_142 YASOLR_LBL_127 " Speed" #define YASOLR_LBL_143 YASOLR_LBL_127 " Type" -#define YASOLR_LBL_144 YASOLR_LBL_127 " Rotation" +#define YASOLR_LBL_144 YASOLR_LBL_127 " Rotation (°)" #define YASOLR_LBL_145 YASOLR_LBL_046 " Resistance (Ω)" #define YASOLR_LBL_146 YASOLR_LBL_070 " Resistance (Ω)" #define YASOLR_LBL_147 YASOLR_LBL_046 " PZEM Pairing" @@ -156,7 +156,7 @@ #define YASOLR_LBL_154 "Invalid" #define YASOLR_LBL_155 "Input Only" #define YASOLR_LBL_156 "I/O" -#define YASOLR_LBL_157 YASOLR_LBL_128 " Remote UDP: Message Rate" +#define YASOLR_LBL_157 YASOLR_LBL_128 " Remote UDP (msg/s)" #define YASOLR_LBL_158 "Grid Excess Remaining" #define YASOLR_LBL_159 "PID Controller" #define YASOLR_LBL_160 "Proportional Mode" @@ -184,9 +184,9 @@ #define YASOLR_LBL_182 YASOLR_LBL_070 " " YASOLR_LBL_048 " MQTT Topic" #define YASOLR_LBL_183 YASOLR_LBL_046 " Dimmer Min/Max Remapping" #define YASOLR_LBL_184 YASOLR_LBL_070 " Dimmer Min/Max Remapping" -#define YASOLR_LBL_185 +// #define YASOLR_LBL_185 #define YASOLR_LBL_186 "Resistance Value Detection" -#define YASOLR_LBL_187 +// #define YASOLR_LBL_187 #define YASOLR_LBL_030 "Relay: " YASOLR_LBL_046 " Bypass Relay Switch Count" #define YASOLR_LBL_031 "Relay: " YASOLR_LBL_070 " Bypass Relay Switch Count" #define YASOLR_LBL_032 "Relay: " YASOLR_LBL_074 " Switch Count" @@ -196,11 +196,11 @@ #define YASOLR_LBL_190 "Gateway" #define YASOLR_LBL_191 "DNS Server" #define YASOLR_LBL_192 "Device: Reboot Reason" -#define YASOLR_LBL_193 -#define YASOLR_LBL_194 -#define YASOLR_LBL_195 -#define YASOLR_LBL_196 -#define YASOLR_LBL_197 -#define YASOLR_LBL_198 -#define YASOLR_LBL_199 -#define YASOLR_LBL_200 +// #define YASOLR_LBL_193 +// #define YASOLR_LBL_194 +// #define YASOLR_LBL_195 +// #define YASOLR_LBL_196 +// #define YASOLR_LBL_197 +// #define YASOLR_LBL_198 +// #define YASOLR_LBL_199 +// #define YASOLR_LBL_200 diff --git a/include/i18n/fr.h b/include/i18n/fr.h index 04da1c55..55f6f376 100644 --- a/include/i18n/fr.h +++ b/include/i18n/fr.h @@ -10,18 +10,18 @@ #define YASOLR_LBL_004 "Application: Développeur" #define YASOLR_LBL_005 "Micro-contrôleur: Démarrages" #define YASOLR_LBL_006 "Micro-contrôleur: Coeurs" -#define YASOLR_LBL_007 "Micro-contrôleur: Mémoire Heap: totale" -#define YASOLR_LBL_008 "Micro-contrôleur: Mémoire Heap: utilisation" -#define YASOLR_LBL_009 "Micro-contrôleur: Mémoire Heap: utilisée" +#define YASOLR_LBL_007 "Micro-contrôleur: Mémoire Heap: totale (bytes)" +#define YASOLR_LBL_008 "Micro-contrôleur: Mémoire Heap: utilisation (%)" +#define YASOLR_LBL_009 "Micro-contrôleur: Mémoire Heap: utilisée (bytes)" #define YASOLR_LBL_010 "Micro-contrôleur: ID" #define YASOLR_LBL_011 "Micro-contrôleur: Modèle" #define YASOLR_LBL_012 "Micro-contrôleur: Révision" #define YASOLR_LBL_013 "Micro-logiciel: Hachage de construction" #define YASOLR_LBL_014 "Micro-logiciel: Date de construction" #define YASOLR_LBL_015 "Micro-logiciel: Nom de fichier" -#define YASOLR_LBL_016 "Réseau électrique: Énergie" -#define YASOLR_LBL_017 "Réseau électrique: Énergie retournée" -#define YASOLR_LBL_018 "Réseau électrique: Fréquence" +#define YASOLR_LBL_016 "Réseau électrique: Énergie (kWh)" +#define YASOLR_LBL_017 "Réseau électrique: Énergie retournée (kWh)" +#define YASOLR_LBL_018 "Réseau électrique: Fréquence (Hz)" #define YASOLR_LBL_019 "Réseau: Nom d'hôte" #define YASOLR_LBL_020 "Réseau: Interface" #define YASOLR_LBL_021 "Réseau: Point d'accès: Adresse IP" @@ -31,8 +31,8 @@ #define YASOLR_LBL_025 "Réseau: WiFi: Adresse IP" #define YASOLR_LBL_026 "Réseau: WiFi: Adresse MAC" #define YASOLR_LBL_027 "Réseau: WiFi: SSID" -#define YASOLR_LBL_028 "Réseau: WiFi: RSSI" -#define YASOLR_LBL_029 "Réseau: WiFi: Signal" +#define YASOLR_LBL_028 "Réseau: WiFi: RSSI (dBm)" +#define YASOLR_LBL_029 "Réseau: WiFi: Signal (%)" #define YASOLR_LBL_030 "Relais: Déclenchements relais marche forcée sortie 1" #define YASOLR_LBL_031 "Relais: Déclenchements relais marche forcée sortie 2" #define YASOLR_LBL_032 "Relais: Déclenchements relais 1" @@ -65,11 +65,11 @@ #define YASOLR_LBL_059 "Énergie" #define YASOLR_LBL_060 "Routage automatique" #define YASOLR_LBL_061 "Surplus réseau réservé" -#define YASOLR_LBL_062 "Limitation du routage" -#define YASOLR_LBL_063 "Température de consigne d'arrêt du routage" +#define YASOLR_LBL_062 "Limitation puissance routage" +#define YASOLR_LBL_063 "Température de consigne d'arrêt du routage (°C)" #define YASOLR_LBL_064 "Marche forcée automatique" -#define YASOLR_LBL_065 "Température de démarrage de la marche forcée" -#define YASOLR_LBL_066 "Température d'arrêt de la marche forcée" +#define YASOLR_LBL_065 "Température de démarrage de la marche forcée (°C)" +#define YASOLR_LBL_066 "Température d'arrêt de la marche forcée (°C)" #define YASOLR_LBL_067 "Heure de démarrage de la marche forcée" #define YASOLR_LBL_068 "Heure d'arrêt de la marche forcée" #define YASOLR_LBL_069 "Jours de démarrage de la marche forcée" @@ -126,7 +126,7 @@ #define YASOLR_LBL_120 "LED Jaune" #define YASOLR_LBL_121 "PZEM (TX) Serial RX" #define YASOLR_LBL_122 "PZEM (RX) Serial TX" -#define YASOLR_LBL_123 "En attente" +// #define YASOLR_LBL_123 "En attente" #define YASOLR_LBL_124 "Non démarré" #define YASOLR_LBL_125 "Détection de passage par zéro" #define YASOLR_LBL_126 "Matériel" @@ -144,10 +144,10 @@ #define YASOLR_LBL_138 "Sortie 2: Relais (marche forcée)" #define YASOLR_LBL_139 "Router DS18" #define YASOLR_LBL_140 "Configuration du matériel" -#define YASOLR_LBL_141 "Fréquence nominale du réseau" +#define YASOLR_LBL_141 "Fréquence nominale du réseau (Hz)" #define YASOLR_LBL_142 "Écran: Vitesse" #define YASOLR_LBL_143 "Écran: Type" -#define YASOLR_LBL_144 "Écran: Rotation" +#define YASOLR_LBL_144 "Écran: Rotation (°)" #define YASOLR_LBL_145 "Sortie 1: Résistance (Ω)" #define YASOLR_LBL_146 "Sortie 2: Résistance (Ω)" #define YASOLR_LBL_147 "Sortie 1: Association du PZEM" @@ -160,7 +160,7 @@ #define YASOLR_LBL_154 "Invalide" #define YASOLR_LBL_155 "Entrée uniquement" #define YASOLR_LBL_156 "E/S" -#define YASOLR_LBL_157 "JSY Remote UDP: Débit" +#define YASOLR_LBL_157 "JSY Remote UDP: Débit (msg/s)" #define YASOLR_LBL_158 "Surplus réseau restant" #define YASOLR_LBL_159 "Contrôleur PID" #define YASOLR_LBL_160 "Mode proportionnel" @@ -188,19 +188,19 @@ #define YASOLR_LBL_182 "Topic MQTT pour la température sortie 2" #define YASOLR_LBL_183 "Redéfinition Min/Max Variateur Sortie 1" #define YASOLR_LBL_184 "Redéfinition Min/Max Variateur Sortie 2" -#define YASOLR_LBL_185 +// #define YASOLR_LBL_185 #define YASOLR_LBL_186 "Détection valeur résistances" -#define YASOLR_LBL_187 +// #define YASOLR_LBL_187 #define YASOLR_LBL_188 "Adresse IP statique" #define YASOLR_LBL_189 "Masque de sous-réseau" #define YASOLR_LBL_190 "Passerelle" #define YASOLR_LBL_191 "Serveur DNS" #define YASOLR_LBL_192 "Micro-contrôleur: Raison du reboot" -#define YASOLR_LBL_193 -#define YASOLR_LBL_194 -#define YASOLR_LBL_195 -#define YASOLR_LBL_196 -#define YASOLR_LBL_197 -#define YASOLR_LBL_198 -#define YASOLR_LBL_199 -#define YASOLR_LBL_200 +// #define YASOLR_LBL_193 +// #define YASOLR_LBL_194 +// #define YASOLR_LBL_195 +// #define YASOLR_LBL_196 +// #define YASOLR_LBL_197 +// #define YASOLR_LBL_198 +// #define YASOLR_LBL_199 +// #define YASOLR_LBL_200 diff --git a/lib/ESPDASHPro b/lib/ESPDASHPro index f86f86d9..4f5df65d 160000 --- a/lib/ESPDASHPro +++ b/lib/ESPDASHPro @@ -1 +1 @@ -Subproject commit f86f86d98f933c96e66af5622e4463a581b05243 +Subproject commit 4f5df65db2442dd304c7824768d88b860d9247c3 diff --git a/platformio.ini b/platformio.ini index b2c5cf11..cac8a0ec 100644 --- a/platformio.ini +++ b/platformio.ini @@ -133,7 +133,8 @@ build_flags = -D DASH_DEFAULT_CARD_SIZE_XS=12 -D DASH_DEFAULT_CARD_SIZE_XXL=3 -D DASH_USE_STL_STRING=1 - ; -D DASH_JSON_SIZE=4096 + -D DASH_JSON_SIZE=4096 + -D DASH_DEBUG=1 ; WebSerial -D WSL_HIGH_PERF ; YaSolR @@ -150,8 +151,8 @@ build_flags = ; -Og ; -Os ; -D CONFIG_ARDUHAL_LOG_COLORS - -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO - ; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + ; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO + -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG ; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE build_unflags = -std=gnu++11 diff --git a/src/Website.cpp b/src/Website.cpp index ff2750c1..9dafdeac 100644 --- a/src/Website.cpp +++ b/src/Website.cpp @@ -7,8 +7,6 @@ #include #include -#define HIDDEN_PWD "********" - #ifdef APP_MODEL_OSS #define LINE_CHART BAR_CHART #define AREA_CHART BAR_CHART @@ -22,92 +20,93 @@ static const ChartSize chartSize = {.xs = 12, .sm = 12, .md = 12, .lg = 12, .xl int _historyX[YASOLR_GRAPH_POINTS] = {0}; // statistics -Statistic _appName = Statistic(&dashboard, YASOLR_LBL_001); -Statistic _appModel = Statistic(&dashboard, YASOLR_LBL_002); -Statistic _appVersion = Statistic(&dashboard, YASOLR_LBL_003); -Statistic _appManufacturer = Statistic(&dashboard, YASOLR_LBL_004); - -Statistic _deviceBootCount = Statistic(&dashboard, YASOLR_LBL_005); -Statistic _deviceBootReason = Statistic(&dashboard, YASOLR_LBL_192); -Statistic _deviceCores = Statistic(&dashboard, YASOLR_LBL_006); -Statistic _deviceHeapTotal = Statistic(&dashboard, YASOLR_LBL_007); -Statistic _deviceHeapUsage = Statistic(&dashboard, YASOLR_LBL_008); -Statistic _deviceHeapUsed = Statistic(&dashboard, YASOLR_LBL_009); -Statistic _deviceID = Statistic(&dashboard, YASOLR_LBL_010); -Statistic _deviceModel = Statistic(&dashboard, YASOLR_LBL_011); -Statistic _deviceRev = Statistic(&dashboard, YASOLR_LBL_012); - -Statistic _firmwareBuildHash = Statistic(&dashboard, YASOLR_LBL_013); -Statistic _firmwareBuildTimestamp = Statistic(&dashboard, YASOLR_LBL_014); -Statistic _firmwareFilename = Statistic(&dashboard, YASOLR_LBL_015); - -Statistic _gridEnergy = Statistic(&dashboard, YASOLR_LBL_016); -Statistic _gridEnergyReturned = Statistic(&dashboard, YASOLR_LBL_017); -Statistic _gridFrequency = Statistic(&dashboard, YASOLR_LBL_018); - -Statistic _udpMessageRateBuffer = Statistic(&dashboard, YASOLR_LBL_157); - -Statistic _networkHostname = Statistic(&dashboard, YASOLR_LBL_019); -Statistic _networkInterface = Statistic(&dashboard, YASOLR_LBL_020); -Statistic _networkAPIP = Statistic(&dashboard, YASOLR_LBL_021); -Statistic _networkAPMAC = Statistic(&dashboard, YASOLR_LBL_022); -Statistic _networkEthIP = Statistic(&dashboard, YASOLR_LBL_023); -Statistic _networkEthMAC = Statistic(&dashboard, YASOLR_LBL_024); -Statistic _networkWiFiIP = Statistic(&dashboard, YASOLR_LBL_025); -Statistic _networkWiFiMAC = Statistic(&dashboard, YASOLR_LBL_026); -Statistic _networkWiFiSSID = Statistic(&dashboard, YASOLR_LBL_027); -Statistic _networkWiFiRSSI = Statistic(&dashboard, YASOLR_LBL_028); -Statistic _networkWiFiSignal = Statistic(&dashboard, YASOLR_LBL_029); - -Statistic _output1RelaySwitchCount = Statistic(&dashboard, YASOLR_LBL_030); -Statistic _output2RelaySwitchCount = Statistic(&dashboard, YASOLR_LBL_031); -Statistic _relay1SwitchCount = Statistic(&dashboard, YASOLR_LBL_032); -Statistic _relay2SwitchCount = Statistic(&dashboard, YASOLR_LBL_033); - -Statistic _time = Statistic(&dashboard, YASOLR_LBL_034); -Statistic _uptime = Statistic(&dashboard, YASOLR_LBL_035); +dash::StatisticValue _appName(dashboard, YASOLR_LBL_001); +dash::StatisticValue _appModel(dashboard, YASOLR_LBL_002); +dash::StatisticValue _appVersion(dashboard, YASOLR_LBL_003); +dash::StatisticValue _appManufacturer(dashboard, YASOLR_LBL_004); + +dash::StatisticValue _deviceBootCount(dashboard, YASOLR_LBL_005); +dash::StatisticValue _deviceBootReason(dashboard, YASOLR_LBL_192); +dash::StatisticValue _deviceCores(dashboard, YASOLR_LBL_006); +dash::StatisticValue _deviceHeapTotal(dashboard, YASOLR_LBL_007); +dash::StatisticValue _deviceHeapUsage(dashboard, YASOLR_LBL_008); +dash::StatisticValue _deviceHeapUsed(dashboard, YASOLR_LBL_009); +dash::StatisticValue _deviceID(dashboard, YASOLR_LBL_010); +dash::StatisticValue _deviceModel(dashboard, YASOLR_LBL_011); +dash::StatisticValue _deviceRev(dashboard, YASOLR_LBL_012); + +dash::StatisticValue _firmwareBuildHash(dashboard, YASOLR_LBL_013); +dash::StatisticValue _firmwareBuildTimestamp(dashboard, YASOLR_LBL_014); +dash::StatisticValue _firmwareFilename(dashboard, YASOLR_LBL_015); + +dash::StatisticValue _gridEnergy(dashboard, YASOLR_LBL_016); +dash::StatisticValue _gridEnergyReturned(dashboard, YASOLR_LBL_017); +dash::StatisticValue _gridFrequency(dashboard, YASOLR_LBL_018); + +dash::StatisticValue _udpMessageRateBuffer(dashboard, YASOLR_LBL_157); + +dash::StatisticValue _networkHostname(dashboard, YASOLR_LBL_019); +dash::StatisticValue _networkInterface(dashboard, YASOLR_LBL_020); +dash::StatisticValue _networkAPIP(dashboard, YASOLR_LBL_021); +dash::StatisticValue _networkAPMAC(dashboard, YASOLR_LBL_022); +dash::StatisticValue _networkEthIP(dashboard, YASOLR_LBL_023); +dash::StatisticValue _networkEthMAC(dashboard, YASOLR_LBL_024); +dash::StatisticValue _networkWiFiIP(dashboard, YASOLR_LBL_025); +dash::StatisticValue _networkWiFiMAC(dashboard, YASOLR_LBL_026); +dash::StatisticValue _networkWiFiSSID(dashboard, YASOLR_LBL_027); +dash::StatisticValue _networkWiFiRSSI(dashboard, YASOLR_LBL_028); +dash::StatisticValue _networkWiFiSignal(dashboard, YASOLR_LBL_029); + +dash::StatisticValue _output1RelaySwitchCount(dashboard, YASOLR_LBL_030); +dash::StatisticValue _output2RelaySwitchCount(dashboard, YASOLR_LBL_031); +dash::StatisticValue _relay1SwitchCount(dashboard, YASOLR_LBL_032); +dash::StatisticValue _relay2SwitchCount(dashboard, YASOLR_LBL_033); + +dash::StatisticValue _time(dashboard, YASOLR_LBL_034); +dash::StatisticValue _uptime(dashboard, YASOLR_LBL_035); #ifdef APP_MODEL_TRIAL -Statistic _trialRemainingTime = Statistic(&dashboard, "Trial Remaining Time"); +dash::StatisticValue _trialRemainingTime(dashboard, "Trial Remaining Time"); #endif // home -Card _routerPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_036, "W"); -Card _routerApparentPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_037, "VA"); -Card _routerPowerFactor = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_038); -Card _routerTHDi = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_039, "%"); -Card _routerVoltage = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_040, "V"); -Card _routerCurrent = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_041, "A"); -Card _routerResistance = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_042, "Ω"); -Card _routerEnergy = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_043, "kWh"); -Card _gridPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_044, "W"); -Card _routerDS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_045, "°C"); +dash::EnergyCard _routerPower(dashboard, YASOLR_LBL_036, "W"); +dash::EnergyCard _routerApparentPower(dashboard, YASOLR_LBL_037, "VA"); +dash::EnergyCard _routerPowerFactor(dashboard, YASOLR_LBL_038); +dash::EnergyCard _routerTHDi(dashboard, YASOLR_LBL_039, "%"); +dash::EnergyCard _routerVoltage(dashboard, YASOLR_LBL_040, "V"); +dash::EnergyCard _routerCurrent(dashboard, YASOLR_LBL_041, "A"); +dash::EnergyCard _routerResistance(dashboard, YASOLR_LBL_042, "Ω"); +dash::EnergyCard _routerEnergy(dashboard, YASOLR_LBL_043, "kWh"); +dash::EnergyCard _gridPower(dashboard, YASOLR_LBL_044, "W"); +dash::TemperatureCard _routerDS18State(dashboard, YASOLR_LBL_045); + #ifdef APP_MODEL_OSS -Card _relay1Switch = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_073); -Card _relay2Switch = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_076); - -Card _output1State = Card(&dashboard, STATUS_CARD, YASOLR_LBL_046, DASH_STATUS_IDLE); -Card _output1DS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_046 ": " YASOLR_LBL_048, "°C"); -Card _output1DimmerSlider = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_046 ": " YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output1Bypass = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_046 ": " YASOLR_LBL_051); - -Card _output2State = Card(&dashboard, STATUS_CARD, YASOLR_LBL_070, DASH_STATUS_IDLE); -Card _output2DS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_070 ": " YASOLR_LBL_048, "°C"); -Card _output2DimmerSlider = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_070 ": " YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output2Bypass = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_070 ": " YASOLR_LBL_051); +dash::SwitchCard _relay1Switch(dashboard, YASOLR_LBL_073); +dash::SwitchCard _relay2Switch(dashboard, YASOLR_LBL_076); + +dash::FeedbackCard _output1State(dashboard, YASOLR_LBL_046); +dash::TemperatureCard _output1DS18State(dashboard, YASOLR_LBL_046 ": " YASOLR_LBL_048); +dash::SliderCard _output1DimmerSlider(dashboard, YASOLR_LBL_046 ": " YASOLR_LBL_050, 0.0f, 100.0f, 0.01f, "%"); +dash::SwitchCard _output1Bypass(dashboard, YASOLR_LBL_046 ": " YASOLR_LBL_051); + +dash::FeedbackCard _output2State(dashboard, YASOLR_LBL_070); +dash::TemperatureCard _output2DS18State(dashboard, YASOLR_LBL_070 ": " YASOLR_LBL_048); +dash::SliderCard _output2DimmerSlider(dashboard, YASOLR_LBL_070 ": " YASOLR_LBL_050, 0.0f, 100.0f, 0.01f, "%"); +dash::SwitchCard _output2Bypass(&dashboard, YASOLR_LBL_070 ": " YASOLR_LBL_051); #endif int _gridPowerHistoryY[YASOLR_GRAPH_POINTS] = {0}; int _routedPowerHistoryY[YASOLR_GRAPH_POINTS] = {0}; int _routerTHDiHistoryY[YASOLR_GRAPH_POINTS] = {0}; -Chart _gridPowerHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_044 " (W)"); -Chart _routedPowerHistory = Chart(&dashboard, AREA_CHART, YASOLR_LBL_036 " (W)"); -Chart _routerTHDiHistory = Chart(&dashboard, BAR_CHART, YASOLR_LBL_039 " (%)"); +dash::LineChart _gridPowerHistory(dashboard, YASOLR_LBL_044 " (W)"); +dash::AreaChart _routedPowerHistory(dashboard, YASOLR_LBL_036 " (W)"); +dash::BarChart _routerTHDiHistory(dashboard, YASOLR_LBL_039 " (%)"); #ifdef APP_MODEL_OSS -Card _output1PZEMSync = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_147); -Card _output2PZEMSync = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_148); -Card _resistanceCalibration = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_186); +dash::SwitchCard _output1PZEMSync(dashboard, YASOLR_LBL_147); +dash::SwitchCard _output2PZEMSync(dashboard, YASOLR_LBL_148); +dash::SwitchCard _resistanceCalibration(dashboard, YASOLR_LBL_186); #endif #ifdef APP_MODEL_PRO @@ -115,175 +114,175 @@ Card _resistanceCalibration = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_186); // https://en.wikipedia.org/wiki/List_of_Unicode_characters#Miscellaneous_Symbols // https://en.wikipedia.org/wiki/List_of_Unicode_characters#Dingbats -Tab _output1Tab = Tab(&dashboard, "\u2600 " YASOLR_LBL_046); -Card _output1State = Card(&dashboard, STATUS_CARD, YASOLR_LBL_047, DASH_STATUS_IDLE); -Card _output1DS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_048, "°C"); -Card _output1DimmerSlider = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output1DimmerSliderRO = Card(&dashboard, PROGRESS_CARD, YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output1Bypass = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_051); -Card _output1BypassRO = Card(&dashboard, STATUS_CARD, YASOLR_LBL_051); -Card _output1Power = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_052, "W"); -Card _output1ApparentPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_053, "VA"); -Card _output1PowerFactor = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_054); -Card _output1THDi = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_055, "%"); -Card _output1Voltage = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_056, "V"); -Card _output1Current = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_057, "A"); -Card _output1Resistance = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_058, "Ω"); -Card _output1Energy = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_059, "kWh"); -Card _output1DimmerDutyLimiter = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_062, "%", 0, 100, 1); -Card _output1DimmerTempLimiter = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_063, "°C"); -Card _output1DimmerAuto = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_060); -Card _output1DimmerReservedExcess = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_061, "%", 0, 100, 1); -Card _output1BypassAuto = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_064); -Card _output1AutoStartTemp = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_065, "°C"); -Card _output1AutoStoptTemp = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_066, "°C"); -Card _output1AutoStartTime = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_067); -Card _output1AutoStoptTime = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_068); -Card _output1AutoStartWDays = Card(&dashboard, WEEK_SELECTOR_CARD, YASOLR_LBL_069); - -Tab _output2Tab = Tab(&dashboard, "\u2600 " YASOLR_LBL_070); -Card _output2State = Card(&dashboard, STATUS_CARD, YASOLR_LBL_047, DASH_STATUS_IDLE); -Card _output2DS18State = Card(&dashboard, TEMPERATURE_CARD, YASOLR_LBL_048, "°C"); -Card _output2DimmerSlider = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output2DimmerSliderRO = Card(&dashboard, PROGRESS_CARD, YASOLR_LBL_050, "%", 0.0f, 100.0f, 0.01f); -Card _output2Bypass = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_051); -Card _output2BypassRO = Card(&dashboard, STATUS_CARD, YASOLR_LBL_051); -Card _output2Power = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_052, "W"); -Card _output2ApparentPower = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_053, "VA"); -Card _output2PowerFactor = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_054); -Card _output2THDi = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_055, "%"); -Card _output2Voltage = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_056, "V"); -Card _output2Current = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_057, "A"); -Card _output2Resistance = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_058, "Ω"); -Card _output2Energy = Card(&dashboard, ENERGY_CARD, YASOLR_LBL_059, "kWh"); -Card _output2DimmerDutyLimiter = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_062, "%", 0, 100, 1); -Card _output2DimmerTempLimiter = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_063, "°C"); -Card _output2DimmerAuto = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_060); -Card _output2DimmerReservedExcess = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_158, "%", 0, 100, 1); -Card _output2BypassAuto = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_064); -Card _output2AutoStartTemp = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_065); -Card _output2AutoStoptTemp = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_066); -Card _output2AutoStartTime = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_067); -Card _output2AutoStoptTime = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_068); -Card _output2AutoStartWDays = Card(&dashboard, WEEK_SELECTOR_CARD, YASOLR_LBL_069); - -Tab _relaysTab = Tab(&dashboard, "\u2600 " YASOLR_LBL_071); -Card _relay1Switch = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_073); -Card _relay1SwitchRO = Card(&dashboard, STATUS_CARD, YASOLR_LBL_074); -Card _relay2Switch = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_076); -Card _relay2SwitchRO = Card(&dashboard, STATUS_CARD, YASOLR_LBL_077); - -Tab _managementTab = Tab(&dashboard, "\u2764 " YASOLR_LBL_078); -Card _configBackup = Card(&dashboard, LINK_CARD, YASOLR_LBL_079); -Card _configRestore = Card(&dashboard, FILE_UPLOAD_CARD, YASOLR_LBL_080, ".txt"); -Card _restart = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_082); -Card _safeBoot = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_081); -Card _energyReset = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_085); -Card _reset = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_086); -Card _debugMode = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_083); -Card _consoleLink = Card(&dashboard, LINK_CARD, YASOLR_LBL_084); -Card _debugInfo = Card(&dashboard, LINK_CARD, YASOLR_LBL_178); - -Tab _networkConfigTab = Tab(&dashboard, "\u2728 " YASOLR_LBL_087); -Card _adminPwd = Card(&dashboard, PASSWORD_CARD, YASOLR_LBL_088); -Card _ntpServer = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_089); -Card _ntpTimezone = Card(&dashboard, ASYNC_DROPDOWN_CARD, YASOLR_LBL_090); -Card _ntpSync = Card(&dashboard, TIME_SYNC_CARD, YASOLR_LBL_091); -Card _wifiSSID = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_092); -Card _wifiPwd = Card(&dashboard, PASSWORD_CARD, YASOLR_LBL_093); -Card _staticIP = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_188); -Card _subnetMask = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_189); -Card _gateway = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_190); -Card _dnsServer = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_191); -Card _apMode = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_094); - -Tab _mqttConfigTab = Tab(&dashboard, "\u2728 " YASOLR_LBL_095); -Card _mqttServer = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_096); -Card _mqttPort = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_097); -Card _mqttUser = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_098); -Card _mqttPwd = Card(&dashboard, PASSWORD_CARD, YASOLR_LBL_099); -Card _mqttSecured = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_100); -Card _mqttServerCert = Card(&dashboard, FILE_UPLOAD_CARD, YASOLR_LBL_101, ".pem"); -Card _mqttServerCertDelete = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_049); -Card _mqttPublishInterval = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_102, "s", 1, 30, 1); -Card _mqttTopic = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_103); -Card _haDiscovery = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_104); -Card _haDiscoveryTopic = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_105); -Card _mqttGridVoltage = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_106); -Card _mqttGridPower = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_107); -Card _mqttTempO1 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_181); -Card _mqttTempO2 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_182); - -Tab _pinConfigTab = Tab(&dashboard, "\u21C6 " YASOLR_LBL_108); -Card _pinDisplayClock = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_111); -Card _pinDisplayData = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_112); -Card _pinJsyRX = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_116); -Card _pinJsyTX = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_117); -Card _pinLEDGreen = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_118); -Card _pinLEDRed = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_119); -Card _pinLEDYellow = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_120); -Card _pinDimmerO1 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_131); -Card _pinDS18O1 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_132); -Card _pinRelayO1 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_134); -Card _pinDimmerO2 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_135); -Card _pinDS18O2 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_136); -Card _pinRelayO2 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_138); -Card _pinPZEMRX = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_121); -Card _pinPZEMTX = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_122); -Card _pinRelay1 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_074); -Card _pinRelay2 = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_077); -Card _pinDS18Router = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_139); -Card _pinZCD = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_125); - -Tab _hardwareEnableTab = Tab(&dashboard, "\u2699 " YASOLR_LBL_126); -Card _display = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_127); -Card _jsy = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_128); -Card _led = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_129); -Card _mqtt = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_095); -Card _output1Dimmer = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_131); -Card _output1DS18 = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_132); -Card _output1PZEM = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_133); -Card _output1Relay = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_134); -Card _output2Dimmer = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_135); -Card _output2DS18 = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_136); -Card _output2PZEM = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_137); -Card _output2Relay = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_138); -Card _relay1 = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_074); -Card _relay2 = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_077); -Card _routerDS18 = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_139); -Card _zcd = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_125); - -Tab _hardwareConfigTab = Tab(&dashboard, "\u2699 " YASOLR_LBL_140); -Card _gridFreq = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_141); -Card _displaySpeed = Card(&dashboard, SLIDER_CARD, YASOLR_LBL_142, "s", 1, 10, 1); -Card _displayType = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_143); -Card _displayRotation = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_144); -Card _relay1Type = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_151); -Card _relay2Type = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_152); -Card _relay1Load = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_072); -Card _relay2Load = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_075); -Card _output1RelayType = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_149); -Card _output2RelayType = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_150); -Card _output1DimmerMapper = Card(&dashboard, RANGE_SLIDER_CARD, YASOLR_LBL_183, "%", 0, 100, 1); -Card _output2DimmerMapper = Card(&dashboard, RANGE_SLIDER_CARD, YASOLR_LBL_184, "%", 0, 100, 1); -Card _output1PZEMSync = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_147); -Card _output2PZEMSync = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_148); -Card _output1ResistanceInput = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_145); -Card _output2ResistanceInput = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_146); -Card _resistanceCalibration = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_186); - -Tab _pidTab = Tab(&dashboard, "\u2699 " YASOLR_LBL_159); -Card _pidView = Card(&dashboard, BUTTON_CARD, YASOLR_LBL_169); -Card _pidPMode = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_160); -Card _pidDMode = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_161); -Card _pidICMode = Card(&dashboard, DROPDOWN_CARD, YASOLR_LBL_162); -Card _pidSetpoint = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_163); -Card _pidKp = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_166); -Card _pidKi = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_167); -Card _pidKd = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_168); -Card _pidOutMin = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_164); -Card _pidOutMax = Card(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_165); -Card _pidReset = Card(&dashboard, PUSH_BUTTON_CARD, YASOLR_LBL_177); +dash::Tab _output1Tab(dashboard, "\u2600 " YASOLR_LBL_046); +dash::FeedbackCard _output1State(dashboard, YASOLR_LBL_047); +dash::TemperatureCard _output1DS18State(dashboard, YASOLR_LBL_048); +dash::SliderCard _output1DimmerSlider(dashboard, YASOLR_LBL_050, 0.0f, 100.0f, 0.01f, "%"); +dash::ProgressCard _output1DimmerSliderRO(dashboard, YASOLR_LBL_050, 0.0f, 100.0f, "%"); +dash::SwitchCard _output1Bypass(dashboard, YASOLR_LBL_051); +dash::FeedbackCard _output1BypassRO(dashboard, YASOLR_LBL_051); +dash::EnergyCard _output1Power(dashboard, YASOLR_LBL_052, "W"); +dash::EnergyCard _output1ApparentPower(dashboard, YASOLR_LBL_053, "VA"); +dash::EnergyCard _output1PowerFactor(dashboard, YASOLR_LBL_054); +dash::EnergyCard _output1THDi(dashboard, YASOLR_LBL_055, "%"); +dash::EnergyCard _output1Voltage(dashboard, YASOLR_LBL_056, "V"); +dash::EnergyCard _output1Current(dashboard, YASOLR_LBL_057, "A"); +dash::EnergyCard _output1Resistance(dashboard, YASOLR_LBL_058, "Ω"); +dash::EnergyCard _output1Energy(dashboard, YASOLR_LBL_059, "kWh"); +dash::PercentageSliderCard _output1DimmerDutyLimiter(dashboard, YASOLR_LBL_062); +dash::TextInputCard _output1DimmerTempLimiter(dashboard, YASOLR_LBL_063); +dash::SwitchCard _output1DimmerAuto(dashboard, YASOLR_LBL_060); +dash::PercentageSliderCard _output1DimmerReservedExcess(dashboard, YASOLR_LBL_061); +dash::SwitchCard _output1BypassAuto(dashboard, YASOLR_LBL_064); +dash::TextInputCard _output1AutoStartTemp(dashboard, YASOLR_LBL_065); +dash::TextInputCard _output1AutoStoptTemp(dashboard, YASOLR_LBL_066); +Card _output1AutoStartTime(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_067); +Card _output1AutoStoptTime(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_068); +dash::WeekCard _output1AutoStartWDays(dashboard, YASOLR_LBL_069); + +dash::Tab _output2Tab(dashboard, "\u2600 " YASOLR_LBL_070); +dash::FeedbackCard _output2State(dashboard, YASOLR_LBL_047); +dash::TemperatureCard _output2DS18State(dashboard, YASOLR_LBL_048); +dash::SliderCard _output2DimmerSlider(dashboard, YASOLR_LBL_050, 0.0f, 100.0f, 0.01f, "%"); +dash::ProgressCard _output2DimmerSliderRO(dashboard, YASOLR_LBL_050, 0.0f, 100.0f, "%"); +dash::SwitchCard _output2Bypass(dashboard, YASOLR_LBL_051); +dash::FeedbackCard _output2BypassRO(dashboard, YASOLR_LBL_051); +dash::EnergyCard _output2Power(dashboard, YASOLR_LBL_052, "W"); +dash::EnergyCard _output2ApparentPower(dashboard, YASOLR_LBL_053, "VA"); +dash::EnergyCard _output2PowerFactor(dashboard, YASOLR_LBL_054); +dash::EnergyCard _output2THDi(dashboard, YASOLR_LBL_055, "%"); +dash::EnergyCard _output2Voltage(dashboard, YASOLR_LBL_056, "V"); +dash::EnergyCard _output2Current(dashboard, YASOLR_LBL_057, "A"); +dash::EnergyCard _output2Resistance(dashboard, YASOLR_LBL_058, "Ω"); +dash::EnergyCard _output2Energy(dashboard, YASOLR_LBL_059, "kWh"); +dash::PercentageSliderCard _output2DimmerDutyLimiter(dashboard, YASOLR_LBL_062); +dash::TextInputCard _output2DimmerTempLimiter(dashboard, YASOLR_LBL_063); +dash::SwitchCard _output2DimmerAuto(dashboard, YASOLR_LBL_060); +dash::PercentageSliderCard _output2DimmerReservedExcess(dashboard, YASOLR_LBL_158); +dash::SwitchCard _output2BypassAuto(dashboard, YASOLR_LBL_064); +dash::TextInputCard _output2AutoStartTemp(dashboard, YASOLR_LBL_065); +dash::TextInputCard _output2AutoStoptTemp(dashboard, YASOLR_LBL_066); +Card _output2AutoStartTime(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_067); +Card _output2AutoStoptTime(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_068); +dash::WeekCard _output2AutoStartWDays(dashboard, YASOLR_LBL_069); + +dash::Tab _relaysTab(dashboard, "\u2600 " YASOLR_LBL_071); +dash::SwitchCard _relay1Switch(dashboard, YASOLR_LBL_073); +dash::FeedbackCard _relay1SwitchRO(dashboard, YASOLR_LBL_074); +dash::SwitchCard _relay2Switch(dashboard, YASOLR_LBL_076); +dash::FeedbackCard _relay2SwitchRO(dashboard, YASOLR_LBL_077); + +dash::Tab _managementTab(dashboard, "\u2764 " YASOLR_LBL_078); +dash::LinkCard _configBackup(dashboard, YASOLR_LBL_079); +dash::FileUploadCard _configRestore(dashboard, YASOLR_LBL_080, ".txt"); +dash::PushButtonCard _restart(dashboard, YASOLR_LBL_082); +dash::PushButtonCard _safeBoot(dashboard, YASOLR_LBL_081); +dash::PushButtonCard _energyReset(dashboard, YASOLR_LBL_085); +dash::PushButtonCard _reset(dashboard, YASOLR_LBL_086); +dash::SwitchCard _debugMode(dashboard, YASOLR_LBL_083); +dash::LinkCard _consoleLink(dashboard, YASOLR_LBL_084); +dash::LinkCard _debugInfo(dashboard, YASOLR_LBL_178); + +dash::Tab _networkConfigTab(dashboard, "\u2728 " YASOLR_LBL_087); +Card _adminPwd(&dashboard, PASSWORD_CARD, YASOLR_LBL_088); +Card _ntpServer(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_089); +Card _ntpTimezone(&dashboard, ASYNC_DROPDOWN_CARD, YASOLR_LBL_090); +dash::TimeSyncCard _ntpSync(dashboard, YASOLR_LBL_091); +Card _wifiSSID(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_092); +Card _wifiPwd(&dashboard, PASSWORD_CARD, YASOLR_LBL_093); +Card _staticIP(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_188); +Card _subnetMask(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_189); +Card _gateway(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_190); +Card _dnsServer(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_191); +dash::SwitchCard _apMode(dashboard, YASOLR_LBL_094); + +dash::Tab _mqttConfigTab(dashboard, "\u2728 " YASOLR_LBL_095); +Card _mqttServer(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_096); +dash::TextInputCard _mqttPort(dashboard, YASOLR_LBL_097); +Card _mqttUser(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_098); +Card _mqttPwd(&dashboard, PASSWORD_CARD, YASOLR_LBL_099); +dash::SwitchCard _mqttSecured(dashboard, YASOLR_LBL_100); +Card _mqttServerCert(&dashboard, FILE_UPLOAD_CARD, YASOLR_LBL_101, ".pem"); +dash::PushButtonCard _mqttServerCertDelete(dashboard, YASOLR_LBL_049); +dash::SliderCard _mqttPublishInterval(dashboard, YASOLR_LBL_102, 1, 30, 1, "s"); +Card _mqttTopic(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_103); +dash::SwitchCard _haDiscovery(dashboard, YASOLR_LBL_104); +Card _haDiscoveryTopic(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_105); +Card _mqttGridVoltage(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_106); +Card _mqttGridPower(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_107); +Card _mqttTempO1(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_181); +Card _mqttTempO2(&dashboard, TEXT_INPUT_CARD, YASOLR_LBL_182); + +dash::Tab _pinConfigTab(dashboard, "\u21C6 " YASOLR_LBL_108); +dash::FeedbackTextInputCard _pinDisplayClock(dashboard, YASOLR_LBL_111); +dash::FeedbackTextInputCard _pinDisplayData(dashboard, YASOLR_LBL_112); +dash::FeedbackTextInputCard _pinJsyRX(dashboard, YASOLR_LBL_116); +dash::FeedbackTextInputCard _pinJsyTX(dashboard, YASOLR_LBL_117); +dash::FeedbackTextInputCard _pinLEDGreen(dashboard, YASOLR_LBL_118); +dash::FeedbackTextInputCard _pinLEDRed(dashboard, YASOLR_LBL_119); +dash::FeedbackTextInputCard _pinLEDYellow(dashboard, YASOLR_LBL_120); +dash::FeedbackTextInputCard _pinDimmerO1(dashboard, YASOLR_LBL_131); +dash::FeedbackTextInputCard _pinDS18O1(dashboard, YASOLR_LBL_132); +dash::FeedbackTextInputCard _pinRelayO1(dashboard, YASOLR_LBL_134); +dash::FeedbackTextInputCard _pinDimmerO2(dashboard, YASOLR_LBL_135); +dash::FeedbackTextInputCard _pinDS18O2(dashboard, YASOLR_LBL_136); +dash::FeedbackTextInputCard _pinRelayO2(dashboard, YASOLR_LBL_138); +dash::FeedbackTextInputCard _pinPZEMRX(dashboard, YASOLR_LBL_121); +dash::FeedbackTextInputCard _pinPZEMTX(dashboard, YASOLR_LBL_122); +dash::FeedbackTextInputCard _pinRelay1(dashboard, YASOLR_LBL_074); +dash::FeedbackTextInputCard _pinRelay2(dashboard, YASOLR_LBL_077); +dash::FeedbackTextInputCard _pinDS18Router(dashboard, YASOLR_LBL_139); +dash::FeedbackTextInputCard _pinZCD(dashboard, YASOLR_LBL_125); + +dash::Tab _hardwareEnableTab(dashboard, "\u2699 " YASOLR_LBL_126); +dash::FeedbackSwitchCard _display(dashboard, YASOLR_LBL_127); +dash::FeedbackSwitchCard _jsy(dashboard, YASOLR_LBL_128); +dash::FeedbackSwitchCard _led(dashboard, YASOLR_LBL_129); +dash::FeedbackSwitchCard _mqtt(dashboard, YASOLR_LBL_095); +dash::FeedbackSwitchCard _output1Dimmer(dashboard, YASOLR_LBL_131); +dash::FeedbackSwitchCard _output1DS18(dashboard, YASOLR_LBL_132); +dash::FeedbackSwitchCard _output1PZEM(dashboard, YASOLR_LBL_133); +dash::FeedbackSwitchCard _output1Relay(dashboard, YASOLR_LBL_134); +dash::FeedbackSwitchCard _output2Dimmer(dashboard, YASOLR_LBL_135); +dash::FeedbackSwitchCard _output2DS18(dashboard, YASOLR_LBL_136); +dash::FeedbackSwitchCard _output2PZEM(dashboard, YASOLR_LBL_137); +dash::FeedbackSwitchCard _output2Relay(dashboard, YASOLR_LBL_138); +dash::FeedbackSwitchCard _relay1(dashboard, YASOLR_LBL_074); +dash::FeedbackSwitchCard _relay2(dashboard, YASOLR_LBL_077); +dash::FeedbackSwitchCard _routerDS18(dashboard, YASOLR_LBL_139); +dash::FeedbackSwitchCard _zcd(dashboard, YASOLR_LBL_125); + +dash::Tab _hardwareConfigTab(dashboard, "\u2699 " YASOLR_LBL_140); +dash::DropdownCard _gridFreq(dashboard, YASOLR_LBL_141, "Auto-detect,50 Hz,60 Hz"); +dash::SliderCard _displaySpeed(dashboard, YASOLR_LBL_142, 1, 10, 1, "s"); +Card _displayType(&dashboard, DROPDOWN_CARD, YASOLR_LBL_143); +dash::DropdownCard _displayRotation(dashboard, YASOLR_LBL_144, "0,90,180,270"); +Card _relay1Type(&dashboard, DROPDOWN_CARD, YASOLR_LBL_151); +Card _relay2Type(&dashboard, DROPDOWN_CARD, YASOLR_LBL_152); +dash::TextInputCard _relay1Load(dashboard, YASOLR_LBL_072); +dash::TextInputCard _relay2Load(dashboard, YASOLR_LBL_075); +Card _output1RelayType(&dashboard, DROPDOWN_CARD, YASOLR_LBL_149); +Card _output2RelayType(&dashboard, DROPDOWN_CARD, YASOLR_LBL_150); +dash::RangeSliderCard _output1DimmerMapper(dashboard, YASOLR_LBL_183, 0, 100, 1, "%"); +dash::RangeSliderCard _output2DimmerMapper(dashboard, YASOLR_LBL_184, 0, 100, 1, "%"); +dash::SwitchCard _output1PZEMSync(dashboard, YASOLR_LBL_147); +dash::SwitchCard _output2PZEMSync(dashboard, YASOLR_LBL_148); +dash::FeedbackTextInputCard _output1ResistanceInput(dashboard, YASOLR_LBL_145); +dash::FeedbackTextInputCard _output2ResistanceInput(dashboard, YASOLR_LBL_146); +dash::SwitchCard _resistanceCalibration(dashboard, YASOLR_LBL_186); + +dash::Tab _pidTab(dashboard, "\u2699 " YASOLR_LBL_159); +dash::SwitchCard _pidView(dashboard, YASOLR_LBL_169); +dash::DropdownCard _pidPMode(dashboard, YASOLR_LBL_160, YASOLR_PID_P_MODE_1 "," YASOLR_PID_P_MODE_2 "," YASOLR_PID_P_MODE_3); +dash::DropdownCard _pidDMode(dashboard, YASOLR_LBL_161, YASOLR_PID_D_MODE_1 "," YASOLR_PID_D_MODE_2); +dash::DropdownCard _pidICMode(dashboard, YASOLR_LBL_162, YASOLR_PID_IC_MODE_0 "," YASOLR_PID_IC_MODE_1 "," YASOLR_PID_IC_MODE_2); +dash::TextInputCard _pidSetpoint(dashboard, YASOLR_LBL_163); +dash::TextInputCard _pidKp(dashboard, YASOLR_LBL_166); +dash::TextInputCard _pidKi(dashboard, YASOLR_LBL_167); +dash::TextInputCard _pidKd(dashboard, YASOLR_LBL_168); +dash::TextInputCard _pidOutMin(dashboard, YASOLR_LBL_164); +dash::TextInputCard _pidOutMax(dashboard, YASOLR_LBL_165); +dash::PushButtonCard _pidReset(dashboard, YASOLR_LBL_177); // input,output,error,pTerm,iTerm,dTerm,sum int _pidInputHistoryY[YASOLR_GRAPH_POINTS] = {0}; @@ -293,13 +292,13 @@ int _pidPTermHistoryY[YASOLR_GRAPH_POINTS] = {0}; int _pidITermHistoryY[YASOLR_GRAPH_POINTS] = {0}; int _pidDTermHistoryY[YASOLR_GRAPH_POINTS] = {0}; int _pidSumHistoryY[YASOLR_GRAPH_POINTS] = {0}; -Chart _pidInputHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_170); -Chart _pidOutputHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_171); -Chart _pidErrorHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_172); -Chart _pidSumHistory = Chart(&dashboard, BAR_CHART, YASOLR_LBL_173); -Chart _pidPTermHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_174); -Chart _pidITermHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_175); -Chart _pidDTermHistory = Chart(&dashboard, LINE_CHART, YASOLR_LBL_176); +dash::LineChart _pidInputHistory(dashboard, YASOLR_LBL_170); +dash::LineChart _pidOutputHistory(dashboard, YASOLR_LBL_171); +dash::LineChart _pidErrorHistory(dashboard, YASOLR_LBL_172); +dash::BarChart _pidSumHistory(dashboard, YASOLR_LBL_173); +dash::LineChart _pidPTermHistory(dashboard, YASOLR_LBL_174); +dash::LineChart _pidITermHistory(dashboard, YASOLR_LBL_175); +dash::LineChart _pidDTermHistory(dashboard, YASOLR_LBL_176); #endif void YaSolR::Website::initLayout() { @@ -310,9 +309,9 @@ void YaSolR::Website::initLayout() { // overview - _gridPowerHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _routedPowerHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _routerTHDiHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); + _gridPowerHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _routedPowerHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _routerTHDiHistory.setX(_historyX, YASOLR_GRAPH_POINTS); _outputBypassSwitch(_output1Bypass, output1); _outputDimmerSlider(_output1DimmerSlider, output1); @@ -323,19 +322,19 @@ void YaSolR::Website::initLayout() { _relaySwitch(_relay1Switch, routerRelay1); _relaySwitch(_relay2Switch, routerRelay2); - _output1PZEMSync.attachCallback([this](int32_t value) { + _output1PZEMSync.onChange([](bool value) { pzemO1PairingTask.resume(); - _output1PZEMSync.update(!pzemO1PairingTask.isPaused()); - dashboard.refreshCard(&_output1PZEMSync); + _output1PZEMSync.setValue(!pzemO1PairingTask.isPaused()); + dashboard.refresh(_output1PZEMSync); }); - _output2PZEMSync.attachCallback([this](int32_t value) { + _output2PZEMSync.onChange([](bool value) { pzemO2PairingTask.resume(); - _output2PZEMSync.update(!pzemO2PairingTask.isPaused()); - dashboard.refreshCard(&_output2PZEMSync); + _output2PZEMSync.setValue(!pzemO2PairingTask.isPaused()); + dashboard.refresh(_output2PZEMSync); }); - _resistanceCalibration.attachCallback([this](int32_t value) { + _resistanceCalibration.onChange([this](bool value) { config.set(KEY_ENABLE_OUTPUT1_AUTO_BYPASS, YASOLR_FALSE, false); config.set(KEY_ENABLE_OUTPUT1_AUTO_DIMMER, YASOLR_FALSE, false); config.set(KEY_OUTPUT1_DIMMER_LIMIT, "100", false); @@ -352,8 +351,8 @@ void YaSolR::Website::initLayout() { mqttPublishConfigTask.resume(); mqttPublishTask.requestEarlyRun(); - _resistanceCalibration.update(router.isCalibrationRunning()); - dashboard.refreshCard(&_resistanceCalibration); + _resistanceCalibration.setValue(router.isCalibrationRunning()); + dashboard.refresh(_resistanceCalibration); }); #ifdef APP_MODEL_PRO @@ -367,13 +366,13 @@ void YaSolR::Website::initLayout() { // PID - _pidInputHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidOutputHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidErrorHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidPTermHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidITermHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidDTermHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); - _pidSumHistory.updateX(_historyX, YASOLR_GRAPH_POINTS); + _pidInputHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidOutputHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidErrorHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidPTermHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidITermHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidDTermHistory.setX(_historyX, YASOLR_GRAPH_POINTS); + _pidSumHistory.setX(_historyX, YASOLR_GRAPH_POINTS); _pidInputHistory.setSize(chartSize); _pidOutputHistory.setSize(chartSize); @@ -385,33 +384,33 @@ void YaSolR::Website::initLayout() { // output 1 - _output1State.setTab(&_output1Tab); - _output1DS18State.setTab(&_output1Tab); - _output1DimmerSlider.setTab(&_output1Tab); - _output1DimmerSliderRO.setTab(&_output1Tab); - _output1Bypass.setTab(&_output1Tab); - _output1BypassRO.setTab(&_output1Tab); - - _output1Power.setTab(&_output1Tab); - _output1PowerFactor.setTab(&_output1Tab); - _output1THDi.setTab(&_output1Tab); - _output1Energy.setTab(&_output1Tab); - - _output1ApparentPower.setTab(&_output1Tab); - _output1Voltage.setTab(&_output1Tab); - _output1Current.setTab(&_output1Tab); - _output1Resistance.setTab(&_output1Tab); - - _output1BypassAuto.setTab(&_output1Tab); - _output1DimmerAuto.setTab(&_output1Tab); - _output1AutoStartTemp.setTab(&_output1Tab); + _output1State.setTab(_output1Tab); + _output1DS18State.setTab(_output1Tab); + _output1DimmerSlider.setTab(_output1Tab); + _output1DimmerSliderRO.setTab(_output1Tab); + _output1Bypass.setTab(_output1Tab); + _output1BypassRO.setTab(_output1Tab); + + _output1Power.setTab(_output1Tab); + _output1PowerFactor.setTab(_output1Tab); + _output1THDi.setTab(_output1Tab); + _output1Energy.setTab(_output1Tab); + + _output1ApparentPower.setTab(_output1Tab); + _output1Voltage.setTab(_output1Tab); + _output1Current.setTab(_output1Tab); + _output1Resistance.setTab(_output1Tab); + + _output1BypassAuto.setTab(_output1Tab); + _output1DimmerAuto.setTab(_output1Tab); + _output1AutoStartTemp.setTab(_output1Tab); _output1AutoStartTime.setTab(&_output1Tab); - _output1AutoStartWDays.setTab(&_output1Tab); - _output1AutoStoptTemp.setTab(&_output1Tab); + _output1AutoStartWDays.setTab(_output1Tab); + _output1AutoStoptTemp.setTab(_output1Tab); _output1AutoStoptTime.setTab(&_output1Tab); - _output1DimmerReservedExcess.setTab(&_output1Tab); - _output1DimmerDutyLimiter.setTab(&_output1Tab); - _output1DimmerTempLimiter.setTab(&_output1Tab); + _output1DimmerReservedExcess.setTab(_output1Tab); + _output1DimmerDutyLimiter.setTab(_output1Tab); + _output1DimmerTempLimiter.setTab(_output1Tab); _boolConfig(_output1BypassAuto, KEY_ENABLE_OUTPUT1_AUTO_BYPASS); _boolConfig(_output1DimmerAuto, KEY_ENABLE_OUTPUT1_AUTO_DIMMER); @@ -419,40 +418,40 @@ void YaSolR::Website::initLayout() { _numConfig(_output1AutoStartTemp, KEY_OUTPUT1_TEMPERATURE_START); _numConfig(_output1AutoStoptTemp, KEY_OUTPUT1_TEMPERATURE_STOP); _numConfig(_output1DimmerTempLimiter, KEY_OUTPUT1_DIMMER_STOP_TEMP); - _percentageSlider(_output1DimmerDutyLimiter, KEY_OUTPUT1_DIMMER_LIMIT); - _percentageSlider(_output1DimmerReservedExcess, KEY_OUTPUT1_RESERVED_EXCESS); + _sliderConfig(_output1DimmerDutyLimiter, KEY_OUTPUT1_DIMMER_LIMIT); + _sliderConfig(_output1DimmerReservedExcess, KEY_OUTPUT1_RESERVED_EXCESS); _textConfig(_output1AutoStartTime, KEY_OUTPUT1_TIME_START); _textConfig(_output1AutoStoptTime, KEY_OUTPUT1_TIME_STOP); // output 2 - _output2State.setTab(&_output2Tab); - _output2DS18State.setTab(&_output2Tab); - _output2DimmerSlider.setTab(&_output2Tab); - _output2DimmerSliderRO.setTab(&_output2Tab); - _output2Bypass.setTab(&_output2Tab); - _output2BypassRO.setTab(&_output2Tab); - - _output2Power.setTab(&_output2Tab); - _output2PowerFactor.setTab(&_output2Tab); - _output2THDi.setTab(&_output2Tab); - _output2Energy.setTab(&_output2Tab); - - _output2ApparentPower.setTab(&_output2Tab); - _output2Voltage.setTab(&_output2Tab); - _output2Current.setTab(&_output2Tab); - _output2Resistance.setTab(&_output2Tab); - - _output2BypassAuto.setTab(&_output2Tab); - _output2DimmerAuto.setTab(&_output2Tab); - _output2AutoStartTemp.setTab(&_output2Tab); + _output2State.setTab(_output2Tab); + _output2DS18State.setTab(_output2Tab); + _output2DimmerSlider.setTab(_output2Tab); + _output2DimmerSliderRO.setTab(_output2Tab); + _output2Bypass.setTab(_output2Tab); + _output2BypassRO.setTab(_output2Tab); + + _output2Power.setTab(_output2Tab); + _output2PowerFactor.setTab(_output2Tab); + _output2THDi.setTab(_output2Tab); + _output2Energy.setTab(_output2Tab); + + _output2ApparentPower.setTab(_output2Tab); + _output2Voltage.setTab(_output2Tab); + _output2Current.setTab(_output2Tab); + _output2Resistance.setTab(_output2Tab); + + _output2BypassAuto.setTab(_output2Tab); + _output2DimmerAuto.setTab(_output2Tab); + _output2AutoStartTemp.setTab(_output2Tab); _output2AutoStartTime.setTab(&_output2Tab); - _output2AutoStartWDays.setTab(&_output2Tab); - _output2AutoStoptTemp.setTab(&_output2Tab); + _output2AutoStartWDays.setTab(_output2Tab); + _output2AutoStoptTemp.setTab(_output2Tab); _output2AutoStoptTime.setTab(&_output2Tab); - _output2DimmerReservedExcess.setTab(&_output2Tab); - _output2DimmerDutyLimiter.setTab(&_output2Tab); - _output2DimmerTempLimiter.setTab(&_output2Tab); + _output2DimmerReservedExcess.setTab(_output2Tab); + _output2DimmerDutyLimiter.setTab(_output2Tab); + _output2DimmerTempLimiter.setTab(_output2Tab); _boolConfig(_output2BypassAuto, KEY_ENABLE_OUTPUT2_AUTO_BYPASS); _boolConfig(_output2DimmerAuto, KEY_ENABLE_OUTPUT2_AUTO_DIMMER); @@ -460,47 +459,47 @@ void YaSolR::Website::initLayout() { _numConfig(_output2AutoStartTemp, KEY_OUTPUT2_TEMPERATURE_START); _numConfig(_output2AutoStoptTemp, KEY_OUTPUT2_TEMPERATURE_STOP); _numConfig(_output2DimmerTempLimiter, KEY_OUTPUT2_DIMMER_STOP_TEMP); - _percentageSlider(_output2DimmerDutyLimiter, KEY_OUTPUT2_DIMMER_LIMIT); - _percentageSlider(_output2DimmerReservedExcess, KEY_OUTPUT2_RESERVED_EXCESS); + _sliderConfig(_output2DimmerDutyLimiter, KEY_OUTPUT2_DIMMER_LIMIT); + _sliderConfig(_output2DimmerReservedExcess, KEY_OUTPUT2_RESERVED_EXCESS); _textConfig(_output2AutoStartTime, KEY_OUTPUT2_TIME_START); _textConfig(_output2AutoStoptTime, KEY_OUTPUT2_TIME_STOP); // relays - _relay1Switch.setTab(&_relaysTab); - _relay1SwitchRO.setTab(&_relaysTab); - _relay2Switch.setTab(&_relaysTab); - _relay2SwitchRO.setTab(&_relaysTab); + _relay1Switch.setTab(_relaysTab); + _relay1SwitchRO.setTab(_relaysTab); + _relay2Switch.setTab(_relaysTab); + _relay2SwitchRO.setTab(_relaysTab); // management - _configBackup.setTab(&_managementTab); - _configRestore.setTab(&_managementTab); - _consoleLink.setTab(&_managementTab); - _debugInfo.setTab(&_managementTab); - _debugMode.setTab(&_managementTab); - _safeBoot.setTab(&_managementTab); - _reset.setTab(&_managementTab); - _restart.setTab(&_managementTab); - _energyReset.setTab(&_managementTab); + _configBackup.setTab(_managementTab); + _configRestore.setTab(_managementTab); + _consoleLink.setTab(_managementTab); + _debugInfo.setTab(_managementTab); + _debugMode.setTab(_managementTab); + _safeBoot.setTab(_managementTab); + _reset.setTab(_managementTab); + _restart.setTab(_managementTab); + _energyReset.setTab(_managementTab); _boolConfig(_debugMode, KEY_ENABLE_DEBUG); - _energyReset.attachCallback([]() { + _energyReset.onPush([]() { jsy.resetEnergy(); pzemO1.resetEnergy(); pzemO2.resetEnergy(); }); - _reset.attachCallback([]() { resetTask.resume(); }); - _restart.attachCallback([]() { restartTask.resume(); }); - _safeBoot.attachCallback([]() { safeBootTask.resume(); }); + _reset.onPush([]() { resetTask.resume(); }); + _restart.onPush([]() { restartTask.resume(); }); + _safeBoot.onPush([]() { safeBootTask.resume(); }); // network (config) _adminPwd.setTab(&_networkConfigTab); - _apMode.setTab(&_networkConfigTab); + _apMode.setTab(_networkConfigTab); _ntpServer.setTab(&_networkConfigTab); - _ntpSync.setTab(&_networkConfigTab); + _ntpSync.setTab(_networkConfigTab); _ntpTimezone.setTab(&_networkConfigTab); _wifiPwd.setTab(&_networkConfigTab); _wifiSSID.setTab(&_networkConfigTab); @@ -520,27 +519,23 @@ void YaSolR::Website::initLayout() { _textConfig(_gateway, KEY_NET_GATEWAY); _textConfig(_dnsServer, KEY_NET_DNS); - _ntpSync.attachCallback([](const char* value) { - const size_t len = strlen(value); - timeval tv; - tv.tv_sec = std::stoul(std::string(value, len - 3)); - tv.tv_usec = atol(value + len - 3); + _ntpSync.onSync([](const timeval& tv) { Mycila::NTP.sync(tv); }); // mqtt (config) - _haDiscovery.setTab(&_mqttConfigTab); + _haDiscovery.setTab(_mqttConfigTab); _haDiscoveryTopic.setTab(&_mqttConfigTab); _mqttGridPower.setTab(&_mqttConfigTab); _mqttGridVoltage.setTab(&_mqttConfigTab); - _mqttPort.setTab(&_mqttConfigTab); - _mqttPublishInterval.setTab(&_mqttConfigTab); + _mqttPort.setTab(_mqttConfigTab); + _mqttPublishInterval.setTab(_mqttConfigTab); _mqttPwd.setTab(&_mqttConfigTab); - _mqttSecured.setTab(&_mqttConfigTab); + _mqttSecured.setTab(_mqttConfigTab); _mqttServer.setTab(&_mqttConfigTab); _mqttServerCert.setTab(&_mqttConfigTab); - _mqttServerCertDelete.setTab(&_mqttConfigTab); + _mqttServerCertDelete.setTab(_mqttConfigTab); _mqttTopic.setTab(&_mqttConfigTab); _mqttUser.setTab(&_mqttConfigTab); _mqttTempO1.setTab(&_mqttConfigTab); @@ -560,35 +555,35 @@ void YaSolR::Website::initLayout() { _textConfig(_mqttTopic, KEY_MQTT_TOPIC); _textConfig(_mqttUser, KEY_MQTT_USERNAME); - _mqttServerCertDelete.attachCallback([this]() { + _mqttServerCertDelete.onPush([this]() { if (LittleFS.exists(YASOLR_MQTT_SERVER_CERT_FILE) && LittleFS.remove(YASOLR_MQTT_SERVER_CERT_FILE)) { logger.warn(TAG, "MQTT server certificate deleted successfully!"); initCards(); - dashboardTask.requestEarlyRun(); + dashboardUpdateTask.requestEarlyRun(); } }); // GPIO (configuration) - _pinDimmerO1.setTab(&_pinConfigTab); - _pinDimmerO2.setTab(&_pinConfigTab); - _pinDisplayClock.setTab(&_pinConfigTab); - _pinDisplayData.setTab(&_pinConfigTab); - _pinDS18O1.setTab(&_pinConfigTab); - _pinDS18O2.setTab(&_pinConfigTab); - _pinDS18Router.setTab(&_pinConfigTab); - _pinJsyRX.setTab(&_pinConfigTab); - _pinJsyTX.setTab(&_pinConfigTab); - _pinLEDGreen.setTab(&_pinConfigTab); - _pinLEDRed.setTab(&_pinConfigTab); - _pinLEDYellow.setTab(&_pinConfigTab); - _pinPZEMRX.setTab(&_pinConfigTab); - _pinPZEMTX.setTab(&_pinConfigTab); - _pinRelay1.setTab(&_pinConfigTab); - _pinRelay2.setTab(&_pinConfigTab); - _pinRelayO1.setTab(&_pinConfigTab); - _pinRelayO2.setTab(&_pinConfigTab); - _pinZCD.setTab(&_pinConfigTab); + _pinDimmerO1.setTab(_pinConfigTab); + _pinDimmerO2.setTab(_pinConfigTab); + _pinDisplayClock.setTab(_pinConfigTab); + _pinDisplayData.setTab(_pinConfigTab); + _pinDS18O1.setTab(_pinConfigTab); + _pinDS18O2.setTab(_pinConfigTab); + _pinDS18Router.setTab(_pinConfigTab); + _pinJsyRX.setTab(_pinConfigTab); + _pinJsyTX.setTab(_pinConfigTab); + _pinLEDGreen.setTab(_pinConfigTab); + _pinLEDRed.setTab(_pinConfigTab); + _pinLEDYellow.setTab(_pinConfigTab); + _pinPZEMRX.setTab(_pinConfigTab); + _pinPZEMTX.setTab(_pinConfigTab); + _pinRelay1.setTab(_pinConfigTab); + _pinRelay2.setTab(_pinConfigTab); + _pinRelayO1.setTab(_pinConfigTab); + _pinRelayO2.setTab(_pinConfigTab); + _pinZCD.setTab(_pinConfigTab); _pinConfig(_pinDimmerO1, KEY_PIN_OUTPUT1_DIMMER); _pinConfig(_pinDimmerO2, KEY_PIN_OUTPUT2_DIMMER); @@ -612,22 +607,22 @@ void YaSolR::Website::initLayout() { // Hardware - _display.setTab(&_hardwareEnableTab); - _jsy.setTab(&_hardwareEnableTab); - _led.setTab(&_hardwareEnableTab); - _mqtt.setTab(&_hardwareEnableTab); - _output1Dimmer.setTab(&_hardwareEnableTab); - _output1PZEM.setTab(&_hardwareEnableTab); - _output1Relay.setTab(&_hardwareEnableTab); - _output1DS18.setTab(&_hardwareEnableTab); - _output2Dimmer.setTab(&_hardwareEnableTab); - _output2PZEM.setTab(&_hardwareEnableTab); - _output2Relay.setTab(&_hardwareEnableTab); - _output2DS18.setTab(&_hardwareEnableTab); - _relay1.setTab(&_hardwareEnableTab); - _relay2.setTab(&_hardwareEnableTab); - _routerDS18.setTab(&_hardwareEnableTab); - _zcd.setTab(&_hardwareEnableTab); + _display.setTab(_hardwareEnableTab); + _jsy.setTab(_hardwareEnableTab); + _led.setTab(_hardwareEnableTab); + _mqtt.setTab(_hardwareEnableTab); + _output1Dimmer.setTab(_hardwareEnableTab); + _output1PZEM.setTab(_hardwareEnableTab); + _output1Relay.setTab(_hardwareEnableTab); + _output1DS18.setTab(_hardwareEnableTab); + _output2Dimmer.setTab(_hardwareEnableTab); + _output2PZEM.setTab(_hardwareEnableTab); + _output2Relay.setTab(_hardwareEnableTab); + _output2DS18.setTab(_hardwareEnableTab); + _relay1.setTab(_hardwareEnableTab); + _relay2.setTab(_hardwareEnableTab); + _routerDS18.setTab(_hardwareEnableTab); + _zcd.setTab(_hardwareEnableTab); _boolConfig(_display, KEY_ENABLE_DISPLAY); _boolConfig(_jsy, KEY_ENABLE_JSY); @@ -648,93 +643,172 @@ void YaSolR::Website::initLayout() { // Hardware (config) - _gridFreq.setTab(&_hardwareConfigTab); - _displayRotation.setTab(&_hardwareConfigTab); + _gridFreq.setTab(_hardwareConfigTab); + _displayRotation.setTab(_hardwareConfigTab); _displayType.setTab(&_hardwareConfigTab); - _displaySpeed.setTab(&_hardwareConfigTab); - _output1PZEMSync.setTab(&_hardwareConfigTab); - _output2PZEMSync.setTab(&_hardwareConfigTab); + _displaySpeed.setTab(_hardwareConfigTab); + _output1PZEMSync.setTab(_hardwareConfigTab); + _output2PZEMSync.setTab(_hardwareConfigTab); _output1RelayType.setTab(&_hardwareConfigTab); _output2RelayType.setTab(&_hardwareConfigTab); _relay1Type.setTab(&_hardwareConfigTab); _relay2Type.setTab(&_hardwareConfigTab); - _relay1Load.setTab(&_hardwareConfigTab); - _relay2Load.setTab(&_hardwareConfigTab); - _output1ResistanceInput.setTab(&_hardwareConfigTab); - _output2ResistanceInput.setTab(&_hardwareConfigTab); - _output1DimmerMapper.setTab(&_hardwareConfigTab); - _output2DimmerMapper.setTab(&_hardwareConfigTab); - _resistanceCalibration.setTab(&_hardwareConfigTab); - - _numConfig(_gridFreq, KEY_GRID_FREQUENCY); + _relay1Load.setTab(_hardwareConfigTab); + _relay2Load.setTab(_hardwareConfigTab); + _output1ResistanceInput.setTab(_hardwareConfigTab); + _output2ResistanceInput.setTab(_hardwareConfigTab); + _output1DimmerMapper.setTab(_hardwareConfigTab); + _output2DimmerMapper.setTab(_hardwareConfigTab); + _resistanceCalibration.setTab(_hardwareConfigTab); + + _gridFreq.onChange([](const char* value) { + if (strcmp(value, "50 Hz") == 0) + config.set(KEY_GRID_FREQUENCY, "50"); + else if (strcmp(value, "60 Hz") == 0) + config.set(KEY_GRID_FREQUENCY, "60"); + else + config.unset(KEY_GRID_FREQUENCY); + _gridFreq.setValue(config.get(KEY_GRID_FREQUENCY)); + dashboard.refresh(_gridFreq); + }); + _numConfig(_displayRotation, KEY_DISPLAY_ROTATION); _numConfig(_relay1Load, KEY_RELAY1_LOAD); _numConfig(_relay2Load, KEY_RELAY2_LOAD); _textConfig(_displayType, KEY_DISPLAY_TYPE); - _floatConfig(_output1ResistanceInput, KEY_OUTPUT1_RESISTANCE); - _floatConfig(_output2ResistanceInput, KEY_OUTPUT2_RESISTANCE); _textConfig(_output1RelayType, KEY_OUTPUT1_RELAY_TYPE); _textConfig(_output2RelayType, KEY_OUTPUT2_RELAY_TYPE); _textConfig(_relay1Type, KEY_RELAY1_TYPE); _textConfig(_relay2Type, KEY_RELAY2_TYPE); _sliderConfig(_displaySpeed, KEY_DISPLAY_SPEED); - _output1DimmerMapper.attachCallback([this](const char* value) { - const char* comma = strchr(value, ','); - if (comma != nullptr) { - config.set(KEY_OUTPUT1_DIMMER_MIN, std::string(value, comma - value)); - config.set(KEY_OUTPUT1_DIMMER_MAX, comma + 1); - } - _output1DimmerMapper.update(value); - dashboard.refreshCard(&_output1DimmerMapper); + _output1ResistanceInput.onChange([](const std::optional value) { + if (value.has_value()) + config.set(KEY_OUTPUT1_RESISTANCE, dash::to_string(value.value())); + else + config.unset(KEY_OUTPUT1_RESISTANCE); + _output1ResistanceInput.setValue(config.getFloat(KEY_OUTPUT1_RESISTANCE)); + dashboard.refresh(_output1ResistanceInput); }); - _output2DimmerMapper.attachCallback([this](const char* value) { - const char* comma = strchr(value, ','); - if (comma != nullptr) { - config.set(KEY_OUTPUT2_DIMMER_MIN, std::string(value, comma - value)); - config.set(KEY_OUTPUT2_DIMMER_MAX, comma + 1); - } - _output2DimmerMapper.update(value); - dashboard.refreshCard(&_output2DimmerMapper); + _output2ResistanceInput.onChange([](const std::optional value) { + if (value.has_value()) + config.set(KEY_OUTPUT2_RESISTANCE, dash::to_string(value.value())); + else + config.unset(KEY_OUTPUT2_RESISTANCE); + _output2ResistanceInput.setValue(config.getFloat(KEY_OUTPUT2_RESISTANCE)); + dashboard.refresh(_output2ResistanceInput); + }); + + _output1DimmerMapper.onChange([](const dash::Range& range) { + config.set(KEY_OUTPUT1_DIMMER_MIN, std::to_string(range.low())); + config.set(KEY_OUTPUT1_DIMMER_MAX, std::to_string(range.high())); + _output1DimmerMapper.setValue({static_cast(config.getInt(KEY_OUTPUT1_DIMMER_MIN)), + static_cast(config.getInt(KEY_OUTPUT1_DIMMER_MAX))}); + dashboard.refresh(_output1DimmerMapper); + }); + + _output2DimmerMapper.onChange([](const dash::Range& range) { + config.set(KEY_OUTPUT2_DIMMER_MIN, std::to_string(range.low())); + config.set(KEY_OUTPUT2_DIMMER_MAX, std::to_string(range.high())); + _output2DimmerMapper.setValue({static_cast(config.getInt(KEY_OUTPUT2_DIMMER_MIN)), + static_cast(config.getInt(KEY_OUTPUT2_DIMMER_MAX))}); + dashboard.refresh(_output2DimmerMapper); }); // PID - _pidView.setTab(&_pidTab); - _pidPMode.setTab(&_pidTab); - _pidDMode.setTab(&_pidTab); - _pidICMode.setTab(&_pidTab); - _pidSetpoint.setTab(&_pidTab); - _pidKp.setTab(&_pidTab); - _pidKi.setTab(&_pidTab); - _pidKd.setTab(&_pidTab); - _pidOutMin.setTab(&_pidTab); - _pidOutMax.setTab(&_pidTab); - - _pidInputHistory.setTab(&_pidTab); - _pidOutputHistory.setTab(&_pidTab); - _pidErrorHistory.setTab(&_pidTab); - _pidSumHistory.setTab(&_pidTab); - _pidPTermHistory.setTab(&_pidTab); - _pidITermHistory.setTab(&_pidTab); - _pidDTermHistory.setTab(&_pidTab); - _pidReset.setTab(&_pidTab); - - _pidReset.attachCallback([this]() { + _pidView.setTab(_pidTab); + _pidPMode.setTab(_pidTab); + _pidDMode.setTab(_pidTab); + _pidICMode.setTab(_pidTab); + _pidSetpoint.setTab(_pidTab); + _pidKp.setTab(_pidTab); + _pidKi.setTab(_pidTab); + _pidKd.setTab(_pidTab); + _pidOutMin.setTab(_pidTab); + _pidOutMax.setTab(_pidTab); + + _pidInputHistory.setTab(_pidTab); + _pidOutputHistory.setTab(_pidTab); + _pidErrorHistory.setTab(_pidTab); + _pidSumHistory.setTab(_pidTab); + _pidPTermHistory.setTab(_pidTab); + _pidITermHistory.setTab(_pidTab); + _pidDTermHistory.setTab(_pidTab); + _pidReset.setTab(_pidTab); + + _pidReset.onPush([this]() { resetPID(); updatePID(); }); + _pidPMode.onChange([](const char* value) { + if (strcmp(value, YASOLR_PID_P_MODE_1) == 0) + config.set(KEY_PID_P_MODE, "1"); + else if (strcmp(value, YASOLR_PID_P_MODE_2) == 0) + config.set(KEY_PID_P_MODE, "2"); + else if (strcmp(value, YASOLR_PID_P_MODE_3) == 0) + config.set(KEY_PID_P_MODE, "3"); + else + config.unset(KEY_PID_P_MODE); + _pidPMode.setValue(config.get(KEY_PID_P_MODE)); + dashboard.refresh(_pidPMode); + }); + + _pidDMode.onChange([](const char* value) { + if (strcmp(value, YASOLR_PID_D_MODE_1) == 0) + config.set(KEY_PID_D_MODE, "1"); + else if (strcmp(value, YASOLR_PID_D_MODE_2) == 0) + config.set(KEY_PID_D_MODE, "2"); + else + config.unset(KEY_PID_D_MODE); + _pidDMode.setValue(config.get(KEY_PID_D_MODE)); + dashboard.refresh(_pidDMode); + }); + + _pidICMode.onChange([](const char* value) { + if (strcmp(value, YASOLR_PID_IC_MODE_0) == 0) + config.set(KEY_PID_IC_MODE, "0"); + else if (strcmp(value, YASOLR_PID_IC_MODE_1) == 0) + config.set(KEY_PID_IC_MODE, "1"); + else if (strcmp(value, YASOLR_PID_IC_MODE_2) == 0) + config.set(KEY_PID_IC_MODE, "2"); + else + config.unset(KEY_PID_IC_MODE); + _pidICMode.setValue(config.get(KEY_PID_IC_MODE)); + dashboard.refresh(_pidICMode); + }); + _boolConfig(_pidView, KEY_ENABLE_PID_VIEW); - _numConfig(_pidPMode, KEY_PID_P_MODE); - _numConfig(_pidDMode, KEY_PID_D_MODE); - _numConfig(_pidICMode, KEY_PID_IC_MODE); _numConfig(_pidSetpoint, KEY_PID_SETPOINT); - _floatConfig(_pidKp, KEY_PID_KP); - _floatConfig(_pidKi, KEY_PID_KI); - _floatConfig(_pidKd, KEY_PID_KD); _numConfig(_pidOutMin, KEY_PID_OUT_MIN); _numConfig(_pidOutMax, KEY_PID_OUT_MAX); + + _pidKp.onChange([](const std::optional value) { + if (value.has_value()) + config.set(KEY_PID_KP, dash::to_string(value.value())); + else + config.unset(KEY_PID_KP); + _pidKp.setValue(config.getFloat(KEY_PID_KP)); + dashboard.refresh(_pidKp); + }); + _pidKi.onChange([](const std::optional value) { + if (value.has_value()) + config.set(KEY_PID_KI, dash::to_string(value.value())); + else + config.unset(KEY_PID_KI); + _pidKi.setValue(config.getFloat(KEY_PID_KI)); + dashboard.refresh(_pidKi); + }); + _pidKd.onChange([](const std::optional value) { + if (value.has_value()) + config.set(KEY_PID_KD, dash::to_string(value.value())); + else + config.unset(KEY_PID_KD); + _pidKd.setValue(config.getFloat(KEY_PID_KD)); + dashboard.refresh(_pidKd); + }); + #endif } @@ -743,28 +817,34 @@ void YaSolR::Website::initCards() { // Statistics - _appManufacturer.set(Mycila::AppInfo.manufacturer); - _appModel.set(Mycila::AppInfo.model); - _appName.set(Mycila::AppInfo.name); - _appVersion.set(Mycila::AppInfo.version); - _deviceBootCount.set(std::to_string(Mycila::System::getBootCount())); - _deviceBootReason.set(Mycila::System::getLastRebootReason()); - _deviceCores.set(std::to_string(ESP.getChipCores())); - _deviceModel.set(ESP.getChipModel()); - _deviceRev.set(std::to_string(ESP.getChipRevision())); - _deviceID.set(Mycila::AppInfo.id); - _firmwareBuildHash.set(Mycila::AppInfo.buildHash); - _firmwareBuildTimestamp.set(Mycila::AppInfo.buildDate); - _firmwareFilename.set(Mycila::AppInfo.firmware); - _networkAPMAC.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::AP)); - _networkEthMAC.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::ETH).empty() ? std::string("N/A") : espConnect.getMACAddress(Mycila::ESPConnect::Mode::ETH)); - _networkHostname.set(Mycila::AppInfo.defaultHostname); - _networkWiFiMAC.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::STA)); + Mycila::ESPConnect::Mode mode = espConnect.getMode(); + _appManufacturer.setValue(Mycila::AppInfo.manufacturer.c_str()); + _appModel.setValue(Mycila::AppInfo.model.c_str()); + _appName.setValue(Mycila::AppInfo.name.c_str()); + _appVersion.setValue(Mycila::AppInfo.version.c_str()); + _deviceBootCount.setValue(Mycila::System::getBootCount()); + _deviceBootReason.setValue(Mycila::System::getLastRebootReason()); + _deviceCores.setValue(ESP.getChipCores()); + _deviceID.setValue(Mycila::AppInfo.id.c_str()); + _deviceModel.setValue(ESP.getChipModel()); + _deviceRev.setValue(ESP.getChipRevision()); + _firmwareBuildHash.setValue(Mycila::AppInfo.buildHash.c_str()); + _firmwareBuildTimestamp.setValue(Mycila::AppInfo.buildDate.c_str()); + _firmwareFilename.setValue(Mycila::AppInfo.firmware.c_str()); + _networkAPIP.setValue(espConnect.getIPAddress(Mycila::ESPConnect::Mode::AP).toString().c_str()); + _networkAPMAC.setValue(espConnect.getMACAddress(Mycila::ESPConnect::Mode::AP)); + _networkEthIP.setValue(espConnect.getIPAddress(Mycila::ESPConnect::Mode::ETH).toString().c_str()); + _networkEthMAC.setValue(espConnect.getMACAddress(Mycila::ESPConnect::Mode::ETH).empty() ? std::string("N/A") : espConnect.getMACAddress(Mycila::ESPConnect::Mode::ETH)); + _networkHostname.setValue(Mycila::AppInfo.defaultHostname.c_str()); + _networkInterface.setValue(mode == Mycila::ESPConnect::Mode::AP ? "AP" : (mode == Mycila::ESPConnect::Mode::STA ? "WiFi" : (mode == Mycila::ESPConnect::Mode::ETH ? "Ethernet" : ""))); + _networkWiFiIP.setValue(espConnect.getIPAddress(Mycila::ESPConnect::Mode::STA).toString().c_str()); + _networkWiFiMAC.setValue(espConnect.getMACAddress(Mycila::ESPConnect::Mode::STA)); + _networkWiFiSSID.setValue(espConnect.getWiFiSSID()); #ifdef APP_MODEL_PRO const bool jsyEnabled = config.getBool(KEY_ENABLE_JSY); - // output 1 (control) + // output 1 const bool dimmer1Enabled = config.getBool(KEY_ENABLE_OUTPUT1_DIMMER); const bool output1RelayEnabled = config.getBool(KEY_ENABLE_OUTPUT1_RELAY); @@ -773,16 +853,17 @@ void YaSolR::Website::initCards() { const bool autoBypass1Activated = config.getBool(KEY_ENABLE_OUTPUT1_AUTO_BYPASS); const bool output1TempEnabled = config.getBool(KEY_ENABLE_OUTPUT1_DS18) || config.isEmpty(KEY_OUTPUT1_TEMPERATURE_MQTT_TOPIC); const bool pzem1Enabled = config.getBool(KEY_ENABLE_OUTPUT1_PZEM); - - _output1DimmerAuto.update(autoDimmer1Activated); - _output1DimmerReservedExcess.update(config.getInt(KEY_OUTPUT1_RESERVED_EXCESS)); - _output1DimmerDutyLimiter.update(config.getInt(KEY_OUTPUT1_DIMMER_LIMIT)); - _output1DimmerTempLimiter.update(config.get(KEY_OUTPUT1_DIMMER_STOP_TEMP)); - _output1BypassAuto.update(autoBypass1Activated); - _output1AutoStartWDays.update(config.get(KEY_OUTPUT1_DAYS)); - _output1AutoStartTemp.update(config.get(KEY_OUTPUT1_TEMPERATURE_START)); + const char* output1Days = config.get(KEY_OUTPUT1_DAYS); + + _output1DimmerAuto.setValue(autoDimmer1Activated); + _output1DimmerReservedExcess.setValue(config.getInt(KEY_OUTPUT1_RESERVED_EXCESS)); + _output1DimmerDutyLimiter.setValue(config.getInt(KEY_OUTPUT1_DIMMER_LIMIT)); + _output1DimmerTempLimiter.setValue(config.getInt(KEY_OUTPUT1_DIMMER_STOP_TEMP)); + _output1BypassAuto.setValue(autoBypass1Activated); + _output1AutoStartWDays.setValue(strcmp(output1Days, YASOLR_WEEK_DAYS_EMPTY) == 0 ? "" : output1Days); + _output1AutoStartTemp.setValue(config.getInt(KEY_OUTPUT1_TEMPERATURE_START)); _output1AutoStartTime.update(config.get(KEY_OUTPUT1_TIME_START)); - _output1AutoStoptTemp.update(config.get(KEY_OUTPUT1_TEMPERATURE_STOP)); + _output1AutoStoptTemp.setValue(config.getInt(KEY_OUTPUT1_TEMPERATURE_STOP)); _output1AutoStoptTime.update(config.get(KEY_OUTPUT1_TIME_STOP)); _output1Tab.setDisplay(dimmer1Enabled || output1TempEnabled || output1RelayEnabled); @@ -809,7 +890,7 @@ void YaSolR::Website::initCards() { _output1AutoStartTemp.setDisplay(bypass1Possible && autoBypass1Activated && output1TempEnabled); _output1AutoStoptTemp.setDisplay(bypass1Possible && autoBypass1Activated && output1TempEnabled); - // output 2 (control) + // output 2 const bool dimmer2Enabled = config.getBool(KEY_ENABLE_OUTPUT2_DIMMER); const bool output2RelayEnabled = config.getBool(KEY_ENABLE_OUTPUT2_RELAY); @@ -818,16 +899,17 @@ void YaSolR::Website::initCards() { const bool autoBypass2Activated = config.getBool(KEY_ENABLE_OUTPUT2_AUTO_BYPASS); const bool output2TempEnabled = config.getBool(KEY_ENABLE_OUTPUT2_DS18) || !config.isEmpty(KEY_OUTPUT2_TEMPERATURE_MQTT_TOPIC); const bool pzem2Enabled = config.getBool(KEY_ENABLE_OUTPUT2_PZEM); - - _output2DimmerAuto.update(autoDimmer2Activated); - _output2DimmerReservedExcess.update(config.getInt(KEY_OUTPUT2_RESERVED_EXCESS)); - _output2DimmerDutyLimiter.update(config.getInt(KEY_OUTPUT2_DIMMER_LIMIT)); - _output2DimmerTempLimiter.update(config.get(KEY_OUTPUT2_DIMMER_STOP_TEMP)); - _output2BypassAuto.update(autoBypass2Activated); - _output2AutoStartWDays.update(config.get(KEY_OUTPUT2_DAYS)); - _output2AutoStartTemp.update(config.get(KEY_OUTPUT2_TEMPERATURE_START)); + const char* output2Days = config.get(KEY_OUTPUT2_DAYS); + + _output2DimmerAuto.setValue(autoDimmer2Activated); + _output2DimmerReservedExcess.setValue(config.getInt(KEY_OUTPUT2_RESERVED_EXCESS)); + _output2DimmerDutyLimiter.setValue(config.getInt(KEY_OUTPUT2_DIMMER_LIMIT)); + _output2DimmerTempLimiter.setValue(config.getInt(KEY_OUTPUT2_DIMMER_STOP_TEMP)); + _output2BypassAuto.setValue(autoBypass2Activated); + _output2AutoStartWDays.setValue(strcmp(output2Days, YASOLR_WEEK_DAYS_EMPTY) == 0 ? "" : output2Days); + _output2AutoStartTemp.setValue(config.getInt(KEY_OUTPUT2_TEMPERATURE_START)); _output2AutoStartTime.update(config.get(KEY_OUTPUT2_TIME_START)); - _output2AutoStoptTemp.update(config.get(KEY_OUTPUT2_TEMPERATURE_STOP)); + _output2AutoStoptTemp.setValue(config.getInt(KEY_OUTPUT2_TEMPERATURE_STOP)); _output2AutoStoptTime.update(config.get(KEY_OUTPUT2_TIME_STOP)); _output2Tab.setDisplay(dimmer2Enabled || output2TempEnabled || output2RelayEnabled); @@ -854,10 +936,10 @@ void YaSolR::Website::initCards() { _output2AutoStartTemp.setDisplay(bypass2Possible && autoBypass2Activated && output2TempEnabled); _output2AutoStoptTemp.setDisplay(bypass2Possible && autoBypass2Activated && output2TempEnabled); - // relays (control) + // relays - const int load1 = config.getInt(KEY_RELAY1_LOAD); - const int load2 = config.getInt(KEY_RELAY2_LOAD); + const uint16_t load1 = config.getInt(KEY_RELAY1_LOAD); + const uint16_t load2 = config.getInt(KEY_RELAY2_LOAD); const bool relay1Enabled = config.getBool(KEY_ENABLE_RELAY1); const bool relay2Enabled = config.getBool(KEY_ENABLE_RELAY2); _relaysTab.setDisplay(relay1Enabled || relay2Enabled); @@ -868,39 +950,39 @@ void YaSolR::Website::initCards() { // management - _configBackup.update("/api/config/backup"); - _configRestore.update("/api/config/restore"); - _consoleLink.update("/console"); - _debugInfo.update("/api/debug"); - _debugMode.update(config.getBool(KEY_ENABLE_DEBUG)); + _configBackup.setValue("/api/config/backup"); + _configRestore.setValue("/api/config/restore"); + _consoleLink.setValue("/console"); + _debugInfo.setValue("/api/debug"); + _debugMode.setValue(config.getBool(KEY_ENABLE_DEBUG)); _energyReset.setDisplay(jsyEnabled || pzem1Enabled || pzem2Enabled); _debugInfo.setDisplay(config.getBool(KEY_ENABLE_DEBUG)); - // network (config) + // network - _adminPwd.update(config.isEmpty(KEY_ADMIN_PASSWORD) ? "" : HIDDEN_PWD); - _apMode.update(config.getBool(KEY_ENABLE_AP_MODE)); + _adminPwd.update(config.isEmpty(KEY_ADMIN_PASSWORD) ? "" : YASOLR_HIDDEN_PWD); + _apMode.setValue(config.getBool(KEY_ENABLE_AP_MODE)); _ntpServer.update(config.get(KEY_NTP_SERVER)); _ntpTimezone.update(config.get(KEY_NTP_TIMEZONE), "/timezones"); - _wifiPwd.update(config.isEmpty(KEY_WIFI_PASSWORD) ? "" : HIDDEN_PWD); + _wifiPwd.update(config.isEmpty(KEY_WIFI_PASSWORD) ? "" : YASOLR_HIDDEN_PWD); _wifiSSID.update(config.get(KEY_WIFI_SSID)); _staticIP.update(config.get(KEY_NET_IP)); _subnetMask.update(config.get(KEY_NET_SUBNET)); _gateway.update(config.get(KEY_NET_GATEWAY)); _dnsServer.update(config.get(KEY_NET_DNS)); - // mqtt (config) + // mqtt - _haDiscovery.update(config.getBool(KEY_ENABLE_HA_DISCOVERY)); + _haDiscovery.setValue(config.getBool(KEY_ENABLE_HA_DISCOVERY)); _haDiscoveryTopic.update(config.get(KEY_HA_DISCOVERY_TOPIC)); _mqttGridPower.update(config.get(KEY_GRID_POWER_MQTT_TOPIC)); _mqttGridVoltage.update(config.get(KEY_GRID_VOLTAGE_MQTT_TOPIC)); _mqttTempO1.update(config.get(KEY_OUTPUT1_TEMPERATURE_MQTT_TOPIC)); _mqttTempO2.update(config.get(KEY_OUTPUT2_TEMPERATURE_MQTT_TOPIC)); - _mqttPort.update(config.get(KEY_MQTT_PORT)); - _mqttPublishInterval.update(config.get(KEY_MQTT_PUBLISH_INTERVAL)); - _mqttPwd.update(config.isEmpty(KEY_MQTT_PASSWORD) ? "" : HIDDEN_PWD); - _mqttSecured.update(config.getBool(KEY_MQTT_SECURED)); + _mqttPort.setValue(config.getInt(KEY_MQTT_PORT)); + _mqttPublishInterval.setValue(config.getInt(KEY_MQTT_PUBLISH_INTERVAL)); + _mqttPwd.update(config.isEmpty(KEY_MQTT_PASSWORD) ? "" : YASOLR_HIDDEN_PWD); + _mqttSecured.setValue(config.getBool(KEY_MQTT_SECURED)); _mqttServer.update(config.get(KEY_MQTT_SERVER)); _mqttServerCert.update("/api/config/mqttServerCertificate"); _mqttTopic.update(config.get(KEY_MQTT_TOPIC)); @@ -913,26 +995,26 @@ void YaSolR::Website::initCards() { // GPIO - std::unordered_map pinout = {}; - _pinout(_pinDimmerO1, config.getLong(KEY_PIN_OUTPUT1_DIMMER), pinout); - _pinout(_pinDimmerO2, config.getLong(KEY_PIN_OUTPUT2_DIMMER), pinout); - _pinout(_pinDisplayClock, config.getLong(KEY_PIN_DISPLAY_SCL), pinout); - _pinout(_pinDisplayData, config.getLong(KEY_PIN_DISPLAY_SDA), pinout); - _pinout(_pinDS18O1, config.getLong(KEY_PIN_OUTPUT1_DS18), pinout); - _pinout(_pinDS18O2, config.getLong(KEY_PIN_OUTPUT2_DS18), pinout); - _pinout(_pinDS18Router, config.getLong(KEY_PIN_ROUTER_DS18), pinout); - _pinout(_pinJsyRX, config.getLong(KEY_PIN_JSY_RX), pinout); - _pinout(_pinJsyTX, config.getLong(KEY_PIN_JSY_TX), pinout); - _pinout(_pinLEDGreen, config.getLong(KEY_PIN_LIGHTS_GREEN), pinout); - _pinout(_pinLEDRed, config.getLong(KEY_PIN_LIGHTS_RED), pinout); - _pinout(_pinLEDYellow, config.getLong(KEY_PIN_LIGHTS_YELLOW), pinout); - _pinout(_pinPZEMRX, config.getLong(KEY_PIN_PZEM_RX), pinout); - _pinout(_pinPZEMTX, config.getLong(KEY_PIN_PZEM_TX), pinout); - _pinout(_pinRelay1, config.getLong(KEY_PIN_RELAY1), pinout); - _pinout(_pinRelay2, config.getLong(KEY_PIN_RELAY2), pinout); - _pinout(_pinRelayO1, config.getLong(KEY_PIN_OUTPUT1_RELAY), pinout); - _pinout(_pinRelayO2, config.getLong(KEY_PIN_OUTPUT2_RELAY), pinout); - _pinout(_pinZCD, config.getLong(KEY_PIN_ZCD), pinout); + std::unordered_map*> pinout = {}; + _pinout(_pinDimmerO1, KEY_PIN_OUTPUT1_DIMMER, pinout); + _pinout(_pinDimmerO2, KEY_PIN_OUTPUT2_DIMMER, pinout); + _pinout(_pinDisplayClock, KEY_PIN_DISPLAY_SCL, pinout); + _pinout(_pinDisplayData, KEY_PIN_DISPLAY_SDA, pinout); + _pinout(_pinDS18O1, KEY_PIN_OUTPUT1_DS18, pinout); + _pinout(_pinDS18O2, KEY_PIN_OUTPUT2_DS18, pinout); + _pinout(_pinDS18Router, KEY_PIN_ROUTER_DS18, pinout); + _pinout(_pinJsyRX, KEY_PIN_JSY_RX, pinout); + _pinout(_pinJsyTX, KEY_PIN_JSY_TX, pinout); + _pinout(_pinLEDGreen, KEY_PIN_LIGHTS_GREEN, pinout); + _pinout(_pinLEDRed, KEY_PIN_LIGHTS_RED, pinout); + _pinout(_pinLEDYellow, KEY_PIN_LIGHTS_YELLOW, pinout); + _pinout(_pinPZEMRX, KEY_PIN_PZEM_RX, pinout); + _pinout(_pinPZEMTX, KEY_PIN_PZEM_TX, pinout); + _pinout(_pinRelay1, KEY_PIN_RELAY1, pinout); + _pinout(_pinRelay2, KEY_PIN_RELAY2, pinout); + _pinout(_pinRelayO1, KEY_PIN_OUTPUT1_RELAY, pinout); + _pinout(_pinRelayO2, KEY_PIN_OUTPUT2_RELAY, pinout); + _pinout(_pinZCD, KEY_PIN_ZCD, pinout); pinout.clear(); // Hardware @@ -944,34 +1026,37 @@ void YaSolR::Website::initCards() { _status(_relay1, KEY_ENABLE_RELAY1, relay1.isEnabled()); _status(_relay2, KEY_ENABLE_RELAY2, relay2.isEnabled()); - // Hardware (config) + // Hardware Config - switch (config.getLong(KEY_GRID_FREQUENCY)) { + switch (config.getInt(KEY_GRID_FREQUENCY)) { case 50: - _gridFreq.update("50 Hz", "Auto-detect,50 Hz,60 Hz"); + _gridFreq.setValue("50 Hz"); break; case 60: - _gridFreq.update("60 Hz", "Auto-detect,50 Hz,60 Hz"); + _gridFreq.setValue("60 Hz"); break; default: - _gridFreq.update("Auto-detect", "Auto-detect,50 Hz,60 Hz"); + _gridFreq.setValue("Auto-detect"); break; } _displayType.update(config.get(KEY_DISPLAY_TYPE), "SH1106,SH1107,SSD1306"); - _displaySpeed.update(config.getInt(KEY_DISPLAY_SPEED)); - _displayRotation.update(config.getString(KEY_DISPLAY_ROTATION) + "°", "0°,90°,180°,270°"); + _displaySpeed.setValue(config.getInt(KEY_DISPLAY_SPEED)); + _displayRotation.setValue(config.getInt(KEY_DISPLAY_ROTATION)); _output1RelayType.update(config.get(KEY_OUTPUT1_RELAY_TYPE), "NO,NC"); _output2RelayType.update(config.get(KEY_OUTPUT2_RELAY_TYPE), "NO,NC"); _relay1Type.update(config.get(KEY_RELAY1_TYPE), "NO,NC"); _relay2Type.update(config.get(KEY_RELAY2_TYPE), "NO,NC"); - _relay1Load.update(load1); - _relay2Load.update(load2); - _output1ResistanceInput.update(config.get(KEY_OUTPUT1_RESISTANCE), config.getFloat(KEY_OUTPUT1_RESISTANCE) == 0 ? DASH_STATUS_DANGER : DASH_STATUS_SUCCESS); - _output2ResistanceInput.update(config.get(KEY_OUTPUT2_RESISTANCE), config.getFloat(KEY_OUTPUT2_RESISTANCE) == 0 ? DASH_STATUS_DANGER : DASH_STATUS_SUCCESS); - _output1DimmerMapper.update(config.getString(KEY_OUTPUT1_DIMMER_MIN) + "," + config.get(KEY_OUTPUT1_DIMMER_MAX)); - _output2DimmerMapper.update(config.getString(KEY_OUTPUT2_DIMMER_MIN) + "," + config.get(KEY_OUTPUT2_DIMMER_MAX)); - + _relay1Load.setValue(load1); + _relay2Load.setValue(load2); + _output1ResistanceInput.setValue(config.getFloat(KEY_OUTPUT1_RESISTANCE)); + _output1ResistanceInput.setStatus(_output1ResistanceInput.value() == 0 ? dash::Status::DANGER : dash::Status::SUCCESS); + _output2ResistanceInput.setValue(config.getFloat(KEY_OUTPUT2_RESISTANCE)); + _output2ResistanceInput.setStatus(_output1ResistanceInput.value() ? dash::Status::DANGER : dash::Status::SUCCESS); + _output1DimmerMapper.setValue({static_cast(config.getInt(KEY_OUTPUT1_DIMMER_MIN)), + static_cast(config.getInt(KEY_OUTPUT1_DIMMER_MAX))}); + _output2DimmerMapper.setValue({static_cast(config.getInt(KEY_OUTPUT2_DIMMER_MIN)), + static_cast(config.getInt(KEY_OUTPUT2_DIMMER_MAX))}); _displayType.setDisplay(config.getBool(KEY_ENABLE_DISPLAY)); _displaySpeed.setDisplay(config.getBool(KEY_ENABLE_DISPLAY)); _displayRotation.setDisplay(config.getBool(KEY_ENABLE_DISPLAY)); @@ -995,52 +1080,52 @@ void YaSolR::Website::initCards() { // PID const bool pidViewEnabled = config.getBool(KEY_ENABLE_PID_VIEW); - _pidView.update(pidViewEnabled); - switch (config.getLong(KEY_PID_P_MODE)) { + _pidView.setValue(pidViewEnabled); + switch (config.getInt(KEY_PID_P_MODE)) { case 1: - _pidPMode.update(YASOLR_PID_P_MODE_1, YASOLR_PID_P_MODE_1 "," YASOLR_PID_P_MODE_2 "," YASOLR_PID_P_MODE_3); + _pidPMode.setValue(YASOLR_PID_P_MODE_1); break; case 2: - _pidPMode.update(YASOLR_PID_P_MODE_2, YASOLR_PID_P_MODE_1 "," YASOLR_PID_P_MODE_2 "," YASOLR_PID_P_MODE_3); + _pidPMode.setValue(YASOLR_PID_P_MODE_2); break; case 3: - _pidPMode.update(YASOLR_PID_P_MODE_3, YASOLR_PID_P_MODE_1 "," YASOLR_PID_P_MODE_2 "," YASOLR_PID_P_MODE_3); + _pidPMode.setValue(YASOLR_PID_P_MODE_3); break; default: - _pidPMode.update("", YASOLR_PID_P_MODE_1 "," YASOLR_PID_P_MODE_2 "," YASOLR_PID_P_MODE_3); + _pidPMode.setValue(""); break; } - switch (config.getLong(KEY_PID_D_MODE)) { + switch (config.getInt(KEY_PID_D_MODE)) { case 1: - _pidDMode.update(YASOLR_PID_D_MODE_1, YASOLR_PID_D_MODE_1 "," YASOLR_PID_D_MODE_2); + _pidDMode.setValue(YASOLR_PID_D_MODE_1); break; case 2: - _pidDMode.update(YASOLR_PID_D_MODE_2, YASOLR_PID_D_MODE_1 "," YASOLR_PID_D_MODE_2); + _pidDMode.setValue(YASOLR_PID_D_MODE_2); break; default: - _pidDMode.update("", YASOLR_PID_D_MODE_1 "," YASOLR_PID_D_MODE_2); + _pidDMode.setValue(""); break; } - switch (config.getLong(KEY_PID_IC_MODE)) { + switch (config.getInt(KEY_PID_IC_MODE)) { case 0: - _pidICMode.update(YASOLR_PID_IC_MODE_0, YASOLR_PID_IC_MODE_0 "," YASOLR_PID_IC_MODE_1 "," YASOLR_PID_IC_MODE_2); + _pidICMode.setValue(YASOLR_PID_IC_MODE_0); break; case 1: - _pidICMode.update(YASOLR_PID_IC_MODE_1, YASOLR_PID_IC_MODE_0 "," YASOLR_PID_IC_MODE_1 "," YASOLR_PID_IC_MODE_2); + _pidICMode.setValue(YASOLR_PID_IC_MODE_1); break; case 2: - _pidICMode.update(YASOLR_PID_IC_MODE_2, YASOLR_PID_IC_MODE_0 "," YASOLR_PID_IC_MODE_1 "," YASOLR_PID_IC_MODE_2); + _pidICMode.setValue(YASOLR_PID_IC_MODE_2); break; default: - _pidICMode.update("", YASOLR_PID_IC_MODE_0 "," YASOLR_PID_IC_MODE_1 "," YASOLR_PID_IC_MODE_2); + _pidICMode.setValue(""); break; } - _pidSetpoint.update(config.get(KEY_PID_SETPOINT)); - _pidKp.update(config.get(KEY_PID_KP)); - _pidKi.update(config.get(KEY_PID_KI)); - _pidKd.update(config.get(KEY_PID_KD)); - _pidOutMin.update(config.get(KEY_PID_OUT_MIN)); - _pidOutMax.update(config.get(KEY_PID_OUT_MAX)); + _pidSetpoint.setValue(config.getInt(KEY_PID_SETPOINT)); + _pidKp.setValue(config.getFloat(KEY_PID_KP)); + _pidKi.setValue(config.getFloat(KEY_PID_KI)); + _pidKd.setValue(config.getFloat(KEY_PID_KD)); + _pidOutMin.setValue(config.getInt(KEY_PID_OUT_MIN)); + _pidOutMax.setValue(config.getInt(KEY_PID_OUT_MAX)); _pidInputHistory.setDisplay(pidViewEnabled); _pidOutputHistory.setDisplay(pidViewEnabled); @@ -1068,133 +1153,125 @@ void YaSolR::Website::updateCards() { // stats Mycila::System::Memory memory; Mycila::System::getMemory(memory); - Mycila::ESPConnect::Mode mode = espConnect.getMode(); - _output1RelaySwitchCount.set(std::to_string(bypassRelayO1.getSwitchCount())); - _output2RelaySwitchCount.set(std::to_string(bypassRelayO2.getSwitchCount())); - _deviceHeapTotal.set(std::to_string(memory.total) + " bytes"); - _deviceHeapUsed.set(std::to_string(memory.used) + " bytes"); - _deviceHeapUsage.set(Mycila::string::to_string(memory.usage, 2) + " %"); - _gridEnergy.set(Mycila::string::to_string(gridMetrics.energy, 3) + " kWh"); - _gridEnergyReturned.set(Mycila::string::to_string(gridMetrics.energyReturned, 3) + " kWh"); - _gridFrequency.set(Mycila::string::to_string(detectGridFrequency(), 0) + " Hz"); - _networkAPIP.set(espConnect.getIPAddress(Mycila::ESPConnect::Mode::AP).toString().c_str()); - _networkEthIP.set(espConnect.getIPAddress(Mycila::ESPConnect::Mode::ETH).toString().c_str()); - _networkInterface.set(mode == Mycila::ESPConnect::Mode::AP ? "AP" : (mode == Mycila::ESPConnect::Mode::STA ? "WiFi" : (mode == Mycila::ESPConnect::Mode::ETH ? "Ethernet" : ""))); - _networkWiFiIP.set(espConnect.getIPAddress(Mycila::ESPConnect::Mode::STA).toString().c_str()); - _networkWiFiRSSI.set(std::to_string(espConnect.getWiFiRSSI()) + " dBm"); - _networkWiFiSignal.set(std::to_string(espConnect.getWiFiSignalQuality()) + " %"); - _networkWiFiSSID.set(espConnect.getWiFiSSID()); - _relay1SwitchCount.set(std::to_string(relay1.getSwitchCount())); - _relay2SwitchCount.set(std::to_string(relay2.getSwitchCount())); - _udpMessageRateBuffer.set(Mycila::string::to_string(udpMessageRateBuffer.rate(), 2) + " msg/s"); - _time.set(Mycila::Time::getLocalStr()); - _uptime.set(Mycila::Time::toDHHMMSS(Mycila::System::getUptime())); + _output1RelaySwitchCount.setValue(bypassRelayO1.getSwitchCount()); + _output2RelaySwitchCount.setValue(bypassRelayO2.getSwitchCount()); + _deviceHeapTotal.setValue(memory.total); + _deviceHeapUsed.setValue(memory.used); + _deviceHeapUsage.setValue(memory.usage); + _gridEnergy.setValue(gridMetrics.energy); + _gridEnergyReturned.setValue(gridMetrics.energyReturned); + _gridFrequency.setValue(detectGridFrequency()); + _networkWiFiRSSI.setValue(espConnect.getWiFiRSSI()); + _networkWiFiSignal.setValue(espConnect.getWiFiSignalQuality()); + _relay1SwitchCount.setValue(relay1.getSwitchCount()); + _relay2SwitchCount.setValue(relay2.getSwitchCount()); + _udpMessageRateBuffer.setValue(udpMessageRateBuffer.rate()); + _time.setValue(Mycila::Time::getLocalStr()); + _uptime.setValue(Mycila::Time::toDHHMMSS(Mycila::System::getUptime())); #ifdef APP_MODEL_TRIAL - _trialRemainingTime.set(Mycila::Time::toDHHMMSS(Mycila::Trial.getRemaining())); + _trialRemainingTime.setValue(Mycila::Time::toDHHMMSS(Mycila::Trial.getRemaining())); #endif // home - _routerPower.update(routerMetrics.power); - _routerApparentPower.update(routerMetrics.apparentPower); - _routerPowerFactor.update(routerMetrics.powerFactor); - _routerTHDi.update(routerMetrics.thdi * 100); - _routerVoltage.update(gridMetrics.voltage); - _routerCurrent.update(routerMetrics.current); - _routerResistance.update(routerMetrics.resistance); - _routerEnergy.update(routerMetrics.energy); - - _gridPower.update(gridMetrics.power); - _temperature(_routerDS18State, ds18Sys); + _routerPower.setValue(routerMetrics.power); + _routerApparentPower.setValue(routerMetrics.apparentPower); + _routerPowerFactor.setValue(routerMetrics.powerFactor); + _routerTHDi.setValue(routerMetrics.thdi * 100); + _routerVoltage.setValue(gridMetrics.voltage); + _routerCurrent.setValue(routerMetrics.current); + _routerResistance.setValue(routerMetrics.resistance); + _routerEnergy.setValue(routerMetrics.energy); + _gridPower.setValue(gridMetrics.power); + _routerDS18State.setValue(ds18Sys.getTemperature().value_or(0.0f)); // output 1 switch (output1.getState()) { case Mycila::RouterOutput::State::OUTPUT_DISABLED: case Mycila::RouterOutput::State::OUTPUT_IDLE: - _output1State.update(output1.getStateName(), DASH_STATUS_IDLE); + _output1State.setFeedback(output1.getStateName(), dash::Status::IDLE); break; case Mycila::RouterOutput::State::OUTPUT_BYPASS_AUTO: case Mycila::RouterOutput::State::OUTPUT_BYPASS_MANUAL: - _output1State.update(output1.getStateName(), DASH_STATUS_WARNING); + _output1State.setFeedback(output1.getStateName(), dash::Status::WARNING); break; case Mycila::RouterOutput::State::OUTPUT_ROUTING: - _output1State.update(output1.getStateName(), DASH_STATUS_SUCCESS); + _output1State.setFeedback(output1.getStateName(), dash::Status::SUCCESS); break; default: - _output1State.update(YASOLR_LBL_109, DASH_STATUS_DANGER); + _output1State.setFeedback(YASOLR_LBL_109, dash::Status::DANGER); break; } - _temperature(_output1DS18State, output1); - _output1DimmerSlider.update(dimmerO1.getDutyCycle() * 100); - _output1Bypass.update(output1.isBypassOn()); + _output1DS18State.setValue(output1.temperature().orElse(0.0f)); + _output1DimmerSlider.setValue(dimmerO1.getDutyCycle() * 100); + _output1Bypass.setValue(output1.isBypassOn()); // output 2 switch (output2.getState()) { case Mycila::RouterOutput::State::OUTPUT_DISABLED: case Mycila::RouterOutput::State::OUTPUT_IDLE: - _output2State.update(output2.getStateName(), DASH_STATUS_IDLE); + _output2State.setFeedback(output2.getStateName(), dash::Status::IDLE); break; case Mycila::RouterOutput::State::OUTPUT_BYPASS_AUTO: case Mycila::RouterOutput::State::OUTPUT_BYPASS_MANUAL: - _output2State.update(output2.getStateName(), DASH_STATUS_WARNING); + _output2State.setFeedback(output2.getStateName(), dash::Status::WARNING); break; case Mycila::RouterOutput::State::OUTPUT_ROUTING: - _output2State.update(output2.getStateName(), DASH_STATUS_SUCCESS); + _output2State.setFeedback(output2.getStateName(), dash::Status::SUCCESS); break; default: - _output2State.update(YASOLR_LBL_109, DASH_STATUS_DANGER); + _output2State.setFeedback(YASOLR_LBL_109, dash::Status::DANGER); break; } - _temperature(_output2DS18State, output2); - _output2DimmerSlider.update(dimmerO2.getDutyCycle() * 100); - _output2Bypass.update(output2.isBypassOn()); + _output2DS18State.setValue(output2.temperature().orElse(0.0f)); + _output2DimmerSlider.setValue(dimmerO2.getDutyCycle() * 100); + _output2Bypass.setValue(output2.isBypassOn()); // relay - _relay1Switch.update(relay1.isOn()); - _relay2Switch.update(relay2.isOn()); + _relay1Switch.setValue(relay1.isOn()); + _relay2Switch.setValue(relay2.isOn()); // Hardware (config) - _output1PZEMSync.update(!pzemO1PairingTask.isPaused()); - _output2PZEMSync.update(!pzemO2PairingTask.isPaused()); - _resistanceCalibration.update(router.isCalibrationRunning()); + _output1PZEMSync.setValue(!pzemO1PairingTask.isPaused()); + _output2PZEMSync.setValue(!pzemO2PairingTask.isPaused()); + _resistanceCalibration.setValue(router.isCalibrationRunning()); #ifdef APP_MODEL_PRO // Output 1 - _output1DimmerSliderRO.update(dimmerO1.getDutyCycle() * 100); - _output1BypassRO.update(YASOLR_STATE(output1.isBypassOn()), output1.isBypassOn() ? DASH_STATUS_SUCCESS : DASH_STATUS_IDLE); - _output1Power.update(output1Measurements.power); - _output1ApparentPower.update(output1Measurements.apparentPower); - _output1PowerFactor.update(output1Measurements.powerFactor); - _output1THDi.update(output1Measurements.thdi * 100); - _output1Voltage.update(output1Measurements.dimmedVoltage); - _output1Current.update(output1Measurements.current); - _output1Resistance.update(output1Measurements.resistance); - _output1Energy.update(output1Measurements.energy); + _output1DimmerSliderRO.setValue(dimmerO1.getDutyCycle() * 100); + _output1BypassRO.setFeedback(YASOLR_STATE(output1.isBypassOn()), output1.isBypassOn() ? dash::Status::SUCCESS : dash::Status::IDLE); + _output1Power.setValue(output1Measurements.power); + _output1ApparentPower.setValue(output1Measurements.apparentPower); + _output1PowerFactor.setValue(output1Measurements.powerFactor); + _output1THDi.setValue(output1Measurements.thdi * 100); + _output1Voltage.setValue(output1Measurements.dimmedVoltage); + _output1Current.setValue(output1Measurements.current); + _output1Resistance.setValue(output1Measurements.resistance); + _output1Energy.setValue(output1Measurements.energy); // output 2 - _output2DimmerSliderRO.update(dimmerO2.getDutyCycle() * 100); - _output2BypassRO.update(YASOLR_STATE(output2.isBypassOn()), output2.isBypassOn() ? DASH_STATUS_SUCCESS : DASH_STATUS_IDLE); - _output2Power.update(output2Measurements.power); - _output2ApparentPower.update(output2Measurements.apparentPower); - _output2PowerFactor.update(output2Measurements.powerFactor); - _output2THDi.update(output2Measurements.thdi * 100); - _output2Voltage.update(output2Measurements.dimmedVoltage); - _output2Current.update(output2Measurements.current); - _output2Resistance.update(output2Measurements.resistance); - _output2Energy.update(output2Measurements.energy); + _output2DimmerSliderRO.setValue(dimmerO2.getDutyCycle() * 100); + _output2BypassRO.setFeedback(YASOLR_STATE(output2.isBypassOn()), output2.isBypassOn() ? dash::Status::SUCCESS : dash::Status::IDLE); + _output2Power.setValue(output2Measurements.power); + _output2ApparentPower.setValue(output2Measurements.apparentPower); + _output2PowerFactor.setValue(output2Measurements.powerFactor); + _output2THDi.setValue(output2Measurements.thdi * 100); + _output2Voltage.setValue(output2Measurements.dimmedVoltage); + _output2Current.setValue(output2Measurements.current); + _output2Resistance.setValue(output2Measurements.resistance); + _output2Energy.setValue(output2Measurements.energy); // relays - _relay1SwitchRO.update(YASOLR_STATE(relay1.isOn()), relay1.isOn() ? DASH_STATUS_SUCCESS : DASH_STATUS_IDLE); - _relay2SwitchRO.update(YASOLR_STATE(relay2.isOn()), relay2.isOn() ? DASH_STATUS_SUCCESS : DASH_STATUS_IDLE); + _relay1SwitchRO.setFeedback(YASOLR_STATE(relay1.isOn()), relay1.isOn() ? dash::Status::SUCCESS : dash::Status::IDLE); - // Hardware (status) + // Hardware _status(_jsy, KEY_ENABLE_JSY, jsy.isEnabled(), jsy.isConnected(), YASOLR_LBL_110); _status(_mqtt, KEY_ENABLE_MQTT, mqtt.isEnabled(), mqtt.isConnected(), mqtt.getLastError() ? mqtt.getLastError() : YASOLR_LBL_113); @@ -1229,9 +1306,9 @@ void YaSolR::Website::updateCharts() { _routerTHDiHistoryY[YASOLR_GRAPH_POINTS - 1] = round(routerMetrics.thdi * 100); // update charts - _gridPowerHistory.updateY(_gridPowerHistoryY, YASOLR_GRAPH_POINTS); - _routedPowerHistory.updateY(_routedPowerHistoryY, YASOLR_GRAPH_POINTS); - _routerTHDiHistory.updateY(_routerTHDiHistoryY, YASOLR_GRAPH_POINTS); + _gridPowerHistory.setY(_gridPowerHistoryY, YASOLR_GRAPH_POINTS); + _routedPowerHistory.setY(_routedPowerHistoryY, YASOLR_GRAPH_POINTS); + _routerTHDiHistory.setY(_routerTHDiHistoryY, YASOLR_GRAPH_POINTS); } void YaSolR::Website::updatePID() { @@ -1256,13 +1333,13 @@ void YaSolR::Website::updatePID() { _pidDTermHistoryY[YASOLR_GRAPH_POINTS - 1] = round(pidController.getDTerm()); // update charts - _pidInputHistory.updateY(_pidInputHistoryY, YASOLR_GRAPH_POINTS); - _pidOutputHistory.updateY(_pidOutputHistoryY, YASOLR_GRAPH_POINTS); - _pidErrorHistory.updateY(_pidErrorHistoryY, YASOLR_GRAPH_POINTS); - _pidSumHistory.updateY(_pidSumHistoryY, YASOLR_GRAPH_POINTS); - _pidPTermHistory.updateY(_pidPTermHistoryY, YASOLR_GRAPH_POINTS); - _pidITermHistory.updateY(_pidITermHistoryY, YASOLR_GRAPH_POINTS); - _pidDTermHistory.updateY(_pidDTermHistoryY, YASOLR_GRAPH_POINTS); + _pidInputHistory.setY(_pidInputHistoryY, YASOLR_GRAPH_POINTS); + _pidOutputHistory.setY(_pidOutputHistoryY, YASOLR_GRAPH_POINTS); + _pidErrorHistory.setY(_pidErrorHistoryY, YASOLR_GRAPH_POINTS); + _pidSumHistory.setY(_pidSumHistoryY, YASOLR_GRAPH_POINTS); + _pidPTermHistory.setY(_pidPTermHistoryY, YASOLR_GRAPH_POINTS); + _pidITermHistory.setY(_pidITermHistoryY, YASOLR_GRAPH_POINTS); + _pidDTermHistory.setY(_pidDTermHistoryY, YASOLR_GRAPH_POINTS); #endif } @@ -1277,184 +1354,3 @@ void YaSolR::Website::resetPID() { memset(_pidDTermHistoryY, 0, sizeof(_pidDTermHistoryY)); #endif } - -void YaSolR::Website::_sliderConfig(Card& card, const char* key) { - card.attachCallback([key, &card](int value) { - config.set(key, std::to_string(value)); - card.update(config.getInt(key)); - dashboard.refreshCard(&card); - }); -} - -void YaSolR::Website::_percentageSlider(Card& card, const char* key) { - card.attachCallback([key, &card](int value) { - config.set(key, std::to_string(value)); - card.update(value); - dashboard.refreshCard(&card); - }); -} - -void YaSolR::Website::_floatConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card](const char* value) { - if (value[0]) { - config.set(key, value); - } else { - config.unset(key); - } - card.update(config.get(key)); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_numConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card](const char* value) { - if (value[0]) { - config.set(key, std::to_string(strtol(value, nullptr, 10))); - } else { - config.unset(key); - } - card.update(config.getInt(key)); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_pinConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card, this](const char* value) { - if (value[0]) { - config.set(key, std::to_string(strtol(value, nullptr, 10))); - } else { - config.unset(key); - } - initCards(); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_boolConfig(Card& card, const char* key) { - card.attachCallback([key, &card, this](int value) { - config.setBool(key, value); - card.update(config.getBool(key) ? 1 : 0); - dashboard.refreshCard(&card); - }); -} - -void YaSolR::Website::_textConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card](const char* value) { - config.set(key, value); - card.update(config.get(key)); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_daysConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card, this](const char* value) { - config.set(key, value[0] ? value : "none"); - card.update(config.get(key)); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_passwordConfig(Card& card, const char* key) { -#ifdef APP_MODEL_PRO - card.attachCallback([key, &card, this](const char* value) { - if (value[0]) { - config.set(key, value); - } else { - config.unset(key); - } - card.update(config.isEmpty(key) ? "" : HIDDEN_PWD); - dashboard.refreshCard(&card); - }); -#endif -} - -void YaSolR::Website::_relaySwitch(Card& card, Mycila::RouterRelay& relay) { - card.attachCallback([&card, &relay, this](int value) { - relay.tryRelayState(value); - card.update(relay.isOn()); - dashboard.refreshCard(&card); - }); -} - -void YaSolR::Website::_outputBypassSwitch(Card& card, Mycila::RouterOutput& output) { - card.attachCallback([&card, &output, this](int value) { - if (output.isBypassEnabled()) { - output.setBypass(value); - } - card.update(output.isBypassOn()); - dashboard.refreshCard(&card); - dashboardTask.requestEarlyRun(); - }); -} - -void YaSolR::Website::_outputDimmerSlider(Card& card, Mycila::RouterOutput& output) { - card.attachCallbackF([&card, &output, this](float value) { - if (output.isDimmerEnabled()) { - output.setDimmerDutyCycle(value / 100); - } - card.update(output.getDimmerDutyCycle() * 100); - dashboard.refreshCard(&card); - dashboardTask.requestEarlyRun(); - }); -} - -void YaSolR::Website::_temperature(Card& card, Mycila::DS18& sensor) { - if (!sensor.isEnabled()) { - card.update(YASOLR_LBL_115, ""); - } else if (!sensor.isValid()) { - card.update(YASOLR_LBL_123, ""); - } else { - card.update(sensor.getTemperature().value_or(0), "°C"); - } -} - -void YaSolR::Website::_temperature(Card& card, Mycila::RouterOutput& output) { - if (output.temperature().neverUpdated()) { - card.update(YASOLR_LBL_115, ""); - } else if (output.temperature().isAbsent()) { - card.update(YASOLR_LBL_123, ""); - } else { - card.update(output.temperature().get(), "°C"); - } -} - -void YaSolR::Website::_status(Card& card, const char* key, bool enabled, bool active, const char* err) { - const bool configEnabled = config.getBool(key); - if (!configEnabled) - card.update(config.getBool(key), DASH_STATUS_IDLE "," YASOLR_LBL_115); - else if (!enabled) - card.update(config.getBool(key), DASH_STATUS_DANGER "," YASOLR_LBL_124); - else if (!active) - card.update(config.getBool(key), (std::string(DASH_STATUS_WARNING) + "," + err).c_str()); - else - card.update(config.getBool(key), DASH_STATUS_SUCCESS "," YASOLR_LBL_130); -} - -void YaSolR::Website::_pinout(Card& card, int32_t pin, std::unordered_map& pinout) { - if (pin == GPIO_NUM_NC) { - card.update(YASOLR_LBL_115, DASH_STATUS_IDLE); - } else if (pinout.find(pin) != pinout.end()) { - std::string v = std::to_string(pin) + " (" YASOLR_LBL_153 ")"; - pinout[pin]->update(v, DASH_STATUS_DANGER); - card.update(v, DASH_STATUS_DANGER); - } else if (!GPIO_IS_VALID_GPIO(pin)) { - pinout[pin] = &card; - card.update(std::to_string(pin) + " (" YASOLR_LBL_154 ")", DASH_STATUS_DANGER); - } else if (!GPIO_IS_VALID_OUTPUT_GPIO(pin)) { - pinout[pin] = &card; - card.update(std::to_string(pin) + " (" YASOLR_LBL_155 ")", DASH_STATUS_WARNING); - } else { - pinout[pin] = &card; - card.update(std::to_string(pin) + " (" YASOLR_LBL_156 ")", DASH_STATUS_SUCCESS); - } -} diff --git a/src/init/Config.cpp b/src/init/Config.cpp index e24f5921..79053698 100644 --- a/src/init/Config.cpp +++ b/src/init/Config.cpp @@ -16,8 +16,9 @@ Mycila::Task initConfigTask("Init Config", [](void* params) { calibrationTask.setInterval(1 * Mycila::TaskDuration::SECONDS); carouselTask.setEnabledWhen([]() { return display.isEnabled(); }); carouselTask.setIntervalSupplier([]() { return config.getLong(KEY_DISPLAY_SPEED) * Mycila::TaskDuration::SECONDS; }); - dashboardTask.setEnabledWhen([]() { return espConnect.isConnected() && !dashboard.isAsyncAccessInProgress(); }); - dashboardTask.setInterval(1000 * Mycila::TaskDuration::MILLISECONDS); + dashboardInitTask.setEnabledWhen([]() { return espConnect.isConnected() && !dashboard.isAsyncAccessInProgress(); }); + dashboardUpdateTask.setEnabledWhen([]() { return espConnect.isConnected() && !dashboard.isAsyncAccessInProgress(); }); + dashboardUpdateTask.setInterval(1000 * Mycila::TaskDuration::MILLISECONDS); debugTask.setEnabledWhen([]() { return config.getBool(KEY_ENABLE_DEBUG); }); debugTask.setInterval(20 * Mycila::TaskDuration::SECONDS); displayTask.setEnabledWhen([]() { return display.isEnabled(); }); diff --git a/src/init/Core.cpp b/src/init/Core.cpp index 66661860..ea3287ff 100644 --- a/src/init/Core.cpp +++ b/src/init/Core.cpp @@ -13,7 +13,8 @@ Mycila::Task initCoreTask("Init Core", [](void* params) { // coreTaskManager calibrationTask.setManager(coreTaskManager); carouselTask.setManager(coreTaskManager); - dashboardTask.setManager(coreTaskManager); + dashboardInitTask.setManager(coreTaskManager); + dashboardUpdateTask.setManager(coreTaskManager); debugTask.setManager(coreTaskManager); displayTask.setManager(coreTaskManager); lightsTask.setManager(coreTaskManager); diff --git a/src/init/Dashboard.cpp b/src/init/Dashboard.cpp index 60290c54..7272d1b0 100644 --- a/src/init/Dashboard.cpp +++ b/src/init/Dashboard.cpp @@ -7,7 +7,7 @@ extern YaSolR::Website website; -Mycila::Task initDashboardCards("Init Dashboard", [](void* params) { +Mycila::Task initDashboard("Init Dashboard", [](void* params) { logger.info(TAG, "Initializing dashboard"); website.initLayout(); website.initCards(); diff --git a/src/init/Debug.cpp b/src/init/Debug.cpp index f2e45be9..8b4ef239 100644 --- a/src/init/Debug.cpp +++ b/src/init/Debug.cpp @@ -22,7 +22,7 @@ Mycila::Task initLoggingTask("Init Logging", [](void* params) { if (debug) { // Enable profiling for some FOREVER tasks - dashboardTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); + dashboardUpdateTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); // debugTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); // ds18Task.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); displayTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); @@ -32,7 +32,7 @@ Mycila::Task initLoggingTask("Init Logging", [](void* params) { // routerTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); // routingTask.enableProfiling(10, Mycila::TaskTimeUnit::MILLISECONDS); } else { - dashboardTask.disableProfiling(); + dashboardUpdateTask.disableProfiling(); // debugTask.disableProfiling(); // ds18Task.disableProfiling(); displayTask.disableProfiling(); @@ -44,6 +44,7 @@ Mycila::Task initLoggingTask("Init Logging", [](void* params) { } // Log execution time for some "ONCE" tasks + dashboardInitTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); ds18Task.setCallback(debug ? LOG_EXEC_TIME : nullptr); haDiscoveryTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); mqttConfigTask.setCallback(debug ? LOG_EXEC_TIME : nullptr); diff --git a/src/init/Events.cpp b/src/init/Events.cpp index 2bd8c841..bc8821c0 100644 --- a/src/init/Events.cpp +++ b/src/init/Events.cpp @@ -222,7 +222,7 @@ Mycila::Task initEventsTask("Init Events", [](void* params) { logger.info(TAG, "PID Controller reconfigured!"); } - website.initCards(); + dashboardInitTask.resume(); mqttPublishConfigTask.resume(); mqttPublishTask.requestEarlyRun(); }); @@ -287,6 +287,7 @@ Mycila::Task initEventsTask("Init Events", [](void* params) { default: break; } + dashboardInitTask.resume(); }); bypassRelayO1.listen([](bool state) { diff --git a/src/init/REST.cpp b/src/init/REST.cpp index 9a1bd201..21429766 100644 --- a/src/init/REST.cpp +++ b/src/init/REST.cpp @@ -156,8 +156,8 @@ Mycila::Task initRestApiTask("Init REST API", [](void* params) { File serverCertFile = LittleFS.open(YASOLR_MQTT_SERVER_CERT_FILE, "r"); logger.info(TAG, "Uploaded MQTT PEM server certificate:\n%s", serverCertFile.readString().c_str()); serverCertFile.close(); - website.initCards(); - dashboardTask.requestEarlyRun(); + dashboardInitTask.resume(); + dashboardUpdateTask.requestEarlyRun(); request->send(response); }, [](AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) { diff --git a/src/main.cpp b/src/main.cpp index 8cdade85..a4a5fd9d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,7 +64,7 @@ void setup() { initWebTask.forceRun(); initRestApiTask.forceRun(); initMqttSubscribersTask.forceRun(); - initDashboardCards.forceRun(); + initDashboard.forceRun(); assert( jsyTaskManager.asyncStart(512 * 6, 5, 0, 100, true)); // NOLINT assert( pioTaskManager.asyncStart(512 * 7, 1, 1, 100, true)); // NOLINT diff --git a/src/tasks/Dashboard.cpp b/src/tasks/Dashboard.cpp index 818d5243..088f38f5 100644 --- a/src/tasks/Dashboard.cpp +++ b/src/tasks/Dashboard.cpp @@ -8,7 +8,11 @@ extern YaSolR::Website website; -Mycila::Task dashboardTask("Dashboard", [](void* params) { +Mycila::Task dashboardInitTask("Dashboard Init", Mycila::TaskType::ONCE, [](void* params) { + website.initCards(); +}); + +Mycila::Task dashboardUpdateTask("Dashboard Update", [](void* params) { if (config.getBool(KEY_ENABLE_PID_VIEW)) { website.updatePID(); if (wsDebugPID.count()) { diff --git a/src/tasks/Routing.cpp b/src/tasks/Routing.cpp index f7149f3d..5ec4737d 100644 --- a/src/tasks/Routing.cpp +++ b/src/tasks/Routing.cpp @@ -11,7 +11,7 @@ Mycila::Task routingTask("Routing", Mycila::TaskType::ONCE, [](void* params) { if (voltage.has_value() && power.isPresent()) { router.divert(voltage.value(), power.get()); if (config.getBool(KEY_ENABLE_PID_VIEW)) { - dashboardTask.requestEarlyRun(); + dashboardUpdateTask.requestEarlyRun(); } } });