diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 232b748fb..c537e0dc4 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -8,10 +8,11 @@ For more details go to [emsesp.org](https://emsesp.org/). - comfortpoint for BC400 [#2935](https://github.com/emsesp/EMS-ESP32/issues/2935) - customize device brand [#2784](https://github.com/emsesp/EMS-ESP32/issues/2784) +- set model for ems-esp devices temperature, analog, etc. [#2958](https://github.com/emsesp/EMS-ESP32/discussions/2958) ## Fixed -- SRC climate creation [#2936](https://github.com/emsesp/EMS-ESP32/issues/2936) +- SRC climate creation [#2936](https://github.com/emsesp/EMS-ESP32/issues/2936) and [#2960](https://github.com/emsesp/EMS-ESP32/issues/2960) ## Changed diff --git a/src/ESP32React/APSettingsService.cpp b/src/ESP32React/APSettingsService.cpp index 47d90a8b1..a68037738 100644 --- a/src/ESP32React/APSettingsService.cpp +++ b/src/ESP32React/APSettingsService.cpp @@ -10,7 +10,6 @@ APSettingsService::APSettingsService(AsyncWebServer * server, FS * fs, SecurityM , _reconfigureAp(false) , _connected(0) { addUpdateHandler([this] { reconfigureAP(); }, false); - WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); } void APSettingsService::begin() { @@ -19,39 +18,27 @@ void APSettingsService::begin() { // reconfigureAP(); } -// wait 10 sec on STA disconnect before starting AP -void APSettingsService::WiFiEvent(WiFiEvent_t event) { - const uint8_t was_connected = _connected; - switch (event) { - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - _connected &= ~1U; - break; - case ARDUINO_EVENT_ETH_DISCONNECTED: - _connected &= ~2U; - break; - case ARDUINO_EVENT_WIFI_STA_GOT_IP: - case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - _connected |= 1U; - break; - case ARDUINO_EVENT_ETH_GOT_IP: - case ARDUINO_EVENT_ETH_GOT_IP6: - _connected |= 2U; - break; - default: - return; - } - // wait 10 sec before starting AP - if (was_connected && !_connected) { - _lastManaged = uuid::get_uptime(); - } -} - void APSettingsService::reconfigureAP() { _lastManaged = uuid::get_uptime() - MANAGE_NETWORK_DELAY; _reconfigureAp = true; } void APSettingsService::loop() { + const uint8_t was_connected = _connected; + if (WiFi.isConnected()) { + _connected |= 1U; + } else { + _connected &= ~1U; + } + if (ETH.connected()) { + _connected |= 2U; + } else { + _connected &= ~2U; + } + // wait 10 sec before starting AP + if (was_connected && !_connected) { + _lastManaged = uuid::get_uptime(); + } const unsigned long currentMillis = uuid::get_uptime(); if ((currentMillis - _lastManaged) >= MANAGE_NETWORK_DELAY) { _lastManaged = currentMillis; diff --git a/src/ESP32React/APSettingsService.h b/src/ESP32React/APSettingsService.h index 9b52f84d0..21eb24075 100644 --- a/src/ESP32React/APSettingsService.h +++ b/src/ESP32React/APSettingsService.h @@ -104,7 +104,6 @@ class APSettingsService : public StatefulService { void startAP(); void stopAP(); void handleDNS(); - void WiFiEvent(WiFiEvent_t event); }; #endif diff --git a/src/ESP32React/ESP32React.cpp b/src/ESP32React/ESP32React.cpp index 41536153f..9b533dfba 100644 --- a/src/ESP32React/ESP32React.cpp +++ b/src/ESP32React/ESP32React.cpp @@ -84,4 +84,5 @@ void ESP32React::loop() { _networkSettingsService.loop(); _apSettingsService.loop(); _mqttSettingsService.loop(); + _ntpSettingsService.loop(); } \ No newline at end of file diff --git a/src/ESP32React/MqttSettingsService.cpp b/src/ESP32React/MqttSettingsService.cpp index 63879e6a8..7049c5713 100644 --- a/src/ESP32React/MqttSettingsService.cpp +++ b/src/ESP32React/MqttSettingsService.cpp @@ -9,7 +9,6 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur , _disconnectedAt(0) , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) , _mqttClient(nullptr) { - WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); addUpdateHandler([this] { onConfigUpdated(); }, false); } @@ -29,6 +28,7 @@ MqttSettingsService::~MqttSettingsService() { void MqttSettingsService::begin() { _fsPersistence.readFromFS(); startClient(); + _reconfigureMqtt = true; } void MqttSettingsService::startClient() { @@ -79,6 +79,10 @@ void MqttSettingsService::startClient() { } void MqttSettingsService::loop() { + if (_state.enabled && _mqttClient && _mqttClient->connected() && !emsesp::EMSESP::system_.network_connected()) { + // emsesp::EMSESP::logger().info("Network connection dropped, stopping MQTT client"); + _mqttClient->disconnect(true); + } if (_reconfigureMqtt || (_disconnectedAt && static_cast(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) { // reconfigure MQTT client _disconnectedAt = configureMqtt() ? 0 : uuid::get_uptime(); @@ -142,28 +146,6 @@ void MqttSettingsService::onConfigUpdated() { emsesp::EMSESP::mqtt_.start(); // reload EMS-ESP MQTT settings } -void MqttSettingsService::WiFiEvent(WiFiEvent_t event) { - switch (event) { - case ARDUINO_EVENT_WIFI_STA_GOT_IP: - case ARDUINO_EVENT_ETH_GOT_IP: - case ARDUINO_EVENT_ETH_GOT_IP6: - case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - if (_state.enabled && !_mqttClient->connected()) { - onConfigUpdated(); - } - break; - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - case ARDUINO_EVENT_ETH_DISCONNECTED: - if (_state.enabled) { - _mqttClient->disconnect(true); - } - break; - - default: - break; - } -} - bool MqttSettingsService::configureMqtt() { // disconnect if already connected if (_mqttClient->connected()) { @@ -256,7 +238,7 @@ void MqttSettings::read(MqttSettings & settings, JsonObject root) { StateUpdateResult MqttSettings::update(JsonObject root, MqttSettings & settings) { MqttSettings newSettings; - bool changed = false; + bool changed = false; #ifndef NO_TLS_SUPPORT newSettings.enableTLS = root["enableTLS"]; @@ -316,6 +298,10 @@ StateUpdateResult MqttSettings::update(JsonObject root, MqttSettings & settings) changed = true; } + if (newSettings.ha_number_mode != settings.ha_number_mode) { + changed = true; + } + if (newSettings.entity_format != settings.entity_format) { changed = true; } diff --git a/src/ESP32React/MqttSettingsService.h b/src/ESP32React/MqttSettingsService.h index 36b52fa74..c286c3544 100644 --- a/src/ESP32React/MqttSettingsService.h +++ b/src/ESP32React/MqttSettingsService.h @@ -134,7 +134,6 @@ class MqttSettingsService : public StatefulService { // the MQTT client instance MqttClient * _mqttClient; - void WiFiEvent(WiFiEvent_t event); void onMqttConnect(bool sessionPresent); void onMqttDisconnect(espMqttClientTypes::DisconnectReason reason); void diff --git a/src/ESP32React/NTPSettingsService.cpp b/src/ESP32React/NTPSettingsService.cpp index 81e5cdf82..b12d69bbf 100644 --- a/src/ESP32React/NTPSettingsService.cpp +++ b/src/ESP32React/NTPSettingsService.cpp @@ -11,7 +11,6 @@ NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, Securit configureTime(request, json); }); - WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); addUpdateHandler([this] { configureNTP(); }, false); } @@ -20,27 +19,10 @@ void NTPSettingsService::begin() { configureNTP(); } -// handles both WiFI and Ethernet -void NTPSettingsService::WiFiEvent(WiFiEvent_t event) { - switch (event) { - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - case ARDUINO_EVENT_ETH_DISCONNECTED: - if (_connected && emsesp::EMSESP::system_.ntp_connected()) { - emsesp::EMSESP::logger().info("WiFi connection dropped, stopping NTP"); - _connected = false; - configureNTP(); - } - break; - - case ARDUINO_EVENT_WIFI_STA_GOT_IP: - case ARDUINO_EVENT_ETH_GOT_IP: - // emsesp::EMSESP::logger().info("Got IP address, starting NTP synchronization"); - _connected = true; +void NTPSettingsService::loop() { + if (_connected != emsesp::EMSESP::system_.network_connected()) { + _connected = emsesp::EMSESP::system_.network_connected(); configureNTP(); - break; - - default: - break; } } @@ -55,7 +37,9 @@ void NTPSettingsService::configureNTP() { } else { setenv("TZ", _state.tzFormat.c_str(), 1); tzset(); - esp_sntp_stop(); + if (esp_sntp_enabled()) { + esp_sntp_stop(); + } } } diff --git a/src/ESP32React/NTPSettingsService.h b/src/ESP32React/NTPSettingsService.h index 635b68f1c..ca75c5dd9 100644 --- a/src/ESP32React/NTPSettingsService.h +++ b/src/ESP32React/NTPSettingsService.h @@ -44,6 +44,7 @@ class NTPSettingsService : public StatefulService { NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); void begin(); + void loop(); static void ntp_received(struct timeval * tv); private: @@ -51,7 +52,6 @@ class NTPSettingsService : public StatefulService { FSPersistence _fsPersistence; volatile bool _connected; - void WiFiEvent(WiFiEvent_t event); void configureNTP(); void configureTime(AsyncWebServerRequest * request, JsonVariant json); }; diff --git a/src/ESP32React/NetworkSettingsService.cpp b/src/ESP32React/NetworkSettingsService.cpp index 2e9bd6d04..b274c5208 100644 --- a/src/ESP32React/NetworkSettingsService.cpp +++ b/src/ESP32React/NetworkSettingsService.cpp @@ -9,7 +9,7 @@ NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, , _stopping(false) { addUpdateHandler([this] { reconfigureWiFiConnection(); }, false); // Eth is also bound to the WifiGeneric event handler - WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event, info); }); + // Network.onEvent([this](arduino_event_id_t event, arduino_event_info_t info) { WiFiEvent(event, info); }); } static bool formatBssid(const String & bssid, uint8_t (&mac)[6]) { @@ -62,14 +62,62 @@ void NetworkSettingsService::loop() { _lastConnectionAttempt = currentMillis; manageSTA(); } + static uint8_t connect = 0; + enum uint8_t { CONNECT_IDLE = 0, CONNECT_WAIT_ETH, CONNECT_ETH_ACTIVE, CONNECT_WIFI_ACTIVE }; + switch (connect) { + default: + connect = CONNECT_IDLE; + break; + case CONNECT_IDLE: + if (ETH.started() && _state.ssid.length() == 0) { + emsesp::EMSESP::logger().info("ETH started"); + connect = CONNECT_WAIT_ETH; + ETH.enableIPv6(true); + if (_state.staticIPConfig) { + ETH.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); + } + ETH.setHostname(emsesp::EMSESP::system_.hostname().c_str()); + } + if (WiFi.isConnected()) { + emsesp::EMSESP::logger().info("Wifi connected"); + connect = CONNECT_WIFI_ACTIVE; + if (_state.tx_power == 0) { + setWiFiPowerOnRSSI(); + } + mDNS_start(); + } + break; + case CONNECT_WAIT_ETH: + if (ETH.connected()) { + emsesp::EMSESP::logger().info("ETH connected"); + connect = CONNECT_ETH_ACTIVE; + emsesp::EMSESP::system_.ethernet_connected(true); + mDNS_start(); + } + break; + case CONNECT_ETH_ACTIVE: + if (!ETH.connected()) { + emsesp::EMSESP::logger().info("ETH disconnected"); + emsesp::EMSESP::system_.ethernet_connected(false); + connect = CONNECT_IDLE; + } + break; + case CONNECT_WIFI_ACTIVE: + if (!WiFi.isConnected()) { + emsesp::EMSESP::logger().info("WiFi disconnected"); + connect = CONNECT_IDLE; + if (_stopping) { + _lastConnectionAttempt = 0; + _stopping = false; + } + } + break; + } } void NetworkSettingsService::manageSTA() { // Abort if already connected, or if we have no SSID if (WiFi.isConnected() || _state.ssid.length() == 0) { - if (_state.ssid.length() == 0) { - ETH.enableIPv6(true); - } return; } @@ -289,7 +337,7 @@ const char * NetworkSettingsService::disconnectReason(uint8_t code) { } // handles both WiFI and Ethernet -void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { +void NetworkSettingsService::WiFiEvent(arduino_event_id_t event, arduino_event_info_t info) { #ifndef EMSESP_STANDALONE switch (event) { diff --git a/src/ESP32React/NetworkSettingsService.h b/src/ESP32React/NetworkSettingsService.h index 7c1ed0ff7..4635c5181 100644 --- a/src/ESP32React/NetworkSettingsService.h +++ b/src/ESP32React/NetworkSettingsService.h @@ -107,7 +107,7 @@ class NetworkSettingsService : public StatefulService { volatile uint16_t connectcount_ = 0; // number of wifi reconnects - void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); + void WiFiEvent(arduino_event_id_t event, arduino_event_info_t info); void mDNS_start() const; const char * disconnectReason(uint8_t code); void reconfigureWiFiConnection(); diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index dc558c413..12b594d41 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -2135,7 +2135,7 @@ void EMSdevice::mqtt_ha_entity_config_create() { if (needs_update) { const char * const ** mode_options = nullptr; - for (auto & d : devicevalues_) { + for (const auto & d : devicevalues_) { // make sure mode in same circuit is DeviceValueType::ENUM if ((d.tag == dv.tag) && (d.type == DeviceValueType::ENUM) && !strcmp(d.short_name, FL_(mode)[0]) && (d.options_size > 0)) { // get options @@ -2167,19 +2167,25 @@ void EMSdevice::mqtt_ha_entity_config_create() { } // SRC thermostats mapped to connect/src1/... always contains mode, seltemp, currtemp - if (dv.tag >= DeviceValueTAG::TAG_SRC1 && dv.tag <= DeviceValueTAG::TAG_SRC16 && !strcmp(dv.short_name, FL_(mode)[0])) { - // add icon if we have one - const char * icon = nullptr; - for (auto & d : devicevalues_) { - if (d.tag == dv.tag && !strcmp(d.short_name, FL_(icon)[0]) && (dv.type == DeviceValueType::ENUM)) { + if (dv.tag >= DeviceValueTAG::TAG_SRC1 && dv.tag <= DeviceValueTAG::TAG_SRC16 && !strcmp(dv.short_name, FL_(seltemp)[0])) { + // add modes and icon if we have one + const char * icon = nullptr; + const char * const ** mode_options = nullptr; + for (const auto & d : devicevalues_) { + if ((d.tag != dv.tag) || (d.type != DeviceValueType::ENUM)) { + continue; + } + if (!strcmp(d.short_name, FL_(mode)[0]) && (d.options_size > 0)) { + mode_options = d.options; + } + if (!strcmp(d.short_name, FL_(icon)[0])) { uint8_t val = *(uint8_t *)(d.value_p); if (val != 0 && val < d.options_size) { icon = d.options[val][0]; } - break; } } - Mqtt::publish_ha_climate_config(dv, true, dv.options, false, icon); + Mqtt::publish_ha_climate_config(dv, true, mode_options, false, icon); count++; } diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index d559efcac..225c7f56e 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -1545,9 +1545,7 @@ void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const bool crea // add mf (manufacturer/brand), mdl (model), sw (software version) and via_device dev_json["mf"] = brand != nullptr ? brand : "EMS-ESP"; - if (model != nullptr) { - dev_json["mdl"] = model; - } + dev_json["mdl"] = model != nullptr ? model : "EMS-ESP"; dev_json["sw"] = version != nullptr ? version : "v" + std::string(EMSESP_APP_VERSION); dev_json["via_device"] = Mqtt::basename(); } diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index 4a96c0700..2ae873c3c 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -129,15 +129,20 @@ void Connect::process_roomThermostat(std::shared_ptr telegram) { } has_update(telegram, rc->temp_, 0); has_update(telegram, rc->humidity_, 2); // could show -3 if not set - has_update(telegram, rc->seltemp_, 3); + // make sure we have read mode and icon, needed for ha climate + if (!Mqtt::ha_enabled() || (Helpers::hasValue(rc->mode_) && Helpers::hasValue(rc->icon_))) { + has_update(telegram, rc->seltemp_, 3); + } // calculate dew temperature - const float k2 = 17.62; - const float k3 = 243.12; - const float t = (float)rc->temp_ / 10; - const float h = (float)rc->humidity_ / 100; - int16_t dt = (10 * k3 * (((k2 * t) / (k3 + t)) + log(h)) / (((k2 * k3) / (k3 + t)) - log(h))); - has_update(rc->dewtemp_, dt); + if (rc->humidity_ >= 0 && rc->humidity_ <= 100) { + const float k2 = 17.62; + const float k3 = 243.12; + const float t = (float)rc->temp_ / 10; + const float h = (float)rc->humidity_ / 100; + int16_t dt = (10 * k3 * (((k2 * t) / (k3 + t)) + log(h)) / (((k2 * k3) / (k3 + t)) - log(h))); + has_update(rc->dewtemp_, dt); + } } // gateway(0x48) W gateway(0x50), ?(0x0B42), data: 01 // icon in offset 0 @@ -221,8 +226,9 @@ bool Connect::set_seltemp(const char * value, const int8_t id) { } float v; if (Helpers::value2float(value, v)) { - // write_command(0xBB5 + rc->room(), rc->mode_ == 2 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); - write_command(0xBB5 + rc->room(), rc->mode_ == 0 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); + // depends on mode, auto (2 for enum_mode2, 0 for enum_mode8) set in offset 1 + write_command(0xBB5 + rc->room(), rc->mode_ == 2 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); + // write_command(0xBB5 + rc->room(), rc->mode_ == 0 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); return true; } return false; diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 1d71f4366..3945693dd 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.8.2-dev.5" +#define EMSESP_APP_VERSION "3.8.2-dev.6"