From ed801f7a279f9d4f9a166d3fb5c311de8a5cea21 Mon Sep 17 00:00:00 2001 From: Mat931 <49403702+Mat931@users.noreply.github.com> Date: Mon, 20 Feb 2023 02:47:37 +0000 Subject: [PATCH] Add internal_temperature component (#4330) * Add cpu_temperature component * Add tests * Fix formatting * Possible fix for "sensor not shown in HomeAssistant" * Rename component to internal_temperature * Update esphome/components/internal_temperature/internal_temperature.cpp Co-authored-by: Oxan van Leeuwen * Update esphome/components/internal_temperature/internal_temperature.cpp Co-authored-by: Oxan van Leeuwen * Update esphome/components/internal_temperature/internal_temperature.cpp Co-authored-by: Oxan van Leeuwen * Update internal_temperature.h * Remove unique_id * Update ESP32 variant detection --------- Co-authored-by: Oxan van Leeuwen --- CODEOWNERS | 1 + .../internal_temperature/__init__.py | 1 + .../internal_temperature.cpp | 58 +++++++++++++++++++ .../internal_temperature.h | 17 ++++++ .../components/internal_temperature/sensor.py | 31 ++++++++++ tests/test1.yaml | 2 + tests/test5.yaml | 2 + tests/test6.yaml | 4 ++ 8 files changed, 116 insertions(+) create mode 100644 esphome/components/internal_temperature/__init__.py create mode 100644 esphome/components/internal_temperature/internal_temperature.cpp create mode 100644 esphome/components/internal_temperature/internal_temperature.h create mode 100644 esphome/components/internal_temperature/sensor.py diff --git a/CODEOWNERS b/CODEOWNERS index ca1da2f15..9cfa81b36 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -113,6 +113,7 @@ esphome/components/ina260/* @MrEditor97 esphome/components/inkbird_ibsth1_mini/* @fkirill esphome/components/inkplate6/* @jesserockz esphome/components/integration/* @OttoWinter +esphome/components/internal_temperature/* @Mat931 esphome/components/interval/* @esphome/core esphome/components/json/* @OttoWinter esphome/components/kalman_combinator/* @Cat-Ion diff --git a/esphome/components/internal_temperature/__init__.py b/esphome/components/internal_temperature/__init__.py new file mode 100644 index 000000000..9433ade13 --- /dev/null +++ b/esphome/components/internal_temperature/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@Mat931"] diff --git a/esphome/components/internal_temperature/internal_temperature.cpp b/esphome/components/internal_temperature/internal_temperature.cpp new file mode 100644 index 000000000..9a22a77f6 --- /dev/null +++ b/esphome/components/internal_temperature/internal_temperature.cpp @@ -0,0 +1,58 @@ +#include "internal_temperature.h" +#include "esphome/core/log.h" + +#ifdef USE_ESP32 +#if defined(USE_ESP32_VARIANT_ESP32) +// there is no official API available on the original ESP32 +extern "C" { +uint8_t temprature_sens_read(); +} +#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#include "driver/temp_sensor.h" +#endif // USE_ESP32_VARIANT +#endif // USE_ESP32 +#ifdef USE_RP2040 +#include "Arduino.h" +#endif // USE_RP2040 + +namespace esphome { +namespace internal_temperature { + +static const char *const TAG = "internal_temperature"; + +void InternalTemperatureSensor::update() { + float temperature = NAN; + bool success = false; +#ifdef USE_ESP32 +#if defined(USE_ESP32_VARIANT_ESP32) + uint8_t raw = temprature_sens_read(); + ESP_LOGV(TAG, "Raw temperature value: %d", raw); + temperature = (raw - 32) / 1.8f; + success = (raw != 128); +#elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) + temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT(); + temp_sensor_set_config(tsens); + temp_sensor_start(); + esp_err_t result = temp_sensor_read_celsius(&temperature); + temp_sensor_stop(); + success = (result == ESP_OK); +#endif // USE_ESP32_VARIANT +#endif // USE_ESP32 +#ifdef USE_RP2040 + temperature = analogReadTemp(); + success = (temperature != 0.0f); +#endif // USE_RP2040 + if (success && std::isfinite(temperature)) { + this->publish_state(temperature); + } else { + ESP_LOGD(TAG, "Ignoring invalid temperature (success=%d, value=%.1f)", success, temperature); + if (!this->has_state()) { + this->publish_state(NAN); + } + } +} + +void InternalTemperatureSensor::dump_config() { LOG_SENSOR("", "Internal Temperature Sensor", this); } + +} // namespace internal_temperature +} // namespace esphome diff --git a/esphome/components/internal_temperature/internal_temperature.h b/esphome/components/internal_temperature/internal_temperature.h new file mode 100644 index 000000000..0e46a6976 --- /dev/null +++ b/esphome/components/internal_temperature/internal_temperature.h @@ -0,0 +1,17 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" + +namespace esphome { +namespace internal_temperature { + +class InternalTemperatureSensor : public sensor::Sensor, public PollingComponent { + public: + void dump_config() override; + + void update() override; +}; + +} // namespace internal_temperature +} // namespace esphome diff --git a/esphome/components/internal_temperature/sensor.py b/esphome/components/internal_temperature/sensor.py new file mode 100644 index 000000000..2655711bb --- /dev/null +++ b/esphome/components/internal_temperature/sensor.py @@ -0,0 +1,31 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome.const import ( + STATE_CLASS_MEASUREMENT, + UNIT_CELSIUS, + DEVICE_CLASS_TEMPERATURE, + ENTITY_CATEGORY_DIAGNOSTIC, +) + +internal_temperature_ns = cg.esphome_ns.namespace("internal_temperature") +InternalTemperatureSensor = internal_temperature_ns.class_( + "InternalTemperatureSensor", sensor.Sensor, cg.PollingComponent +) + +CONFIG_SCHEMA = cv.All( + sensor.sensor_schema( + InternalTemperatureSensor, + 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")), + cv.only_on(["esp32", "rp2040"]), +) + + +async def to_code(config): + var = await sensor.new_sensor(config) + await cg.register_component(var, config) diff --git a/tests/test1.yaml b/tests/test1.yaml index a77f8802b..bdc6da340 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -324,6 +324,8 @@ mcp23s17: deviceaddress: 1 sensor: + - platform: internal_temperature + name: "Internal Temperature" - platform: ble_client type: characteristic ble_client_id: ble_foo diff --git a/tests/test5.yaml b/tests/test5.yaml index 5f72579d0..21419692e 100644 --- a/tests/test5.yaml +++ b/tests/test5.yaml @@ -373,6 +373,8 @@ select: "Three": 3 sensor: + - platform: internal_temperature + name: "Internal Temperature" - platform: selec_meter total_active_energy: name: SelecEM2M Total Active Energy diff --git a/tests/test6.yaml b/tests/test6.yaml index 264773331..2930400e3 100644 --- a/tests/test6.yaml +++ b/tests/test6.yaml @@ -37,3 +37,7 @@ switch: - platform: output output: pin_4 id: pin_4_switch + +sensor: + - platform: internal_temperature + name: "Internal Temperature"