[remote_base] Dedupe dumpers, fold receiver attach into one helper, compile a bare receiver

This commit is contained in:
J. Nick Koston
2026-09-10 19:41:28 -05:00
parent 3bd2faf4a9
commit afd718ec3e
7 changed files with 46 additions and 22 deletions
@@ -1,6 +1,9 @@
"""IR/RF Proxy component - provides remote_base backend for infrared platform."""
import esphome.codegen as cg
from esphome.components import remote_base
from esphome.cpp_generator import MockObj
from esphome.types import ConfigType
CODEOWNERS = ["@kbx81"]
@@ -9,3 +12,10 @@ ir_rf_proxy_ns = cg.esphome_ns.namespace("ir_rf_proxy")
CONF_REMOTE_RECEIVER_ID = "remote_receiver_id"
CONF_REMOTE_TRANSMITTER_ID = "remote_transmitter_id"
async def attach_receiver(var: MockObj, config: ConfigType) -> None:
"""Wire the configured remote_receiver to a proxy entity and register it as a listener."""
receiver = await cg.get_variable(config[CONF_REMOTE_RECEIVER_ID])
cg.add(var.set_receiver(receiver))
remote_base.add_listener(receiver, var)
+8 -10
View File
@@ -3,18 +3,18 @@
from typing import Any
import esphome.codegen as cg
from esphome.components import (
infrared,
remote_base,
remote_receiver,
remote_transmitter,
)
from esphome.components import infrared, remote_receiver, remote_transmitter
from esphome.components.const import CONF_RECEIVER_FREQUENCY
import esphome.config_validation as cv
from esphome.const import CONF_CARRIER_DUTY_PERCENT, CONF_FREQUENCY
import esphome.final_validate as fv
from . import CONF_REMOTE_RECEIVER_ID, CONF_REMOTE_TRANSMITTER_ID, ir_rf_proxy_ns
from . import (
CONF_REMOTE_RECEIVER_ID,
CONF_REMOTE_TRANSMITTER_ID,
attach_receiver,
ir_rf_proxy_ns,
)
CODEOWNERS = ["@kbx81"]
DEPENDENCIES = ["infrared"]
@@ -87,9 +87,7 @@ async def to_code(config: dict[str, Any]) -> None:
# Link receiver if specified
if CONF_REMOTE_RECEIVER_ID in config:
receiver = await cg.get_variable(config[CONF_REMOTE_RECEIVER_ID])
cg.add(var.set_receiver(receiver))
remote_base.add_listener(receiver, var)
await attach_receiver(var, config)
# Set receiver demodulation frequency if specified (metadata only, no hardware effect)
if CONF_RECEIVER_FREQUENCY in config:
@@ -1,18 +1,18 @@
"""Radio Frequency platform implementation using remote_base (remote_transmitter/receiver)."""
import esphome.codegen as cg
from esphome.components import (
radio_frequency,
remote_base,
remote_receiver,
remote_transmitter,
)
from esphome.components import radio_frequency, remote_receiver, remote_transmitter
import esphome.config_validation as cv
from esphome.const import CONF_CARRIER_DUTY_PERCENT, CONF_FREQUENCY
import esphome.final_validate as fv
from esphome.types import ConfigType
from . import CONF_REMOTE_RECEIVER_ID, CONF_REMOTE_TRANSMITTER_ID, ir_rf_proxy_ns
from . import (
CONF_REMOTE_RECEIVER_ID,
CONF_REMOTE_TRANSMITTER_ID,
attach_receiver,
ir_rf_proxy_ns,
)
CODEOWNERS = ["@kbx81"]
DEPENDENCIES = ["radio_frequency"]
@@ -71,6 +71,4 @@ async def to_code(config: ConfigType) -> None:
cg.add(var.set_transmitter(transmitter))
if CONF_REMOTE_RECEIVER_ID in config:
receiver = await cg.get_variable(config[CONF_REMOTE_RECEIVER_ID])
cg.add(var.set_receiver(receiver))
remote_base.add_listener(receiver, var)
await attach_receiver(var, config)
@@ -231,6 +231,13 @@ DUMPER_REGISTRY = Registry()
def validate_dumpers(value):
if isinstance(value, str) and value.lower() == "all":
return validate_dumpers(list(DUMPER_REGISTRY.keys()))
if isinstance(value, list):
# a dumper listed twice would register twice; the receiver holds one secondary dumper
value = (
list(dict.fromkeys(value))
if all(isinstance(v, str) for v in value)
else value
)
return cv.validate_registry("dumper", DUMPER_REGISTRY)(value)
@@ -1,4 +1,6 @@
#include "rc_switch_protocol.h"
#include <iterator>
#include "esphome/core/log.h"
namespace esphome::remote_base {
@@ -113,7 +115,7 @@ bool RCSwitchBase::decode(RemoteReceiveData &src, uint64_t *out_data, uint8_t *o
optional<RCSwitchData> RCSwitchBase::decode(RemoteReceiveData &src) const {
RCSwitchData out;
uint8_t out_nbits;
for (uint8_t i = 1; i <= 8; i++) {
for (uint8_t i = 1; i < std::size(RC_SWITCH_PROTOCOLS); i++) {
src.reset();
const RCSwitchBase *protocol = &RC_SWITCH_PROTOCOLS[i];
if (protocol->decode(src, &out.code, &out_nbits) && out_nbits >= 3) {
@@ -226,7 +228,7 @@ bool RCSwitchRawReceiver::matches(RemoteReceiveData src) {
return decoded_nbits == this->nbits_ && (decoded_code & this->mask_) == (this->code_ & this->mask_);
}
bool RCSwitchDumper::dump(RemoteReceiveData src) {
for (uint8_t i = 1; i <= 8; i++) {
for (uint8_t i = 1; i < std::size(RC_SWITCH_PROTOCOLS); i++) {
src.reset();
uint64_t out_data;
uint8_t out_nbits;
@@ -0,0 +1,4 @@
# A receiver with no dumpers and no listeners compiles both lists out
remote_receiver:
- id: rcvr_bare
pin: ${pin}
@@ -0,0 +1,5 @@
substitutions:
pin: GPIO2
packages:
bare: !include bare-common.yaml