diff --git a/esphome/components/script/__init__.py b/esphome/components/script/__init__.py index d8d0f6eb94..8d69981db0 100644 --- a/esphome/components/script/__init__.py +++ b/esphome/components/script/__init__.py @@ -54,7 +54,7 @@ def check_max_runs(value): if value[CONF_MODE] not in [CONF_QUEUED, CONF_PARALLEL]: raise cv.Invalid( - "The option 'max_runs' is only valid in 'queue' and 'parallel' mode.", + "The option 'max_runs' is only valid in 'queued' and 'parallel' mode.", path=[CONF_MAX_RUNS], ) diff --git a/esphome/components/script/script.h b/esphome/components/script/script.h index 80afa154de..3a97a26985 100644 --- a/esphome/components/script/script.h +++ b/esphome/components/script/script.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" @@ -137,6 +139,10 @@ template class QueueingScript : public Script, public Com } void stop() override { + // Clear all queued items to free memory immediately + for (int i = 0; i < this->max_runs_ - 1; i++) { + this->var_queue_[i].reset(); + } this->num_queued_ = 0; this->queue_front_ = 0; Script::stop(); @@ -144,11 +150,11 @@ template class QueueingScript : public Script, public Com void loop() override { if (this->num_queued_ != 0 && !this->is_action_running()) { - // Dequeue: decrement count, read from front, advance read position + // Dequeue: decrement count, move tuple out (frees slot), advance read position this->num_queued_--; - auto &vars = *this->var_queue_[this->queue_front_]; + auto tuple_ptr = std::move(this->var_queue_[this->queue_front_]); this->queue_front_ = (this->queue_front_ + 1) % (this->max_runs_ - 1); - this->trigger_tuple_(vars, typename gens::type()); + this->trigger_tuple_(*tuple_ptr, typename gens::type()); } } diff --git a/esphome/const.py b/esphome/const.py index d62dc617d1..f3f177b3ae 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -696,6 +696,7 @@ CONF_OPEN_DRAIN = "open_drain" CONF_OPEN_DRAIN_INTERRUPT = "open_drain_interrupt" CONF_OPEN_DURATION = "open_duration" CONF_OPEN_ENDSTOP = "open_endstop" +CONF_OPENTHREAD = "openthread" CONF_OPERATION = "operation" CONF_OPTIMISTIC = "optimistic" CONF_OPTION = "option" diff --git a/esphome/core/__init__.py b/esphome/core/__init__.py index 49a6e1f90a..a3efcf69a9 100644 --- a/esphome/core/__init__.py +++ b/esphome/core/__init__.py @@ -11,6 +11,7 @@ from esphome.const import ( CONF_COMMENT, CONF_ESPHOME, CONF_ETHERNET, + CONF_OPENTHREAD, CONF_PORT, CONF_USE_ADDRESS, CONF_WEB_SERVER, @@ -641,6 +642,9 @@ class EsphomeCore: if CONF_ETHERNET in self.config: return self.config[CONF_ETHERNET][CONF_USE_ADDRESS] + if CONF_OPENTHREAD in self.config: + return f"{self.name}.local" + return None @property diff --git a/tests/integration/test_script_queued.py b/tests/integration/test_script_queued.py index 414a27ca2e..9f4bce6f31 100644 --- a/tests/integration/test_script_queued.py +++ b/tests/integration/test_script_queued.py @@ -135,7 +135,7 @@ async def test_script_queued( api_client_connected() as client, ): # Get services - entities, services = await client.list_entities_services() + _, services = await client.list_entities_services() # Test 1: Queue depth limit test_service = next((s for s in services if s.name == "test_queue_depth"), None) diff --git a/tests/unit_tests/test_core.py b/tests/unit_tests/test_core.py index 0e0bdcf9ea..edf055ca73 100644 --- a/tests/unit_tests/test_core.py +++ b/tests/unit_tests/test_core.py @@ -570,6 +570,13 @@ class TestEsphomeCore: assert target.address == "4.3.2.1" + def test_address__openthread(self, target): + target.name = "test-device" + target.config = {} + target.config[const.CONF_OPENTHREAD] = {} + + assert target.address == "test-device.local" + def test_is_esp32(self, target): target.data[const.KEY_CORE] = {const.KEY_TARGET_PLATFORM: "esp32"}