1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-31 23:21:54 +00:00

Merge branch 'e131_cleanups' into integration

This commit is contained in:
J. Nick Koston
2025-10-29 00:03:50 -05:00
5 changed files with 56 additions and 15 deletions

View File

@@ -3,6 +3,8 @@
#include "e131_addressable_light_effect.h" #include "e131_addressable_light_effect.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include <algorithm>
namespace esphome { namespace esphome {
namespace e131 { namespace e131 {
@@ -76,14 +78,14 @@ void E131Component::loop() {
} }
void E131Component::add_effect(E131AddressableLightEffect *light_effect) { void E131Component::add_effect(E131AddressableLightEffect *light_effect) {
if (light_effects_.count(light_effect)) { if (std::find(light_effects_.begin(), light_effects_.end(), light_effect) != light_effects_.end()) {
return; return;
} }
ESP_LOGD(TAG, "Registering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(), ESP_LOGD(TAG, "Registering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(),
light_effect->get_last_universe()); light_effect->get_last_universe());
light_effects_.insert(light_effect); light_effects_.push_back(light_effect);
for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) { for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) {
join_(universe); join_(universe);
@@ -91,14 +93,17 @@ void E131Component::add_effect(E131AddressableLightEffect *light_effect) {
} }
void E131Component::remove_effect(E131AddressableLightEffect *light_effect) { void E131Component::remove_effect(E131AddressableLightEffect *light_effect) {
if (!light_effects_.count(light_effect)) { auto it = std::find(light_effects_.begin(), light_effects_.end(), light_effect);
if (it == light_effects_.end()) {
return; return;
} }
ESP_LOGD(TAG, "Unregistering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(), ESP_LOGD(TAG, "Unregistering '%s' for universes %d-%d.", light_effect->get_name(), light_effect->get_first_universe(),
light_effect->get_last_universe()); light_effect->get_last_universe());
light_effects_.erase(light_effect); // Swap with last element and pop for O(1) removal (order doesn't matter)
*it = light_effects_.back();
light_effects_.pop_back();
for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) { for (auto universe = light_effect->get_first_universe(); universe <= light_effect->get_last_universe(); ++universe) {
leave_(universe); leave_(universe);

View File

@@ -7,7 +7,6 @@
#include <cinttypes> #include <cinttypes>
#include <map> #include <map>
#include <memory> #include <memory>
#include <set>
#include <vector> #include <vector>
namespace esphome { namespace esphome {
@@ -47,9 +46,8 @@ class E131Component : public esphome::Component {
E131ListenMethod listen_method_{E131_MULTICAST}; E131ListenMethod listen_method_{E131_MULTICAST};
std::unique_ptr<socket::Socket> socket_; std::unique_ptr<socket::Socket> socket_;
std::set<E131AddressableLightEffect *> light_effects_; std::vector<E131AddressableLightEffect *> light_effects_;
std::map<int, int> universe_consumers_; std::map<int, int> universe_consumers_;
std::map<int, E131Packet> universe_packets_;
}; };
} // namespace e131 } // namespace e131

View File

@@ -12,7 +12,7 @@ platformio==6.1.18 # When updating platformio, also update /docker/Dockerfile
esptool==5.1.0 esptool==5.1.0
click==8.1.7 click==8.1.7
esphome-dashboard==20251013.0 esphome-dashboard==20251013.0
aioesphomeapi==42.4.0 aioesphomeapi==42.5.0
zeroconf==0.148.0 zeroconf==0.148.0
puremagic==1.30 puremagic==1.30
ruamel.yaml==0.18.16 # dashboard_import ruamel.yaml==0.18.16 # dashboard_import

View File

@@ -90,16 +90,18 @@ def get_component_from_path(file_path: str) -> str | None:
"""Extract component name from a file path. """Extract component name from a file path.
Args: Args:
file_path: Path to a file (e.g., "esphome/components/wifi/wifi.cpp") file_path: Path to a file (e.g., "esphome/components/wifi/wifi.cpp"
or "tests/components/uart/test.esp32-idf.yaml")
Returns: Returns:
Component name if path is in components directory, None otherwise Component name if path is in components or tests directory, None otherwise
""" """
if not file_path.startswith(ESPHOME_COMPONENTS_PATH): if file_path.startswith(ESPHOME_COMPONENTS_PATH) or file_path.startswith(
return None ESPHOME_TESTS_COMPONENTS_PATH
parts = file_path.split("/") ):
if len(parts) >= 3: parts = file_path.split("/")
return parts[2] if len(parts) >= 3 and parts[2]:
return parts[2]
return None return None

View File

@@ -1065,3 +1065,39 @@ def test_parse_list_components_output(output: str, expected: list[str]) -> None:
"""Test parse_list_components_output function.""" """Test parse_list_components_output function."""
result = helpers.parse_list_components_output(output) result = helpers.parse_list_components_output(output)
assert result == expected assert result == expected
@pytest.mark.parametrize(
("file_path", "expected_component"),
[
# Component files
("esphome/components/wifi/wifi.cpp", "wifi"),
("esphome/components/uart/uart.h", "uart"),
("esphome/components/api/api_server.cpp", "api"),
("esphome/components/sensor/sensor.cpp", "sensor"),
# Test files
("tests/components/uart/test.esp32-idf.yaml", "uart"),
("tests/components/wifi/test.esp8266-ard.yaml", "wifi"),
("tests/components/sensor/test.esp32-idf.yaml", "sensor"),
("tests/components/api/test_api.cpp", "api"),
("tests/components/uart/common.h", "uart"),
# Non-component files
("esphome/core/component.cpp", None),
("esphome/core/helpers.h", None),
("tests/integration/test_api.py", None),
("tests/unit_tests/test_helpers.py", None),
("README.md", None),
("script/helpers.py", None),
# Edge cases
("esphome/components/", None), # No component name
("tests/components/", None), # No component name
("esphome/components", None), # No trailing slash
("tests/components", None), # No trailing slash
],
)
def test_get_component_from_path(
file_path: str, expected_component: str | None
) -> None:
"""Test extraction of component names from file paths."""
result = helpers.get_component_from_path(file_path)
assert result == expected_component