diff --git a/esphome/components/debug/debug_component.h b/esphome/components/debug/debug_component.h index 5783bc5418..6cf52d890c 100644 --- a/esphome/components/debug/debug_component.h +++ b/esphome/components/debug/debug_component.h @@ -74,8 +74,11 @@ class DebugComponent : public PollingComponent { #ifdef USE_SENSOR void set_free_sensor(sensor::Sensor *free_sensor) { free_sensor_ = free_sensor; } void set_block_sensor(sensor::Sensor *block_sensor) { block_sensor_ = block_sensor; } -#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2) +#if (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)) || defined(USE_ESP32) void set_fragmentation_sensor(sensor::Sensor *fragmentation_sensor) { fragmentation_sensor_ = fragmentation_sensor; } +#endif +#if defined(USE_ESP32) || defined(USE_LIBRETINY) + void set_min_free_sensor(sensor::Sensor *min_free_sensor) { min_free_sensor_ = min_free_sensor; } #endif void set_loop_time_sensor(sensor::Sensor *loop_time_sensor) { loop_time_sensor_ = loop_time_sensor; } #ifdef USE_ESP32 @@ -97,8 +100,11 @@ class DebugComponent : public PollingComponent { sensor::Sensor *free_sensor_{nullptr}; sensor::Sensor *block_sensor_{nullptr}; -#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2) +#if (defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)) || defined(USE_ESP32) sensor::Sensor *fragmentation_sensor_{nullptr}; +#endif +#if defined(USE_ESP32) || defined(USE_LIBRETINY) + sensor::Sensor *min_free_sensor_{nullptr}; #endif sensor::Sensor *loop_time_sensor_{nullptr}; #ifdef USE_ESP32 diff --git a/esphome/components/debug/debug_esp32.cpp b/esphome/components/debug/debug_esp32.cpp index ebb6abf4da..8c41011f7d 100644 --- a/esphome/components/debug/debug_esp32.cpp +++ b/esphome/components/debug/debug_esp32.cpp @@ -234,8 +234,19 @@ size_t DebugComponent::get_device_info_(std::span void DebugComponent::update_platform_() { #ifdef USE_SENSOR + uint32_t max_alloc = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL); if (this->block_sensor_ != nullptr) { - this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL)); + this->block_sensor_->publish_state(max_alloc); + } + if (this->min_free_sensor_ != nullptr) { + this->min_free_sensor_->publish_state(heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL)); + } + if (this->fragmentation_sensor_ != nullptr) { + uint32_t free_heap = heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + if (free_heap > 0) { + float fragmentation = 100.0f - (100.0f * max_alloc / free_heap); + this->fragmentation_sensor_->publish_state(fragmentation); + } } if (this->psram_sensor_ != nullptr) { this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM)); diff --git a/esphome/components/debug/debug_libretiny.cpp b/esphome/components/debug/debug_libretiny.cpp index 4f07a4cc17..aae27c8ca2 100644 --- a/esphome/components/debug/debug_libretiny.cpp +++ b/esphome/components/debug/debug_libretiny.cpp @@ -51,6 +51,9 @@ void DebugComponent::update_platform_() { if (this->block_sensor_ != nullptr) { this->block_sensor_->publish_state(lt_heap_get_max_alloc()); } + if (this->min_free_sensor_ != nullptr) { + this->min_free_sensor_->publish_state(lt_heap_get_min_free()); + } #endif } diff --git a/esphome/components/debug/sensor.py b/esphome/components/debug/sensor.py index 6a8e2cd828..0a716d666e 100644 --- a/esphome/components/debug/sensor.py +++ b/esphome/components/debug/sensor.py @@ -11,6 +11,9 @@ from esphome.const import ( ENTITY_CATEGORY_DIAGNOSTIC, ICON_COUNTER, ICON_TIMER, + PLATFORM_BK72XX, + PLATFORM_LN882X, + PLATFORM_RTL87XX, UNIT_BYTES, UNIT_HERTZ, UNIT_MILLISECOND, @@ -25,6 +28,7 @@ from . import ( # noqa: F401 pylint: disable=unused-import DEPENDENCIES = ["debug"] +CONF_MIN_FREE = "min_free" CONF_PSRAM = "psram" CONFIG_SCHEMA = { @@ -42,8 +46,14 @@ CONFIG_SCHEMA = { entity_category=ENTITY_CATEGORY_DIAGNOSTIC, ), cv.Optional(CONF_FRAGMENTATION): cv.All( - cv.only_on_esp8266, - cv.require_framework_version(esp8266_arduino=cv.Version(2, 5, 2)), + cv.Any( + cv.All( + cv.only_on_esp8266, + cv.require_framework_version(esp8266_arduino=cv.Version(2, 5, 2)), + ), + cv.only_on_esp32, + msg="This feature is only available on ESP8266 (Arduino 2.5.2+) and ESP32", + ), sensor.sensor_schema( unit_of_measurement=UNIT_PERCENT, icon=ICON_COUNTER, @@ -51,6 +61,19 @@ CONFIG_SCHEMA = { entity_category=ENTITY_CATEGORY_DIAGNOSTIC, ), ), + cv.Optional(CONF_MIN_FREE): cv.All( + cv.Any( + cv.only_on_esp32, + cv.only_on([PLATFORM_BK72XX, PLATFORM_LN882X, PLATFORM_RTL87XX]), + msg="This feature is only available on ESP32 and LibreTiny (BK72xx, LN882x, RTL87xx)", + ), + sensor.sensor_schema( + unit_of_measurement=UNIT_BYTES, + icon=ICON_COUNTER, + accuracy_decimals=0, + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, + ), + ), cv.Optional(CONF_LOOP_TIME): sensor.sensor_schema( unit_of_measurement=UNIT_MILLISECOND, icon=ICON_TIMER, @@ -93,6 +116,10 @@ async def to_code(config): sens = await sensor.new_sensor(fragmentation_conf) cg.add(debug_component.set_fragmentation_sensor(sens)) + if min_free_conf := config.get(CONF_MIN_FREE): + sens = await sensor.new_sensor(min_free_conf) + cg.add(debug_component.set_min_free_sensor(sens)) + if loop_time_conf := config.get(CONF_LOOP_TIME): sens = await sensor.new_sensor(loop_time_conf) cg.add(debug_component.set_loop_time_sensor(sens)) diff --git a/tests/components/debug/common.yaml b/tests/components/debug/common.yaml index d9a61f8df0..59ba39c3a4 100644 --- a/tests/components/debug/common.yaml +++ b/tests/components/debug/common.yaml @@ -11,6 +11,8 @@ sensor: - platform: debug free: name: "Heap Free" + block: + name: "Heap Block" loop_time: name: "Loop Time" cpu_frequency: diff --git a/tests/components/debug/test.bk72xx-ard.yaml b/tests/components/debug/test.bk72xx-ard.yaml index dade44d145..fdae374788 100644 --- a/tests/components/debug/test.bk72xx-ard.yaml +++ b/tests/components/debug/test.bk72xx-ard.yaml @@ -1 +1,6 @@ <<: !include common.yaml + +sensor: + - platform: debug + min_free: + name: "Heap Min Free" diff --git a/tests/components/debug/test.esp32-ard.yaml b/tests/components/debug/test.esp32-ard.yaml index 8e19a4d627..8f93b0925e 100644 --- a/tests/components/debug/test.esp32-ard.yaml +++ b/tests/components/debug/test.esp32-ard.yaml @@ -2,3 +2,10 @@ esp32: cpu_frequency: 240MHz + +sensor: + - platform: debug + fragmentation: + name: "Heap Fragmentation" + min_free: + name: "Heap Min Free" diff --git a/tests/components/debug/test.esp32-idf.yaml b/tests/components/debug/test.esp32-idf.yaml index f7483a54b3..6a9996ad06 100644 --- a/tests/components/debug/test.esp32-idf.yaml +++ b/tests/components/debug/test.esp32-idf.yaml @@ -9,5 +9,9 @@ sensor: name: "Heap Free" psram: name: "Free PSRAM" + fragmentation: + name: "Heap Fragmentation" + min_free: + name: "Heap Min Free" psram: diff --git a/tests/components/debug/test.esp32-s2-idf.yaml b/tests/components/debug/test.esp32-s2-idf.yaml index dade44d145..80919b0bab 100644 --- a/tests/components/debug/test.esp32-s2-idf.yaml +++ b/tests/components/debug/test.esp32-s2-idf.yaml @@ -1 +1,8 @@ <<: !include common.yaml + +sensor: + - platform: debug + fragmentation: + name: "Heap Fragmentation" + min_free: + name: "Heap Min Free" diff --git a/tests/components/debug/test.esp8266-ard.yaml b/tests/components/debug/test.esp8266-ard.yaml index dade44d145..1398087bf0 100644 --- a/tests/components/debug/test.esp8266-ard.yaml +++ b/tests/components/debug/test.esp8266-ard.yaml @@ -1 +1,6 @@ <<: !include common.yaml + +sensor: + - platform: debug + fragmentation: + name: "Heap Fragmentation" diff --git a/tests/components/debug/test.ln882x-ard.yaml b/tests/components/debug/test.ln882x-ard.yaml index dade44d145..fdae374788 100644 --- a/tests/components/debug/test.ln882x-ard.yaml +++ b/tests/components/debug/test.ln882x-ard.yaml @@ -1 +1,6 @@ <<: !include common.yaml + +sensor: + - platform: debug + min_free: + name: "Heap Min Free" diff --git a/tests/components/debug/test.rtl87xx-ard.yaml b/tests/components/debug/test.rtl87xx-ard.yaml new file mode 100644 index 0000000000..fdae374788 --- /dev/null +++ b/tests/components/debug/test.rtl87xx-ard.yaml @@ -0,0 +1,6 @@ +<<: !include common.yaml + +sensor: + - platform: debug + min_free: + name: "Heap Min Free"