From 6ff866cf5b79b58bdef84def05b777ed3086e87e Mon Sep 17 00:00:00 2001 From: Long Vo Date: Fri, 8 Nov 2024 15:57:38 +0700 Subject: [PATCH 1/9] Fix nan issue for engineering mode --- esphome/components/ld2410/ld2410.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/ld2410/ld2410.cpp b/esphome/components/ld2410/ld2410.cpp index c3b57815d6be..9a7fc9ade71c 100644 --- a/esphome/components/ld2410/ld2410.cpp +++ b/esphome/components/ld2410/ld2410.cpp @@ -255,16 +255,16 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { } else { for (auto *s : this->gate_move_sensors_) { if (s != nullptr && !std::isnan(s->get_state())) { - s->publish_state(NAN); + s->publish_state(0); } } for (auto *s : this->gate_still_sensors_) { if (s != nullptr && !std::isnan(s->get_state())) { - s->publish_state(NAN); + s->publish_state(0); } } if (this->light_sensor_ != nullptr && !std::isnan(this->light_sensor_->get_state())) { - this->light_sensor_->publish_state(NAN); + this->light_sensor_->publish_state(0); } } #endif From 0ce94826e5484edfb3826a01dbfdf640aeadf313 Mon Sep 17 00:00:00 2001 From: Long Vo Date: Thu, 14 Nov 2024 16:17:30 +0700 Subject: [PATCH 2/9] MQTT handling of nan values to align with Hass --- esphome/components/ld2410/ld2410.cpp | 6 +++--- esphome/components/mqtt/mqtt_sensor.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/esphome/components/ld2410/ld2410.cpp b/esphome/components/ld2410/ld2410.cpp index 9a7fc9ade71c..c3b57815d6be 100644 --- a/esphome/components/ld2410/ld2410.cpp +++ b/esphome/components/ld2410/ld2410.cpp @@ -255,16 +255,16 @@ void LD2410Component::handle_periodic_data_(uint8_t *buffer, int len) { } else { for (auto *s : this->gate_move_sensors_) { if (s != nullptr && !std::isnan(s->get_state())) { - s->publish_state(0); + s->publish_state(NAN); } } for (auto *s : this->gate_still_sensors_) { if (s != nullptr && !std::isnan(s->get_state())) { - s->publish_state(0); + s->publish_state(NAN); } } if (this->light_sensor_ != nullptr && !std::isnan(this->light_sensor_->get_state())) { - this->light_sensor_->publish_state(0); + this->light_sensor_->publish_state(NAN); } } #endif diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index fff75a3c008f..2586e1ebc329 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -69,7 +69,9 @@ bool MQTTSensorComponent::send_initial_state() { } } bool MQTTSensorComponent::publish_state(float value) { - int8_t accuracy = this->sensor_->get_accuracy_decimals(); + int8_t accuracy = this->sensor_->get_accuracy_decimals(); + if(std::isnan(value)) + return this->publish(this->get_state_topic_(), "None"); return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy)); } std::string MQTTSensorComponent::unique_id() { return this->sensor_->unique_id(); } From 9f027103ed3475ac47720ad24d25e839edcce39a Mon Sep 17 00:00:00 2001 From: Long Vo Date: Thu, 14 Nov 2024 16:44:23 +0700 Subject: [PATCH 3/9] removed whitespace --- esphome/components/mqtt/mqtt_sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index 2586e1ebc329..2f040bff9e0a 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -69,7 +69,7 @@ bool MQTTSensorComponent::send_initial_state() { } } bool MQTTSensorComponent::publish_state(float value) { - int8_t accuracy = this->sensor_->get_accuracy_decimals(); + int8_t accuracy = this->sensor_->get_accuracy_decimals(); if(std::isnan(value)) return this->publish(this->get_state_topic_(), "None"); return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy)); From 9af492c219c701adffad9c8bc6ff8409bb20d652 Mon Sep 17 00:00:00 2001 From: Long Vo Date: Thu, 14 Nov 2024 16:48:46 +0700 Subject: [PATCH 4/9] updated formatting --- esphome/components/mqtt/mqtt_sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index 2f040bff9e0a..add02e7b9c87 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -70,7 +70,7 @@ bool MQTTSensorComponent::send_initial_state() { } bool MQTTSensorComponent::publish_state(float value) { int8_t accuracy = this->sensor_->get_accuracy_decimals(); - if(std::isnan(value)) + if (std::isnan(value)) return this->publish(this->get_state_topic_(), "None"); return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy)); } From cf8d9311760fec086cccef104a171fb186b19cc7 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:13:30 +1300 Subject: [PATCH 5/9] Update esphome/components/mqtt/mqtt_sensor.cpp --- esphome/components/mqtt/mqtt_sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index add02e7b9c87..50c41beaa122 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -69,9 +69,9 @@ bool MQTTSensorComponent::send_initial_state() { } } bool MQTTSensorComponent::publish_state(float value) { - int8_t accuracy = this->sensor_->get_accuracy_decimals(); if (std::isnan(value)) return this->publish(this->get_state_topic_(), "None"); + int8_t accuracy = this->sensor_->get_accuracy_decimals(); return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy)); } std::string MQTTSensorComponent::unique_id() { return this->sensor_->unique_id(); } From a0bd95a790af1169eea0399782bb6b590a7d7302 Mon Sep 17 00:00:00 2001 From: Long Vo Date: Tue, 19 Nov 2024 14:17:58 +0700 Subject: [PATCH 6/9] Added mqtt config to publish nan as none --- esphome/components/mqtt/__init__.py | 4 ++++ esphome/components/mqtt/mqtt_client.cpp | 2 ++ esphome/components/mqtt/mqtt_client.h | 6 ++++++ esphome/components/mqtt/mqtt_sensor.cpp | 2 +- esphome/const.py | 1 + 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py index 86d163e61dce..12024820c401 100644 --- a/esphome/components/mqtt/__init__.py +++ b/esphome/components/mqtt/__init__.py @@ -49,6 +49,7 @@ CONF_USE_ABBREVIATIONS, CONF_USERNAME, CONF_WILL_MESSAGE, + CONF_PUBLISH_NAN_AS_NONE, PLATFORM_BK72XX, PLATFORM_ESP32, PLATFORM_ESP8266, @@ -296,6 +297,7 @@ def validate_fingerprint(value): cv.Optional(CONF_QOS, default=0): cv.mqtt_qos, } ), + cv.Optional(CONF_PUBLISH_NAN_AS_NONE): cv.boolean, } ), validate_config, @@ -449,6 +451,8 @@ async def to_code(config): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) await automation.build_automation(trigger, [], conf) + if CONF_PUBLISH_NAN_AS_NONE in config: + cg.add(var.set_publish_nan_as_none(config[CONF_PUBLISH_NAN_AS_NONE])) MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema( { diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 106192c0e39b..9139dfdc0077 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -608,6 +608,8 @@ void MQTTClientComponent::set_log_message_template(MQTTMessage &&message) { this const MQTTDiscoveryInfo &MQTTClientComponent::get_discovery_info() const { return this->discovery_info_; } void MQTTClientComponent::set_topic_prefix(const std::string &topic_prefix) { this->topic_prefix_ = topic_prefix; } const std::string &MQTTClientComponent::get_topic_prefix() const { return this->topic_prefix_; } +void MQTTClientComponent::set_publish_nan_as_none(bool publish_nan_as_none) { this->publish_nan_as_none_ = publish_nan_as_none; } +bool MQTTClientComponent::is_publish_nan_as_none() const { return this->publish_nan_as_none_; } void MQTTClientComponent::disable_birth_message() { this->birth_message_.topic = ""; this->recalculate_availability_(); diff --git a/esphome/components/mqtt/mqtt_client.h b/esphome/components/mqtt/mqtt_client.h index 7ae3a6c5e836..80a4ef51a3b4 100644 --- a/esphome/components/mqtt/mqtt_client.h +++ b/esphome/components/mqtt/mqtt_client.h @@ -263,6 +263,10 @@ class MQTTClientComponent : public Component { void set_on_connect(mqtt_on_connect_callback_t &&callback); void set_on_disconnect(mqtt_on_disconnect_callback_t &&callback); + // Publish None state instead of NaN for Home Assistant + void set_publish_nan_as_none(bool publish_nan_as_none_); + bool is_publish_nan_as_none() const; + protected: void send_device_info_(); @@ -328,6 +332,8 @@ class MQTTClientComponent : public Component { uint32_t connect_begin_; uint32_t last_connected_{0}; optional disconnect_reason_{}; + + bool publish_nan_as_none_{false}; }; extern MQTTClientComponent *global_mqtt_client; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index 50c41beaa122..2cbc291ccf5c 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -69,7 +69,7 @@ bool MQTTSensorComponent::send_initial_state() { } } bool MQTTSensorComponent::publish_state(float value) { - if (std::isnan(value)) + if (mqtt::global_mqtt_client->is_publish_nan_as_none() && std::isnan(value)) return this->publish(this->get_state_topic_(), "None"); int8_t accuracy = this->sensor_->get_accuracy_decimals(); return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy)); diff --git a/esphome/const.py b/esphome/const.py index 6a643e1e3012..1546346898d7 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -955,6 +955,7 @@ CONF_Y_GRID = "y_grid" CONF_YEAR = "year" CONF_ZERO = "zero" +CONF_PUBLISH_NAN_AS_NONE = "publish_nan_as_none" TYPE_GIT = "git" TYPE_LOCAL = "local" From 819bb7b8ed50facef31cdf89d63d0695a82e9711 Mon Sep 17 00:00:00 2001 From: Long Vo Date: Tue, 19 Nov 2024 14:56:43 +0700 Subject: [PATCH 7/9] Fix lint + test --- esphome/components/mqtt/__init__.py | 1 + esphome/components/mqtt/mqtt_client.cpp | 4 +++- esphome/const.py | 2 +- tests/components/mqtt/common.yaml | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py index 12024820c401..e16144dc60e5 100644 --- a/esphome/components/mqtt/__init__.py +++ b/esphome/components/mqtt/__init__.py @@ -454,6 +454,7 @@ async def to_code(config): if CONF_PUBLISH_NAN_AS_NONE in config: cg.add(var.set_publish_nan_as_none(config[CONF_PUBLISH_NAN_AS_NONE])) + MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema( { cv.GenerateID(): cv.use_id(MQTTClientComponent), diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 9139dfdc0077..c7ace505a80f 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -608,7 +608,9 @@ void MQTTClientComponent::set_log_message_template(MQTTMessage &&message) { this const MQTTDiscoveryInfo &MQTTClientComponent::get_discovery_info() const { return this->discovery_info_; } void MQTTClientComponent::set_topic_prefix(const std::string &topic_prefix) { this->topic_prefix_ = topic_prefix; } const std::string &MQTTClientComponent::get_topic_prefix() const { return this->topic_prefix_; } -void MQTTClientComponent::set_publish_nan_as_none(bool publish_nan_as_none) { this->publish_nan_as_none_ = publish_nan_as_none; } +void MQTTClientComponent::set_publish_nan_as_none(bool publish_nan_as_none) { + this->publish_nan_as_none_ = publish_nan_as_none; +} bool MQTTClientComponent::is_publish_nan_as_none() const { return this->publish_nan_as_none_; } void MQTTClientComponent::disable_birth_message() { this->birth_message_.topic = ""; diff --git a/esphome/const.py b/esphome/const.py index 1546346898d7..bb3a5b0d0d39 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -690,6 +690,7 @@ CONF_PROJECT = "project" CONF_PROTOCOL = "protocol" CONF_PUBLISH_INITIAL_STATE = "publish_initial_state" +CONF_PUBLISH_NAN_AS_NONE = "publish_nan_as_none" CONF_PULL_MODE = "pull_mode" CONF_PULLDOWN = "pulldown" CONF_PULLUP = "pullup" @@ -955,7 +956,6 @@ CONF_Y_GRID = "y_grid" CONF_YEAR = "year" CONF_ZERO = "zero" -CONF_PUBLISH_NAN_AS_NONE = "publish_nan_as_none" TYPE_GIT = "git" TYPE_LOCAL = "local" diff --git a/tests/components/mqtt/common.yaml b/tests/components/mqtt/common.yaml index d22fe9579f2b..a4bdf58809b6 100644 --- a/tests/components/mqtt/common.yaml +++ b/tests/components/mqtt/common.yaml @@ -60,6 +60,7 @@ mqtt: - mqtt.publish: topic: some/topic payload: Good-bye + publish_nan_as_none: false binary_sensor: - platform: template From db1ee1babce4814e31f7659a9daf4e57a467fc7a Mon Sep 17 00:00:00 2001 From: Long Vo Date: Tue, 19 Nov 2024 15:15:16 +0700 Subject: [PATCH 8/9] updated formating --- esphome/components/mqtt/mqtt_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/mqtt/mqtt_client.h b/esphome/components/mqtt/mqtt_client.h index 80a4ef51a3b4..34eac294641a 100644 --- a/esphome/components/mqtt/mqtt_client.h +++ b/esphome/components/mqtt/mqtt_client.h @@ -264,7 +264,7 @@ class MQTTClientComponent : public Component { void set_on_disconnect(mqtt_on_disconnect_callback_t &&callback); // Publish None state instead of NaN for Home Assistant - void set_publish_nan_as_none(bool publish_nan_as_none_); + void set_publish_nan_as_none(bool publish_nan_as_none); bool is_publish_nan_as_none() const; protected: From 60f505f195896ca27d45d8b114675331d42168f7 Mon Sep 17 00:00:00 2001 From: kbullet Date: Thu, 21 Nov 2024 09:38:05 +0700 Subject: [PATCH 9/9] Apply suggestions from code review Updated Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/mqtt/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py index e16144dc60e5..2b0d9412204d 100644 --- a/esphome/components/mqtt/__init__.py +++ b/esphome/components/mqtt/__init__.py @@ -297,7 +297,7 @@ def validate_fingerprint(value): cv.Optional(CONF_QOS, default=0): cv.mqtt_qos, } ), - cv.Optional(CONF_PUBLISH_NAN_AS_NONE): cv.boolean, + cv.Optional(CONF_PUBLISH_NAN_AS_NONE, default=False): cv.boolean, } ), validate_config, @@ -451,8 +451,7 @@ async def to_code(config): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) await automation.build_automation(trigger, [], conf) - if CONF_PUBLISH_NAN_AS_NONE in config: - cg.add(var.set_publish_nan_as_none(config[CONF_PUBLISH_NAN_AS_NONE])) + cg.add(var.set_publish_nan_as_none(config[CONF_PUBLISH_NAN_AS_NONE])) MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema(