mirror of
https://github.com/esphome/esphome.git
synced 2026-10-15 10:42:52 +00:00
[remote_base] Generate the simple transmit actions with no C++ class (#20549)
This commit is contained in:
+18
-2
@@ -1,4 +1,4 @@
|
||||
from collections.abc import Callable, Sequence
|
||||
from collections.abc import Awaitable, Callable, Sequence
|
||||
from dataclasses import dataclass, field
|
||||
import logging
|
||||
import string
|
||||
@@ -465,6 +465,22 @@ def register_apply_action(
|
||||
) -> None:
|
||||
"""Register an action that only forwards config values to its parent, with no C++ class.
|
||||
|
||||
See ``apply_action_builder``.
|
||||
"""
|
||||
register_action(name, ApplyAction, schema, synchronous=True)(
|
||||
apply_action_builder(name, schema, *fields, call=call, id_key=id_key)
|
||||
)
|
||||
|
||||
|
||||
def apply_action_builder(
|
||||
name: str,
|
||||
schema: cv.Schema,
|
||||
*fields: ApplyField | ApplyCall,
|
||||
call: str | None = None,
|
||||
id_key: str = CONF_ID,
|
||||
) -> Callable[..., Awaitable[MockObj]]:
|
||||
"""The builder ``register_apply_action`` registers, for a caller that wraps it.
|
||||
|
||||
Generates one static function with the parent (read from ``id_key``) and constants baked
|
||||
in, lambdas called inline with the trigger args, and an ``ApplyAction`` templated on it.
|
||||
A constant that is an id (``cv.use_id`` under ``cv.templatable``) is the object it names.
|
||||
@@ -515,7 +531,7 @@ def register_apply_action(
|
||||
action_id, cg.void, template_arg, lambda_args, statements
|
||||
)
|
||||
|
||||
register_action(name, ApplyAction, schema, synchronous=True)(builder)
|
||||
return builder
|
||||
|
||||
|
||||
def _apply_call_active(members: list[tuple[Any, Any, Any]], values: list[Any]) -> bool:
|
||||
|
||||
@@ -44,10 +44,10 @@ from esphome.const import (
|
||||
CONF_WAND_ID,
|
||||
CONF_ZERO,
|
||||
)
|
||||
from esphome.core import coroutine
|
||||
from esphome.core import ID, coroutine
|
||||
from esphome.cpp_generator import MockObj
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.types import ConfigType, TemplateArgsType
|
||||
from esphome.types import ConfigType, SafeExpType, TemplateArgsType
|
||||
from esphome.util import Registry, SimpleRegistry
|
||||
|
||||
AUTO_LOAD = ["binary_sensor"]
|
||||
@@ -257,14 +257,23 @@ BASE_REMOTE_TRANSMITTER_SCHEMA = cv.Schema(
|
||||
).extend(REMOTE_TRANSMITTABLE_SCHEMA)
|
||||
|
||||
|
||||
def _transmit_action(
|
||||
name: str,
|
||||
schema: cv.Schema,
|
||||
validate: Callable[[ConfigType], ConfigType] | None,
|
||||
) -> tuple[str, cv.Schema, Any]:
|
||||
"""The action name, its schema and the schema with ``validate`` applied."""
|
||||
schema = templatize(schema).extend(BASE_REMOTE_TRANSMITTER_SCHEMA)
|
||||
validator = schema if validate is None else cv.All(schema, validate)
|
||||
return f"remote_transmitter.transmit_{name}", schema, validator
|
||||
|
||||
|
||||
def register_action(
|
||||
name, type_, schema, *, validate: Callable[[ConfigType], ConfigType] | None = None
|
||||
):
|
||||
validator = templatize(schema).extend(BASE_REMOTE_TRANSMITTER_SCHEMA)
|
||||
if validate is not None:
|
||||
validator = cv.All(validator, validate)
|
||||
action, _, validator = _transmit_action(name, schema, validate)
|
||||
registerer = automation.register_action(
|
||||
f"remote_transmitter.transmit_{name}",
|
||||
action,
|
||||
type_,
|
||||
validator,
|
||||
synchronous=True,
|
||||
@@ -289,6 +298,48 @@ def register_action(
|
||||
return decorator
|
||||
|
||||
|
||||
def register_protocol_action(
|
||||
name: str,
|
||||
protocol: str,
|
||||
schema: cv.Schema,
|
||||
*fields: tuple[str, str, SafeExpType],
|
||||
validate: Callable[[ConfigType], ConfigType] | None = None,
|
||||
) -> None:
|
||||
"""Register ``transmit_<name>`` with no C++ action class.
|
||||
|
||||
One generated function fills ``<protocol>Data`` from ``(conf_key, member, type_)`` fields
|
||||
and sends it; the action is a core ``ApplyAction``.
|
||||
"""
|
||||
action, schema, validator = _transmit_action(name, schema, validate)
|
||||
builder = automation.apply_action_builder(
|
||||
action,
|
||||
schema,
|
||||
*(
|
||||
automation.ApplyField(key, f"data.{member} = {{}}", type_)
|
||||
for key, member, type_ in fields
|
||||
),
|
||||
automation.ApplyField((CONF_REPEAT, CONF_TIMES), "set_send_times", cg.uint32),
|
||||
automation.ApplyField(
|
||||
(CONF_REPEAT, CONF_WAIT_TIME), "set_send_wait", cg.uint32
|
||||
),
|
||||
call=f"protocol_call<{ns.class_(f'{protocol}Protocol')}>",
|
||||
id_key=CONF_TRANSMITTER_ID,
|
||||
)
|
||||
|
||||
async def protocol_builder(
|
||||
config: ConfigType,
|
||||
action_id: ID,
|
||||
template_arg: cg.TemplateArguments,
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
_request_protocol_if_in_tree(name)
|
||||
return await builder(config, action_id, template_arg, args)
|
||||
|
||||
automation.register_action(
|
||||
action, automation.ApplyAction, validator, synchronous=True
|
||||
)(protocol_builder)
|
||||
|
||||
|
||||
def declare_protocol(name):
|
||||
data = ns.struct(f"{name}Data")
|
||||
binary_sensor_ = ns.class_(f"{name}BinarySensor", RemoteReceiverBinarySensorBase)
|
||||
@@ -372,9 +423,7 @@ async def build_dumpers(config):
|
||||
|
||||
|
||||
# Beo4
|
||||
Beo4Data, Beo4BinarySensor, Beo4Trigger, Beo4Action, Beo4Dumper = declare_protocol(
|
||||
"Beo4"
|
||||
)
|
||||
Beo4Data, Beo4BinarySensor, Beo4Trigger, _, Beo4Dumper = declare_protocol("Beo4")
|
||||
BEO4_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_SOURCE): cv.hex_uint8_t,
|
||||
@@ -408,14 +457,14 @@ def beo4_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("beo4", Beo4Action, BEO4_SCHEMA)
|
||||
async def beo4_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_SOURCE], args, cg.uint8)
|
||||
cg.add(var.set_source(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND_REPEATS], args, cg.uint8)
|
||||
cg.add(var.set_repeats(template_))
|
||||
register_protocol_action(
|
||||
"beo4",
|
||||
"Beo4",
|
||||
BEO4_SCHEMA,
|
||||
(CONF_SOURCE, "source", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
(CONF_COMMAND_REPEATS, "repeats", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Brennenstuhl
|
||||
@@ -423,7 +472,7 @@ async def beo4_action(var, config, args):
|
||||
BrennenstuhlData,
|
||||
BrennenstuhlBinarySensor,
|
||||
BrennenstuhlTrigger,
|
||||
BrennenstuhlAction,
|
||||
_,
|
||||
BrennenstuhlDumper,
|
||||
) = declare_protocol("Brennenstuhl")
|
||||
|
||||
@@ -456,10 +505,12 @@ def brennenstuhl_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("brennenstuhl", BrennenstuhlAction, BRENNENSTUHL_SCHEMA)
|
||||
async def brennenstuhl_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, cg.uint32)
|
||||
cg.add(var.set_code(template_))
|
||||
register_protocol_action(
|
||||
"brennenstuhl",
|
||||
"Brennenstuhl",
|
||||
BRENNENSTUHL_SCHEMA,
|
||||
(CONF_CODE, "code", cg.uint32),
|
||||
)
|
||||
|
||||
|
||||
# ByronSX
|
||||
@@ -467,7 +518,7 @@ async def brennenstuhl_action(var, config, args):
|
||||
ByronSXData,
|
||||
ByronSXBinarySensor,
|
||||
ByronSXTrigger,
|
||||
ByronSXAction,
|
||||
_,
|
||||
ByronSXDumper,
|
||||
) = declare_protocol("ByronSX")
|
||||
BYRONSX_SCHEMA = cv.Schema(
|
||||
@@ -503,12 +554,13 @@ def byronsx_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("byronsx", ByronSXAction, BYRONSX_SCHEMA)
|
||||
async def byronsx_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint8)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"byronsx",
|
||||
"ByronSX",
|
||||
BYRONSX_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# CanalSat
|
||||
@@ -516,7 +568,7 @@ async def byronsx_action(var, config, args):
|
||||
CanalSatData,
|
||||
CanalSatBinarySensor,
|
||||
CanalSatTrigger,
|
||||
CanalSatAction,
|
||||
_,
|
||||
CanalSatDumper,
|
||||
) = declare_protocol("CanalSat")
|
||||
CANALSAT_SCHEMA = cv.Schema(
|
||||
@@ -552,21 +604,21 @@ def canalsat_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("canalsat", CanalSatAction, CANALSAT_SCHEMA)
|
||||
async def canalsat_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DEVICE], args, cg.uint8)
|
||||
cg.add(var.set_device(template_))
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint8)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"canalsat",
|
||||
"CanalSat",
|
||||
CANALSAT_SCHEMA,
|
||||
(CONF_DEVICE, "device", cg.uint8),
|
||||
(CONF_ADDRESS, "address", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
(
|
||||
CanalSatLDData,
|
||||
CanalSatLDBinarySensor,
|
||||
CanalSatLDTrigger,
|
||||
CanalSatLDAction,
|
||||
_,
|
||||
CanalSatLDDumper,
|
||||
) = declare_protocol("CanalSatLD")
|
||||
CANALSATLD_SCHEMA = cv.Schema(
|
||||
@@ -602,14 +654,14 @@ def canalsatld_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("canalsatld", CanalSatLDAction, CANALSATLD_SCHEMA)
|
||||
async def canalsatld_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DEVICE], args, cg.uint8)
|
||||
cg.add(var.set_device(template_))
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint8)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"canalsatld",
|
||||
"CanalSatLD",
|
||||
CANALSATLD_SCHEMA,
|
||||
(CONF_DEVICE, "device", cg.uint8),
|
||||
(CONF_ADDRESS, "address", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Coolix
|
||||
@@ -617,7 +669,7 @@ async def canalsatld_action(var, config, args):
|
||||
CoolixData,
|
||||
CoolixBinarySensor,
|
||||
CoolixTrigger,
|
||||
CoolixAction,
|
||||
_,
|
||||
CoolixDumper,
|
||||
) = declare_protocol("Coolix")
|
||||
|
||||
@@ -647,12 +699,13 @@ def coolix_binary_sensor(var, config):
|
||||
cg.add(var.set_data(cg.ArrayInitializer(0, config)))
|
||||
|
||||
|
||||
@register_action("coolix", CoolixAction, COOLIX_BASE_SCHEMA)
|
||||
async def coolix_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_FIRST], args, cg.uint32)
|
||||
cg.add(var.set_first(template_))
|
||||
template_ = await cg.templatable(config[CONF_SECOND], args, cg.uint32)
|
||||
cg.add(var.set_second(template_))
|
||||
register_protocol_action(
|
||||
"coolix",
|
||||
"Coolix",
|
||||
COOLIX_BASE_SCHEMA,
|
||||
(CONF_FIRST, "first", cg.uint32),
|
||||
(CONF_SECOND, "second", cg.uint32),
|
||||
)
|
||||
|
||||
|
||||
@register_trigger("coolix", CoolixTrigger, CoolixData)
|
||||
@@ -666,9 +719,7 @@ def coolix_dumper(var, config):
|
||||
|
||||
|
||||
# Dish
|
||||
DishData, DishBinarySensor, DishTrigger, DishAction, DishDumper = declare_protocol(
|
||||
"Dish"
|
||||
)
|
||||
DishData, DishBinarySensor, DishTrigger, _, DishDumper = declare_protocol("Dish")
|
||||
DISH_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_ADDRESS, default=1): cv.int_range(min=1, max=16),
|
||||
@@ -700,18 +751,17 @@ def dish_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("dish", DishAction, DISH_SCHEMA)
|
||||
async def dish_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint8)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"dish",
|
||||
"Dish",
|
||||
DISH_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Dooya
|
||||
DooyaData, DooyaBinarySensor, DooyaTrigger, DooyaAction, DooyaDumper = declare_protocol(
|
||||
"Dooya"
|
||||
)
|
||||
DooyaData, DooyaBinarySensor, DooyaTrigger, _, DooyaDumper = declare_protocol("Dooya")
|
||||
DOOYA_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.hex_int_range(0, 16777215),
|
||||
@@ -747,22 +797,19 @@ def dooya_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("dooya", DooyaAction, DOOYA_SCHEMA)
|
||||
async def dooya_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ID], args, cg.uint32)
|
||||
cg.add(var.set_id(template_))
|
||||
template_ = await cg.templatable(config[CONF_CHANNEL], args, cg.uint8)
|
||||
cg.add(var.set_channel(template_))
|
||||
template_ = await cg.templatable(config[CONF_BUTTON], args, cg.uint8)
|
||||
cg.add(var.set_button(template_))
|
||||
template_ = await cg.templatable(config[CONF_CHECK], args, cg.uint8)
|
||||
cg.add(var.set_check(template_))
|
||||
register_protocol_action(
|
||||
"dooya",
|
||||
"Dooya",
|
||||
DOOYA_SCHEMA,
|
||||
(CONF_ID, "id", cg.uint32),
|
||||
(CONF_CHANNEL, "channel", cg.uint8),
|
||||
(CONF_BUTTON, "button", cg.uint8),
|
||||
(CONF_CHECK, "check", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Dyson
|
||||
DysonData, DysonBinarySensor, DysonTrigger, DysonAction, DysonDumper = declare_protocol(
|
||||
"Dyson"
|
||||
)
|
||||
DysonData, DysonBinarySensor, DysonTrigger, _, DysonDumper = declare_protocol("Dyson")
|
||||
DYSON_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_CODE): cv.hex_uint16_t,
|
||||
@@ -794,16 +841,17 @@ def dyson_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("dyson", DysonAction, DYSON_SCHEMA)
|
||||
async def dyson_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, cg.uint16)
|
||||
cg.add(var.set_code(template_))
|
||||
template_ = await cg.templatable(config[CONF_INDEX], args, cg.uint8)
|
||||
cg.add(var.set_index(template_))
|
||||
register_protocol_action(
|
||||
"dyson",
|
||||
"Dyson",
|
||||
DYSON_SCHEMA,
|
||||
(CONF_CODE, "code", cg.uint16),
|
||||
(CONF_INDEX, "index", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# JVC
|
||||
JVCData, JVCBinarySensor, JVCTrigger, JVCAction, JVCDumper = declare_protocol("JVC")
|
||||
JVCData, JVCBinarySensor, JVCTrigger, _, JVCDumper = declare_protocol("JVC")
|
||||
JVC_SCHEMA = cv.Schema({cv.Required(CONF_DATA): cv.hex_uint32_t})
|
||||
|
||||
|
||||
@@ -829,14 +877,16 @@ def jvc_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("jvc", JVCAction, JVC_SCHEMA)
|
||||
async def jvc_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint32)
|
||||
cg.add(var.set_data(template_))
|
||||
register_protocol_action(
|
||||
"jvc",
|
||||
"JVC",
|
||||
JVC_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint32),
|
||||
)
|
||||
|
||||
|
||||
# LG
|
||||
LGData, LGBinarySensor, LGTrigger, LGAction, LGDumper = declare_protocol("LG")
|
||||
LGData, LGBinarySensor, LGTrigger, _, LGDumper = declare_protocol("LG")
|
||||
LG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_DATA): cv.hex_uint32_t,
|
||||
@@ -868,12 +918,13 @@ def lg_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("lg", LGAction, LG_SCHEMA)
|
||||
async def lg_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint32)
|
||||
cg.add(var.set_data(template_))
|
||||
template_ = await cg.templatable(config[CONF_NBITS], args, cg.uint8)
|
||||
cg.add(var.set_nbits(template_))
|
||||
register_protocol_action(
|
||||
"lg",
|
||||
"LG",
|
||||
LG_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint32),
|
||||
(CONF_NBITS, "nbits", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# MagiQuest
|
||||
@@ -881,7 +932,7 @@ async def lg_action(var, config, args):
|
||||
MagiQuestData,
|
||||
MagiQuestBinarySensor,
|
||||
MagiQuestTrigger,
|
||||
MagiQuestAction,
|
||||
_,
|
||||
MagiQuestDumper,
|
||||
) = declare_protocol("MagiQuest")
|
||||
|
||||
@@ -916,12 +967,13 @@ def magiquest_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("magiquest", MagiQuestAction, MAGIQUEST_SCHEMA)
|
||||
async def magiquest_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_WAND_ID], args, cg.uint32)
|
||||
cg.add(var.set_wand_id(template_))
|
||||
template_ = await cg.templatable(config[CONF_MAGNITUDE], args, cg.uint16)
|
||||
cg.add(var.set_magnitude(template_))
|
||||
register_protocol_action(
|
||||
"magiquest",
|
||||
"MagiQuest",
|
||||
MAGIQUEST_SCHEMA,
|
||||
(CONF_WAND_ID, "wand_id", cg.uint32),
|
||||
(CONF_MAGNITUDE, "magnitude", cg.uint16),
|
||||
)
|
||||
|
||||
|
||||
# Microchip HCS301 KeeLoq OOK
|
||||
@@ -929,7 +981,7 @@ async def magiquest_action(var, config, args):
|
||||
KeeloqData,
|
||||
KeeloqBinarySensor,
|
||||
KeeloqTrigger,
|
||||
KeeloqAction,
|
||||
_,
|
||||
KeeloqDumper,
|
||||
) = declare_protocol("Keeloq")
|
||||
KEELOQ_SCHEMA = cv.Schema(
|
||||
@@ -947,8 +999,8 @@ KEELOQ_SCHEMA = cv.Schema(
|
||||
|
||||
def _keeloq_suffix_fits(config: ConfigType) -> ConfigType:
|
||||
# A lambda is only known on the device. A plain value has to fit the width.
|
||||
suffix = config[CONF_SUFFIX]
|
||||
bits = config[CONF_SUFFIX_BITS]
|
||||
suffix = config.get(CONF_SUFFIX, 0)
|
||||
bits = config.get(CONF_SUFFIX_BITS, 0)
|
||||
if isinstance(suffix, int) and isinstance(bits, int) and suffix >> bits:
|
||||
raise cv.Invalid(
|
||||
f"suffix 0x{suffix:X} does not fit in {bits} suffix_bits", [CONF_SUFFIX]
|
||||
@@ -958,10 +1010,9 @@ def _keeloq_suffix_fits(config: ConfigType) -> ConfigType:
|
||||
|
||||
KEELOQ_ACTION_SCHEMA = KEELOQ_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_SUFFIX, default=0): cv.All(
|
||||
cv.hex_int, cv.Range(min=0, max=0xFFFF)
|
||||
),
|
||||
cv.Optional(CONF_SUFFIX_BITS, default=0): cv.int_range(min=0, max=16),
|
||||
# No defaults: an absent key leaves the data at 0 and emits nothing.
|
||||
cv.Optional(CONF_SUFFIX): cv.All(cv.hex_int, cv.Range(min=0, max=0xFFFF)),
|
||||
cv.Optional(CONF_SUFFIX_BITS): cv.int_range(min=0, max=16),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -989,28 +1040,22 @@ def keeloq_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action(
|
||||
"keeloq", KeeloqAction, KEELOQ_ACTION_SCHEMA, validate=_keeloq_suffix_fits
|
||||
register_protocol_action(
|
||||
"keeloq",
|
||||
"Keeloq",
|
||||
KEELOQ_ACTION_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint32),
|
||||
(CONF_CODE, "encrypted", cg.uint32),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
(CONF_LEVEL, "vlow", cg.bool_),
|
||||
(CONF_SUFFIX, "suffix", cg.uint16),
|
||||
(CONF_SUFFIX_BITS, "suffix_bits", cg.uint8),
|
||||
validate=_keeloq_suffix_fits,
|
||||
)
|
||||
async def keeloq_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint32)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, cg.uint32)
|
||||
cg.add(var.set_encrypted(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
template_ = await cg.templatable(config[CONF_LEVEL], args, cg.bool_)
|
||||
cg.add(var.set_vlow(template_))
|
||||
# Without suffix bits nothing of the suffix is sent, so both stay at their C++ default.
|
||||
if (suffix_bits := config[CONF_SUFFIX_BITS]) != 0:
|
||||
template_ = await cg.templatable(config[CONF_SUFFIX], args, cg.uint16)
|
||||
cg.add(var.set_suffix(template_))
|
||||
template_ = await cg.templatable(suffix_bits, args, cg.uint8)
|
||||
cg.add(var.set_suffix_bits(template_))
|
||||
|
||||
|
||||
# NEC
|
||||
NECData, NECBinarySensor, NECTrigger, NECAction, NECDumper = declare_protocol("NEC")
|
||||
NECData, NECBinarySensor, NECTrigger, _, NECDumper = declare_protocol("NEC")
|
||||
NEC_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
||||
@@ -1044,19 +1089,19 @@ def nec_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("nec", NECAction, NEC_SCHEMA)
|
||||
async def nec_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint16)
|
||||
cg.add(var.set_command(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND_REPEATS], args, cg.uint16)
|
||||
cg.add(var.set_command_repeats(template_))
|
||||
register_protocol_action(
|
||||
"nec",
|
||||
"NEC",
|
||||
NEC_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint16),
|
||||
(CONF_COMMAND, "command", cg.uint16),
|
||||
(CONF_COMMAND_REPEATS, "command_repeats", cg.uint16),
|
||||
)
|
||||
|
||||
|
||||
# Onkyo RI
|
||||
OnkyoRIData, OnkyoRIBinarySensor, OnkyoRITrigger, OnkyoRIAction, OnkyoRIDumper = (
|
||||
declare_protocol("OnkyoRI")
|
||||
OnkyoRIData, OnkyoRIBinarySensor, OnkyoRITrigger, _, OnkyoRIDumper = declare_protocol(
|
||||
"OnkyoRI"
|
||||
)
|
||||
ONKYORI_SCHEMA = cv.Schema({cv.Required(CONF_DATA): cv.hex_int_range(0, 0xFFF)})
|
||||
|
||||
@@ -1083,12 +1128,12 @@ def onkyori_dumper(var: MockObj, config: ConfigType) -> None:
|
||||
"""The dumper takes no options."""
|
||||
|
||||
|
||||
@register_action("onkyori", OnkyoRIAction, ONKYORI_SCHEMA)
|
||||
async def onkyori_action(
|
||||
var: MockObj, config: ConfigType, args: TemplateArgsType
|
||||
) -> None:
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint16)
|
||||
cg.add(var.set_data(template_))
|
||||
register_protocol_action(
|
||||
"onkyori",
|
||||
"OnkyoRI",
|
||||
ONKYORI_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint16),
|
||||
)
|
||||
|
||||
|
||||
# Pioneer
|
||||
@@ -1096,7 +1141,7 @@ async def onkyori_action(
|
||||
PioneerData,
|
||||
PioneerBinarySensor,
|
||||
PioneerTrigger,
|
||||
PioneerAction,
|
||||
_,
|
||||
PioneerDumper,
|
||||
) = declare_protocol("Pioneer")
|
||||
PIONEER_SCHEMA = cv.Schema(
|
||||
@@ -1130,12 +1175,13 @@ def pioneer_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("pioneer", PioneerAction, PIONEER_SCHEMA)
|
||||
async def pioneer_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_1], args, cg.uint16)
|
||||
cg.add(var.set_rc_code_1(template_))
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_2], args, cg.uint16)
|
||||
cg.add(var.set_rc_code_2(template_))
|
||||
register_protocol_action(
|
||||
"pioneer",
|
||||
"Pioneer",
|
||||
PIONEER_SCHEMA,
|
||||
(CONF_RC_CODE_1, "rc_code_1", cg.uint16),
|
||||
(CONF_RC_CODE_2, "rc_code_2", cg.uint16),
|
||||
)
|
||||
|
||||
|
||||
# Pronto
|
||||
@@ -1188,7 +1234,7 @@ async def pronto_action(var, config, args):
|
||||
GoboxData,
|
||||
GoboxBinarySensor,
|
||||
GoboxTrigger,
|
||||
GoboxAction,
|
||||
_,
|
||||
GoboxDumper,
|
||||
) = declare_protocol("Gobox")
|
||||
GOBOX_SCHEMA = cv.Schema(
|
||||
@@ -1220,10 +1266,12 @@ def gobox_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("gobox", GoboxAction, GOBOX_SCHEMA)
|
||||
async def gobox_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, cg.uint64)
|
||||
cg.add(var.set_code(template_))
|
||||
register_protocol_action(
|
||||
"gobox",
|
||||
"Gobox",
|
||||
GOBOX_SCHEMA,
|
||||
(CONF_CODE, "code", cg.uint64),
|
||||
)
|
||||
|
||||
|
||||
# Roomba
|
||||
@@ -1231,7 +1279,7 @@ async def gobox_action(var, config, args):
|
||||
RoombaData,
|
||||
RoombaBinarySensor,
|
||||
RoombaTrigger,
|
||||
RoombaAction,
|
||||
_,
|
||||
RoombaDumper,
|
||||
) = declare_protocol("Roomba")
|
||||
ROOMBA_SCHEMA = cv.Schema({cv.Required(CONF_DATA): cv.hex_uint8_t})
|
||||
@@ -1259,16 +1307,16 @@ def roomba_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("roomba", RoombaAction, ROOMBA_SCHEMA)
|
||||
async def roomba_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint8)
|
||||
cg.add(var.set_data(template_))
|
||||
register_protocol_action(
|
||||
"roomba",
|
||||
"Roomba",
|
||||
ROOMBA_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Sony
|
||||
SonyData, SonyBinarySensor, SonyTrigger, SonyAction, SonyDumper = declare_protocol(
|
||||
"Sony"
|
||||
)
|
||||
SonyData, SonyBinarySensor, SonyTrigger, _, SonyDumper = declare_protocol("Sony")
|
||||
SONY_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_DATA): cv.hex_uint32_t,
|
||||
@@ -1300,16 +1348,17 @@ def sony_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("sony", SonyAction, SONY_SCHEMA)
|
||||
async def sony_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint32)
|
||||
cg.add(var.set_data(template_))
|
||||
template_ = await cg.templatable(config[CONF_NBITS], args, cg.uint8)
|
||||
cg.add(var.set_nbits(template_))
|
||||
register_protocol_action(
|
||||
"sony",
|
||||
"Sony",
|
||||
SONY_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint32),
|
||||
(CONF_NBITS, "nbits", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Symphony
|
||||
SymphonyData, SymphonyBinarySensor, SymphonyTrigger, SymphonyAction, SymphonyDumper = (
|
||||
SymphonyData, SymphonyBinarySensor, SymphonyTrigger, _, SymphonyDumper = (
|
||||
declare_protocol("Symphony")
|
||||
)
|
||||
SYMPHONY_SCHEMA = cv.Schema(
|
||||
@@ -1344,14 +1393,14 @@ def symphony_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("symphony", SymphonyAction, SYMPHONY_SCHEMA)
|
||||
async def symphony_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint32)
|
||||
cg.add(var.set_data(template_))
|
||||
template_ = await cg.templatable(config[CONF_NBITS], args, cg.uint8)
|
||||
cg.add(var.set_nbits(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND_REPEATS], args, cg.uint8)
|
||||
cg.add(var.set_repeats(template_))
|
||||
register_protocol_action(
|
||||
"symphony",
|
||||
"Symphony",
|
||||
SYMPHONY_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint32),
|
||||
(CONF_NBITS, "nbits", cg.uint8),
|
||||
(CONF_COMMAND_REPEATS, "repeats", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Raw
|
||||
@@ -1430,7 +1479,7 @@ async def raw_action(var, config, args):
|
||||
DraytonData,
|
||||
DraytonBinarySensor,
|
||||
DraytonTrigger,
|
||||
DraytonAction,
|
||||
_,
|
||||
DraytonDumper,
|
||||
) = declare_protocol("Drayton")
|
||||
DRAYTON_SCHEMA = cv.Schema(
|
||||
@@ -1466,18 +1515,18 @@ def drayton_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("drayton", DraytonAction, DRAYTON_SCHEMA)
|
||||
async def drayton_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_CHANNEL], args, cg.uint8)
|
||||
cg.add(var.set_channel(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"drayton",
|
||||
"Drayton",
|
||||
DRAYTON_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint16),
|
||||
(CONF_CHANNEL, "channel", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# RC5
|
||||
RC5Data, RC5BinarySensor, RC5Trigger, RC5Action, RC5Dumper = declare_protocol("RC5")
|
||||
RC5Data, RC5BinarySensor, RC5Trigger, _, RC5Dumper = declare_protocol("RC5")
|
||||
RC5_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ADDRESS): cv.All(cv.hex_int, cv.Range(min=0, max=0x1F)),
|
||||
@@ -1509,12 +1558,13 @@ def rc5_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("rc5", RC5Action, RC5_SCHEMA)
|
||||
async def rc5_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint8)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"rc5",
|
||||
"RC5",
|
||||
RC5_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# RC6
|
||||
@@ -1873,7 +1923,7 @@ def rc_switch_dumper(var, config):
|
||||
SamsungData,
|
||||
SamsungBinarySensor,
|
||||
SamsungTrigger,
|
||||
SamsungAction,
|
||||
_,
|
||||
SamsungDumper,
|
||||
) = declare_protocol("Samsung")
|
||||
SAMSUNG_SCHEMA = cv.Schema(
|
||||
@@ -1907,12 +1957,13 @@ def samsung_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("samsung", SamsungAction, SAMSUNG_SCHEMA)
|
||||
async def samsung_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint64)
|
||||
cg.add(var.set_data(template_))
|
||||
template_ = await cg.templatable(config[CONF_NBITS], args, cg.uint8)
|
||||
cg.add(var.set_nbits(template_))
|
||||
register_protocol_action(
|
||||
"samsung",
|
||||
"Samsung",
|
||||
SAMSUNG_SCHEMA,
|
||||
(CONF_DATA, "data", cg.uint64),
|
||||
(CONF_NBITS, "nbits", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Samsung36
|
||||
@@ -1920,7 +1971,7 @@ async def samsung_action(var, config, args):
|
||||
Samsung36Data,
|
||||
Samsung36BinarySensor,
|
||||
Samsung36Trigger,
|
||||
Samsung36Action,
|
||||
_,
|
||||
Samsung36Dumper,
|
||||
) = declare_protocol("Samsung36")
|
||||
SAMSUNG36_SCHEMA = cv.Schema(
|
||||
@@ -1954,12 +2005,13 @@ def samsung36_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("samsung36", Samsung36Action, SAMSUNG36_SCHEMA)
|
||||
async def samsung36_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint32)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"samsung36",
|
||||
"Samsung36",
|
||||
SAMSUNG36_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint16),
|
||||
(CONF_COMMAND, "command", cg.uint32),
|
||||
)
|
||||
|
||||
|
||||
# Toshiba AC
|
||||
@@ -1967,7 +2019,7 @@ async def samsung36_action(var, config, args):
|
||||
ToshibaAcData,
|
||||
ToshibaAcBinarySensor,
|
||||
ToshibaAcTrigger,
|
||||
ToshibaAcAction,
|
||||
_,
|
||||
ToshibaAcDumper,
|
||||
) = declare_protocol("ToshibaAc")
|
||||
TOSHIBAAC_SCHEMA = cv.Schema(
|
||||
@@ -2001,12 +2053,13 @@ def toshibaac_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("toshiba_ac", ToshibaAcAction, TOSHIBAAC_SCHEMA)
|
||||
async def toshibaac_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_1], args, cg.uint64)
|
||||
cg.add(var.set_rc_code_1(template_))
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_2], args, cg.uint64)
|
||||
cg.add(var.set_rc_code_2(template_))
|
||||
register_protocol_action(
|
||||
"toshiba_ac",
|
||||
"ToshibaAc",
|
||||
TOSHIBAAC_SCHEMA,
|
||||
(CONF_RC_CODE_1, "rc_code_1", cg.uint64),
|
||||
(CONF_RC_CODE_2, "rc_code_2", cg.uint64),
|
||||
)
|
||||
|
||||
|
||||
# Panasonic
|
||||
@@ -2014,7 +2067,7 @@ async def toshibaac_action(var, config, args):
|
||||
PanasonicData,
|
||||
PanasonicBinarySensor,
|
||||
PanasonicTrigger,
|
||||
PanasonicAction,
|
||||
_,
|
||||
PanasonicDumper,
|
||||
) = declare_protocol("Panasonic")
|
||||
PANASONIC_SCHEMA = cv.Schema(
|
||||
@@ -2048,18 +2101,17 @@ def panasonic_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("panasonic", PanasonicAction, PANASONIC_SCHEMA)
|
||||
async def panasonic_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16)
|
||||
cg.add(var.set_address(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint32)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"panasonic",
|
||||
"Panasonic",
|
||||
PANASONIC_SCHEMA,
|
||||
(CONF_ADDRESS, "address", cg.uint16),
|
||||
(CONF_COMMAND, "command", cg.uint32),
|
||||
)
|
||||
|
||||
|
||||
# Nexa
|
||||
NexaData, NexaBinarySensor, NexaTrigger, NexaAction, NexaDumper = declare_protocol(
|
||||
"Nexa"
|
||||
)
|
||||
NexaData, NexaBinarySensor, NexaTrigger, _, NexaDumper = declare_protocol("Nexa")
|
||||
NEXA_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_DEVICE): cv.hex_uint32_t,
|
||||
@@ -2097,13 +2149,16 @@ def nexa_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("nexa", NexaAction, NEXA_SCHEMA)
|
||||
async def nexa_action(var, config, args):
|
||||
cg.add(var.set_device(await cg.templatable(config[CONF_DEVICE], args, cg.uint32)))
|
||||
cg.add(var.set_group(await cg.templatable(config[CONF_GROUP], args, cg.uint8)))
|
||||
cg.add(var.set_state(await cg.templatable(config[CONF_STATE], args, cg.uint8)))
|
||||
cg.add(var.set_channel(await cg.templatable(config[CONF_CHANNEL], args, cg.uint8)))
|
||||
cg.add(var.set_level(await cg.templatable(config[CONF_LEVEL], args, cg.uint8)))
|
||||
register_protocol_action(
|
||||
"nexa",
|
||||
"Nexa",
|
||||
NEXA_SCHEMA,
|
||||
(CONF_DEVICE, "device", cg.uint32),
|
||||
(CONF_GROUP, "group", cg.uint8),
|
||||
(CONF_STATE, "state", cg.uint8),
|
||||
(CONF_CHANNEL, "channel", cg.uint8),
|
||||
(CONF_LEVEL, "level", cg.uint8),
|
||||
)
|
||||
|
||||
|
||||
# Midea
|
||||
@@ -2210,7 +2265,7 @@ async def aeha_action(var, config, args):
|
||||
Hob2HoodData,
|
||||
Hob2HoodBinarySensor,
|
||||
Hob2HoodTrigger,
|
||||
Hob2HoodAction,
|
||||
_,
|
||||
Hob2HoodDumper,
|
||||
) = declare_protocol("Hob2Hood")
|
||||
|
||||
@@ -2252,12 +2307,12 @@ def hob2hood_dumper(var: MockObj, config: ConfigType) -> None:
|
||||
"""The dumper takes no options."""
|
||||
|
||||
|
||||
@register_action("hob2hood", Hob2HoodAction, HOB2HOOD_SCHEMA)
|
||||
async def hob2hood_action(
|
||||
var: MockObj, config: ConfigType, args: TemplateArgsType
|
||||
) -> None:
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, Hob2HoodCommand)
|
||||
cg.add(var.set_command(template_))
|
||||
register_protocol_action(
|
||||
"hob2hood",
|
||||
"Hob2Hood",
|
||||
HOB2HOOD_SCHEMA,
|
||||
(CONF_COMMAND, "command", Hob2HoodCommand),
|
||||
)
|
||||
|
||||
|
||||
# Haier
|
||||
@@ -2446,7 +2501,7 @@ async def mirage_action(var, config, args):
|
||||
TotoData,
|
||||
TotoBinarySensor,
|
||||
TotoTrigger,
|
||||
TotoAction,
|
||||
_,
|
||||
TotoDumper,
|
||||
) = declare_protocol("Toto")
|
||||
|
||||
@@ -2483,17 +2538,19 @@ def toto_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
@register_action("toto", TotoAction, TOTO_SCHEMA)
|
||||
async def Toto_action(var, config, args):
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_1], args, cg.uint8)
|
||||
cg.add(var.set_rc_code_1(template_))
|
||||
template_ = await cg.templatable(config[CONF_RC_CODE_2], args, cg.uint8)
|
||||
cg.add(var.set_rc_code_2(template_))
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
# Set toto-specific defaults (only if user didn't configure repeat)
|
||||
if CONF_REPEAT not in config:
|
||||
template_ = await cg.templatable(3, args, cg.uint32)
|
||||
cg.add(var.set_send_times(template_))
|
||||
template_ = await cg.templatable(36000, args, cg.uint32)
|
||||
cg.add(var.set_send_wait(template_))
|
||||
def _toto_default_repeat(config: ConfigType) -> ConfigType:
|
||||
# Toto remotes send each frame 3 times, 36 ms apart
|
||||
if CONF_REPEAT in config:
|
||||
return config
|
||||
return {**config, CONF_REPEAT: {CONF_TIMES: 3, CONF_WAIT_TIME: 36000}}
|
||||
|
||||
|
||||
register_protocol_action(
|
||||
"toto",
|
||||
"Toto",
|
||||
TOTO_SCHEMA,
|
||||
(CONF_RC_CODE_1, "rc_code_1", cg.uint8),
|
||||
(CONF_RC_CODE_2, "rc_code_2", cg.uint8),
|
||||
(CONF_COMMAND, "command", cg.uint8),
|
||||
validate=_toto_default_repeat,
|
||||
)
|
||||
|
||||
@@ -23,19 +23,4 @@ class Beo4Protocol : public RemoteProtocol<Beo4Data> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Beo4)
|
||||
|
||||
template<typename... Ts> class Beo4Action : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, source)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
TEMPLATABLE_VALUE(uint8_t, repeats)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
Beo4Data data{};
|
||||
data.source = this->source_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
data.repeats = this->repeats_.value(x...);
|
||||
Beo4Protocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -20,15 +20,4 @@ class BrennenstuhlProtocol : public RemoteProtocol<BrennenstuhlData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Brennenstuhl)
|
||||
|
||||
template<typename... Ts> class BrennenstuhlAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, code)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
BrennenstuhlData data{};
|
||||
data.code = this->code_.value(x...);
|
||||
BrennenstuhlProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -28,17 +28,4 @@ class ByronSXProtocol : public RemoteProtocol<ByronSXData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(ByronSX)
|
||||
|
||||
template<typename... Ts> class ByronSXAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
ByronSXData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
ByronSXProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -41,36 +41,6 @@ class CanalSatLDProtocol : public CanalSatBaseProtocol {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(CanalSat)
|
||||
|
||||
template<typename... Ts> class CanalSatAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, device)
|
||||
TEMPLATABLE_VALUE(uint8_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) {
|
||||
CanalSatData data{};
|
||||
data.device = this->device_.value(x...);
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
CanalSatProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(CanalSatLD)
|
||||
|
||||
template<typename... Ts> class CanalSatLDAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, device)
|
||||
TEMPLATABLE_VALUE(uint8_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) {
|
||||
CanalSatData data{};
|
||||
data.device = this->device_.value(x...);
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
CanalSatLDProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -28,12 +28,4 @@ class CoolixProtocol : public RemoteProtocol<CoolixData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Coolix)
|
||||
|
||||
template<typename... Ts> class CoolixAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
TEMPLATABLE_VALUE(uint32_t, first)
|
||||
TEMPLATABLE_VALUE(uint32_t, second)
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
CoolixProtocol().encode(dst, {this->first_.value(x...), this->second_.value(x...)});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -20,17 +20,4 @@ class DishProtocol : public RemoteProtocol<DishData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Dish)
|
||||
|
||||
template<typename... Ts> class DishAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
DishData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
DishProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -27,21 +27,4 @@ class DooyaProtocol : public RemoteProtocol<DooyaData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Dooya)
|
||||
|
||||
template<typename... Ts> class DooyaAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, id)
|
||||
TEMPLATABLE_VALUE(uint8_t, channel)
|
||||
TEMPLATABLE_VALUE(uint8_t, button)
|
||||
TEMPLATABLE_VALUE(uint8_t, check)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
DooyaData data{};
|
||||
data.id = this->id_.value(x...);
|
||||
data.channel = this->channel_.value(x...);
|
||||
data.button = this->button_.value(x...);
|
||||
data.check = this->check_.value(x...);
|
||||
DooyaProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -26,19 +26,4 @@ class DraytonProtocol : public RemoteProtocol<DraytonData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Drayton)
|
||||
|
||||
template<typename... Ts> class DraytonAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, channel)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
DraytonData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.channel = this->channel_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
DraytonProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -28,17 +28,4 @@ class DysonProtocol : public RemoteProtocol<DysonData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Dyson)
|
||||
|
||||
template<typename... Ts> class DysonAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, code)
|
||||
TEMPLATABLE_VALUE(uint8_t, index)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
DysonData data{};
|
||||
data.code = this->code_.value(x...);
|
||||
data.index = this->index_.value(x...);
|
||||
DysonProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -38,15 +38,4 @@ class GoboxProtocol : public RemoteProtocol<GoboxData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Gobox)
|
||||
|
||||
template<typename... Ts> class GoboxAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint64_t, code);
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
GoboxData data{};
|
||||
data.code = this->code_.value(x...);
|
||||
GoboxProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -28,12 +28,4 @@ class Hob2HoodProtocol : public RemoteProtocol<Hob2HoodData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Hob2Hood)
|
||||
|
||||
template<typename... Ts> class Hob2HoodAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(Hob2HoodCommand, command)
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
Hob2HoodProtocol().encode(dst, Hob2HoodData{this->command_.value(x...)});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -21,15 +21,4 @@ class JVCProtocol : public RemoteProtocol<JVCData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(JVC)
|
||||
|
||||
template<typename... Ts> class JVCAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, data)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
JVCData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
JVCProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -32,25 +32,4 @@ class KeeloqProtocol : public RemoteProtocol<KeeloqData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Keeloq)
|
||||
|
||||
template<typename... Ts> class KeeloqAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, address)
|
||||
TEMPLATABLE_VALUE(uint32_t, encrypted)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
TEMPLATABLE_VALUE(bool, vlow)
|
||||
TEMPLATABLE_VALUE(uint16_t, suffix)
|
||||
TEMPLATABLE_VALUE(uint8_t, suffix_bits)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
KeeloqData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.encrypted = this->encrypted_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
data.vlow = this->vlow_.value(x...);
|
||||
data.suffix = this->suffix_.value(x...);
|
||||
data.suffix_bits = this->suffix_bits_.value(x...);
|
||||
KeeloqProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -23,17 +23,4 @@ class LGProtocol : public RemoteProtocol<LGData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(LG)
|
||||
|
||||
template<typename... Ts> class LGAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, data)
|
||||
TEMPLATABLE_VALUE(uint8_t, nbits)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
LGData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
data.nbits = this->nbits_.value(x...);
|
||||
LGProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -34,17 +34,4 @@ class MagiQuestProtocol : public RemoteProtocol<MagiQuestData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(MagiQuest)
|
||||
|
||||
template<typename... Ts> class MagiQuestAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, magnitude)
|
||||
TEMPLATABLE_VALUE(uint32_t, wand_id)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
MagiQuestData data{};
|
||||
data.magnitude = this->magnitude_.value(x...);
|
||||
data.wand_id = this->wand_id_.value(x...);
|
||||
MagiQuestProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -21,19 +21,4 @@ class NECProtocol : public RemoteProtocol<NECData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(NEC)
|
||||
|
||||
template<typename... Ts> class NECAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, address)
|
||||
TEMPLATABLE_VALUE(uint16_t, command)
|
||||
TEMPLATABLE_VALUE(uint16_t, command_repeats)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
NECData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
data.command_repeats = this->command_repeats_.value(x...);
|
||||
NECProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -31,22 +31,4 @@ class NexaProtocol : public RemoteProtocol<NexaData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Nexa)
|
||||
|
||||
template<typename... Ts> class NexaAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, device)
|
||||
TEMPLATABLE_VALUE(uint8_t, group)
|
||||
TEMPLATABLE_VALUE(uint8_t, state)
|
||||
TEMPLATABLE_VALUE(uint8_t, channel)
|
||||
TEMPLATABLE_VALUE(uint8_t, level)
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
NexaData data{};
|
||||
data.device = this->device_.value(x...);
|
||||
data.group = this->group_.value(x...);
|
||||
data.state = this->state_.value(x...);
|
||||
data.channel = this->channel_.value(x...);
|
||||
data.level = this->level_.value(x...);
|
||||
NexaProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -19,15 +19,4 @@ class OnkyoRIProtocol : public RemoteProtocol<OnkyoRIData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(OnkyoRI)
|
||||
|
||||
template<typename... Ts> class OnkyoRIAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, data)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
OnkyoRIData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
OnkyoRIProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -23,17 +23,4 @@ class PanasonicProtocol : public RemoteProtocol<PanasonicData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Panasonic)
|
||||
|
||||
template<typename... Ts> class PanasonicAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, address)
|
||||
TEMPLATABLE_VALUE(uint32_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
PanasonicData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
PanasonicProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -20,17 +20,4 @@ class PioneerProtocol : public RemoteProtocol<PioneerData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Pioneer)
|
||||
|
||||
template<typename... Ts> class PioneerAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, rc_code_1)
|
||||
TEMPLATABLE_VALUE(uint16_t, rc_code_2)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
PioneerData data{};
|
||||
data.rc_code_1 = this->rc_code_1_.value(x...);
|
||||
data.rc_code_2 = this->rc_code_2_.value(x...);
|
||||
PioneerProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -21,17 +21,4 @@ class RC5Protocol : public RemoteProtocol<RC5Data> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(RC5)
|
||||
|
||||
template<typename... Ts> class RC5Action : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, address)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
RC5Data data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
RC5Protocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -182,6 +182,15 @@ bool RemoteTransmitData::set_data_from_base64url(const std::string &base64url) {
|
||||
|
||||
/* RemoteTransmitterBase */
|
||||
|
||||
void RemoteTransmitterBase::transmit_encoded_(EncodeFn encode, const void *data, uint32_t send_times,
|
||||
uint32_t send_wait) {
|
||||
auto call = this->transmit();
|
||||
encode(call.get_data(), data);
|
||||
call.set_send_times(send_times);
|
||||
call.set_send_wait(send_wait);
|
||||
call.perform();
|
||||
}
|
||||
|
||||
void RemoteTransmitterBase::send_(uint32_t send_times, uint32_t send_wait, [[maybe_unused]] uint16_t seq) {
|
||||
#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
|
||||
const auto &vec = this->temp_.get_data();
|
||||
|
||||
@@ -193,14 +193,34 @@ class RemoteTransmitterBase : public RemoteComponentBase {
|
||||
}
|
||||
template<RemoteProtocolEncoder Protocol>
|
||||
void transmit(const typename Protocol::ProtocolData &data, uint32_t send_times = 1, uint32_t send_wait = 0) {
|
||||
auto call = this->transmit();
|
||||
Protocol().encode(call.get_data(), data);
|
||||
call.set_send_times(send_times);
|
||||
call.set_send_wait(send_wait);
|
||||
call.perform();
|
||||
this->transmit_encoded_(&encode_thunk<Protocol>, &data, send_times, send_wait);
|
||||
}
|
||||
/// Protocol data filled field by field, then sent by perform(); the call a generated transmit action builds.
|
||||
template<RemoteProtocolEncoder Protocol> class ProtocolCall {
|
||||
public:
|
||||
explicit ProtocolCall(RemoteTransmitterBase *parent) : parent_(parent) {}
|
||||
void set_send_times(uint32_t send_times) { this->send_times_ = send_times; }
|
||||
void set_send_wait(uint32_t send_wait) { this->send_wait_ = send_wait; }
|
||||
void perform() { this->parent_->transmit<Protocol>(this->data, this->send_times_, this->send_wait_); }
|
||||
|
||||
typename Protocol::ProtocolData data{};
|
||||
|
||||
protected:
|
||||
RemoteTransmitterBase *parent_;
|
||||
uint32_t send_times_{1};
|
||||
uint32_t send_wait_{0};
|
||||
};
|
||||
template<RemoteProtocolEncoder Protocol> ProtocolCall<Protocol> protocol_call() {
|
||||
return ProtocolCall<Protocol>(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
using EncodeFn = void (*)(RemoteTransmitData *dst, const void *data);
|
||||
// One out-of-line send path, so each transmit<P>() call site only fills its data.
|
||||
void transmit_encoded_(EncodeFn encode, const void *data, uint32_t send_times, uint32_t send_wait);
|
||||
template<RemoteProtocolEncoder Protocol> static void encode_thunk(RemoteTransmitData *dst, const void *data) {
|
||||
Protocol().encode(dst, *static_cast<const typename Protocol::ProtocolData *>(data));
|
||||
}
|
||||
void send_(uint32_t send_times, uint32_t send_wait, uint16_t seq);
|
||||
virtual void send_internal(uint32_t send_times, uint32_t send_wait) = 0;
|
||||
/// Platforms that report completion later wait out the previous frame here, before send_()
|
||||
|
||||
@@ -19,15 +19,4 @@ class RoombaProtocol : public RemoteProtocol<RoombaData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Roomba)
|
||||
|
||||
template<typename... Ts> class RoombaAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, data)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
RoombaData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
RoombaProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -23,17 +23,4 @@ class Samsung36Protocol : public RemoteProtocol<Samsung36Data> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Samsung36)
|
||||
|
||||
template<typename... Ts> class Samsung36Action : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, address)
|
||||
TEMPLATABLE_VALUE(uint32_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
Samsung36Data data{};
|
||||
data.address = this->address_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
Samsung36Protocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -21,17 +21,4 @@ class SamsungProtocol : public RemoteProtocol<SamsungData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Samsung)
|
||||
|
||||
template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint64_t, data)
|
||||
TEMPLATABLE_VALUE(uint8_t, nbits)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
SamsungData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
data.nbits = this->nbits_.value(x...);
|
||||
SamsungProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -23,17 +23,4 @@ class SonyProtocol : public RemoteProtocol<SonyData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Sony)
|
||||
|
||||
template<typename... Ts> class SonyAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, data)
|
||||
TEMPLATABLE_VALUE(uint8_t, nbits)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
SonyData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
data.nbits = this->nbits_.value(x...);
|
||||
SonyProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -24,19 +24,4 @@ class SymphonyProtocol : public RemoteProtocol<SymphonyData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Symphony)
|
||||
|
||||
template<typename... Ts> class SymphonyAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, data)
|
||||
TEMPLATABLE_VALUE(uint8_t, nbits)
|
||||
TEMPLATABLE_VALUE(uint8_t, repeats)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
SymphonyData data{};
|
||||
data.data = this->data_.value(x...);
|
||||
data.nbits = this->nbits_.value(x...);
|
||||
data.repeats = this->repeats_.value(x...);
|
||||
SymphonyProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -21,17 +21,4 @@ class ToshibaAcProtocol : public RemoteProtocol<ToshibaAcData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(ToshibaAc)
|
||||
|
||||
template<typename... Ts> class ToshibaAcAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint64_t, rc_code_1)
|
||||
TEMPLATABLE_VALUE(uint64_t, rc_code_2)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
ToshibaAcData data{};
|
||||
data.rc_code_1 = this->rc_code_1_.value(x...);
|
||||
data.rc_code_2 = this->rc_code_2_.value(x...);
|
||||
ToshibaAcProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -23,19 +23,4 @@ class TotoProtocol : public RemoteProtocol<TotoData> {
|
||||
|
||||
DECLARE_REMOTE_PROTOCOL(Toto)
|
||||
|
||||
template<typename... Ts> class TotoAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint8_t, rc_code_1)
|
||||
TEMPLATABLE_VALUE(uint8_t, rc_code_2)
|
||||
TEMPLATABLE_VALUE(uint8_t, command)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
TotoData data{};
|
||||
data.rc_code_1 = this->rc_code_1_.value(x...);
|
||||
data.rc_code_2 = this->rc_code_2_.value(x...);
|
||||
data.command = this->command_.value(x...);
|
||||
TotoProtocol().encode(dst, data);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::remote_base
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
"""Helpers for the remote_transmitter component tests."""
|
||||
|
||||
import re
|
||||
|
||||
_PROTOCOL_CALL_BODY = re.compile(
|
||||
r"auto apply_call = \S+->protocol_call<remote_base::\w+>\(\);\n(.*?)apply_call\.perform\(\);",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def protocol_call_bodies(main_cpp: str) -> list[str]:
|
||||
"""The statements of each generated transmit action, in config order."""
|
||||
return _PROTOCOL_CALL_BODY.findall(main_cpp)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp8266:
|
||||
board: esp01_1m
|
||||
|
||||
remote_transmitter:
|
||||
pin: GPIO4
|
||||
carrier_duty_percent: 50%
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: Toto default repeat
|
||||
on_press:
|
||||
- remote_transmitter.transmit_toto:
|
||||
command: 0xEC
|
||||
rc_code_1: 0x0D
|
||||
rc_code_2: 0x0D
|
||||
- platform: template
|
||||
name: Toto explicit repeat
|
||||
on_press:
|
||||
- remote_transmitter.transmit_toto:
|
||||
command: 0xEC
|
||||
rc_code_1: 0x0D
|
||||
rc_code_2: 0x0D
|
||||
repeat:
|
||||
times: 2
|
||||
wait_time: 20ms
|
||||
- platform: template
|
||||
name: NEC default wait
|
||||
on_press:
|
||||
- remote_transmitter.transmit_nec:
|
||||
address: 0x4242
|
||||
command: 0x8484
|
||||
repeat: 4
|
||||
- platform: template
|
||||
name: NEC once
|
||||
on_press:
|
||||
- remote_transmitter.transmit_nec:
|
||||
address: 0x4242
|
||||
command: 0x8484
|
||||
@@ -1,18 +1,23 @@
|
||||
"""transmit_keeloq sets the suffix only when suffix bits are sent."""
|
||||
"""transmit_keeloq sets the suffix only when the config names it."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from tests.component_tests.remote_transmitter import protocol_call_bodies
|
||||
|
||||
def test_keeloq_suffix_is_set_only_with_suffix_bits(
|
||||
|
||||
def test_keeloq_suffix_is_set_only_when_configured(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
) -> None:
|
||||
main_cpp = generate_main(component_config_path("keeloq_suffix.yaml"))
|
||||
|
||||
# The plain word gets the same setters as before the suffix existed.
|
||||
assert "remote_base_keeloqaction_id->set_suffix" not in main_cpp
|
||||
# A constant and a lambda width both set the suffix.
|
||||
for action in ("remote_base_keeloqaction_id_2", "remote_base_keeloqaction_id_3"):
|
||||
assert f"{action}->set_suffix([]() -> uint16_t" in main_cpp
|
||||
assert f"{action}->set_suffix_bits([]() -> uint8_t" in main_cpp
|
||||
bodies = protocol_call_bodies(main_cpp)
|
||||
assert len(bodies) == 3
|
||||
plain, constant, lambda_ = bodies
|
||||
# The plain word fills only the HCS301 fields.
|
||||
assert "data.suffix" not in plain
|
||||
assert "apply_call.data.suffix = 0x2A;" in constant
|
||||
assert "apply_call.data.suffix_bits = 6;" in constant
|
||||
# A lambda is called inline.
|
||||
assert "apply_call.data.suffix = static_cast<uint16_t>(0x2A);" in lambda_
|
||||
assert "apply_call.data.suffix_bits = static_cast<uint8_t>(6);" in lambda_
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
"""repeat on a generated transmit action, and toto's default."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from tests.component_tests.remote_transmitter import protocol_call_bodies
|
||||
|
||||
|
||||
def test_transmit_repeat(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
) -> None:
|
||||
main_cpp = generate_main(component_config_path("transmit_repeat.yaml"))
|
||||
bodies = protocol_call_bodies(main_cpp)
|
||||
assert len(bodies) == 4
|
||||
toto_default, toto_explicit, nec_repeat, nec_once = bodies
|
||||
# toto sends 3 times 36 ms apart unless the config says otherwise.
|
||||
assert "apply_call.set_send_times(3);" in toto_default
|
||||
assert "apply_call.set_send_wait(36000);" in toto_default
|
||||
assert "apply_call.set_send_times(2);" in toto_explicit
|
||||
assert "apply_call.set_send_wait(20000);" in toto_explicit
|
||||
# A bare count gets the 25 ms default wait, in microseconds.
|
||||
assert "apply_call.set_send_times(4);" in nec_repeat
|
||||
assert "apply_call.set_send_wait(25000);" in nec_repeat
|
||||
# Without repeat neither setter is emitted; the call sends once.
|
||||
assert "set_send_times" not in nec_once
|
||||
assert "set_send_wait" not in nec_once
|
||||
Reference in New Issue
Block a user