diff --git a/README.md b/README.md index 5c47af6..508a1cb 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ ![Integration with HomeAssistant](/assets/poster-3.png) ## Features + +The current version targets ESP32-based boards. - DHW temperature control - Heating temperature control - Smart heating temperature control modes: @@ -81,7 +83,7 @@ Anyone is welcome to add their native language as a [new localization](https://h ## Gratitude -* To the developers of the libraries used: [OpenTherm Library](https://github.com/ihormelnyk/opentherm_library), [ESP8266Scheduler](https://github.com/nrwiersma/ESP8266Scheduler), [ArduinoJson](https://github.com/bblanchon/ArduinoJson), [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino), [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient), [ESPTelnet](https://github.com/LennartHennigs/ESPTelnet), [FileData](https://github.com/GyverLibs/FileData), [GyverPID](https://github.com/GyverLibs/GyverPID), [GyverBlinker](https://github.com/GyverLibs/GyverBlinker), [OneWireNg](https://github.com/pstolarz/OneWireNg) & [OneWire](https://github.com/PaulStoffregen/OneWire) +* To the developers of the libraries used: [OpenTherm Library](https://github.com/ihormelnyk/opentherm_library), [ESP32Scheduler](https://github.com/laxilef/ESP32Scheduler), [ArduinoJson](https://github.com/bblanchon/ArduinoJson), [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino), [ArduinoMqttClient](https://github.com/arduino-libraries/ArduinoMqttClient), [ESPTelnet](https://github.com/LennartHennigs/ESPTelnet), [FileData](https://github.com/GyverLibs/FileData), [GyverPID](https://github.com/GyverLibs/GyverPID), [GyverBlinker](https://github.com/GyverLibs/GyverBlinker), [OneWireNg](https://github.com/pstolarz/OneWireNg) & [OneWire](https://github.com/PaulStoffregen/OneWire) * To the [PlatformIO](https://platformio.org/) Team * To the team and contributors of the [pioarduino](https://github.com/pioarduino/platform-espressif32) project * To the [BrowserStack](https://www.browserstack.com/) team. This project is tested with BrowserStack. diff --git a/lib/BufferedWebServer/BufferedWebServer.h b/lib/BufferedWebServer/BufferedWebServer.h index 401279b..61e3d8d 100644 --- a/lib/BufferedWebServer/BufferedWebServer.h +++ b/lib/BufferedWebServer/BufferedWebServer.h @@ -14,17 +14,8 @@ public: void send(int code, T contentType, const JsonVariantConst content, bool pretty = false) { auto contentLength = pretty ? measureJsonPretty(content) : measureJson(content); - #ifdef ARDUINO_ARCH_ESP8266 - if (!this->webServer->chunkedResponseModeStart(code, contentType)) { - this->webServer->send(505, F("text/html"), F("HTTP1.1 required")); - return; - } - - this->webServer->setContentLength(contentLength); - #else this->webServer->setContentLength(contentLength); this->webServer->send(code, contentType, emptyString); - #endif if (pretty) { serializeJsonPretty(content, *this); @@ -35,11 +26,7 @@ public: this->flush(); - #ifdef ARDUINO_ARCH_ESP8266 - this->webServer->chunkedResponseFinalize(); - #else this->webServer->sendContent(emptyString); - #endif } size_t write(uint8_t c) { @@ -78,10 +65,6 @@ public: return; } - #ifdef ARDUINO_ARCH_ESP8266 - ::optimistic_yield(1000); - #endif - auto& client = this->webServer->client(); if (client.connected()) { this->webServer->sendContent((const char*)this->buffer, this->bufferPos); @@ -89,9 +72,6 @@ public: this->bufferPos = 0; - #ifdef ARDUINO_ARCH_ESP8266 - ::optimistic_yield(1000); - #endif } protected: diff --git a/lib/HomeAssistantHelper/HomeAssistantHelper.h b/lib/HomeAssistantHelper/HomeAssistantHelper.h index 2c7c004..1b21827 100644 --- a/lib/HomeAssistantHelper/HomeAssistantHelper.h +++ b/lib/HomeAssistantHelper/HomeAssistantHelper.h @@ -53,23 +53,23 @@ public: return false; } - doc[FPSTR(HA_DEVICE)][FPSTR(HA_IDENTIFIERS)][0] = this->devicePrefix; - doc[FPSTR(HA_DEVICE)][FPSTR(HA_SW_VERSION)] = this->deviceVersion; + doc[HA_DEVICE][HA_IDENTIFIERS][0] = this->devicePrefix; + doc[HA_DEVICE][HA_SW_VERSION] = this->deviceVersion; if (this->deviceManufacturer != nullptr) { - doc[FPSTR(HA_DEVICE)][FPSTR(HA_MANUFACTURER)] = this->deviceManufacturer; + doc[HA_DEVICE][HA_MANUFACTURER] = this->deviceManufacturer; } if (this->deviceModel != nullptr) { - doc[FPSTR(HA_DEVICE)][FPSTR(HA_MODEL)] = this->deviceModel; + doc[HA_DEVICE][HA_MODEL] = this->deviceModel; } if (this->deviceName != nullptr) { - doc[FPSTR(HA_DEVICE)][FPSTR(HA_NAME)] = this->deviceName; + doc[HA_DEVICE][HA_NAME] = this->deviceName; } if (this->deviceConfigUrl != nullptr) { - doc[FPSTR(HA_DEVICE)][FPSTR(HA_CONF_URL)] = this->deviceConfigUrl; + doc[HA_DEVICE][HA_CONF_URL] = this->deviceConfigUrl; } bool result = this->writer->publish(topic, doc, true); @@ -110,7 +110,7 @@ public: topic.concat(this->devicePrefix); topic.concat(nameSeparator); topic.concat(name); - topic.concat(F("/config")); + topic.concat("/config"); return topic; } diff --git a/lib/HomeAssistantHelper/strings.h b/lib/HomeAssistantHelper/strings.h index d9b9029..4d4d597 100644 --- a/lib/HomeAssistantHelper/strings.h +++ b/lib/HomeAssistantHelper/strings.h @@ -1,78 +1,75 @@ #pragma once -#ifndef PROGMEM - #define PROGMEM // NOLINT -#endif -const char HA_ENTITY_BINARY_SENSOR[] PROGMEM = "binary_sensor"; -const char HA_ENTITY_BUTTON[] PROGMEM = "button"; -const char HA_ENTITY_FAN[] PROGMEM = "fan"; -const char HA_ENTITY_CLIMATE[] PROGMEM = "climate"; -const char HA_ENTITY_NUMBER[] PROGMEM = "number"; -const char HA_ENTITY_SELECT[] PROGMEM = "select"; -const char HA_ENTITY_SENSOR[] PROGMEM = "sensor"; -const char HA_ENTITY_SWITCH[] PROGMEM = "switch"; +const char HA_ENTITY_BINARY_SENSOR[] = "binary_sensor"; +const char HA_ENTITY_BUTTON[] = "button"; +const char HA_ENTITY_FAN[] = "fan"; +const char HA_ENTITY_CLIMATE[] = "climate"; +const char HA_ENTITY_NUMBER[] = "number"; +const char HA_ENTITY_SELECT[] = "select"; +const char HA_ENTITY_SENSOR[] = "sensor"; +const char HA_ENTITY_SWITCH[] = "switch"; // https://www.home-assistant.io/integrations/mqtt/#supported-abbreviations-in-mqtt-discovery-messages -const char HA_DEFAULT_ENTITY_ID[] PROGMEM = "def_ent_id"; // "default_entity_id " -const char HA_DEVICE[] PROGMEM = "dev"; // "device" -const char HA_IDENTIFIERS[] PROGMEM = "ids"; // "identifiers" -const char HA_SW_VERSION[] PROGMEM = "sw"; // "sw_version" -const char HA_MANUFACTURER[] PROGMEM = "mf"; // "manufacturer" -const char HA_MODEL[] PROGMEM = "mdl"; // "model" -const char HA_NAME[] PROGMEM = "name"; -const char HA_CONF_URL[] PROGMEM = "cu"; // "configuration_url" -const char HA_COMMAND_TOPIC[] PROGMEM = "cmd_t"; // "command_topic" -const char HA_COMMAND_TEMPLATE[] PROGMEM = "cmd_tpl"; // "command_template" -const char HA_ENABLED_BY_DEFAULT[] PROGMEM = "en"; // "enabled_by_default" -const char HA_UNIQUE_ID[] PROGMEM = "uniq_id"; // "unique_id" -const char HA_ENTITY_CATEGORY[] PROGMEM = "ent_cat"; // "entity_category" -const char HA_ENTITY_CATEGORY_DIAGNOSTIC[] PROGMEM = "diagnostic"; -const char HA_ENTITY_CATEGORY_CONFIG[] PROGMEM = "config"; -const char HA_STATE_TOPIC[] PROGMEM = "stat_t"; // "state_topic" -const char HA_VALUE_TEMPLATE[] PROGMEM = "val_tpl"; // "value_template" -const char HA_OPTIONS[] PROGMEM = "ops"; // "options" -const char HA_AVAILABILITY[] PROGMEM = "avty"; // "availability" -const char HA_AVAILABILITY_MODE[] PROGMEM = "avty_mode"; // "availability_mode" -const char HA_TOPIC[] PROGMEM = "t"; // "topic" -const char HA_DEVICE_CLASS[] PROGMEM = "dev_cla"; // "device_class" -const char HA_UNIT_OF_MEASUREMENT[] PROGMEM = "unit_of_meas"; // "unit_of_measurement" -const char HA_UNIT_OF_MEASUREMENT_C[] PROGMEM = "°C"; -const char HA_UNIT_OF_MEASUREMENT_F[] PROGMEM = "°F"; -const char HA_UNIT_OF_MEASUREMENT_PERCENT[] PROGMEM = "%"; -const char HA_UNIT_OF_MEASUREMENT_L_MIN[] PROGMEM = "L/min"; -const char HA_UNIT_OF_MEASUREMENT_GAL_MIN[] PROGMEM = "gal/min"; -const char HA_ICON[] PROGMEM = "ic"; // "icon" -const char HA_MIN[] PROGMEM = "min"; -const char HA_MAX[] PROGMEM = "max"; -const char HA_STEP[] PROGMEM = "step"; -const char HA_MODE[] PROGMEM = "mode"; -const char HA_MODE_BOX[] PROGMEM = "box"; -const char HA_STATE_ON[] PROGMEM = "stat_on"; // "state_on" -const char HA_STATE_OFF[] PROGMEM = "stat_off"; // "state_off" -const char HA_PAYLOAD_ON[] PROGMEM = "pl_on"; // "payload_on" -const char HA_PAYLOAD_OFF[] PROGMEM = "pl_off"; // "payload_off" -const char HA_STATE_CLASS[] PROGMEM = "stat_cla"; // "state_class" -const char HA_STATE_CLASS_MEASUREMENT[] PROGMEM = "measurement"; -const char HA_EXPIRE_AFTER[] PROGMEM = "exp_aft"; // "expire_after" -const char HA_CURRENT_TEMPERATURE_TOPIC[] PROGMEM = "curr_temp_t"; // "current_temperature_topic" -const char HA_CURRENT_TEMPERATURE_TEMPLATE[] PROGMEM = "curr_temp_tpl"; // "current_temperature_template" -const char HA_TEMPERATURE_COMMAND_TOPIC[] PROGMEM = "temp_cmd_t"; // "temperature_command_topic" -const char HA_TEMPERATURE_COMMAND_TEMPLATE[] PROGMEM = "temp_cmd_tpl"; // "temperature_command_template" -const char HA_TEMPERATURE_STATE_TOPIC[] PROGMEM = "temp_stat_t"; // "temperature_state_topic" -const char HA_TEMPERATURE_STATE_TEMPLATE[] PROGMEM = "temp_stat_tpl"; // "temperature_state_template" -const char HA_TEMPERATURE_UNIT[] PROGMEM = "temp_unit"; // "temperature_unit" -const char HA_MODE_COMMAND_TOPIC[] PROGMEM = "mode_cmd_t"; // "mode_command_topic" -const char HA_MODE_COMMAND_TEMPLATE[] PROGMEM = "mode_cmd_tpl"; // "mode_command_template" -const char HA_MODE_STATE_TOPIC[] PROGMEM = "mode_stat_t"; // "mode_state_topic" -const char HA_MODE_STATE_TEMPLATE[] PROGMEM = "mode_stat_tpl"; // "mode_state_template" -const char HA_MODES[] PROGMEM = "modes"; -const char HA_ACTION_TOPIC[] PROGMEM = "act_t"; // "action_topic" -const char HA_ACTION_TEMPLATE[] PROGMEM = "act_tpl"; // "action_template" -const char HA_MIN_TEMP[] PROGMEM = "min_temp"; -const char HA_MAX_TEMP[] PROGMEM = "max_temp"; -const char HA_TEMP_STEP[] PROGMEM = "temp_step"; -const char HA_PRESET_MODE_COMMAND_TOPIC[] PROGMEM = "pr_mode_cmd_t"; // "preset_mode_command_topic" -const char HA_PRESET_MODE_COMMAND_TEMPLATE[] PROGMEM = "pr_mode_cmd_tpl"; // "preset_mode_command_template" -const char HA_PRESET_MODE_STATE_TOPIC[] PROGMEM = "pr_mode_stat_t"; // "preset_mode_state_topic" -const char HA_PRESET_MODE_VALUE_TEMPLATE[] PROGMEM = "pr_mode_val_tpl"; // "preset_mode_value_template" -const char HA_PRESET_MODES[] PROGMEM = "pr_modes"; // "preset_modes" +const char HA_DEFAULT_ENTITY_ID[] = "def_ent_id"; // "default_entity_id " +const char HA_DEVICE[] = "dev"; // "device" +const char HA_IDENTIFIERS[] = "ids"; // "identifiers" +const char HA_SW_VERSION[] = "sw"; // "sw_version" +const char HA_MANUFACTURER[] = "mf"; // "manufacturer" +const char HA_MODEL[] = "mdl"; // "model" +const char HA_NAME[] = "name"; +const char HA_CONF_URL[] = "cu"; // "configuration_url" +const char HA_COMMAND_TOPIC[] = "cmd_t"; // "command_topic" +const char HA_COMMAND_TEMPLATE[] = "cmd_tpl"; // "command_template" +const char HA_ENABLED_BY_DEFAULT[] = "en"; // "enabled_by_default" +const char HA_UNIQUE_ID[] = "uniq_id"; // "unique_id" +const char HA_ENTITY_CATEGORY[] = "ent_cat"; // "entity_category" +const char HA_ENTITY_CATEGORY_DIAGNOSTIC[] = "diagnostic"; +const char HA_ENTITY_CATEGORY_CONFIG[] = "config"; +const char HA_STATE_TOPIC[] = "stat_t"; // "state_topic" +const char HA_VALUE_TEMPLATE[] = "val_tpl"; // "value_template" +const char HA_OPTIONS[] = "ops"; // "options" +const char HA_AVAILABILITY[] = "avty"; // "availability" +const char HA_AVAILABILITY_MODE[] = "avty_mode"; // "availability_mode" +const char HA_TOPIC[] = "t"; // "topic" +const char HA_DEVICE_CLASS[] = "dev_cla"; // "device_class" +const char HA_UNIT_OF_MEASUREMENT[] = "unit_of_meas"; // "unit_of_measurement" +const char HA_UNIT_OF_MEASUREMENT_C[] = "°C"; +const char HA_UNIT_OF_MEASUREMENT_F[] = "°F"; +const char HA_UNIT_OF_MEASUREMENT_PERCENT[] = "%"; +const char HA_UNIT_OF_MEASUREMENT_L_MIN[] = "L/min"; +const char HA_UNIT_OF_MEASUREMENT_GAL_MIN[] = "gal/min"; +const char HA_ICON[] = "ic"; // "icon" +const char HA_MIN[] = "min"; +const char HA_MAX[] = "max"; +const char HA_STEP[] = "step"; +const char HA_MODE[] = "mode"; +const char HA_MODE_BOX[] = "box"; +const char HA_STATE_ON[] = "stat_on"; // "state_on" +const char HA_STATE_OFF[] = "stat_off"; // "state_off" +const char HA_PAYLOAD_ON[] = "pl_on"; // "payload_on" +const char HA_PAYLOAD_OFF[] = "pl_off"; // "payload_off" +const char HA_STATE_CLASS[] = "stat_cla"; // "state_class" +const char HA_STATE_CLASS_MEASUREMENT[] = "measurement"; +const char HA_EXPIRE_AFTER[] = "exp_aft"; // "expire_after" +const char HA_CURRENT_TEMPERATURE_TOPIC[] = "curr_temp_t"; // "current_temperature_topic" +const char HA_CURRENT_TEMPERATURE_TEMPLATE[] = "curr_temp_tpl"; // "current_temperature_template" +const char HA_TEMPERATURE_COMMAND_TOPIC[] = "temp_cmd_t"; // "temperature_command_topic" +const char HA_TEMPERATURE_COMMAND_TEMPLATE[] = "temp_cmd_tpl"; // "temperature_command_template" +const char HA_TEMPERATURE_STATE_TOPIC[] = "temp_stat_t"; // "temperature_state_topic" +const char HA_TEMPERATURE_STATE_TEMPLATE[] = "temp_stat_tpl"; // "temperature_state_template" +const char HA_TEMPERATURE_UNIT[] = "temp_unit"; // "temperature_unit" +const char HA_MODE_COMMAND_TOPIC[] = "mode_cmd_t"; // "mode_command_topic" +const char HA_MODE_COMMAND_TEMPLATE[] = "mode_cmd_tpl"; // "mode_command_template" +const char HA_MODE_STATE_TOPIC[] = "mode_stat_t"; // "mode_state_topic" +const char HA_MODE_STATE_TEMPLATE[] = "mode_stat_tpl"; // "mode_state_template" +const char HA_MODES[] = "modes"; +const char HA_ACTION_TOPIC[] = "act_t"; // "action_topic" +const char HA_ACTION_TEMPLATE[] = "act_tpl"; // "action_template" +const char HA_MIN_TEMP[] = "min_temp"; +const char HA_MAX_TEMP[] = "max_temp"; +const char HA_TEMP_STEP[] = "temp_step"; +const char HA_PRESET_MODE_COMMAND_TOPIC[] = "pr_mode_cmd_t"; // "preset_mode_command_topic" +const char HA_PRESET_MODE_COMMAND_TEMPLATE[] = "pr_mode_cmd_tpl"; // "preset_mode_command_template" +const char HA_PRESET_MODE_STATE_TOPIC[] = "pr_mode_stat_t"; // "preset_mode_state_topic" +const char HA_PRESET_MODE_VALUE_TEMPLATE[] = "pr_mode_val_tpl"; // "preset_mode_value_template" +const char HA_PRESET_MODES[] = "pr_modes"; // "preset_modes" diff --git a/lib/MqttWriter/MqttWiFiClient.h b/lib/MqttWriter/MqttWiFiClient.h deleted file mode 100644 index 58f6d3a..0000000 --- a/lib/MqttWriter/MqttWiFiClient.h +++ /dev/null @@ -1,24 +0,0 @@ -#include - -class MqttWiFiClient : public WiFiClient { -public: -#ifdef ARDUINO_ARCH_ESP8266 - void flush() override { - if (this->connected()) { - WiFiClient::flush(0); - } - } - - void stop() override { - this->abort(); - } -#endif - -#ifdef ARDUINO_ARCH_ESP32 - void setSync(bool) {} - - bool getSync() { - return false; - } -#endif -}; diff --git a/lib/MqttWriter/MqttWriter.h b/lib/MqttWriter/MqttWriter.h index 0c03cbd..457e49c 100644 --- a/lib/MqttWriter/MqttWriter.h +++ b/lib/MqttWriter/MqttWriter.h @@ -1,9 +1,7 @@ #pragma once #include #include -#ifdef ARDUINO_ARCH_ESP32 #include -#endif class MqttWriter { @@ -17,17 +15,13 @@ public: this->bufferSize = bufferSize; this->buffer = static_cast(malloc(bufferSize * sizeof(*this->buffer))); -#ifdef ARDUINO_ARCH_ESP32 this->mutex = new std::mutex(); -#endif } ~MqttWriter() { free(this->buffer); -#ifdef ARDUINO_ARCH_ESP32 delete this->mutex; -#endif } MqttWriter* setYieldCallback(YieldCallback callback = nullptr) { @@ -49,15 +43,9 @@ public: } bool lock() { -#ifdef ARDUINO_ARCH_ESP32 if (!this->mutex->try_lock()) { return false; } -#else - if (this->isLocked()) { - return false; - } -#endif this->locked = true; this->writeAfterLock = 0; @@ -72,9 +60,7 @@ public: void unlock() { this->locked = false; -#if defined(ARDUINO_ARCH_ESP32) this->mutex->unlock(); -#endif } bool publish(const char* topic, const JsonVariantConst doc, bool retained = false) { @@ -212,9 +198,7 @@ protected: size_t bufferSize = 64; size_t bufferPos = 0; bool locked = false; -#ifdef ARDUINO_ARCH_ESP32 mutable std::mutex* mutex; -#endif unsigned long lockedTime = 0; size_t writeAfterLock = 0; }; diff --git a/lib/NetworkUtils/NetworkConnection.cpp b/lib/NetworkUtils/NetworkConnection.cpp index a98e208..929d6d2 100644 --- a/lib/NetworkUtils/NetworkConnection.cpp +++ b/lib/NetworkUtils/NetworkConnection.cpp @@ -4,11 +4,7 @@ using namespace NetworkUtils; void NetworkConnection::setup(bool useDhcp) { setUseDhcp(useDhcp); - #if defined(ARDUINO_ARCH_ESP8266) - wifi_set_event_handler_cb(NetworkConnection::onEvent); - #elif defined(ARDUINO_ARCH_ESP32) WiFi.onEvent(NetworkConnection::onEvent); - #endif } void NetworkConnection::reset() { @@ -29,57 +25,6 @@ NetworkConnection::DisconnectReason NetworkConnection::getDisconnectReason() { return disconnectReason; } -#if defined(ARDUINO_ARCH_ESP8266) -void NetworkConnection::onEvent(System_Event_t *event) { - switch (event->event) { - case EVENT_STAMODE_CONNECTED: - status = useDhcp ? Status::CONNECTING : Status::CONNECTED; - rawDisconnectReason = 0; - disconnectReason = DisconnectReason::NONE; - break; - - case EVENT_STAMODE_GOT_IP: - status = Status::CONNECTED; - rawDisconnectReason = 0; - disconnectReason = DisconnectReason::NONE; - break; - - case EVENT_STAMODE_DHCP_TIMEOUT: - status = Status::DISCONNECTED; - rawDisconnectReason = 0; - disconnectReason = DisconnectReason::DHCP_TIMEOUT; - break; - - case EVENT_STAMODE_DISCONNECTED: - status = Status::DISCONNECTED; - rawDisconnectReason = event->event_info.disconnected.reason; - disconnectReason = convertDisconnectReason(event->event_info.disconnected.reason); - - // https://github.com/esp8266/Arduino/blob/d5eb265f78bff9deb7063d10030a02d021c8c66c/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L231 - if ((wifi_station_get_connect_status() == STATION_GOT_IP) && !wifi_station_get_reconnect_policy()) { - wifi_station_disconnect(); - } - break; - - case EVENT_STAMODE_AUTHMODE_CHANGE: - // https://github.com/esp8266/Arduino/blob/d5eb265f78bff9deb7063d10030a02d021c8c66c/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L241 - { - auto& src = event->event_info.auth_change; - if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { - status = Status::DISCONNECTED; - rawDisconnectReason = 0; - disconnectReason = DisconnectReason::OTHER; - - wifi_station_disconnect(); - } - } - break; - - default: - break; - } -} -#elif defined(ARDUINO_ARCH_ESP32) void NetworkConnection::onEvent(WiFiEvent_t event, WiFiEventInfo_t info) { switch (event) { case ARDUINO_EVENT_WIFI_STA_CONNECTED: @@ -111,26 +56,9 @@ void NetworkConnection::onEvent(WiFiEvent_t event, WiFiEventInfo_t info) { break; } } -#endif NetworkConnection::DisconnectReason NetworkConnection::convertDisconnectReason(uint8_t reason) { switch (reason) { - #if defined(ARDUINO_ARCH_ESP8266) - case REASON_BEACON_TIMEOUT: - return DisconnectReason::BEACON_TIMEOUT; - - case REASON_NO_AP_FOUND: - return DisconnectReason::NO_AP_FOUND; - - case REASON_AUTH_FAIL: - return DisconnectReason::AUTH_FAIL; - - case REASON_ASSOC_FAIL: - return DisconnectReason::ASSOC_FAIL; - - case REASON_HANDSHAKE_TIMEOUT: - return DisconnectReason::HANDSHAKE_TIMEOUT; - #elif defined(ARDUINO_ARCH_ESP32) case WIFI_REASON_BEACON_TIMEOUT: return DisconnectReason::BEACON_TIMEOUT; @@ -145,7 +73,6 @@ NetworkConnection::DisconnectReason NetworkConnection::convertDisconnectReason(u case WIFI_REASON_HANDSHAKE_TIMEOUT: return DisconnectReason::HANDSHAKE_TIMEOUT; - #endif default: return DisconnectReason::OTHER; diff --git a/lib/NetworkUtils/NetworkConnection.h b/lib/NetworkUtils/NetworkConnection.h index f6b8910..ec9439d 100644 --- a/lib/NetworkUtils/NetworkConnection.h +++ b/lib/NetworkUtils/NetworkConnection.h @@ -1,9 +1,4 @@ -#if defined(ARDUINO_ARCH_ESP8266) - #include - #include "lwip/etharp.h" -#elif defined(ARDUINO_ARCH_ESP32) - #include -#endif +#include namespace NetworkUtils { struct NetworkConnection { @@ -34,11 +29,7 @@ namespace NetworkUtils { static void reset(); static Status getStatus(); static DisconnectReason getDisconnectReason(); - #if defined(ARDUINO_ARCH_ESP8266) - static void onEvent(System_Event_t *evt); - #elif defined(ARDUINO_ARCH_ESP32) static void onEvent(WiFiEvent_t event, WiFiEventInfo_t info); - #endif protected: static DisconnectReason convertDisconnectReason(uint8_t reason); diff --git a/lib/NetworkUtils/NetworkMgr.h b/lib/NetworkUtils/NetworkMgr.h index aeea4f3..5883c41 100644 --- a/lib/NetworkUtils/NetworkMgr.h +++ b/lib/NetworkUtils/NetworkMgr.h @@ -1,10 +1,5 @@ -#if defined(ARDUINO_ARCH_ESP8266) -#include -#include "lwip/etharp.h" -#elif defined(ARDUINO_ARCH_ESP32) #include #include -#endif #include namespace NetworkUtils { @@ -147,44 +142,23 @@ namespace NetworkUtils { bool resetWifi() { // set policy manual for work 13 ch { - #ifdef ARDUINO_ARCH_ESP8266 - wifi_country_t country = {"JP", 1, 14, WIFI_COUNTRY_POLICY_MANUAL}; - wifi_set_country(&country); - #elif defined(ARDUINO_ARCH_ESP32) const wifi_country_t country = {"JP", 1, 14, CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER, WIFI_COUNTRY_POLICY_MANUAL}; esp_wifi_set_country(&country); - #endif } WiFi.persistent(false); - #if !defined(ESP_ARDUINO_VERSION_MAJOR) || ESP_ARDUINO_VERSION_MAJOR < 3 + #if ESP_ARDUINO_VERSION_MAJOR < 3 WiFi.setAutoConnect(false); #endif WiFi.setAutoReconnect(false); - #ifdef ARDUINO_ARCH_ESP8266 - WiFi.setSleepMode(WIFI_NONE_SLEEP); - #elif defined(ARDUINO_ARCH_ESP32) WiFi.setSleep(USE_BLE ? WIFI_PS_MIN_MODEM : WIFI_PS_NONE); - #endif WiFi.softAPdisconnect(); - #ifdef ARDUINO_ARCH_ESP8266 - /*if (wifi_softap_dhcps_status() == DHCP_STARTED) { - wifi_softap_dhcps_stop(); - }*/ - #endif WiFi.disconnect(false, true); - #ifdef ARDUINO_ARCH_ESP8266 - /*if (wifi_station_dhcpc_status() == DHCP_STARTED) { - wifi_station_dhcpc_stop(); - }*/ - wifi_station_dhcpc_set_maxtry(5); - #endif - - #if defined(ARDUINO_ARCH_ESP32) && ESP_ARDUINO_VERSION_MAJOR < 3 + #if ESP_ARDUINO_VERSION_MAJOR < 3 // Nothing. Because memory leaks when turn off WiFi on ESP32 SDK < 3.0.0 return true; #else @@ -206,12 +180,6 @@ namespace NetworkUtils { NetworkConnection::reset(); } else { - /*#ifdef ARDUINO_ARCH_ESP8266 - if (wifi_station_dhcpc_status() == DHCP_STARTED) { - wifi_station_dhcpc_stop(); - } - #endif*/ - this->disconnect(); } @@ -221,14 +189,12 @@ namespace NetworkUtils { this->delayCallback(250); - #ifdef ARDUINO_ARCH_ESP32 if (this->setWifiHostname(this->hostname)) { - Log.straceln(FPSTR(L_NETWORK), F("Set hostname '%s': success"), this->hostname); + Log.straceln(L_NETWORK, "Set hostname '%s': success", this->hostname); } else { - Log.serrorln(FPSTR(L_NETWORK), F("Set hostname '%s': fail"), this->hostname); + Log.serrorln(L_NETWORK, "Set hostname '%s': fail", this->hostname); } - #endif if (!WiFi.mode((WiFiMode_t)(WiFi.getMode() | WIFI_STA))) { return false; @@ -236,21 +202,8 @@ namespace NetworkUtils { this->delayCallback(250); - #ifdef ARDUINO_ARCH_ESP8266 - if (this->setWifiHostname(this->hostname)) { - Log.straceln(FPSTR(L_NETWORK), F("Set hostname '%s': success"), this->hostname); - - } else { - Log.serrorln(FPSTR(L_NETWORK), F("Set hostname '%s': fail"), this->hostname); - } - - this->delayCallback(250); - #endif - - #ifdef ARDUINO_ARCH_ESP32 WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); - #endif if (!this->useDhcp) { WiFi.begin(this->staSsid, this->staPassword, this->staChannel, nullptr, false); @@ -275,30 +228,26 @@ namespace NetworkUtils { } void disconnect() { - #ifdef ARDUINO_ARCH_ESP32 WiFi.disconnectAsync(false, true); const unsigned long start = millis(); while (WiFi.isConnected() && (millis() - start) < 5000) { this->delayCallback(100); } - #else - WiFi.disconnect(false, true); - #endif } void loop() { if (this->reconnectFlag) { this->delayCallback(5000); - Log.sinfoln(FPSTR(L_NETWORK), F("Reconnecting...")); + Log.sinfoln(L_NETWORK, "Reconnecting..."); this->reconnectFlag = false; this->disconnect(); NetworkConnection::reset(); this->delayCallback(1000); } else if (this->isConnected() && !this->hasStaCredentials()) { - Log.sinfoln(FPSTR(L_NETWORK), F("Reset")); + Log.sinfoln(L_NETWORK, "Reset"); this->resetWifi(); NetworkConnection::reset(); this->delayCallback(1000); @@ -309,8 +258,8 @@ namespace NetworkUtils { this->connected = true; Log.sinfoln( - FPSTR(L_NETWORK), - F("Connected, downtime: %lu s., IP: %s, RSSI: %hhd"), + L_NETWORK, + "Connected, downtime: %lu s., IP: %s, RSSI: %hhd", (millis() - this->disconnectedTime) / 1000, WiFi.localIP().toString().c_str(), WiFi.RSSI() @@ -318,58 +267,51 @@ namespace NetworkUtils { } if (this->isApEnabled() && millis() - this->connectedTime > this->reconnectInterval && !this->hasApClients()) { - Log.sinfoln(FPSTR(L_NETWORK), F("Stop AP because STA connected")); + Log.sinfoln(L_NETWORK, "Stop AP because STA connected"); WiFi.mode(WIFI_STA); return; } - #ifdef ARDUINO_ARCH_ESP8266 - if (millis() - this->prevArpGratuitous > 60000) { - this->stationKeepAliveNow(); - this->prevArpGratuitous = millis(); - } - #endif - } else { if (this->connected) { this->disconnectedTime = millis(); this->connected = false; Log.sinfoln( - FPSTR(L_NETWORK), - F("Disconnected, reason: %d, uptime: %lu s."), + L_NETWORK, + "Disconnected, reason: %d, uptime: %lu s.", NetworkConnection::getDisconnectReason(), (millis() - this->connectedTime) / 1000 ); } if (!this->hasStaCredentials() && !this->isApEnabled()) { - Log.sinfoln(FPSTR(L_NETWORK), F("No STA credentials, start AP")); + Log.sinfoln(L_NETWORK, "No STA credentials, start AP"); WiFi.mode(WIFI_AP_STA); this->delayCallback(250); WiFi.softAP(this->apName, this->apPassword, this->apChannel); } else if (!this->isApEnabled() && millis() - this->disconnectedTime > this->failedConnectTimeout) { - Log.sinfoln(FPSTR(L_NETWORK), F("Disconnected for a long time, start AP")); + Log.sinfoln(L_NETWORK, "Disconnected for a long time, start AP"); WiFi.mode(WIFI_AP_STA); this->delayCallback(250); WiFi.softAP(this->apName, this->apPassword, this->apChannel); } else if (this->isConnecting() && millis() - this->prevReconnectingTime > this->resetConnectionTimeout) { - Log.swarningln(FPSTR(L_NETWORK), F("Connection timeout, reset wifi...")); + Log.swarningln(L_NETWORK, "Connection timeout, reset wifi..."); this->resetWifi(); NetworkConnection::reset(); this->delayCallback(250); } else if (!this->isConnecting() && this->hasStaCredentials() && (!this->prevReconnectingTime || millis() - this->prevReconnectingTime > this->reconnectInterval)) { - Log.sinfoln(FPSTR(L_NETWORK), F("Try connect...")); + Log.sinfoln(L_NETWORK, "Try connect..."); NetworkConnection::reset(); if (!this->connect(true, this->connectionTimeout)) { - Log.straceln(FPSTR(L_NETWORK), F("Connection failed. Status: %d, reason: %d, raw reason: %d"), NetworkConnection::getStatus(), NetworkConnection::getDisconnectReason(), NetworkConnection::rawDisconnectReason); + Log.straceln(L_NETWORK, "Connection failed. Status: %d, reason: %d, raw reason: %d", NetworkConnection::getStatus(), NetworkConnection::getDisconnectReason(), NetworkConnection::rawDisconnectReason); } this->prevReconnectingTime = millis(); @@ -451,7 +393,6 @@ namespace NetworkUtils { bool connected = false; bool reconnectFlag = false; - unsigned long prevArpGratuitous = 0; unsigned long prevReconnectingTime = 0; unsigned long connectedTime = 0; unsigned long disconnectedTime = 0; @@ -469,25 +410,5 @@ namespace NetworkUtils { return WiFi.setHostname(hostname); } - #ifdef ARDUINO_ARCH_ESP8266 - /** - * @brief - * https://github.com/arendst/Tasmota/blob/e6515883f0ee5451931b6280ff847b117de5a231/tasmota/tasmota_support/support_wifi.ino#L1196 - */ - static void stationKeepAliveNow(void) { - for (netif* interface = netif_list; interface != nullptr; interface = interface->next) { - if ( - (interface->flags & NETIF_FLAG_LINK_UP) - && (interface->flags & NETIF_FLAG_UP) - && interface->num == STATION_IF - && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) - ) { - etharp_gratuitous(interface); - break; - } - } - } - #endif - }; } diff --git a/lib/WebServerHandlers/StaticPage.h b/lib/WebServerHandlers/StaticPage.h index 1fe10b5..8d61f91 100644 --- a/lib/WebServerHandlers/StaticPage.h +++ b/lib/WebServerHandlers/StaticPage.h @@ -28,11 +28,9 @@ public: return this; } - #if defined(ARDUINO_ARCH_ESP32) bool canHandle(WebServer &server, HTTPMethod method, const String &uri) override { return this->canHandle(method, uri); } - #endif bool canHandle(HTTPMethod method, const String& uri) override { return method == HTTP_GET && uri.equals(this->uri) && (!this->canHandleCallback || this->canHandleCallback(method, uri)); @@ -54,17 +52,17 @@ public: } } - if (!this->eTag.isEmpty() && server.header(F("If-None-Match")).equals(this->eTag.c_str())) { + if (!this->eTag.isEmpty() && server.header("If-None-Match").equals(this->eTag.c_str())) { server.send(304); return true; } } - if (!this->path.endsWith(FPSTR(mimeTable[gz].endsWith)) && !this->fs->exists(path)) { - String pathWithGz = this->path + FPSTR(mimeTable[gz].endsWith); + if (!this->path.endsWith(mimeTable[gz].endsWith) && !this->fs->exists(path)) { + String pathWithGz = this->path + mimeTable[gz].endsWith; if (this->fs->exists(pathWithGz)) { - this->path += FPSTR(mimeTable[gz].endsWith); + this->path += mimeTable[gz].endsWith; } } @@ -78,18 +76,14 @@ public: } if (this->cacheHeader != nullptr) { - server.sendHeader(F("Cache-Control"), this->cacheHeader); + server.sendHeader("Cache-Control", this->cacheHeader); } if (server._eTagEnabled && !this->eTag.isEmpty()) { - server.sendHeader(F("ETag"), this->eTag); + server.sendHeader("ETag", this->eTag); } - #if defined(ARDUINO_ARCH_ESP8266) - server.streamFile(file, F("text/html"), method); - #else - server.streamFile(file, F("text/html"), 200); - #endif + server.streamFile(file, "text/html", 200); return true; } diff --git a/lib/WebServerHandlers/UpgradeHandler.h b/lib/WebServerHandlers/UpgradeHandler.h index 33f3e7e..bf6aaf4 100644 --- a/lib/WebServerHandlers/UpgradeHandler.h +++ b/lib/WebServerHandlers/UpgradeHandler.h @@ -132,11 +132,11 @@ public: result->status = UpgradeStatus::ERROR_ON_START; result->error = Update.errorString(); - Log.serrorln(FPSTR(L_PORTAL_OTA), "File '%s', on start: %s", fileName.c_str(), result->error.c_str()); + Log.serrorln(L_PORTAL_OTA, "File '%s', on start: %s", fileName.c_str(), result->error.c_str()); return; } - Log.sinfoln(FPSTR(L_PORTAL_OTA), "File '%s', started", fileName.c_str()); + Log.sinfoln(L_PORTAL_OTA, "File '%s', started", fileName.c_str()); } if (dataLength) { @@ -146,7 +146,7 @@ public: result->error = Update.errorString(); Log.serrorln( - FPSTR(L_PORTAL_OTA), "File '%s', on write %d bytes, %d of %d bytes", + L_PORTAL_OTA, "File '%s', on write %d bytes, %d of %d bytes", fileName.c_str(), dataLength, result->progress + dataLength, @@ -157,7 +157,7 @@ public: result->progress += dataLength; Log.sinfoln( - FPSTR(L_PORTAL_OTA), "File '%s', write %d bytes, %d of %d bytes", + L_PORTAL_OTA, "File '%s', write %d bytes, %d of %d bytes", fileName.c_str(), dataLength, result->progress, @@ -171,7 +171,7 @@ public: result->status = UpgradeStatus::SIZE_MISMATCH; Log.serrorln( - FPSTR(L_PORTAL_OTA), "File '%s', size mismatch: %d of %d bytes", + L_PORTAL_OTA, "File '%s', size mismatch: %d of %d bytes", fileName.c_str(), result->progress, result->size @@ -185,12 +185,12 @@ public: result->status = UpgradeStatus::ERROR_ON_FINISH; result->error = Update.errorString(); - Log.serrorln(FPSTR(L_PORTAL_OTA), "File '%s', on finish: %s", fileName.c_str(), result->error); + Log.serrorln(L_PORTAL_OTA, "File '%s', on finish: %s", fileName.c_str(), result->error.c_str()); return; } result->status = UpgradeStatus::SUCCESS; - Log.sinfoln(FPSTR(L_PORTAL_OTA), "File '%s': finish", fileName.c_str()); + Log.sinfoln(L_PORTAL_OTA, "File '%s': finish", fileName.c_str()); } } diff --git a/src/CrashRecorder.h b/src/CrashRecorder.h index 2a7a94e..b0a106e 100644 --- a/src/CrashRecorder.h +++ b/src/CrashRecorder.h @@ -1,20 +1,7 @@ #pragma once #include -#ifdef ARDUINO_ARCH_ESP32 - #include "esp_err.h" -#endif - -#ifdef ARDUINO_ARCH_ESP8266 - extern "C" { - #include - } - - // https://github.com/espressif/ESP8266_RTOS_SDK/blob/master/components/esp8266/include/esp_attr.h - #define _COUNTER_STRINGIFY(COUNTER) #COUNTER - #define _SECTION_ATTR_IMPL(SECTION, COUNTER) __attribute__((section(SECTION "." _COUNTER_STRINGIFY(COUNTER)))) - #define __NOINIT_ATTR _SECTION_ATTR_IMPL(".noinit", __COUNTER__) -#endif +#include "esp_err.h" namespace CrashRecorder { typedef struct { @@ -42,7 +29,6 @@ namespace CrashRecorder { uint8_t backtraceMaxLength = sizeof(backtrace.data) / sizeof(*backtrace.data); uint8_t epcMaxLength = sizeof(epc.data) / sizeof(*epc.data); - #ifdef ARDUINO_ARCH_ESP32 void IRAM_ATTR panicHandler(arduino_panic_info_t *info, void *arg) {; ext.core = info->core; ext.heap = ESP.getFreeHeap(); @@ -69,7 +55,6 @@ namespace CrashRecorder { epc.length = 0; } } - #endif void init() { if (backtrace.length > backtraceMaxLength) { @@ -80,53 +65,6 @@ namespace CrashRecorder { epc.length = 0; } - #ifdef ARDUINO_ARCH_ESP32 set_arduino_panic_handler(panicHandler, nullptr); - #endif } } - -#ifdef ARDUINO_ARCH_ESP8266 -extern "C" void custom_crash_callback(struct rst_info *info, uint32_t stack, uint32_t stack_end) { - uint8_t _length = 0; - - CrashRecorder::ext.core = 0; - CrashRecorder::ext.heap = ESP.getFreeHeap(); - CrashRecorder::ext.uptime = millis() / 1000u; - - // Backtrace - CrashRecorder::backtrace.continues = false; - uint32_t value; - for (uint32_t i = stack; i < stack_end; i += 4) { - value = *((uint32_t*) i); // NOLINT - - // keep only addresses in code area - if ((value >= 0x40000000) && (value < 0x40300000)) { - if (_length >= CrashRecorder::backtraceMaxLength) { - CrashRecorder::backtrace.continues = true; - break; - } - - CrashRecorder::backtrace.data[_length++] = value; - } - } - - CrashRecorder::backtrace.length = _length; - - // EPC - _length = 0; - if (info->epc1 > 0) { - CrashRecorder::epc.data[_length++] = info->epc1; - } - - if (info->epc2 > 0) { - CrashRecorder::epc.data[_length++] = info->epc2; - } - - if (info->epc3 > 0) { - CrashRecorder::epc.data[_length++] = info->epc3; - } - - CrashRecorder::epc.length = _length; -} -#endif diff --git a/src/HaHelper.h b/src/HaHelper.h index 0e334c9..3334081 100644 --- a/src/HaHelper.h +++ b/src/HaHelper.h @@ -9,11 +9,11 @@ public: static const char AVAILABILITY_SENSOR_CONN[]; void updateCachedTopics() { - this->statusTopic = this->getDeviceTopic(F("status")); - this->stateTopic = this->getDeviceTopic(F("state")); - this->setStateTopic = this->getDeviceTopic(F("state/set")); - this->settingsTopic = this->getDeviceTopic(F("settings")); - this->setSettingsTopic = this->getDeviceTopic(F("settings/set")); + this->statusTopic = this->getDeviceTopic("status"); + this->stateTopic = this->getDeviceTopic("state"); + this->setStateTopic = this->getDeviceTopic("state/set"); + this->settingsTopic = this->getDeviceTopic("settings"); + this->setSettingsTopic = this->getDeviceTopic("settings/set"); } void setExpireAfter(unsigned short value) { @@ -37,68 +37,68 @@ public: case Sensors::Purpose::DHW_RETURN_TEMP: case Sensors::Purpose::EXHAUST_TEMP: case Sensors::Purpose::TEMPERATURE: - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; if (sSensor.type == Sensors::Type::MANUAL) { - doc[FPSTR(HA_MIN)] = -99; - doc[FPSTR(HA_MAX)] = 99; + doc[HA_MIN] = -99; + doc[HA_MAX] = 99; } } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; if (sSensor.type == Sensors::Type::MANUAL) { - doc[FPSTR(HA_MIN)] = -147; - doc[FPSTR(HA_MAX)] = 211; + doc[HA_MIN] = -147; + doc[HA_MAX] = 211; } } break; case Sensors::Purpose::DHW_FLOW_RATE: - doc[FPSTR(HA_DEVICE_CLASS)] = F("volume_flow_rate"); + doc[HA_DEVICE_CLASS] = "volume_flow_rate"; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_L_MIN); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_L_MIN; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_GAL_MIN); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_GAL_MIN; } break; case Sensors::Purpose::MODULATION_LEVEL: case Sensors::Purpose::POWER_FACTOR: - doc[FPSTR(HA_DEVICE_CLASS)] = F("power_factor"); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); + doc[HA_DEVICE_CLASS] = "power_factor"; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_PERCENT; break; case Sensors::Purpose::POWER: - doc[FPSTR(HA_DEVICE_CLASS)] = F("power"); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("kW"); + doc[HA_DEVICE_CLASS] = "power"; + doc[HA_UNIT_OF_MEASUREMENT] = "kW"; break; case Sensors::Purpose::FAN_SPEED: - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("RPM"); + doc[HA_UNIT_OF_MEASUREMENT] = "RPM"; break; case Sensors::Purpose::CO2: - doc[FPSTR(HA_DEVICE_CLASS)] = F("carbon_dioxide"); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("ppm"); + doc[HA_DEVICE_CLASS] = "carbon_dioxide"; + doc[HA_UNIT_OF_MEASUREMENT] = "ppm"; break; case Sensors::Purpose::PRESSURE: - doc[FPSTR(HA_DEVICE_CLASS)] = F("pressure"); + doc[HA_DEVICE_CLASS] = "pressure"; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("bar"); + doc[HA_UNIT_OF_MEASUREMENT] = "bar"; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("psi"); + doc[HA_UNIT_OF_MEASUREMENT] = "psi"; } break; case Sensors::Purpose::HUMIDITY: - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_HUMIDITY); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); + doc[HA_DEVICE_CLASS] = S_HUMIDITY; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_PERCENT; break; default: @@ -108,60 +108,60 @@ public: // set icon switch (sSensor.purpose) { case Sensors::Purpose::OUTDOOR_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:home-thermometer-outline"); + doc[HA_ICON] = "mdi:home-thermometer-outline"; break; case Sensors::Purpose::INDOOR_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:home-thermometer"); + doc[HA_ICON] = "mdi:home-thermometer"; break; case Sensors::Purpose::HEATING_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:radiator"); + doc[HA_ICON] = "mdi:radiator"; break; case Sensors::Purpose::HEATING_RETURN_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:heating-coil"); + doc[HA_ICON] = "mdi:heating-coil"; break; case Sensors::Purpose::DHW_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:faucet"); + doc[HA_ICON] = "mdi:faucet"; break; case Sensors::Purpose::DHW_RETURN_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:heating-coil"); + doc[HA_ICON] = "mdi:heating-coil"; break; case Sensors::Purpose::EXHAUST_TEMP: - doc[FPSTR(HA_ICON)] = F("mdi:smoke"); + doc[HA_ICON] = "mdi:smoke"; break; case Sensors::Purpose::TEMPERATURE: - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-lines"); + doc[HA_ICON] = "mdi:thermometer-lines"; break; case Sensors::Purpose::DHW_FLOW_RATE: - doc[FPSTR(HA_ICON)] = F("mdi:faucet"); + doc[HA_ICON] = "mdi:faucet"; break; case Sensors::Purpose::MODULATION_LEVEL: - doc[FPSTR(HA_ICON)] = F("mdi:fire-circle"); + doc[HA_ICON] = "mdi:fire-circle"; break; case Sensors::Purpose::POWER_FACTOR: case Sensors::Purpose::POWER: - doc[FPSTR(HA_ICON)] = F("mdi:chart-bar"); + doc[HA_ICON] = "mdi:chart-bar"; break; case Sensors::Purpose::FAN_SPEED: - doc[FPSTR(HA_ICON)] = F("mdi:fan"); + doc[HA_ICON] = "mdi:fan"; break; case Sensors::Purpose::PRESSURE: - doc[FPSTR(HA_ICON)] = F("mdi:gauge"); + doc[HA_ICON] = "mdi:gauge"; break; case Sensors::Purpose::HUMIDITY: - doc[FPSTR(HA_ICON)] = F("mdi:water-percent"); + doc[HA_ICON] = "mdi:water-percent"; break; default: @@ -171,8 +171,8 @@ public: String objId = Sensors::makeObjectId(sSensor.name); // state topic - doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic( - F("sensors"), + doc[HA_STATE_TOPIC] = this->getDeviceTopic( + "sensors", objId.c_str() ); @@ -181,56 +181,56 @@ public: if (sSensor.type == Sensors::Type::BLUETOOTH || sSensor.type == Sensors::Type::DHT11 || sSensor.type == Sensors::Type::DHT22) { // available state topic - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)]; - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_SENSOR_CONN, true); + doc[HA_AVAILABILITY][1][HA_TOPIC] = doc[HA_STATE_TOPIC]; + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_SENSOR_CONN, true); String sName = sSensor.name; switch (vType) { case Sensors::ValueType::TEMPERATURE: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, F("temp")); - sName += F(" temperature"); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, "temp"); + sName += " temperature"; - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; } - doc[FPSTR(HA_NAME)] = sName; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.temperature|float(0)|round(2) }}"); + doc[HA_NAME] = sName; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.temperature|float(0)|round(2) }}"; break; case Sensors::ValueType::HUMIDITY: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_HUMIDITY)); - sName += F(" humidity"); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_HUMIDITY); + sName += " humidity"; - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_HUMIDITY); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); - doc[FPSTR(HA_NAME)] = sName; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.humidity|float(0)|round(2) }}"); + doc[HA_DEVICE_CLASS] = S_HUMIDITY; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_PERCENT; + doc[HA_NAME] = sName; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.humidity|float(0)|round(2) }}"; break; case Sensors::ValueType::BATTERY: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_BATTERY)); - sName += F(" battery"); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_BATTERY); + sName += " battery"; - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_BATTERY); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); - doc[FPSTR(HA_NAME)] = sName; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.battery|float(0)|round(2) }}"); + doc[HA_DEVICE_CLASS] = S_BATTERY; + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_PERCENT; + doc[HA_NAME] = sName; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.battery|float(0)|round(2) }}"; break; case Sensors::ValueType::RSSI: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_RSSI)); - sName += F(" RSSI"); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_RSSI); + sName += " RSSI"; - doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength"); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("dBm"); - doc[FPSTR(HA_NAME)] = sName; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.rssi|float(0)|round(2) }}"); + doc[HA_DEVICE_CLASS] = "signal_strength"; + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_UNIT_OF_MEASUREMENT] = "dBm"; + doc[HA_NAME] = sName; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.rssi|float(0)|round(2) }}"; break; default: @@ -238,49 +238,49 @@ public: } } else if (sSensor.type == Sensors::Type::MANUAL) { - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_STEP)] = 0.01f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_STEP] = 0.01f; + doc[HA_MODE] = HA_MODE_BOX; - doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic( - F("sensors"), + doc[HA_COMMAND_TOPIC] = this->getDeviceTopic( + "sensors", objId.c_str(), - F("set") + "set" ); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"value\": {{ value }}}"); + doc[HA_COMMAND_TEMPLATE] = "{\"value\": {{ value }}}"; - doc[FPSTR(HA_NAME)] = sSensor.name; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}"); + doc[HA_NAME] = sSensor.name; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.value|float(0)|round(2) }}"; } else { // available state topic - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)]; - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_SENSOR_CONN, true); + doc[HA_AVAILABILITY][1][HA_TOPIC] = doc[HA_STATE_TOPIC]; + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_SENSOR_CONN, true); - doc[FPSTR(HA_NAME)] = sSensor.name; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}"); + doc[HA_NAME] = sSensor.name; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.value|float(0)|round(2) }}"; } // object id's - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(objId.c_str()); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix( + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(objId.c_str()); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix( sSensor.type == Sensors::Type::MANUAL - ? FPSTR(HA_ENTITY_NUMBER) - : FPSTR(HA_ENTITY_SENSOR), + ? HA_ENTITY_NUMBER + : HA_ENTITY_SENSOR, objId.c_str() ); const String& configTopic = this->makeConfigTopic( - sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR), + sSensor.type == Sensors::Type::MANUAL ? HA_ENTITY_NUMBER : HA_ENTITY_SENSOR, objId.c_str() ); objId.clear(); - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_STATE_CLASS)] = FPSTR(HA_STATE_CLASS_MEASUREMENT); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_STATE_CLASS] = HA_STATE_CLASS_MEASUREMENT; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); return this->publish(configTopic.c_str(), doc); @@ -292,19 +292,19 @@ public: if (sSensor.type == Sensors::Type::BLUETOOTH) { switch (vType) { case Sensors::ValueType::TEMPERATURE: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, F("temp")); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, "temp"); break; case Sensors::ValueType::HUMIDITY: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_HUMIDITY)); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_HUMIDITY); break; case Sensors::ValueType::BATTERY: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_BATTERY)); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_BATTERY); break; case Sensors::ValueType::RSSI: - Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_RSSI)); + Sensors::makeObjectIdWithSuffix(objId, sSensor.name, S_RSSI); break; default: @@ -316,7 +316,7 @@ public: } const String& configTopic = this->makeConfigTopic( - sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR), + sSensor.type == Sensors::Type::MANUAL ? HA_ENTITY_NUMBER : HA_ENTITY_SENSOR, objId.c_str() ); objId.clear(); @@ -326,15 +326,15 @@ public: bool publishConnectionDynamicSensor(Sensors::Settings& sSensor, bool enabledByDefault = true) { JsonDocument doc; - String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected")); + String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, "connected"); // object id's - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(objId.c_str()); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), objId.c_str()); + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(objId.c_str()); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, objId.c_str()); // state topic - doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic( - F("sensors"), + doc[HA_STATE_TOPIC] = this->getDeviceTopic( + "sensors", Sensors::makeObjectId(sSensor.name).c_str() ); @@ -342,21 +342,21 @@ public: { String sName = sSensor.name; sName.trim(); - sName += F(" connected"); + sName += " connected"; - doc[FPSTR(HA_NAME)] = sName; + doc[HA_NAME] = sName; } - const String& configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), objId.c_str()); + const String& configTopic = this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, objId.c_str()); objId.clear(); - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("connectivity"); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.connected, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "connectivity"; + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.connected, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); return this->publish(configTopic.c_str(), doc); @@ -364,8 +364,8 @@ public: bool deleteConnectionDynamicSensor(Sensors::Settings& sSensor) { const String& configTopic = this->makeConfigTopic( - FPSTR(HA_ENTITY_BINARY_SENSOR), - Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected")).c_str() + HA_ENTITY_BINARY_SENSOR, + Sensors::makeObjectIdWithSuffix(sSensor.name, "connected").c_str() ); return this->publish(configTopic.c_str()); @@ -373,15 +373,15 @@ public: bool publishSignalQualityDynamicSensor(Sensors::Settings& sSensor, bool enabledByDefault = true) { JsonDocument doc; - String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality")); + String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, "signal_quality"); // object id's - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(objId.c_str()); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SENSOR), objId.c_str()); + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(objId.c_str()); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SENSOR, objId.c_str()); // state topic - doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic( - F("sensors"), + doc[HA_STATE_TOPIC] = this->getDeviceTopic( + "sensors", Sensors::makeObjectId(sSensor.name).c_str() ); @@ -389,24 +389,24 @@ public: { String sName = sSensor.name; sName.trim(); - sName += F(" signal quality"); + sName += " signal quality"; - doc[FPSTR(HA_NAME)] = sName; + doc[HA_NAME] = sName; } - const String& configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), objId.c_str()); + const String& configTopic = this->makeConfigTopic(HA_ENTITY_SENSOR, objId.c_str()); objId.clear(); - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - //doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength"); - doc[FPSTR(HA_STATE_CLASS)] = FPSTR(HA_STATE_CLASS_MEASUREMENT); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); - doc[FPSTR(HA_ICON)] = F("mdi:signal"); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.signalQuality|float(0)|round(0) }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + //doc[HA_DEVICE_CLASS] = "signal_strength"; + doc[HA_STATE_CLASS] = HA_STATE_CLASS_MEASUREMENT; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_PERCENT; + doc[HA_ICON] = "mdi:signal"; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.signalQuality|float(0)|round(0) }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); return this->publish(configTopic.c_str(), doc); @@ -414,8 +414,8 @@ public: bool deleteSignalQualityDynamicSensor(Sensors::Settings& sSensor) { const String& configTopic = this->makeConfigTopic( - FPSTR(HA_ENTITY_SENSOR), - Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality")).c_str() + HA_ENTITY_SENSOR, + Sensors::makeObjectIdWithSuffix(sSensor.name, "signal_quality").c_str() ); return this->publish(configTopic.c_str()); @@ -424,952 +424,952 @@ public: bool publishSwitchHeatingTurbo(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_turbo")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SWITCH), F("heating_turbo")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Turbo heating"); - doc[FPSTR(HA_ICON)] = F("mdi:rocket-launch-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_STATE_ON)] = true; - doc[FPSTR(HA_STATE_OFF)] = false; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.turbo }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_PAYLOAD_ON)] = F("{\"heating\": {\"turbo\" : true}}"); - doc[FPSTR(HA_PAYLOAD_OFF)] = F("{\"heating\": {\"turbo\" : false}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_turbo"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SWITCH, "heating_turbo"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Turbo heating"; + doc[HA_ICON] = "mdi:rocket-launch-outline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_STATE_ON] = true; + doc[HA_STATE_OFF] = false; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.turbo }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_PAYLOAD_ON] = "{\"heating\": {\"turbo\" : true}}"; + doc[HA_PAYLOAD_OFF] = "{\"heating\": {\"turbo\" : false}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SWITCH), F("heating_turbo")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SWITCH, "heating_turbo").c_str(), doc); } bool publishSwitchHeatingHysteresis(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_hysteresis")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SWITCH), F("heating_hysteresis")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Use heating hysteresis"); - doc[FPSTR(HA_ICON)] = F("mdi:altimeter"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_STATE_ON)] = true; - doc[FPSTR(HA_STATE_OFF)] = false; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.hysteresis.enabled }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_PAYLOAD_ON)] = F("{\"heating\": {\"hysteresis\" : {\"enabled\" : true}}}"); - doc[FPSTR(HA_PAYLOAD_OFF)] = F("{\"heating\": {\"hysteresis\" : {\"enabled\" : false}}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_hysteresis"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SWITCH, "heating_hysteresis"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Use heating hysteresis"; + doc[HA_ICON] = "mdi:altimeter"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_STATE_ON] = true; + doc[HA_STATE_OFF] = false; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.hysteresis.enabled }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_PAYLOAD_ON] = "{\"heating\": {\"hysteresis\" : {\"enabled\" : true}}}"; + doc[HA_PAYLOAD_OFF] = "{\"heating\": {\"hysteresis\" : {\"enabled\" : false}}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SWITCH), F("heating_hysteresis")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SWITCH, "heating_hysteresis").c_str(), doc); } bool publishInputHeatingHysteresis(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_hysteresis")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("heating_hysteresis")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_hysteresis"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "heating_hysteresis"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; } - doc[FPSTR(HA_NAME)] = F("Heating hysteresis"); - doc[FPSTR(HA_ICON)] = F("mdi:altimeter"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.hysteresis.value|float(0)|round(2) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"heating\": {\"hysteresis\" : {\"value\" : {{ value }}}}}"); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 15; - doc[FPSTR(HA_STEP)] = 0.01f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "Heating hysteresis"; + doc[HA_ICON] = "mdi:altimeter"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.hysteresis.value|float(0)|round(2) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"heating\": {\"hysteresis\" : {\"value\" : {{ value }}}}}"; + doc[HA_MIN] = 0; + doc[HA_MAX] = 15; + doc[HA_STEP] = 0.01f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("heating_hysteresis")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "heating_hysteresis").c_str(), doc); } bool publishInputHeatingTurboFactor(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_turbo_factor")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("heating_turbo_factor")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = F("power_factor"); - doc[FPSTR(HA_NAME)] = F("Heating turbo factor"); - doc[FPSTR(HA_ICON)] = F("mdi:multiplication-box"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.turboFactor|float(0)|round(2) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"heating\": {\"turboFactor\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 1.5; - doc[FPSTR(HA_MAX)] = 10; - doc[FPSTR(HA_STEP)] = 0.01f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_turbo_factor"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "heating_turbo_factor"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = "power_factor"; + doc[HA_NAME] = "Heating turbo factor"; + doc[HA_ICON] = "mdi:multiplication-box"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.turboFactor|float(0)|round(2) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"heating\": {\"turboFactor\" : {{ value }}}}"; + doc[HA_MIN] = 1.5; + doc[HA_MAX] = 10; + doc[HA_STEP] = 0.01f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("heating_turbo_factor")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "heating_turbo_factor").c_str(), doc); } bool publishInputHeatingMinTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_min_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("heating_min_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_min_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "heating_min_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 99; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = 0; + doc[HA_MAX] = 99; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = 32; - doc[FPSTR(HA_MAX)] = 211; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = 32; + doc[HA_MAX] = 211; } - doc[FPSTR(HA_NAME)] = F("Heating min temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-down"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.minTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"heating\": {\"minTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "Heating min temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-down"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.minTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"heating\": {\"minTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("heating_min_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "heating_min_temp").c_str(), doc); } bool publishInputHeatingMaxTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating_max_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("heating_max_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating_max_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "heating_max_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = 1; - doc[FPSTR(HA_MAX)] = 100; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = 1; + doc[HA_MAX] = 100; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = 33; - doc[FPSTR(HA_MAX)] = 212; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = 33; + doc[HA_MAX] = 212; } - doc[FPSTR(HA_NAME)] = F("Heating max temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-up"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.heating.maxTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"heating\": {\"maxTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "Heating max temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-up"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.heating.maxTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"heating\": {\"maxTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("heating_max_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "heating_max_temp").c_str(), doc); } bool publishInputDhwMinTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("dhw_min_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("dhw_min_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("dhw_min_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "dhw_min_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 99; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = 0; + doc[HA_MAX] = 99; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = 32; - doc[FPSTR(HA_MAX)] = 211; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = 32; + doc[HA_MAX] = 211; } - doc[FPSTR(HA_NAME)] = F("DHW min temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-down"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.dhw.minTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"dhw\": {\"minTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "DHW min temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-down"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.dhw.minTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"dhw\": {\"minTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("dhw_min_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "dhw_min_temp").c_str(), doc); } bool publishInputDhwMaxTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("dhw_max_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("dhw_max_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("dhw_max_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "dhw_max_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = 1; - doc[FPSTR(HA_MAX)] = 100; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = 1; + doc[HA_MAX] = 100; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = 33; - doc[FPSTR(HA_MAX)] = 212; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = 33; + doc[HA_MAX] = 212; } - doc[FPSTR(HA_NAME)] = F("DHW max temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-up"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.dhw.maxTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"dhw\": {\"maxTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "DHW max temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-up"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.dhw.maxTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"dhw\": {\"maxTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("dhw_max_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "dhw_max_temp").c_str(), doc); } bool publishSwitchPid(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SWITCH), F("pid")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("PID"); - doc[FPSTR(HA_ICON)] = F("mdi:chart-bar-stacked"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_STATE_ON)] = true; - doc[FPSTR(HA_STATE_OFF)] = false; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.enabled }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_PAYLOAD_ON)] = F("{\"pid\": {\"enabled\" : true}}"); - doc[FPSTR(HA_PAYLOAD_OFF)] = F("{\"pid\": {\"enabled\" : false}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SWITCH, "pid"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "PID"; + doc[HA_ICON] = "mdi:chart-bar-stacked"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_STATE_ON] = true; + doc[HA_STATE_OFF] = false; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.enabled }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_PAYLOAD_ON] = "{\"pid\": {\"enabled\" : true}}"; + doc[HA_PAYLOAD_OFF] = "{\"pid\": {\"enabled\" : false}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SWITCH), F("pid")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SWITCH, "pid").c_str(), doc); } bool publishInputPidFactorP(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_p")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_p")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("PID factor P"); - doc[FPSTR(HA_ICON)] = F("mdi:alpha-p-circle-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.p_factor|float(0)|round(3) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"p_factor\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0.1f; - doc[FPSTR(HA_MAX)] = 1000; - doc[FPSTR(HA_STEP)] = 0.1f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_p"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_p"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "PID factor P"; + doc[HA_ICON] = "mdi:alpha-p-circle-outline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.p_factor|float(0)|round(3) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"p_factor\" : {{ value }}}}"; + doc[HA_MIN] = 0.1f; + doc[HA_MAX] = 1000; + doc[HA_STEP] = 0.1f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_p_factor")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_p_factor").c_str(), doc); } bool publishInputPidFactorI(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_i")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_i")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("PID factor I"); - doc[FPSTR(HA_ICON)] = F("mdi:alpha-i-circle-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.i_factor|float(0)|round(4) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"i_factor\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 100; - doc[FPSTR(HA_STEP)] = 0.001f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_i"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_i"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "PID factor I"; + doc[HA_ICON] = "mdi:alpha-i-circle-outline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.i_factor|float(0)|round(4) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"i_factor\" : {{ value }}}}"; + doc[HA_MIN] = 0; + doc[HA_MAX] = 100; + doc[HA_STEP] = 0.001f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_i_factor")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_i_factor").c_str(), doc); } bool publishInputPidFactorD(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_d")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_d")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("PID factor D"); - doc[FPSTR(HA_ICON)] = F("mdi:alpha-d-circle-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.d_factor|float(0)|round(3) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"d_factor\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 100000; - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_d"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_d"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "PID factor D"; + doc[HA_ICON] = "mdi:alpha-d-circle-outline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.d_factor|float(0)|round(3) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"d_factor\" : {{ value }}}}"; + doc[HA_MIN] = 0; + doc[HA_MAX] = 100000; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_d_factor")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_d_factor").c_str(), doc); } bool publishInputPidDt(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_dt")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_dt")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = F("duration"); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("s"); - doc[FPSTR(HA_NAME)] = F("PID DT"); - doc[FPSTR(HA_ICON)] = F("mdi:timer-cog-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.dt|int(0) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"dt\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 30; - doc[FPSTR(HA_MAX)] = 1800; - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_dt"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_dt"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = "duration"; + doc[HA_UNIT_OF_MEASUREMENT] = "s"; + doc[HA_NAME] = "PID DT"; + doc[HA_ICON] = "mdi:timer-cog-outline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.dt|int(0) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"dt\" : {{ value }}}}"; + doc[HA_MIN] = 30; + doc[HA_MAX] = 1800; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_dt")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_dt").c_str(), doc); } bool publishInputPidMinTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_min_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_min_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_min_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_min_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = -99; - doc[FPSTR(HA_MAX)] = 99; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = -99; + doc[HA_MAX] = 99; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = -146; - doc[FPSTR(HA_MAX)] = 211; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = -146; + doc[HA_MAX] = 211; } - doc[FPSTR(HA_NAME)] = F("PID min temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-down"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.minTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"minTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "PID min temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-down"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.minTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"minTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_min_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_min_temp").c_str(), doc); } bool publishInputPidMaxTemp(UnitSystem unit = UnitSystem::METRIC, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("pid_max_temp")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("pid_max_temp")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("pid_max_temp"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "pid_max_temp"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); - doc[FPSTR(HA_MIN)] = 1; - doc[FPSTR(HA_MAX)] = 100; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_C; + doc[HA_MIN] = 1; + doc[HA_MAX] = 100; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_F); - doc[FPSTR(HA_MIN)] = 1; - doc[FPSTR(HA_MAX)] = 212; + doc[HA_UNIT_OF_MEASUREMENT] = HA_UNIT_OF_MEASUREMENT_F; + doc[HA_MIN] = 1; + doc[HA_MAX] = 212; } - doc[FPSTR(HA_NAME)] = F("PID max temp"); - doc[FPSTR(HA_ICON)] = F("mdi:thermometer-chevron-up"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.pid.maxTemp|float(0)|round(1) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"pid\": {\"maxTemp\" : {{ value }}}}"); - doc[FPSTR(HA_STEP)] = 1; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_NAME] = "PID max temp"; + doc[HA_ICON] = "mdi:thermometer-chevron-up"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.pid.maxTemp|float(0)|round(1) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"pid\": {\"maxTemp\" : {{ value }}}}"; + doc[HA_STEP] = 1; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("pid_max_temp")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "pid_max_temp").c_str(), doc); } bool publishSwitchEquitherm(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("equitherm")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SWITCH), F("equitherm")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Equitherm"); - doc[FPSTR(HA_ICON)] = F("mdi:sun-snowflake-variant"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_STATE_ON)] = true; - doc[FPSTR(HA_STATE_OFF)] = false; - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.equitherm.enabled }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_PAYLOAD_ON)] = F("{\"equitherm\": {\"enabled\" : true}}"); - doc[FPSTR(HA_PAYLOAD_OFF)] = F("{\"equitherm\": {\"enabled\" : false}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("equitherm"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SWITCH, "equitherm"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Equitherm"; + doc[HA_ICON] = "mdi:sun-snowflake-variant"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_STATE_ON] = true; + doc[HA_STATE_OFF] = false; + doc[HA_VALUE_TEMPLATE] = "{{ value_json.equitherm.enabled }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_PAYLOAD_ON] = "{\"equitherm\": {\"enabled\" : true}}"; + doc[HA_PAYLOAD_OFF] = "{\"equitherm\": {\"enabled\" : false}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SWITCH), F("equitherm")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SWITCH, "equitherm").c_str(), doc); } bool publishInputEquithermSlope(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("equitherm_slope")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("equitherm_slope")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Equitherm slope"); - doc[FPSTR(HA_ICON)] = F("mdi:slope-uphill"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.equitherm.slope|float(0)|round(3) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"equitherm\": {\"slope\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0.001f; - doc[FPSTR(HA_MAX)] = 10; - doc[FPSTR(HA_STEP)] = 0.001f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("equitherm_slope"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "equitherm_slope"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Equitherm slope"; + doc[HA_ICON] = "mdi:slope-uphill"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.equitherm.slope|float(0)|round(3) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"equitherm\": {\"slope\" : {{ value }}}}"; + doc[HA_MIN] = 0.001f; + doc[HA_MAX] = 10; + doc[HA_STEP] = 0.001f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_slope")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "equitherm_slope").c_str(), doc); } bool publishInputEquithermExponent(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("equitherm_exponent")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("equitherm_exponent")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Equitherm exponent"); - doc[FPSTR(HA_ICON)] = F("mdi:exponent"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.equitherm.exponent|float(0)|round(3) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"equitherm\": {\"exponent\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0.1; - doc[FPSTR(HA_MAX)] = 2; - doc[FPSTR(HA_STEP)] = 0.001f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("equitherm_exponent"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "equitherm_exponent"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Equitherm exponent"; + doc[HA_ICON] = "mdi:exponent"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.equitherm.exponent|float(0)|round(3) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"equitherm\": {\"exponent\" : {{ value }}}}"; + doc[HA_MIN] = 0.1; + doc[HA_MAX] = 2; + doc[HA_STEP] = 0.001f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_exponent")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "equitherm_exponent").c_str(), doc); } bool publishInputEquithermShift(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("equitherm_shift")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("equitherm_shift")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE); - doc[FPSTR(HA_NAME)] = F("Equitherm shift"); - doc[FPSTR(HA_ICON)] = F("mdi:chart-areaspline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.equitherm.shift|float(0)|round(2) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"equitherm\": {\"shift\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = -15; - doc[FPSTR(HA_MAX)] = 15; - doc[FPSTR(HA_STEP)] = 0.01f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("equitherm_shift"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "equitherm_shift"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_TEMPERATURE; + doc[HA_NAME] = "Equitherm shift"; + doc[HA_ICON] = "mdi:chart-areaspline"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.equitherm.shift|float(0)|round(2) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"equitherm\": {\"shift\" : {{ value }}}}"; + doc[HA_MIN] = -15; + doc[HA_MAX] = 15; + doc[HA_STEP] = 0.01f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_shift")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "equitherm_shift").c_str(), doc); } bool publishInputEquithermTargetDiffFactor(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.pid.enabled, 'offline', 'online') }}"); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("equitherm_target_diff_factor")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_NUMBER), F("equitherm_target_diff_factor")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_NAME)] = F("Equitherm target diff factor"); - doc[FPSTR(HA_ICON)] = F("mdi:chart-timeline-variant-shimmer"); - doc[FPSTR(HA_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.equitherm.targetDiffFactor|float(0)|round(3) }}"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"equitherm\": {\"targetDiffFactor\" : {{ value }}}}"); - doc[FPSTR(HA_MIN)] = 0; - doc[FPSTR(HA_MAX)] = 10; - doc[FPSTR(HA_STEP)] = 0.001f; - doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->settingsTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = "{{ iif(value_json.pid.enabled, 'offline', 'online') }}"; + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("equitherm_target_diff_factor"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_NUMBER, "equitherm_target_diff_factor"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_NAME] = "Equitherm target diff factor"; + doc[HA_ICON] = "mdi:chart-timeline-variant-shimmer"; + doc[HA_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.equitherm.targetDiffFactor|float(0)|round(3) }}"; + doc[HA_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"equitherm\": {\"targetDiffFactor\" : {{ value }}}}"; + doc[HA_MIN] = 0; + doc[HA_MAX] = 10; + doc[HA_STEP] = 0.001f; + doc[HA_MODE] = HA_MODE_BOX; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_target_diff_factor")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "equitherm_target_diff_factor").c_str(), doc); } bool publishStatusState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("status")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("status")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("problem"); - doc[FPSTR(HA_NAME)] = F("Status"); - doc[FPSTR(HA_ICON)] = F("mdi:list-status"); - doc[FPSTR(HA_STATE_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value == 'online', 'OFF', 'ON') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = 60; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("status"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "status"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "problem"; + doc[HA_NAME] = "Status"; + doc[HA_ICON] = "mdi:list-status"; + doc[HA_STATE_TOPIC] = this->statusTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value == 'online', 'OFF', 'ON') }}"; + doc[HA_EXPIRE_AFTER] = 60; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("status")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "status").c_str(), doc); } bool publishEmergencyState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("emergency")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("emergency")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("problem"); - doc[FPSTR(HA_NAME)] = F("Emergency"); - doc[FPSTR(HA_ICON)] = F("mdi:alert-rhombus-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.master.emergency.state, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("emergency"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "emergency"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "problem"; + doc[HA_NAME] = "Emergency"; + doc[HA_ICON] = "mdi:alert-rhombus-outline"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.master.emergency.state, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("emergency")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "emergency").c_str(), doc); } bool publishOpenthermConnectedState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("ot_status")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("ot_status")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("connectivity"); - doc[FPSTR(HA_NAME)] = F("Opentherm status"); - doc[FPSTR(HA_ICON)] = F("mdi:list-status"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.connected, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("ot_status"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "ot_status"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "connectivity"; + doc[HA_NAME] = "Opentherm status"; + doc[HA_ICON] = "mdi:list-status"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.connected, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("ot_status")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "ot_status").c_str(), doc); } bool publishHeatingState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("heating")); - doc[FPSTR(HA_DEVICE_CLASS)] = F("running"); - doc[FPSTR(HA_NAME)] = F("Heating"); - doc[FPSTR(HA_ICON)] = F("mdi:radiator"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.heating.active, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_OT_CONN, true); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "heating"); + doc[HA_DEVICE_CLASS] = "running"; + doc[HA_NAME] = "Heating"; + doc[HA_ICON] = "mdi:radiator"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.heating.active, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("heating")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "heating").c_str(), doc); } bool publishDhwState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("dhw")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("dhw")); - doc[FPSTR(HA_DEVICE_CLASS)] = F("running"); - doc[FPSTR(HA_NAME)] = F("DHW"); - doc[FPSTR(HA_ICON)] = F("mdi:faucet"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.dhw.active, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_OT_CONN, true); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("dhw"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "dhw"); + doc[HA_DEVICE_CLASS] = "running"; + doc[HA_NAME] = "DHW"; + doc[HA_ICON] = "mdi:faucet"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.dhw.active, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("dhw")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "dhw").c_str(), doc); } bool publishFlameState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("flame")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("flame")); - doc[FPSTR(HA_DEVICE_CLASS)] = F("running"); - doc[FPSTR(HA_NAME)] = F("Flame"); - doc[FPSTR(HA_ICON)] = F("mdi:gas-burner"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.flame, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_OT_CONN, true); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("flame"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "flame"); + doc[HA_DEVICE_CLASS] = "running"; + doc[HA_NAME] = "Flame"; + doc[HA_ICON] = "mdi:gas-burner"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.flame, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("flame")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "flame").c_str(), doc); } bool publishFaultState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("fault")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("fault")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("problem"); - doc[FPSTR(HA_NAME)] = F("Fault"); - doc[FPSTR(HA_ICON)] = F("mdi:alert-remove-outline"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.fault.active, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_OT_CONN, true); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("fault"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "fault"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "problem"; + doc[HA_NAME] = "Fault"; + doc[HA_ICON] = "mdi:alert-remove-outline"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.fault.active, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("fault")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "fault").c_str(), doc); } bool publishDiagState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = JsonString(AVAILABILITY_OT_CONN, true); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC)); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC)); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("problem"); - doc[FPSTR(HA_NAME)] = F("Diagnostic"); - doc[FPSTR(HA_ICON)] = F("mdi:account-wrench"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.diag.active, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = JsonString(AVAILABILITY_OT_CONN, true); + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(HA_ENTITY_CATEGORY_DIAGNOSTIC); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, HA_ENTITY_CATEGORY_DIAGNOSTIC); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "problem"; + doc[HA_NAME] = "Diagnostic"; + doc[HA_ICON] = "mdi:account-wrench"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.diag.active, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC)).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, HA_ENTITY_CATEGORY_DIAGNOSTIC).c_str(), doc); } bool publishExternalPumpState(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("ext_pump")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BINARY_SENSOR), F("ext_pump")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("running"); - doc[FPSTR(HA_NAME)] = F("External pump"); - doc[FPSTR(HA_ICON)] = F("mdi:pump"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.master.externalPump.state, 'ON', 'OFF') }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("ext_pump"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BINARY_SENSOR, "ext_pump"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "running"; + doc[HA_NAME] = "External pump"; + doc[HA_ICON] = "mdi:pump"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ iif(value_json.master.externalPump.state, 'ON', 'OFF') }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("ext_pump")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "ext_pump").c_str(), doc); } bool publishFaultCode(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.connected and value_json.slave.fault.active, 'online', 'offline') }}"); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("fault_code")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SENSOR), F("fault_code")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_NAME)] = F("Fault code"); - doc[FPSTR(HA_ICON)] = F("mdi:cog-box"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ \"%02d (0x%02X)\"|format(value_json.slave.fault.code, value_json.slave.fault.code) }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.connected and value_json.slave.fault.active, 'online', 'offline') }}"; + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("fault_code"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SENSOR, "fault_code"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_NAME] = "Fault code"; + doc[HA_ICON] = "mdi:cog-box"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ \"%02d (0x%02X)\"|format(value_json.slave.fault.code, value_json.slave.fault.code) }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), F("fault_code")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SENSOR, "fault_code").c_str(), doc); } bool publishDiagCode(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.connected and value_json.slave.fault.active or value_json.slave.diag.active, 'online', 'offline') }}"); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("diagnostic_code")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SENSOR), F("diagnostic_code")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_NAME)] = F("Diagnostic code"); - doc[FPSTR(HA_ICON)] = F("mdi:information-box"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ \"%02d (0x%02X)\"|format(value_json.slave.diag.code, value_json.slave.diag.code) }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.connected and value_json.slave.fault.active or value_json.slave.diag.active, 'online', 'offline') }}"; + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("diagnostic_code"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SENSOR, "diagnostic_code"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_NAME] = "Diagnostic code"; + doc[HA_ICON] = "mdi:information-box"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ \"%02d (0x%02X)\"|format(value_json.slave.diag.code, value_json.slave.diag.code) }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), F("diagnostic_code")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SENSOR, "diagnostic_code").c_str(), doc); } bool publishNetworkRssi(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(FPSTR(S_RSSI)); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SENSOR), FPSTR(S_RSSI)); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength"); - doc[FPSTR(HA_STATE_CLASS)] = FPSTR(HA_STATE_CLASS_MEASUREMENT); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("dBm"); - doc[FPSTR(HA_NAME)] = F("RSSI"); - doc[FPSTR(HA_ICON)] = F("mdi:signal"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.master.network.rssi|float(0)|round(1) }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(S_RSSI); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SENSOR, S_RSSI); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "signal_strength"; + doc[HA_STATE_CLASS] = HA_STATE_CLASS_MEASUREMENT; + doc[HA_UNIT_OF_MEASUREMENT] = "dBm"; + doc[HA_NAME] = "RSSI"; + doc[HA_ICON] = "mdi:signal"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.master.network.rssi|float(0)|round(1) }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), FPSTR(S_RSSI)).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SENSOR, S_RSSI).c_str(), doc); } bool publishUptime(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("uptime")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_SENSOR), F("uptime")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); - doc[FPSTR(HA_DEVICE_CLASS)] = F("duration"); - doc[FPSTR(HA_STATE_CLASS)] = F("total_increasing"); - doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("s"); - doc[FPSTR(HA_NAME)] = F("Uptime"); - doc[FPSTR(HA_ICON)] = F("mdi:clock-start"); - doc[FPSTR(HA_STATE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.master.uptime|int(0) }}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("uptime"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_SENSOR, "uptime"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_DIAGNOSTIC; + doc[HA_DEVICE_CLASS] = "duration"; + doc[HA_STATE_CLASS] = "total_increasing"; + doc[HA_UNIT_OF_MEASUREMENT] = "s"; + doc[HA_NAME] = "Uptime"; + doc[HA_ICON] = "mdi:clock-start"; + doc[HA_STATE_TOPIC] = this->stateTopic.c_str(); + doc[HA_VALUE_TEMPLATE] = "{{ value_json.master.uptime|int(0) }}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), F("uptime")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_SENSOR, "uptime").c_str(), doc); } bool publishClimateHeating(UnitSystem unit = UnitSystem::METRIC, uint8_t minTemp = 20, uint8_t maxTemp = 90, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("heating")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_CLIMATE), F("heating")); - doc[FPSTR(HA_NAME)] = F("Heating"); - doc[FPSTR(HA_ICON)] = F("mdi:radiator"); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("heating"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_CLIMATE, "heating"); + doc[HA_NAME] = "Heating"; + doc[HA_ICON] = "mdi:radiator"; - doc[FPSTR(HA_CURRENT_TEMPERATURE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_CURRENT_TEMPERATURE_TEMPLATE)] = F("{{ iif(value_json.master.heating.indoorTempControl, value_json.master.heating.indoorTemp, value_json.master.heating.currentTemp, 0)|float(0)|round(2) }}"); + doc[HA_CURRENT_TEMPERATURE_TOPIC] = this->stateTopic.c_str(); + doc[HA_CURRENT_TEMPERATURE_TEMPLATE] = "{{ iif(value_json.master.heating.indoorTempControl, value_json.master.heating.indoorTemp, value_json.master.heating.currentTemp, 0)|float(0)|round(2) }}"; - doc[FPSTR(HA_TEMPERATURE_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_TEMPERATURE_COMMAND_TEMPLATE)] = F("{\"heating\": {\"target\" : {{ value }}}}"); + doc[HA_TEMPERATURE_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_TEMPERATURE_COMMAND_TEMPLATE] = "{\"heating\": {\"target\" : {{ value }}}}"; - doc[FPSTR(HA_TEMPERATURE_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_TEMPERATURE_STATE_TEMPLATE)] = F("{{ value_json.heating.target|float(0)|round(1) }}"); + doc[HA_TEMPERATURE_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_TEMPERATURE_STATE_TEMPLATE] = "{{ value_json.heating.target|float(0)|round(1) }}"; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_TEMPERATURE_UNIT)] = "C"; + doc[HA_TEMPERATURE_UNIT] = "C"; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_TEMPERATURE_UNIT)] = "F"; + doc[HA_TEMPERATURE_UNIT] = "F"; } - doc[FPSTR(HA_MODE_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_MODE_COMMAND_TEMPLATE)] = F("{% if value == 'heat' %}{\"heating\": {\"enabled\" : true}}" - "{% elif value == 'off' %}{\"heating\": {\"enabled\" : false}}{% endif %}"); - doc[FPSTR(HA_MODE_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_MODE_STATE_TEMPLATE)] = F("{{ iif(value_json.heating.enabled, 'heat', 'off') }}"); - doc[FPSTR(HA_MODES)][0] = F("off"); - doc[FPSTR(HA_MODES)][1] = F("heat"); + doc[HA_MODE_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_MODE_COMMAND_TEMPLATE] = "{% if value == 'heat' %}{\"heating\": {\"enabled\" : true}}" + "{% elif value == 'off' %}{\"heating\": {\"enabled\" : false}}{% endif %}"; + doc[HA_MODE_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_MODE_STATE_TEMPLATE] = "{{ iif(value_json.heating.enabled, 'heat', 'off') }}"; + doc[HA_MODES][0] = "off"; + doc[HA_MODES][1] = "heat"; - doc[FPSTR(HA_ACTION_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_ACTION_TEMPLATE)] = F("{{ iif(value_json.slave.heating.active, 'heating', 'idle') }}"); + doc[HA_ACTION_TOPIC] = this->stateTopic.c_str(); + doc[HA_ACTION_TEMPLATE] = "{{ iif(value_json.slave.heating.active, 'heating', 'idle') }}"; - doc[FPSTR(HA_PRESET_MODE_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_PRESET_MODE_COMMAND_TEMPLATE)] = F("{% if value == 'boost' %}{\"heating\": {\"turbo\" : true}}" - "{% elif value == 'none' %}{\"heating\": {\"turbo\" : false}}{% endif %}"); - doc[FPSTR(HA_PRESET_MODE_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_PRESET_MODE_VALUE_TEMPLATE)] = F("{{ iif(value_json.heating.turbo, 'boost', 'none') }}"); - doc[FPSTR(HA_PRESET_MODES)][0] = F("boost"); + doc[HA_PRESET_MODE_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_PRESET_MODE_COMMAND_TEMPLATE] = "{% if value == 'boost' %}{\"heating\": {\"turbo\" : true}}" + "{% elif value == 'none' %}{\"heating\": {\"turbo\" : false}}{% endif %}"; + doc[HA_PRESET_MODE_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_PRESET_MODE_VALUE_TEMPLATE] = "{{ iif(value_json.heating.turbo, 'boost', 'none') }}"; + doc[HA_PRESET_MODES][0] = "boost"; - doc[FPSTR(HA_MIN_TEMP)] = minTemp; - doc[FPSTR(HA_MAX_TEMP)] = maxTemp; - doc[FPSTR(HA_TEMP_STEP)] = 0.1f; - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_MIN_TEMP] = minTemp; + doc[HA_MAX_TEMP] = maxTemp; + doc[HA_TEMP_STEP] = 0.1f; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_CLIMATE), F("heating"), '_').c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_CLIMATE, "heating", '_').c_str(), doc); } bool publishClimateDhw(UnitSystem unit = UnitSystem::METRIC, uint8_t minTemp = 40, uint8_t maxTemp = 60, bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("dhw")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_CLIMATE), F("dhw")); - doc[FPSTR(HA_NAME)] = F("DHW"); - doc[FPSTR(HA_ICON)] = F("mdi:faucet"); + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("dhw"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_CLIMATE, "dhw"); + doc[HA_NAME] = "DHW"; + doc[HA_ICON] = "mdi:faucet"; - doc[FPSTR(HA_CURRENT_TEMPERATURE_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_CURRENT_TEMPERATURE_TEMPLATE)] = F("{{ value_json.master.dhw.currentTemp|float(0)|round(1) }}"); + doc[HA_CURRENT_TEMPERATURE_TOPIC] = this->stateTopic.c_str(); + doc[HA_CURRENT_TEMPERATURE_TEMPLATE] = "{{ value_json.master.dhw.currentTemp|float(0)|round(1) }}"; - doc[FPSTR(HA_TEMPERATURE_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_TEMPERATURE_COMMAND_TEMPLATE)] = F("{\"dhw\": {\"target\" : {{ value|int(0) }}}}"); + doc[HA_TEMPERATURE_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_TEMPERATURE_COMMAND_TEMPLATE] = "{\"dhw\": {\"target\" : {{ value|int(0) }}}}"; - doc[FPSTR(HA_TEMPERATURE_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_TEMPERATURE_STATE_TEMPLATE)] = F("{{ value_json.dhw.target|float(0)|round(1) }}"); + doc[HA_TEMPERATURE_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_TEMPERATURE_STATE_TEMPLATE] = "{{ value_json.dhw.target|float(0)|round(1) }}"; if (unit == UnitSystem::METRIC) { - doc[FPSTR(HA_TEMPERATURE_UNIT)] = "C"; + doc[HA_TEMPERATURE_UNIT] = "C"; } else if (unit == UnitSystem::IMPERIAL) { - doc[FPSTR(HA_TEMPERATURE_UNIT)] = "F"; + doc[HA_TEMPERATURE_UNIT] = "F"; } - doc[FPSTR(HA_MODE_COMMAND_TOPIC)] = this->setSettingsTopic.c_str(); - doc[FPSTR(HA_MODE_COMMAND_TEMPLATE)] = F("{% if value == 'heat' %}{\"dhw\": {\"enabled\" : true}}" - "{% elif value == 'off' %}{\"dhw\": {\"enabled\" : false}}{% endif %}"); - doc[FPSTR(HA_MODE_STATE_TOPIC)] = this->settingsTopic.c_str(); - doc[FPSTR(HA_MODE_STATE_TEMPLATE)] = F("{{ iif(value_json.dhw.enabled, 'heat', 'off') }}"); - doc[FPSTR(HA_MODES)][0] = F("off"); - doc[FPSTR(HA_MODES)][1] = F("heat"); + doc[HA_MODE_COMMAND_TOPIC] = this->setSettingsTopic.c_str(); + doc[HA_MODE_COMMAND_TEMPLATE] = "{% if value == 'heat' %}{\"dhw\": {\"enabled\" : true}}" + "{% elif value == 'off' %}{\"dhw\": {\"enabled\" : false}}{% endif %}"; + doc[HA_MODE_STATE_TOPIC] = this->settingsTopic.c_str(); + doc[HA_MODE_STATE_TEMPLATE] = "{{ iif(value_json.dhw.enabled, 'heat', 'off') }}"; + doc[HA_MODES][0] = "off"; + doc[HA_MODES][1] = "heat"; - doc[FPSTR(HA_ACTION_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_ACTION_TEMPLATE)] = F("{{ iif(value_json.slave.dhw.active, 'heating', 'idle') }}"); + doc[HA_ACTION_TOPIC] = this->stateTopic.c_str(); + doc[HA_ACTION_TEMPLATE] = "{{ iif(value_json.slave.dhw.active, 'heating', 'idle') }}"; - doc[FPSTR(HA_MIN_TEMP)] = minTemp; - doc[FPSTR(HA_MAX_TEMP)] = maxTemp; - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_MIN_TEMP] = minTemp; + doc[HA_MAX_TEMP] = maxTemp; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_CLIMATE), F("dhw"), '_').c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_CLIMATE, "dhw", '_').c_str(), doc); } bool publishRestartButton(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(FPSTR(S_RESTART)); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BUTTON), FPSTR(S_RESTART)); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART); - doc[FPSTR(HA_NAME)] = F("Restart"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"restart\": true}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix(S_RESTART); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BUTTON, S_RESTART); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_RESTART; + doc[HA_NAME] = "Restart"; + doc[HA_COMMAND_TOPIC] = this->setStateTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"actions\": {\"restart\": true}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BUTTON), FPSTR(S_RESTART)).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BUTTON, S_RESTART).c_str(), doc); } bool publishResetFaultButton(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.fault.active, 'online', 'offline') }}"); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("reset_fault")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BUTTON), F("reset_fault")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART); - doc[FPSTR(HA_NAME)] = F("Reset fault"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetFault\": true}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.fault.active, 'online', 'offline') }}"; + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("reset_fault"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BUTTON, "reset_fault"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_RESTART; + doc[HA_NAME] = "Reset fault"; + doc[HA_COMMAND_TOPIC] = this->setStateTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"actions\": {\"resetFault\": true}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BUTTON), F("reset_fault")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BUTTON, "reset_fault").c_str(), doc); } bool publishResetDiagButton(bool enabledByDefault = true) { JsonDocument doc; - doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->stateTopic.c_str(); - doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.slave.diag.active, 'online', 'offline') }}"); - doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); - doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; - doc[FPSTR(HA_UNIQUE_ID)] = this->getUniqueIdWithPrefix(F("reset_diagnostic")); - doc[FPSTR(HA_DEFAULT_ENTITY_ID)] = this->getEntityIdWithPrefix(FPSTR(HA_ENTITY_BUTTON), F("reset_diagnostic")); - doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); - doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART); - doc[FPSTR(HA_NAME)] = F("Reset diagnostic"); - doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); - doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetDiagnostic\": true}}"); - doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; + doc[HA_AVAILABILITY][0][HA_TOPIC] = this->statusTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_TOPIC] = this->stateTopic.c_str(); + doc[HA_AVAILABILITY][1][HA_VALUE_TEMPLATE] = "{{ iif(value_json.slave.diag.active, 'online', 'offline') }}"; + doc[HA_AVAILABILITY_MODE] = "all"; + doc[HA_ENABLED_BY_DEFAULT] = enabledByDefault; + doc[HA_UNIQUE_ID] = this->getUniqueIdWithPrefix("reset_diagnostic"); + doc[HA_DEFAULT_ENTITY_ID] = this->getEntityIdWithPrefix(HA_ENTITY_BUTTON, "reset_diagnostic"); + doc[HA_ENTITY_CATEGORY] = HA_ENTITY_CATEGORY_CONFIG; + doc[HA_DEVICE_CLASS] = S_RESTART; + doc[HA_NAME] = "Reset diagnostic"; + doc[HA_COMMAND_TOPIC] = this->setStateTopic.c_str(); + doc[HA_COMMAND_TEMPLATE] = "{\"actions\": {\"resetDiagnostic\": true}}"; + doc[HA_EXPIRE_AFTER] = this->expireAfter; doc.shrinkToFit(); - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BUTTON), F("reset_diagnostic")).c_str(), doc); + return this->publish(this->makeConfigTopic(HA_ENTITY_BUTTON, "reset_diagnostic").c_str(), doc); } @@ -1379,27 +1379,27 @@ public: } bool deleteSwitchDhw() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SWITCH), F("dhw")).c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_SWITCH, "dhw").c_str()); } bool deleteInputDhwMinTemp() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("dhw_min_temp")).c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "dhw_min_temp").c_str()); } bool deleteInputDhwMaxTemp() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("dhw_max_temp")).c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "dhw_max_temp").c_str()); } bool deleteDhwState() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("dhw")).c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_BINARY_SENSOR, "dhw").c_str()); } bool deleteInputDhwTarget() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("dhw_target")).c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_NUMBER, "dhw_target").c_str()); } bool deleteClimateDhw() { - return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_CLIMATE), F("dhw"), '_').c_str()); + return this->publish(this->makeConfigTopic(HA_ENTITY_CLIMATE, "dhw", '_').c_str()); } protected: diff --git a/src/MainTask.h b/src/MainTask.h index 88a4918..e1a1cf4 100644 --- a/src/MainTask.h +++ b/src/MainTask.h @@ -42,7 +42,6 @@ protected: bool emergencyDetected = false; unsigned long emergencyFlipTime = 0; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "Main"; } @@ -58,7 +57,6 @@ protected: int getTaskPriority() override { return 3; } - #endif void setup() {} @@ -66,15 +64,15 @@ protected: network->loop(); if (fsNetworkSettings.tick() == FD_WRITE) { - Log.sinfoln(FPSTR(L_NETWORK_SETTINGS), F("Updated")); + Log.sinfoln(L_NETWORK_SETTINGS, "Updated"); } if (fsSettings.tick() == FD_WRITE) { - Log.sinfoln(FPSTR(L_SETTINGS), F("Updated")); + Log.sinfoln(L_SETTINGS, "Updated"); } if (fsSensorsSettings.tick() == FD_WRITE) { - Log.sinfoln(FPSTR(L_SENSORS_SETTINGS), F("Updated")); + Log.sinfoln(L_SENSORS_SETTINGS, "Updated"); } if (vars.actions.restart) { @@ -82,7 +80,7 @@ protected: this->restartSignalReceived = true; vars.actions.restart = false; - Log.sinfoln(FPSTR(L_MAIN), F("Received restart signal")); + Log.sinfoln(L_MAIN, "Received restart signal"); } if (!vars.states.restarting && this->restartSignalReceived && millis() - this->restartSignalReceivedTime > 5000) { @@ -99,7 +97,7 @@ protected: fsNetworkSettings.write(); } - Log.sinfoln(FPSTR(L_MAIN), F("Restart scheduled in 10 sec.")); + Log.sinfoln(L_MAIN, "Restart scheduled in 10 sec."); } vars.mqtt.connected = tMqtt->isConnected(); @@ -210,8 +208,8 @@ protected: if (millis() - this->lastHeapInfo > 20000 || minFreeHeapDiff > 0 || minMaxFreeBlockHeapDiff > 0) { Log.sverboseln( - FPSTR(L_MAIN), - F("Free heap size: %u of %u bytes (min: %u, diff: %u), max free block: %u (min: %u, diff: %u, frag: %hhu%%)"), + L_MAIN, + "Free heap size: %u of %u bytes (min: %u, diff: %u), max free block: %u (min: %u, diff: %u, frag: %hhu%%)", freeHeap, getTotalHeap(), this->minFreeHeap, minFreeHeapDiff, maxFreeBlockHeap, this->minMaxFreeBlockHeap, minMaxFreeBlockHeapDiff, getHeapFrag() ); this->lastHeapInfo = millis(); @@ -257,8 +255,8 @@ protected: vars.master.heating.freezing = false; Log.sinfoln( - FPSTR(L_MAIN), - F("No freezing detected. Current low temp: %.2f, threshold (high): %hhu"), + L_MAIN, + "No freezing detected. Current low temp: %.2f, threshold (high): %hhu", lowTemp, settings.heating.freezeProtection.highTemp ); } @@ -273,8 +271,8 @@ protected: } Log.sinfoln( - FPSTR(L_MAIN), - F("Freezing detected! Current low temp: %.2f, threshold (low): %hhu"), + L_MAIN, + "Freezing detected! Current low temp: %.2f, threshold (low): %hhu", lowTemp, settings.heating.freezeProtection.lowTemp ); } @@ -283,7 +281,7 @@ protected: } else if (vars.master.heating.freezing) { vars.master.heating.freezing = false; - Log.sinfoln(FPSTR(L_MAIN), F("No sensors available, freeze protection unavailable!")); + Log.sinfoln(L_MAIN, "No sensors available, freeze protection unavailable!"); } } } @@ -321,7 +319,7 @@ protected: // enable emergency if (millis() - this->emergencyFlipTime > (settings.emergency.tresholdTime * 1000)) { vars.emergency.state = true; - Log.sinfoln(FPSTR(L_MAIN), F("Emergency mode enabled (%hhu)"), emergencyFlags); + Log.sinfoln(L_MAIN, "Emergency mode enabled (%hhu)", emergencyFlags); } } @@ -335,7 +333,7 @@ protected: // disable emergency if (millis() - this->emergencyFlipTime > (settings.emergency.tresholdTime * 1000)) { vars.emergency.state = false; - Log.sinfoln(FPSTR(L_MAIN), F("Emergency mode disabled")); + Log.sinfoln(L_MAIN, "Emergency mode disabled"); } } } @@ -435,19 +433,19 @@ protected: pinMode(configuredInputGpio, OUTPUT); digitalWrite(configuredInputGpio, LOW); - Log.sinfoln(FPSTR(L_CASCADE_INPUT), F("Deinitialized on GPIO %hhu"), configuredInputGpio); + Log.sinfoln(L_CASCADE_INPUT, "Deinitialized on GPIO %hhu", configuredInputGpio); } if (GPIO_IS_VALID(settings.cascadeControl.input.gpio)) { configuredInputGpio = settings.cascadeControl.input.gpio; pinMode(configuredInputGpio, INPUT); - Log.sinfoln(FPSTR(L_CASCADE_INPUT), F("Initialized on GPIO %hhu"), configuredInputGpio); + Log.sinfoln(L_CASCADE_INPUT, "Initialized on GPIO %hhu", configuredInputGpio); } else if (configuredInputGpio != GPIO_IS_NOT_CONFIGURED) { configuredInputGpio = GPIO_IS_NOT_CONFIGURED; - Log.swarningln(FPSTR(L_CASCADE_INPUT), F("Failed initialize: GPIO %hhu is not valid!"), configuredInputGpio); + Log.swarningln(L_CASCADE_INPUT, "Failed initialize: GPIO %hhu is not valid!", configuredInputGpio); } } @@ -468,9 +466,9 @@ protected: vars.cascadeControl.input = value; Log.sinfoln( - FPSTR(L_CASCADE_INPUT), - F("State changed to %s"), - value ? F("TRUE") : F("FALSE") + L_CASCADE_INPUT, + "State changed to %s", + value ? "TRUE" : "FALSE" ); } @@ -485,9 +483,9 @@ protected: vars.cascadeControl.input = true; Log.sinfoln( - FPSTR(L_CASCADE_INPUT), - F("Disabled, state changed to %s"), - vars.cascadeControl.input ? F("TRUE") : F("FALSE") + L_CASCADE_INPUT, + "Disabled, state changed to %s", + vars.cascadeControl.input ? "TRUE" : "FALSE" ); } } @@ -500,7 +498,7 @@ protected: pinMode(configuredOutputGpio, OUTPUT); digitalWrite(configuredOutputGpio, LOW); - Log.sinfoln(FPSTR(L_CASCADE_OUTPUT), F("Deinitialized on GPIO %hhu"), configuredOutputGpio); + Log.sinfoln(L_CASCADE_OUTPUT, "Deinitialized on GPIO %hhu", configuredOutputGpio); } if (GPIO_IS_VALID(settings.cascadeControl.output.gpio)) { @@ -513,12 +511,12 @@ protected: : LOW ); - Log.sinfoln(FPSTR(L_CASCADE_OUTPUT), F("Initialized on GPIO %hhu"), configuredOutputGpio); + Log.sinfoln(L_CASCADE_OUTPUT, "Initialized on GPIO %hhu", configuredOutputGpio); } else if (configuredOutputGpio != GPIO_IS_NOT_CONFIGURED) { configuredOutputGpio = GPIO_IS_NOT_CONFIGURED; - Log.swarningln(FPSTR(L_CASCADE_OUTPUT), F("Failed initialize: GPIO %hhu is not valid!"), configuredOutputGpio); + Log.swarningln(L_CASCADE_OUTPUT, "Failed initialize: GPIO %hhu is not valid!", configuredOutputGpio); } } @@ -550,9 +548,9 @@ protected: ); Log.sinfoln( - FPSTR(L_CASCADE_OUTPUT), - F("State changed to %s"), - value ? F("TRUE") : F("FALSE") + L_CASCADE_OUTPUT, + "State changed to %s", + value ? "TRUE" : "FALSE" ); } @@ -576,9 +574,9 @@ protected: } Log.sinfoln( - FPSTR(L_CASCADE_OUTPUT), - F("Disabled, state changed to %s"), - vars.cascadeControl.output ? F("TRUE") : F("FALSE") + L_CASCADE_OUTPUT, + "Disabled, state changed to %s", + vars.cascadeControl.output ? "TRUE" : "FALSE" ); } } @@ -612,7 +610,7 @@ protected: vars.externalPump.state = false; vars.externalPump.lastEnabledTime = millis(); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Disabled: use = off")); + Log.sinfoln(L_EXTPUMP, "Disabled: use = off"); } return; @@ -638,7 +636,7 @@ protected: vars.externalPump.state = false; vars.externalPump.lastEnabledTime = millis(); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Disabled: use = off")); + Log.sinfoln(L_EXTPUMP, "Disabled: use = off"); } return; @@ -656,7 +654,7 @@ protected: vars.externalPump.state = false; vars.externalPump.lastEnabledTime = millis(); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Disabled: expired post circulation time")); + Log.sinfoln(L_EXTPUMP, "Disabled: expired post circulation time"); } else if (this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK && millis() - this->externalPumpStartTime >= (settings.externalPump.antiStuckTime * 1000u)) { digitalWrite( @@ -669,7 +667,7 @@ protected: vars.externalPump.state = false; vars.externalPump.lastEnabledTime = millis(); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Disabled: expired anti stuck time")); + Log.sinfoln(L_EXTPUMP, "Disabled: expired anti stuck time"); } } else if (vars.externalPump.state && this->heatingEnabled && this->extPumpStartReason == MainTask::PumpStartReason::ANTISTUCK) { @@ -687,7 +685,7 @@ protected: : HIGH ); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Enabled: heating on")); + Log.sinfoln(L_EXTPUMP, "Enabled: heating on"); } else if (!vars.externalPump.state && (vars.externalPump.lastEnabledTime == 0 || millis() - vars.externalPump.lastEnabledTime >= (settings.externalPump.antiStuckInterval * 1000lu))) { vars.externalPump.state = true; @@ -701,7 +699,7 @@ protected: : HIGH ); - Log.sinfoln(FPSTR(L_EXTPUMP), F("Enabled: anti stuck")); + Log.sinfoln(L_EXTPUMP, "Enabled: anti stuck"); } } }; diff --git a/src/MqttTask.h b/src/MqttTask.h index bc74ec5..41efccf 100644 --- a/src/MqttTask.h +++ b/src/MqttTask.h @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "HaHelper.h" @@ -9,7 +9,7 @@ extern FileData fsSettings; class MqttTask : public Task { public: explicit MqttTask(bool _enabled = false, unsigned long _interval = 0) : Task(_enabled, _interval) { - this->wifiClient = new MqttWiFiClient(); + this->wifiClient = new WiFiClient(); this->client = new MqttClient(this->wifiClient); this->writer = new MqttWriter(this->client, 256); this->haHelper = new HaHelper(); @@ -45,13 +45,13 @@ public: Task::disable(); - Log.sinfoln(FPSTR(L_MQTT), F("Disabled")); + Log.sinfoln(L_MQTT, "Disabled"); } void enable() { Task::enable(); - Log.sinfoln(FPSTR(L_MQTT), F("Enabled")); + Log.sinfoln(L_MQTT, "Enabled"); } inline bool isConnected() { @@ -75,7 +75,7 @@ public: } protected: - MqttWiFiClient* wifiClient = nullptr; + WiFiClient* wifiClient = nullptr; MqttClient* client = nullptr; HaHelper* haHelper = nullptr; MqttWriter* writer = nullptr; @@ -92,7 +92,6 @@ protected: bool connected = false; bool newConnection = false; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "Mqtt"; } @@ -104,28 +103,17 @@ protected: int getTaskPriority() override { return 2; } - #endif inline bool isReadyForSend() { return millis() - this->connectedTime > this->readyForSendTime; } void setup() { - Log.sinfoln(FPSTR(L_MQTT), F("Started")); - - // wificlient settings - #ifdef ARDUINO_ARCH_ESP8266 - this->wifiClient->setSync(true); - this->wifiClient->setNoDelay(true); - #endif + Log.sinfoln(L_MQTT, "Started"); // client settings this->client->setTxPayloadSize(256); - #ifdef ARDUINO_ARCH_ESP8266 - this->client->setConnectionTimeout(1000); - #else this->client->setConnectionTimeout(3000); - #endif this->client->onMessage([this] (void*, size_t length) { const String& topic = this->client->messageTopic(); @@ -142,35 +130,17 @@ protected: }); // writer settings - #ifdef ARDUINO_ARCH_ESP32 this->writer->setYieldCallback([this] { this->delay(10); }); - #endif this->writer->setPublishEventCallback([this] (const char* topic, size_t written, size_t length, bool result) { - Log.straceln(FPSTR(L_MQTT), F("%s publish %u of %u bytes to topic: %s"), result ? F("Successfully") : F("Failed"), written, length, topic); - - #ifdef ARDUINO_ARCH_ESP8266 - ::optimistic_yield(1000); - #endif + Log.straceln(L_MQTT, "%s publish %u of %u bytes to topic: %s", result ? "Successfully" : "Failed", written, length, topic); //this->client->poll(); this->delay(250); }); - #ifdef ARDUINO_ARCH_ESP8266 - this->writer->setFlushEventCallback([this] (size_t, size_t) { - ::optimistic_yield(1000); - - if (this->wifiClient->connected()) { - this->wifiClient->flush(); - } - - ::optimistic_yield(1000); - }); - #endif - // ha helper settings this->haHelper->setDevicePrefix(settings.mqtt.prefix); this->haHelper->setDeviceVersion(BUILD_VERSION); @@ -192,7 +162,7 @@ protected: this->onDisconnect(); } else if (!this->connected && millis() - this->lastReconnectTime >= MQTT_RECONNECT_INTERVAL) { - Log.sinfoln(FPSTR(L_MQTT), F("Connecting to %s:%u..."), settings.mqtt.server, settings.mqtt.port); + Log.sinfoln(L_MQTT, "Connecting to %s:%u...", settings.mqtt.server, settings.mqtt.port); this->haHelper->setDevicePrefix(settings.mqtt.prefix); this->haHelper->updateCachedTopics(); @@ -201,8 +171,8 @@ protected: this->client->setKeepAliveInterval(settings.mqtt.interval * 10000); this->client->setId(networkSettings.hostname); this->client->setUsernamePassword(settings.mqtt.user, settings.mqtt.password); - this->client->beginWill(this->haHelper->getDeviceTopic(F("status")).c_str(), 7, true, 1); - this->client->print(F("offline")); + this->client->beginWill(this->haHelper->getDeviceTopic("status").c_str(), 7, true, 1); + this->client->print("offline"); this->client->endWill(); this->client->connect(settings.mqtt.server, settings.mqtt.port); this->lastReconnectTime = millis(); @@ -224,20 +194,16 @@ protected: return; } - #ifdef ARDUINO_ARCH_ESP8266 - ::optimistic_yield(1000); - #endif - // publish variables and status if (this->newConnection || millis() - this->prevPubVarsTime > (settings.mqtt.interval * 1000u)) { - this->writer->publish(this->haHelper->getDeviceTopic(F("status")).c_str(), "online", false); - this->publishVariables(this->haHelper->getDeviceTopic(F("state")).c_str()); + this->writer->publish(this->haHelper->getDeviceTopic("status").c_str(), "online", false); + this->publishVariables(this->haHelper->getDeviceTopic("state").c_str()); this->prevPubVarsTime = millis(); } // publish settings if (this->newConnection || millis() - this->prevPubSettingsTime > (settings.mqtt.interval * 10000u)) { - this->publishSettings(this->haHelper->getDeviceTopic(F("settings")).c_str()); + this->publishSettings(this->haHelper->getDeviceTopic("settings").c_str()); this->prevPubSettingsTime = millis(); } @@ -278,7 +244,7 @@ protected: // rebuilding ha configs for (auto& [sensorId, prevSettings] : this->queueReconfigureSensors) { - Log.sinfoln(FPSTR(L_MQTT_HA), F("Rebuilding config for sensor #%hhu '%s'"), sensorId, prevSettings.name); + Log.sinfoln(L_MQTT_HA, "Rebuilding config for sensor #%hhu '%s'", sensorId, prevSettings.name); // delete old config if (strlen(prevSettings.name) && prevSettings.enabled) { @@ -357,9 +323,9 @@ protected: if (prevSettings.type == Sensors::Type::MANUAL) { this->client->unsubscribe( this->haHelper->getDeviceTopic( - F("sensors"), + "sensors", Sensors::makeObjectId(prevSettings.name).c_str(), - F("set") + "set" ).c_str() ); } @@ -374,9 +340,9 @@ protected: if (sSettings.type == Sensors::Type::MANUAL) { this->client->subscribe( this->haHelper->getDeviceTopic( - F("sensors"), + "sensors", Sensors::makeObjectId(sSettings.name).c_str(), - F("set") + "set" ).c_str() ); } @@ -394,10 +360,10 @@ protected: this->connectedTime = millis(); this->newConnection = true; unsigned long downtime = (millis() - this->disconnectedTime) / 1000; - Log.sinfoln(FPSTR(L_MQTT), F("Connected (downtime: %u s.)"), downtime); + Log.sinfoln(L_MQTT, "Connected (downtime: %u s.)", downtime); - this->client->subscribe(this->haHelper->getDeviceTopic(F("settings/set")).c_str()); - this->client->subscribe(this->haHelper->getDeviceTopic(F("state/set")).c_str()); + this->client->subscribe(this->haHelper->getDeviceTopic("settings/set").c_str()); + this->client->subscribe(this->haHelper->getDeviceTopic("state/set").c_str()); // subscribe to manual sensors for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) { @@ -412,9 +378,9 @@ protected: this->client->subscribe( this->haHelper->getDeviceTopic( - F("sensors"), + "sensors", Sensors::makeObjectId(sSettings.name).c_str(), - F("set") + "set" ).c_str() ); } @@ -424,7 +390,7 @@ protected: this->disconnectedTime = millis(); unsigned long uptime = (millis() - this->connectedTime) / 1000; - Log.swarningln(FPSTR(L_MQTT), F("Disconnected (reason: %d uptime: %lu s.)"), this->client->connectError(), uptime); + Log.swarningln(L_MQTT, "Disconnected (reason: %d uptime: %lu s.)", this->client->connectError(), uptime); } void onMessage(const String& topic, uint8_t* payload, size_t length) { @@ -433,7 +399,7 @@ protected: } if (settings.system.logLevel >= TinyLoggerLevel::TRACE) { - Log.strace(FPSTR(L_MQTT_MSG), F("Topic: %s\r\n> "), topic.c_str()); + Log.strace(L_MQTT_MSG, "Topic: %s\r\n> ", topic.c_str()); if (Log.lock()) { for (size_t i = 0; i < length; i++) { if (payload[i] == 0) { @@ -441,12 +407,12 @@ protected: } else if (payload[i] == 13) { continue; } else if (payload[i] == 10) { - Log.print(F("\r\n> ")); + Log.print("\r\n> "); } else { Log.print(static_cast(payload[i])); } } - Log.print(F("\r\n\n")); + Log.print("\r\n\n"); Log.flush(); Log.unlock(); } @@ -455,11 +421,11 @@ protected: JsonDocument doc; DeserializationError dErr = deserializeJson(doc, payload, length); if (dErr != DeserializationError::Ok) { - Log.swarningln(FPSTR(L_MQTT_MSG), F("Error on deserialization: %s"), dErr.f_str()); + Log.swarningln(L_MQTT_MSG, "Error on deserialization: %s", dErr.c_str()); return; } else if (doc.isNull() || !doc.size()) { - Log.swarningln(FPSTR(L_MQTT_MSG), F("Not valid json")); + Log.swarningln(L_MQTT_MSG, "Not valid json"); return; } doc.shrinkToFit(); @@ -467,22 +433,22 @@ protected: // delete topic this->writer->publish(topic.c_str(), nullptr, 0, true); - if (this->haHelper->getDeviceTopic(F("state/set")).equals(topic)) { + if (this->haHelper->getDeviceTopic("state/set").equals(topic)) { if (jsonToVars(doc, vars)) { this->resetPublishedVarsTime(); } - } else if (this->haHelper->getDeviceTopic(F("settings/set")).equals(topic)) { + } else if (this->haHelper->getDeviceTopic("settings/set").equals(topic)) { if (safeJsonToSettings(doc, settings)) { this->resetPublishedSettingsTime(); fsSettings.update(); } } else { - const String& sensorsTopic = this->haHelper->getDeviceTopic(F("sensors/")); + const String& sensorsTopic = this->haHelper->getDeviceTopic("sensors/"); auto stLength = sensorsTopic.length(); - if (topic.startsWith(sensorsTopic) && topic.endsWith(F("/set"))) { + if (topic.startsWith(sensorsTopic) && topic.endsWith("/set")) { if (topic.length() > stLength + 4) { const String& name = topic.substring(stLength, topic.indexOf('/', stLength)); int16_t id = Sensors::getIdByObjectId(name.c_str()); @@ -649,7 +615,7 @@ protected: return this->writer->publish( this->haHelper->getDeviceTopic( - F("sensors"), + "sensors", Sensors::makeObjectId(sSettings.name).c_str() ).c_str(), doc, diff --git a/src/OpenThermTask.h b/src/OpenThermTask.h index bc9cf5c..32e0efb 100644 --- a/src/OpenThermTask.h +++ b/src/OpenThermTask.h @@ -35,7 +35,6 @@ protected: unsigned long roomSetTempCh2Time = 0; uint8_t configuredRxLedGpio = GPIO_IS_NOT_CONFIGURED; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "OpenTherm"; } @@ -51,7 +50,6 @@ protected: int getTaskPriority() override { return 5; } - #endif void setup() { // Convert defaults at start @@ -66,13 +64,13 @@ protected: if (this->instance != nullptr) { delete this->instance; this->instance = nullptr; - Log.sinfoln(FPSTR(L_OT), F("Stopped")); + Log.sinfoln(L_OT, "Stopped"); } if (!GPIO_IS_VALID(settings.opentherm.inGpio) || !GPIO_IS_VALID(settings.opentherm.outGpio)) { Log.swarningln( - FPSTR(L_OT), - F("Not started. GPIO IN: %hhu or GPIO OUT: %hhu is not valid"), + L_OT, + "Not started. GPIO IN: %hhu or GPIO OUT: %hhu is not valid", settings.opentherm.inGpio, settings.opentherm.outGpio ); @@ -99,12 +97,12 @@ protected: this->roomSetTempTime = 0; this->roomSetTempCh2Time = 0; - Log.sinfoln(FPSTR(L_OT), F("Started. GPIO IN: %hhu, GPIO OUT: %hhu"), settings.opentherm.inGpio, settings.opentherm.outGpio); + Log.sinfoln(L_OT, "Started. GPIO IN: %hhu, GPIO OUT: %hhu", settings.opentherm.inGpio, settings.opentherm.outGpio); this->instance->setAfterSendRequestCallback([this](unsigned long request, unsigned long response, OpenThermResponseStatus status, uint8_t attempt) { Log.sverboseln( - FPSTR(L_OT), - F("ID: %4d Request: %8lx Response: %8lx Msg type: %s Attempt: %2d Status: %s"), + L_OT, + "ID: %4d Request: %8lx Response: %8lx Msg type: %s Attempt: %2d Status: %s", CustomOpenTherm::getDataID(request), request, response, @@ -155,7 +153,7 @@ protected: } else if (this->instance->status == OpenThermStatus::NOT_INITIALIZED) { if (!this->instance->begin()) { - Log.swarningln(FPSTR(L_OT), F("Failed begin")); + Log.swarningln(L_OT, "Failed begin"); this->delay(5000); return; @@ -241,8 +239,8 @@ protected: if (!CustomOpenTherm::isValidResponse(response) || !CustomOpenTherm::isValidResponseId(response, OpenThermMessageID::Status)) { Log.swarningln( - FPSTR(L_OT), - F("Failed receive boiler status: %s"), + L_OT, + "Failed receive boiler status: %s", CustomOpenTherm::statusToString(this->instance->getLastResponseStatus()) ); @@ -262,7 +260,7 @@ protected: } Log.snoticeln( - FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; channel 2: %hhu; fault: %hhu; diag: %hhu"), + L_OT, "Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; channel 2: %hhu; fault: %hhu; diag: %hhu", vars.slave.heating.active, vars.slave.dhw.active, vars.slave.flame, vars.slave.cooling.active, vars.slave.ch2.active, vars.slave.fault.active, vars.slave.diag.active ); @@ -275,8 +273,8 @@ protected: // 5 * (1000 + 100) * 1.15 = 6325 ms if (!vars.slave.connected && millis() - this->lastSuccessResponse < 6325) { Log.sinfoln( - FPSTR(L_OT), - F("Connected, downtime: %lu s."), + L_OT, + "Connected, downtime: %lu s.", (millis() - this->disconnectedTime) / 1000 ); @@ -285,8 +283,8 @@ protected: } else if (vars.slave.connected && millis() - this->lastSuccessResponse > 6325) { Log.swarningln( - FPSTR(L_OT), - F("Disconnected, uptime: %lu s."), + L_OT, + "Disconnected, uptime: %lu s.", (millis() - this->connectedTime) / 1000 ); @@ -343,7 +341,7 @@ protected: // reset bus if (millis() - this->disconnectedTime > this->resetBusInterval) { if (millis() - this->resetBusTime > this->resetBusInterval) { - Log.sinfoln(FPSTR(L_OT), F("Reset bus...")); + Log.sinfoln(L_OT, "Reset bus..."); this->instance->end(); this->instance->status = OpenThermStatus::NOT_INITIALIZED; @@ -358,7 +356,7 @@ protected: } if (!this->initialized) { - Log.sinfoln(FPSTR(L_OT), F("Initializing...")); + Log.sinfoln(L_OT, "Initializing..."); this->initialized = true; this->initializedTime = millis(); this->initialize(); @@ -367,13 +365,13 @@ protected: if (vars.master.heating.enabled != vars.slave.heating.enabled) { this->prevUpdateNonEssentialVars = 0; vars.slave.heating.enabled = vars.master.heating.enabled; - Log.sinfoln(FPSTR(L_OT_HEATING), vars.master.heating.enabled ? F("Enabled") : F("Disabled")); + Log.sinfoln(L_OT_HEATING, vars.master.heating.enabled ? "Enabled" : "Disabled"); } if (vars.master.dhw.enabled != vars.slave.dhw.enabled) { this->prevUpdateNonEssentialVars = 0; vars.slave.dhw.enabled = vars.master.dhw.enabled; - Log.sinfoln(FPSTR(L_OT_DHW), vars.master.dhw.enabled ? F("Enabled") : F("Disabled")); + Log.sinfoln(L_OT_DHW, vars.master.dhw.enabled ? "Enabled" : "Disabled"); } // These parameters will be updated every minute @@ -384,24 +382,24 @@ protected: if (getLocalTime(&ti)) { if (this->setYear(&ti)) { - Log.sinfoln(FPSTR(L_OT), F("Year of date set successfully")); + Log.sinfoln(L_OT, "Year of date set successfully"); } else { - Log.sinfoln(FPSTR(L_OT), F("Failed set year of date")); + Log.sinfoln(L_OT, "Failed set year of date"); } if (this->setDayAndMonth(&ti)) { - Log.sinfoln(FPSTR(L_OT), F("Day and month of date set successfully")); + Log.sinfoln(L_OT, "Day and month of date set successfully"); } else { - Log.sinfoln(FPSTR(L_OT), F("Failed set day and month of date")); + Log.sinfoln(L_OT, "Failed set day and month of date"); } if (this->setTime(&ti)) { - Log.sinfoln(FPSTR(L_OT), F("Time set successfully")); + Log.sinfoln(L_OT, "Time set successfully"); } else { - Log.sinfoln(FPSTR(L_OT), F("Failed set time")); + Log.sinfoln(L_OT, "Failed set time"); } } } @@ -409,7 +407,7 @@ protected: // Get min modulation level & max power if (this->updateMinModulationLevel()) { Log.snoticeln( - FPSTR(L_OT), F("Received min modulation: %hhu%%, max power: %.2f kW"), + L_OT, "Received min modulation: %hhu%%, max power: %.2f kW", vars.slave.modulation.min, vars.slave.power.max ); @@ -418,7 +416,7 @@ protected: fsSettings.update(); Log.swarningln( - FPSTR(L_SETTINGS_HEATING), F("Updated min modulation: %hhu%%"), + L_SETTINGS_HEATING, "Updated min modulation: %hhu%%", settings.heating.maxModulation ); } @@ -428,7 +426,7 @@ protected: fsSettings.update(); Log.swarningln( - FPSTR(L_SETTINGS_DHW), F("Updated min modulation: %hhu%%"), + L_SETTINGS_DHW, "Updated min modulation: %hhu%%", settings.dhw.maxModulation ); } @@ -439,13 +437,13 @@ protected: fsSettings.update(); Log.swarningln( - FPSTR(L_SETTINGS_OT), F("Updated power, min: %.2f kW, max: %.2f kW"), + L_SETTINGS_OT, "Updated power, min: %.2f kW, max: %.2f kW", settings.opentherm.minPower, settings.opentherm.maxPower ); } } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive min modulation and max power")); + Log.swarningln(L_OT, "Failed receive min modulation and max power"); } @@ -465,7 +463,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_DHW), F("Received min temp: %hhu (converted: %hhu), max temp: %hhu (converted: %hhu)"), + L_OT_DHW, "Received min temp: %hhu (converted: %hhu), max temp: %hhu (converted: %hhu)", vars.slave.dhw.minTemp, convertedMinTemp, vars.slave.dhw.maxTemp, convertedMaxTemp ); @@ -473,18 +471,18 @@ protected: settings.dhw.minTemp = convertedMinTemp; fsSettings.update(); - Log.swarningln(FPSTR(L_SETTINGS_DHW), F("Updated min temp: %hhu"), settings.dhw.minTemp); + Log.swarningln(L_SETTINGS_DHW, "Updated min temp: %hhu", settings.dhw.minTemp); } if (settings.dhw.maxTemp > convertedMaxTemp) { settings.dhw.maxTemp = convertedMaxTemp; fsSettings.update(); - Log.swarningln(FPSTR(L_SETTINGS_DHW), F("Updated max temp: %hhu"), settings.dhw.maxTemp); + Log.swarningln(L_SETTINGS_DHW, "Updated max temp: %hhu", settings.dhw.maxTemp); } } else { - Log.swarningln(FPSTR(L_OT_DHW), F("Failed receive min/max temp")); + Log.swarningln(L_OT_DHW, "Failed receive min/max temp"); } } @@ -511,7 +509,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_HEATING), F("Received min temp: %hhu (converted: %hhu), max temp: %hhu (converted: %hhu)"), + L_OT_HEATING, "Received min temp: %hhu (converted: %hhu), max temp: %hhu (converted: %hhu)", vars.slave.heating.minTemp, convertedMinTemp, vars.slave.heating.maxTemp, convertedMaxTemp ); @@ -519,18 +517,18 @@ protected: settings.heating.minTemp = convertedMinTemp; fsSettings.update(); - Log.swarningln(FPSTR(L_SETTINGS_HEATING), F("Updated min temp: %hhu"), settings.heating.minTemp); + Log.swarningln(L_SETTINGS_HEATING, "Updated min temp: %hhu", settings.heating.minTemp); } if (settings.heating.maxTemp > convertedMaxTemp) { settings.heating.maxTemp = convertedMaxTemp; fsSettings.update(); - Log.swarningln(FPSTR(L_SETTINGS_HEATING), F("Updated max temp: %hhu"), settings.heating.maxTemp); + Log.swarningln(L_SETTINGS_HEATING, "Updated max temp: %hhu", settings.heating.maxTemp); } } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed receive min/max temp")); + Log.swarningln(L_OT_HEATING, "Failed receive min/max temp"); } } @@ -544,12 +542,12 @@ protected: if (vars.slave.fault.active) { if (this->updateFaultCode()) { Log.snoticeln( - FPSTR(L_OT), F("Received fault code: %hhu (0x%02X)"), + L_OT, "Received fault code: %hhu (0x%02X)", vars.slave.fault.code, vars.slave.fault.code ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive fault code")); + Log.swarningln(L_OT, "Failed receive fault code"); } } else if (vars.slave.fault.code != 0) { @@ -560,12 +558,12 @@ protected: if (vars.slave.fault.active || vars.slave.diag.active) { if (this->updateDiagCode()) { Log.snoticeln( - FPSTR(L_OT), F("Received diag code: %hu (0x%02X)"), + L_OT, "Received diag code: %hu (0x%02X)", vars.slave.diag.code, vars.slave.diag.code ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive diag code")); + Log.swarningln(L_OT, "Failed receive diag code"); } } else if (vars.slave.diag.code != 0) { @@ -575,7 +573,7 @@ protected: // Update burner starts if (Sensors::getAmountByType(Sensors::Type::OT_BURNER_STARTS, true)) { if (this->updateBurnerStarts()) { - Log.snoticeln(FPSTR(L_OT), F("Received burner starts: %hu"), vars.slave.stats.burnerStarts); + Log.snoticeln(L_OT, "Received burner starts: %hu", vars.slave.stats.burnerStarts); Sensors::setValueByType( Sensors::Type::OT_BURNER_STARTS, vars.slave.stats.burnerStarts, @@ -583,14 +581,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive burner starts")); + Log.swarningln(L_OT, "Failed receive burner starts"); } } // Update DHW burner starts if (Sensors::getAmountByType(Sensors::Type::OT_DHW_BURNER_STARTS, true)) { if (this->updateDhwBurnerStarts()) { - Log.snoticeln(FPSTR(L_OT), F("Received DHW burner starts: %hu"), vars.slave.stats.dhwBurnerStarts); + Log.snoticeln(L_OT, "Received DHW burner starts: %hu", vars.slave.stats.dhwBurnerStarts); Sensors::setValueByType( Sensors::Type::OT_DHW_BURNER_STARTS, vars.slave.stats.dhwBurnerStarts, @@ -598,14 +596,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive DHW burner starts")); + Log.swarningln(L_OT, "Failed receive DHW burner starts"); } } // Update heating pump starts if (Sensors::getAmountByType(Sensors::Type::OT_HEATING_PUMP_STARTS, true)) { if (this->updateHeatingPumpStarts()) { - Log.snoticeln(FPSTR(L_OT), F("Received heating pump starts: %hu"), vars.slave.stats.heatingPumpStarts); + Log.snoticeln(L_OT, "Received heating pump starts: %hu", vars.slave.stats.heatingPumpStarts); Sensors::setValueByType( Sensors::Type::OT_HEATING_PUMP_STARTS, vars.slave.stats.heatingPumpStarts, @@ -613,14 +611,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive heating pump starts")); + Log.swarningln(L_OT, "Failed receive heating pump starts"); } } // Update DHW pump starts if (Sensors::getAmountByType(Sensors::Type::OT_DHW_PUMP_STARTS, true)) { if (this->updateDhwPumpStarts()) { - Log.snoticeln(FPSTR(L_OT), F("Received DHW pump starts: %hu"), vars.slave.stats.dhwPumpStarts); + Log.snoticeln(L_OT, "Received DHW pump starts: %hu", vars.slave.stats.dhwPumpStarts); Sensors::setValueByType( Sensors::Type::OT_DHW_PUMP_STARTS, vars.slave.stats.dhwPumpStarts, @@ -628,14 +626,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive DHW pump starts")); + Log.swarningln(L_OT, "Failed receive DHW pump starts"); } } // Update burner hours if (Sensors::getAmountByType(Sensors::Type::OT_BURNER_HOURS, true)) { if (this->updateBurnerHours()) { - Log.snoticeln(FPSTR(L_OT), F("Received burner hours: %hu"), vars.slave.stats.burnerHours); + Log.snoticeln(L_OT, "Received burner hours: %hu", vars.slave.stats.burnerHours); Sensors::setValueByType( Sensors::Type::OT_BURNER_HOURS, vars.slave.stats.burnerHours, @@ -643,14 +641,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive burner hours")); + Log.swarningln(L_OT, "Failed receive burner hours"); } } // Update DHW burner hours if (Sensors::getAmountByType(Sensors::Type::OT_DHW_BURNER_HOURS, true)) { if (this->updateDhwBurnerHours()) { - Log.snoticeln(FPSTR(L_OT), F("Received DHW burner hours: %hu"), vars.slave.stats.dhwBurnerHours); + Log.snoticeln(L_OT, "Received DHW burner hours: %hu", vars.slave.stats.dhwBurnerHours); Sensors::setValueByType( Sensors::Type::OT_DHW_BURNER_HOURS, vars.slave.stats.dhwBurnerHours, @@ -658,14 +656,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive DHW burner hours")); + Log.swarningln(L_OT, "Failed receive DHW burner hours"); } } // Update heating pump hours if (Sensors::getAmountByType(Sensors::Type::OT_HEATING_PUMP_HOURS, true)) { if (this->updateHeatingPumpHours()) { - Log.snoticeln(FPSTR(L_OT), F("Received heating pump hours: %hu"), vars.slave.stats.heatingPumpHours); + Log.snoticeln(L_OT, "Received heating pump hours: %hu", vars.slave.stats.heatingPumpHours); Sensors::setValueByType( Sensors::Type::OT_HEATING_PUMP_HOURS, vars.slave.stats.heatingPumpHours, @@ -673,14 +671,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive heating pump hours")); + Log.swarningln(L_OT, "Failed receive heating pump hours"); } } // Update DHW pump hours if (Sensors::getAmountByType(Sensors::Type::OT_DHW_PUMP_HOURS, true)) { if (this->updateDhwPumpHours()) { - Log.snoticeln(FPSTR(L_OT), F("Received DHW pump hours: %hu"), vars.slave.stats.dhwPumpHours); + Log.snoticeln(L_OT, "Received DHW pump hours: %hu", vars.slave.stats.dhwPumpHours); Sensors::setValueByType( Sensors::Type::OT_DHW_PUMP_HOURS, vars.slave.stats.dhwPumpHours, @@ -688,14 +686,14 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive DHW pump hours")); + Log.swarningln(L_OT, "Failed receive DHW pump hours"); } } // Update cooling hours if (Sensors::getAmountByType(Sensors::Type::OT_COOLING_HOURS, true)) { if (this->updateCoolingHours()) { - Log.snoticeln(FPSTR(L_OT), F("Received cooling hours: %hu"), vars.slave.stats.coolingHours); + Log.snoticeln(L_OT, "Received cooling hours: %hu", vars.slave.stats.coolingHours); Sensors::setValueByType( Sensors::Type::OT_COOLING_HOURS, vars.slave.stats.coolingHours, @@ -703,7 +701,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive cooling hours")); + Log.swarningln(L_OT, "Failed receive cooling hours"); } } @@ -724,13 +722,13 @@ protected: if (settings.opentherm.options.coolingSupport) { if (this->setCoolingSetpoint(settings.heating.maxModulation)) { Log.snoticeln( - FPSTR(L_OT), F("Set cooling setpoint: %hhu%% (response: %hhu%%)"), + L_OT, "Set cooling setpoint: %hhu%% (response: %hhu%%)", settings.heating.maxModulation, vars.slave.cooling.setpoint ); } else { Log.swarningln( - FPSTR(L_OT), F("Failed set cooling setpoint: %hhu%% (response: %hhu%%)"), + L_OT, "Failed set cooling setpoint: %hhu%% (response: %hhu%%)", settings.heating.maxModulation, vars.slave.cooling.setpoint ); } @@ -759,13 +757,13 @@ protected: if (this->setMaxModulationLevel(targetMaxModulation)) { Log.snoticeln( - FPSTR(L_OT), F("Set max modulation: %hhu%% (response: %hhu%%)"), + L_OT, "Set max modulation: %hhu%% (response: %hhu%%)", targetMaxModulation, vars.slave.modulation.max ); } else { Log.swarningln( - FPSTR(L_OT), F("Failed set max modulation: %hhu%% (response: %hhu%%)"), + L_OT, "Failed set max modulation: %hhu%% (response: %hhu%%)", targetMaxModulation, vars.slave.modulation.max ); } @@ -790,7 +788,7 @@ protected: vars.slave.power.current = power; Log.snoticeln( - FPSTR(L_OT), F("Received modulation level: %hhu%%, power: %.2f of %.2f kW (min: %.2f kW)"), + L_OT, "Received modulation level: %hhu%%, power: %.2f of %.2f kW (min: %.2f kW)", vars.slave.modulation.current, vars.slave.power.current, settings.opentherm.maxPower, settings.opentherm.minPower ); @@ -808,7 +806,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive modulation level")); + Log.swarningln(L_OT, "Failed receive modulation level"); } } else { @@ -841,7 +839,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_DHW), F("Received temp: %.2f (converted: %.2f)"), + L_OT_DHW, "Received temp: %.2f (converted: %.2f)", vars.slave.dhw.currentTemp, convertedDhwTemp ); @@ -851,7 +849,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_DHW), F("Failed receive temp")); + Log.swarningln(L_OT_DHW, "Failed receive temp"); } } @@ -865,7 +863,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_DHW), F("Received temp 2: %.2f (converted: %.2f)"), + L_OT_DHW, "Received temp 2: %.2f (converted: %.2f)", vars.slave.dhw.currentTemp2, convertedDhwTemp2 ); @@ -875,7 +873,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_DHW), F("Failed receive temp 2")); + Log.swarningln(L_OT_DHW, "Failed receive temp 2"); } } @@ -889,7 +887,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_DHW), F("Received flow rate: %.2f (converted: %.2f)"), + L_OT_DHW, "Received flow rate: %.2f (converted: %.2f)", vars.slave.dhw.flowRate, convertedDhwFlowRate ); @@ -899,7 +897,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_DHW), F("Failed receive flow rate")); + Log.swarningln(L_OT_DHW, "Failed receive flow rate"); } } @@ -913,7 +911,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_HEATING), F("Received temp: %.2f"), + L_OT_HEATING, "Received temp: %.2f", vars.slave.heating.currentTemp, convertedHeatingTemp ); @@ -923,7 +921,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed receive temp")); + Log.swarningln(L_OT_HEATING, "Failed receive temp"); } } @@ -937,7 +935,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_HEATING), F("Received return temp: %.2f (converted: %.2f)"), + L_OT_HEATING, "Received return temp: %.2f (converted: %.2f)", vars.slave.heating.returnTemp, convertedHeatingReturnTemp ); @@ -947,7 +945,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed receive return temp")); + Log.swarningln(L_OT_HEATING, "Failed receive return temp"); } } @@ -962,7 +960,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT_CH2), F("Received temp: %.2f (converted: %.2f)"), + L_OT_CH2, "Received temp: %.2f (converted: %.2f)", vars.slave.ch2.currentTemp, convertedCh2Temp ); @@ -972,7 +970,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT_CH2), F("Failed receive temp")); + Log.swarningln(L_OT_CH2, "Failed receive temp"); } } } @@ -987,7 +985,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received exhaust temp: %.2f (converted: %.2f)"), + L_OT, "Received exhaust temp: %.2f (converted: %.2f)", vars.slave.exhaust.temp, convertedExhaustTemp ); @@ -997,7 +995,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive exhaust temp")); + Log.swarningln(L_OT, "Failed receive exhaust temp"); } } @@ -1011,7 +1009,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received heat exchanger temp: %.2f (converted: %.2f)"), + L_OT, "Received heat exchanger temp: %.2f (converted: %.2f)", vars.slave.heatExchangerTemp, convertedHeatExchTemp ); @@ -1021,7 +1019,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive heat exchanger temp")); + Log.swarningln(L_OT, "Failed receive heat exchanger temp"); } } @@ -1035,7 +1033,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received outdoor temp: %.2f (converted: %.2f)"), + L_OT, "Received outdoor temp: %.2f (converted: %.2f)", vars.slave.heating.outdoorTemp, convertedOutdoorTemp ); @@ -1045,7 +1043,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive outdoor temp")); + Log.swarningln(L_OT, "Failed receive outdoor temp"); } } @@ -1059,7 +1057,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received solar storage temp: %.2f (converted: %.2f)"), + L_OT, "Received solar storage temp: %.2f (converted: %.2f)", vars.slave.solar.storage, convertedSolarStorageTemp ); @@ -1069,7 +1067,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive solar storage temp")); + Log.swarningln(L_OT, "Failed receive solar storage temp"); } } @@ -1083,7 +1081,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received solar collector temp: %.2f (converted: %.2f)"), + L_OT, "Received solar collector temp: %.2f (converted: %.2f)", vars.slave.solar.collector, convertedSolarCollectorTemp ); @@ -1093,7 +1091,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive solar collector temp")); + Log.swarningln(L_OT, "Failed receive solar collector temp"); } } @@ -1104,7 +1102,7 @@ protected: ) { if (this->updateFanSpeed()) { Log.snoticeln( - FPSTR(L_OT), F("Received fan speed, setpoint: %hhu%%, current: %hhu%%"), + L_OT, "Received fan speed, setpoint: %hhu%%, current: %hhu%%", vars.slave.fanSpeed.setpoint, vars.slave.fanSpeed.current ); @@ -1129,7 +1127,7 @@ protected: ); Log.snoticeln( - FPSTR(L_OT), F("Received pressure: %.2f (converted: %.2f)"), + L_OT, "Received pressure: %.2f (converted: %.2f)", vars.slave.pressure, convertedPressure ); @@ -1139,7 +1137,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive pressure")); + Log.swarningln(L_OT, "Failed receive pressure"); } } @@ -1147,7 +1145,7 @@ protected: if (Sensors::getAmountByType(Sensors::Type::OT_EXHAUST_CO2, true)) { if (this->updateExhaustCo2()) { Log.snoticeln( - FPSTR(L_OT), F("Received exhaust CO2: %hu ppm"), + L_OT, "Received exhaust CO2: %hu ppm", vars.slave.exhaust.co2 ); @@ -1157,7 +1155,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive exhaust CO2")); + Log.swarningln(L_OT, "Failed receive exhaust CO2"); } } @@ -1165,7 +1163,7 @@ protected: if (Sensors::getAmountByType(Sensors::Type::OT_EXHAUST_FAN_SPEED, true)) { if (this->updateExhaustFanSpeed()) { Log.snoticeln( - FPSTR(L_OT), F("Received exhaust fan speed: %hu rpm"), + L_OT, "Received exhaust fan speed: %hu rpm", vars.slave.exhaust.fanSpeed ); @@ -1175,7 +1173,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive exhaust fan speed")); + Log.swarningln(L_OT, "Failed receive exhaust fan speed"); } } @@ -1183,7 +1181,7 @@ protected: if (Sensors::getAmountByType(Sensors::Type::OT_SUPPLY_FAN_SPEED, true)) { if (this->updateSupplyFanSpeed()) { Log.snoticeln( - FPSTR(L_OT), F("Received supply fan speed: %hu rpm"), + L_OT, "Received supply fan speed: %hu rpm", vars.slave.fanSpeed.supply ); @@ -1193,7 +1191,7 @@ protected: ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive supply fan speed")); + Log.swarningln(L_OT, "Failed receive supply fan speed"); } } @@ -1201,10 +1199,10 @@ protected: if (vars.actions.resetFault) { if (vars.slave.fault.active) { if (this->instance->sendBoilerReset()) { - Log.sinfoln(FPSTR(L_OT), F("Boiler fault reset successfully")); + Log.sinfoln(L_OT, "Boiler fault reset successfully"); } else { - Log.serrorln(FPSTR(L_OT), F("Boiler fault reset failed")); + Log.serrorln(L_OT, "Boiler fault reset failed"); } } @@ -1215,10 +1213,10 @@ protected: if (vars.actions.resetDiagnostic) { if (vars.slave.diag.active) { if (this->instance->sendServiceReset()) { - Log.sinfoln(FPSTR(L_OT), F("Boiler diagnostic reset successfully")); + Log.sinfoln(L_OT, "Boiler diagnostic reset successfully"); } else { - Log.serrorln(FPSTR(L_OT), F("Boiler diagnostic reset failed")); + Log.serrorln(L_OT, "Boiler diagnostic reset failed"); } } @@ -1242,12 +1240,12 @@ protected: this->dhwSetTempTime = millis(); Log.sinfoln( - FPSTR(L_OT_DHW), F("Set temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_DHW, "Set temp: %.2f (converted: %.2f, response: %.2f)", targetTemp, convertedTemp, vars.slave.dhw.targetTemp ); } else { - Log.swarningln(FPSTR(L_OT_DHW), F("Failed set temp")); + Log.swarningln(L_OT_DHW, "Failed set temp"); } } } @@ -1263,24 +1261,24 @@ protected: // Set current indoor temp if (this->setRoomTemp(convertedTemp)) { Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set current indoor temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_HEATING, "Set current indoor temp: %.2f (converted: %.2f, response: %.2f)", indoorTemp, convertedTemp, vars.slave.heating.indoorTemp ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set current indoor temp")); + Log.swarningln(L_OT_HEATING, "Failed set current indoor temp"); } // Set current CH2 indoor temp if (settings.opentherm.options.heatingToCh2) { if (this->setRoomTempCh2(convertedTemp)) { Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set current CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_HEATING, "Set current CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)", indoorTemp, convertedTemp, vars.slave.ch2.indoorTemp ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set current CH2 indoor temp")); + Log.swarningln(L_OT_HEATING, "Failed set current CH2 indoor temp"); } } } @@ -1303,12 +1301,12 @@ protected: this->roomSetTempTime = millis(); Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set target indoor temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_HEATING, "Set target indoor temp: %.2f (converted: %.2f, response: %.2f)", targetTemp, convertedTemp, vars.slave.heating.roomTargetTemp ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set target indoor temp")); + Log.swarningln(L_OT_HEATING, "Failed set target indoor temp"); } } @@ -1318,12 +1316,12 @@ protected: this->roomSetTempCh2Time = millis(); Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set target CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_HEATING, "Set target CH2 indoor temp: %.2f (converted: %.2f, response: %.2f)", targetTemp, convertedTemp, vars.slave.ch2.roomTargetTemp ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set target CH2 indoor temp")); + Log.swarningln(L_OT_HEATING, "Failed set target CH2 indoor temp"); } } } @@ -1347,13 +1345,13 @@ protected: if (settings.opentherm.options.maxTempSyncWithTargetTemp) { if (this->setMaxHeatingTemp(convertedTemp)) { Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set max heating temp: %.2f (converted: %.2f)"), + L_OT_HEATING, "Set max heating temp: %.2f (converted: %.2f)", targetTemp, convertedTemp ); } else { Log.swarningln( - FPSTR(L_OT_HEATING), F("Failed set max heating temp: %.2f (converted: %.2f)"), + L_OT_HEATING, "Failed set max heating temp: %.2f (converted: %.2f)", targetTemp, convertedTemp ); } @@ -1364,12 +1362,12 @@ protected: this->heatingSetTempTime = millis(); Log.sinfoln( - FPSTR(L_OT_HEATING), F("Set target temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_HEATING, "Set target temp: %.2f (converted: %.2f, response: %.2f)", targetTemp, convertedTemp, vars.slave.heating.targetTemp ); } else { - Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set target temp")); + Log.swarningln(L_OT_HEATING, "Failed set target temp"); } } } @@ -1390,12 +1388,12 @@ protected: this->ch2SetTempTime = millis(); Log.sinfoln( - FPSTR(L_OT_CH2), F("Set temp: %.2f (converted: %.2f, response: %.2f)"), + L_OT_CH2, "Set temp: %.2f (converted: %.2f, response: %.2f)", targetTemp, convertedTemp, vars.slave.ch2.targetTemp ); } else { - Log.swarningln(FPSTR(L_OT_CH2), F("Failed set temp")); + Log.swarningln(L_OT_CH2, "Failed set temp"); } } } @@ -1418,7 +1416,7 @@ protected: vars.master.heating.overheat = false; Log.sinfoln( - FPSTR(L_OT_HEATING), F("Overheating not detected. Current high temp: %.2f, threshold (low): %hhu"), + L_OT_HEATING, "Overheating not detected. Current high temp: %.2f, threshold (low): %hhu", highTemp, settings.heating.overheatProtection.lowTemp ); } @@ -1428,7 +1426,7 @@ protected: vars.master.heating.overheat = true; Log.swarningln( - FPSTR(L_OT_HEATING), F("Overheating detected! Current high temp: %.2f, threshold (high): %hhu"), + L_OT_HEATING, "Overheating detected! Current high temp: %.2f, threshold (high): %hhu", highTemp, settings.heating.overheatProtection.highTemp ); } @@ -1458,7 +1456,7 @@ protected: vars.master.dhw.overheat = false; Log.sinfoln( - FPSTR(L_OT_DHW), F("Overheating not detected. Current high temp: %.2f, threshold (low): %hhu"), + L_OT_DHW, "Overheating not detected. Current high temp: %.2f, threshold (low): %hhu", highTemp, settings.dhw.overheatProtection.lowTemp ); } @@ -1468,7 +1466,7 @@ protected: vars.master.dhw.overheat = true; Log.swarningln( - FPSTR(L_OT_DHW), F("Overheating detected! Current high temp: %.2f, threshold (high): %hhu"), + L_OT_DHW, "Overheating detected! Current high temp: %.2f, threshold (high): %hhu", highTemp, settings.dhw.overheatProtection.highTemp ); } @@ -1483,69 +1481,69 @@ protected: // Not all boilers support these, only try once when the boiler becomes connected if (this->updateSlaveVersion()) { Log.snoticeln( - FPSTR(L_OT), F("Received slave app version: %u, type: %u"), + L_OT, "Received slave app version: %u, type: %u", vars.slave.appVersion, vars.slave.type ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive slave version")); + Log.swarningln(L_OT, "Failed receive slave version"); } if (this->setMasterVersion(vars.master.appVersion, vars.master.type)) { Log.snoticeln( - FPSTR(L_OT), F("Set master version: %u, type: %u"), + L_OT, "Set master version: %u, type: %u", vars.master.appVersion, vars.master.type ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed set master version")); + Log.swarningln(L_OT, "Failed set master version"); } if (this->updateSlaveOtVersion()) { - Log.snoticeln(FPSTR(L_OT), F("Received slave OT version: %f"), vars.slave.protocolVersion); + Log.snoticeln(L_OT, "Received slave OT version: %f", vars.slave.protocolVersion); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive slave OT version")); + Log.swarningln(L_OT, "Failed receive slave OT version"); } if (this->setMasterOtVersion(vars.master.protocolVersion)) { - Log.snoticeln(FPSTR(L_OT), F("Set master OT version: %f"), vars.master.protocolVersion); + Log.snoticeln(L_OT, "Set master OT version: %f", vars.master.protocolVersion); } else { - Log.swarningln(FPSTR(L_OT), F("Failed set master OT version")); + Log.swarningln(L_OT, "Failed set master OT version"); } if (this->updateSlaveConfig()) { Log.snoticeln( - FPSTR(L_OT), F("Received slave member id: %u, flags: %u"), + L_OT, "Received slave member id: %u, flags: %u", vars.slave.memberId, vars.slave.flags ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed receive slave config")); + Log.swarningln(L_OT, "Failed receive slave config"); } if (this->setMasterConfig(vars.master.memberId, vars.master.flags)) { Log.snoticeln( - FPSTR(L_OT), F("Set master member id: %u, flags: %u"), + L_OT, "Set master member id: %u, flags: %u", vars.master.memberId, vars.master.flags ); } else { - Log.swarningln(FPSTR(L_OT), F("Failed set master config")); + Log.swarningln(L_OT, "Failed set master config"); } /*char buf[100]; if (this->instance->getStr(OpenThermMessageID::Brand, buf, sizeof(buf) - 1)) { - Log.snoticeln(FPSTR(L_OT), F("Slave brand: %s"), buf); + Log.snoticeln(L_OT, "Slave brand: %s", buf); } if (this->instance->getStr(OpenThermMessageID::BrandVersion, buf, sizeof(buf) - 1)) { - Log.snoticeln(FPSTR(L_OT), F("Slave brand version: %s"), buf); + Log.snoticeln(L_OT, "Slave brand version: %s", buf); } if (this->instance->getStr(OpenThermMessageID::BrandSerialNumber, buf, sizeof(buf) - 1)) { - Log.snoticeln(FPSTR(L_OT), F("Slave brand s/n: %s"), buf); + Log.snoticeln(L_OT, "Slave brand s/n: %s", buf); }*/ } @@ -1624,7 +1622,7 @@ protected: /*uint8_t flags = (response & 0xFFFF) >> 8; Log.straceln( "OT", - F("MasterMemberIdCode:\r\n DHW present: %u\r\n Control type: %u\r\n Cooling configuration: %u\r\n DHW configuration: %u\r\n Pump control: %u\r\n CH2 present: %u\r\n Remote water filling function: %u\r\n Heat/cool mode control: %u\r\n Slave MemberID Code: %u\r\n Raw: %u"), + "MasterMemberIdCode:\r\n DHW present: %u\r\n Control type: %u\r\n Cooling configuration: %u\r\n DHW configuration: %u\r\n Pump control: %u\r\n CH2 present: %u\r\n Remote water filling function: %u\r\n Heat/cool mode control: %u\r\n Slave MemberID Code: %u\r\n Raw: %u", (bool) (flags & 0x01), (bool) (flags & 0x02), (bool) (flags & 0x04), diff --git a/src/PortalTask.h b/src/PortalTask.h index b741e08..d5da17a 100644 --- a/src/PortalTask.h +++ b/src/PortalTask.h @@ -46,7 +46,6 @@ protected: unsigned long webServerChangeState = 0; bool mDnsState = false; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "Portal"; } @@ -58,7 +57,6 @@ protected: int getTaskPriority() override { return 1; } - #endif void setup() { this->dnsServer->setTTL(0); @@ -176,16 +174,16 @@ protected: auto& doc = response->getRoot(); // add network settings - auto networkDoc = doc[FPSTR(S_NETWORK)].to(); + auto networkDoc = doc[S_NETWORK].to(); networkSettingsToJson(networkSettings, networkDoc); // add main settings - auto settingsDoc = doc[FPSTR(S_SETTINGS)].to(); + auto settingsDoc = doc[S_SETTINGS].to(); settingsToJson(settings, settingsDoc); // add sensors settings for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) { - auto sensorsettingsDoc = doc[FPSTR(S_SENSORS)][sensorId].to(); + auto sensorsettingsDoc = doc[S_SENSORS][sensorId].to(); sensorSettingsToJson(sensorId, Sensors::settings[sensorId], sensorsettingsDoc); } @@ -193,10 +191,10 @@ protected: getFilename(filename, sizeof(filename), "backup"); char contentDispositionValue[128]; - snprintf_P( + snprintf( contentDispositionValue, sizeof(contentDispositionValue), - PSTR("attachment; filename=\"%s\""), + "attachment; filename=\"%s\"", filename ); @@ -220,7 +218,7 @@ protected: bool changed = false; // restore network settings - if (!requestDoc[FPSTR(S_NETWORK)].isNull() && jsonToNetworkSettings(requestDoc[FPSTR(S_NETWORK)], networkSettings)) { + if (!requestDoc[S_NETWORK].isNull() && jsonToNetworkSettings(requestDoc[S_NETWORK], networkSettings)) { fsNetworkSettings.update(); network->setHostname(networkSettings.hostname) ->setStaCredentials(networkSettings.sta.ssid, networkSettings.sta.password, networkSettings.sta.channel) @@ -236,14 +234,14 @@ protected: } // restore main settings - if (!requestDoc[FPSTR(S_SETTINGS)].isNull() && jsonToSettings(requestDoc[FPSTR(S_SETTINGS)], settings)) { + if (!requestDoc[S_SETTINGS].isNull() && jsonToSettings(requestDoc[S_SETTINGS], settings)) { fsSettings.update(); changed = true; } // restore sensors settings - if (!requestDoc[FPSTR(S_SENSORS)].isNull()) { - for (auto sensor : requestDoc[FPSTR(S_SENSORS)].as()) { + if (!requestDoc[S_SENSORS].isNull()) { + for (auto sensor : requestDoc[S_SENSORS].as()) { uint8_t sensorId; if (!Sensors::parseId(sensor.key().c_str(), sensorId)) { continue; @@ -338,12 +336,12 @@ protected: auto *response = new AsyncJsonResponse(true); auto& doc = response->getRoot(); for (short int i = 0; i < apCount; i++) { - doc[i][FPSTR(S_SSID)] = WiFi.SSID(i); - doc[i][FPSTR(S_BSSID)] = WiFi.BSSIDstr(i); - doc[i][FPSTR(S_SIGNAL_QUALITY)] = NetworkMgr::rssiToSignalQuality(WiFi.RSSI(i)); - doc[i][FPSTR(S_CHANNEL)] = WiFi.channel(i); - doc[i][FPSTR(S_HIDDEN)] = !WiFi.SSID(i).length(); - doc[i][FPSTR(S_AUTH)] = WiFi.encryptionType(i); + doc[i][S_SSID] = WiFi.SSID(i); + doc[i][S_BSSID] = WiFi.BSSIDstr(i); + doc[i][S_SIGNAL_QUALITY] = NetworkMgr::rssiToSignalQuality(WiFi.RSSI(i)); + doc[i][S_CHANNEL] = WiFi.channel(i); + doc[i][S_HIDDEN] = !WiFi.SSID(i).length(); + doc[i][S_AUTH] = WiFi.encryptionType(i); } // send response @@ -411,9 +409,9 @@ protected: for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) { if (detailed) { auto& sSensor = Sensors::settings[sensorId]; - responseDoc[sensorId][FPSTR(S_ENABLED)] = sSensor.enabled; - responseDoc[sensorId][FPSTR(S_NAME)] = sSensor.name; - responseDoc[sensorId][FPSTR(S_PURPOSE)] = static_cast(sSensor.purpose); + responseDoc[sensorId][S_ENABLED] = sSensor.enabled; + responseDoc[sensorId][S_NAME] = sSensor.name; + responseDoc[sensorId][S_PURPOSE] = static_cast(sSensor.purpose); sensorResultToJson(sensorId, responseDoc[sensorId]); } else { @@ -538,53 +536,53 @@ protected: auto *response = new AsyncJsonResponse(); auto& doc = response->getRoot(); - auto docSystem = doc[FPSTR(S_SYSTEM)].to(); - docSystem[FPSTR(S_RESET_REASON)] = getResetReason(); - docSystem[FPSTR(S_UPTIME)] = millis() / 1000; + auto docSystem = doc[S_SYSTEM].to(); + docSystem[S_RESET_REASON] = getResetReason(); + docSystem[S_UPTIME] = millis() / 1000; bool isConnected = network->isConnected(); - auto docNetwork = doc[FPSTR(S_NETWORK)].to(); - docNetwork[FPSTR(S_HOSTNAME)] = networkSettings.hostname; - docNetwork[FPSTR(S_MAC)] = network->getStaMac(); - docNetwork[FPSTR(S_CONNECTED)] = isConnected; - docNetwork[FPSTR(S_SSID)] = network->getStaSsid(); - docNetwork[FPSTR(S_SIGNAL_QUALITY)] = isConnected ? NetworkMgr::rssiToSignalQuality(network->getRssi()) : 0; - docNetwork[FPSTR(S_CHANNEL)] = isConnected ? network->getStaChannel() : 0; - docNetwork[FPSTR(S_IP)] = isConnected ? network->getStaIp().toString() : ""; - docNetwork[FPSTR(S_SUBNET)] = isConnected ? network->getStaSubnet().toString() : ""; - docNetwork[FPSTR(S_GATEWAY)] = isConnected ? network->getStaGateway().toString() : ""; - docNetwork[FPSTR(S_DNS)] = isConnected ? network->getStaDns().toString() : ""; + auto docNetwork = doc[S_NETWORK].to(); + docNetwork[S_HOSTNAME] = networkSettings.hostname; + docNetwork[S_MAC] = network->getStaMac(); + docNetwork[S_CONNECTED] = isConnected; + docNetwork[S_SSID] = network->getStaSsid(); + docNetwork[S_SIGNAL_QUALITY] = isConnected ? NetworkMgr::rssiToSignalQuality(network->getRssi()) : 0; + docNetwork[S_CHANNEL] = isConnected ? network->getStaChannel() : 0; + docNetwork[S_IP] = isConnected ? network->getStaIp().toString() : ""; + docNetwork[S_SUBNET] = isConnected ? network->getStaSubnet().toString() : ""; + docNetwork[S_GATEWAY] = isConnected ? network->getStaGateway().toString() : ""; + docNetwork[S_DNS] = isConnected ? network->getStaDns().toString() : ""; - auto docBuild = doc[FPSTR(S_BUILD)].to(); - docBuild[FPSTR(S_VERSION)] = BUILD_VERSION; - docBuild[FPSTR(S_COMMIT)] = BUILD_COMMIT; - docBuild[FPSTR(S_DATE)] = __DATE__ " " __TIME__; - docBuild[FPSTR(S_ENV)] = BUILD_ENV; - docBuild[FPSTR(S_CORE)] = ESP.getCoreVersion(); - docBuild[FPSTR(S_SDK)] = ESP.getSdkVersion(); + auto docBuild = doc[S_BUILD].to(); + docBuild[S_VERSION] = BUILD_VERSION; + docBuild[S_COMMIT] = BUILD_COMMIT; + docBuild[S_DATE] = __DATE__ " " __TIME__; + docBuild[S_ENV] = BUILD_ENV; + docBuild[S_CORE] = ESP.getCoreVersion(); + docBuild[S_SDK] = ESP.getSdkVersion(); - auto docHeap = doc[FPSTR(S_HEAP)].to(); - docHeap[FPSTR(S_TOTAL)] = getTotalHeap(); - docHeap[FPSTR(S_FREE)] = getFreeHeap(); - docHeap[FPSTR(S_MIN_FREE)] = getFreeHeap(true); - docHeap[FPSTR(S_MAX_FREE_BLOCK)] = getMaxFreeBlockHeap(); - docHeap[FPSTR(S_MIN_MAX_FREE_BLOCK)] = getMaxFreeBlockHeap(true); + auto docHeap = doc[S_HEAP].to(); + docHeap[S_TOTAL] = getTotalHeap(); + docHeap[S_FREE] = getFreeHeap(); + docHeap[S_MIN_FREE] = getFreeHeap(true); + docHeap[S_MAX_FREE_BLOCK] = getMaxFreeBlockHeap(); + docHeap[S_MIN_MAX_FREE_BLOCK] = getMaxFreeBlockHeap(true); - auto docPsram = doc[FPSTR(S_PSRAM)].to(); - docPsram[FPSTR(S_TOTAL)] = ESP.getPsramSize(); - docPsram[FPSTR(S_FREE)] = ESP.getFreePsram(); - docPsram[FPSTR(S_MIN_FREE)] = ESP.getMinFreePsram(); - docPsram[FPSTR(S_MAX_FREE_BLOCK)] = ESP.getMaxAllocPsram(); + auto docPsram = doc[S_PSRAM].to(); + docPsram[S_TOTAL] = ESP.getPsramSize(); + docPsram[S_FREE] = ESP.getFreePsram(); + docPsram[S_MIN_FREE] = ESP.getMinFreePsram(); + docPsram[S_MAX_FREE_BLOCK] = ESP.getMaxAllocPsram(); - auto docChip = doc[FPSTR(S_CHIP)].to(); - docChip[FPSTR(S_MODEL)] = ESP.getChipModel(); - docChip[FPSTR(S_REV)] = ESP.getChipRevision(); - docChip[FPSTR(S_CORES)] = ESP.getChipCores(); - docChip[FPSTR(S_FREQ)] = ESP.getCpuFreqMHz(); + auto docChip = doc[S_CHIP].to(); + docChip[S_MODEL] = ESP.getChipModel(); + docChip[S_REV] = ESP.getChipRevision(); + docChip[S_CORES] = ESP.getChipCores(); + docChip[S_FREQ] = ESP.getCpuFreqMHz(); - auto docFlash = doc[FPSTR(S_FLASH)].to(); - docFlash[FPSTR(S_SIZE)] = ESP.getFlashChipSize(); - docFlash[FPSTR(S_REAL_SIZE)] = docFlash[FPSTR(S_SIZE)]; + auto docFlash = doc[S_FLASH].to(); + docFlash[S_SIZE] = ESP.getFlashChipSize(); + docFlash[S_REAL_SIZE] = docFlash[S_SIZE]; // send response response->setLength(); @@ -596,60 +594,60 @@ protected: auto *response = new AsyncJsonResponse(); auto& doc = response->getRoot(); - auto docBuild = doc[FPSTR(S_BUILD)].to(); - docBuild[FPSTR(S_VERSION)] = BUILD_VERSION; - docBuild[FPSTR(S_COMMIT)] = BUILD_COMMIT; - docBuild[FPSTR(S_DATE)] = __DATE__ " " __TIME__; - docBuild[FPSTR(S_ENV)] = BUILD_ENV; - docBuild[FPSTR(S_CORE)] = ESP.getCoreVersion(); - docBuild[FPSTR(S_SDK)] = ESP.getSdkVersion(); + auto docBuild = doc[S_BUILD].to(); + docBuild[S_VERSION] = BUILD_VERSION; + docBuild[S_COMMIT] = BUILD_COMMIT; + docBuild[S_DATE] = __DATE__ " " __TIME__; + docBuild[S_ENV] = BUILD_ENV; + docBuild[S_CORE] = ESP.getCoreVersion(); + docBuild[S_SDK] = ESP.getSdkVersion(); - auto docHeap = doc[FPSTR(S_HEAP)].to(); - docHeap[FPSTR(S_TOTAL)] = getTotalHeap(); - docHeap[FPSTR(S_FREE)] = getFreeHeap(); - docHeap[FPSTR(S_MIN_FREE)] = getFreeHeap(true); - docHeap[FPSTR(S_MAX_FREE_BLOCK)] = getMaxFreeBlockHeap(); - docHeap[FPSTR(S_MIN_MAX_FREE_BLOCK)] = getMaxFreeBlockHeap(true); + auto docHeap = doc[S_HEAP].to(); + docHeap[S_TOTAL] = getTotalHeap(); + docHeap[S_FREE] = getFreeHeap(); + docHeap[S_MIN_FREE] = getFreeHeap(true); + docHeap[S_MAX_FREE_BLOCK] = getMaxFreeBlockHeap(); + docHeap[S_MIN_MAX_FREE_BLOCK] = getMaxFreeBlockHeap(true); - auto docChip = doc[FPSTR(S_CHIP)].to(); - docChip[FPSTR(S_MODEL)] = ESP.getChipModel(); - docChip[FPSTR(S_REV)] = ESP.getChipRevision(); - docChip[FPSTR(S_CORES)] = ESP.getChipCores(); - docChip[FPSTR(S_FREQ)] = ESP.getCpuFreqMHz(); + auto docChip = doc[S_CHIP].to(); + docChip[S_MODEL] = ESP.getChipModel(); + docChip[S_REV] = ESP.getChipRevision(); + docChip[S_CORES] = ESP.getChipCores(); + docChip[S_FREQ] = ESP.getCpuFreqMHz(); - auto docFlash = doc[FPSTR(S_FLASH)].to(); - docFlash[FPSTR(S_SIZE)] = ESP.getFlashChipSize(); - docFlash[FPSTR(S_REAL_SIZE)] = docFlash[FPSTR(S_SIZE)]; + auto docFlash = doc[S_FLASH].to(); + docFlash[S_SIZE] = ESP.getFlashChipSize(); + docFlash[S_REAL_SIZE] = docFlash[S_SIZE]; auto reason = esp_reset_reason(); if (reason != ESP_RST_UNKNOWN && reason != ESP_RST_POWERON && reason != ESP_RST_SW) { - auto docCrash = doc[FPSTR(S_CRASH)].to(); - docCrash[FPSTR(S_REASON)] = getResetReason(); - docCrash[FPSTR(S_CORE)] = CrashRecorder::ext.core; - docCrash[FPSTR(S_HEAP)] = CrashRecorder::ext.heap; - docCrash[FPSTR(S_UPTIME)] = CrashRecorder::ext.uptime; + auto docCrash = doc[S_CRASH].to(); + docCrash[S_REASON] = getResetReason(); + docCrash[S_CORE] = CrashRecorder::ext.core; + docCrash[S_HEAP] = CrashRecorder::ext.heap; + docCrash[S_UPTIME] = CrashRecorder::ext.uptime; if (CrashRecorder::backtrace.length > 0 && CrashRecorder::backtrace.length <= CrashRecorder::backtraceMaxLength) { String backtraceStr; arr2str(backtraceStr, CrashRecorder::backtrace.data, CrashRecorder::backtrace.length); - docCrash[FPSTR(S_BACKTRACE)][FPSTR(S_DATA)] = backtraceStr; - docCrash[FPSTR(S_BACKTRACE)][FPSTR(S_CONTINUES)] = CrashRecorder::backtrace.continues; + docCrash[S_BACKTRACE][S_DATA] = backtraceStr; + docCrash[S_BACKTRACE][S_CONTINUES] = CrashRecorder::backtrace.continues; } if (CrashRecorder::epc.length > 0 && CrashRecorder::epc.length <= CrashRecorder::epcMaxLength) { String epcStr; arr2str(epcStr, CrashRecorder::epc.data, CrashRecorder::epc.length); - docCrash[FPSTR(S_EPC)] = epcStr; + docCrash[S_EPC] = epcStr; } } char filename[64]; getFilename(filename, sizeof(filename), "debug"); char contentDispositionValue[128]; - snprintf_P( + snprintf( contentDispositionValue, sizeof(contentDispositionValue), - PSTR("attachment; filename=\"%s\""), + "attachment; filename=\"%s\"", filename ); @@ -663,7 +661,7 @@ protected: // not found this->webServer->onNotFound([this](AsyncWebServerRequest *request) { const auto& url = request->url(); - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Page not found, uri: %s"), url.c_str()); + Log.straceln(L_PORTAL_WEBSERVER, "Page not found, uri: %s", url.c_str()); if (url.equals("/")) { request->send(200, "text/plain", "The file system is not flashed!"); @@ -685,7 +683,7 @@ protected: // web server if (!this->stateWebServer() && (network->isApEnabled() || network->isConnected()) && millis() - this->webServerChangeState >= this->changeStateInterval) { this->startWebServer(); - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Started: AP up or STA connected")); + Log.straceln(L_PORTAL_WEBSERVER, "Started: AP up or STA connected"); // Enabling mDNS if (!this->mDnsState && settings.portal.mdns) { @@ -693,20 +691,20 @@ protected: MDNS.addService("http", "tcp", 80); this->mDnsState = true; - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("mDNS enabled and service added")); + Log.straceln(L_PORTAL_WEBSERVER, "mDNS enabled and service added"); } } } else if (this->stateWebServer() && !network->isApEnabled() && !network->isStaEnabled()) { this->stopWebServer(); - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Stopped: AP and STA down")); + Log.straceln(L_PORTAL_WEBSERVER, "Stopped: AP and STA down"); // Disabling mDNS if (this->mDnsState) { MDNS.end(); this->mDnsState = false; - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("mDNS disabled")); + Log.straceln(L_PORTAL_WEBSERVER, "mDNS disabled"); } } @@ -715,17 +713,17 @@ protected: MDNS.end(); this->mDnsState = false; - Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("mDNS disabled")); + Log.straceln(L_PORTAL_WEBSERVER, "mDNS disabled"); } // dns server if (!this->stateDnsServer() && !network->isConnected() && network->isApEnabled() && this->stateWebServer()) { this->startDnsServer(); - Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Started: AP up")); + Log.straceln(L_PORTAL_DNSSERVER, "Started: AP up"); } else if (this->stateDnsServer() && (network->isConnected() || !network->isApEnabled() || !this->stateWebServer())) { this->stopDnsServer(); - Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Stopped: AP down/STA connected")); + Log.straceln(L_PORTAL_DNSSERVER, "Stopped: AP down/STA connected"); } if (this->stateDnsServer()) { @@ -743,17 +741,17 @@ protected: if (url.equals("/connecttest.txt")) { request->redirect("http://logout.net", 302); - Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Redirect to http://logout.net with 302 code")); + Log.straceln(L_PORTAL_CAPTIVE, "Redirect to http://logout.net with 302 code"); - } else if (url.equals(F("/wpad.dat"))) { + } else if (url.equals("/wpad.dat")) { request->send(404); - Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Send empty page with 404 code")); + Log.straceln(L_PORTAL_CAPTIVE, "Send empty page with 404 code"); - } else if (url.equals(F("/success.txt"))) { + } else if (url.equals("/success.txt")) { request->send(200); - Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Send empty page with 200 code")); + Log.straceln(L_PORTAL_CAPTIVE, "Send empty page with 200 code"); } else { String portalUrl = "http://"; @@ -762,7 +760,7 @@ protected: request->redirect(portalUrl, 302); - Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Redirect to portal page with 302 code")); + Log.straceln(L_PORTAL_CAPTIVE, "Redirect to portal page with 302 code"); } } @@ -824,8 +822,8 @@ protected: localtime_r(&now, &localNow); char localNowValue[20]; - strftime(localNowValue, sizeof(localNowValue), PSTR("%Y-%m-%d-%H-%M-%S"), &localNow); + strftime(localNowValue, sizeof(localNowValue), "%Y-%m-%d-%H-%M-%S", &localNow); - snprintf_P(filename, maxSizeFilename, PSTR("%s_%s_%s.json"), networkSettings.hostname, localNowValue, type); + snprintf(filename, maxSizeFilename, "%s_%s_%s.json", networkSettings.hostname, localNowValue, type); } }; diff --git a/src/RegulatorTask.h b/src/RegulatorTask.h index bd7be47..7e47dca 100644 --- a/src/RegulatorTask.h +++ b/src/RegulatorTask.h @@ -15,7 +15,6 @@ protected: bool indoorSensorsConnected = false; //bool outdoorSensorsConnected = false; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "Regulator"; } @@ -31,7 +30,6 @@ protected: int getTaskPriority() override { return 4; } - #endif void loop() { if (vars.states.restarting || vars.states.upgrading) { @@ -55,7 +53,7 @@ protected: if (!settings.pid.enabled && fabsf(pidRegulator.integral) > 0.01f) { pidRegulator.integral = 0.0f; - Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); + Log.sinfoln(L_REGULATOR_PID, "Integral sum has been reset"); } this->turbo(); @@ -87,7 +85,7 @@ protected: } if (!settings.heating.turbo) { - Log.sinfoln(FPSTR(L_REGULATOR), F("Turbo mode auto disabled")); + Log.sinfoln(L_REGULATOR, "Turbo mode auto disabled"); } } } @@ -128,11 +126,11 @@ protected: if (fabsf(prevHeatingTarget - settings.heating.target) > 0.0001f) { prevHeatingTarget = settings.heating.target; - Log.sinfoln(FPSTR(L_REGULATOR), F("New target: %.2f"), settings.heating.target); + Log.sinfoln(L_REGULATOR, "New target: %.2f", settings.heating.target); /*if (settings.pid.enabled) { pidRegulator.integral = 0.0f; - Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); + Log.sinfoln(L_REGULATOR_PID, "Integral sum has been reset"); }*/ } @@ -179,7 +177,7 @@ protected: prevEtResult = etResult; newTemp += etResult; - Log.sinfoln(FPSTR(L_REGULATOR_EQUITHERM), F("New result: %.2f"), etResult); + Log.sinfoln(L_REGULATOR_EQUITHERM, "New result: %.2f", etResult); } else { newTemp += prevEtResult; @@ -204,7 +202,7 @@ protected: pidRegulator.integral = 0.0f; pidRegulator.getResultNow(); - Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); + Log.sinfoln(L_REGULATOR_PID, "Integral sum has been reset"); }*/ float error = pidRegulator.setpoint - pidRegulator.input; @@ -223,8 +221,8 @@ protected: prevPidResult = pidResult; newTemp += pidResult; - Log.sinfoln(FPSTR(L_REGULATOR_PID), F("New result: %.2f"), pidResult); - Log.straceln(FPSTR(L_REGULATOR_PID), F("Integral: %.2f"), pidRegulator.integral); + Log.sinfoln(L_REGULATOR_PID, "New result: %.2f", pidResult); + Log.straceln(L_REGULATOR_PID, "Integral: %.2f", pidRegulator.integral); } else { newTemp += prevPidResult; diff --git a/src/Sensors.h b/src/Sensors.h index d694a18..f67a8aa 100644 --- a/src/Sensors.h +++ b/src/Sensors.h @@ -253,13 +253,13 @@ public: rSensor.connected = true; Log.snoticeln( - FPSTR(L_SENSORS), F("#%hhu '%s' new status: CONNECTED"), + L_SENSORS, "#%hhu '%s' new status: CONNECTED", sensorId, sSensor.name ); } Log.snoticeln( - FPSTR(L_SENSORS), F("#%hhu '%s' new value %hhu: %.2f, compensated: %.2f, raw: %.2f"), + L_SENSORS, "#%hhu '%s' new value %hhu: %.2f, compensated: %.2f, raw: %.2f", sensorId, sSensor.name, valueId, rSensor.values[valueId], compensatedValue, value ); @@ -316,8 +316,8 @@ public: if (rSensor.connected != status) { Log.snoticeln( - FPSTR(L_SENSORS), F("#%hhu '%s' new status: %s"), - sensorId, sSensor.name, status ? F("CONNECTED") : F("DISCONNECTED") + L_SENSORS, "#%hhu '%s' new status: %s", + sensorId, sSensor.name, status ? "CONNECTED" : "DISCONNECTED" ); rSensor.connected = status; diff --git a/src/SensorsTask.h b/src/SensorsTask.h index 187a40e..120acb0 100644 --- a/src/SensorsTask.h +++ b/src/SensorsTask.h @@ -42,14 +42,14 @@ public: auto deviceRssi = device->getRSSI(); Log.sinfoln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': discovered device %s, name: %s, RSSI: %hhd"), + L_SENSORS_BLE, "Sensor #%hhu '%s': discovered device %s, name: %s, RSSI: %hhd", sensorId, sSensor.name, deviceAddress.toString().c_str(), deviceName.c_str(), deviceRssi ); if (!device->haveServiceData()) { Log.swarningln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': not found service data!"), + L_SENSORS_BLE, "Sensor #%hhu '%s': not found service data!", sensorId, sSensor.name ); return; @@ -57,7 +57,7 @@ public: auto serviceDataCount = device->getServiceDataCount(); Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found %hhu service data"), + L_SENSORS_BLE, "Sensor #%hhu '%s': found %hhu service data", sensorId, sSensor.name, serviceDataCount ); @@ -67,7 +67,7 @@ public: } else { Log.swarningln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': unsupported data format!"), + L_SENSORS_BLE, "Sensor #%hhu '%s': unsupported data format!", sensorId, sSensor.name ); } @@ -79,21 +79,21 @@ public: auto serviceData = device->getServiceData(serviceUuid); if (!serviceData.size()) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: not found ATC1441 data"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: not found ATC1441 data", sensorId, serviceUuid.toString().c_str() ); return false; } else if (serviceData.size() != 13) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: not in ATC1441 format"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: not in ATC1441 format", sensorId, serviceUuid.toString().c_str() ); return false; } Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: found ATC1441 format"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: found ATC1441 format", sensorId, serviceUuid.toString().c_str() ); @@ -116,8 +116,8 @@ public: // Log Log.snoticeln( - FPSTR(L_SENSORS_BLE), - F("Sensor #%hhu, received temp: %.2f; humidity: %.2f, battery voltage: %hu, battery level: %hhu"), + L_SENSORS_BLE, + "Sensor #%hhu, received temp: %.2f; humidity: %.2f, battery voltage: %hu, battery level: %hhu", sensorId, temperature, humidity, batteryMv, batteryLevel ); @@ -130,21 +130,21 @@ public: auto serviceData = device->getServiceData(serviceUuid); if (!serviceData.size()) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: not found PVVX data"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: not found PVVX data", sensorId, serviceUuid.toString().c_str() ); return false; } else if (serviceData.size() != 15) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: not in PVVX format"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: not in PVVX format", sensorId, serviceUuid.toString().c_str() ); return false; } Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: found PVVX format"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: found PVVX format", sensorId, serviceUuid.toString().c_str() ); @@ -169,8 +169,8 @@ public: // Log Log.snoticeln( - FPSTR(L_SENSORS_BLE), - F("Sensor #%hhu, received temp: %.2f; humidity: %.2f, battery voltage: %hu, battery level: %hhu"), + L_SENSORS_BLE, + "Sensor #%hhu, received temp: %.2f; humidity: %.2f, battery voltage: %hu, battery level: %hhu", sensorId, temperature, humidity, batteryMv, batteryLevel ); @@ -183,28 +183,28 @@ public: auto serviceData = device->getServiceData(serviceUuid); if (!serviceData.size()) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: not found BTHome data"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: not found BTHome data", sensorId, serviceUuid.toString().c_str() ); return false; } else if ((serviceData[0] & 0xE0) != 0x40) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: unsupported BTHome version"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: unsupported BTHome version", sensorId, serviceUuid.toString().c_str() ); return false; } else if ((serviceData[0] & 0x01) != 0) { Log.straceln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: unsupported BTHome encrypted data"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: unsupported BTHome encrypted data", sensorId, serviceUuid.toString().c_str() ); return false; } Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, service %s: found BTHome format"), + L_SENSORS_BLE, "Sensor #%hhu, service %s: found BTHome format", sensorId, serviceUuid.toString().c_str() ); @@ -231,7 +231,7 @@ public: foundData = true; Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, received battery level: %hhu"), + L_SENSORS_BLE, "Sensor #%hhu, received battery level: %hhu", sensorId, batteryLevel ); break; @@ -251,7 +251,7 @@ public: foundData = true; Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, received temp: %.2f"), + L_SENSORS_BLE, "Sensor #%hhu, received temp: %.2f", sensorId, temperature ); break; @@ -271,7 +271,7 @@ public: foundData = true; Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, received humidity: %.2f"), + L_SENSORS_BLE, "Sensor #%hhu, received humidity: %.2f", sensorId, humidity ); break; @@ -289,7 +289,7 @@ public: foundData = true; Log.snoticeln( - FPSTR(L_SENSORS_BLE), F("Sensor #%hhu, received battery voltage: %hu"), + L_SENSORS_BLE, "Sensor #%hhu, received battery voltage: %hu", sensorId, batteryMv ); break; @@ -359,7 +359,6 @@ protected: #endif unsigned long globalLastPollingTime = 0; - #if defined(ARDUINO_ARCH_ESP32) const char* getTaskName() override { return "Sensors"; } @@ -380,7 +379,6 @@ protected: int getTaskPriority() override { return 4; } - #endif void loop() { if (vars.states.restarting || vars.states.upgrading) { @@ -493,7 +491,7 @@ protected: instance.setOneWire(&owInstance); instance.setWaitForConversion(false); - Log.sinfoln(FPSTR(L_SENSORS_DALLAS), F("Started on GPIO %hhu"), sSensor.gpio); + Log.sinfoln(L_SENSORS_DALLAS, "Started on GPIO %hhu", sSensor.gpio); } } @@ -524,7 +522,7 @@ protected: this->dallasPolling.erase(gpio); this->gpioLastPollingTime.erase(gpio); - Log.sinfoln(FPSTR(L_SENSORS_DALLAS), F("Stopped on GPIO %hhu"), gpio); + Log.sinfoln(L_SENSORS_DALLAS, "Stopped on GPIO %hhu", gpio); continue; } @@ -549,8 +547,8 @@ protected: instance.begin(); Log.straceln( - FPSTR(L_SENSORS_DALLAS), - F("GPIO %hhu, devices on bus: %hhu, DS18* devices: %hhu"), + L_SENSORS_DALLAS, + "GPIO %hhu, devices on bus: %hhu, DS18* devices: %hhu", gpio, instance.getDeviceCount(), instance.getDS18Count() ); } @@ -616,7 +614,7 @@ protected: fsSensorsSettings.update(); Log.straceln( - FPSTR(L_SENSORS_DALLAS), F("GPIO %hhu, sensor #%hhu '%s', set address: %hhX:%hhX:%hhX:%hhX:%hhX:%hhX:%hhX:%hhX"), + L_SENSORS_DALLAS, "GPIO %hhu, sensor #%hhu '%s', set address: %hhX:%hhX:%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", sSensor.gpio, sensorId, sSensor.name, sSensor.address[0], sSensor.address[1], sSensor.address[2], sSensor.address[3], sSensor.address[4], sSensor.address[5], sSensor.address[6], sSensor.address[7] @@ -667,7 +665,7 @@ protected: float value = instance.getTempC(sSensor.address); if (value == DEVICE_DISCONNECTED_C) { Log.swarningln( - FPSTR(L_SENSORS_DALLAS), F("GPIO %hhu, sensor #%hhu '%s': failed receiving data"), + L_SENSORS_DALLAS, "GPIO %hhu, sensor #%hhu '%s': failed receiving data", sSensor.gpio, sensorId, sSensor.name ); @@ -679,7 +677,7 @@ protected: } Log.straceln( - FPSTR(L_SENSORS_DALLAS), F("GPIO %hhu, sensor #%hhu '%s', received data: %.2f"), + L_SENSORS_DALLAS, "GPIO %hhu, sensor #%hhu '%s', received data: %.2f", sSensor.gpio, sensorId, sSensor.name, value ); @@ -708,7 +706,7 @@ protected: this->dallasPolling[gpio] = true; this->gpioLastPollingTime[gpio] = ts; - Log.straceln(FPSTR(L_SENSORS_DALLAS), F("GPIO %hhu, polling..."), gpio); + Log.straceln(L_SENSORS_DALLAS, "GPIO %hhu, polling...", gpio); } } } @@ -741,7 +739,7 @@ protected: auto& sSensor = Sensors::settings[sensorId]; Log.straceln( - FPSTR(L_SENSORS_DHT), F("GPIO %hhu, sensor #%hhu '%s', temp: %.2f, humidity: %.2f%%"), + L_SENSORS_DHT, "GPIO %hhu, sensor #%hhu '%s', temp: %.2f, humidity: %.2f%%", sSensor.gpio, sensorId, sSensor.name, temperature, humidity ); @@ -764,7 +762,7 @@ protected: auto& sSensor = Sensors::settings[sensorId]; Log.swarningln( - FPSTR(L_SENSORS_DHT), F("GPIO %hhu, sensor #%hhu '%s': failed receiving data (err: %s)"), + L_SENSORS_DHT, "GPIO %hhu, sensor #%hhu '%s': failed receiving data (err: %s)", sSensor.gpio, sensorId, sSensor.name, DHT::statusToString(this->dhtInstance.getStatus()) ); @@ -786,11 +784,11 @@ protected: } if (this->dhtInstance.setup(sensorGpio, sType)) { - Log.sinfoln(FPSTR(L_SENSORS_DHT), F("Started on GPIO %hhu"), sSensor.gpio); + Log.sinfoln(L_SENSORS_DHT, "Started on GPIO %hhu", sSensor.gpio); } else { Log.swarningln( - FPSTR(L_SENSORS_DHT), F("Failed to start on GPIO %hhu (err: %s)"), + L_SENSORS_DHT, "Failed to start on GPIO %hhu (err: %s)", sSensor.gpio, DHT::statusToString(this->dhtInstance.getStatus()) ); } @@ -810,11 +808,7 @@ protected: continue; } - #ifdef ARDUINO_ARCH_ESP32 const auto value = analogReadMilliVolts(sSensor.gpio); - #else - const auto value = analogRead(sSensor.gpio) / 1023 * DEFAULT_NTC_VREF; - #endif if (value < DEFAULT_NTC_VLOW_TRESHOLD || value > DEFAULT_NTC_VHIGH_TRESHOLD) { if (Sensors::getConnectionStatusById(sensorId)) { @@ -822,7 +816,7 @@ protected: } Log.swarningln( - FPSTR(L_SENSORS_NTC), F("GPIO %hhu, sensor #%hhu '%s', voltage is out of threshold: %.3f"), + L_SENSORS_NTC, "GPIO %hhu, sensor #%hhu '%s', voltage is out of threshold: %.3f", sSensor.gpio, sensorId, sSensor.name, (value / 1000.0f) ); @@ -838,7 +832,7 @@ protected: ) - 273.15f; Log.straceln( - FPSTR(L_SENSORS_NTC), F("GPIO %hhu, sensor #%hhu '%s', raw temp: %.2f, raw voltage: %.3f, raw resistance: %.2f"), + L_SENSORS_NTC, "GPIO %hhu, sensor #%hhu '%s', raw temp: %.2f, raw voltage: %.3f, raw resistance: %.2f", sSensor.gpio, sensorId, sSensor.name, rawTemp, (value / 1000.0f), sensorResistance ); @@ -862,10 +856,10 @@ protected: if (this->pBLEScan == nullptr) { if (NimBLEDevice::deinit(true)) { - Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Deinitialized")); + Log.sinfoln(L_SENSORS_BLE, "Deinitialized"); } else { - Log.swarningln(FPSTR(L_SENSORS_BLE), F("Unable to deinitialize!")); + Log.swarningln(L_SENSORS_BLE, "Unable to deinitialize!"); } } } @@ -875,7 +869,7 @@ protected: if (!NimBLEDevice::isInitialized() && millis() > 5000) { if (NimBLEDevice::init(PROJECT_NAME)) { - Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Initialized")); + Log.sinfoln(L_SENSORS_BLE, "Initialized"); #ifdef ESP_PWR_LVL_P20 NimBLEDevice::setPower(ESP_PWR_LVL_P20); @@ -884,7 +878,7 @@ protected: #endif } else { - Log.swarningln(FPSTR(L_SENSORS_BLE), F("Unable to initialize!")); + Log.swarningln(L_SENSORS_BLE, "Unable to initialize!"); return; } } @@ -900,7 +894,7 @@ protected: this->pBLEScan->setInterval(10000); this->pBLEScan->setWindow(10000); - Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Scanning initialized")); + Log.sinfoln(L_SENSORS_BLE, "Scanning initialized"); } if (!this->pBLEScan->isScanning()) { @@ -909,13 +903,13 @@ protected: if (this->pBLEScan->start(30000, false, false)) { Log.sinfoln( - FPSTR(L_SENSORS_BLE), - F("%s scanning started"), + L_SENSORS_BLE, + "%s scanning started", this->activeScanBle ? "Active" : "Passive" ); } else { - Log.sinfoln(FPSTR(L_SENSORS_BLE), F("Unable to start scanning")); + Log.sinfoln(L_SENSORS_BLE, "Unable to start scanning"); } } } diff --git a/src/defines.h b/src/defines.h index 8a56039..ad6f2e1 100644 --- a/src/defines.h +++ b/src/defines.h @@ -146,15 +146,7 @@ #define DEFAULT_EXT_PUMP_GPIO GPIO_IS_NOT_CONFIGURED #endif -#ifndef PROGMEM - #define PROGMEM // NOLINT -#endif - -#ifdef ARDUINO_ARCH_ESP32 - #include -#elif !defined(GPIO_IS_VALID_GPIO) - #define GPIO_IS_VALID_GPIO(gpioNum) (gpioNum >= 0 && gpioNum <= 17) -#endif +#include #define GPIO_IS_VALID(gpioNum) (gpioNum != GPIO_IS_NOT_CONFIGURED && GPIO_IS_VALID_GPIO(gpioNum)) diff --git a/src/main.cpp b/src/main.cpp index 950282a..ac0a024 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,9 @@ #include + +#if !defined(ARDUINO_ARCH_ESP32) + #error Only ESP32 boards are supported +#endif + #include #include #include @@ -14,13 +19,7 @@ #include "Settings.h" #include "utils.h" -#if defined(ARDUINO_ARCH_ESP32) - #include -#elif defined(ARDUINO_ARCH_ESP8266) - #include -#else - #error Wrong board. Supported boards: esp8266, esp32 -#endif +#include #include #include @@ -83,17 +82,17 @@ void setup() { // Network settings switch (fsNetworkSettings.read()) { case FD_FS_ERR: - Log.swarningln(FPSTR(L_NETWORK_SETTINGS), F("Filesystem error, load default")); + Log.swarningln(L_NETWORK_SETTINGS, "Filesystem error, load default"); break; case FD_FILE_ERR: - Log.swarningln(FPSTR(L_NETWORK_SETTINGS), F("Bad data, load default")); + Log.swarningln(L_NETWORK_SETTINGS, "Bad data, load default"); break; case FD_WRITE: - Log.sinfoln(FPSTR(L_NETWORK_SETTINGS), F("Not found, load default")); + Log.sinfoln(L_NETWORK_SETTINGS, "Not found, load default"); break; case FD_ADD: case FD_READ: - Log.sinfoln(FPSTR(L_NETWORK_SETTINGS), F("Loaded")); + Log.sinfoln(L_NETWORK_SETTINGS, "Loaded"); break; default: break; @@ -128,20 +127,20 @@ void setup() { // Settings switch (fsSettings.read()) { case FD_FS_ERR: - Log.swarningln(FPSTR(L_SETTINGS), F("Filesystem error, load default")); + Log.swarningln(L_SETTINGS, "Filesystem error, load default"); break; case FD_FILE_ERR: - Log.swarningln(FPSTR(L_SETTINGS), F("Bad data, load default")); + Log.swarningln(L_SETTINGS, "Bad data, load default"); break; case FD_WRITE: - Log.sinfoln(FPSTR(L_SETTINGS), F("Not found, load default")); + Log.sinfoln(L_SETTINGS, "Not found, load default"); break; case FD_ADD: case FD_READ: - Log.sinfoln(FPSTR(L_SETTINGS), F("Loaded")); + Log.sinfoln(L_SETTINGS, "Loaded"); if (strcmp(SETTINGS_VALID_VALUE, settings.validationValue) != 0) { - Log.swarningln(FPSTR(L_SETTINGS), F("Not valid, set default and restart...")); + Log.swarningln(L_SETTINGS, "Not valid, set default and restart..."); fsSettings.reset(); ::delay(5000); ESP.restart(); @@ -184,17 +183,17 @@ void setup() { // Sensors settings switch (fsSensorsSettings.read()) { case FD_FS_ERR: - Log.swarningln(FPSTR(L_SENSORS), F("Filesystem error, load default")); + Log.swarningln(L_SENSORS, "Filesystem error, load default"); break; case FD_FILE_ERR: - Log.swarningln(FPSTR(L_SENSORS), F("Bad data, load default")); + Log.swarningln(L_SENSORS, "Bad data, load default"); break; case FD_WRITE: - Log.sinfoln(FPSTR(L_SENSORS), F("Not found, load default")); + Log.sinfoln(L_SENSORS, "Not found, load default"); break; case FD_ADD: case FD_READ: - Log.sinfoln(FPSTR(L_SENSORS), F("Loaded")); + Log.sinfoln(L_SENSORS, "Loaded"); default: break; } @@ -223,7 +222,5 @@ void setup() { } void loop() { -#if defined(ARDUINO_ARCH_ESP32) vTaskDelete(NULL); -#endif } diff --git a/src/strings.h b/src/strings.h index 8353618..b7f2eb8 100644 --- a/src/strings.h +++ b/src/strings.h @@ -1,229 +1,226 @@ #pragma once -#ifndef PROGMEM - #define PROGMEM // NOLINT -#endif -const char L_SETTINGS[] PROGMEM = "SETTINGS"; -const char L_SETTINGS_OT[] PROGMEM = "SETTINGS.OT"; -const char L_SETTINGS_DHW[] PROGMEM = "SETTINGS.DHW"; -const char L_SETTINGS_HEATING[] PROGMEM = "SETTINGS.HEATING"; -const char L_NETWORK[] PROGMEM = "NETWORK"; -const char L_NETWORK_SETTINGS[] PROGMEM = "NETWORK.SETTINGS"; -const char L_PORTAL_WEBSERVER[] PROGMEM = "PORTAL.WEBSERVER"; -const char L_PORTAL_DNSSERVER[] PROGMEM = "PORTAL.DNSSERVER"; -const char L_PORTAL_CAPTIVE[] PROGMEM = "PORTAL.CAPTIVE"; -const char L_PORTAL_OTA[] PROGMEM = "PORTAL.OTA"; -const char L_MAIN[] PROGMEM = "MAIN"; -const char L_MQTT[] PROGMEM = "MQTT"; -const char L_MQTT_HA[] PROGMEM = "MQTT.HA"; -const char L_MQTT_MSG[] PROGMEM = "MQTT.MSG"; -const char L_OT[] PROGMEM = "OT"; -const char L_OT_DHW[] PROGMEM = "OT.DHW"; -const char L_OT_HEATING[] PROGMEM = "OT.HEATING"; -const char L_OT_CH2[] PROGMEM = "OT.CH2"; -const char L_SENSORS[] PROGMEM = "SENSORS"; -const char L_SENSORS_SETTINGS[] PROGMEM = "SENSORS.SETTINGS"; -const char L_SENSORS_DALLAS[] PROGMEM = "SENSORS.DALLAS"; -const char L_SENSORS_DHT[] PROGMEM = "SENSORS.DHT"; -const char L_SENSORS_NTC[] PROGMEM = "SENSORS.NTC"; -const char L_SENSORS_BLE[] PROGMEM = "SENSORS.BLE"; -const char L_REGULATOR[] PROGMEM = "REGULATOR"; -const char L_REGULATOR_PID[] PROGMEM = "REGULATOR.PID"; -const char L_REGULATOR_EQUITHERM[] PROGMEM = "REGULATOR.EQUITHERM"; -const char L_CASCADE_INPUT[] PROGMEM = "CASCADE.INPUT"; -const char L_CASCADE_OUTPUT[] PROGMEM = "CASCADE.OUTPUT"; -const char L_EXTPUMP[] PROGMEM = "EXTPUMP"; +const char L_SETTINGS[] = "SETTINGS"; +const char L_SETTINGS_OT[] = "SETTINGS.OT"; +const char L_SETTINGS_DHW[] = "SETTINGS.DHW"; +const char L_SETTINGS_HEATING[] = "SETTINGS.HEATING"; +const char L_NETWORK[] = "NETWORK"; +const char L_NETWORK_SETTINGS[] = "NETWORK.SETTINGS"; +const char L_PORTAL_WEBSERVER[] = "PORTAL.WEBSERVER"; +const char L_PORTAL_DNSSERVER[] = "PORTAL.DNSSERVER"; +const char L_PORTAL_CAPTIVE[] = "PORTAL.CAPTIVE"; +const char L_PORTAL_OTA[] = "PORTAL.OTA"; +const char L_MAIN[] = "MAIN"; +const char L_MQTT[] = "MQTT"; +const char L_MQTT_HA[] = "MQTT.HA"; +const char L_MQTT_MSG[] = "MQTT.MSG"; +const char L_OT[] = "OT"; +const char L_OT_DHW[] = "OT.DHW"; +const char L_OT_HEATING[] = "OT.HEATING"; +const char L_OT_CH2[] = "OT.CH2"; +const char L_SENSORS[] = "SENSORS"; +const char L_SENSORS_SETTINGS[] = "SENSORS.SETTINGS"; +const char L_SENSORS_DALLAS[] = "SENSORS.DALLAS"; +const char L_SENSORS_DHT[] = "SENSORS.DHT"; +const char L_SENSORS_NTC[] = "SENSORS.NTC"; +const char L_SENSORS_BLE[] = "SENSORS.BLE"; +const char L_REGULATOR[] = "REGULATOR"; +const char L_REGULATOR_PID[] = "REGULATOR.PID"; +const char L_REGULATOR_EQUITHERM[] = "REGULATOR.EQUITHERM"; +const char L_CASCADE_INPUT[] = "CASCADE.INPUT"; +const char L_CASCADE_OUTPUT[] = "CASCADE.OUTPUT"; +const char L_EXTPUMP[] = "EXTPUMP"; -const char S_ACTIONS[] PROGMEM = "actions"; -const char S_ACTIVE[] PROGMEM = "active"; -const char S_ADDRESS[] PROGMEM = "address"; -const char S_ANTI_STUCK_INTERVAL[] PROGMEM = "antiStuckInterval"; -const char S_ANTI_STUCK_TIME[] PROGMEM = "antiStuckTime"; -const char S_AP[] PROGMEM = "ap"; -const char S_APP_VERSION[] PROGMEM = "appVersion"; -const char S_AUTH[] PROGMEM = "auth"; -const char S_AUTO_DIAG_RESET[] PROGMEM = "autoDiagReset"; -const char S_AUTO_FAULT_RESET[] PROGMEM = "autoFaultReset"; -const char S_BACKTRACE[] PROGMEM = "backtrace"; -const char S_BATTERY[] PROGMEM = "battery"; -const char S_BAUDRATE[] PROGMEM = "baudrate"; -const char S_BLOCKING[] PROGMEM = "blocking"; -const char S_BSSID[] PROGMEM = "bssid"; -const char S_BUILD[] PROGMEM = "build"; -const char S_CASCADE_CONTROL[] PROGMEM = "cascadeControl"; -const char S_CHANNEL[] PROGMEM = "channel"; -const char S_CH2_ALWAYS_ENABLED[] PROGMEM = "ch2AlwaysEnabled"; -const char S_CH2_DISABLING_ACTION[] PROGMEM = "ch2DisablingAction"; -const char S_CHIP[] PROGMEM = "chip"; -const char S_CODE[] PROGMEM = "code"; -const char S_COMMIT[] PROGMEM = "commit"; -const char S_CONNECTED[] PROGMEM = "connected"; -const char S_CONTINUES[] PROGMEM = "continues"; -const char S_COOLING[] PROGMEM = "cooling"; -const char S_COOLING_SUPPORT[] PROGMEM = "coolingSupport"; -const char S_CORE[] PROGMEM = "core"; -const char S_CORES[] PROGMEM = "cores"; -const char S_CRASH[] PROGMEM = "crash"; -const char S_CURRENT_TEMP[] PROGMEM = "currentTemp"; -const char S_DATA[] PROGMEM = "data"; -const char S_DATE[] PROGMEM = "date"; -const char S_DEADBAND[] PROGMEM = "deadband"; -const char S_DHW[] PROGMEM = "dhw"; -const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking"; -const char S_DHW_DISABLING_ACTION[] PROGMEM = "dhwDisablingAction"; -const char S_DHW_STATE_AS_DHW_BLOCKING[] PROGMEM = "dhwStateAsDhwBlocking"; -const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport"; -const char S_DHW_TO_CH2[] PROGMEM = "dhwToCh2"; -const char S_DIAG[] PROGMEM = "diag"; -const char S_DNS[] PROGMEM = "dns"; -const char S_DT[] PROGMEM = "dt"; -const char S_D_FACTOR[] PROGMEM = "d_factor"; -const char S_D_MULTIPLIER[] PROGMEM = "d_multiplier"; -const char S_EMERGENCY[] PROGMEM = "emergency"; -const char S_ENABLED[] PROGMEM = "enabled"; -const char S_ENV[] PROGMEM = "env"; -const char S_EPC[] PROGMEM = "epc"; -const char S_EQUITHERM[] PROGMEM = "equitherm"; -const char S_EXPONENT[] PROGMEM = "exponent"; -const char S_EXTERNAL_PUMP[] PROGMEM = "externalPump"; -const char S_FACTOR[] PROGMEM = "factor"; -const char S_FAULT[] PROGMEM = "fault"; -const char S_FREEZE_PROTECTION[] PROGMEM = "freezeProtection"; -const char S_FREEZING[] PROGMEM = "freezing"; -const char S_FILTERING[] PROGMEM = "filtering"; -const char S_FILTERING_FACTOR[] PROGMEM = "filteringFactor"; -const char S_FLAGS[] PROGMEM = "flags"; -const char S_FLAME[] PROGMEM = "flame"; -const char S_FLASH[] PROGMEM = "flash"; -const char S_FREE[] PROGMEM = "free"; -const char S_FREQ[] PROGMEM = "freq"; -const char S_GATEWAY[] PROGMEM = "gateway"; -const char S_GET_MIN_MAX_TEMP[] PROGMEM = "getMinMaxTemp"; -const char S_GPIO[] PROGMEM = "gpio"; -const char S_HEAP[] PROGMEM = "heap"; -const char S_HEATING[] PROGMEM = "heating"; -const char S_HEATING_DISABLING_ACTION[] PROGMEM = "heatingDisablingAction"; -const char S_HEATING_TO_CH2[] PROGMEM = "heatingToCh2"; -const char S_HEATING_STATE_TO_SUMMER_WINTER_MODE[] PROGMEM = "heatingStateToSummerWinterMode"; -const char S_HIDDEN[] PROGMEM = "hidden"; -const char S_HIGH_TEMP[] PROGMEM = "highTemp"; -const char S_HOME_ASSISTANT_DISCOVERY[] PROGMEM = "homeAssistantDiscovery"; -const char S_HOSTNAME[] PROGMEM = "hostname"; -const char S_HUMIDITY[] PROGMEM = "humidity"; -const char S_HYSTERESIS[] PROGMEM = "hysteresis"; -const char S_ID[] PROGMEM = "id"; -const char S_IGNORE_DIAG_STATE[] PROGMEM = "ignoreDiagState"; -const char S_IMMERGAS_FIX[] PROGMEM = "immergasFix"; -const char S_ALWAYS_SEND_INDOOR_TEMP[] PROGMEM = "alwaysSendIndoorTemp"; -const char S_INDOOR_TEMP[] PROGMEM = "indoorTemp"; -const char S_INDOOR_TEMP_AVG_TYPE[] PROGMEM = "indoorTempAvgType"; -const char S_INDOOR_TEMP_CONTROL[] PROGMEM = "indoorTempControl"; -const char S_IN_GPIO[] PROGMEM = "inGpio"; -const char S_INPUT[] PROGMEM = "input"; -const char S_INTERVAL[] PROGMEM = "interval"; -const char S_INVERT_STATE[] PROGMEM = "invertState"; -const char S_IP[] PROGMEM = "ip"; -const char S_I_FACTOR[] PROGMEM = "i_factor"; -const char S_I_MULTIPLIER[] PROGMEM = "i_multiplier"; -const char S_LOGIN[] PROGMEM = "login"; -const char S_LOG_LEVEL[] PROGMEM = "logLevel"; -const char S_LOW_TEMP[] PROGMEM = "lowTemp"; -const char S_MAC[] PROGMEM = "mac"; -const char S_MASTER[] PROGMEM = "master"; -const char S_MAX[] PROGMEM = "max"; -const char S_MAX_FREE_BLOCK[] PROGMEM = "maxFreeBlock"; -const char S_MAX_MODULATION[] PROGMEM = "maxModulation"; -const char S_MAX_POWER[] PROGMEM = "maxPower"; -const char S_MAX_TEMP[] PROGMEM = "maxTemp"; -const char S_MAX_TEMP_SYNC_WITH_TARGET_TEMP[] PROGMEM = "maxTempSyncWithTargetTemp"; -const char S_MDNS[] PROGMEM = "mdns"; -const char S_MEMBER_ID[] PROGMEM = "memberId"; -const char S_MIN[] PROGMEM = "min"; -const char S_MIN_FREE[] PROGMEM = "minFree"; -const char S_MIN_MAX_FREE_BLOCK[] PROGMEM = "minMaxFreeBlock"; -const char S_MIN_POWER[] PROGMEM = "minPower"; -const char S_MIN_TEMP[] PROGMEM = "minTemp"; -const char S_MODEL[] PROGMEM = "model"; -const char S_MODULATION[] PROGMEM = "modulation"; -const char S_MQTT[] PROGMEM = "mqtt"; -const char S_NAME[] PROGMEM = "name"; -const char S_NATIVE_OTC[] PROGMEM = "nativeOTC"; -const char S_NETWORK[] PROGMEM = "network"; -const char S_NTP[] PROGMEM = "ntp"; -const char S_OFFSET[] PROGMEM = "offset"; -const char S_ON_ENABLED_HEATING[] PROGMEM = "onEnabledHeating"; -const char S_ON_FAULT[] PROGMEM = "onFault"; -const char S_ON_LOSS_CONNECTION[] PROGMEM = "onLossConnection"; -const char S_OPENTHERM[] PROGMEM = "opentherm"; -const char S_OPTIONS[] PROGMEM = "options"; -const char S_OUTDOOR_TEMP[] PROGMEM = "outdoorTemp"; -const char S_OUTDOOR_TEMP_AVG_TYPE[] PROGMEM = "outdoorTempAvgType"; -const char S_OUT_GPIO[] PROGMEM = "outGpio"; -const char S_OUTPUT[] PROGMEM = "output"; -const char S_OVERHEAT[] PROGMEM = "overheat"; -const char S_OVERHEAT_PROTECTION[] PROGMEM = "overheatProtection"; -const char S_PASSWORD[] PROGMEM = "password"; -const char S_PID[] PROGMEM = "pid"; -const char S_PORT[] PROGMEM = "port"; -const char S_PORTAL[] PROGMEM = "portal"; -const char S_POST_CIRCULATION_TIME[] PROGMEM = "postCirculationTime"; -const char S_POWER[] PROGMEM = "power"; -const char S_PREFIX[] PROGMEM = "prefix"; -const char S_PROTOCOL_VERSION[] PROGMEM = "protocolVersion"; -const char S_PURPOSE[] PROGMEM = "purpose"; -const char S_PSRAM[] PROGMEM = "psram"; -const char S_P_FACTOR[] PROGMEM = "p_factor"; -const char S_P_MULTIPLIER[] PROGMEM = "p_multiplier"; -const char S_REAL_SIZE[] PROGMEM = "realSize"; -const char S_REASON[] PROGMEM = "reason"; -const char S_RESET_DIAGNOSTIC[] PROGMEM = "resetDiagnostic"; -const char S_RESET_FAULT[] PROGMEM = "resetFault"; -const char S_RESET_REASON[] PROGMEM = "resetReason"; -const char S_RESTART[] PROGMEM = "restart"; -const char S_RETURN_TEMP[] PROGMEM = "returnTemp"; -const char S_REV[] PROGMEM = "rev"; -const char S_RSSI[] PROGMEM = "rssi"; -const char S_RX_LED_GPIO[] PROGMEM = "rxLedGpio"; -const char S_SDK[] PROGMEM = "sdk"; -const char S_SENSORS[] PROGMEM = "sensors"; -const char S_SERIAL[] PROGMEM = "serial"; -const char S_SERVER[] PROGMEM = "server"; -const char S_SETTINGS[] PROGMEM = "settings"; -const char S_SET_DATE_AND_TIME[] PROGMEM = "setDateAndTime"; -const char S_SHIFT[] PROGMEM = "shift"; -const char S_SIGNAL_QUALITY[] PROGMEM = "signalQuality"; -const char S_SIZE[] PROGMEM = "size"; -const char S_SLAVE[] PROGMEM = "slave"; -const char S_SLOPE[] PROGMEM = "slope"; -const char S_SSID[] PROGMEM = "ssid"; -const char S_STA[] PROGMEM = "sta"; -const char S_STATE[] PROGMEM = "state"; -const char S_STATIC_CONFIG[] PROGMEM = "staticConfig"; -const char S_STATUS_LED_GPIO[] PROGMEM = "statusLedGpio"; -const char S_SETPOINT[] PROGMEM = "setpoint"; -const char S_SETPOINT_TEMP[] PROGMEM = "setpointTemp"; -const char S_SUBNET[] PROGMEM = "subnet"; -const char S_SUMMER_WINTER_MODE[] PROGMEM = "summerWinterMode"; -const char S_SYSTEM[] PROGMEM = "system"; -const char S_TARGET[] PROGMEM = "target"; -const char S_TARGET_DIFF_FACTOR[] PROGMEM = "targetDiffFactor"; -const char S_TARGET_TEMP[] PROGMEM = "targetTemp"; -const char S_TEMPERATURE[] PROGMEM = "temperature"; -const char S_THRESHOLD_HIGH[] PROGMEM = "thresholdHigh"; -const char S_THRESHOLD_LOW[] PROGMEM = "thresholdLow"; -const char S_THRESHOLD_TIME[] PROGMEM = "thresholdTime"; -const char S_TIMEZONE[] PROGMEM = "timezone"; -const char S_TOTAL[] PROGMEM = "total"; -const char S_TRESHOLD_TIME[] PROGMEM = "tresholdTime"; -const char S_TURBO[] PROGMEM = "turbo"; -const char S_TURBO_FACTOR[] PROGMEM = "turboFactor"; -const char S_TYPE[] PROGMEM = "type"; -const char S_UNIT_SYSTEM[] PROGMEM = "unitSystem"; -const char S_UPTIME[] PROGMEM = "uptime"; -const char S_USE[] PROGMEM = "use"; -const char S_USE_DHCP[] PROGMEM = "useDhcp"; -const char S_USER[] PROGMEM = "user"; -const char S_VALUE[] PROGMEM = "value"; -const char S_VERSION[] PROGMEM = "version"; -const char S_WEBSERIAL[] PROGMEM = "webSerial"; +const char S_ACTIONS[] = "actions"; +const char S_ACTIVE[] = "active"; +const char S_ADDRESS[] = "address"; +const char S_ANTI_STUCK_INTERVAL[] = "antiStuckInterval"; +const char S_ANTI_STUCK_TIME[] = "antiStuckTime"; +const char S_AP[] = "ap"; +const char S_APP_VERSION[] = "appVersion"; +const char S_AUTH[] = "auth"; +const char S_AUTO_DIAG_RESET[] = "autoDiagReset"; +const char S_AUTO_FAULT_RESET[] = "autoFaultReset"; +const char S_BACKTRACE[] = "backtrace"; +const char S_BATTERY[] = "battery"; +const char S_BAUDRATE[] = "baudrate"; +const char S_BLOCKING[] = "blocking"; +const char S_BSSID[] = "bssid"; +const char S_BUILD[] = "build"; +const char S_CASCADE_CONTROL[] = "cascadeControl"; +const char S_CHANNEL[] = "channel"; +const char S_CH2_ALWAYS_ENABLED[] = "ch2AlwaysEnabled"; +const char S_CH2_DISABLING_ACTION[] = "ch2DisablingAction"; +const char S_CHIP[] = "chip"; +const char S_CODE[] = "code"; +const char S_COMMIT[] = "commit"; +const char S_CONNECTED[] = "connected"; +const char S_CONTINUES[] = "continues"; +const char S_COOLING[] = "cooling"; +const char S_COOLING_SUPPORT[] = "coolingSupport"; +const char S_CORE[] = "core"; +const char S_CORES[] = "cores"; +const char S_CRASH[] = "crash"; +const char S_CURRENT_TEMP[] = "currentTemp"; +const char S_DATA[] = "data"; +const char S_DATE[] = "date"; +const char S_DEADBAND[] = "deadband"; +const char S_DHW[] = "dhw"; +const char S_DHW_BLOCKING[] = "dhwBlocking"; +const char S_DHW_DISABLING_ACTION[] = "dhwDisablingAction"; +const char S_DHW_STATE_AS_DHW_BLOCKING[] = "dhwStateAsDhwBlocking"; +const char S_DHW_SUPPORT[] = "dhwSupport"; +const char S_DHW_TO_CH2[] = "dhwToCh2"; +const char S_DIAG[] = "diag"; +const char S_DNS[] = "dns"; +const char S_DT[] = "dt"; +const char S_D_FACTOR[] = "d_factor"; +const char S_D_MULTIPLIER[] = "d_multiplier"; +const char S_EMERGENCY[] = "emergency"; +const char S_ENABLED[] = "enabled"; +const char S_ENV[] = "env"; +const char S_EPC[] = "epc"; +const char S_EQUITHERM[] = "equitherm"; +const char S_EXPONENT[] = "exponent"; +const char S_EXTERNAL_PUMP[] = "externalPump"; +const char S_FACTOR[] = "factor"; +const char S_FAULT[] = "fault"; +const char S_FREEZE_PROTECTION[] = "freezeProtection"; +const char S_FREEZING[] = "freezing"; +const char S_FILTERING[] = "filtering"; +const char S_FILTERING_FACTOR[] = "filteringFactor"; +const char S_FLAGS[] = "flags"; +const char S_FLAME[] = "flame"; +const char S_FLASH[] = "flash"; +const char S_FREE[] = "free"; +const char S_FREQ[] = "freq"; +const char S_GATEWAY[] = "gateway"; +const char S_GET_MIN_MAX_TEMP[] = "getMinMaxTemp"; +const char S_GPIO[] = "gpio"; +const char S_HEAP[] = "heap"; +const char S_HEATING[] = "heating"; +const char S_HEATING_DISABLING_ACTION[] = "heatingDisablingAction"; +const char S_HEATING_TO_CH2[] = "heatingToCh2"; +const char S_HEATING_STATE_TO_SUMMER_WINTER_MODE[] = "heatingStateToSummerWinterMode"; +const char S_HIDDEN[] = "hidden"; +const char S_HIGH_TEMP[] = "highTemp"; +const char S_HOME_ASSISTANT_DISCOVERY[] = "homeAssistantDiscovery"; +const char S_HOSTNAME[] = "hostname"; +const char S_HUMIDITY[] = "humidity"; +const char S_HYSTERESIS[] = "hysteresis"; +const char S_ID[] = "id"; +const char S_IGNORE_DIAG_STATE[] = "ignoreDiagState"; +const char S_IMMERGAS_FIX[] = "immergasFix"; +const char S_ALWAYS_SEND_INDOOR_TEMP[] = "alwaysSendIndoorTemp"; +const char S_INDOOR_TEMP[] = "indoorTemp"; +const char S_INDOOR_TEMP_AVG_TYPE[] = "indoorTempAvgType"; +const char S_INDOOR_TEMP_CONTROL[] = "indoorTempControl"; +const char S_IN_GPIO[] = "inGpio"; +const char S_INPUT[] = "input"; +const char S_INTERVAL[] = "interval"; +const char S_INVERT_STATE[] = "invertState"; +const char S_IP[] = "ip"; +const char S_I_FACTOR[] = "i_factor"; +const char S_I_MULTIPLIER[] = "i_multiplier"; +const char S_LOGIN[] = "login"; +const char S_LOG_LEVEL[] = "logLevel"; +const char S_LOW_TEMP[] = "lowTemp"; +const char S_MAC[] = "mac"; +const char S_MASTER[] = "master"; +const char S_MAX[] = "max"; +const char S_MAX_FREE_BLOCK[] = "maxFreeBlock"; +const char S_MAX_MODULATION[] = "maxModulation"; +const char S_MAX_POWER[] = "maxPower"; +const char S_MAX_TEMP[] = "maxTemp"; +const char S_MAX_TEMP_SYNC_WITH_TARGET_TEMP[] = "maxTempSyncWithTargetTemp"; +const char S_MDNS[] = "mdns"; +const char S_MEMBER_ID[] = "memberId"; +const char S_MIN[] = "min"; +const char S_MIN_FREE[] = "minFree"; +const char S_MIN_MAX_FREE_BLOCK[] = "minMaxFreeBlock"; +const char S_MIN_POWER[] = "minPower"; +const char S_MIN_TEMP[] = "minTemp"; +const char S_MODEL[] = "model"; +const char S_MODULATION[] = "modulation"; +const char S_MQTT[] = "mqtt"; +const char S_NAME[] = "name"; +const char S_NATIVE_OTC[] = "nativeOTC"; +const char S_NETWORK[] = "network"; +const char S_NTP[] = "ntp"; +const char S_OFFSET[] = "offset"; +const char S_ON_ENABLED_HEATING[] = "onEnabledHeating"; +const char S_ON_FAULT[] = "onFault"; +const char S_ON_LOSS_CONNECTION[] = "onLossConnection"; +const char S_OPENTHERM[] = "opentherm"; +const char S_OPTIONS[] = "options"; +const char S_OUTDOOR_TEMP[] = "outdoorTemp"; +const char S_OUTDOOR_TEMP_AVG_TYPE[] = "outdoorTempAvgType"; +const char S_OUT_GPIO[] = "outGpio"; +const char S_OUTPUT[] = "output"; +const char S_OVERHEAT[] = "overheat"; +const char S_OVERHEAT_PROTECTION[] = "overheatProtection"; +const char S_PASSWORD[] = "password"; +const char S_PID[] = "pid"; +const char S_PORT[] = "port"; +const char S_PORTAL[] = "portal"; +const char S_POST_CIRCULATION_TIME[] = "postCirculationTime"; +const char S_POWER[] = "power"; +const char S_PREFIX[] = "prefix"; +const char S_PROTOCOL_VERSION[] = "protocolVersion"; +const char S_PURPOSE[] = "purpose"; +const char S_PSRAM[] = "psram"; +const char S_P_FACTOR[] = "p_factor"; +const char S_P_MULTIPLIER[] = "p_multiplier"; +const char S_REAL_SIZE[] = "realSize"; +const char S_REASON[] = "reason"; +const char S_RESET_DIAGNOSTIC[] = "resetDiagnostic"; +const char S_RESET_FAULT[] = "resetFault"; +const char S_RESET_REASON[] = "resetReason"; +const char S_RESTART[] = "restart"; +const char S_RETURN_TEMP[] = "returnTemp"; +const char S_REV[] = "rev"; +const char S_RSSI[] = "rssi"; +const char S_RX_LED_GPIO[] = "rxLedGpio"; +const char S_SDK[] = "sdk"; +const char S_SENSORS[] = "sensors"; +const char S_SERIAL[] = "serial"; +const char S_SERVER[] = "server"; +const char S_SETTINGS[] = "settings"; +const char S_SET_DATE_AND_TIME[] = "setDateAndTime"; +const char S_SHIFT[] = "shift"; +const char S_SIGNAL_QUALITY[] = "signalQuality"; +const char S_SIZE[] = "size"; +const char S_SLAVE[] = "slave"; +const char S_SLOPE[] = "slope"; +const char S_SSID[] = "ssid"; +const char S_STA[] = "sta"; +const char S_STATE[] = "state"; +const char S_STATIC_CONFIG[] = "staticConfig"; +const char S_STATUS_LED_GPIO[] = "statusLedGpio"; +const char S_SETPOINT[] = "setpoint"; +const char S_SETPOINT_TEMP[] = "setpointTemp"; +const char S_SUBNET[] = "subnet"; +const char S_SUMMER_WINTER_MODE[] = "summerWinterMode"; +const char S_SYSTEM[] = "system"; +const char S_TARGET[] = "target"; +const char S_TARGET_DIFF_FACTOR[] = "targetDiffFactor"; +const char S_TARGET_TEMP[] = "targetTemp"; +const char S_TEMPERATURE[] = "temperature"; +const char S_THRESHOLD_HIGH[] = "thresholdHigh"; +const char S_THRESHOLD_LOW[] = "thresholdLow"; +const char S_THRESHOLD_TIME[] = "thresholdTime"; +const char S_TIMEZONE[] = "timezone"; +const char S_TOTAL[] = "total"; +const char S_TRESHOLD_TIME[] = "tresholdTime"; +const char S_TURBO[] = "turbo"; +const char S_TURBO_FACTOR[] = "turboFactor"; +const char S_TYPE[] = "type"; +const char S_UNIT_SYSTEM[] = "unitSystem"; +const char S_UPTIME[] = "uptime"; +const char S_USE[] = "use"; +const char S_USE_DHCP[] = "useDhcp"; +const char S_USER[] = "user"; +const char S_VALUE[] = "value"; +const char S_VERSION[] = "version"; +const char S_WEBSERIAL[] = "webSerial"; diff --git a/src/utils.h b/src/utils.h index eb1a0b7..60fab59 100644 --- a/src/utils.h +++ b/src/utils.h @@ -13,14 +13,10 @@ String getChipId(const char* prefix = nullptr, const char* suffix = nullptr) { } uint32_t cid = 0; - #if defined(ARDUINO_ARCH_ESP8266) - cid = ESP.getChipId(); - #elif defined(ARDUINO_ARCH_ESP32) // https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/ChipID/GetChipID/GetChipID.ino for (uint8_t i = 0; i < 17; i = i + 8) { cid |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } - #endif chipId += String(cid, HEX); @@ -145,47 +141,21 @@ float roundf(float value, uint8_t decimals = 2) { } inline size_t getTotalHeap() { - #if defined(ARDUINO_ARCH_ESP32) return ESP.getHeapSize(); - #elif defined(ARDUINO_ARCH_ESP8266) - return 81920; - #else - return 99999; - #endif } size_t getFreeHeap(bool getMinValue = false) { - #if defined(ARDUINO_ARCH_ESP32) return getMinValue ? ESP.getMinFreeHeap() : ESP.getFreeHeap(); - - #elif defined(ARDUINO_ARCH_ESP8266) - static size_t minValue = 0; - size_t value = ESP.getFreeHeap(); - - if (value < minValue || minValue == 0) { - minValue = value; - } - - return getMinValue ? minValue : value; - #else - return 0; - #endif } size_t getMaxFreeBlockHeap(bool getMinValue = false) { static size_t minValue = 0; - size_t value = 0; - - #if defined(ARDUINO_ARCH_ESP32) - value = ESP.getMaxAllocHeap(); + size_t value = ESP.getMaxAllocHeap(); size_t minHeapValue = getFreeHeap(true); if (minHeapValue < minValue || minValue == 0) { minValue = minHeapValue; } - #elif defined(ARDUINO_ARCH_ESP8266) - value = ESP.getMaxFreeBlockSize(); - #endif if (value < minValue || minValue == 0) { minValue = value; @@ -201,59 +171,53 @@ inline uint8_t getHeapFrag() { String getResetReason() { String value; - #if defined(ARDUINO_ARCH_ESP8266) - value = ESP.getResetReason(); - #elif defined(ARDUINO_ARCH_ESP32) switch (esp_reset_reason()) { case ESP_RST_POWERON: - value = F("Reset due to power-on event"); + value = "Reset due to power-on event"; break; case ESP_RST_EXT: - value = F("Reset by external pin"); + value = "Reset by external pin"; break; case ESP_RST_SW: - value = F("Software reset via esp_restart"); + value = "Software reset via esp_restart"; break; case ESP_RST_PANIC: - value = F("Software reset due to exception/panic"); + value = "Software reset due to exception/panic"; break; case ESP_RST_INT_WDT: - value = F("Reset (software or hardware) due to interrupt watchdog"); + value = "Reset (software or hardware) due to interrupt watchdog"; break; case ESP_RST_TASK_WDT: - value = F("Reset due to task watchdog"); + value = "Reset due to task watchdog"; break; case ESP_RST_WDT: - value = F("Reset due to other watchdogs"); + value = "Reset due to other watchdogs"; break; case ESP_RST_DEEPSLEEP: - value = F("Reset after exiting deep sleep mode"); + value = "Reset after exiting deep sleep mode"; break; case ESP_RST_BROWNOUT: - value = F("Brownout reset (software or hardware)"); + value = "Brownout reset (software or hardware)"; break; case ESP_RST_SDIO: - value = F("Reset over SDIO"); + value = "Reset over SDIO"; break; case ESP_RST_UNKNOWN: default: - value = F("unknown"); + value = "unknown"; break; } - #else - value = F("unknown"); - #endif return value; } @@ -275,29 +239,29 @@ void arr2str(String& str, T arr[], size_t length) { } void networkSettingsToJson(const NetworkSettings& src, JsonVariant dst) { - dst[FPSTR(S_HOSTNAME)] = src.hostname; + dst[S_HOSTNAME] = src.hostname; - dst[FPSTR(S_USE_DHCP)] = src.useDhcp; - dst[FPSTR(S_STATIC_CONFIG)][FPSTR(S_IP)] = src.staticConfig.ip; - dst[FPSTR(S_STATIC_CONFIG)][FPSTR(S_GATEWAY)] = src.staticConfig.gateway; - dst[FPSTR(S_STATIC_CONFIG)][FPSTR(S_SUBNET)] = src.staticConfig.subnet; - dst[FPSTR(S_STATIC_CONFIG)][FPSTR(S_DNS)] = src.staticConfig.dns; + dst[S_USE_DHCP] = src.useDhcp; + dst[S_STATIC_CONFIG][S_IP] = src.staticConfig.ip; + dst[S_STATIC_CONFIG][S_GATEWAY] = src.staticConfig.gateway; + dst[S_STATIC_CONFIG][S_SUBNET] = src.staticConfig.subnet; + dst[S_STATIC_CONFIG][S_DNS] = src.staticConfig.dns; - dst[FPSTR(S_AP)][FPSTR(S_SSID)] = src.ap.ssid; - dst[FPSTR(S_AP)][FPSTR(S_PASSWORD)] = src.ap.password; - dst[FPSTR(S_AP)][FPSTR(S_CHANNEL)] = src.ap.channel; + dst[S_AP][S_SSID] = src.ap.ssid; + dst[S_AP][S_PASSWORD] = src.ap.password; + dst[S_AP][S_CHANNEL] = src.ap.channel; - dst[FPSTR(S_STA)][FPSTR(S_SSID)] = src.sta.ssid; - dst[FPSTR(S_STA)][FPSTR(S_PASSWORD)] = src.sta.password; - dst[FPSTR(S_STA)][FPSTR(S_CHANNEL)] = src.sta.channel; + dst[S_STA][S_SSID] = src.sta.ssid; + dst[S_STA][S_PASSWORD] = src.sta.password; + dst[S_STA][S_CHANNEL] = src.sta.channel; } bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { bool changed = false; // hostname - if (src[FPSTR(S_HOSTNAME)].is()) { - const JsonString value = src[FPSTR(S_HOSTNAME)].as(); + if (src[S_HOSTNAME].is()) { + const JsonString value = src[S_HOSTNAME].as(); if (value.size() < sizeof(dst.hostname) && NetworkUtils::NetworkMgr::isHostnameValid(value.c_str())) { if (strcmp(value.c_str(), dst.hostname) != 0) { @@ -308,15 +272,15 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } // use dhcp - if (src[FPSTR(S_USE_DHCP)].is()) { - dst.useDhcp = src[FPSTR(S_USE_DHCP)].as(); + if (src[S_USE_DHCP].is()) { + dst.useDhcp = src[S_USE_DHCP].as(); changed = true; } // static config - if (!src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_IP)].isNull()) { - String value = src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_IP)].as(); + if (!src[S_STATIC_CONFIG][S_IP].isNull()) { + String value = src[S_STATIC_CONFIG][S_IP].as(); if (value.length() < sizeof(dst.staticConfig.ip) && !value.equals(dst.staticConfig.ip)) { strcpy(dst.staticConfig.ip, value.c_str()); @@ -324,8 +288,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_GATEWAY)].isNull()) { - String value = src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_GATEWAY)].as(); + if (!src[S_STATIC_CONFIG][S_GATEWAY].isNull()) { + String value = src[S_STATIC_CONFIG][S_GATEWAY].as(); if (value.length() < sizeof(dst.staticConfig.gateway) && !value.equals(dst.staticConfig.gateway)) { strcpy(dst.staticConfig.gateway, value.c_str()); @@ -333,8 +297,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_SUBNET)].isNull()) { - String value = src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_SUBNET)].as(); + if (!src[S_STATIC_CONFIG][S_SUBNET].isNull()) { + String value = src[S_STATIC_CONFIG][S_SUBNET].as(); if (value.length() < sizeof(dst.staticConfig.subnet) && !value.equals(dst.staticConfig.subnet)) { strcpy(dst.staticConfig.subnet, value.c_str()); @@ -342,8 +306,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_DNS)].isNull()) { - String value = src[FPSTR(S_STATIC_CONFIG)][FPSTR(S_DNS)].as(); + if (!src[S_STATIC_CONFIG][S_DNS].isNull()) { + String value = src[S_STATIC_CONFIG][S_DNS].as(); if (value.length() < sizeof(dst.staticConfig.dns) && !value.equals(dst.staticConfig.dns)) { strcpy(dst.staticConfig.dns, value.c_str()); @@ -353,8 +317,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { // ap - if (!src[FPSTR(S_AP)][FPSTR(S_SSID)].isNull()) { - String value = src[FPSTR(S_AP)][FPSTR(S_SSID)].as(); + if (!src[S_AP][S_SSID].isNull()) { + String value = src[S_AP][S_SSID].as(); if (value.length() < sizeof(dst.ap.ssid) && !value.equals(dst.ap.ssid)) { strcpy(dst.ap.ssid, value.c_str()); @@ -362,8 +326,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_AP)][FPSTR(S_PASSWORD)].isNull()) { - String value = src[FPSTR(S_AP)][FPSTR(S_PASSWORD)].as(); + if (!src[S_AP][S_PASSWORD].isNull()) { + String value = src[S_AP][S_PASSWORD].as(); if (value.length() < sizeof(dst.ap.password) && !value.equals(dst.ap.password)) { strcpy(dst.ap.password, value.c_str()); @@ -371,8 +335,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_AP)][FPSTR(S_CHANNEL)].isNull()) { - unsigned char value = src[FPSTR(S_AP)][FPSTR(S_CHANNEL)].as(); + if (!src[S_AP][S_CHANNEL].isNull()) { + unsigned char value = src[S_AP][S_CHANNEL].as(); if (value >= 0 && value < 12) { dst.ap.channel = value; @@ -382,8 +346,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { // sta - if (!src[FPSTR(S_STA)][FPSTR(S_SSID)].isNull()) { - String value = src[FPSTR(S_STA)][FPSTR(S_SSID)].as(); + if (!src[S_STA][S_SSID].isNull()) { + String value = src[S_STA][S_SSID].as(); if (value.length() < sizeof(dst.sta.ssid) && !value.equals(dst.sta.ssid)) { strcpy(dst.sta.ssid, value.c_str()); @@ -391,8 +355,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_STA)][FPSTR(S_PASSWORD)].isNull()) { - String value = src[FPSTR(S_STA)][FPSTR(S_PASSWORD)].as(); + if (!src[S_STA][S_PASSWORD].isNull()) { + String value = src[S_STA][S_PASSWORD].as(); if (value.length() < sizeof(dst.sta.password) && !value.equals(dst.sta.password)) { strcpy(dst.sta.password, value.c_str()); @@ -400,8 +364,8 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { } } - if (!src[FPSTR(S_STA)][FPSTR(S_CHANNEL)].isNull()) { - unsigned char value = src[FPSTR(S_STA)][FPSTR(S_CHANNEL)].as(); + if (!src[S_STA][S_CHANNEL].isNull()) { + unsigned char value = src[S_STA][S_CHANNEL].as(); if (value >= 0 && value < 12) { dst.sta.channel = value; @@ -414,157 +378,157 @@ bool jsonToNetworkSettings(const JsonVariantConst src, NetworkSettings& dst) { void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) { if (!safe) { - auto system = dst[FPSTR(S_SYSTEM)].to(); - system[FPSTR(S_LOG_LEVEL)] = static_cast(src.system.logLevel); + auto system = dst[S_SYSTEM].to(); + system[S_LOG_LEVEL] = static_cast(src.system.logLevel); - auto serial = system[FPSTR(S_SERIAL)].to(); - serial[FPSTR(S_ENABLED)] = src.system.serial.enabled; - serial[FPSTR(S_BAUDRATE)] = src.system.serial.baudrate; + auto serial = system[S_SERIAL].to(); + serial[S_ENABLED] = src.system.serial.enabled; + serial[S_BAUDRATE] = src.system.serial.baudrate; - auto webSerial = system[FPSTR(S_WEBSERIAL)].to(); - webSerial[FPSTR(S_ENABLED)] = src.system.webSerial.enabled; + auto webSerial = system[S_WEBSERIAL].to(); + webSerial[S_ENABLED] = src.system.webSerial.enabled; - auto ntp = system[FPSTR(S_NTP)].to(); - ntp[FPSTR(S_SERVER)] = src.system.ntp.server; - ntp[FPSTR(S_TIMEZONE)] = src.system.ntp.timezone; + auto ntp = system[S_NTP].to(); + ntp[S_SERVER] = src.system.ntp.server; + ntp[S_TIMEZONE] = src.system.ntp.timezone; - system[FPSTR(S_UNIT_SYSTEM)] = static_cast(src.system.unitSystem); - system[FPSTR(S_STATUS_LED_GPIO)] = src.system.statusLedGpio; + system[S_UNIT_SYSTEM] = static_cast(src.system.unitSystem); + system[S_STATUS_LED_GPIO] = src.system.statusLedGpio; - auto portal = dst[FPSTR(S_PORTAL)].to(); - portal[FPSTR(S_AUTH)] = src.portal.auth; - portal[FPSTR(S_LOGIN)] = src.portal.login; - portal[FPSTR(S_PASSWORD)] = src.portal.password; - portal[FPSTR(S_MDNS)] = src.portal.mdns; + auto portal = dst[S_PORTAL].to(); + portal[S_AUTH] = src.portal.auth; + portal[S_LOGIN] = src.portal.login; + portal[S_PASSWORD] = src.portal.password; + portal[S_MDNS] = src.portal.mdns; - auto opentherm = dst[FPSTR(S_OPENTHERM)].to(); - opentherm[FPSTR(S_UNIT_SYSTEM)] = static_cast(src.opentherm.unitSystem); - opentherm[FPSTR(S_IN_GPIO)] = src.opentherm.inGpio; - opentherm[FPSTR(S_OUT_GPIO)] = src.opentherm.outGpio; - opentherm[FPSTR(S_RX_LED_GPIO)] = src.opentherm.rxLedGpio; - opentherm[FPSTR(S_MEMBER_ID)] = src.opentherm.memberId; - opentherm[FPSTR(S_FLAGS)] = src.opentherm.flags; - opentherm[FPSTR(S_HEATING_DISABLING_ACTION)] = static_cast(src.opentherm.heatingDisablingAction); - opentherm[FPSTR(S_DHW_DISABLING_ACTION)] = static_cast(src.opentherm.dhwDisablingAction); - opentherm[FPSTR(S_CH2_DISABLING_ACTION)] = static_cast(src.opentherm.ch2DisablingAction); - opentherm[FPSTR(S_MIN_POWER)] = roundf(src.opentherm.minPower, 2); - opentherm[FPSTR(S_MAX_POWER)] = roundf(src.opentherm.maxPower, 2); + auto opentherm = dst[S_OPENTHERM].to(); + opentherm[S_UNIT_SYSTEM] = static_cast(src.opentherm.unitSystem); + opentherm[S_IN_GPIO] = src.opentherm.inGpio; + opentherm[S_OUT_GPIO] = src.opentherm.outGpio; + opentherm[S_RX_LED_GPIO] = src.opentherm.rxLedGpio; + opentherm[S_MEMBER_ID] = src.opentherm.memberId; + opentherm[S_FLAGS] = src.opentherm.flags; + opentherm[S_HEATING_DISABLING_ACTION] = static_cast(src.opentherm.heatingDisablingAction); + opentherm[S_DHW_DISABLING_ACTION] = static_cast(src.opentherm.dhwDisablingAction); + opentherm[S_CH2_DISABLING_ACTION] = static_cast(src.opentherm.ch2DisablingAction); + opentherm[S_MIN_POWER] = roundf(src.opentherm.minPower, 2); + opentherm[S_MAX_POWER] = roundf(src.opentherm.maxPower, 2); - auto otOptions = opentherm[FPSTR(S_OPTIONS)].to(); - otOptions[FPSTR(S_DHW_SUPPORT)] = src.opentherm.options.dhwSupport; - otOptions[FPSTR(S_COOLING_SUPPORT)] = src.opentherm.options.coolingSupport; - otOptions[FPSTR(S_SUMMER_WINTER_MODE)] = src.opentherm.options.summerWinterMode; - otOptions[FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)] = src.opentherm.options.heatingStateToSummerWinterMode; - otOptions[FPSTR(S_CH2_ALWAYS_ENABLED)] = src.opentherm.options.ch2AlwaysEnabled; - otOptions[FPSTR(S_HEATING_TO_CH2)] = src.opentherm.options.heatingToCh2; - otOptions[FPSTR(S_DHW_TO_CH2)] = src.opentherm.options.dhwToCh2; - otOptions[FPSTR(S_DHW_BLOCKING)] = src.opentherm.options.dhwBlocking; - otOptions[FPSTR(S_DHW_STATE_AS_DHW_BLOCKING)] = src.opentherm.options.dhwStateAsDhwBlocking; - otOptions[FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)] = src.opentherm.options.maxTempSyncWithTargetTemp; - otOptions[FPSTR(S_GET_MIN_MAX_TEMP)] = src.opentherm.options.getMinMaxTemp; - otOptions[FPSTR(S_IGNORE_DIAG_STATE)] = src.opentherm.options.ignoreDiagState; - otOptions[FPSTR(S_AUTO_FAULT_RESET)] = src.opentherm.options.autoFaultReset; - otOptions[FPSTR(S_AUTO_DIAG_RESET)] = src.opentherm.options.autoDiagReset; - otOptions[FPSTR(S_SET_DATE_AND_TIME)] = src.opentherm.options.setDateAndTime; - otOptions[FPSTR(S_ALWAYS_SEND_INDOOR_TEMP)] = src.opentherm.options.alwaysSendIndoorTemp; - otOptions[FPSTR(S_NATIVE_OTC)] = src.opentherm.options.nativeOTC; - otOptions[FPSTR(S_IMMERGAS_FIX)] = src.opentherm.options.immergasFix; + auto otOptions = opentherm[S_OPTIONS].to(); + otOptions[S_DHW_SUPPORT] = src.opentherm.options.dhwSupport; + otOptions[S_COOLING_SUPPORT] = src.opentherm.options.coolingSupport; + otOptions[S_SUMMER_WINTER_MODE] = src.opentherm.options.summerWinterMode; + otOptions[S_HEATING_STATE_TO_SUMMER_WINTER_MODE] = src.opentherm.options.heatingStateToSummerWinterMode; + otOptions[S_CH2_ALWAYS_ENABLED] = src.opentherm.options.ch2AlwaysEnabled; + otOptions[S_HEATING_TO_CH2] = src.opentherm.options.heatingToCh2; + otOptions[S_DHW_TO_CH2] = src.opentherm.options.dhwToCh2; + otOptions[S_DHW_BLOCKING] = src.opentherm.options.dhwBlocking; + otOptions[S_DHW_STATE_AS_DHW_BLOCKING] = src.opentherm.options.dhwStateAsDhwBlocking; + otOptions[S_MAX_TEMP_SYNC_WITH_TARGET_TEMP] = src.opentherm.options.maxTempSyncWithTargetTemp; + otOptions[S_GET_MIN_MAX_TEMP] = src.opentherm.options.getMinMaxTemp; + otOptions[S_IGNORE_DIAG_STATE] = src.opentherm.options.ignoreDiagState; + otOptions[S_AUTO_FAULT_RESET] = src.opentherm.options.autoFaultReset; + otOptions[S_AUTO_DIAG_RESET] = src.opentherm.options.autoDiagReset; + otOptions[S_SET_DATE_AND_TIME] = src.opentherm.options.setDateAndTime; + otOptions[S_ALWAYS_SEND_INDOOR_TEMP] = src.opentherm.options.alwaysSendIndoorTemp; + otOptions[S_NATIVE_OTC] = src.opentherm.options.nativeOTC; + otOptions[S_IMMERGAS_FIX] = src.opentherm.options.immergasFix; - auto mqtt = dst[FPSTR(S_MQTT)].to(); - mqtt[FPSTR(S_ENABLED)] = src.mqtt.enabled; - mqtt[FPSTR(S_SERVER)] = src.mqtt.server; - mqtt[FPSTR(S_PORT)] = src.mqtt.port; - mqtt[FPSTR(S_USER)] = src.mqtt.user; - mqtt[FPSTR(S_PASSWORD)] = src.mqtt.password; - mqtt[FPSTR(S_PREFIX)] = src.mqtt.prefix; - mqtt[FPSTR(S_INTERVAL)] = src.mqtt.interval; - mqtt[FPSTR(S_HOME_ASSISTANT_DISCOVERY)] = src.mqtt.homeAssistantDiscovery; + auto mqtt = dst[S_MQTT].to(); + mqtt[S_ENABLED] = src.mqtt.enabled; + mqtt[S_SERVER] = src.mqtt.server; + mqtt[S_PORT] = src.mqtt.port; + mqtt[S_USER] = src.mqtt.user; + mqtt[S_PASSWORD] = src.mqtt.password; + mqtt[S_PREFIX] = src.mqtt.prefix; + mqtt[S_INTERVAL] = src.mqtt.interval; + mqtt[S_HOME_ASSISTANT_DISCOVERY] = src.mqtt.homeAssistantDiscovery; - auto emergency = dst[FPSTR(S_EMERGENCY)].to(); - emergency[FPSTR(S_TARGET)] = roundf(src.emergency.target, 2); - emergency[FPSTR(S_TRESHOLD_TIME)] = src.emergency.tresholdTime; + auto emergency = dst[S_EMERGENCY].to(); + emergency[S_TARGET] = roundf(src.emergency.target, 2); + emergency[S_TRESHOLD_TIME] = src.emergency.tresholdTime; } - auto heating = dst[FPSTR(S_HEATING)].to(); - heating[FPSTR(S_ENABLED)] = src.heating.enabled; - heating[FPSTR(S_TURBO)] = src.heating.turbo; - heating[FPSTR(S_TARGET)] = roundf(src.heating.target, 2); - heating[FPSTR(S_HYSTERESIS)][FPSTR(S_ENABLED)] = src.heating.hysteresis.enabled; - heating[FPSTR(S_HYSTERESIS)][FPSTR(S_VALUE)] = roundf(src.heating.hysteresis.value, 3); - heating[FPSTR(S_TURBO_FACTOR)] = roundf(src.heating.turboFactor, 3); - heating[FPSTR(S_MIN_TEMP)] = src.heating.minTemp; - heating[FPSTR(S_MAX_TEMP)] = src.heating.maxTemp; - heating[FPSTR(S_MAX_MODULATION)] = src.heating.maxModulation; - heating[FPSTR(S_INDOOR_TEMP_AVG_TYPE)] = static_cast(src.heating.indoorTempAvgType); - heating[FPSTR(S_OUTDOOR_TEMP_AVG_TYPE)] = static_cast(src.heating.outdoorTempAvgType); + auto heating = dst[S_HEATING].to(); + heating[S_ENABLED] = src.heating.enabled; + heating[S_TURBO] = src.heating.turbo; + heating[S_TARGET] = roundf(src.heating.target, 2); + heating[S_HYSTERESIS][S_ENABLED] = src.heating.hysteresis.enabled; + heating[S_HYSTERESIS][S_VALUE] = roundf(src.heating.hysteresis.value, 3); + heating[S_TURBO_FACTOR] = roundf(src.heating.turboFactor, 3); + heating[S_MIN_TEMP] = src.heating.minTemp; + heating[S_MAX_TEMP] = src.heating.maxTemp; + heating[S_MAX_MODULATION] = src.heating.maxModulation; + heating[S_INDOOR_TEMP_AVG_TYPE] = static_cast(src.heating.indoorTempAvgType); + heating[S_OUTDOOR_TEMP_AVG_TYPE] = static_cast(src.heating.outdoorTempAvgType); - auto heatingOverheatProtection = heating[FPSTR(S_OVERHEAT_PROTECTION)].to(); - heatingOverheatProtection[FPSTR(S_HIGH_TEMP)] = src.heating.overheatProtection.highTemp; - heatingOverheatProtection[FPSTR(S_LOW_TEMP)] = src.heating.overheatProtection.lowTemp; + auto heatingOverheatProtection = heating[S_OVERHEAT_PROTECTION].to(); + heatingOverheatProtection[S_HIGH_TEMP] = src.heating.overheatProtection.highTemp; + heatingOverheatProtection[S_LOW_TEMP] = src.heating.overheatProtection.lowTemp; - auto freezeProtection = heating[FPSTR(S_FREEZE_PROTECTION)].to(); - freezeProtection[FPSTR(S_HIGH_TEMP)] = src.heating.freezeProtection.highTemp; - freezeProtection[FPSTR(S_LOW_TEMP)] = src.heating.freezeProtection.lowTemp; + auto freezeProtection = heating[S_FREEZE_PROTECTION].to(); + freezeProtection[S_HIGH_TEMP] = src.heating.freezeProtection.highTemp; + freezeProtection[S_LOW_TEMP] = src.heating.freezeProtection.lowTemp; - auto dhw = dst[FPSTR(S_DHW)].to(); - dhw[FPSTR(S_ENABLED)] = src.dhw.enabled; - dhw[FPSTR(S_TARGET)] = roundf(src.dhw.target, 1); - dhw[FPSTR(S_MIN_TEMP)] = src.dhw.minTemp; - dhw[FPSTR(S_MAX_TEMP)] = src.dhw.maxTemp; - dhw[FPSTR(S_MAX_MODULATION)] = src.dhw.maxModulation; + auto dhw = dst[S_DHW].to(); + dhw[S_ENABLED] = src.dhw.enabled; + dhw[S_TARGET] = roundf(src.dhw.target, 1); + dhw[S_MIN_TEMP] = src.dhw.minTemp; + dhw[S_MAX_TEMP] = src.dhw.maxTemp; + dhw[S_MAX_MODULATION] = src.dhw.maxModulation; - auto dhwOverheatProtection = dhw[FPSTR(S_OVERHEAT_PROTECTION)].to(); - dhwOverheatProtection[FPSTR(S_HIGH_TEMP)] = src.dhw.overheatProtection.highTemp; - dhwOverheatProtection[FPSTR(S_LOW_TEMP)] = src.dhw.overheatProtection.lowTemp; + auto dhwOverheatProtection = dhw[S_OVERHEAT_PROTECTION].to(); + dhwOverheatProtection[S_HIGH_TEMP] = src.dhw.overheatProtection.highTemp; + dhwOverheatProtection[S_LOW_TEMP] = src.dhw.overheatProtection.lowTemp; - auto equitherm = dst[FPSTR(S_EQUITHERM)].to(); - equitherm[FPSTR(S_ENABLED)] = src.equitherm.enabled; - equitherm[FPSTR(S_SLOPE)] = roundf(src.equitherm.slope, 3); - equitherm[FPSTR(S_EXPONENT)] = roundf(src.equitherm.exponent, 3); - equitherm[FPSTR(S_SHIFT)] = roundf(src.equitherm.shift, 2); - equitherm[FPSTR(S_TARGET_DIFF_FACTOR)] = roundf(src.equitherm.targetDiffFactor, 3); + auto equitherm = dst[S_EQUITHERM].to(); + equitherm[S_ENABLED] = src.equitherm.enabled; + equitherm[S_SLOPE] = roundf(src.equitherm.slope, 3); + equitherm[S_EXPONENT] = roundf(src.equitherm.exponent, 3); + equitherm[S_SHIFT] = roundf(src.equitherm.shift, 2); + equitherm[S_TARGET_DIFF_FACTOR] = roundf(src.equitherm.targetDiffFactor, 3); - auto pid = dst[FPSTR(S_PID)].to(); - pid[FPSTR(S_ENABLED)] = src.pid.enabled; - pid[FPSTR(S_P_FACTOR)] = roundf(src.pid.p_factor, 3); - pid[FPSTR(S_I_FACTOR)] = roundf(src.pid.i_factor, 4); - pid[FPSTR(S_D_FACTOR)] = roundf(src.pid.d_factor, 1); - pid[FPSTR(S_DT)] = src.pid.dt; - pid[FPSTR(S_MIN_TEMP)] = src.pid.minTemp; - pid[FPSTR(S_MAX_TEMP)] = src.pid.maxTemp; + auto pid = dst[S_PID].to(); + pid[S_ENABLED] = src.pid.enabled; + pid[S_P_FACTOR] = roundf(src.pid.p_factor, 3); + pid[S_I_FACTOR] = roundf(src.pid.i_factor, 4); + pid[S_D_FACTOR] = roundf(src.pid.d_factor, 1); + pid[S_DT] = src.pid.dt; + pid[S_MIN_TEMP] = src.pid.minTemp; + pid[S_MAX_TEMP] = src.pid.maxTemp; - auto pidDeadband = pid[FPSTR(S_DEADBAND)].to(); - pidDeadband[FPSTR(S_ENABLED)] = src.pid.deadband.enabled; - pidDeadband[FPSTR(S_P_MULTIPLIER)] = src.pid.deadband.p_multiplier; - pidDeadband[FPSTR(S_I_MULTIPLIER)] = src.pid.deadband.i_multiplier; - pidDeadband[FPSTR(S_D_MULTIPLIER)] = src.pid.deadband.d_multiplier; - pidDeadband[FPSTR(S_THRESHOLD_HIGH)] = src.pid.deadband.thresholdHigh; - pidDeadband[FPSTR(S_THRESHOLD_LOW)] = src.pid.deadband.thresholdLow; + auto pidDeadband = pid[S_DEADBAND].to(); + pidDeadband[S_ENABLED] = src.pid.deadband.enabled; + pidDeadband[S_P_MULTIPLIER] = src.pid.deadband.p_multiplier; + pidDeadband[S_I_MULTIPLIER] = src.pid.deadband.i_multiplier; + pidDeadband[S_D_MULTIPLIER] = src.pid.deadband.d_multiplier; + pidDeadband[S_THRESHOLD_HIGH] = src.pid.deadband.thresholdHigh; + pidDeadband[S_THRESHOLD_LOW] = src.pid.deadband.thresholdLow; if (!safe) { - auto externalPump = dst[FPSTR(S_EXTERNAL_PUMP)].to(); - externalPump[FPSTR(S_USE)] = src.externalPump.use; - externalPump[FPSTR(S_GPIO)] = src.externalPump.gpio; - externalPump[FPSTR(S_INVERT_STATE)] = src.externalPump.invertState; - externalPump[FPSTR(S_POST_CIRCULATION_TIME)] = roundf(src.externalPump.postCirculationTime / 60, 0); - externalPump[FPSTR(S_ANTI_STUCK_INTERVAL)] = roundf(src.externalPump.antiStuckInterval / 86400, 0); - externalPump[FPSTR(S_ANTI_STUCK_TIME)] = roundf(src.externalPump.antiStuckTime / 60, 0); + auto externalPump = dst[S_EXTERNAL_PUMP].to(); + externalPump[S_USE] = src.externalPump.use; + externalPump[S_GPIO] = src.externalPump.gpio; + externalPump[S_INVERT_STATE] = src.externalPump.invertState; + externalPump[S_POST_CIRCULATION_TIME] = roundf(src.externalPump.postCirculationTime / 60, 0); + externalPump[S_ANTI_STUCK_INTERVAL] = roundf(src.externalPump.antiStuckInterval / 86400, 0); + externalPump[S_ANTI_STUCK_TIME] = roundf(src.externalPump.antiStuckTime / 60, 0); - auto cascadeControlInput = dst[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)].to(); - cascadeControlInput[FPSTR(S_ENABLED)] = src.cascadeControl.input.enabled; - cascadeControlInput[FPSTR(S_GPIO)] = src.cascadeControl.input.gpio; - cascadeControlInput[FPSTR(S_INVERT_STATE)] = src.cascadeControl.input.invertState; - cascadeControlInput[FPSTR(S_THRESHOLD_TIME)] = src.cascadeControl.input.thresholdTime; + auto cascadeControlInput = dst[S_CASCADE_CONTROL][S_INPUT].to(); + cascadeControlInput[S_ENABLED] = src.cascadeControl.input.enabled; + cascadeControlInput[S_GPIO] = src.cascadeControl.input.gpio; + cascadeControlInput[S_INVERT_STATE] = src.cascadeControl.input.invertState; + cascadeControlInput[S_THRESHOLD_TIME] = src.cascadeControl.input.thresholdTime; - auto cascadeControlOutput = dst[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)].to(); - cascadeControlOutput[FPSTR(S_ENABLED)] = src.cascadeControl.output.enabled; - cascadeControlOutput[FPSTR(S_GPIO)] = src.cascadeControl.output.gpio; - cascadeControlOutput[FPSTR(S_INVERT_STATE)] = src.cascadeControl.output.invertState; - cascadeControlOutput[FPSTR(S_THRESHOLD_TIME)] = src.cascadeControl.output.thresholdTime; - cascadeControlOutput[FPSTR(S_ON_FAULT)] = src.cascadeControl.output.onFault; - cascadeControlOutput[FPSTR(S_ON_LOSS_CONNECTION)] = src.cascadeControl.output.onLossConnection; - cascadeControlOutput[FPSTR(S_ON_ENABLED_HEATING)] = src.cascadeControl.output.onEnabledHeating; + auto cascadeControlOutput = dst[S_CASCADE_CONTROL][S_OUTPUT].to(); + cascadeControlOutput[S_ENABLED] = src.cascadeControl.output.enabled; + cascadeControlOutput[S_GPIO] = src.cascadeControl.output.gpio; + cascadeControlOutput[S_INVERT_STATE] = src.cascadeControl.output.invertState; + cascadeControlOutput[S_THRESHOLD_TIME] = src.cascadeControl.output.thresholdTime; + cascadeControlOutput[S_ON_FAULT] = src.cascadeControl.output.onFault; + cascadeControlOutput[S_ON_LOSS_CONNECTION] = src.cascadeControl.output.onLossConnection; + cascadeControlOutput[S_ON_ENABLED_HEATING] = src.cascadeControl.output.onEnabledHeating; } } @@ -600,8 +564,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false if (!safe) { // system - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_LOG_LEVEL)].isNull()) { - uint8_t value = src[FPSTR(S_SYSTEM)][FPSTR(S_LOG_LEVEL)].as(); + if (!src[S_SYSTEM][S_LOG_LEVEL].isNull()) { + uint8_t value = src[S_SYSTEM][S_LOG_LEVEL].as(); if (value != dst.system.logLevel && value >= TinyLoggerLevel::SILENT && value <= TinyLoggerLevel::VERBOSE) { dst.system.logLevel = value; @@ -609,8 +573,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_SYSTEM)][FPSTR(S_SERIAL)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_SYSTEM)][FPSTR(S_SERIAL)][FPSTR(S_ENABLED)].as(); + if (src[S_SYSTEM][S_SERIAL][S_ENABLED].is()) { + bool value = src[S_SYSTEM][S_SERIAL][S_ENABLED].as(); if (value != dst.system.serial.enabled) { dst.system.serial.enabled = value; @@ -618,8 +582,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_SERIAL)][FPSTR(S_BAUDRATE)].isNull()) { - unsigned int value = src[FPSTR(S_SYSTEM)][FPSTR(S_SERIAL)][FPSTR(S_BAUDRATE)].as(); + if (!src[S_SYSTEM][S_SERIAL][S_BAUDRATE].isNull()) { + unsigned int value = src[S_SYSTEM][S_SERIAL][S_BAUDRATE].as(); if (value == 9600 || value == 19200 || value == 38400 || value == 57600 || value == 74880 || value == 115200) { if (value != dst.system.serial.baudrate) { @@ -629,8 +593,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_SYSTEM)][FPSTR(S_WEBSERIAL)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_SYSTEM)][FPSTR(S_WEBSERIAL)][FPSTR(S_ENABLED)].as(); + if (src[S_SYSTEM][S_WEBSERIAL][S_ENABLED].is()) { + bool value = src[S_SYSTEM][S_WEBSERIAL][S_ENABLED].as(); if (value != dst.system.webSerial.enabled) { dst.system.webSerial.enabled = value; @@ -638,8 +602,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_NTP)][FPSTR(S_SERVER)].isNull()) { - String value = src[FPSTR(S_SYSTEM)][FPSTR(S_NTP)][FPSTR(S_SERVER)].as(); + if (!src[S_SYSTEM][S_NTP][S_SERVER].isNull()) { + String value = src[S_SYSTEM][S_NTP][S_SERVER].as(); if (value.length() < sizeof(dst.system.ntp.server) && !value.equals(dst.system.ntp.server)) { strcpy(dst.system.ntp.server, value.c_str()); @@ -647,8 +611,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_NTP)][FPSTR(S_TIMEZONE)].isNull()) { - String value = src[FPSTR(S_SYSTEM)][FPSTR(S_NTP)][FPSTR(S_TIMEZONE)].as(); + if (!src[S_SYSTEM][S_NTP][S_TIMEZONE].isNull()) { + String value = src[S_SYSTEM][S_NTP][S_TIMEZONE].as(); if (value.length() < sizeof(dst.system.ntp.timezone) && !value.equals(dst.system.ntp.timezone)) { strcpy(dst.system.ntp.timezone, value.c_str()); @@ -656,8 +620,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_UNIT_SYSTEM)].isNull()) { - uint8_t value = src[FPSTR(S_SYSTEM)][FPSTR(S_UNIT_SYSTEM)].as(); + if (!src[S_SYSTEM][S_UNIT_SYSTEM].isNull()) { + uint8_t value = src[S_SYSTEM][S_UNIT_SYSTEM].as(); UnitSystem prevUnitSystem = dst.system.unitSystem; switch (value) { @@ -693,15 +657,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_SYSTEM)][FPSTR(S_STATUS_LED_GPIO)].isNull()) { - if (src[FPSTR(S_SYSTEM)][FPSTR(S_STATUS_LED_GPIO)].is() && src[FPSTR(S_SYSTEM)][FPSTR(S_STATUS_LED_GPIO)].as().size() == 0) { + if (!src[S_SYSTEM][S_STATUS_LED_GPIO].isNull()) { + if (src[S_SYSTEM][S_STATUS_LED_GPIO].is() && src[S_SYSTEM][S_STATUS_LED_GPIO].as().size() == 0) { if (dst.system.statusLedGpio != GPIO_IS_NOT_CONFIGURED) { dst.system.statusLedGpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_SYSTEM)][FPSTR(S_STATUS_LED_GPIO)].as(); + unsigned char value = src[S_SYSTEM][S_STATUS_LED_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.system.statusLedGpio) { dst.system.statusLedGpio = value; @@ -712,8 +676,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // portal - if (src[FPSTR(S_PORTAL)][FPSTR(S_AUTH)].is()) { - bool value = src[FPSTR(S_PORTAL)][FPSTR(S_AUTH)].as(); + if (src[S_PORTAL][S_AUTH].is()) { + bool value = src[S_PORTAL][S_AUTH].as(); if (value != dst.portal.auth) { dst.portal.auth = value; @@ -721,8 +685,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PORTAL)][FPSTR(S_LOGIN)].isNull()) { - String value = src[FPSTR(S_PORTAL)][FPSTR(S_LOGIN)].as(); + if (!src[S_PORTAL][S_LOGIN].isNull()) { + String value = src[S_PORTAL][S_LOGIN].as(); if (value.length() < sizeof(dst.portal.login) && !value.equals(dst.portal.login)) { strcpy(dst.portal.login, value.c_str()); @@ -730,8 +694,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PORTAL)][FPSTR(S_PASSWORD)].isNull()) { - String value = src[FPSTR(S_PORTAL)][FPSTR(S_PASSWORD)].as(); + if (!src[S_PORTAL][S_PASSWORD].isNull()) { + String value = src[S_PORTAL][S_PASSWORD].as(); if (value.length() < sizeof(dst.portal.password) && !value.equals(dst.portal.password)) { strcpy(dst.portal.password, value.c_str()); @@ -744,8 +708,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false changed = true; } - if (src[FPSTR(S_PORTAL)][FPSTR(S_MDNS)].is()) { - bool value = src[FPSTR(S_PORTAL)][FPSTR(S_MDNS)].as(); + if (src[S_PORTAL][S_MDNS].is()) { + bool value = src[S_PORTAL][S_MDNS].as(); if (value != dst.portal.mdns) { dst.portal.mdns = value; @@ -755,8 +719,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // opentherm - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_UNIT_SYSTEM)].isNull()) { - uint8_t value = src[FPSTR(S_OPENTHERM)][FPSTR(S_UNIT_SYSTEM)].as(); + if (!src[S_OPENTHERM][S_UNIT_SYSTEM].isNull()) { + uint8_t value = src[S_OPENTHERM][S_UNIT_SYSTEM].as(); switch (value) { case static_cast(UnitSystem::METRIC): @@ -778,15 +742,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_IN_GPIO)].isNull()) { - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_IN_GPIO)].is() && src[FPSTR(S_OPENTHERM)][FPSTR(S_IN_GPIO)].as().size() == 0) { + if (!src[S_OPENTHERM][S_IN_GPIO].isNull()) { + if (src[S_OPENTHERM][S_IN_GPIO].is() && src[S_OPENTHERM][S_IN_GPIO].as().size() == 0) { if (dst.opentherm.inGpio != GPIO_IS_NOT_CONFIGURED) { dst.opentherm.inGpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_OPENTHERM)][FPSTR(S_IN_GPIO)].as(); + unsigned char value = src[S_OPENTHERM][S_IN_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.opentherm.inGpio) { dst.opentherm.inGpio = value; @@ -795,15 +759,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_OUT_GPIO)].isNull()) { - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OUT_GPIO)].is() && src[FPSTR(S_OPENTHERM)][FPSTR(S_OUT_GPIO)].as().size() == 0) { + if (!src[S_OPENTHERM][S_OUT_GPIO].isNull()) { + if (src[S_OPENTHERM][S_OUT_GPIO].is() && src[S_OPENTHERM][S_OUT_GPIO].as().size() == 0) { if (dst.opentherm.outGpio != GPIO_IS_NOT_CONFIGURED) { dst.opentherm.outGpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OUT_GPIO)].as(); + unsigned char value = src[S_OPENTHERM][S_OUT_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.opentherm.outGpio) { dst.opentherm.outGpio = value; @@ -812,15 +776,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_RX_LED_GPIO)].isNull()) { - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_RX_LED_GPIO)].is() && src[FPSTR(S_OPENTHERM)][FPSTR(S_RX_LED_GPIO)].as().size() == 0) { + if (!src[S_OPENTHERM][S_RX_LED_GPIO].isNull()) { + if (src[S_OPENTHERM][S_RX_LED_GPIO].is() && src[S_OPENTHERM][S_RX_LED_GPIO].as().size() == 0) { if (dst.opentherm.rxLedGpio != GPIO_IS_NOT_CONFIGURED) { dst.opentherm.rxLedGpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_OPENTHERM)][FPSTR(S_RX_LED_GPIO)].as(); + unsigned char value = src[S_OPENTHERM][S_RX_LED_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.opentherm.rxLedGpio) { dst.opentherm.rxLedGpio = value; @@ -829,8 +793,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_MEMBER_ID)].isNull()) { - auto value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MEMBER_ID)].as(); + if (!src[S_OPENTHERM][S_MEMBER_ID].isNull()) { + auto value = src[S_OPENTHERM][S_MEMBER_ID].as(); if (value != dst.opentherm.memberId) { dst.opentherm.memberId = value; @@ -838,8 +802,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_FLAGS)].isNull()) { - auto value = src[FPSTR(S_OPENTHERM)][FPSTR(S_FLAGS)].as(); + if (!src[S_OPENTHERM][S_FLAGS].isNull()) { + auto value = src[S_OPENTHERM][S_FLAGS].as(); if (value != dst.opentherm.flags) { dst.opentherm.flags = value; @@ -847,20 +811,20 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_DISABLING_ACTION)], dst.opentherm.heatingDisablingAction)) { + if (jsonToChannelDisablingAction(src[S_OPENTHERM][S_HEATING_DISABLING_ACTION], dst.opentherm.heatingDisablingAction)) { changed = true; } - if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_DISABLING_ACTION)], dst.opentherm.dhwDisablingAction)) { + if (jsonToChannelDisablingAction(src[S_OPENTHERM][S_DHW_DISABLING_ACTION], dst.opentherm.dhwDisablingAction)) { changed = true; } - if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_CH2_DISABLING_ACTION)], dst.opentherm.ch2DisablingAction)) { + if (jsonToChannelDisablingAction(src[S_OPENTHERM][S_CH2_DISABLING_ACTION], dst.opentherm.ch2DisablingAction)) { changed = true; } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].isNull()) { - float value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].as(); + if (!src[S_OPENTHERM][S_MIN_POWER].isNull()) { + float value = src[S_OPENTHERM][S_MIN_POWER].as(); if (value >= 0 && value <= 1000 && fabsf(value - dst.opentherm.minPower) > 0.0001f) { dst.opentherm.minPower = roundf(value, 2); @@ -868,8 +832,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_MAX_POWER)].isNull()) { - float value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MAX_POWER)].as(); + if (!src[S_OPENTHERM][S_MAX_POWER].isNull()) { + float value = src[S_OPENTHERM][S_MAX_POWER].as(); if (value >= 0 && value <= 1000 && fabsf(value - dst.opentherm.maxPower) > 0.0001f) { dst.opentherm.maxPower = roundf(value, 2); @@ -877,8 +841,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_SUPPORT)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_SUPPORT)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_DHW_SUPPORT].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_DHW_SUPPORT].as(); if (value != dst.opentherm.options.dhwSupport) { dst.opentherm.options.dhwSupport = value; @@ -886,8 +850,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_COOLING_SUPPORT)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_COOLING_SUPPORT)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_COOLING_SUPPORT].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_COOLING_SUPPORT].as(); if (value != dst.opentherm.options.coolingSupport) { dst.opentherm.options.coolingSupport = value; @@ -895,8 +859,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SUMMER_WINTER_MODE)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SUMMER_WINTER_MODE)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_SUMMER_WINTER_MODE].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_SUMMER_WINTER_MODE].as(); if (value != dst.opentherm.options.summerWinterMode) { dst.opentherm.options.summerWinterMode = value; @@ -904,8 +868,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_STATE_TO_SUMMER_WINTER_MODE)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_HEATING_STATE_TO_SUMMER_WINTER_MODE].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_HEATING_STATE_TO_SUMMER_WINTER_MODE].as(); if (value != dst.opentherm.options.heatingStateToSummerWinterMode) { dst.opentherm.options.heatingStateToSummerWinterMode = value; @@ -913,8 +877,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_CH2_ALWAYS_ENABLED)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_CH2_ALWAYS_ENABLED)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_CH2_ALWAYS_ENABLED].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_CH2_ALWAYS_ENABLED].as(); if (value != dst.opentherm.options.ch2AlwaysEnabled) { dst.opentherm.options.ch2AlwaysEnabled = value; @@ -928,8 +892,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_TO_CH2)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_HEATING_TO_CH2)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_HEATING_TO_CH2].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_HEATING_TO_CH2].as(); if (value != dst.opentherm.options.heatingToCh2) { dst.opentherm.options.heatingToCh2 = value; @@ -943,8 +907,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_TO_CH2)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_TO_CH2)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_DHW_TO_CH2].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_DHW_TO_CH2].as(); if (value != dst.opentherm.options.dhwToCh2) { dst.opentherm.options.dhwToCh2 = value; @@ -958,8 +922,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_BLOCKING)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_BLOCKING)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_DHW_BLOCKING].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_DHW_BLOCKING].as(); if (value != dst.opentherm.options.dhwBlocking) { dst.opentherm.options.dhwBlocking = value; @@ -967,8 +931,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_STATE_AS_DHW_BLOCKING)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_DHW_STATE_AS_DHW_BLOCKING)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_DHW_STATE_AS_DHW_BLOCKING].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_DHW_STATE_AS_DHW_BLOCKING].as(); if (value != dst.opentherm.options.dhwStateAsDhwBlocking) { dst.opentherm.options.dhwStateAsDhwBlocking = value; @@ -976,8 +940,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_MAX_TEMP_SYNC_WITH_TARGET_TEMP)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_MAX_TEMP_SYNC_WITH_TARGET_TEMP].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_MAX_TEMP_SYNC_WITH_TARGET_TEMP].as(); if (value != dst.opentherm.options.maxTempSyncWithTargetTemp) { dst.opentherm.options.maxTempSyncWithTargetTemp = value; @@ -985,8 +949,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_GET_MIN_MAX_TEMP)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_GET_MIN_MAX_TEMP)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_GET_MIN_MAX_TEMP].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_GET_MIN_MAX_TEMP].as(); if (value != dst.opentherm.options.getMinMaxTemp) { dst.opentherm.options.getMinMaxTemp = value; @@ -994,8 +958,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IGNORE_DIAG_STATE)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IGNORE_DIAG_STATE)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_IGNORE_DIAG_STATE].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_IGNORE_DIAG_STATE].as(); if (value != dst.opentherm.options.ignoreDiagState) { dst.opentherm.options.ignoreDiagState = value; @@ -1003,8 +967,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_AUTO_FAULT_RESET)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_AUTO_FAULT_RESET)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_AUTO_FAULT_RESET].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_AUTO_FAULT_RESET].as(); if (value != dst.opentherm.options.autoFaultReset) { dst.opentherm.options.autoFaultReset = value; @@ -1012,8 +976,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_AUTO_DIAG_RESET)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_AUTO_DIAG_RESET)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_AUTO_DIAG_RESET].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_AUTO_DIAG_RESET].as(); if (value != dst.opentherm.options.autoDiagReset) { dst.opentherm.options.autoDiagReset = value; @@ -1021,8 +985,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SET_DATE_AND_TIME)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_SET_DATE_AND_TIME)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_SET_DATE_AND_TIME].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_SET_DATE_AND_TIME].as(); if (value != dst.opentherm.options.setDateAndTime) { dst.opentherm.options.setDateAndTime = value; @@ -1030,8 +994,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_ALWAYS_SEND_INDOOR_TEMP)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_ALWAYS_SEND_INDOOR_TEMP)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_ALWAYS_SEND_INDOOR_TEMP].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_ALWAYS_SEND_INDOOR_TEMP].as(); if (value != dst.opentherm.options.alwaysSendIndoorTemp) { dst.opentherm.options.alwaysSendIndoorTemp = value; @@ -1039,8 +1003,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_OTC)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_NATIVE_OTC)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_NATIVE_OTC].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_NATIVE_OTC].as(); if (value != dst.opentherm.options.nativeOTC) { dst.opentherm.options.nativeOTC = value; @@ -1054,8 +1018,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IMMERGAS_FIX)].is()) { - bool value = src[FPSTR(S_OPENTHERM)][FPSTR(S_OPTIONS)][FPSTR(S_IMMERGAS_FIX)].as(); + if (src[S_OPENTHERM][S_OPTIONS][S_IMMERGAS_FIX].is()) { + bool value = src[S_OPENTHERM][S_OPTIONS][S_IMMERGAS_FIX].as(); if (value != dst.opentherm.options.immergasFix) { dst.opentherm.options.immergasFix = value; @@ -1064,8 +1028,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } // mqtt - if (src[FPSTR(S_MQTT)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_MQTT)][FPSTR(S_ENABLED)].as(); + if (src[S_MQTT][S_ENABLED].is()) { + bool value = src[S_MQTT][S_ENABLED].as(); if (value != dst.mqtt.enabled) { dst.mqtt.enabled = value; @@ -1073,8 +1037,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_SERVER)].isNull()) { - String value = src[FPSTR(S_MQTT)][FPSTR(S_SERVER)].as(); + if (!src[S_MQTT][S_SERVER].isNull()) { + String value = src[S_MQTT][S_SERVER].as(); if (value.length() < sizeof(dst.mqtt.server) && !value.equals(dst.mqtt.server)) { strcpy(dst.mqtt.server, value.c_str()); @@ -1082,8 +1046,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_PORT)].isNull()) { - unsigned short value = src[FPSTR(S_MQTT)][FPSTR(S_PORT)].as(); + if (!src[S_MQTT][S_PORT].isNull()) { + unsigned short value = src[S_MQTT][S_PORT].as(); if (value > 0 && value <= 65535 && value != dst.mqtt.port) { dst.mqtt.port = value; @@ -1091,8 +1055,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_USER)].isNull()) { - String value = src[FPSTR(S_MQTT)][FPSTR(S_USER)].as(); + if (!src[S_MQTT][S_USER].isNull()) { + String value = src[S_MQTT][S_USER].as(); if (value.length() < sizeof(dst.mqtt.user) && !value.equals(dst.mqtt.user)) { strcpy(dst.mqtt.user, value.c_str()); @@ -1100,8 +1064,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_PASSWORD)].isNull()) { - String value = src[FPSTR(S_MQTT)][FPSTR(S_PASSWORD)].as(); + if (!src[S_MQTT][S_PASSWORD].isNull()) { + String value = src[S_MQTT][S_PASSWORD].as(); if (value.length() < sizeof(dst.mqtt.password) && !value.equals(dst.mqtt.password)) { strcpy(dst.mqtt.password, value.c_str()); @@ -1109,8 +1073,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_PREFIX)].isNull()) { - String value = src[FPSTR(S_MQTT)][FPSTR(S_PREFIX)].as(); + if (!src[S_MQTT][S_PREFIX].isNull()) { + String value = src[S_MQTT][S_PREFIX].as(); if (value.length() < sizeof(dst.mqtt.prefix) && !value.equals(dst.mqtt.prefix)) { strcpy(dst.mqtt.prefix, value.c_str()); @@ -1118,8 +1082,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_MQTT)][FPSTR(S_INTERVAL)].isNull()) { - unsigned short value = src[FPSTR(S_MQTT)][FPSTR(S_INTERVAL)].as(); + if (!src[S_MQTT][S_INTERVAL].isNull()) { + unsigned short value = src[S_MQTT][S_INTERVAL].as(); if (value >= 3 && value <= 60 && value != dst.mqtt.interval) { dst.mqtt.interval = value; @@ -1127,8 +1091,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_MQTT)][FPSTR(S_HOME_ASSISTANT_DISCOVERY)].is()) { - bool value = src[FPSTR(S_MQTT)][FPSTR(S_HOME_ASSISTANT_DISCOVERY)].as(); + if (src[S_MQTT][S_HOME_ASSISTANT_DISCOVERY].is()) { + bool value = src[S_MQTT][S_HOME_ASSISTANT_DISCOVERY].as(); if (value != dst.mqtt.homeAssistantDiscovery) { dst.mqtt.homeAssistantDiscovery = value; @@ -1138,8 +1102,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // emergency - if (!src[FPSTR(S_EMERGENCY)][FPSTR(S_TRESHOLD_TIME)].isNull()) { - unsigned short value = src[FPSTR(S_EMERGENCY)][FPSTR(S_TRESHOLD_TIME)].as(); + if (!src[S_EMERGENCY][S_TRESHOLD_TIME].isNull()) { + unsigned short value = src[S_EMERGENCY][S_TRESHOLD_TIME].as(); if (value >= 60 && value <= 1800 && value != dst.emergency.tresholdTime) { dst.emergency.tresholdTime = value; @@ -1150,8 +1114,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // equitherm - if (src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_EQUITHERM)][FPSTR(S_ENABLED)].as(); + if (src[S_EQUITHERM][S_ENABLED].is()) { + bool value = src[S_EQUITHERM][S_ENABLED].as(); if (!dst.opentherm.options.nativeOTC) { if (value != dst.equitherm.enabled) { @@ -1165,8 +1129,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EQUITHERM)][FPSTR(S_SLOPE)].isNull()) { - float value = src[FPSTR(S_EQUITHERM)][FPSTR(S_SLOPE)].as(); + if (!src[S_EQUITHERM][S_SLOPE].isNull()) { + float value = src[S_EQUITHERM][S_SLOPE].as(); if (value > 0.0f && value <= 10.0f && fabsf(value - dst.equitherm.slope) > 0.0001f) { dst.equitherm.slope = roundf(value, 3); @@ -1174,8 +1138,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EQUITHERM)][FPSTR(S_EXPONENT)].isNull()) { - float value = src[FPSTR(S_EQUITHERM)][FPSTR(S_EXPONENT)].as(); + if (!src[S_EQUITHERM][S_EXPONENT].isNull()) { + float value = src[S_EQUITHERM][S_EXPONENT].as(); if (value > 0.0f && value <= 2.0f && fabsf(value - dst.equitherm.exponent) > 0.0001f) { dst.equitherm.exponent = roundf(value, 3); @@ -1183,8 +1147,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EQUITHERM)][FPSTR(S_SHIFT)].isNull()) { - float value = src[FPSTR(S_EQUITHERM)][FPSTR(S_SHIFT)].as(); + if (!src[S_EQUITHERM][S_SHIFT].isNull()) { + float value = src[S_EQUITHERM][S_SHIFT].as(); if (value >= -15.0f && value <= 15.0f && fabsf(value - dst.equitherm.shift) > 0.0001f) { dst.equitherm.shift = roundf(value, 2); @@ -1192,8 +1156,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EQUITHERM)][FPSTR(S_TARGET_DIFF_FACTOR)].isNull()) { - float value = src[FPSTR(S_EQUITHERM)][FPSTR(S_TARGET_DIFF_FACTOR)].as(); + if (!src[S_EQUITHERM][S_TARGET_DIFF_FACTOR].isNull()) { + float value = src[S_EQUITHERM][S_TARGET_DIFF_FACTOR].as(); if (value >= 0.0f && value <= 10.0f && fabsf(value - dst.equitherm.targetDiffFactor) > 0.0001f) { dst.equitherm.targetDiffFactor = roundf(value, 3); @@ -1203,8 +1167,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // pid - if (src[FPSTR(S_PID)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_PID)][FPSTR(S_ENABLED)].as(); + if (src[S_PID][S_ENABLED].is()) { + bool value = src[S_PID][S_ENABLED].as(); if (!dst.opentherm.options.nativeOTC) { if (value != dst.pid.enabled) { @@ -1218,8 +1182,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_P_FACTOR)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_P_FACTOR)].as(); + if (!src[S_PID][S_P_FACTOR].isNull()) { + float value = src[S_PID][S_P_FACTOR].as(); if (value > 0 && value <= 1000 && fabsf(value - dst.pid.p_factor) > 0.0001f) { dst.pid.p_factor = roundf(value, 3); @@ -1227,8 +1191,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_I_FACTOR)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_I_FACTOR)].as(); + if (!src[S_PID][S_I_FACTOR].isNull()) { + float value = src[S_PID][S_I_FACTOR].as(); if (value >= 0 && value <= 100 && fabsf(value - dst.pid.i_factor) > 0.0001f) { dst.pid.i_factor = roundf(value, 4); @@ -1236,8 +1200,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_D_FACTOR)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_D_FACTOR)].as(); + if (!src[S_PID][S_D_FACTOR].isNull()) { + float value = src[S_PID][S_D_FACTOR].as(); if (value >= 0 && value <= 100000 && fabsf(value - dst.pid.d_factor) > 0.0001f) { dst.pid.d_factor = roundf(value, 1); @@ -1245,8 +1209,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DT)].isNull()) { - unsigned short value = src[FPSTR(S_PID)][FPSTR(S_DT)].as(); + if (!src[S_PID][S_DT].isNull()) { + unsigned short value = src[S_PID][S_DT].as(); if (value >= 30 && value <= 1800 && value != dst.pid.dt) { dst.pid.dt = value; @@ -1254,8 +1218,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_MIN_TEMP)].isNull()) { - short value = src[FPSTR(S_PID)][FPSTR(S_MIN_TEMP)].as(); + if (!src[S_PID][S_MIN_TEMP].isNull()) { + short value = src[S_PID][S_MIN_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, dst.equitherm.enabled ? -99.9f : 0.0f) && value != dst.pid.minTemp) { dst.pid.minTemp = value; @@ -1263,8 +1227,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_MAX_TEMP)].isNull()) { - short value = src[FPSTR(S_PID)][FPSTR(S_MAX_TEMP)].as(); + if (!src[S_PID][S_MAX_TEMP].isNull()) { + short value = src[S_PID][S_MAX_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem) && value != dst.pid.maxTemp) { dst.pid.maxTemp = value; @@ -1277,8 +1241,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false changed = true; } - if (src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_ENABLED)].as(); + if (src[S_PID][S_DEADBAND][S_ENABLED].is()) { + bool value = src[S_PID][S_DEADBAND][S_ENABLED].as(); if (value != dst.pid.deadband.enabled) { dst.pid.deadband.enabled = value; @@ -1286,8 +1250,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_P_MULTIPLIER)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_P_MULTIPLIER)].as(); + if (!src[S_PID][S_DEADBAND][S_P_MULTIPLIER].isNull()) { + float value = src[S_PID][S_DEADBAND][S_P_MULTIPLIER].as(); if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.p_multiplier) > 0.0001f) { dst.pid.deadband.p_multiplier = roundf(value, 3); @@ -1295,8 +1259,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_I_MULTIPLIER)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_I_MULTIPLIER)].as(); + if (!src[S_PID][S_DEADBAND][S_I_MULTIPLIER].isNull()) { + float value = src[S_PID][S_DEADBAND][S_I_MULTIPLIER].as(); if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.i_multiplier) > 0.0001f) { dst.pid.deadband.i_multiplier = roundf(value, 3); @@ -1304,8 +1268,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_D_MULTIPLIER)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_D_MULTIPLIER)].as(); + if (!src[S_PID][S_DEADBAND][S_D_MULTIPLIER].isNull()) { + float value = src[S_PID][S_DEADBAND][S_D_MULTIPLIER].as(); if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.d_multiplier) > 0.0001f) { dst.pid.deadband.d_multiplier = roundf(value, 3); @@ -1313,8 +1277,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_HIGH)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_HIGH)].as(); + if (!src[S_PID][S_DEADBAND][S_THRESHOLD_HIGH].isNull()) { + float value = src[S_PID][S_DEADBAND][S_THRESHOLD_HIGH].as(); if (value >= 0.0f && value <= 5.0f && fabsf(value - dst.pid.deadband.thresholdHigh) > 0.0001f) { dst.pid.deadband.thresholdHigh = roundf(value, 2); @@ -1322,8 +1286,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_LOW)].isNull()) { - float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_LOW)].as(); + if (!src[S_PID][S_DEADBAND][S_THRESHOLD_LOW].isNull()) { + float value = src[S_PID][S_DEADBAND][S_THRESHOLD_LOW].as(); if (value >= 0.0f && value <= 5.0f && fabsf(value - dst.pid.deadband.thresholdLow) > 0.0001f) { dst.pid.deadband.thresholdLow = roundf(value, 2); @@ -1333,8 +1297,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // heating - if (src[FPSTR(S_HEATING)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_HEATING)][FPSTR(S_ENABLED)].as(); + if (src[S_HEATING][S_ENABLED].is()) { + bool value = src[S_HEATING][S_ENABLED].as(); if (value != dst.heating.enabled) { dst.heating.enabled = value; @@ -1342,8 +1306,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_HEATING)][FPSTR(S_TURBO)].is()) { - bool value = src[FPSTR(S_HEATING)][FPSTR(S_TURBO)].as(); + if (src[S_HEATING][S_TURBO].is()) { + bool value = src[S_HEATING][S_TURBO].as(); if (value != dst.heating.turbo) { dst.heating.turbo = value; @@ -1351,8 +1315,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_ENABLED)].as(); + if (src[S_HEATING][S_HYSTERESIS][S_ENABLED].is()) { + bool value = src[S_HEATING][S_HYSTERESIS][S_ENABLED].as(); if (value != dst.heating.hysteresis.enabled) { dst.heating.hysteresis.enabled = value; @@ -1360,8 +1324,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_VALUE)].isNull()) { - float value = src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_VALUE)].as(); + if (!src[S_HEATING][S_HYSTERESIS][S_VALUE].isNull()) { + float value = src[S_HEATING][S_HYSTERESIS][S_VALUE].as(); if (value >= 0.0f && value <= 15.0f && fabsf(value - dst.heating.hysteresis.value) > 0.0001f) { dst.heating.hysteresis.value = roundf(value, 2); @@ -1369,8 +1333,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].isNull()) { - float value = src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].as(); + if (!src[S_HEATING][S_TURBO_FACTOR].isNull()) { + float value = src[S_HEATING][S_TURBO_FACTOR].as(); if (value >= 1.5f && value <= 10.0f && fabsf(value - dst.heating.turboFactor) > 0.0001f) { dst.heating.turboFactor = roundf(value, 3); @@ -1378,8 +1342,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_MIN_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_HEATING)][FPSTR(S_MIN_TEMP)].as(); + if (!src[S_HEATING][S_MIN_TEMP].isNull()) { + unsigned char value = src[S_HEATING][S_MIN_TEMP].as(); if (value != dst.heating.minTemp && value >= vars.slave.heating.minTemp && value < vars.slave.heating.maxTemp && value != dst.heating.maxTemp) { dst.heating.minTemp = value; @@ -1387,8 +1351,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_MAX_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_HEATING)][FPSTR(S_MAX_TEMP)].as(); + if (!src[S_HEATING][S_MAX_TEMP].isNull()) { + unsigned char value = src[S_HEATING][S_MAX_TEMP].as(); if (value != dst.heating.maxTemp && value > vars.slave.heating.minTemp && value <= vars.slave.heating.maxTemp && value != dst.heating.minTemp) { dst.heating.maxTemp = value; @@ -1402,8 +1366,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } - if (!src[FPSTR(S_HEATING)][FPSTR(S_MAX_MODULATION)].isNull()) { - unsigned char value = src[FPSTR(S_HEATING)][FPSTR(S_MAX_MODULATION)].as(); + if (!src[S_HEATING][S_MAX_MODULATION].isNull()) { + unsigned char value = src[S_HEATING][S_MAX_MODULATION].as(); if (value > 0 && value <= 100 && value != dst.heating.maxModulation) { dst.heating.maxModulation = value; @@ -1411,8 +1375,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_INDOOR_TEMP_AVG_TYPE)].isNull()) { - uint8_t value = src[FPSTR(S_HEATING)][FPSTR(S_INDOOR_TEMP_AVG_TYPE)].as(); + if (!src[S_HEATING][S_INDOOR_TEMP_AVG_TYPE].isNull()) { + uint8_t value = src[S_HEATING][S_INDOOR_TEMP_AVG_TYPE].as(); switch (value) { case static_cast(Sensors::AverageType::MEAN): @@ -1429,8 +1393,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_OUTDOOR_TEMP_AVG_TYPE)].isNull()) { - uint8_t value = src[FPSTR(S_HEATING)][FPSTR(S_OUTDOOR_TEMP_AVG_TYPE)].as(); + if (!src[S_HEATING][S_OUTDOOR_TEMP_AVG_TYPE].isNull()) { + uint8_t value = src[S_HEATING][S_OUTDOOR_TEMP_AVG_TYPE].as(); switch (value) { case static_cast(Sensors::AverageType::MEAN): @@ -1447,8 +1411,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_HIGH_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_HEATING)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_HIGH_TEMP)].as(); + if (!src[S_HEATING][S_OVERHEAT_PROTECTION][S_HIGH_TEMP].isNull()) { + unsigned char value = src[S_HEATING][S_OVERHEAT_PROTECTION][S_HIGH_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 0.0f, 100.0f) && value != dst.heating.overheatProtection.highTemp) { dst.heating.overheatProtection.highTemp = value; @@ -1456,8 +1420,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_LOW_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_HEATING)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_LOW_TEMP)].as(); + if (!src[S_HEATING][S_OVERHEAT_PROTECTION][S_LOW_TEMP].isNull()) { + unsigned char value = src[S_HEATING][S_OVERHEAT_PROTECTION][S_LOW_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 0.0f, 99.0f) && value != dst.heating.overheatProtection.lowTemp) { dst.heating.overheatProtection.lowTemp = value; @@ -1470,8 +1434,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false changed = true; } - if (!src[FPSTR(S_HEATING)][FPSTR(S_FREEZE_PROTECTION)][FPSTR(S_HIGH_TEMP)].isNull()) { - unsigned short value = src[FPSTR(S_HEATING)][FPSTR(S_FREEZE_PROTECTION)][FPSTR(S_HIGH_TEMP)].as(); + if (!src[S_HEATING][S_FREEZE_PROTECTION][S_HIGH_TEMP].isNull()) { + unsigned short value = src[S_HEATING][S_FREEZE_PROTECTION][S_HIGH_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 1, 50) && value != dst.heating.freezeProtection.highTemp) { dst.heating.freezeProtection.highTemp = value; @@ -1479,8 +1443,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_HEATING)][FPSTR(S_FREEZE_PROTECTION)][FPSTR(S_LOW_TEMP)].isNull()) { - unsigned short value = src[FPSTR(S_HEATING)][FPSTR(S_FREEZE_PROTECTION)][FPSTR(S_LOW_TEMP)].as(); + if (!src[S_HEATING][S_FREEZE_PROTECTION][S_LOW_TEMP].isNull()) { + unsigned short value = src[S_HEATING][S_FREEZE_PROTECTION][S_LOW_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 1, 30) && value != dst.heating.freezeProtection.lowTemp) { dst.heating.freezeProtection.lowTemp = value; @@ -1495,8 +1459,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // dhw - if (src[FPSTR(S_DHW)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_DHW)][FPSTR(S_ENABLED)].as(); + if (src[S_DHW][S_ENABLED].is()) { + bool value = src[S_DHW][S_ENABLED].as(); if (value != dst.dhw.enabled) { dst.dhw.enabled = value; @@ -1504,8 +1468,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_DHW)][FPSTR(S_MIN_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_DHW)][FPSTR(S_MIN_TEMP)].as(); + if (!src[S_DHW][S_MIN_TEMP].isNull()) { + unsigned char value = src[S_DHW][S_MIN_TEMP].as(); if (value >= vars.slave.dhw.minTemp && value < vars.slave.dhw.maxTemp && value != dst.dhw.minTemp) { dst.dhw.minTemp = value; @@ -1513,8 +1477,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_DHW)][FPSTR(S_MAX_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_DHW)][FPSTR(S_MAX_TEMP)].as(); + if (!src[S_DHW][S_MAX_TEMP].isNull()) { + unsigned char value = src[S_DHW][S_MAX_TEMP].as(); if (value > vars.slave.dhw.minTemp && value <= vars.slave.dhw.maxTemp && value != dst.dhw.maxTemp) { dst.dhw.maxTemp = value; @@ -1527,8 +1491,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false changed = true; } - if (!src[FPSTR(S_DHW)][FPSTR(S_MAX_MODULATION)].isNull()) { - unsigned char value = src[FPSTR(S_DHW)][FPSTR(S_MAX_MODULATION)].as(); + if (!src[S_DHW][S_MAX_MODULATION].isNull()) { + unsigned char value = src[S_DHW][S_MAX_MODULATION].as(); if (value > 0 && value <= 100 && value != dst.dhw.maxModulation) { dst.dhw.maxModulation = value; @@ -1536,8 +1500,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_DHW)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_HIGH_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_DHW)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_HIGH_TEMP)].as(); + if (!src[S_DHW][S_OVERHEAT_PROTECTION][S_HIGH_TEMP].isNull()) { + unsigned char value = src[S_DHW][S_OVERHEAT_PROTECTION][S_HIGH_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 0.0f, 100.0f) && value != dst.dhw.overheatProtection.highTemp) { dst.dhw.overheatProtection.highTemp = value; @@ -1545,8 +1509,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_DHW)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_LOW_TEMP)].isNull()) { - unsigned char value = src[FPSTR(S_DHW)][FPSTR(S_OVERHEAT_PROTECTION)][FPSTR(S_LOW_TEMP)].as(); + if (!src[S_DHW][S_OVERHEAT_PROTECTION][S_LOW_TEMP].isNull()) { + unsigned char value = src[S_DHW][S_OVERHEAT_PROTECTION][S_LOW_TEMP].as(); if (isValidTemp(value, dst.system.unitSystem, 0.0f, 99.0f) && value != dst.dhw.overheatProtection.lowTemp) { dst.dhw.overheatProtection.lowTemp = value; @@ -1562,8 +1526,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false if (!safe) { // external pump - if (src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_USE)].is()) { - bool value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_USE)].as(); + if (src[S_EXTERNAL_PUMP][S_USE].is()) { + bool value = src[S_EXTERNAL_PUMP][S_USE].as(); if (value != dst.externalPump.use) { dst.externalPump.use = value; @@ -1571,15 +1535,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_GPIO)].isNull()) { - if (src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_GPIO)].is() && src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_GPIO)].as().size() == 0) { + if (!src[S_EXTERNAL_PUMP][S_GPIO].isNull()) { + if (src[S_EXTERNAL_PUMP][S_GPIO].is() && src[S_EXTERNAL_PUMP][S_GPIO].as().size() == 0) { if (dst.externalPump.gpio != GPIO_IS_NOT_CONFIGURED) { dst.externalPump.gpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_GPIO)].as(); + unsigned char value = src[S_EXTERNAL_PUMP][S_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.externalPump.gpio) { dst.externalPump.gpio = value; @@ -1588,8 +1552,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_INVERT_STATE)].is()) { - bool value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_INVERT_STATE)].as(); + if (src[S_EXTERNAL_PUMP][S_INVERT_STATE].is()) { + bool value = src[S_EXTERNAL_PUMP][S_INVERT_STATE].as(); if (value != dst.externalPump.invertState) { dst.externalPump.invertState = value; @@ -1597,8 +1561,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_POST_CIRCULATION_TIME)].isNull()) { - unsigned short value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_POST_CIRCULATION_TIME)].as(); + if (!src[S_EXTERNAL_PUMP][S_POST_CIRCULATION_TIME].isNull()) { + unsigned short value = src[S_EXTERNAL_PUMP][S_POST_CIRCULATION_TIME].as(); if (value >= 0 && value <= 120) { value = value * 60; @@ -1610,8 +1574,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_ANTI_STUCK_INTERVAL)].isNull()) { - unsigned int value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_ANTI_STUCK_INTERVAL)].as(); + if (!src[S_EXTERNAL_PUMP][S_ANTI_STUCK_INTERVAL].isNull()) { + unsigned int value = src[S_EXTERNAL_PUMP][S_ANTI_STUCK_INTERVAL].as(); if (value >= 0 && value <= 366) { value = value * 86400; @@ -1623,8 +1587,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_ANTI_STUCK_TIME)].isNull()) { - unsigned short value = src[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_ANTI_STUCK_TIME)].as(); + if (!src[S_EXTERNAL_PUMP][S_ANTI_STUCK_TIME].isNull()) { + unsigned short value = src[S_EXTERNAL_PUMP][S_ANTI_STUCK_TIME].as(); if (value >= 0 && value <= 20) { value = value * 60; @@ -1638,8 +1602,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // cascade control - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_ENABLED)].as(); + if (src[S_CASCADE_CONTROL][S_INPUT][S_ENABLED].is()) { + bool value = src[S_CASCADE_CONTROL][S_INPUT][S_ENABLED].as(); if (value != dst.cascadeControl.input.enabled) { dst.cascadeControl.input.enabled = value; @@ -1647,15 +1611,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_GPIO)].isNull()) { - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_GPIO)].is() && src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_GPIO)].as().size() == 0) { + if (!src[S_CASCADE_CONTROL][S_INPUT][S_GPIO].isNull()) { + if (src[S_CASCADE_CONTROL][S_INPUT][S_GPIO].is() && src[S_CASCADE_CONTROL][S_INPUT][S_GPIO].as().size() == 0) { if (dst.cascadeControl.input.gpio != GPIO_IS_NOT_CONFIGURED) { dst.cascadeControl.input.gpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_GPIO)].as(); + unsigned char value = src[S_CASCADE_CONTROL][S_INPUT][S_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.cascadeControl.input.gpio) { dst.cascadeControl.input.gpio = value; @@ -1664,8 +1628,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_INVERT_STATE)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_INVERT_STATE)].as(); + if (src[S_CASCADE_CONTROL][S_INPUT][S_INVERT_STATE].is()) { + bool value = src[S_CASCADE_CONTROL][S_INPUT][S_INVERT_STATE].as(); if (value != dst.cascadeControl.input.invertState) { dst.cascadeControl.input.invertState = value; @@ -1673,8 +1637,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_THRESHOLD_TIME)].isNull()) { - unsigned short value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_INPUT)][FPSTR(S_THRESHOLD_TIME)].as(); + if (!src[S_CASCADE_CONTROL][S_INPUT][S_THRESHOLD_TIME].isNull()) { + unsigned short value = src[S_CASCADE_CONTROL][S_INPUT][S_THRESHOLD_TIME].as(); if (value >= 5 && value <= 600) { if (value != dst.cascadeControl.input.thresholdTime) { @@ -1684,8 +1648,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ENABLED)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ENABLED)].as(); + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_ENABLED].is()) { + bool value = src[S_CASCADE_CONTROL][S_OUTPUT][S_ENABLED].as(); if (value != dst.cascadeControl.output.enabled) { dst.cascadeControl.output.enabled = value; @@ -1693,15 +1657,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_GPIO)].isNull()) { - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_GPIO)].is() && src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_GPIO)].as().size() == 0) { + if (!src[S_CASCADE_CONTROL][S_OUTPUT][S_GPIO].isNull()) { + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_GPIO].is() && src[S_CASCADE_CONTROL][S_OUTPUT][S_GPIO].as().size() == 0) { if (dst.cascadeControl.output.gpio != GPIO_IS_NOT_CONFIGURED) { dst.cascadeControl.output.gpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_GPIO)].as(); + unsigned char value = src[S_CASCADE_CONTROL][S_OUTPUT][S_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.cascadeControl.output.gpio) { dst.cascadeControl.output.gpio = value; @@ -1710,8 +1674,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_INVERT_STATE)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_INVERT_STATE)].as(); + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_INVERT_STATE].is()) { + bool value = src[S_CASCADE_CONTROL][S_OUTPUT][S_INVERT_STATE].as(); if (value != dst.cascadeControl.output.invertState) { dst.cascadeControl.output.invertState = value; @@ -1719,8 +1683,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (!src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_THRESHOLD_TIME)].isNull()) { - unsigned short value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_THRESHOLD_TIME)].as(); + if (!src[S_CASCADE_CONTROL][S_OUTPUT][S_THRESHOLD_TIME].isNull()) { + unsigned short value = src[S_CASCADE_CONTROL][S_OUTPUT][S_THRESHOLD_TIME].as(); if (value >= 5 && value <= 600) { if (value != dst.cascadeControl.output.thresholdTime) { @@ -1730,8 +1694,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_FAULT)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_FAULT)].as(); + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_FAULT].is()) { + bool value = src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_FAULT].as(); if (value != dst.cascadeControl.output.onFault) { dst.cascadeControl.output.onFault = value; @@ -1739,8 +1703,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_LOSS_CONNECTION)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_LOSS_CONNECTION)].as(); + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_LOSS_CONNECTION].is()) { + bool value = src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_LOSS_CONNECTION].as(); if (value != dst.cascadeControl.output.onLossConnection) { dst.cascadeControl.output.onLossConnection = value; @@ -1748,8 +1712,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } - if (src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_ENABLED_HEATING)].is()) { - bool value = src[FPSTR(S_CASCADE_CONTROL)][FPSTR(S_OUTPUT)][FPSTR(S_ON_ENABLED_HEATING)].as(); + if (src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_ENABLED_HEATING].is()) { + bool value = src[S_CASCADE_CONTROL][S_OUTPUT][S_ON_ENABLED_HEATING].as(); if (value != dst.cascadeControl.output.onEnabledHeating) { dst.cascadeControl.output.onEnabledHeating = value; @@ -1760,7 +1724,7 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // force check emergency target { - float value = !src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].isNull() ? src[FPSTR(S_EMERGENCY)][FPSTR(S_TARGET)].as() : dst.emergency.target; + float value = !src[S_EMERGENCY][S_TARGET].isNull() ? src[S_EMERGENCY][S_TARGET].as() : dst.emergency.target; bool noRegulators = !dst.opentherm.options.nativeOTC; bool valid = isValidTemp( value, @@ -1790,8 +1754,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false float minTemp = indoorTempControl ? THERMOSTAT_INDOOR_MIN_TEMP : dst.heating.minTemp; float maxTemp = indoorTempControl ? THERMOSTAT_INDOOR_MAX_TEMP : dst.heating.maxTemp; - float value = !src[FPSTR(S_HEATING)][FPSTR(S_TARGET)].isNull() - ? src[FPSTR(S_HEATING)][FPSTR(S_TARGET)].as() + float value = !src[S_HEATING][S_TARGET].isNull() + ? src[S_HEATING][S_TARGET].as() : dst.heating.target; bool valid = isValidTemp( value, @@ -1817,8 +1781,8 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false // force check dhw target { - float value = !src[FPSTR(S_DHW)][FPSTR(S_TARGET)].isNull() - ? src[FPSTR(S_DHW)][FPSTR(S_TARGET)].as() + float value = !src[S_DHW][S_TARGET].isNull() + ? src[S_DHW][S_TARGET].as() : dst.dhw.target; bool valid = isValidTemp( value, @@ -1846,41 +1810,41 @@ inline bool safeJsonToSettings(const JsonVariantConst src, Settings& dst) { } void sensorSettingsToJson(const uint8_t sensorId, const Sensors::Settings& src, JsonVariant dst) { - dst[FPSTR(S_ID)] = sensorId; - dst[FPSTR(S_ENABLED)] = src.enabled; - dst[FPSTR(S_NAME)] = src.name; - dst[FPSTR(S_PURPOSE)] = static_cast(src.purpose); - dst[FPSTR(S_TYPE)] = static_cast(src.type); - dst[FPSTR(S_GPIO)] = src.gpio; + dst[S_ID] = sensorId; + dst[S_ENABLED] = src.enabled; + dst[S_NAME] = src.name; + dst[S_PURPOSE] = static_cast(src.purpose); + dst[S_TYPE] = static_cast(src.type); + dst[S_GPIO] = src.gpio; if (src.type == Sensors::Type::DALLAS_TEMP) { char addr[24]; - sprintf_P( + sprintf( addr, - PSTR("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"), + "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", src.address[0], src.address[1], src.address[2], src.address[3], src.address[4], src.address[5], src.address[6], src.address[7] ); - dst[FPSTR(S_ADDRESS)] = String(addr); + dst[S_ADDRESS] = String(addr); } else if (src.type == Sensors::Type::BLUETOOTH) { char addr[18]; - sprintf_P( + sprintf( addr, - PSTR("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"), + "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", src.address[0], src.address[1], src.address[2], src.address[3], src.address[4], src.address[5] ); - dst[FPSTR(S_ADDRESS)] = String(addr); + dst[S_ADDRESS] = String(addr); } else { - dst[FPSTR(S_ADDRESS)] = ""; + dst[S_ADDRESS] = ""; } - dst[FPSTR(S_OFFSET)] = roundf(src.offset, 3); - dst[FPSTR(S_FACTOR)] = roundf(src.factor, 3); - dst[FPSTR(S_FILTERING)] = src.filtering; - dst[FPSTR(S_FILTERING_FACTOR)] = roundf(src.filteringFactor, 3); + dst[S_OFFSET] = roundf(src.offset, 3); + dst[S_FACTOR] = roundf(src.factor, 3); + dst[S_FILTERING] = src.filtering; + dst[S_FILTERING_FACTOR] = roundf(src.filteringFactor, 3); } bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Sensors::Settings& dst) { @@ -1891,8 +1855,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se bool changed = false; // enabled - if (src[FPSTR(S_ENABLED)].is()) { - auto value = src[FPSTR(S_ENABLED)].as(); + if (src[S_ENABLED].is()) { + auto value = src[S_ENABLED].as(); if (value != dst.enabled) { dst.enabled = value; @@ -1901,8 +1865,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // name - if (src[FPSTR(S_NAME)].is() && src[FPSTR(S_NAME)].as().size() < sizeof(dst.name)) { - auto value = src[FPSTR(S_NAME)].as(); + if (src[S_NAME].is() && src[S_NAME].as().size() < sizeof(dst.name)) { + auto value = src[S_NAME].as(); Sensors::cleanName(value); if (value.length() < sizeof(dst.name) && !value.equals(dst.name)) { @@ -1912,8 +1876,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // purpose - if (!src[FPSTR(S_PURPOSE)].isNull()) { - uint8_t value = src[FPSTR(S_PURPOSE)].as(); + if (!src[S_PURPOSE].isNull()) { + uint8_t value = src[S_PURPOSE].as(); switch (value) { case static_cast(Sensors::Purpose::OUTDOOR_TEMP): @@ -1947,8 +1911,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // type - if (!src[FPSTR(S_TYPE)].isNull()) { - uint8_t value = src[FPSTR(S_TYPE)].as(); + if (!src[S_TYPE].isNull()) { + uint8_t value = src[S_TYPE].as(); switch (value) { case static_cast(Sensors::Type::OT_OUTDOOR_TEMP): @@ -2001,7 +1965,7 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // gpio - if (!src[FPSTR(S_GPIO)].isNull()) { + if (!src[S_GPIO].isNull()) { if (dst.type != Sensors::Type::DALLAS_TEMP && dst.type != Sensors::Type::NTC_10K_TEMP && dst.type != Sensors::Type::DHT11 && dst.type != Sensors::Type::DHT22) { if (dst.gpio != GPIO_IS_NOT_CONFIGURED) { @@ -2009,14 +1973,14 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se changed = true; } - } else if (src[FPSTR(S_GPIO)].is() && src[FPSTR(S_GPIO)].as().size() == 0) { + } else if (src[S_GPIO].is() && src[S_GPIO].as().size() == 0) { if (dst.gpio != GPIO_IS_NOT_CONFIGURED) { dst.gpio = GPIO_IS_NOT_CONFIGURED; changed = true; } } else { - unsigned char value = src[FPSTR(S_GPIO)].as(); + unsigned char value = src[S_GPIO].as(); if (GPIO_IS_VALID(value) && value != dst.gpio) { dst.gpio = value; @@ -2026,8 +1990,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // address - if (!src[FPSTR(S_ADDRESS)].isNull()) { - String value = src[FPSTR(S_ADDRESS)].as(); + if (!src[S_ADDRESS].isNull()) { + String value = src[S_ADDRESS].as(); if (dst.type == Sensors::Type::DALLAS_TEMP) { uint8_t tmp[8]; @@ -2084,8 +2048,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // offset - if (!src[FPSTR(S_OFFSET)].isNull()) { - float value = src[FPSTR(S_OFFSET)].as(); + if (!src[S_OFFSET].isNull()) { + float value = src[S_OFFSET].as(); if (value >= -20.0f && value <= 20.0f && fabsf(value - dst.offset) > 0.0001f) { dst.offset = roundf(value, 2); @@ -2094,8 +2058,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // factor - if (!src[FPSTR(S_FACTOR)].isNull()) { - float value = src[FPSTR(S_FACTOR)].as(); + if (!src[S_FACTOR].isNull()) { + float value = src[S_FACTOR].as(); if (value > 0.09f && value <= 100.0f && fabsf(value - dst.factor) > 0.0001f) { dst.factor = roundf(value, 3); @@ -2104,8 +2068,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // filtering - if (src[FPSTR(S_FILTERING)].is()) { - auto value = src[FPSTR(S_FILTERING)].as(); + if (src[S_FILTERING].is()) { + auto value = src[S_FILTERING].as(); if (value != dst.filtering) { dst.filtering = value; @@ -2114,8 +2078,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se } // filtering factor - if (!src[FPSTR(S_FILTERING_FACTOR)].isNull()) { - float value = src[FPSTR(S_FILTERING_FACTOR)].as(); + if (!src[S_FILTERING_FACTOR].isNull()) { + float value = src[S_FILTERING_FACTOR].as(); if (value > 0 && value <= 1 && fabsf(value - dst.filteringFactor) > 0.0001f) { dst.filteringFactor = roundf(value, 3); @@ -2134,22 +2098,22 @@ void sensorResultToJson(const uint8_t sensorId, JsonVariant dst) { auto& sSensor = Sensors::settings[sensorId]; auto& rSensor = Sensors::results[sensorId]; - //dst[FPSTR(S_ID)] = sensorId; - dst[FPSTR(S_CONNECTED)] = rSensor.connected; - dst[FPSTR(S_SIGNAL_QUALITY)] = rSensor.signalQuality; + //dst[S_ID] = sensorId; + dst[S_CONNECTED] = rSensor.connected; + dst[S_SIGNAL_QUALITY] = rSensor.signalQuality; if (sSensor.type == Sensors::Type::BLUETOOTH) { - dst[FPSTR(S_TEMPERATURE)] = roundf(rSensor.values[static_cast(Sensors::ValueType::TEMPERATURE)], 3); - dst[FPSTR(S_HUMIDITY)] = roundf(rSensor.values[static_cast(Sensors::ValueType::HUMIDITY)], 3); - dst[FPSTR(S_BATTERY)] = roundf(rSensor.values[static_cast(Sensors::ValueType::BATTERY)], 1); - dst[FPSTR(S_RSSI)] = roundf(rSensor.values[static_cast(Sensors::ValueType::RSSI)], 0); + dst[S_TEMPERATURE] = roundf(rSensor.values[static_cast(Sensors::ValueType::TEMPERATURE)], 3); + dst[S_HUMIDITY] = roundf(rSensor.values[static_cast(Sensors::ValueType::HUMIDITY)], 3); + dst[S_BATTERY] = roundf(rSensor.values[static_cast(Sensors::ValueType::BATTERY)], 1); + dst[S_RSSI] = roundf(rSensor.values[static_cast(Sensors::ValueType::RSSI)], 0); } else if (sSensor.type == Sensors::Type::DHT11 || sSensor.type == Sensors::Type::DHT22) { - dst[FPSTR(S_TEMPERATURE)] = roundf(rSensor.values[static_cast(Sensors::ValueType::TEMPERATURE)], 3); - dst[FPSTR(S_HUMIDITY)] = roundf(rSensor.values[static_cast(Sensors::ValueType::HUMIDITY)], 3); + dst[S_TEMPERATURE] = roundf(rSensor.values[static_cast(Sensors::ValueType::TEMPERATURE)], 3); + dst[S_HUMIDITY] = roundf(rSensor.values[static_cast(Sensors::ValueType::HUMIDITY)], 3); } else { - dst[FPSTR(S_VALUE)] = roundf(rSensor.values[static_cast(Sensors::ValueType::PRIMARY)], 3); + dst[S_VALUE] = roundf(rSensor.values[static_cast(Sensors::ValueType::PRIMARY)], 3); } } @@ -2164,10 +2128,10 @@ bool jsonToSensorResult(const uint8_t sensorId, const JsonVariantConst src) { } // value - if (!src[FPSTR(S_VALUE)].isNull()) { + if (!src[S_VALUE].isNull()) { return Sensors::setValueById( sensorId, - src[FPSTR(S_VALUE)].as(), + src[S_VALUE].as(), Sensors::ValueType::PRIMARY, true, true @@ -2178,97 +2142,97 @@ bool jsonToSensorResult(const uint8_t sensorId, const JsonVariantConst src) { } void varsToJson(const Variables& src, JsonVariant dst) { - auto slave = dst[FPSTR(S_SLAVE)].to(); - slave[FPSTR(S_MEMBER_ID)] = src.slave.memberId; - slave[FPSTR(S_FLAGS)] = src.slave.flags; - slave[FPSTR(S_TYPE)] = src.slave.type; - slave[FPSTR(S_APP_VERSION)] = src.slave.appVersion; - slave[FPSTR(S_PROTOCOL_VERSION)] = src.slave.protocolVersion; - slave[FPSTR(S_CONNECTED)] = src.slave.connected; - slave[FPSTR(S_FLAME)] = src.slave.flame; + auto slave = dst[S_SLAVE].to(); + slave[S_MEMBER_ID] = src.slave.memberId; + slave[S_FLAGS] = src.slave.flags; + slave[S_TYPE] = src.slave.type; + slave[S_APP_VERSION] = src.slave.appVersion; + slave[S_PROTOCOL_VERSION] = src.slave.protocolVersion; + slave[S_CONNECTED] = src.slave.connected; + slave[S_FLAME] = src.slave.flame; - auto sCooling = slave[FPSTR(S_COOLING)].to(); - sCooling[FPSTR(S_ACTIVE)] = src.slave.cooling.active; - sCooling[FPSTR(S_SETPOINT)] = src.slave.cooling.setpoint; + auto sCooling = slave[S_COOLING].to(); + sCooling[S_ACTIVE] = src.slave.cooling.active; + sCooling[S_SETPOINT] = src.slave.cooling.setpoint; - auto sModulation = slave[FPSTR(S_MODULATION)].to(); - sModulation[FPSTR(S_MIN)] = src.slave.modulation.min; - sModulation[FPSTR(S_MAX)] = src.slave.modulation.max; + auto sModulation = slave[S_MODULATION].to(); + sModulation[S_MIN] = src.slave.modulation.min; + sModulation[S_MAX] = src.slave.modulation.max; - auto sPower = slave[FPSTR(S_POWER)].to(); - sPower[FPSTR(S_MIN)] = roundf(src.slave.power.min, 2); - sPower[FPSTR(S_MAX)] = roundf(src.slave.power.max, 2); + auto sPower = slave[S_POWER].to(); + sPower[S_MIN] = roundf(src.slave.power.min, 2); + sPower[S_MAX] = roundf(src.slave.power.max, 2); - auto sHeating = slave[FPSTR(S_HEATING)].to(); - sHeating[FPSTR(S_ACTIVE)] = src.slave.heating.active; - sHeating[FPSTR(S_MIN_TEMP)] = src.slave.heating.minTemp; - sHeating[FPSTR(S_MAX_TEMP)] = src.slave.heating.maxTemp; + auto sHeating = slave[S_HEATING].to(); + sHeating[S_ACTIVE] = src.slave.heating.active; + sHeating[S_MIN_TEMP] = src.slave.heating.minTemp; + sHeating[S_MAX_TEMP] = src.slave.heating.maxTemp; - auto sDhw = slave[FPSTR(S_DHW)].to(); - sDhw[FPSTR(S_ACTIVE)] = src.slave.dhw.active; - sDhw[FPSTR(S_MIN_TEMP)] = src.slave.dhw.minTemp; - sDhw[FPSTR(S_MAX_TEMP)] = src.slave.dhw.maxTemp; + auto sDhw = slave[S_DHW].to(); + sDhw[S_ACTIVE] = src.slave.dhw.active; + sDhw[S_MIN_TEMP] = src.slave.dhw.minTemp; + sDhw[S_MAX_TEMP] = src.slave.dhw.maxTemp; - auto sFault = slave[FPSTR(S_FAULT)].to(); - sFault[FPSTR(S_ACTIVE)] = src.slave.fault.active; - sFault[FPSTR(S_CODE)] = src.slave.fault.code; + auto sFault = slave[S_FAULT].to(); + sFault[S_ACTIVE] = src.slave.fault.active; + sFault[S_CODE] = src.slave.fault.code; - auto sDiag = slave[FPSTR(S_DIAG)].to(); - sDiag[FPSTR(S_ACTIVE)] = src.slave.diag.active; - sDiag[FPSTR(S_CODE)] = src.slave.diag.code; + auto sDiag = slave[S_DIAG].to(); + sDiag[S_ACTIVE] = src.slave.diag.active; + sDiag[S_CODE] = src.slave.diag.code; - auto master = dst[FPSTR(S_MASTER)].to(); - auto mHeating = master[FPSTR(S_HEATING)].to(); - mHeating[FPSTR(S_ENABLED)] = src.master.heating.enabled; - mHeating[FPSTR(S_BLOCKING)] = src.master.heating.blocking; - mHeating[FPSTR(S_INDOOR_TEMP_CONTROL)] = src.master.heating.indoorTempControl; - mHeating[FPSTR(S_OVERHEAT)] = src.master.heating.overheat; - mHeating[FPSTR(S_FREEZING)] = src.master.heating.freezing; - mHeating[FPSTR(S_SETPOINT_TEMP)] = roundf(src.master.heating.setpointTemp, 2); - mHeating[FPSTR(S_TARGET_TEMP)] = roundf(src.master.heating.targetTemp, 2); - mHeating[FPSTR(S_CURRENT_TEMP)] = roundf(src.master.heating.currentTemp, 2); - mHeating[FPSTR(S_RETURN_TEMP)] = roundf(src.master.heating.returnTemp, 2); - mHeating[FPSTR(S_INDOOR_TEMP)] = roundf(src.master.heating.indoorTemp, 2); - mHeating[FPSTR(S_OUTDOOR_TEMP)] = roundf(src.master.heating.outdoorTemp, 2); - mHeating[FPSTR(S_MIN_TEMP)] = roundf(src.master.heating.minTemp, 2); - mHeating[FPSTR(S_MAX_TEMP)] = roundf(src.master.heating.maxTemp, 2); + auto master = dst[S_MASTER].to(); + auto mHeating = master[S_HEATING].to(); + mHeating[S_ENABLED] = src.master.heating.enabled; + mHeating[S_BLOCKING] = src.master.heating.blocking; + mHeating[S_INDOOR_TEMP_CONTROL] = src.master.heating.indoorTempControl; + mHeating[S_OVERHEAT] = src.master.heating.overheat; + mHeating[S_FREEZING] = src.master.heating.freezing; + mHeating[S_SETPOINT_TEMP] = roundf(src.master.heating.setpointTemp, 2); + mHeating[S_TARGET_TEMP] = roundf(src.master.heating.targetTemp, 2); + mHeating[S_CURRENT_TEMP] = roundf(src.master.heating.currentTemp, 2); + mHeating[S_RETURN_TEMP] = roundf(src.master.heating.returnTemp, 2); + mHeating[S_INDOOR_TEMP] = roundf(src.master.heating.indoorTemp, 2); + mHeating[S_OUTDOOR_TEMP] = roundf(src.master.heating.outdoorTemp, 2); + mHeating[S_MIN_TEMP] = roundf(src.master.heating.minTemp, 2); + mHeating[S_MAX_TEMP] = roundf(src.master.heating.maxTemp, 2); - auto mDhw = master[FPSTR(S_DHW)].to(); - mDhw[FPSTR(S_ENABLED)] = src.master.dhw.enabled; - mDhw[FPSTR(S_OVERHEAT)] = src.master.dhw.overheat; - mDhw[FPSTR(S_TARGET_TEMP)] = roundf(src.master.dhw.targetTemp, 2); - mDhw[FPSTR(S_CURRENT_TEMP)] = roundf(src.master.dhw.currentTemp, 2); - mDhw[FPSTR(S_RETURN_TEMP)] = roundf(src.master.dhw.returnTemp, 2); - mDhw[FPSTR(S_MIN_TEMP)] = settings.dhw.minTemp; - mDhw[FPSTR(S_MAX_TEMP)] = settings.dhw.maxTemp; + auto mDhw = master[S_DHW].to(); + mDhw[S_ENABLED] = src.master.dhw.enabled; + mDhw[S_OVERHEAT] = src.master.dhw.overheat; + mDhw[S_TARGET_TEMP] = roundf(src.master.dhw.targetTemp, 2); + mDhw[S_CURRENT_TEMP] = roundf(src.master.dhw.currentTemp, 2); + mDhw[S_RETURN_TEMP] = roundf(src.master.dhw.returnTemp, 2); + mDhw[S_MIN_TEMP] = settings.dhw.minTemp; + mDhw[S_MAX_TEMP] = settings.dhw.maxTemp; - master[FPSTR(S_NETWORK)][FPSTR(S_CONNECTED)] = src.network.connected; - master[FPSTR(S_NETWORK)][FPSTR(S_RSSI)] = src.network.rssi; - master[FPSTR(S_MQTT)][FPSTR(S_CONNECTED)] = src.mqtt.connected; - master[FPSTR(S_EMERGENCY)][FPSTR(S_STATE)] = src.emergency.state; - master[FPSTR(S_EXTERNAL_PUMP)][FPSTR(S_STATE)] = src.externalPump.state; + master[S_NETWORK][S_CONNECTED] = src.network.connected; + master[S_NETWORK][S_RSSI] = src.network.rssi; + master[S_MQTT][S_CONNECTED] = src.mqtt.connected; + master[S_EMERGENCY][S_STATE] = src.emergency.state; + master[S_EXTERNAL_PUMP][S_STATE] = src.externalPump.state; - auto mCascadeControl = master[FPSTR(S_CASCADE_CONTROL)].to(); - mCascadeControl[FPSTR(S_INPUT)] = src.cascadeControl.input; - mCascadeControl[FPSTR(S_OUTPUT)] = src.cascadeControl.output; + auto mCascadeControl = master[S_CASCADE_CONTROL].to(); + mCascadeControl[S_INPUT] = src.cascadeControl.input; + mCascadeControl[S_OUTPUT] = src.cascadeControl.output; - master[FPSTR(S_UPTIME)] = millis() / 1000; + master[S_UPTIME] = millis() / 1000; } bool jsonToVars(const JsonVariantConst src, Variables& dst) { bool changed = false; // actions - if (src[FPSTR(S_ACTIONS)][FPSTR(S_RESTART)].is() && src[FPSTR(S_ACTIONS)][FPSTR(S_RESTART)].as()) { + if (src[S_ACTIONS][S_RESTART].is() && src[S_ACTIONS][S_RESTART].as()) { dst.actions.restart = true; } - if (src[FPSTR(S_ACTIONS)][FPSTR(S_RESET_FAULT)].is() && src[FPSTR(S_ACTIONS)][FPSTR(S_RESET_FAULT)].as()) { + if (src[S_ACTIONS][S_RESET_FAULT].is() && src[S_ACTIONS][S_RESET_FAULT].as()) { dst.actions.resetFault = true; } - if (src[FPSTR(S_ACTIONS)][FPSTR(S_RESET_DIAGNOSTIC)].is() && src[FPSTR(S_ACTIONS)][FPSTR(S_RESET_DIAGNOSTIC)].as()) { + if (src[S_ACTIONS][S_RESET_DIAGNOSTIC].is() && src[S_ACTIONS][S_RESET_DIAGNOSTIC].as()) { dst.actions.resetDiagnostic = true; }