Merge remote-tracking branch 'origin/dev' into integration

This commit is contained in:
J. Nick Koston
2026-09-25 17:32:22 +01:00
159 changed files with 1679 additions and 2193 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ runs:
# detects the activated venv via ``VIRTUAL_ENV`` so the venv layout
# downstream jobs rely on is preserved.
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pull request saves land in per-PR scopes nothing else can
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
- name: Set up uv
# ``--system`` (below) installs into the setup-python interpreter;
# no venv is created or restored by this workflow.
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pull-request-only workflow: a save could never be shared and
+3 -3
View File
@@ -49,7 +49,7 @@ jobs:
# detects the activated venv via ``VIRTUAL_ENV`` so downstream jobs
# that ``. venv/bin/activate`` see an identical layout.
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pull request saves land in per-PR scopes nothing else can
@@ -413,7 +413,7 @@ jobs:
- name: Set up uv
# Only needed on cache miss to populate the venv.
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pull request saves land in per-PR scopes nothing else can
@@ -1274,7 +1274,7 @@ jobs:
# install step (order-of-magnitude faster on cold boots,
# with its own wheel cache). actions/setup-python still
# provides the interpreter.
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pull request saves land in per-PR scopes nothing else can
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
# setup-python interpreter so subsequent ``prek`` /
# ``script/run-in-env.py`` steps find the deps without a
# ``uv run`` prefix.
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
# Pin uv version so the action does not have to fetch the
+3 -1
View File
@@ -737,7 +737,9 @@ file does, and it is the authority when they disagree. The most useful starting
6. **Avoid `std::deque`:** It allocates in 512-byte blocks regardless of element size, guaranteeing at least 512 bytes of RAM usage immediately. This is a major source of crashes on memory-constrained devices.
7. **Detection:** Look for these patterns in compiler output:
7. **Never use `new (std::nothrow)`:** On ESP-IDF exceptions are disabled, so a failed nothrow allocation aborts instead of returning `nullptr`. Use `RAMAllocator` from `esphome/core/helpers.h`; CI rejects `std::nothrow`.
8. **Detection:** Look for these patterns in compiler output:
- Large code sections with STL symbols (vector, map, set)
- `alloc`, `realloc`, `dealloc` in symbol names
- `_M_realloc_insert`, `_M_default_append` (vector reallocation)
+5
View File
@@ -1344,8 +1344,12 @@ def _upload_via_native_api(
# fall back to a plaintext upload
noise_psk = None
plaintext_fallback = False
allow_plaintext_upload = False
if (encryption_conf := ota_conf.get(CONF_ENCRYPTION)) is not None:
noise_psk = encryption_conf.get(CONF_KEY)
allow_plaintext_upload = bool(
encryption_conf.get(espota2.CONF_ALLOW_PLAINTEXT_UPLOAD)
)
if not noise_psk:
raise EsphomeError(
"OTA encryption is configured but no key was resolved; "
@@ -1396,6 +1400,7 @@ def _upload_via_native_api(
ota_type,
noise_psk,
plaintext_fallback=plaintext_fallback,
allow_plaintext_upload=allow_plaintext_upload,
)
@@ -208,65 +208,50 @@ for _name, _arm in (
)
@automation.register_action(
automation.register_simple_action(
"alarm_control_panel.pending",
PendingAction,
ALARM_CONTROL_PANEL_ACTION_SCHEMA,
synchronous=True,
)
async def alarm_action_pending_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"alarm_control_panel.triggered",
TriggeredAction,
ALARM_CONTROL_PANEL_ACTION_SCHEMA,
synchronous=True,
)
async def alarm_action_trigger_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"alarm_control_panel.chime",
ChimeAction,
ALARM_CONTROL_PANEL_ACTION_SCHEMA,
synchronous=True,
)
async def alarm_action_chime_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"alarm_control_panel.ready",
ReadyAction,
ALARM_CONTROL_PANEL_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_condition(
automation.register_simple_condition(
"alarm_control_panel.ready",
AlarmControlPanelCondition,
ALARM_CONTROL_PANEL_CONDITION_SCHEMA,
)
async def alarm_action_ready_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_condition(
automation.register_simple_condition(
"alarm_control_panel.is_armed",
AlarmControlPanelCondition,
ALARM_CONTROL_PANEL_CONDITION_SCHEMA,
)
async def alarm_control_panel_is_armed_to_code(
config, condition_id, template_arg, args
):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(condition_id, template_arg, paren)
@coroutine_with_priority(CoroPriority.CORE)
+1
View File
@@ -14,6 +14,7 @@
#include "esphome/components/socket/socket.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/entity_includes.h"
#include "esphome/core/log.h"
#include "esphome/core/string_ref.h"
#ifdef USE_PROVISIONING
+1 -4
View File
@@ -655,7 +655,7 @@ async def to_code(config):
cg.add_global(binary_sensor_ns.using)
@automation.register_action(
automation.register_simple_action(
"binary_sensor.invalidate_state",
BinarySensorInvalidateAction,
cv.maybe_simple_value(
@@ -666,9 +666,6 @@ async def to_code(config):
),
synchronous=True,
)
async def binary_sensor_invalidate_state_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
# automation.cpp only implements the click/double_click/multi_click triggers
+1 -12
View File
@@ -32,8 +32,6 @@ from esphome.const import (
UNIT_VOLT,
UNIT_WATT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
# Import ICONS not included in esphome's const.py, from the local components const.py
@@ -138,7 +136,7 @@ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
)
@automation.register_action(
automation.register_parented_action(
"bl0906.reset_energy",
ResetEnergyAction,
maybe_simple_id(
@@ -148,15 +146,6 @@ FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema(
),
synchronous=True,
)
async def reset_energy_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+3 -12
View File
@@ -207,26 +207,20 @@ BLE_REMOVE_BOND_ACTION_SCHEMA = cv.Schema(
)
@automation.register_action(
automation.register_simple_action(
"ble_client.disconnect",
BLEDisconnectAction,
BLE_CONNECT_ACTION_SCHEMA,
synchronous=False,
)
async def ble_disconnect_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, parent)
@automation.register_action(
automation.register_simple_action(
"ble_client.connect",
BLEConnectAction,
BLE_CONNECT_ACTION_SCHEMA,
synchronous=False,
)
async def ble_connect_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, parent)
@automation.register_action(
@@ -328,15 +322,12 @@ async def passkey_reply_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
automation.register_simple_action(
"ble_client.remove_bond",
BLERemoveBondAction,
BLE_REMOVE_BOND_ACTION_SCHEMA,
synchronous=True,
)
async def remove_bond_to_code(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, parent)
async def to_code(config):
+2 -20
View File
@@ -28,7 +28,7 @@ CONFIG_SCHEMA = (
)
@automation.register_action(
automation.register_parented_action(
"bm8563.write_time",
WriteAction,
automation.maybe_simple_id(
@@ -38,15 +38,6 @@ CONFIG_SCHEMA = (
),
synchronous=True,
)
async def bm8563_write_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
@@ -73,7 +64,7 @@ async def bm8563_start_timer_to_code(
return var
@automation.register_action(
automation.register_parented_action(
"bm8563.read_time",
ReadAction,
automation.maybe_simple_id(
@@ -83,15 +74,6 @@ async def bm8563_start_timer_to_code(
),
synchronous=True,
)
async def bm8563_read_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+4 -14
View File
@@ -16,14 +16,14 @@ from esphome.const import (
DEVICE_CLASS_RESTART,
DEVICE_CLASS_UPDATE,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.entity_helpers import (
entity_duplicate_validator,
queue_entity_register,
setup_device_class,
setup_entity,
)
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
from esphome.cpp_generator import MockObj, MockObjClass
from esphome.types import ConfigType, SafeExpType
CODEOWNERS = ["@esphome/core"]
@@ -40,8 +40,6 @@ button_ns = cg.esphome_ns.namespace("button")
Button = button_ns.class_("Button", cg.EntityBase)
ButtonPtr = Button.operator("ptr")
PressAction = button_ns.class_("PressAction", automation.Action)
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
@@ -123,17 +121,9 @@ BUTTON_PRESS_SCHEMA = maybe_simple_id(
)
@automation.register_action(
"button.press", PressAction, BUTTON_PRESS_SCHEMA, synchronous=True
automation.register_apply_action(
"button.press", BUTTON_PRESS_SCHEMA, automation.ApplyCall("press()")
)
async def button_press_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@coroutine_with_priority(CoroPriority.CORE)
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include "esphome/components/button/button.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
namespace esphome::button {
template<typename... Ts> class PressAction final : public Action<Ts...> {
public:
explicit PressAction(Button *button) : button_(button) {}
void play(const Ts &...x) override { this->button_->press(); }
protected:
Button *button_;
};
} // namespace esphome::button
+26 -12
View File
@@ -364,22 +364,36 @@ CC1101_ACTION_SCHEMA = cv.Schema(
)
@automation.register_action(
"cc1101.begin_tx", BeginTxAction, CC1101_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"cc1101.begin_tx",
BeginTxAction,
CC1101_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"cc1101.begin_rx", BeginRxAction, CC1101_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"cc1101.begin_rx",
BeginRxAction,
CC1101_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"cc1101.reset", ResetAction, CC1101_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"cc1101.reset",
ResetAction,
CC1101_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"cc1101.set_idle", SetIdleAction, CC1101_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"cc1101.set_idle",
SetIdleAction,
CC1101_ACTION_SCHEMA,
synchronous=True,
)
async def cc1101_action_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
def validate_raw_data(value):
+1 -12
View File
@@ -13,8 +13,6 @@ from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_PARTS_PER_MILLION,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
DEPENDENCIES = ["uart"]
@@ -72,18 +70,9 @@ CALIBRATION_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_simple_action(
"cm1106.calibrate_zero",
CM1106CalibrateZeroAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
async def cm1106_calibration_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
"""Service code generation entry point."""
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+1
View File
@@ -23,6 +23,7 @@ CONF_ENABLE_OTA_DOWNGRADE_PROTECTION = "enable_ota_downgrade_protection"
CONF_ENABLED = "enabled"
CONF_GYROSCOPE_ODR = "gyroscope_odr"
CONF_GYROSCOPE_RANGE = "gyroscope_range"
CONF_HUMIDITY_SOURCE = "humidity_source"
CONF_IAQ = "iaq"
CONF_IGNORE_NOT_FOUND = "ignore_not_found"
CONF_IS_WRGB = "is_wrgb"
+1 -11
View File
@@ -17,8 +17,6 @@ from esphome.const import (
UNIT_VOLT,
UNIT_WATT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@balrog-kun"]
@@ -131,7 +129,7 @@ async def to_code(config: ConfigType) -> None:
cg.add(var.set_power_sensor(sens))
@automation.register_action(
automation.register_simple_action(
"cs5460a.restart",
CS5460ARestartAction,
maybe_simple_id(
@@ -141,11 +139,3 @@ async def to_code(config: ConfigType) -> None:
),
synchronous=True,
)
async def restart_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+15 -33
View File
@@ -214,16 +214,6 @@ def _validate_sleep_duration(value: core.TimePeriod) -> core.TimePeriod:
deep_sleep_ns = cg.esphome_ns.namespace("deep_sleep")
DeepSleepComponent = deep_sleep_ns.class_("DeepSleepComponent", cg.Component)
EnterDeepSleepAction = deep_sleep_ns.class_("EnterDeepSleepAction", automation.Action)
PreventDeepSleepAction = deep_sleep_ns.class_(
"PreventDeepSleepAction",
automation.Action,
cg.Parented.template(DeepSleepComponent),
)
AllowDeepSleepAction = deep_sleep_ns.class_(
"AllowDeepSleepAction",
automation.Action,
cg.Parented.template(DeepSleepComponent),
)
WakeupPinMode = deep_sleep_ns.enum("WakeupPinMode")
WAKEUP_PIN_MODES = {
@@ -422,8 +412,12 @@ async def to_code(config: ConfigType) -> None:
if CONF_TOUCH_WAKEUP in config:
cg.add(var.set_touch_wakeup(config[CONF_TOUCH_WAKEUP]))
if CORE.using_zephyr and "zigbee" not in CORE.loaded_integrations:
zephyr_add_prj_conf("POWEROFF", True)
if CORE.using_zephyr:
# Devices are suspended when CPU is entering a low power state
# https://github.com/nrfconnect/sdk-zephyr/blob/v3.7.99-ncs2-2/doc/services/pm/device.rst#system-managed-device-power-management
zephyr_add_prj_conf("PM_DEVICE", True)
if "zigbee" not in CORE.loaded_integrations:
zephyr_add_prj_conf("POWEROFF", True)
cg.add_define("USE_DEEP_SLEEP")
@@ -486,27 +480,15 @@ async def deep_sleep_enter_to_code(
return var
@automation.register_action(
"deep_sleep.prevent",
PreventDeepSleepAction,
automation.maybe_simple_id(DEEP_SLEEP_ACTION_SCHEMA),
synchronous=True,
)
@automation.register_action(
"deep_sleep.allow",
AllowDeepSleepAction,
automation.maybe_simple_id(DEEP_SLEEP_ACTION_SCHEMA),
synchronous=True,
)
async def deep_sleep_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
for _name, _call in (
("deep_sleep.prevent", "prevent_deep_sleep()"),
("deep_sleep.allow", "allow_deep_sleep()"),
):
automation.register_apply_action(
_name,
automation.maybe_simple_id(DEEP_SLEEP_ACTION_SCHEMA),
automation.ApplyCall(_call),
)
FILTER_SOURCE_FILES = filter_source_files_from_platform(
@@ -121,8 +121,6 @@ class Ext1WakeTrigger : public Trigger<>, public Component {
template<typename... Ts> class EnterDeepSleepAction;
template<typename... Ts> class PreventDeepSleepAction;
/** This component allows setting up the node to go into deep sleep mode to conserve battery.
*
* To set this component up, first set *when* the deep sleep should trigger using set_run_cycles
@@ -298,15 +296,4 @@ template<typename... Ts> class EnterDeepSleepAction final : public Action<Ts...>
#endif
};
template<typename... Ts>
class PreventDeepSleepAction final : public Action<Ts...>, public Parented<DeepSleepComponent> {
public:
void play(const Ts &...x) override { this->parent_->prevent_deep_sleep(); }
};
template<typename... Ts> class AllowDeepSleepAction final : public Action<Ts...>, public Parented<DeepSleepComponent> {
public:
void play(const Ts &...x) override { this->parent_->allow_deep_sleep(); }
};
} // namespace esphome::deep_sleep
+1 -5
View File
@@ -199,7 +199,7 @@ automation.register_apply_action(
)
@automation.register_condition(
automation.register_parented_condition(
"dfplayer.is_playing",
DFPlayerIsPlayingCondition,
cv.Schema(
@@ -208,7 +208,3 @@ automation.register_apply_action(
}
),
)
async def dfplayer_is_playing_to_code(config, condition_id, template_arg, args):
var = cg.new_Pvariable(condition_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+1 -11
View File
@@ -49,7 +49,7 @@ async def to_code(config: ConfigType) -> None:
await uart.register_uart_device(var, config)
@automation.register_action(
automation.register_parented_action(
"dfrobot_sen0395.reset",
DfrobotSen0395ResetAction,
maybe_simple_id(
@@ -59,16 +59,6 @@ async def to_code(config: ConfigType) -> None:
),
synchronous=True,
)
async def dfrobot_sen0395_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
def range_segment_list(input: Any) -> list:
@@ -294,74 +294,71 @@ MENU_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
"display_menu.up", UpAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.up",
UpAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_up_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.down", DownAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.down",
DownAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_down_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.left", LeftAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.left",
LeftAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_left_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.right", RightAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.right",
RightAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_right_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.enter", EnterAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.enter",
EnterAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_enter_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.show", ShowAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.show",
ShowAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_show_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"display_menu.hide", HideAction, MENU_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"display_menu.hide",
HideAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_hide_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"display_menu.show_main",
ShowMainAction,
MENU_ACTION_SCHEMA,
synchronous=True,
)
async def menu_show_main_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_condition(
automation.register_simple_condition(
"display_menu.is_active",
IsActiveCondition,
automation.maybe_simple_id(
@@ -370,9 +367,6 @@ async def menu_show_main_to_code(config, action_id, template_arg, args):
}
),
)
async def display_menu_is_active_to_code(config, condition_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(condition_id, template_arg, paren)
async def menu_item_to_code(menu, config, parent):
+2 -22
View File
@@ -3,8 +3,6 @@ import esphome.codegen as cg
from esphome.components import i2c, time
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@badbadc0ffee"]
@@ -22,7 +20,7 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
).extend(i2c.i2c_device_schema(0x68))
@automation.register_action(
automation.register_parented_action(
"ds1307.write_time",
WriteAction,
cv.Schema(
@@ -32,18 +30,9 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
),
synchronous=True,
)
async def ds1307_write_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"ds1307.read_time",
ReadAction,
automation.maybe_simple_id(
@@ -53,15 +42,6 @@ async def ds1307_write_time_to_code(
),
synchronous=True,
)
async def ds1307_read_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+21 -45
View File
@@ -1,10 +1,4 @@
from esphome.automation import (
Action,
Condition,
maybe_simple_id,
register_action,
register_condition,
)
from esphome import automation
import esphome.codegen as cg
from esphome.components import binary_sensor, sensor
import esphome.config_validation as cv
@@ -29,13 +23,13 @@ duty_time_sensor_ns = cg.esphome_ns.namespace("duty_time_sensor")
DutyTimeSensor = duty_time_sensor_ns.class_(
"DutyTimeSensor", sensor.Sensor, cg.PollingComponent
)
BaseAction = duty_time_sensor_ns.class_("BaseAction", Action, cg.Parented)
BaseAction = duty_time_sensor_ns.class_("BaseAction", automation.Action, cg.Parented)
StartAction = duty_time_sensor_ns.class_("StartAction", BaseAction)
StopAction = duty_time_sensor_ns.class_("StopAction", BaseAction)
ResetAction = duty_time_sensor_ns.class_("ResetAction", BaseAction)
SetAction = duty_time_sensor_ns.class_("SetAction", BaseAction)
RunningCondition = duty_time_sensor_ns.class_(
"RunningCondition", Condition, cg.Parented
"RunningCondition", automation.Condition, cg.Parented
)
@@ -86,56 +80,38 @@ async def to_code(config: ConfigType) -> None:
# AUTOMATIONS
DUTY_TIME_ID_SCHEMA = maybe_simple_id(
DUTY_TIME_ID_SCHEMA = automation.maybe_simple_id(
{
cv.Required(CONF_ID): cv.use_id(DutyTimeSensor),
}
)
@register_action(
"sensor.duty_time.start", StartAction, DUTY_TIME_ID_SCHEMA, synchronous=True
automation.register_parented_action(
"sensor.duty_time.start",
StartAction,
DUTY_TIME_ID_SCHEMA,
synchronous=True,
)
async def sensor_runtime_start_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@register_action(
"sensor.duty_time.stop", StopAction, DUTY_TIME_ID_SCHEMA, synchronous=True
automation.register_parented_action(
"sensor.duty_time.stop",
StopAction,
DUTY_TIME_ID_SCHEMA,
synchronous=True,
)
async def sensor_runtime_stop_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@register_action(
"sensor.duty_time.reset", ResetAction, DUTY_TIME_ID_SCHEMA, synchronous=True
automation.register_parented_action(
"sensor.duty_time.reset",
ResetAction,
DUTY_TIME_ID_SCHEMA,
synchronous=True,
)
async def sensor_runtime_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@register_condition(
@automation.register_condition(
"sensor.duty_time.is_running", RunningCondition, DUTY_TIME_ID_SCHEMA
)
async def duty_time_is_running_to_code(
@@ -148,7 +124,7 @@ async def duty_time_is_running_to_code(
return cg.new_Pvariable(condition_id, template_arg, paren, True)
@register_condition(
@automation.register_condition(
"sensor.duty_time.is_not_running", RunningCondition, DUTY_TIME_ID_SCHEMA
)
async def duty_time_is_not_running_to_code(
+54 -1
View File
@@ -11,7 +11,10 @@ from typing import Any
from esphome import yaml_util
import esphome.codegen as cg
from esphome.components.const import CONF_ENABLE_OTA_DOWNGRADE_PROTECTION
from esphome.components.const import (
CONF_ENABLE_OTA_DOWNGRADE_PROTECTION,
CONF_IGNORE_NOT_FOUND,
)
from esphome.config_helpers import filter_source_files_from_defines
import esphome.config_validation as cv
from esphome.const import (
@@ -111,6 +114,7 @@ CONF_ENGINEERING_SAMPLE = "engineering_sample"
CONF_INCLUDE_BUILTIN_IDF_COMPONENTS = "include_builtin_idf_components"
CONF_ENABLE_LWIP_ASSERT = "enable_lwip_assert"
CONF_EXECUTE_FROM_PSRAM = "execute_from_psram"
CONF_NVS_CACHE_IN_PSRAM = "nvs_cache_in_psram"
CONF_FLASH_CHIP = "flash_chip"
CONF_KEY_ID = "key_id"
CONF_MINIMUM_CHIP_REVISION = "minimum_chip_revision"
@@ -1595,6 +1599,29 @@ def final_validate(config) -> None:
path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_EXECUTE_FROM_PSRAM],
)
)
if advanced.get(CONF_NVS_CACHE_IN_PSRAM):
psram_conf = full_config.get(PSRAM_DOMAIN)
if (
psram_conf is None
or psram_conf[CONF_DISABLED]
or psram_conf[CONF_IGNORE_NOT_FOUND]
):
errs.append(
cv.Invalid(
f"'{CONF_NVS_CACHE_IN_PSRAM}' requires PSRAM with 'ignore_not_found: false'",
path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_NVS_CACHE_IN_PSRAM],
)
)
if (
advanced.get(CONF_NVS_ENCRYPTION) is not None
or conf_fw[CONF_SDKCONFIG_OPTIONS].get("CONFIG_NVS_ENCRYPTION") == "y"
):
errs.append(
cv.Invalid(
f"'{CONF_NVS_CACHE_IN_PSRAM}' cannot be used with NVS encryption; the keys must stay in internal RAM",
path=[CONF_FRAMEWORK, CONF_ADVANCED, CONF_NVS_CACHE_IN_PSRAM],
)
)
final_validate_pins(full_config)
@@ -2035,6 +2062,7 @@ FRAMEWORK_SCHEMA = cv.Schema(
cv.Optional(CONF_RINGBUF_IN_IRAM, default=False): cv.boolean,
cv.Optional(CONF_HEAP_IN_IRAM, default=False): cv.boolean,
cv.Optional(CONF_EXECUTE_FROM_PSRAM, default=False): cv.boolean,
cv.Optional(CONF_NVS_CACHE_IN_PSRAM): cv.boolean,
cv.Optional(CONF_LOOP_TASK_STACK_SIZE, default=8192): cv.int_range(
min=8192, max=32768
),
@@ -2361,6 +2389,20 @@ async def _set_libc_picolibc_newlib_compat() -> None:
)
@coroutine_with_priority(CoroPriority.FINAL)
async def _apply_nvs_cache_in_psram(explicit: bool) -> None:
"""Keep the NVS cache in PSRAM unless NVS encryption is on, however it was enabled."""
# The encrypted partition object holds the derived keys, which must stay in internal RAM
if is_idf_sdkconfig_option_enabled("CONFIG_NVS_ENCRYPTION"):
if explicit:
_LOGGER.warning(
"%s ignored: NVS encryption keeps the NVS cache in internal RAM",
CONF_NVS_CACHE_IN_PSRAM,
)
return
set_idf_sdkconfig_default("CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM", True)
@coroutine_with_priority(CoroPriority.FINAL)
async def _reconcile_certificate_bundle_sdkconfig() -> None:
"""Enable the mbedTLS certificate bundle only when something asked for it.
@@ -2913,6 +2955,17 @@ async def to_code(config):
if advanced[CONF_EXECUTE_FROM_PSRAM]:
add_idf_sdkconfig_option("CONFIG_SPIRAM_XIP_FROM_PSRAM", True)
# Imported here as psram imports this module
from esphome.components.psram import is_guaranteed as psram_is_guaranteed
# Frees internal heap (the cache scales with the NVS partition) but slows NVS, so only
# where PSRAM is known to be fitted. Decided at FINAL so every way of enabling NVS
# encryption has been seen and a user's sdkconfig_options value wins.
# Unset means on; only an explicit true is worth a warning when it has to be dropped.
requested = advanced.get(CONF_NVS_CACHE_IN_PSRAM)
if requested is not False and psram_is_guaranteed():
CORE.add_job(_apply_nvs_cache_in_psram, requested is True)
# Apply LWIP core locking for better socket performance
# This is already enabled by default in Arduino framework, where it provides
# significant performance benefits. Our benchmarks show socket operations are
+18 -30
View File
@@ -32,8 +32,7 @@ from esphome.const import (
CONF_NAME,
CONF_NAME_ADD_MAC_SUFFIX,
)
from esphome.core import CORE, ID, TimePeriod
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.core import CORE, TimePeriod
import esphome.final_validate as fv
from esphome.types import ConfigType
@@ -606,38 +605,27 @@ async def to_code(config: ConfigType) -> None:
cg.add_define("USE_ESP32_BLE_UUID")
@automation.register_condition("ble.enabled", BLEEnabledCondition, cv.Schema({}))
async def ble_enabled_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
return cg.new_Pvariable(condition_id, template_arg)
@automation.register_action(
"ble.enable", BLEEnableAction, cv.Schema({}), synchronous=True
automation.register_bare_condition(
"ble.enabled",
BLEEnabledCondition,
cv.Schema({}),
)
async def ble_enable_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
return cg.new_Pvariable(action_id, template_arg)
@automation.register_action(
"ble.disable", BLEDisableAction, cv.Schema({}), synchronous=True
automation.register_bare_action(
"ble.enable",
BLEEnableAction,
cv.Schema({}),
synchronous=True,
)
automation.register_bare_action(
"ble.disable",
BLEDisableAction,
cv.Schema({}),
synchronous=True,
)
async def ble_disable_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
return cg.new_Pvariable(action_id, template_arg)
# ble_advertising.cpp is fully #ifdef'd on USE_ESP32_BLE_ADVERTISING, set
+36 -9
View File
@@ -2,7 +2,7 @@ import logging
import esphome.codegen as cg
from esphome.components.noise import (
encryption_schema,
ENCRYPTION_SCHEMA,
new_psk_progmem,
static_encryption_key,
)
@@ -27,6 +27,7 @@ from esphome.const import (
)
from esphome.core import CORE, coroutine_with_priority
from esphome.coroutine import CoroPriority
from esphome.espota2 import CONF_ALLOW_PLAINTEXT_UPLOAD
import esphome.final_validate as fv
from esphome.types import ConfigType
@@ -231,15 +232,38 @@ def _resolve_encryption_key(encryption_conf: ConfigType, api_conf: ConfigType) -
encryption_conf[CONF_KEY] = api_key
# Uploader side options live only on the ota block; the api block keeps the
# shared schema
_ENCRYPTION_SCHEMA = ENCRYPTION_SCHEMA.extend(
{
cv.Optional(CONF_ALLOW_PLAINTEXT_UPLOAD): cv.boolean,
}
)
def _encryption_schema(config: ConfigType | None) -> ConfigType:
# Only a bare `encryption:` block is keyless; `false` or a list must fail
return _ENCRYPTION_SCHEMA({} if config is None else config)
# Also called on merged same-port configs in final validate, where schemas
# do not run
def _validate_no_password_with_encryption(config: ConfigType) -> ConfigType:
if CONF_PASSWORD in config and CONF_ENCRYPTION in config:
raise cv.Invalid(
f"'{CONF_PASSWORD}' cannot be combined with '{CONF_ENCRYPTION}'; the "
f"encryption key already authenticates the uploader, remove '{CONF_PASSWORD}'"
)
return config
if (
CONF_PASSWORD not in config
or (encryption := config.get(CONF_ENCRYPTION)) is None
):
return config
# The migration install may still have to answer the old firmware's
# password prompt on the plaintext leg; the password is not built in
if encryption.get(CONF_ALLOW_PLAINTEXT_UPLOAD):
return config
raise cv.Invalid(
f"'{CONF_PASSWORD}' cannot be combined with '{CONF_ENCRYPTION}'; the "
f"encryption key already authenticates the uploader, remove '{CONF_PASSWORD}' "
f"(or set '{CONF_ALLOW_PLAINTEXT_UPLOAD}: true' for the one install that "
f"migrates a device still asking for it)"
)
def _consume_ota_sockets(config: ConfigType) -> ConfigType:
@@ -269,7 +293,7 @@ CONFIG_SCHEMA = cv.All(
): cv.port,
cv.Optional(CONF_ALLOW_PARTITION_ACCESS, default=False): cv.boolean,
cv.Optional(CONF_PASSWORD): cv.sensitive(),
cv.Optional(CONF_ENCRYPTION): encryption_schema,
cv.Optional(CONF_ENCRYPTION): _encryption_schema,
cv.Optional(CONF_NUM_ATTEMPTS): cv.invalid(
f"'{CONF_SAFE_MODE}' (and its related configuration variables) has moved from 'ota' to its own component. See https://esphome.io/components/safe_mode"
),
@@ -304,7 +328,10 @@ async def to_code(config: ConfigType) -> None:
# An empty password opts in to the auth code path so set_auth_password() can be
# called at runtime (e.g. to rotate the password from a lambda). When `password:`
# is omitted entirely, the auth path is excluded to save flash on small devices.
if CONF_PASSWORD in config:
# A password is never built in next to encryption: validation only lets
# the two coexist for the migration install, where the password answers
# the running firmware and the build is authenticated by the key
if CONF_PASSWORD in config and CONF_ENCRYPTION not in config:
cg.add_define("USE_OTA_PASSWORD")
if config[CONF_PASSWORD]:
cg.add(var.set_auth_password(config[CONF_PASSWORD]))
+29 -2
View File
@@ -467,6 +467,8 @@ void ESPHomeOTAComponent::handle_data_() {
if (this->extended_proto_()) {
// Read ota type, 1 byte
if (!this->data_readall_(buf, 1)) {
if (this->client_left_before_start_())
return;
this->log_read_error_(LOG_STR("OTA type"));
goto error; // NOLINT(cppcoreguidelines-avoid-goto)
}
@@ -476,6 +478,9 @@ void ESPHomeOTAComponent::handle_data_() {
// Read size, 4 bytes MSB first
if (!this->data_readall_(buf, 4)) {
// The first request byte is the type on the extended protocol; a close after it was a cut-off request
if (!this->extended_proto_() && this->client_left_before_start_())
return;
this->log_read_error_(LOG_STR("size"));
goto error; // NOLINT(cppcoreguidelines-avoid-goto)
}
@@ -542,6 +547,8 @@ void ESPHomeOTAComponent::handle_data_() {
// there is no would-block retry here and failures are already logged.
read = this->noise_read_data_(buf, requested);
if (read <= 0) {
if (this->remote_closed_)
this->log_remote_closed_(LOG_STR("data"));
error_code = ota::OTA_RESPONSE_ERROR_UNKNOWN;
goto error; // NOLINT(cppcoreguidelines-avoid-goto)
}
@@ -666,7 +673,11 @@ bool ESPHomeOTAComponent::readall_(uint8_t *buf, size_t len) {
return false;
}
} else if (read == 0) {
ESP_LOGW(TAG, "Remote closed");
// A partial message is a cut-off request, not a clean close; the caller reports the clean one
this->remote_closed_ = at == 0;
if (at > 0) {
ESP_LOGW(TAG, "Remote closed after %u of %zu bytes", (unsigned) at, len);
}
return false;
} else {
at += read;
@@ -712,7 +723,22 @@ void ESPHomeOTAComponent::log_socket_error_(const LogString *msg) {
ESP_LOGW(TAG, "Socket %s: errno %d", LOG_STR_ARG(msg), errno);
}
void ESPHomeOTAComponent::log_read_error_(const LogString *what) { ESP_LOGW(TAG, "Read %s failed", LOG_STR_ARG(what)); }
bool ESPHomeOTAComponent::client_left_before_start_() {
// Key probes and scanners hang up right after the handshake; nothing started, so no error status or callback
if (!this->remote_closed_)
return false;
ESP_LOGD(TAG, "Client left after the handshake");
this->cleanup_connection_();
return true;
}
void ESPHomeOTAComponent::log_read_error_(const LogString *what) {
if (this->remote_closed_) {
this->log_remote_closed_(what);
return;
}
ESP_LOGW(TAG, "Read %s failed", LOG_STR_ARG(what));
}
void ESPHomeOTAComponent::log_start_(const LogString *phase) {
char peername[socket::SOCKADDR_STR_LEN];
@@ -793,6 +819,7 @@ void ESPHomeOTAComponent::cleanup_connection_() {
this->handshake_buf_pos_ = 0;
this->ota_state_ = OTAState::IDLE;
this->ota_features_ = 0;
this->remote_closed_ = false;
this->backend_ = nullptr;
#ifdef USE_OTA_PASSWORD
this->cleanup_auth_();
@@ -134,6 +134,7 @@ class ESPHomeOTAComponent final : public ota::OTAComponent {
void server_failed_(const LogString *msg);
void log_socket_error_(const LogString *msg);
void log_read_error_(const LogString *what);
bool client_left_before_start_();
void log_start_(const LogString *phase);
void log_remote_closed_(const LogString *during);
void cleanup_connection_();
@@ -186,6 +187,7 @@ class ESPHomeOTAComponent final : public ota::OTAComponent {
OTAState ota_state_{OTAState::IDLE};
uint8_t handshake_buf_pos_{0};
uint8_t ota_features_{0};
bool remote_closed_{false}; // the peer hung up cleanly during a blocking read
#ifdef USE_OTA_PASSWORD
uint8_t auth_buf_pos_{0};
uint8_t auth_type_{0}; // Store auth type to know which hasher to use
+12 -23
View File
@@ -53,12 +53,10 @@ from esphome.const import (
)
from esphome.core import (
CORE,
ID,
CoroPriority,
TimePeriodMilliseconds,
coroutine_with_priority,
)
from esphome.cpp_generator import MockObj, TemplateArgsType
import esphome.final_validate as fv
from esphome.types import ConfigType
@@ -924,24 +922,15 @@ def _filter_source_files() -> list[str]:
FILTER_SOURCE_FILES = _filter_source_files
async def _new_pvariable_to_code(
config: ConfigType,
id_: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
return cg.new_Pvariable(id_, template_arg)
for _name, _cls in (
("ethernet.connected", EthernetConnectedCondition),
("ethernet.enabled", EthernetEnabledCondition),
):
automation.register_condition(_name, _cls, cv.Schema({}))(_new_pvariable_to_code)
for _name, _cls in (
("ethernet.enable", EthernetEnableAction),
("ethernet.disable", EthernetDisableAction),
):
automation.register_action(_name, _cls, cv.Schema({}), synchronous=True)(
_new_pvariable_to_code
)
automation.register_bare_condition(
"ethernet.connected", EthernetConnectedCondition, cv.Schema({})
)
automation.register_bare_condition(
"ethernet.enabled", EthernetEnabledCondition, cv.Schema({})
)
automation.register_bare_action(
"ethernet.enable", EthernetEnableAction, cv.Schema({}), synchronous=True
)
automation.register_bare_action(
"ethernet.disable", EthernetDisableAction, cv.Schema({}), synchronous=True
)
+6 -26
View File
@@ -80,72 +80,52 @@ EzoPMPArbitraryCommandAction = ezo_pmp_ns.class_(
)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.find",
EzoPMPFindAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_find_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.dose_continuously",
EzoPMPDoseContinuouslyAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_dose_continuously_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.clear_total_volume_dosed",
EzoPMPClearTotalVolumeDispensedAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_clear_total_volume_dosed_to_code(
config, action_id, template_arg, args
):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.clear_calibration",
EzoPMPClearCalibrationAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_clear_calibration_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.pause_dosing",
EzoPMPPauseDosingAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_pause_dosing_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
automation.register_simple_action(
"ezo_pmp.stop_dosing",
EzoPMPStopDosingAction,
EZO_PMP_NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def ezo_pmp_stop_dosing_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
# Actions that require Multiple Args
+2 -17
View File
@@ -61,8 +61,6 @@ RESTORE_MODES = {
}
# Actions
TurnOffAction = fan_ns.class_("TurnOffAction", automation.Action)
ToggleAction = fan_ns.class_("ToggleAction", automation.Action)
CycleSpeedAction = fan_ns.class_("CycleSpeedAction", automation.Action)
FanStateTrigger = fan_ns.class_(
@@ -310,21 +308,8 @@ FAN_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
"fan.toggle", ToggleAction, FAN_ACTION_SCHEMA, synchronous=True
)
async def fan_toggle_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"fan.turn_off", TurnOffAction, FAN_ACTION_SCHEMA, synchronous=True
)
async def fan_turn_off_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
automation.register_apply_action("fan.toggle", FAN_ACTION_SCHEMA, call="toggle")
automation.register_apply_action("fan.turn_off", FAN_ACTION_SCHEMA, call="turn_off")
automation.register_apply_action(
"fan.turn_on",
-18
View File
@@ -6,24 +6,6 @@
namespace esphome::fan {
template<typename... Ts> class TurnOffAction final : public Action<Ts...> {
public:
explicit TurnOffAction(Fan *state) : state_(state) {}
void play(const Ts &...x) override { this->state_->turn_off().perform(); }
Fan *state_;
};
template<typename... Ts> class ToggleAction final : public Action<Ts...> {
public:
explicit ToggleAction(Fan *state) : state_(state) {}
void play(const Ts &...x) override { this->state_->toggle().perform(); }
Fan *state_;
};
template<typename... Ts> class CycleSpeedAction final : public Action<Ts...> {
public:
explicit CycleSpeedAction(Fan *state) : state_(state) {}
@@ -206,7 +206,7 @@ async def fingerprint_grow_enroll_to_code(config, action_id, template_arg, args)
return var
@automation.register_action(
automation.register_parented_action(
"fingerprint_grow.cancel_enroll",
CancelEnrollmentAction,
cv.Schema(
@@ -216,10 +216,6 @@ async def fingerprint_grow_enroll_to_code(config, action_id, template_arg, args)
),
synchronous=True,
)
async def fingerprint_grow_cancel_enroll_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
@@ -243,7 +239,7 @@ async def fingerprint_grow_delete_to_code(config, action_id, template_arg, args)
return var
@automation.register_action(
automation.register_parented_action(
"fingerprint_grow.delete_all",
DeleteAllAction,
cv.Schema(
@@ -253,10 +249,6 @@ async def fingerprint_grow_delete_to_code(config, action_id, template_arg, args)
),
synchronous=True,
)
async def fingerprint_grow_delete_all_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
FINGERPRINT_GROW_LED_CONTROL_ACTION_SCHEMA = cv.maybe_simple_value(
+2 -12
View File
@@ -126,7 +126,7 @@ async def grove_tb6612fng_stop_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
automation.register_parented_action(
"grove_tb6612fng.standby",
GROVETB6612FNGMotorStandbyAction,
cv.Schema(
@@ -136,14 +136,9 @@ async def grove_tb6612fng_stop_to_code(config, action_id, template_arg, args):
),
synchronous=True,
)
async def grove_tb6612fng_standby_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"grove_tb6612fng.no_standby",
GROVETB6612FNGMotorNoStandbyAction,
cv.Schema(
@@ -153,11 +148,6 @@ async def grove_tb6612fng_standby_to_code(config, action_id, template_arg, args)
),
synchronous=True,
)
async def grove_tb6612fng_no_standby_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
-128
View File
@@ -1,128 +0,0 @@
#pragma once
#include "esphome/core/automation.h"
#include "haier_base.h"
#include "hon_climate.h"
namespace esphome::haier {
template<typename... Ts> class DisplayOnAction final : public Action<Ts...> {
public:
DisplayOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_display_state(true); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class DisplayOffAction final : public Action<Ts...> {
public:
DisplayOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_display_state(false); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class BeeperOnAction final : public Action<Ts...> {
public:
BeeperOnAction(HonClimate *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_beeper_state(true); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class BeeperOffAction final : public Action<Ts...> {
public:
BeeperOffAction(HonClimate *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_beeper_state(false); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class VerticalAirflowAction final : public Action<Ts...> {
public:
VerticalAirflowAction(HonClimate *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(hon_protocol::VerticalSwingMode, direction)
void play(const Ts &...x) { this->parent_->set_vertical_airflow(this->direction_.value(x...)); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class HorizontalAirflowAction final : public Action<Ts...> {
public:
HorizontalAirflowAction(HonClimate *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(hon_protocol::HorizontalSwingMode, direction)
void play(const Ts &...x) { this->parent_->set_horizontal_airflow(this->direction_.value(x...)); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class HealthOnAction final : public Action<Ts...> {
public:
HealthOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_health_mode(true); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class HealthOffAction final : public Action<Ts...> {
public:
HealthOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->set_health_mode(false); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class StartSelfCleaningAction final : public Action<Ts...> {
public:
StartSelfCleaningAction(HonClimate *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->start_self_cleaning(); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class StartSteriCleaningAction final : public Action<Ts...> {
public:
StartSteriCleaningAction(HonClimate *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->start_steri_cleaning(); }
protected:
HonClimate *parent_;
};
template<typename... Ts> class PowerOnAction final : public Action<Ts...> {
public:
PowerOnAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->send_power_on_command(); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class PowerOffAction final : public Action<Ts...> {
public:
PowerOffAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->send_power_off_command(); }
protected:
HaierClimateBase *parent_;
};
template<typename... Ts> class PowerToggleAction final : public Action<Ts...> {
public:
PowerToggleAction(HaierClimateBase *parent) : parent_(parent) {}
void play(const Ts &...x) { this->parent_->toggle_power(); }
protected:
HaierClimateBase *parent_;
};
} // namespace esphome::haier
+34 -134
View File
@@ -9,7 +9,6 @@ from esphome.const import (
CONF_BEEPER,
CONF_CURRENT_TEMPERATURE,
CONF_DISPLAY,
CONF_ID,
CONF_LEVEL,
CONF_LOGGER,
CONF_LOGS,
@@ -254,23 +253,6 @@ CONFIG_SCHEMA = cv.All(
)
# Actions
DisplayOnAction = haier_ns.class_("DisplayOnAction", automation.Action)
DisplayOffAction = haier_ns.class_("DisplayOffAction", automation.Action)
BeeperOnAction = haier_ns.class_("BeeperOnAction", automation.Action)
BeeperOffAction = haier_ns.class_("BeeperOffAction", automation.Action)
StartSelfCleaningAction = haier_ns.class_("StartSelfCleaningAction", automation.Action)
StartSteriCleaningAction = haier_ns.class_(
"StartSteriCleaningAction", automation.Action
)
VerticalAirflowAction = haier_ns.class_("VerticalAirflowAction", automation.Action)
HorizontalAirflowAction = haier_ns.class_("HorizontalAirflowAction", automation.Action)
HealthOnAction = haier_ns.class_("HealthOnAction", automation.Action)
HealthOffAction = haier_ns.class_("HealthOffAction", automation.Action)
PowerOnAction = haier_ns.class_("PowerOnAction", automation.Action)
PowerOffAction = haier_ns.class_("PowerOffAction", automation.Action)
PowerToggleAction = haier_ns.class_("PowerToggleAction", automation.Action)
HAIER_BASE_ACTION_SCHEMA = automation.maybe_simple_id(
{
cv.GenerateID(): cv.use_id(HaierClimateBase),
@@ -284,62 +266,35 @@ HAIER_HON_BASE_ACTION_SCHEMA = automation.maybe_simple_id(
)
@automation.register_action(
"climate.haier.display_on",
DisplayOnAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.display_off",
DisplayOffAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
async def display_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
for _name, _schema, _call in (
("climate.haier.display_on", HAIER_BASE_ACTION_SCHEMA, "set_display_state(true)"),
("climate.haier.display_off", HAIER_BASE_ACTION_SCHEMA, "set_display_state(false)"),
("climate.haier.beeper_on", HAIER_HON_BASE_ACTION_SCHEMA, "set_beeper_state(true)"),
(
"climate.haier.beeper_off",
HAIER_HON_BASE_ACTION_SCHEMA,
"set_beeper_state(false)",
),
(
"climate.haier.start_self_cleaning",
HAIER_HON_BASE_ACTION_SCHEMA,
"start_self_cleaning()",
),
(
"climate.haier.start_steri_cleaning",
HAIER_HON_BASE_ACTION_SCHEMA,
"start_steri_cleaning()",
),
("climate.haier.health_on", HAIER_BASE_ACTION_SCHEMA, "set_health_mode(true)"),
("climate.haier.health_off", HAIER_BASE_ACTION_SCHEMA, "set_health_mode(false)"),
("climate.haier.power_on", HAIER_BASE_ACTION_SCHEMA, "send_power_on_command()"),
("climate.haier.power_off", HAIER_BASE_ACTION_SCHEMA, "send_power_off_command()"),
("climate.haier.power_toggle", HAIER_BASE_ACTION_SCHEMA, "toggle_power()"),
):
automation.register_apply_action(_name, _schema, automation.ApplyCall(_call))
@automation.register_action(
"climate.haier.beeper_on",
BeeperOnAction,
HAIER_HON_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.beeper_off",
BeeperOffAction,
HAIER_HON_BASE_ACTION_SCHEMA,
synchronous=True,
)
async def beeper_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
# Start self cleaning or steri-cleaning action action
@automation.register_action(
"climate.haier.start_self_cleaning",
StartSelfCleaningAction,
HAIER_HON_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.start_steri_cleaning",
StartSteriCleaningAction,
HAIER_HON_BASE_ACTION_SCHEMA,
synchronous=True,
)
async def start_cleaning_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
# Set vertical airflow direction action
@automation.register_action(
automation.register_apply_action(
"climate.haier.set_vertical_airflow",
VerticalAirflowAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(HonClimate),
@@ -348,22 +303,13 @@ async def start_cleaning_to_code(config, action_id, template_arg, args):
),
}
),
synchronous=True,
automation.ApplyField(
CONF_VERTICAL_AIRFLOW, "set_vertical_airflow", AirflowVerticalDirection
),
)
async def haier_set_vertical_airflow_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(
config[CONF_VERTICAL_AIRFLOW], args, AirflowVerticalDirection
)
cg.add(var.set_direction(template_))
return var
# Set horizontal airflow direction action
@automation.register_action(
automation.register_apply_action(
"climate.haier.set_horizontal_airflow",
HorizontalAirflowAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(HonClimate),
@@ -372,56 +318,10 @@ async def haier_set_vertical_airflow_to_code(config, action_id, template_arg, ar
),
}
),
synchronous=True,
automation.ApplyField(
CONF_HORIZONTAL_AIRFLOW, "set_horizontal_airflow", AirflowHorizontalDirection
),
)
async def haier_set_horizontal_airflow_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(
config[CONF_HORIZONTAL_AIRFLOW], args, AirflowHorizontalDirection
)
cg.add(var.set_direction(template_))
return var
@automation.register_action(
"climate.haier.health_on",
HealthOnAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.health_off",
HealthOffAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
async def health_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"climate.haier.power_on",
PowerOnAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.power_off",
PowerOffAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"climate.haier.power_toggle",
PowerToggleAction,
HAIER_BASE_ACTION_SCHEMA,
synchronous=True,
)
async def power_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
def _final_validate(config) -> None:
+1 -12
View File
@@ -7,14 +7,11 @@ import esphome.config_validation as cv
from esphome.const import (
CONF_DECAY_MODE,
CONF_ENABLE_PIN,
CONF_ID,
CONF_PIN_A,
CONF_PIN_B,
CONF_PRESET_MODES,
CONF_SPEED_COUNT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
from .. import hbridge_ns
@@ -51,20 +48,12 @@ CONFIG_SCHEMA = (
)
@automation.register_action(
automation.register_simple_action(
"fan.hbridge.brake",
BrakeAction,
maybe_simple_id({cv.GenerateID(): cv.use_id(HBridgeFan)}),
synchronous=True,
)
async def fan_hbridge_brake_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
async def to_code(config: ConfigType) -> None:
+1 -10
View File
@@ -139,18 +139,9 @@ async def hdc302x_heater_on_to_code(
return var
@automation.register_action(
automation.register_parented_action(
"hdc302x.heater_off",
HeaterOffAction,
HDC302X_ACTION_SCHEMA,
synchronous=True,
)
async def hdc302x_heater_off_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+1 -10
View File
@@ -106,7 +106,7 @@ async def to_code(config: ConfigType) -> None:
cg.add(var.set_restore(config[CONF_RESTORE]))
@automation.register_action(
automation.register_parented_action(
"sensor.integration.reset",
ResetAction,
automation.maybe_simple_id(
@@ -116,15 +116,6 @@ async def to_code(config: ConfigType) -> None:
),
synchronous=True,
)
async def sensor_integration_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
+2 -21
View File
@@ -15,7 +15,6 @@ from esphome.const import (
CONF_TIMEOUT,
CONF_TRIGGER_ID,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, literal
from esphome.types import ConfigType, TemplateArgsType
@@ -135,7 +134,7 @@ async def to_code(config: ConfigType) -> None:
cg.add(var.set_enabled(config[CONF_ENABLE_ON_BOOT]))
@automation.register_action(
automation.register_parented_action(
"key_collector.enable",
EnableAction,
automation.maybe_simple_id(
@@ -145,18 +144,9 @@ async def to_code(config: ConfigType) -> None:
),
synchronous=True,
)
async def enable_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"key_collector.disable",
DisableAction,
automation.maybe_simple_id(
@@ -166,12 +156,3 @@ async def enable_to_code(
),
synchronous=True,
)
async def disable_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+10 -22
View File
@@ -12,13 +12,13 @@ from esphome.const import (
CONF_ON_UNLOCK,
CONF_WEB_SERVER,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.entity_helpers import (
entity_duplicate_validator,
queue_entity_register,
setup_entity,
)
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
from esphome.cpp_generator import MockObj, MockObjClass
from esphome.types import ConfigType, SafeExpType
CODEOWNERS = ["@esphome/core"]
@@ -29,9 +29,6 @@ Lock = lock_ns.class_("Lock", cg.EntityBase)
LockPtr = Lock.operator("ptr")
LockCall = lock_ns.class_("LockCall")
UnlockAction = lock_ns.class_("UnlockAction", automation.Action)
LockAction = lock_ns.class_("LockAction", automation.Action)
OpenAction = lock_ns.class_("OpenAction", automation.Action)
LockPublishAction = lock_ns.class_("LockPublishAction", automation.Action)
LockStateForwarder = lock_ns.class_("LockStateForwarder")
@@ -134,23 +131,14 @@ LOCK_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
"lock.unlock", UnlockAction, LOCK_ACTION_SCHEMA, synchronous=True
)
@automation.register_action(
"lock.lock", LockAction, LOCK_ACTION_SCHEMA, synchronous=True
)
@automation.register_action(
"lock.open", OpenAction, LOCK_ACTION_SCHEMA, synchronous=True
)
async def lock_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
for _name, _call in (
("lock.unlock", "unlock()"),
("lock.lock", "lock()"),
("lock.open", "open()"),
):
automation.register_apply_action(
_name, LOCK_ACTION_SCHEMA, automation.ApplyCall(_call)
)
automation.register_apply_condition(
-30
View File
@@ -6,36 +6,6 @@
namespace esphome::lock {
template<typename... Ts> class LockAction final : public Action<Ts...> {
public:
explicit LockAction(Lock *a_lock) : lock_(a_lock) {}
void play(const Ts &...x) override { this->lock_->lock(); }
protected:
Lock *lock_;
};
template<typename... Ts> class UnlockAction final : public Action<Ts...> {
public:
explicit UnlockAction(Lock *a_lock) : lock_(a_lock) {}
void play(const Ts &...x) override { this->lock_->unlock(); }
protected:
Lock *lock_;
};
template<typename... Ts> class OpenAction final : public Action<Ts...> {
public:
explicit OpenAction(Lock *a_lock) : lock_(a_lock) {}
void play(const Ts &...x) override { this->lock_->open(); }
protected:
Lock *lock_;
};
/// Callback forwarder that triggers an Automation<> only when a specific lock state is entered.
/// Pointer-sized (single Automation* field) to fit inline in Callback::ctx_.
template<LockState State> struct LockStateForwarder {
+5 -12
View File
@@ -14,8 +14,6 @@ from esphome.const import (
UNIT_PERCENT,
UNIT_VOLT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
DEPENDENCIES = ["i2c"]
@@ -74,14 +72,9 @@ MAX17043_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
"max17043.sleep_mode", SleepAction, MAX17043_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"max17043.sleep_mode",
SleepAction,
MAX17043_ACTION_SCHEMA,
synchronous=True,
)
async def max17043_sleep_mode_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+8 -9
View File
@@ -18,19 +18,18 @@ void MCP3204::dump_config() {
}
float MCP3204::read_data(uint8_t pin, bool differential) {
uint8_t command, b0, b1;
command = (1 << 6) | // start bit
((differential ? 0 : 1) << 5) | // single or differential bit
((pin & 0x07) << 2); // pin
const uint8_t command = (1 << 6) | // start bit
((differential ? 0 : 1) << 5) | // single or differential bit
((pin & 0x07) << 2); // pin
// One full-duplex transaction: command out, 12-bit result back in bytes 1 and 2.
// Word aligned so ESP-IDF DMA uses the buffer in place; only ESP32-P4 also checks the length and bounces.
alignas(4) uint8_t buffer[3] = {command, 0x00, 0x00};
this->enable();
this->transfer_byte(command);
b0 = this->transfer_byte(0x00);
b1 = this->transfer_byte(0x00);
this->transfer_array(buffer, sizeof(buffer));
this->disable();
uint16_t digital_value = encode_uint16(b0, b1) >> 4;
uint16_t digital_value = encode_uint16(buffer[1], buffer[2]) >> 4;
return float(digital_value) / 4096.000f * this->reference_voltage_; // in V
}
+14 -22
View File
@@ -144,36 +144,28 @@ TERMINAL_ACTION_SCHEMA = cv.Schema(
)
@automation.register_action(
"mcp4461.wiper.increase", WiperIncreaseAction, WIPER_ACTION_SCHEMA, synchronous=True
automation.register_simple_action(
"mcp4461.wiper.increase",
WiperIncreaseAction,
WIPER_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"mcp4461.wiper.decrease", WiperDecreaseAction, WIPER_ACTION_SCHEMA, synchronous=True
)
async def mcp4461_wiper_step_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
wiper = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, wiper)
@automation.register_action(
automation.register_simple_action(
"mcp4461.wiper.decrease",
WiperDecreaseAction,
WIPER_ACTION_SCHEMA,
synchronous=True,
)
automation.register_simple_action(
"mcp4461.wiper.store_nonvolatile",
WiperStoreNonvolatileAction,
WIPER_ACTION_SCHEMA,
synchronous=True,
)
async def mcp4461_wiper_store_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
wiper = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, wiper)
@automation.register_action(
+7 -12
View File
@@ -122,33 +122,28 @@ NO_ARGS_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"mhz19.calibrate_zero",
MHZ19CalibrateZeroAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"mhz19.abc_enable",
MHZ19ABCEnableAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"mhz19.abc_disable",
MHZ19ABCDisableAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def mhz19_no_args_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
RANGE_ACTION_SCHEMA = maybe_simple_id(
+14 -36
View File
@@ -6,7 +6,6 @@ import re
from urllib.parse import urljoin
from esphome import automation, external_files, git
from esphome.automation import register_action, register_condition
from esphome.bundle import add_bundle_file
import esphome.codegen as cg
from esphome.components import esp32, microphone, ota, psram
@@ -58,17 +57,6 @@ micro_wake_word_ns = cg.esphome_ns.namespace("micro_wake_word")
MicroWakeWord = micro_wake_word_ns.class_("MicroWakeWord", cg.Component)
DisableModelAction = micro_wake_word_ns.class_("DisableModelAction", automation.Action)
EnableModelAction = micro_wake_word_ns.class_("EnableModelAction", automation.Action)
StartAction = micro_wake_word_ns.class_("StartAction", automation.Action)
StopAction = micro_wake_word_ns.class_("StopAction", automation.Action)
ModelIsEnabledCondition = micro_wake_word_ns.class_(
"ModelIsEnabledCondition", automation.Condition
)
IsRunningCondition = micro_wake_word_ns.class_(
"IsRunningCondition", automation.Condition
)
WakeWordModel = micro_wake_word_ns.class_("WakeWordModel")
@@ -619,23 +607,19 @@ async def to_code(config):
MICRO_WAKE_WORD_ACTION_SCHEMA = cv.Schema({cv.GenerateID(): cv.use_id(MicroWakeWord)})
@register_action(
automation.register_apply_action(
"micro_wake_word.start",
StartAction,
MICRO_WAKE_WORD_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("start()"),
)
@register_action(
"micro_wake_word.stop", StopAction, MICRO_WAKE_WORD_ACTION_SCHEMA, synchronous=True
automation.register_apply_action(
"micro_wake_word.stop",
MICRO_WAKE_WORD_ACTION_SCHEMA,
automation.ApplyCall("stop()"),
)
@register_condition(
"micro_wake_word.is_running", IsRunningCondition, MICRO_WAKE_WORD_ACTION_SCHEMA
automation.register_apply_condition(
"micro_wake_word.is_running", MICRO_WAKE_WORD_ACTION_SCHEMA, "is_running()"
)
async def micro_wake_word_action_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
MICRO_WAKE_WORLD_MODEL_ACTION_SCHEMA = automation.maybe_simple_id(
@@ -644,24 +628,18 @@ MICRO_WAKE_WORLD_MODEL_ACTION_SCHEMA = automation.maybe_simple_id(
}
)
@register_action(
automation.register_apply_action(
"micro_wake_word.enable_model",
EnableModelAction,
MICRO_WAKE_WORLD_MODEL_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("enable()"),
)
@register_action(
automation.register_apply_action(
"micro_wake_word.disable_model",
DisableModelAction,
MICRO_WAKE_WORLD_MODEL_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("disable()"),
)
@register_condition(
automation.register_apply_condition(
"micro_wake_word.model_is_enabled",
ModelIsEnabledCondition,
MICRO_WAKE_WORLD_MODEL_ACTION_SCHEMA,
"is_enabled()",
)
async def model_action(config, action_id, template_arg, args):
parent = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, parent)
@@ -1,54 +0,0 @@
#pragma once
#include "micro_wake_word.h"
#include "streaming_model.h"
#ifdef USE_ESP32
namespace esphome::micro_wake_word {
template<typename... Ts> class StartAction final : public Action<Ts...>, public Parented<MicroWakeWord> {
public:
void play(const Ts &...x) override { this->parent_->start(); }
};
template<typename... Ts> class StopAction final : public Action<Ts...>, public Parented<MicroWakeWord> {
public:
void play(const Ts &...x) override { this->parent_->stop(); }
};
template<typename... Ts> class IsRunningCondition final : public Condition<Ts...>, public Parented<MicroWakeWord> {
public:
bool check(const Ts &...x) override { return this->parent_->is_running(); }
};
template<typename... Ts> class EnableModelAction final : public Action<Ts...> {
public:
explicit EnableModelAction(WakeWordModel *wake_word_model) : wake_word_model_(wake_word_model) {}
void play(const Ts &...x) override { this->wake_word_model_->enable(); }
protected:
WakeWordModel *wake_word_model_;
};
template<typename... Ts> class DisableModelAction final : public Action<Ts...> {
public:
explicit DisableModelAction(WakeWordModel *wake_word_model) : wake_word_model_(wake_word_model) {}
void play(const Ts &...x) override { this->wake_word_model_->disable(); }
protected:
WakeWordModel *wake_word_model_;
};
template<typename... Ts> class ModelIsEnabledCondition final : public Condition<Ts...> {
public:
explicit ModelIsEnabledCondition(WakeWordModel *wake_word_model) : wake_word_model_(wake_word_model) {}
bool check(const Ts &...x) override { return this->wake_word_model_->is_enabled(); }
protected:
WakeWordModel *wake_word_model_;
};
} // namespace esphome::micro_wake_word
#endif
+17 -58
View File
@@ -14,9 +14,9 @@ from esphome.const import (
CONF_ON_DATA,
CONF_TRIGGER_ID,
)
from esphome.core import CORE, ID
from esphome.core import CORE
from esphome.coroutine import CoroPriority, coroutine_with_priority
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.cpp_generator import MockObj
from esphome.types import ConfigType
AUTO_LOAD = ["audio"]
@@ -29,30 +29,11 @@ microphone_ns = cg.esphome_ns.namespace("microphone")
Microphone = microphone_ns.class_("Microphone")
MicrophoneSource = microphone_ns.class_("MicrophoneSource")
CaptureAction = microphone_ns.class_(
"CaptureAction", automation.Action, cg.Parented.template(Microphone)
)
StopCaptureAction = microphone_ns.class_(
"StopCaptureAction", automation.Action, cg.Parented.template(Microphone)
)
MuteAction = microphone_ns.class_(
"MuteAction", automation.Action, cg.Parented.template(Microphone)
)
UnmuteAction = microphone_ns.class_(
"UnmuteAction", automation.Action, cg.Parented.template(Microphone)
)
DataTrigger = microphone_ns.class_(
"DataTrigger",
automation.Trigger.template(cg.std_vector.template(cg.uint8).operator("ref")),
)
IsCapturingCondition = microphone_ns.class_(
"IsCapturingCondition", automation.Condition
)
IsMutedCondition = microphone_ns.class_("IsMutedCondition", automation.Condition)
async def setup_microphone_core_(var: MockObj, config: ConfigType) -> None:
for conf in config.get(CONF_ON_DATA, []):
@@ -189,44 +170,22 @@ async def microphone_source_to_code(
return mic_source
async def microphone_action(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
for _name, _call in (
("microphone.capture", "start()"),
("microphone.stop_capture", "stop()"),
("microphone.mute", "set_mute_state(true)"),
("microphone.unmute", "set_mute_state(false)"),
):
automation.register_apply_action(
_name, MICROPHONE_ACTION_SCHEMA, automation.ApplyCall(_call)
)
automation.register_action(
"microphone.capture",
CaptureAction,
MICROPHONE_ACTION_SCHEMA,
synchronous=True,
)(microphone_action)
automation.register_action(
"microphone.stop_capture",
StopCaptureAction,
MICROPHONE_ACTION_SCHEMA,
synchronous=True,
)(microphone_action)
automation.register_action(
"microphone.mute", MuteAction, MICROPHONE_ACTION_SCHEMA, synchronous=True
)(microphone_action)
automation.register_action(
"microphone.unmute", UnmuteAction, MICROPHONE_ACTION_SCHEMA, synchronous=True
)(microphone_action)
automation.register_condition(
"microphone.is_capturing", IsCapturingCondition, MICROPHONE_ACTION_SCHEMA
)(microphone_action)
automation.register_condition(
"microphone.is_muted", IsMutedCondition, MICROPHONE_ACTION_SCHEMA
)(microphone_action)
automation.register_apply_condition(
"microphone.is_capturing", MICROPHONE_ACTION_SCHEMA, "is_running()"
)
automation.register_apply_condition(
"microphone.is_muted", MICROPHONE_ACTION_SCHEMA, "get_mute_state()"
)
@coroutine_with_priority(CoroPriority.CORE)
@@ -7,21 +7,6 @@
namespace esphome::microphone {
template<typename... Ts> class CaptureAction final : public Action<Ts...>, public Parented<Microphone> {
void play(const Ts &...x) override { this->parent_->start(); }
};
template<typename... Ts> class StopCaptureAction final : public Action<Ts...>, public Parented<Microphone> {
void play(const Ts &...x) override { this->parent_->stop(); }
};
template<typename... Ts> class MuteAction final : public Action<Ts...>, public Parented<Microphone> {
void play(const Ts &...x) override { this->parent_->set_mute_state(true); }
};
template<typename... Ts> class UnmuteAction final : public Action<Ts...>, public Parented<Microphone> {
void play(const Ts &...x) override { this->parent_->set_mute_state(false); }
};
class DataTrigger final : public Trigger<const std::vector<uint8_t> &> {
public:
explicit DataTrigger(Microphone *mic) {
@@ -29,14 +14,4 @@ class DataTrigger final : public Trigger<const std::vector<uint8_t> &> {
}
};
template<typename... Ts> class IsCapturingCondition final : public Condition<Ts...>, public Parented<Microphone> {
public:
bool check(const Ts &...x) override { return this->parent_->is_running(); }
};
template<typename... Ts> class IsMutedCondition final : public Condition<Ts...>, public Parented<Microphone> {
public:
bool check(const Ts &...x) override { return this->parent_->get_mute_state(); }
};
} // namespace esphome::microphone
@@ -162,21 +162,12 @@ async def remote_temperature_action_to_code(
return var
@automation.register_action(
automation.register_parented_action(
f"{DOMAIN}.clear_remote_temperature",
ClearRemoteTemperatureAction,
CLEAR_REMOTE_TEMPERATURE_ACTION_SCHEMA,
synchronous=True,
)
async def clear_temperature_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
VANE_CONTROL_ACTION_SCHEMA = cv.Schema(
+29 -46
View File
@@ -117,10 +117,7 @@ mqtt_ns = cg.esphome_ns.namespace("mqtt")
MQTTMessage = mqtt_ns.struct("MQTTMessage")
MQTTClientDisconnectReason = mqtt_ns.enum("MQTTClientDisconnectReason")
MQTTClientComponent = mqtt_ns.class_("MQTTClientComponent", cg.Component)
MQTTPublishAction = mqtt_ns.class_("MQTTPublishAction", automation.Action)
MQTTPublishJsonAction = mqtt_ns.class_("MQTTPublishJsonAction", automation.Action)
MQTTEnableAction = mqtt_ns.class_("MQTTEnableAction", automation.Action)
MQTTDisableAction = mqtt_ns.class_("MQTTDisableAction", automation.Action)
MQTTMessageTrigger = mqtt_ns.class_(
"MQTTMessageTrigger", automation.Trigger.template(cg.std_string), cg.Component
)
@@ -503,22 +500,26 @@ MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema(
)
@automation.register_action(
"mqtt.publish", MQTTPublishAction, MQTT_PUBLISH_ACTION_SCHEMA, synchronous=True
)
async def mqtt_publish_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(config[CONF_TOPIC], args, cg.std_string)
cg.add(var.set_topic(template_))
# A bare literal is ambiguous between the std::string and (const char *, size_t) publish
# overloads, so constants and inlined `return "...";` lambdas are both spelled as std::string.
def _std_string(config: ConfigType, value: str) -> str:
rendered = automation.flash_string(config, value)
return rendered if CORE.is_esp8266 else f"std::string({rendered})"
template_ = await cg.templatable(config[CONF_PAYLOAD], args, cg.std_string)
cg.add(var.set_payload(template_))
template_ = await cg.templatable(config[CONF_QOS], args, cg.uint8)
cg.add(var.set_qos(template_))
template_ = await cg.templatable(config[CONF_RETAIN], args, cg.bool_)
cg.add(var.set_retain(template_))
return var
automation.register_apply_action(
"mqtt.publish",
MQTT_PUBLISH_ACTION_SCHEMA,
automation.ApplyCall(
"publish({}, {}, {}, {})",
(
(CONF_TOPIC, "std::string", _std_string),
(CONF_PAYLOAD, "std::string", _std_string),
(CONF_QOS, cg.uint8),
(CONF_RETAIN, cg.bool_),
),
),
)
MQTT_PUBLISH_JSON_ACTION_SCHEMA = cv.Schema(
@@ -608,34 +609,16 @@ automation.register_apply_condition(
)
@automation.register_action(
"mqtt.enable",
MQTTEnableAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(MQTTClientComponent),
}
),
synchronous=True,
)
async def mqtt_enable_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"mqtt.disable",
MQTTDisableAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(MQTTClientComponent),
}
),
synchronous=True,
)
async def mqtt_disable_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
for _name, _call in (("mqtt.enable", "enable()"), ("mqtt.disable", "disable()")):
automation.register_apply_action(
_name,
cv.Schema(
{
cv.GenerateID(): cv.use_id(MQTTClientComponent),
}
),
automation.ApplyCall(_call),
)
_platform_filter = filter_source_files_from_platform(
-37
View File
@@ -378,23 +378,6 @@ class MQTTDisconnectTrigger final : public Trigger<MQTTClientDisconnectReason> {
}
};
template<typename... Ts> class MQTTPublishAction final : public Action<Ts...> {
public:
MQTTPublishAction(MQTTClientComponent *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(std::string, topic)
TEMPLATABLE_VALUE(std::string, payload)
TEMPLATABLE_VALUE(uint8_t, qos)
TEMPLATABLE_VALUE(bool, retain)
void play(const Ts &...x) override {
this->parent_->publish(this->topic_.value(x...), this->payload_.value(x...), this->qos_.value(x...),
this->retain_.value(x...));
}
protected:
MQTTClientComponent *parent_;
};
template<typename... Ts> class MQTTPublishJsonAction final : public Action<Ts...> {
public:
MQTTPublishJsonAction(MQTTClientComponent *parent) : parent_(parent) {}
@@ -417,26 +400,6 @@ template<typename... Ts> class MQTTPublishJsonAction final : public Action<Ts...
MQTTClientComponent *parent_;
};
template<typename... Ts> class MQTTEnableAction final : public Action<Ts...> {
public:
MQTTEnableAction(MQTTClientComponent *parent) : parent_(parent) {}
void play(const Ts &...x) override { this->parent_->enable(); }
protected:
MQTTClientComponent *parent_;
};
template<typename... Ts> class MQTTDisableAction final : public Action<Ts...> {
public:
MQTTDisableAction(MQTTClientComponent *parent) : parent_(parent) {}
void play(const Ts &...x) override { this->parent_->disable(); }
protected:
MQTTClientComponent *parent_;
};
} // namespace esphome::mqtt
#endif // USE_MQTT
+7 -14
View File
@@ -4,8 +4,6 @@ import esphome.codegen as cg
from esphome.components import i2c, sensor
import esphome.config_validation as cv
from esphome.const import CONF_GAIN, CONF_ID, ICON_SCALE, STATE_CLASS_MEASUREMENT
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@cujomalainey"]
@@ -116,30 +114,25 @@ NAU7802_CALIBRATE_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"nau7802.calibrate_internal_offset",
NAU7802CalbrateInternalOffsetAction,
NAU7802_CALIBRATE_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"nau7802.calibrate_external_offset",
NAU7802CalbrateExternalOffsetAction,
NAU7802_CALIBRATE_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"nau7802.calibrate_gain",
NAU7802CalbrateGainAction,
NAU7802_CALIBRATE_SCHEMA,
synchronous=True,
)
async def nau7802_calibrate_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
-2
View File
@@ -614,7 +614,6 @@ class Nextion final : public NextionBase, public PollingComponent, public uart::
*/
void disable_component_touch(const char *component);
#ifdef USE_NEXTION_WAVEFORM
/**
* Add waveform data to a waveform component
* @param component_id The integer component id.
@@ -624,7 +623,6 @@ class Nextion final : public NextionBase, public PollingComponent, public uart::
void add_waveform_data(uint8_t component_id, uint8_t channel_number, uint8_t value);
void open_waveform_channel(uint8_t component_id, uint8_t channel_number, uint8_t value);
#endif // USE_NEXTION_WAVEFORM
/**
* Display a picture at coordinates.
@@ -217,7 +217,6 @@ void Nextion::set_component_value(const char *component, int32_t value) {
this->add_no_result_to_queue_with_printf_(".val", "%s.val=%" PRId32, component, value);
}
#ifdef USE_NEXTION_WAVEFORM
void Nextion::add_waveform_data(uint8_t component_id, uint8_t channel_number, uint8_t value) {
this->add_no_result_to_queue_with_printf_("add", "add %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id, channel_number,
value);
@@ -227,7 +226,6 @@ void Nextion::open_waveform_channel(uint8_t component_id, uint8_t channel_number
this->add_no_result_to_queue_with_printf_("addt", "addt %" PRIu8 ",%" PRIu8 ",%" PRIu8, component_id, channel_number,
value);
}
#endif // USE_NEXTION_WAVEFORM
void Nextion::set_component_coordinates(const char *component, uint16_t x, uint16_t y) {
this->add_no_result_to_queue_with_printf_(".xcen", "%s.xcen=%" PRIu16, component, x);
@@ -95,6 +95,7 @@ NoiseResponderHandshake::Action NoiseResponderHandshake::action() const {
}
int NoiseResponderHandshake::read_message(uint8_t *data, size_t len) {
CpuFrequencyBoost boost;
NoiseBuffer mbuf;
noise_buffer_init(mbuf);
noise_buffer_set_input(mbuf, data, len);
@@ -103,6 +104,7 @@ int NoiseResponderHandshake::read_message(uint8_t *data, size_t len) {
int NoiseResponderHandshake::write_message(uint8_t *out, size_t capacity, size_t &out_len) {
out_len = 0;
CpuFrequencyBoost boost;
NoiseBuffer mbuf;
noise_buffer_init(mbuf);
noise_buffer_set_output(mbuf, out, capacity);
+1
View File
@@ -28,6 +28,7 @@ void DeviceFirmwareUpdate::setup() {
this->reset_pin_->digital_write(true);
} else {
NRF_POWER->GPREGRET = DFU_MAGIC_UF2_RESET;
arch_feed_wdt();
App.reboot();
}
}
+2 -22
View File
@@ -3,8 +3,6 @@ import esphome.codegen as cg
from esphome.components import i2c, time
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@brogon"]
@@ -24,7 +22,7 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
).extend(i2c.i2c_device_schema(0x51))
@automation.register_action(
automation.register_parented_action(
"pcf85063.write_time",
WriteAction,
cv.Schema(
@@ -34,18 +32,9 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
),
synchronous=True,
)
async def pcf85063_write_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"pcf85063.read_time",
ReadAction,
automation.maybe_simple_id(
@@ -55,15 +44,6 @@ async def pcf85063_write_time_to_code(
),
synchronous=True,
)
async def pcf85063_read_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+2 -22
View File
@@ -3,8 +3,6 @@ import esphome.codegen as cg
from esphome.components import i2c, time
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@KoenBreeman"]
@@ -27,7 +25,7 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
).extend(i2c.i2c_device_schema(0x51))
@automation.register_action(
automation.register_parented_action(
"pcf8563.write_time",
WriteAction,
automation.maybe_simple_id(
@@ -37,18 +35,9 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
),
synchronous=True,
)
async def pcf8563_write_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"pcf8563.read_time",
ReadAction,
automation.maybe_simple_id(
@@ -58,15 +47,6 @@ async def pcf8563_write_time_to_code(
),
synchronous=True,
)
async def pcf8563_read_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+4 -10
View File
@@ -105,26 +105,20 @@ PMWCS3_CALIBRATION_SCHEMA = cv.Schema(
)
@automation.register_action(
automation.register_simple_action(
"pmwcs3.air_calibration",
PMWCS3AirCalibrationAction,
PMWCS3_CALIBRATION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"pmwcs3.water_calibration",
PMWCS3WaterCalibrationAction,
PMWCS3_CALIBRATION_SCHEMA,
synchronous=True,
)
async def pmwcs3_calibration_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
parent = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, parent)
PMWCS3_NEW_I2C_ADDRESS_SCHEMA = cv.maybe_simple_value(
+2 -13
View File
@@ -3,14 +3,12 @@ import esphome.codegen as cg
from esphome.components import nfc
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_ON_FINISHED_WRITE,
CONF_ON_TAG,
CONF_ON_TAG_REMOVED,
CONF_TRIGGER_ID,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.cpp_generator import MockObj
from esphome.types import ConfigType
CODEOWNERS = ["@OttoWinter", "@jesserockz"]
@@ -79,7 +77,7 @@ async def setup_pn532(var: MockObj, config: ConfigType) -> None:
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
@automation.register_condition(
automation.register_parented_condition(
"pn532.is_writing",
PN532IsWritingCondition,
cv.Schema(
@@ -88,12 +86,3 @@ async def setup_pn532(var: MockObj, config: ConfigType) -> None:
}
),
)
async def pn532_is_writing_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(condition_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+35 -30
View File
@@ -127,54 +127,68 @@ async def pn7150_set_message_to_code(
return var
@automation.register_action(
automation.register_parented_action(
"tag.emulation_off",
EmulationOffAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.emulation_on", EmulationOnAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.emulation_on",
EmulationOnAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.polling_off", PollingOffAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.polling_off",
PollingOffAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.polling_on", PollingOnAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.polling_on",
PollingOnAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_clean_mode",
SetCleanModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_format_mode",
SetFormatModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_read_mode",
SetReadModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_write_mode",
SetWriteModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
async def pn7150_simple_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
_CALLBACK_AUTOMATIONS = (
@@ -220,7 +234,7 @@ async def setup_pn7150(var: MockObj, config: ConfigType) -> None:
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
@automation.register_condition(
automation.register_parented_condition(
"pn7150.is_writing",
PN7150IsWritingCondition,
cv.Schema(
@@ -229,12 +243,3 @@ async def setup_pn7150(var: MockObj, config: ConfigType) -> None:
}
),
)
async def pn7150_is_writing_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(condition_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+35 -30
View File
@@ -131,54 +131,68 @@ async def pn7160_set_message_to_code(
return var
@automation.register_action(
automation.register_parented_action(
"tag.emulation_off",
EmulationOffAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.emulation_on", EmulationOnAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.emulation_on",
EmulationOnAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.polling_off", PollingOffAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.polling_off",
PollingOffAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"tag.polling_on", PollingOnAction, SIMPLE_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tag.polling_on",
PollingOnAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_clean_mode",
SetCleanModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_format_mode",
SetFormatModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_read_mode",
SetReadModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"tag.set_write_mode",
SetWriteModeAction,
SIMPLE_ACTION_SCHEMA,
synchronous=True,
)
async def pn7160_simple_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
_CALLBACK_AUTOMATIONS = (
@@ -232,7 +246,7 @@ async def setup_pn7160(var: MockObj, config: ConfigType) -> None:
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
@automation.register_condition(
automation.register_parented_condition(
"pn7160.is_writing",
PN7160IsWritingCondition,
cv.Schema(
@@ -241,12 +255,3 @@ async def setup_pn7160(var: MockObj, config: ConfigType) -> None:
}
),
)
async def pn7160_is_writing_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(condition_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+1 -11
View File
@@ -26,8 +26,6 @@ from esphome.const import (
UNIT_WATT,
UNIT_WATT_HOURS,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
AUTO_LOAD = ["modbus"]
@@ -85,7 +83,7 @@ CONFIG_SCHEMA = (
)
@automation.register_action(
automation.register_simple_action(
"pzemac.reset_energy",
ResetEnergyAction,
maybe_simple_id(
@@ -95,14 +93,6 @@ CONFIG_SCHEMA = (
),
synchronous=True,
)
async def reset_energy_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
def _final_validate(config: ConfigType) -> None:
+1 -11
View File
@@ -20,8 +20,6 @@ from esphome.const import (
UNIT_VOLT,
UNIT_WATT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
AUTO_LOAD = ["modbus"]
@@ -67,7 +65,7 @@ CONFIG_SCHEMA = (
)
@automation.register_action(
automation.register_simple_action(
"pzemdc.reset_energy",
ResetEnergyAction,
maybe_simple_id(
@@ -77,14 +75,6 @@ CONFIG_SCHEMA = (
),
synchronous=True,
)
async def reset_energy_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
def _final_validate(config: ConfigType) -> None:
+2 -22
View File
@@ -3,8 +3,6 @@ import esphome.codegen as cg
from esphome.components import i2c, time
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@beormund"]
@@ -22,7 +20,7 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
).extend(i2c.i2c_device_schema(0x32))
@automation.register_action(
automation.register_parented_action(
"rx8130.write_time",
WriteAction,
cv.Schema(
@@ -32,18 +30,9 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
),
synchronous=True,
)
async def rx8130_write_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
automation.register_parented_action(
"rx8130.read_time",
ReadAction,
automation.maybe_simple_id(
@@ -53,15 +42,6 @@ async def rx8130_write_time_to_code(
),
synchronous=True,
)
async def rx8130_read_time_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
+4 -16
View File
@@ -10,8 +10,8 @@ from esphome.const import (
CONF_STORAGE,
KEY_PAST_SAFE_MODE,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.cpp_generator import MockObj, RawExpression, TemplateArgsType
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.cpp_generator import RawExpression
from esphome.types import ConfigType
CODEOWNERS = ["@paulmonigatti", "@jsuanet", "@kbx81"]
@@ -22,7 +22,6 @@ CONF_ON_SAFE_MODE = "on_safe_mode"
safe_mode_ns = cg.esphome_ns.namespace("safe_mode")
SafeModeComponent = safe_mode_ns.class_("SafeModeComponent", cg.Component)
MarkSuccessfulAction = safe_mode_ns.class_("MarkSuccessfulAction", automation.Action)
def _remove_id_if_disabled(value: ConfigType) -> ConfigType:
@@ -53,26 +52,15 @@ CONFIG_SCHEMA = cv.All(
)
@automation.register_action(
automation.register_apply_action(
"safe_mode.mark_successful",
MarkSuccessfulAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(SafeModeComponent),
}
),
synchronous=True,
automation.ApplyCall("mark_successful()"),
)
async def safe_mode_mark_successful_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
parent = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg)
cg.add(var.set_parent(parent))
return var
_CALLBACK_AUTOMATIONS = (
-12
View File
@@ -1,12 +0,0 @@
#pragma once
#include "esphome/core/automation.h"
#include "safe_mode.h"
namespace esphome::safe_mode {
template<typename... Ts> class MarkSuccessfulAction final : public Action<Ts...>, public Parented<SafeModeComponent> {
public:
void play(const Ts &...x) override { this->parent_->mark_successful(); }
};
} // namespace esphome::safe_mode
+1 -10
View File
@@ -166,18 +166,9 @@ SCD4X_RESET_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"scd4x.factory_reset",
FactoryResetAction,
SCD4X_RESET_ACTION_SCHEMA,
synchronous=True,
)
async def scd4x_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+2 -8
View File
@@ -9,7 +9,6 @@ CODEOWNERS = ["@esphome/core"]
script_ns = cg.esphome_ns.namespace("script")
Script = script_ns.class_("Script", automation.Trigger.template())
ScriptExecuteAction = script_ns.class_("ScriptExecuteAction", automation.Action)
ScriptStopAction = script_ns.class_("ScriptStopAction", automation.Action)
ScriptWaitAction = script_ns.class_("ScriptWaitAction", automation.Action, cg.Component)
SingleScript = script_ns.class_("SingleScript", Script)
RestartScript = script_ns.class_("RestartScript", Script)
@@ -206,16 +205,11 @@ async def script_execute_action_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
automation.register_apply_action(
"script.stop",
ScriptStopAction,
maybe_simple_id({cv.Required(CONF_ID): cv.use_id(Script)}),
synchronous=True,
automation.ApplyCall("stop()"),
)
async def script_stop_action_to_code(config, action_id, template_arg, args):
full_id, paren = await cg.get_variable_with_full_id(config[CONF_ID])
template_arg = cg.TemplateArguments(full_id.type, *template_arg)
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
-10
View File
@@ -257,16 +257,6 @@ template<class... As, typename... Ts> class ScriptExecuteAction<Script<As...>, T
Args args_;
};
template<class C, typename... Ts> class ScriptStopAction final : public Action<Ts...> {
public:
ScriptStopAction(C *script) : script_(script) {}
void play(const Ts &...x) override { this->script_->stop(); }
protected:
C *script_;
};
/** Wait for a script to finish before continuing.
*
* Uses queue-based storage to safely handle concurrent executions.
+1 -11
View File
@@ -43,8 +43,6 @@ from esphome.const import (
UNIT_MICROGRAMS_PER_CUBIC_METER,
UNIT_PERCENT,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@martgras"]
@@ -282,17 +280,9 @@ SEN5X_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_simple_action(
"sen5x.start_fan_autoclean",
StartFanAction,
SEN5X_ACTION_SCHEMA,
synchronous=True,
)
async def sen54_fan_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+4 -21
View File
@@ -21,8 +21,8 @@ from esphome.const import (
CONF_VERSION,
CONF_WIDTH,
)
from esphome.core import CORE, ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.core import CORE
from esphome.cpp_generator import MockObj
from esphome.types import ConfigType
# mdns for autodiscovery
@@ -109,13 +109,6 @@ SendspinHub = sendspin_ns.class_(
)
SendspinSwitchCommandAction = sendspin_ns.class_(
"SendspinSwitchCommandAction",
automation.Action,
cg.Parented.template(SendspinHub),
)
@dataclass
class SendspinConfiguration:
artwork_support: bool = False
@@ -240,21 +233,11 @@ SENDSPIN_SIMPLE_ACTION_SCHEMA = cv.All(
)
@automation.register_action(
automation.register_apply_action(
"sendspin.switch",
SendspinSwitchCommandAction,
SENDSPIN_SIMPLE_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("switch_client()"),
)
async def sendspin_switch_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def to_code(config: ConfigType) -> None:
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_ESP32
#include "esphome/core/automation.h"
#include "sendspin_hub.h"
namespace esphome::sendspin_ {
#ifdef USE_SENDSPIN_CONTROLLER
template<typename... Ts> class SendspinSwitchCommandAction final : public Action<Ts...>, public Parented<SendspinHub> {
public:
void play(const Ts &...x) override {
// Clear any EXTERNAL_SOURCE state so the switch command is followed
this->parent_->update_state(sendspin::SendspinClientState::SYNCHRONIZED);
this->parent_->send_client_command(sendspin::SendspinControllerCommand::SWITCH);
}
};
#endif // USE_SENDSPIN_CONTROLLER
} // namespace esphome::sendspin_
#endif // USE_ESP32
+2 -20
View File
@@ -16,7 +16,6 @@ from esphome.const import (
CONF_WIDTH,
)
from esphome.core import ID
from esphome.cpp_generator import TemplateArgsType
from esphome.types import ConfigType
from .. import (
@@ -198,16 +197,8 @@ async def to_code(config: ConfigType) -> None:
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
SendspinImageTransitionFinishedAction = sendspin_ns.class_(
"SendspinImageTransitionFinishedAction",
automation.Action,
cg.Parented.template(SendspinImageSlot),
)
@automation.register_action(
automation.register_apply_action(
"sendspin.image.transition_finished",
SendspinImageTransitionFinishedAction,
automation.maybe_simple_id(
cv.Schema(
{
@@ -215,14 +206,5 @@ SendspinImageTransitionFinishedAction = sendspin_ns.class_(
}
)
),
synchronous=True,
automation.ApplyCall("transition_finished()"),
)
async def sendspin_image_transition_finished_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> cg.MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@@ -1,20 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#if defined(USE_ESP32) && defined(USE_SENDSPIN_ARTWORK)
#include "esphome/core/automation.h"
#include "sendspin_image.h"
namespace esphome::sendspin_ {
template<typename... Ts>
class SendspinImageTransitionFinishedAction final : public Action<Ts...>, public Parented<SendspinImageSlot> {
public:
void play(const Ts &...x) override { this->parent_->transition_finished(); }
};
} // namespace esphome::sendspin_
#endif
@@ -8,8 +8,6 @@ from esphome.const import (
CONF_SAMPLE_RATE,
CONF_TASK_STACK_IN_PSRAM,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
from .. import (
@@ -41,18 +39,6 @@ SendspinMediaSource = sendspin_ns.class_(
media_source.MediaSource,
)
EnableStaticDelayAdjustmentAction = sendspin_ns.class_(
"EnableStaticDelayAdjustmentAction",
automation.Action,
cg.Parented.template(SendspinMediaSource),
)
DisableStaticDelayAdjustmentAction = sendspin_ns.class_(
"DisableStaticDelayAdjustmentAction",
automation.Action,
cg.Parented.template(SendspinMediaSource),
)
def _resolve_codecs(config: ConfigType) -> ConfigType:
"""Validate the codec preference list, filling in the default when it is not set."""
@@ -144,25 +130,16 @@ SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA = automation.maybe_simple_id(
)
)
@automation.register_action(
"sendspin.media_source.enable_static_delay_adjustment",
EnableStaticDelayAdjustmentAction,
SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sendspin.media_source.disable_static_delay_adjustment",
DisableStaticDelayAdjustmentAction,
SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA,
synchronous=True,
)
async def sendspin_static_delay_adjustment_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
for _name, _call in (
(
"sendspin.media_source.enable_static_delay_adjustment",
"set_static_delay_adjustable(true)",
),
(
"sendspin.media_source.disable_static_delay_adjustment",
"set_static_delay_adjustable(false)",
),
):
automation.register_apply_action(
_name, SENDSPIN_MEDIA_SOURCE_ACTION_SCHEMA, automation.ApplyCall(_call)
)
@@ -1,26 +0,0 @@
#pragma once
#include "esphome/core/defines.h"
#if defined(USE_ESP32) && defined(USE_SENDSPIN_PLAYER) && defined(USE_SENDSPIN_CONTROLLER)
#include "esphome/core/automation.h"
#include "sendspin_media_source.h"
namespace esphome::sendspin_ {
template<typename... Ts>
class EnableStaticDelayAdjustmentAction final : public Action<Ts...>, public Parented<SendspinMediaSource> {
public:
void play(const Ts &...x) override { this->parent_->set_static_delay_adjustable(true); }
};
template<typename... Ts>
class DisableStaticDelayAdjustmentAction final : public Action<Ts...>, public Parented<SendspinMediaSource> {
public:
void play(const Ts &...x) override { this->parent_->set_static_delay_adjustable(false); }
};
} // namespace esphome::sendspin_
#endif
@@ -284,6 +284,13 @@ void SendspinHub::send_client_command(sendspin::SendspinControllerCommand comman
}
}
// THREAD CONTEXT: Main loop (invoked from the sendspin.switch action)
void SendspinHub::switch_client() {
// Clear any EXTERNAL_SOURCE state so the switch command is followed
this->update_state(sendspin::SendspinClientState::SYNCHRONIZED);
this->send_client_command(sendspin::SendspinControllerCommand::SWITCH);
}
// THREAD CONTEXT: Main loop (ControllerRoleListener override, fired from client_->loop())
void SendspinHub::on_controller_state(const sendspin::ServerStateControllerObject &state) {
this->controller_state_callbacks_.call(state);
@@ -181,6 +181,9 @@ class SendspinHub final : public Component,
void send_client_command(sendspin::SendspinControllerCommand command, std::optional<uint8_t> volume = std::nullopt,
std::optional<bool> mute = std::nullopt);
/// @brief Sends the SWITCH controller command; exposed as the sendspin.switch action.
void switch_client();
template<typename F> void add_controller_state_callback(F &&callback) {
this->controller_state_callbacks_.add(std::forward<F>(callback));
}
+13 -15
View File
@@ -11,8 +11,6 @@ from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_PARTS_PER_MILLION,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
DEPENDENCIES = ["uart"]
@@ -82,41 +80,41 @@ CALIBRATION_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_simple_action(
"senseair.background_calibration",
SenseAirBackgroundCalibrationAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"senseair.background_calibration_result",
SenseAirBackgroundCalibrationResultAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"senseair.abc_enable",
SenseAirABCEnableAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"senseair.abc_disable",
SenseAirABCDisableAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"senseair.abc_get_period",
SenseAirABCGetPeriodAction,
CALIBRATION_ACTION_SCHEMA,
synchronous=True,
)
async def senseair_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+1 -1
View File
@@ -1,5 +1,6 @@
import esphome.codegen as cg
from esphome.components import i2c, sensirion_common, sensor
from esphome.components.const import CONF_HUMIDITY_SOURCE
import esphome.config_validation as cv
from esphome.const import (
CONF_BASELINE,
@@ -31,7 +32,6 @@ SGP30Component = sgp30_ns.class_(
CONF_ECO2_BASELINE = "eco2_baseline"
CONF_TVOC_BASELINE = "tvoc_baseline"
CONF_UPTIME = "uptime"
CONF_HUMIDITY_SOURCE = "humidity_source"
CONFIG_SCHEMA = (
+5 -3
View File
@@ -1,6 +1,10 @@
import esphome.codegen as cg
from esphome.components import i2c, sensirion_common, sensor
from esphome.components.const import CONF_NOX_INDEX, CONF_VOC_INDEX
from esphome.components.const import (
CONF_HUMIDITY_SOURCE,
CONF_NOX_INDEX,
CONF_VOC_INDEX,
)
import esphome.config_validation as cv
from esphome.const import (
CONF_ALGORITHM_TUNING,
@@ -33,8 +37,6 @@ SGP4xComponent = sgp4x_ns.class_(
sensirion_common.SensirionI2CDevice,
)
CONF_HUMIDITY_SOURCE = "humidity_source"
def validate_sensors(config: ConfigType) -> ConfigType:
if CONF_VOC_INDEX not in config and CONF_NOX_INDEX not in config:
+2 -8
View File
@@ -125,15 +125,12 @@ async def sim800l_dial_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
automation.register_simple_action(
"sim800l.connect",
Sim800LConnectAction,
cv.Schema({cv.GenerateID(): cv.use_id(Sim800LComponent)}),
synchronous=True,
)
async def sim800l_connect_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
SIM800L_SEND_USSD_SCHEMA = cv.Schema(
@@ -158,12 +155,9 @@ async def sim800l_send_ussd_to_code(config, action_id, template_arg, args):
return var
@automation.register_action(
automation.register_simple_action(
"sim800l.disconnect",
Sim800LDisconnectAction,
cv.Schema({cv.GenerateID(): cv.use_id(Sim800LComponent)}),
synchronous=True,
)
async def sim800l_disconnect_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+12 -15
View File
@@ -11,8 +11,6 @@ from esphome.const import (
STATE_CLASS_MEASUREMENT,
UNIT_DECIBEL,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
AUTO_LOAD = ["audio"]
@@ -92,18 +90,17 @@ SOUND_LEVEL_ACTION_SCHEMA = automation.maybe_simple_id(
)
@automation.register_action(
"sound_level.start", StartAction, SOUND_LEVEL_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"sound_level.start",
StartAction,
SOUND_LEVEL_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sound_level.stop", StopAction, SOUND_LEVEL_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"sound_level.stop",
StopAction,
SOUND_LEVEL_ACTION_SCHEMA,
synchronous=True,
)
async def sound_level_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+59 -89
View File
@@ -66,19 +66,10 @@ SprinklerControllerSwitch = sprinkler_ns.class_(
"SprinklerControllerSwitch", switch.Switch, cg.Component
)
ClearQueuedValvesAction = sprinkler_ns.class_(
"ClearQueuedValvesAction", automation.Action
)
StartFromQueueAction = sprinkler_ns.class_("StartFromQueueAction", automation.Action)
StartFullCycleAction = sprinkler_ns.class_("StartFullCycleAction", automation.Action)
StartSingleValveAction = sprinkler_ns.class_(
"StartSingleValveAction", automation.Action
)
ShutdownAction = sprinkler_ns.class_("ShutdownAction", automation.Action)
NextValveAction = sprinkler_ns.class_("NextValveAction", automation.Action)
PreviousValveAction = sprinkler_ns.class_("PreviousValveAction", automation.Action)
PauseAction = sprinkler_ns.class_("PauseAction", automation.Action)
ResumeAction = sprinkler_ns.class_("ResumeAction", automation.Action)
ResumeOrStartAction = sprinkler_ns.class_("ResumeOrStartAction", automation.Action)
@@ -415,57 +406,61 @@ CONFIG_SCHEMA = cv.All(
_VALVE_AND_DURATION = ((CONF_VALVE_NUMBER, cg.size_t), (CONF_RUN_DURATION, cg.uint32))
automation.register_apply_action(
"sprinkler.set_divider",
SPRINKLER_ACTION_SET_DIVIDER_SCHEMA,
automation.ApplyField(CONF_DIVIDER, "set_divider", cg.uint32),
)
automation.register_apply_action(
"sprinkler.set_multiplier",
SPRINKLER_ACTION_SET_MULTIPLIER_SCHEMA,
automation.ApplyField(CONF_MULTIPLIER, "set_multiplier", cg.float_),
)
automation.register_apply_action(
"sprinkler.queue_valve",
SPRINKLER_ACTION_QUEUE_VALVE_SCHEMA,
automation.ApplyCall("queue_valve({}, {})", _VALVE_AND_DURATION),
)
automation.register_apply_action(
"sprinkler.set_repeat",
SPRINKLER_ACTION_REPEAT_SCHEMA,
automation.ApplyField(CONF_REPEAT, "set_repeat", cg.uint32),
)
automation.register_apply_action(
"sprinkler.set_valve_run_duration",
SPRINKLER_ACTION_SET_RUN_DURATION_SCHEMA,
automation.ApplyCall("set_valve_run_duration({}, {})", _VALVE_AND_DURATION),
)
@automation.register_action(
"sprinkler.start_from_queue",
StartFromQueueAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
async def sprinkler_start_from_queue_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
@automation.register_action(
"sprinkler.start_full_cycle",
StartFullCycleAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
async def sprinkler_start_full_cycle_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
for _name, _schema, _apply in (
(
"sprinkler.set_divider",
SPRINKLER_ACTION_SET_DIVIDER_SCHEMA,
automation.ApplyField(CONF_DIVIDER, "set_divider", cg.uint32),
),
(
"sprinkler.set_multiplier",
SPRINKLER_ACTION_SET_MULTIPLIER_SCHEMA,
automation.ApplyField(CONF_MULTIPLIER, "set_multiplier", cg.float_),
),
(
"sprinkler.queue_valve",
SPRINKLER_ACTION_QUEUE_VALVE_SCHEMA,
automation.ApplyCall("queue_valve({}, {})", _VALVE_AND_DURATION),
),
(
"sprinkler.set_repeat",
SPRINKLER_ACTION_REPEAT_SCHEMA,
automation.ApplyField(CONF_REPEAT, "set_repeat", cg.uint32),
),
(
"sprinkler.set_valve_run_duration",
SPRINKLER_ACTION_SET_RUN_DURATION_SCHEMA,
automation.ApplyCall("set_valve_run_duration({}, {})", _VALVE_AND_DURATION),
),
(
"sprinkler.start_from_queue",
SPRINKLER_ACTION_SCHEMA,
automation.ApplyCall("start_from_queue()"),
),
(
"sprinkler.start_full_cycle",
SPRINKLER_ACTION_SCHEMA,
automation.ApplyCall("start_full_cycle()"),
),
(
"sprinkler.clear_queued_valves",
SPRINKLER_ACTION_SCHEMA,
automation.ApplyCall("clear_queued_valves()"),
),
(
"sprinkler.next_valve",
SPRINKLER_ACTION_SCHEMA,
automation.ApplyCall("next_valve()"),
),
(
"sprinkler.previous_valve",
SPRINKLER_ACTION_SCHEMA,
automation.ApplyCall("previous_valve()"),
),
("sprinkler.pause", SPRINKLER_ACTION_SCHEMA, automation.ApplyCall("pause()")),
("sprinkler.resume", SPRINKLER_ACTION_SCHEMA, automation.ApplyCall("resume()")),
):
automation.register_apply_action(_name, _schema, _apply)
@automation.register_action(
@@ -485,45 +480,20 @@ async def sprinkler_start_single_valve_to_code(config, action_id, template_arg,
return var
@automation.register_action(
"sprinkler.clear_queued_valves",
ClearQueuedValvesAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sprinkler.next_valve",
NextValveAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sprinkler.previous_valve",
PreviousValveAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
"sprinkler.pause", PauseAction, SPRINKLER_ACTION_SCHEMA, synchronous=True
)
@automation.register_action(
"sprinkler.resume", ResumeAction, SPRINKLER_ACTION_SCHEMA, synchronous=True
)
@automation.register_action(
automation.register_simple_action(
"sprinkler.resume_or_start_full_cycle",
ResumeOrStartAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_simple_action(
"sprinkler.shutdown",
ShutdownAction,
SPRINKLER_ACTION_SCHEMA,
synchronous=True,
)
async def sprinkler_simple_action_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
async def to_code(config):
-70
View File
@@ -6,36 +6,6 @@
namespace esphome::sprinkler {
template<typename... Ts> class ClearQueuedValvesAction final : public Action<Ts...> {
public:
explicit ClearQueuedValvesAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->clear_queued_valves(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class StartFromQueueAction final : public Action<Ts...> {
public:
explicit StartFromQueueAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->start_from_queue(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class StartFullCycleAction final : public Action<Ts...> {
public:
explicit StartFullCycleAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->start_full_cycle(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class StartSingleValveAction final : public Action<Ts...> {
public:
explicit StartSingleValveAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
@@ -64,46 +34,6 @@ template<typename... Ts> class ShutdownAction final : public Action<Ts...> {
Sprinkler *sprinkler_;
};
template<typename... Ts> class NextValveAction final : public Action<Ts...> {
public:
explicit NextValveAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->next_valve(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class PreviousValveAction final : public Action<Ts...> {
public:
explicit PreviousValveAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->previous_valve(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class PauseAction final : public Action<Ts...> {
public:
explicit PauseAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->pause(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class ResumeAction final : public Action<Ts...> {
public:
explicit ResumeAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
void play(const Ts &...x) override { this->sprinkler_->resume(); }
protected:
Sprinkler *sprinkler_;
};
template<typename... Ts> class ResumeOrStartAction final : public Action<Ts...> {
public:
explicit ResumeOrStartAction(Sprinkler *a_sprinkler) : sprinkler_(a_sprinkler) {}
+7 -14
View File
@@ -26,8 +26,6 @@ from esphome.const import (
UNIT_MICROGRAMS_PER_CUBIC_METER,
UNIT_MICROMETER,
)
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@martgras"]
@@ -182,30 +180,25 @@ SPS30_ACTION_SCHEMA = maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"sps30.start_fan_autoclean",
StartFanAction,
SPS30_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sps30.start_measurement",
StartMeasurementAction,
SPS30_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sps30.stop_measurement",
StopMeasurementAction,
SPS30_ACTION_SCHEMA,
synchronous=True,
)
async def sps30_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
+10 -13
View File
@@ -302,39 +302,36 @@ NO_ARGS_ACTION_SCHEMA = automation.maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"sx126x.run_image_cal",
RunImageCalAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx126x.set_mode_tx",
SetModeTxAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx126x.set_mode_rx",
SetModeRxAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx126x.set_mode_standby",
SetModeStandbyAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def no_args_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
SET_MODE_SLEEP_ACTION_SCHEMA = automation.maybe_simple_id(
+13 -14
View File
@@ -286,45 +286,44 @@ NO_ARGS_ACTION_SCHEMA = automation.maybe_simple_id(
)
@automation.register_action(
automation.register_parented_action(
"sx127x.run_image_cal",
RunImageCalAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx127x.set_mode_tx",
SetModeTxAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx127x.set_mode_rx",
SetModeRxAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx127x.set_mode_sleep",
SetModeSleepAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
@automation.register_action(
automation.register_parented_action(
"sx127x.set_mode_standby",
SetModeStandbyAction,
NO_ARGS_ACTION_SCHEMA,
synchronous=True,
)
async def no_args_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
SEND_PACKET_ACTION_SCHEMA = cv.maybe_simple_value(
+1 -11
View File
@@ -12,8 +12,6 @@ from esphome.components.esp32 import (
)
import esphome.config_validation as cv
from esphome.const import CONF_HARDWARE_UART, CONF_ID
from esphome.core import ID
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.types import ConfigType
CODEOWNERS = ["@kbx81"]
@@ -136,16 +134,8 @@ async def to_code(config: ConfigType) -> None:
add_idf_sdkconfig_option("CONFIG_TINYUSB_DESC_BCD_DEVICE", 0x0100)
@automation.register_condition(
automation.register_simple_condition(
"tinyusb.is_mounted",
IsMountedCondition,
cv.Schema({cv.GenerateID(): cv.use_id(TinyUSB)}),
)
async def tinyusb_is_mounted_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(condition_id, template_arg, paren)
+6 -21
View File
@@ -141,32 +141,17 @@ async def tm1651_set_level_percent_to_code(
return var
@automation.register_action(
automation.register_parented_action(
"tm1651.turn_off",
TurnOffAction,
BINARY_OUTPUT_ACTION_SCHEMA,
synchronous=True,
)
async def output_turn_off_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_action(
"tm1651.turn_on", TurnOnAction, BINARY_OUTPUT_ACTION_SCHEMA, synchronous=True
automation.register_parented_action(
"tm1651.turn_on",
TurnOnAction,
BINARY_OUTPUT_ACTION_SCHEMA,
synchronous=True,
)
async def output_turn_on_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@@ -1,5 +1,6 @@
#ifdef USE_ESP8266
#include "uart_component_esp8266.h"
#include <esp8266_peri.h>
#include "esphome/core/application.h"
#include "esphome/core/defines.h"
#include "esphome/core/helpers.h"
@@ -251,23 +252,35 @@ void ESP8266SoftwareSerial::setup(InternalGPIOPin *tx_pin, InternalGPIOPin *rx_p
gpio_rx_pin_->attach_interrupt(ESP8266SoftwareSerial::gpio_intr, this, gpio::INTERRUPT_FALLING_EDGE);
}
}
// A byte can arrive while a CpuFrequencyBoost has an 80 MHz build at 160 MHz; the clock select bit doubles
// the bit time then. The whole byte is read inside the ISR, so the clock cannot change partway through.
__attribute__((always_inline)) static inline uint32_t rx_bit_time(uint32_t bit_time) {
#if F_CPU != 160000000L
// NOLINTNEXTLINE(clang-analyzer-core.FixedAddressDereference) -- CPU2X is MMIO at a fixed address
return bit_time << (CPU2X & 1);
#else
return bit_time;
#endif
}
void IRAM_ATTR ESP8266SoftwareSerial::gpio_intr(ESP8266SoftwareSerial *arg) {
uint32_t wait = arg->bit_time_ + arg->bit_time_ / 3 - 500;
const uint32_t bit_time = rx_bit_time(arg->bit_time_);
uint32_t wait = bit_time + bit_time / 3 - 500;
const uint32_t start = arch_get_cpu_cycle_count();
uint8_t rec = 0;
// Manually unroll the loop
for (int i = 0; i < arg->data_bits_; i++)
rec |= arg->read_bit_(&wait, start) << i;
rec |= arg->read_bit_(&wait, start, bit_time) << i;
/* If parity is enabled, just read it and ignore it. */
/* TODO: Should we check parity? Or is it too slow for nothing added..*/
if (arg->parity_ == UART_CONFIG_PARITY_EVEN || arg->parity_ == UART_CONFIG_PARITY_ODD)
arg->read_bit_(&wait, start);
arg->read_bit_(&wait, start, bit_time);
// Stop bit
arg->wait_(&wait, start);
arg->wait_(&wait, start, bit_time);
if (arg->stop_bits_ == 2)
arg->wait_(&wait, start);
arg->wait_(&wait, start, bit_time);
arg->rx_buffer_[arg->rx_in_pos_] = rec;
arg->rx_in_pos_ = (arg->rx_in_pos_ + 1) % arg->rx_buffer_size_;
@@ -296,37 +309,39 @@ void IRAM_ATTR HOT ESP8266SoftwareSerial::write_byte(uint8_t data) {
}
{
// Transmit runs from the main loop and never overlaps a CpuFrequencyBoost
InterruptLock lock;
uint32_t wait = this->bit_time_;
const uint32_t bit_time = this->bit_time_;
uint32_t wait = bit_time;
const uint32_t start = arch_get_cpu_cycle_count();
// Start bit
this->write_bit_(false, &wait, start);
this->write_bit_(false, &wait, start, bit_time);
for (int i = 0; i < this->data_bits_; i++) {
bool bit = data & (1 << i);
this->write_bit_(bit, &wait, start);
this->write_bit_(bit, &wait, start, bit_time);
if (need_parity_bit)
parity_bit ^= bit;
}
if (need_parity_bit)
this->write_bit_(parity_bit, &wait, start);
this->write_bit_(parity_bit, &wait, start, bit_time);
// Stop bit
this->write_bit_(true, &wait, start);
this->write_bit_(true, &wait, start, bit_time);
if (this->stop_bits_ == 2)
this->wait_(&wait, start);
this->wait_(&wait, start, bit_time);
}
}
void IRAM_ATTR ESP8266SoftwareSerial::wait_(uint32_t *wait, const uint32_t &start) {
void IRAM_ATTR ESP8266SoftwareSerial::wait_(uint32_t *wait, const uint32_t &start, uint32_t bit_time) {
while (arch_get_cpu_cycle_count() - start < *wait)
;
*wait += this->bit_time_;
*wait += bit_time;
}
bool IRAM_ATTR ESP8266SoftwareSerial::read_bit_(uint32_t *wait, const uint32_t &start) {
this->wait_(wait, start);
bool IRAM_ATTR ESP8266SoftwareSerial::read_bit_(uint32_t *wait, const uint32_t &start, uint32_t bit_time) {
this->wait_(wait, start, bit_time);
return this->rx_pin_.digital_read();
}
void IRAM_ATTR ESP8266SoftwareSerial::write_bit_(bool bit, uint32_t *wait, const uint32_t &start) {
void IRAM_ATTR ESP8266SoftwareSerial::write_bit_(bool bit, uint32_t *wait, const uint32_t &start, uint32_t bit_time) {
this->tx_pin_.digital_write(bit);
this->wait_(wait, start);
this->wait_(wait, start, bit_time);
}
uint8_t ESP8266SoftwareSerial::read_byte() {
if (this->rx_in_pos_ == this->rx_out_pos_)
@@ -28,9 +28,9 @@ class ESP8266SoftwareSerial {
protected:
static void gpio_intr(ESP8266SoftwareSerial *arg);
void wait_(uint32_t *wait, const uint32_t &start);
bool read_bit_(uint32_t *wait, const uint32_t &start);
void write_bit_(bool bit, uint32_t *wait, const uint32_t &start);
void wait_(uint32_t *wait, const uint32_t &start, uint32_t bit_time);
bool read_bit_(uint32_t *wait, const uint32_t &start, uint32_t bit_time);
void write_bit_(bool bit, uint32_t *wait, const uint32_t &start, uint32_t bit_time);
uint32_t bit_time_{0};
uint8_t *rx_buffer_{nullptr};
+1 -9
View File
@@ -124,17 +124,9 @@ UFIRE_EC_RESET_SCHEMA = cv.Schema(
)
@automation.register_action(
automation.register_simple_action(
"ufire_ec.reset",
UFireECResetAction,
UFIRE_EC_RESET_SCHEMA,
synchronous=True,
)
async def ufire_ec_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+1 -9
View File
@@ -131,17 +131,9 @@ async def ufire_ise_calibrate_probe_high_to_code(
UFIRE_ISE_RESET_SCHEMA = cv.Schema({cv.GenerateID(): cv.use_id(UFireISEComponent)})
@automation.register_action(
automation.register_simple_action(
"ufire_ise.reset",
UFireISEResetAction,
UFIRE_ISE_RESET_SCHEMA,
synchronous=True,
)
async def ufire_ise_reset_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
+4 -22
View File
@@ -14,14 +14,14 @@ from esphome.const import (
DEVICE_CLASS_FIRMWARE,
ENTITY_CATEGORY_CONFIG,
)
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
from esphome.core import CORE, CoroPriority, coroutine_with_priority
from esphome.core.entity_helpers import (
entity_duplicate_validator,
queue_entity_register,
setup_device_class,
setup_entity,
)
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
from esphome.cpp_generator import MockObj, MockObjClass
from esphome.types import ConfigType
CODEOWNERS = ["@jesserockz"]
@@ -144,7 +144,7 @@ automation.register_apply_action(
)
@automation.register_action(
automation.register_parented_action(
"update.check",
CheckAction,
automation.maybe_simple_id(
@@ -154,18 +154,9 @@ automation.register_apply_action(
),
synchronous=True,
)
async def update_check_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
@automation.register_condition(
automation.register_parented_condition(
"update.is_available",
IsAvailableCondition,
automation.maybe_simple_id(
@@ -174,12 +165,3 @@ async def update_check_action_to_code(
}
),
)
async def update_is_available_condition_to_code(
config: ConfigType,
condition_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(condition_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var

Some files were not shown because too many files have changed in this diff Show More