From 10f8d9193e79f694e3e5e2582155e429397e9842 Mon Sep 17 00:00:00 2001 From: Heggi Date: Thu, 4 Apr 2024 23:27:01 +0400 Subject: [PATCH 1/4] Mirage remote receiver & transmitter --- esphome/components/remote_base/__init__.py | 38 +++++++++ .../remote_base/mirage_protocol.cpp | 84 +++++++++++++++++++ .../components/remote_base/mirage_protocol.h | 39 +++++++++ tests/test1.yaml | 5 ++ 4 files changed, 166 insertions(+) create mode 100644 esphome/components/remote_base/mirage_protocol.cpp create mode 100644 esphome/components/remote_base/mirage_protocol.h diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index 6deab63c60..a4f42cd7a5 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -1874,3 +1874,41 @@ async def abbwelcome_action(var, config, args): cg.add(var.set_data_template(template_)) else: cg.add(var.set_data_static(data_)) + + +# Mirage +( + MirageData, + MirageBinarySensor, + MirageTrigger, + MirageAction, + MirageDumper, +) = declare_protocol("Mirage") + +MIRAGE_SCHEMA = cv.Schema( + { + cv.Required(CONF_CODE): cv.All([cv.hex_uint8_t], cv.Length(min=14, max=14)), + } +) + + +@register_binary_sensor("mirage", MirageBinarySensor, MIRAGE_SCHEMA) +def mirage_binary_sensor(var, config): + cg.add(var.set_code(config[CONF_CODE])) + + +@register_trigger("mirage", MirageTrigger, MirageData) +def mirage_trigger(var, config): + pass + + +@register_dumper("mirage", MirageDumper) +def mirage_dumper(var, config): + pass + + +@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_)) diff --git a/esphome/components/remote_base/mirage_protocol.cpp b/esphome/components/remote_base/mirage_protocol.cpp new file mode 100644 index 0000000000..10d644a1cd --- /dev/null +++ b/esphome/components/remote_base/mirage_protocol.cpp @@ -0,0 +1,84 @@ +#include "mirage_protocol.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace remote_base { + +static const char *const TAG = "remote.mirage"; + +constexpr uint32_t HEADER_MARK_US = 8360; +constexpr uint32_t HEADER_SPACE_US = 4248; +constexpr uint32_t BIT_MARK_US = 554; +constexpr uint32_t BIT_ONE_SPACE_US = 1592; +constexpr uint32_t BIT_ZERO_SPACE_US = 545; + +constexpr unsigned int MIRAGE_IR_PACKET_BIT_SIZE = 120; + +void MirageProtocol::encode(RemoteTransmitData *dst, const MirageData &data) { + ESP_LOGI(TAG, "Transive Mirage: %s", format_hex_pretty(data.data).c_str()); + dst->set_carrier_frequency(38000); + dst->reserve(5 + ((data.data.size() + 1) * 2)); + dst->mark(HEADER_MARK_US); + dst->space(HEADER_SPACE_US); + dst->mark(BIT_MARK_US); + uint8_t checksum = 0; + for (uint8_t item : data.data) { + this->encode_byte_(dst, item); + checksum += (item >> 4) + (item & 0xF); + } + this->encode_byte_(dst, checksum); +} + +void MirageProtocol::encode_byte_(RemoteTransmitData *dst, uint8_t item) { + for (uint8_t b = 0; b < 8; b++) { + if (item & (1UL << b)) { + dst->space(BIT_ONE_SPACE_US); + } else { + dst->space(BIT_ZERO_SPACE_US); + } + dst->mark(BIT_MARK_US); + } +} + +optional MirageProtocol::decode(RemoteReceiveData src) { + if (!src.expect_item(HEADER_MARK_US, HEADER_SPACE_US)) { + return {}; + } + if (!src.expect_mark(BIT_MARK_US)) { + return {}; + } + size_t size = src.size() - src.get_index() - 1; + if (size < MIRAGE_IR_PACKET_BIT_SIZE * 2) + return {}; + size = MIRAGE_IR_PACKET_BIT_SIZE * 2; + uint8_t checksum = 0; + MirageData out; + while (size > 0) { + uint8_t data = 0; + for (uint8_t b = 0; b < 8; b++) { + if (src.expect_space(BIT_ONE_SPACE_US)) { + data |= (1UL << b); + } else if (!src.expect_space(BIT_ZERO_SPACE_US)) { + return {}; + } + if (!src.expect_mark(BIT_MARK_US)) { + return {}; + } + size -= 2; + } + if (size > 0) { + checksum += (data >> 4) + (data & 0xF); + out.data.push_back(data); + } else if (checksum != data) { + return {}; + } + } + return out; +} + +void MirageProtocol::dump(const MirageData &data) { + ESP_LOGI(TAG, "Received Mirage: %s", format_hex_pretty(data.data).c_str()); +} + +} // namespace remote_base +} // namespace esphome diff --git a/esphome/components/remote_base/mirage_protocol.h b/esphome/components/remote_base/mirage_protocol.h new file mode 100644 index 0000000000..4257f7fa00 --- /dev/null +++ b/esphome/components/remote_base/mirage_protocol.h @@ -0,0 +1,39 @@ +#pragma once + +#include "esphome/core/component.h" +#include "remote_base.h" + +namespace esphome { +namespace remote_base { + +struct MirageData { + std::vector data; + + bool operator==(const MirageData &rhs) const { return data == rhs.data; } +}; + +class MirageProtocol : public RemoteProtocol { + public: + void encode(RemoteTransmitData *dst, const MirageData &data) override; + optional decode(RemoteReceiveData src) override; + void dump(const MirageData &data) override; + + protected: + void encode_byte_(RemoteTransmitData *dst, uint8_t item); +}; + +DECLARE_REMOTE_PROTOCOL(Mirage) + +template class MirageAction : public RemoteTransmitterActionBase { + public: + TEMPLATABLE_VALUE(std::vector, code) + + void encode(RemoteTransmitData *dst, Ts... x) override { + MirageData data{}; + data.data = this->code_.value(x...); + MirageProtocol().encode(dst, data); + } +}; + +} // namespace remote_base +} // namespace esphome diff --git a/tests/test1.yaml b/tests/test1.yaml index c8ae9691c2..d2cf2f20dd 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2991,6 +2991,11 @@ switch: 0x00, 0x05, ] + - platform: template + name: Mirage + turn_on_action: + remote_transmitter.transmit_mirage: + code: [0x56, 0x77, 0x00, 0x00, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] - platform: template name: Living Room Lights id: livingroom_lights From fd3f6b092d437aa001784e949da20a675fc694db Mon Sep 17 00:00:00 2001 From: Heggi Date: Wed, 10 Apr 2024 02:11:43 +0400 Subject: [PATCH 2/4] add new tests --- tests/components/remote_receiver/esp32-common.yaml | 4 ++++ tests/components/remote_receiver/test.esp8266.yaml | 4 ++++ tests/components/remote_transmitter/common-buttons.yaml | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/tests/components/remote_receiver/esp32-common.yaml b/tests/components/remote_receiver/esp32-common.yaml index d1d47661c5..810d02d0bd 100644 --- a/tests/components/remote_receiver/esp32-common.yaml +++ b/tests/components/remote_receiver/esp32-common.yaml @@ -9,6 +9,10 @@ remote_receiver: on_rc_switch: then: delay: !lambda "return uint32_t(x.code) + x.protocol;" + on_mirage: + then: + - lambda: |- + ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.code).c_str()); binary_sensor: - platform: remote_receiver diff --git a/tests/components/remote_receiver/test.esp8266.yaml b/tests/components/remote_receiver/test.esp8266.yaml index a7c283da1e..3ff47c57e4 100644 --- a/tests/components/remote_receiver/test.esp8266.yaml +++ b/tests/components/remote_receiver/test.esp8266.yaml @@ -8,6 +8,10 @@ remote_receiver: on_rc_switch: then: delay: !lambda "return uint32_t(x.code) + x.protocol;" + on_mirage: + then: + - lambda: |- + ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.code).c_str()); binary_sensor: - platform: remote_receiver diff --git a/tests/components/remote_transmitter/common-buttons.yaml b/tests/components/remote_transmitter/common-buttons.yaml index 5f655acb7c..f4ae207df8 100644 --- a/tests/components/remote_transmitter/common-buttons.yaml +++ b/tests/components/remote_transmitter/common-buttons.yaml @@ -176,3 +176,8 @@ button: 0x00, 0x05, ] + - platform: template + name: Mirage + on_press: + remote_transmitter.transmit_mirage: + code: [0x56, 0x77, 0x00, 0x00, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] From fbb4ae5dad953b0b4d3478502d4194688a8d084f Mon Sep 17 00:00:00 2001 From: Heggi Date: Wed, 10 Apr 2024 02:48:24 +0400 Subject: [PATCH 3/4] fix remote_receiver test --- tests/components/remote_receiver/esp32-common.yaml | 2 +- tests/components/remote_receiver/test.esp8266.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/remote_receiver/esp32-common.yaml b/tests/components/remote_receiver/esp32-common.yaml index 810d02d0bd..5f2aa7feb1 100644 --- a/tests/components/remote_receiver/esp32-common.yaml +++ b/tests/components/remote_receiver/esp32-common.yaml @@ -12,7 +12,7 @@ remote_receiver: on_mirage: then: - lambda: |- - ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.code).c_str()); + ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.data).c_str()); binary_sensor: - platform: remote_receiver diff --git a/tests/components/remote_receiver/test.esp8266.yaml b/tests/components/remote_receiver/test.esp8266.yaml index 3ff47c57e4..ea3fd8c9e5 100644 --- a/tests/components/remote_receiver/test.esp8266.yaml +++ b/tests/components/remote_receiver/test.esp8266.yaml @@ -11,7 +11,7 @@ remote_receiver: on_mirage: then: - lambda: |- - ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.code).c_str()); + ESP_LOGD("mirage", "Mirage data: %s", format_hex(x.data).c_str()); binary_sensor: - platform: remote_receiver From 5bba7125aa8d934483ee90340ec32649e2e2d986 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:10:53 +1200 Subject: [PATCH 4/4] Discard changes to tests/test1.yaml --- tests/test1.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test1.yaml b/tests/test1.yaml index d2cf2f20dd..c8ae9691c2 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2991,11 +2991,6 @@ switch: 0x00, 0x05, ] - - platform: template - name: Mirage - turn_on_action: - remote_transmitter.transmit_mirage: - code: [0x56, 0x77, 0x00, 0x00, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] - platform: template name: Living Room Lights id: livingroom_lights