From 29db7b3f51b80cb794a9844d092664e9b7cd6268 Mon Sep 17 00:00:00 2001 From: Ivan Kruglov <4630547+ikruglov@users.noreply.github.com> Date: Mon, 12 Oct 2026 07:33:44 +0200 Subject: [PATCH] [bl0939] Add optional internal temperature sensor (#19415) Co-authored-by: J. Nick Koston --- esphome/components/bl0939/bl0939.cpp | 8 ++++++++ esphome/components/bl0939/bl0939.h | 2 ++ esphome/components/bl0939/sensor.py | 12 ++++++++++++ tests/components/bl0939/common.yaml | 2 ++ 4 files changed, 24 insertions(+) diff --git a/esphome/components/bl0939/bl0939.cpp b/esphome/components/bl0939/bl0939.cpp index 0e2da59ab1a..3a34fad1400 100644 --- a/esphome/components/bl0939/bl0939.cpp +++ b/esphome/components/bl0939/bl0939.cpp @@ -116,6 +116,13 @@ void BL0939::received_package_(const DataPacket *data) const { energy_sensor_sum_->publish_state(total_energy_consumption); } + if (this->internal_temperature_sensor_ != nullptr) { + const uint16_t raw_temperature = ((uint16_t(data->tps1.h) << 8) | data->tps1.l) & 0x3FF; + // Datasheet temperature conversion: Tx = (170 / 448) * (TB / 2 - 32) - 45. + const float temperature = (170.0f / 448.0f) * (raw_temperature / 2.0f - 32.0f) - 45.0f; + this->internal_temperature_sensor_->publish_state(temperature); + } + ESP_LOGV(TAG, "BL0939: U %fV, I1 %fA, I2 %fA, P1 %fW, P2 %fW, CntA %" PRId32 ", CntB %" PRId32 ", ∫P1 %fkWh, ∫P2 %fkWh", v_rms, ia_rms, ib_rms, a_watt, b_watt, cfa_cnt, cfb_cnt, a_energy_consumption, b_energy_consumption); @@ -131,6 +138,7 @@ void BL0939::dump_config() { // NOLINT(readability-function-cognitive-complexit LOG_SENSOR("", "Energy 1", this->energy_sensor_1_); LOG_SENSOR("", "Energy 2", this->energy_sensor_2_); LOG_SENSOR("", "Energy sum", this->energy_sensor_sum_); + LOG_SENSOR("", "Internal Temperature", this->internal_temperature_sensor_); } uint32_t BL0939::to_uint32_t(ube24_t input) { return input.h << 16 | input.m << 8 | input.l; } diff --git a/esphome/components/bl0939/bl0939.h b/esphome/components/bl0939/bl0939.h index 333bca37152..a22d96ad406 100644 --- a/esphome/components/bl0939/bl0939.h +++ b/esphome/components/bl0939/bl0939.h @@ -66,6 +66,7 @@ class BL0939 final : public PollingComponent, public uart::UARTDevice { void set_energy_sensor_1(sensor::Sensor *energy_sensor_1) { energy_sensor_1_ = energy_sensor_1; } void set_energy_sensor_2(sensor::Sensor *energy_sensor_2) { energy_sensor_2_ = energy_sensor_2; } void set_energy_sensor_sum(sensor::Sensor *energy_sensor_sum) { energy_sensor_sum_ = energy_sensor_sum; } + void set_internal_temperature_sensor(sensor::Sensor *sensor) { this->internal_temperature_sensor_ = sensor; } void loop() override; @@ -84,6 +85,7 @@ class BL0939 final : public PollingComponent, public uart::UARTDevice { sensor::Sensor *energy_sensor_1_{nullptr}; sensor::Sensor *energy_sensor_2_{nullptr}; sensor::Sensor *energy_sensor_sum_{nullptr}; + sensor::Sensor *internal_temperature_sensor_{nullptr}; // Divide by this to turn into Watt float power_reference_ = BL0939_PREF; diff --git a/esphome/components/bl0939/sensor.py b/esphome/components/bl0939/sensor.py index 9f6bd7814e4..401fafedd5e 100644 --- a/esphome/components/bl0939/sensor.py +++ b/esphome/components/bl0939/sensor.py @@ -3,14 +3,18 @@ from esphome.components import sensor, uart import esphome.config_validation as cv from esphome.const import ( CONF_ID, + CONF_INTERNAL_TEMPERATURE, CONF_VOLTAGE, DEVICE_CLASS_CURRENT, DEVICE_CLASS_ENERGY, DEVICE_CLASS_POWER, + DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, + ENTITY_CATEGORY_DIAGNOSTIC, STATE_CLASS_MEASUREMENT, STATE_CLASS_TOTAL_INCREASING, UNIT_AMPERE, + UNIT_CELSIUS, UNIT_KILOWATT_HOURS, UNIT_VOLT, UNIT_WATT, @@ -82,6 +86,13 @@ CONFIG_SCHEMA = ( device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_TOTAL_INCREASING, ), + cv.Optional(CONF_INTERNAL_TEMPERATURE): sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), } ) .extend(cv.polling_component_schema("60s")) @@ -103,3 +114,4 @@ async def to_code(config: ConfigType) -> None: await sensors(CONF_ENERGY_1, var.set_energy_sensor_1) await sensors(CONF_ENERGY_2, var.set_energy_sensor_2) await sensors(CONF_ENERGY_TOTAL, var.set_energy_sensor_sum) + await sensors(CONF_INTERNAL_TEMPERATURE, var.set_internal_temperature_sensor) diff --git a/tests/components/bl0939/common.yaml b/tests/components/bl0939/common.yaml index a47aa056068..0785fae029a 100644 --- a/tests/components/bl0939/common.yaml +++ b/tests/components/bl0939/common.yaml @@ -16,3 +16,5 @@ sensor: name: BL0939 Energy 2 energy_total: name: BL0939 Total energy + internal_temperature: + name: BL0939 Internal Temperature