mirror of
https://github.com/esphome/esphome.git
synced 2026-10-10 05:23:07 +00:00
[remote_base] Keep constant IR codes in flash (#20083)
This commit is contained in:
@@ -2061,11 +2061,20 @@ def midea_dumper(var, config):
|
||||
pass
|
||||
|
||||
|
||||
async def _code_bytes(
|
||||
value: Any, args: TemplateArgsType, set_template: MockObj, set_static: MockObj
|
||||
) -> None:
|
||||
"""Constant codes share one PROGMEM table pool across the remote protocols."""
|
||||
await automation.templatable_bytes(
|
||||
value, args, set_template, set_static, "remote_base_code"
|
||||
)
|
||||
|
||||
|
||||
@register_action("midea", MideaAction, MIDEA_SCHEMA)
|
||||
async def midea_action(var, config, args):
|
||||
vec_ = cg.std_vector.template(cg.uint8)
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, vec_, vec_)
|
||||
cg.add(var.set_code(template_))
|
||||
await _code_bytes(
|
||||
config[CONF_CODE], args, var.set_code_template, var.set_code_static
|
||||
)
|
||||
|
||||
|
||||
# AEHA
|
||||
@@ -2117,10 +2126,9 @@ def aeha_dumper(var, config):
|
||||
async def aeha_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_DATA], args, cg.std_vector.template(cg.uint8)
|
||||
await _code_bytes(
|
||||
config[CONF_DATA], args, var.set_data_template, var.set_data_static
|
||||
)
|
||||
cg.add(var.set_data(template_))
|
||||
templ = await cg.templatable(config[CONF_CARRIER_FREQUENCY], args, cg.uint32)
|
||||
cg.add(var.set_carrier_frequency(templ))
|
||||
|
||||
@@ -2216,9 +2224,9 @@ def haier_dumper(var, config):
|
||||
|
||||
@register_action("haier", HaierAction, HAIER_SCHEMA)
|
||||
async def haier_action(var, config, args):
|
||||
vec_ = cg.std_vector.template(cg.uint8)
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, vec_, vec_)
|
||||
cg.add(var.set_code(template_))
|
||||
await _code_bytes(
|
||||
config[CONF_CODE], args, var.set_code_template, var.set_code_static
|
||||
)
|
||||
|
||||
|
||||
# ABBWelcome
|
||||
@@ -2359,9 +2367,9 @@ def mirage_dumper(var, config):
|
||||
|
||||
@register_action("mirage", MirageAction, MIRAGE_SCHEMA)
|
||||
async def mirage_action(var, config, args):
|
||||
vec_ = cg.std_vector.template(cg.uint8)
|
||||
template_ = await cg.templatable(config[CONF_CODE], args, vec_, vec_)
|
||||
cg.add(var.set_code(template_))
|
||||
await _code_bytes(
|
||||
config[CONF_CODE], args, var.set_code_template, var.set_code_static
|
||||
)
|
||||
|
||||
|
||||
# Toto
|
||||
|
||||
@@ -28,10 +28,9 @@ DECLARE_REMOTE_PROTOCOL(AEHA)
|
||||
template<typename... Ts> class AEHAAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint16_t, address)
|
||||
TEMPLATABLE_VALUE(std::vector<uint8_t>, data)
|
||||
TEMPLATABLE_BYTES(data)
|
||||
TEMPLATABLE_VALUE(uint32_t, carrier_frequency);
|
||||
|
||||
void set_data(const std::vector<uint8_t> &data) { data_ = data; }
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
AEHAData data{};
|
||||
data.address = this->address_.value(x...);
|
||||
|
||||
@@ -25,7 +25,7 @@ DECLARE_REMOTE_PROTOCOL(Haier)
|
||||
|
||||
template<typename... Ts> class HaierAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(std::vector<uint8_t>, code)
|
||||
TEMPLATABLE_BYTES(code)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
HaierData data{};
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "remote_base.h"
|
||||
|
||||
@@ -21,6 +22,9 @@ class MideaData {
|
||||
MideaData(const std::vector<uint8_t> &data) {
|
||||
std::copy_n(data.begin(), std::min(data.size(), this->data_.size()), this->data_.begin());
|
||||
}
|
||||
MideaData(const uint8_t *data, size_t len) {
|
||||
progmem_memcpy(this->data_.data(), data, std::min(len, this->data_.size()));
|
||||
}
|
||||
|
||||
uint8_t *data() { return this->data_.data(); }
|
||||
const uint8_t *data() const { return this->data_.data(); }
|
||||
@@ -75,10 +79,12 @@ class MideaProtocol : public RemoteProtocol<MideaData> {
|
||||
DECLARE_REMOTE_PROTOCOL(Midea)
|
||||
|
||||
template<typename... Ts> class MideaAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
TEMPLATABLE_VALUE(std::vector<uint8_t>, code)
|
||||
public:
|
||||
TEMPLATABLE_BYTES(code)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
MideaData data(this->code_.value(x...));
|
||||
MideaData data = this->code_.is_static() ? MideaData(this->code_.data(), this->code_.size())
|
||||
: MideaData(this->code_.value(x...));
|
||||
data.finalize();
|
||||
MideaProtocol().encode(dst, data);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ DECLARE_REMOTE_PROTOCOL(Mirage)
|
||||
|
||||
template<typename... Ts> class MirageAction : public RemoteTransmitterActionBase<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(std::vector<uint8_t>, code)
|
||||
TEMPLATABLE_BYTES(code)
|
||||
|
||||
void encode(RemoteTransmitData *dst, Ts... x) override {
|
||||
MirageData data{};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
|
||||
remote_transmitter:
|
||||
pin: GPIO4
|
||||
carrier_duty_percent: 50%
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: Midea A
|
||||
on_press:
|
||||
- remote_transmitter.transmit_midea:
|
||||
code: [0xA2, 0x08, 0xFF, 0xFF, 0xFF]
|
||||
- platform: template
|
||||
name: Midea B
|
||||
on_press:
|
||||
- remote_transmitter.transmit_midea:
|
||||
code: [0xA2, 0x08, 0xFF, 0xFF, 0xFF]
|
||||
- platform: template
|
||||
name: AEHA
|
||||
on_press:
|
||||
- remote_transmitter.transmit_aeha:
|
||||
address: 0x8008
|
||||
data: [0x00, 0x02, 0xFD, 0xFF, 0x00, 0x33]
|
||||
- platform: template
|
||||
name: Haier lambda
|
||||
on_press:
|
||||
- remote_transmitter.transmit_haier:
|
||||
code: !lambda |-
|
||||
return {0xA6, 0xDA, 0x00, 0x00};
|
||||
- platform: template
|
||||
name: Haier static
|
||||
on_press:
|
||||
- remote_transmitter.transmit_haier:
|
||||
code: [0xA6, 0xDA, 0x00, 0x00, 0x40, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x05]
|
||||
- platform: template
|
||||
name: Mirage static
|
||||
on_press:
|
||||
- remote_transmitter.transmit_mirage:
|
||||
code: [0x56, 0x6C, 0x00, 0x00, 0x20, 0x1A, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x42]
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Constant IR byte codes live in shared PROGMEM tables; lambdas stay lambdas."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
||||
def test_ir_codes_use_shared_progmem_tables(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
) -> None:
|
||||
main_cpp = generate_main(component_config_path("ir_codes.yaml"))
|
||||
|
||||
tables = re.findall(
|
||||
r"static constexpr uint8_t (remote_base_code\w*)\[\] PROGMEM", main_cpp
|
||||
)
|
||||
assert len(tables) == 4 # Midea (shared by two actions), AEHA, Haier, Mirage
|
||||
midea = tables[0]
|
||||
assert main_cpp.count(f"->set_code_static({midea}, 5);") == 2
|
||||
assert re.search(r"->set_data_static\(remote_base_code\w*, 6\);", main_cpp)
|
||||
assert re.search(r"->set_code_static\(remote_base_code\w*, 13\);", main_cpp)
|
||||
assert re.search(r"->set_code_static\(remote_base_code\w*, 14\);", main_cpp)
|
||||
assert "->set_code_template([](" in main_cpp
|
||||
assert "std::vector<uint8_t>{" not in main_cpp
|
||||
Reference in New Issue
Block a user