From 899ed02ef2b57be8b4139cd53ebacc71e0aaa52e Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Mon, 27 Jul 2026 06:52:15 -0700 Subject: [PATCH] [remote_base] support haier short IR message (#17826) Co-authored-by: Samuel Sieb --- esphome/components/remote_base/__init__.py | 9 ++++++++- .../components/remote_base/haier_protocol.cpp | 18 +++++++++++++----- .../remote_transmitter/common-buttons.yaml | 17 ++++++++++++++++- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index cbf82e6f440..19b8549f75a 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -2012,7 +2012,14 @@ HaierData, HaierBinarySensor, HaierTrigger, HaierAction, HaierDumper = declare_p HaierAction = ns.class_("HaierAction", RemoteTransmitterActionBase) HAIER_SCHEMA = cv.Schema( { - cv.Required(CONF_CODE): cv.All([cv.hex_uint8_t], cv.Length(min=13, max=13)), + cv.Required(CONF_CODE): cv.All( + [cv.hex_uint8_t], + cv.Any( + cv.Length(min=8, max=8), + cv.Length(min=13, max=13), + msg="must be a list of length 8 or 13", + ), + ), } ) diff --git a/esphome/components/remote_base/haier_protocol.cpp b/esphome/components/remote_base/haier_protocol.cpp index fa4cec773ff..8801f1049af 100644 --- a/esphome/components/remote_base/haier_protocol.cpp +++ b/esphome/components/remote_base/haier_protocol.cpp @@ -11,9 +11,12 @@ constexpr uint32_t HEADER_HIGH_US = 4400; constexpr uint32_t BIT_MARK_US = 540; constexpr uint32_t BIT_ONE_SPACE_US = 1650; constexpr uint32_t BIT_ZERO_SPACE_US = 580; -constexpr unsigned int HAIER_IR_PACKET_BIT_SIZE = 112; +// 8 bytes + checksum +constexpr unsigned int HAIER_IR_PACKET_BIT_SIZE_SHORT = 72; +// 13 bytes + checksum +constexpr unsigned int HAIER_IR_PACKET_BIT_SIZE_LONG = 112; // Max data bytes in packet (excluding checksum) -constexpr size_t HAIER_MAX_DATA_BYTES = (HAIER_IR_PACKET_BIT_SIZE / 8); +constexpr size_t HAIER_MAX_DATA_BYTES = HAIER_IR_PACKET_BIT_SIZE_LONG / 8 - 1; void HaierProtocol::encode_byte_(RemoteTransmitData *dst, uint8_t item) { for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) { @@ -28,7 +31,7 @@ void HaierProtocol::encode_byte_(RemoteTransmitData *dst, uint8_t item) { void HaierProtocol::encode(RemoteTransmitData *dst, const HaierData &data) { dst->set_carrier_frequency(38000); - dst->reserve(5 + ((data.data.size() + 1) * 2)); + dst->reserve(5 + ((data.data.size() + 1) * 16)); dst->mark(HEADER_LOW_US); dst->space(HEADER_LOW_US); dst->mark(HEADER_LOW_US); @@ -50,11 +53,16 @@ optional HaierProtocol::decode(RemoteReceiveData src) { return {}; } size_t size = src.size() - src.get_index() - 1; - if (size < HAIER_IR_PACKET_BIT_SIZE * 2) + if (size >= HAIER_IR_PACKET_BIT_SIZE_LONG * 2) { + size = HAIER_IR_PACKET_BIT_SIZE_LONG * 2; + } else if (size >= HAIER_IR_PACKET_BIT_SIZE_SHORT * 2) { + size = HAIER_IR_PACKET_BIT_SIZE_SHORT * 2; + } else { return {}; - size = HAIER_IR_PACKET_BIT_SIZE * 2; + } uint8_t checksum = 0; HaierData out; + out.data.reserve(size / 16 - 1); while (size > 0) { uint8_t data = 0; for (uint8_t mask = 0x80; mask != 0; mask >>= 1) { diff --git a/tests/components/remote_transmitter/common-buttons.yaml b/tests/components/remote_transmitter/common-buttons.yaml index 5631c48f957..981946a9a4c 100644 --- a/tests/components/remote_transmitter/common-buttons.yaml +++ b/tests/components/remote_transmitter/common-buttons.yaml @@ -198,7 +198,7 @@ button: 0xFF, ] - platform: template - name: Haier + name: Haier Long on_press: remote_transmitter.transmit_haier: code: @@ -217,6 +217,21 @@ button: 0x00, 0x05, ] + - platform: template + name: Haier Short + on_press: + remote_transmitter.transmit_haier: + code: + [ + 0xA6, + 0xDA, + 0x00, + 0x00, + 0x40, + 0x40, + 0x00, + 0x80, + ] - platform: template name: Mirage on_press: