ESPHome 2026.5.1
Loading...
Searching...
No Matches
dyson_protocol.cpp
Go to the documentation of this file.
1#include "dyson_protocol.h"
2#include "esphome/core/log.h"
3
4#include <cinttypes>
5
6namespace esphome::remote_base {
7
8static const char *const TAG = "remote.dyson";
9
10// pulsewidth [µs]
11constexpr uint32_t PW_MARK_US = 780;
12constexpr uint32_t PW_SHORT_US = 720;
13constexpr uint32_t PW_LONG_US = 1500;
14constexpr uint32_t PW_START_US = 2280;
15
16// MSB of 15 bit dyson code
17constexpr uint16_t MSB_DYSON = (1 << 14);
18
19// required symbols in transmit buffer = (start_symbol + 15 data_symbols)
20constexpr uint32_t N_SYMBOLS_REQ = 2u * (1 + 15);
21
23 uint32_t raw_code = (data.code << 2) + (data.index & 3);
24 dst->set_carrier_frequency(36000);
25 dst->reserve(N_SYMBOLS_REQ + 1);
27 for (uint16_t mask = MSB_DYSON; mask != 0; mask >>= 1) {
28 if (mask == (mask & raw_code)) {
30 } else {
32 }
33 }
34 dst->mark(PW_MARK_US); // final carrier pulse
35}
36
37optional<DysonData> DysonProtocol::decode(RemoteReceiveData src) {
38 uint32_t n_received = static_cast<uint32_t>(src.size());
39 uint16_t raw_code = 0;
40 DysonData data{
41 .code = 0,
42 .index = 0,
43 };
44 if (n_received < N_SYMBOLS_REQ)
45 return {}; // invalid frame length
47 return {}; // start not found
48 for (uint16_t mask = MSB_DYSON; mask != 0; mask >>= 1) {
50 raw_code &= ~mask; // zero detected
51 } else if (src.expect_item(PW_MARK_US, PW_LONG_US)) {
52 raw_code |= mask; // one detected
53 } else {
54 return {}; // invalid data item
55 }
56 }
57 data.code = raw_code >> 2; // extract button code
58 data.index = raw_code & 3; // extract rolling index
59 if (src.expect_mark(PW_MARK_US)) { // check total length
60 return data;
61 }
62 return {}; // frame not complete
63}
64
65void DysonProtocol::dump(const DysonData &data) {
66 ESP_LOGI(TAG, "Dyson: code=0x%x rolling index=%d", data.code, data.index);
67}
68
69} // namespace esphome::remote_base
optional< DysonData > decode(RemoteReceiveData src) override
void encode(RemoteTransmitData *dst, const DysonData &data) override
void dump(const DysonData &data) override
bool expect_item(uint32_t mark, uint32_t space)
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:29
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:24
constexpr uint32_t PW_SHORT_US
constexpr uint16_t MSB_DYSON
constexpr uint32_t PW_LONG_US
constexpr uint32_t N_SYMBOLS_REQ
constexpr uint32_t PW_MARK_US
constexpr uint16_t PW_START_US
static void uint32_t