mirror of
https://github.com/esphome/esphome.git
synced 2026-01-14 22:17:47 -07:00
Compare commits
1 Commits
libretiny_
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9da2c08f36 |
@@ -74,11 +74,8 @@ 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)) || defined(USE_ESP32)
|
||||
#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||
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
|
||||
@@ -100,11 +97,8 @@ 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)) || defined(USE_ESP32)
|
||||
#if defined(USE_ESP8266) && USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 5, 2)
|
||||
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
|
||||
|
||||
@@ -234,19 +234,8 @@ size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE>
|
||||
|
||||
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(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);
|
||||
}
|
||||
this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
|
||||
}
|
||||
if (this->psram_sensor_ != nullptr) {
|
||||
this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
|
||||
@@ -51,9 +51,6 @@ 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
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ from . import CONF_DEBUG_ID, DebugComponent
|
||||
|
||||
DEPENDENCIES = ["debug"]
|
||||
|
||||
CONF_MIN_FREE = "min_free"
|
||||
CONF_PSRAM = "psram"
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
@@ -39,13 +38,8 @@ CONFIG_SCHEMA = {
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
),
|
||||
cv.Optional(CONF_FRAGMENTATION): cv.All(
|
||||
cv.Any(
|
||||
cv.All(
|
||||
cv.only_on_esp8266,
|
||||
cv.require_framework_version(esp8266_arduino=cv.Version(2, 5, 2)),
|
||||
),
|
||||
cv.only_on_esp32,
|
||||
),
|
||||
cv.only_on_esp8266,
|
||||
cv.require_framework_version(esp8266_arduino=cv.Version(2, 5, 2)),
|
||||
sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
icon=ICON_COUNTER,
|
||||
@@ -53,15 +47,6 @@ CONFIG_SCHEMA = {
|
||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
cv.Optional(CONF_MIN_FREE): cv.All(
|
||||
cv.Any(cv.only_on_esp32, cv.only_on_libretiny),
|
||||
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,
|
||||
@@ -104,10 +89,6 @@ 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))
|
||||
|
||||
@@ -665,15 +665,10 @@ async def write_image(config, all_frames=False):
|
||||
if is_svg_file(path):
|
||||
import resvg_py
|
||||
|
||||
if resize:
|
||||
width, height = resize
|
||||
# resvg-py allows rendering by width/height directly
|
||||
image_data = resvg_py.svg_to_bytes(
|
||||
svg_path=str(path), width=int(width), height=int(height)
|
||||
)
|
||||
else:
|
||||
# Default size
|
||||
image_data = resvg_py.svg_to_bytes(svg_path=str(path))
|
||||
resize = resize or (None, None)
|
||||
image_data = resvg_py.svg_to_bytes(
|
||||
svg_path=str(path), width=resize[0], height=resize[1], dpi=100
|
||||
)
|
||||
|
||||
# Convert bytes to Pillow Image
|
||||
image = Image.open(io.BytesIO(image_data))
|
||||
|
||||
@@ -68,12 +68,9 @@ from esphome.const import (
|
||||
KEY_CORE,
|
||||
KEY_FRAMEWORK_VERSION,
|
||||
KEY_TARGET_FRAMEWORK,
|
||||
PLATFORM_BK72XX,
|
||||
PLATFORM_ESP32,
|
||||
PLATFORM_ESP8266,
|
||||
PLATFORM_LN882X,
|
||||
PLATFORM_RP2040,
|
||||
PLATFORM_RTL87XX,
|
||||
SCHEDULER_DONT_RUN,
|
||||
TYPE_GIT,
|
||||
TYPE_LOCAL,
|
||||
@@ -699,7 +696,6 @@ def only_with_framework(
|
||||
only_on_esp32 = only_on(PLATFORM_ESP32)
|
||||
only_on_esp8266 = only_on(PLATFORM_ESP8266)
|
||||
only_on_rp2040 = only_on(PLATFORM_RP2040)
|
||||
only_on_libretiny = only_on([PLATFORM_BK72XX, PLATFORM_RTL87XX, PLATFORM_LN882X])
|
||||
only_with_arduino = only_with_framework(Framework.ARDUINO)
|
||||
|
||||
|
||||
|
||||
5
tests/component_tests/image/config/mm_dimensions.svg
Normal file
5
tests/component_tests/image/config/mm_dimensions.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="10mm" height="10mm" viewBox="0 0 100 100">
|
||||
<rect x="0" y="0" width="100" height="100" fill="#00FF00"/>
|
||||
<circle cx="50" cy="50" r="30" fill="#0000FF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 248 B |
@@ -5,17 +5,21 @@ from __future__ import annotations
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome import config_validation as cv
|
||||
from esphome.components.image import (
|
||||
CONF_INVERT_ALPHA,
|
||||
CONF_OPAQUE,
|
||||
CONF_TRANSPARENCY,
|
||||
CONFIG_SCHEMA,
|
||||
get_all_image_metadata,
|
||||
get_image_metadata,
|
||||
write_image,
|
||||
)
|
||||
from esphome.const import CONF_ID, CONF_RAW_DATA_ID, CONF_TYPE
|
||||
from esphome.const import CONF_DITHER, CONF_FILE, CONF_ID, CONF_RAW_DATA_ID, CONF_TYPE
|
||||
from esphome.core import CORE
|
||||
|
||||
|
||||
@@ -350,3 +354,52 @@ def test_get_all_image_metadata_empty() -> None:
|
||||
"get_all_image_metadata should always return a dict"
|
||||
)
|
||||
# Length could be 0 or more depending on what's in CORE at test time
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_progmem_array():
|
||||
"""Mock progmem_array to avoid needing a proper ID object in tests."""
|
||||
with patch("esphome.components.image.cg.progmem_array") as mock_progmem:
|
||||
mock_progmem.return_value = MagicMock()
|
||||
yield mock_progmem
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_svg_with_mm_dimensions_succeeds(
|
||||
component_config_path: Callable[[str], Path],
|
||||
mock_progmem_array: MagicMock,
|
||||
) -> None:
|
||||
"""Test that SVG files with dimensions in mm are successfully processed."""
|
||||
# Create a config for write_image without CONF_RESIZE
|
||||
config = {
|
||||
CONF_FILE: component_config_path("mm_dimensions.svg"),
|
||||
CONF_TYPE: "BINARY",
|
||||
CONF_TRANSPARENCY: CONF_OPAQUE,
|
||||
CONF_DITHER: "NONE",
|
||||
CONF_INVERT_ALPHA: False,
|
||||
CONF_RAW_DATA_ID: "test_raw_data_id",
|
||||
}
|
||||
|
||||
# This should succeed without raising an error
|
||||
result = await write_image(config)
|
||||
|
||||
# Verify that write_image returns the expected tuple
|
||||
assert isinstance(result, tuple), "write_image should return a tuple"
|
||||
assert len(result) == 6, "write_image should return 6 values"
|
||||
|
||||
prog_arr, width, height, image_type, trans_value, frame_count = result
|
||||
|
||||
# Verify the dimensions are positive integers
|
||||
# At 100 DPI, 10mm = ~39 pixels (10mm * 100dpi / 25.4mm_per_inch)
|
||||
assert isinstance(width, int), "Width should be an integer"
|
||||
assert isinstance(height, int), "Height should be an integer"
|
||||
assert width > 0, "Width should be positive"
|
||||
assert height > 0, "Height should be positive"
|
||||
assert frame_count == 1, "Single image should have frame_count of 1"
|
||||
# Verify we got reasonable dimensions from the mm-based SVG
|
||||
assert 30 < width < 50, (
|
||||
f"Width should be around 39 pixels for 10mm at 100dpi, got {width}"
|
||||
)
|
||||
assert 30 < height < 50, (
|
||||
f"Height should be around 39 pixels for 10mm at 100dpi, got {height}"
|
||||
)
|
||||
|
||||
@@ -11,8 +11,6 @@ sensor:
|
||||
- platform: debug
|
||||
free:
|
||||
name: "Heap Free"
|
||||
block:
|
||||
name: "Heap Block"
|
||||
loop_time:
|
||||
name: "Loop Time"
|
||||
cpu_frequency:
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
|
||||
@@ -2,10 +2,3 @@
|
||||
|
||||
esp32:
|
||||
cpu_frequency: 240MHz
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
fragmentation:
|
||||
name: "Heap Fragmentation"
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
|
||||
@@ -9,9 +9,5 @@ sensor:
|
||||
name: "Heap Free"
|
||||
psram:
|
||||
name: "Free PSRAM"
|
||||
fragmentation:
|
||||
name: "Heap Fragmentation"
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
|
||||
psram:
|
||||
|
||||
@@ -1,8 +1 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
fragmentation:
|
||||
name: "Heap Fragmentation"
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
fragmentation:
|
||||
name: "Heap Fragmentation"
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
sensor:
|
||||
- platform: debug
|
||||
min_free:
|
||||
name: "Heap Min Free"
|
||||
Reference in New Issue
Block a user