ESPHome  2024.5.5
rc_switch_protocol.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include "remote_base.h"
5 
6 namespace esphome {
7 namespace remote_base {
8 
9 struct RCSwitchData {
10  uint64_t code;
11  uint8_t protocol;
12 
13  bool operator==(const RCSwitchData &rhs) const { return code == rhs.code && protocol == rhs.protocol; }
14 };
15 
16 class RCSwitchBase {
17  public:
19 
20  RCSwitchBase() = default;
21  RCSwitchBase(uint32_t sync_high, uint32_t sync_low, uint32_t zero_high, uint32_t zero_low, uint32_t one_high,
22  uint32_t one_low, bool inverted);
23 
24  void one(RemoteTransmitData *dst) const;
25 
26  void zero(RemoteTransmitData *dst) const;
27 
28  void sync(RemoteTransmitData *dst) const;
29 
30  void transmit(RemoteTransmitData *dst, uint64_t code, uint8_t len) const;
31 
32  bool expect_one(RemoteReceiveData &src) const;
33 
34  bool expect_zero(RemoteReceiveData &src) const;
35 
36  bool expect_sync(RemoteReceiveData &src) const;
37 
38  bool decode(RemoteReceiveData &src, uint64_t *out_data, uint8_t *out_nbits) const;
39 
40  optional<RCSwitchData> decode(RemoteReceiveData &src) const;
41 
42  static void simple_code_to_tristate(uint16_t code, uint8_t nbits, uint64_t *out_code);
43 
44  static void type_a_code(uint8_t switch_group, uint8_t switch_device, bool state, uint64_t *out_code,
45  uint8_t *out_nbits);
46 
47  static void type_b_code(uint8_t address_code, uint8_t channel_code, bool state, uint64_t *out_code,
48  uint8_t *out_nbits);
49 
50  static void type_c_code(uint8_t family, uint8_t group, uint8_t device, bool state, uint64_t *out_code,
51  uint8_t *out_nbits);
52 
53  static void type_d_code(uint8_t group, uint8_t device, bool state, uint64_t *out_code, uint8_t *out_nbits);
54 
55  protected:
56  uint32_t sync_high_{};
57  uint32_t sync_low_{};
58  uint32_t zero_high_{};
59  uint32_t zero_low_{};
60  uint32_t one_high_{};
61  uint32_t one_low_{};
62  bool inverted_{};
63 };
64 
65 extern const RCSwitchBase RC_SWITCH_PROTOCOLS[9];
66 
67 uint64_t decode_binary_string(const std::string &data);
68 
69 uint64_t decode_binary_string_mask(const std::string &data);
70 
71 template<typename... Ts> class RCSwitchRawAction : public RemoteTransmitterActionBase<Ts...> {
72  public:
73  TEMPLATABLE_VALUE(RCSwitchBase, protocol);
74  TEMPLATABLE_VALUE(std::string, code);
75 
76  void encode(RemoteTransmitData *dst, Ts... x) override {
77  auto code = this->code_.value(x...);
78  uint64_t the_code = decode_binary_string(code);
79  uint8_t nbits = code.size();
80 
81  auto proto = this->protocol_.value(x...);
82  proto.transmit(dst, the_code, nbits);
83  }
84 };
85 
86 template<typename... Ts> class RCSwitchTypeAAction : public RemoteTransmitterActionBase<Ts...> {
87  public:
88  TEMPLATABLE_VALUE(RCSwitchBase, protocol);
89  TEMPLATABLE_VALUE(std::string, group);
90  TEMPLATABLE_VALUE(std::string, device);
91  TEMPLATABLE_VALUE(bool, state);
92 
93  void encode(RemoteTransmitData *dst, Ts... x) override {
94  auto group = this->group_.value(x...);
95  auto device = this->device_.value(x...);
96  auto state = this->state_.value(x...);
97  uint8_t u_group = decode_binary_string(group);
98  uint8_t u_device = decode_binary_string(device);
99 
100  uint64_t code;
101  uint8_t nbits;
102  RCSwitchBase::type_a_code(u_group, u_device, state, &code, &nbits);
103 
104  auto proto = this->protocol_.value(x...);
105  proto.transmit(dst, code, nbits);
106  }
107 };
108 
109 template<typename... Ts> class RCSwitchTypeBAction : public RemoteTransmitterActionBase<Ts...> {
110  public:
111  TEMPLATABLE_VALUE(RCSwitchBase, protocol);
112  TEMPLATABLE_VALUE(uint8_t, address);
113  TEMPLATABLE_VALUE(uint8_t, channel);
114  TEMPLATABLE_VALUE(bool, state);
115 
116  void encode(RemoteTransmitData *dst, Ts... x) override {
117  auto address = this->address_.value(x...);
118  auto channel = this->channel_.value(x...);
119  auto state = this->state_.value(x...);
120 
121  uint64_t code;
122  uint8_t nbits;
123  RCSwitchBase::type_b_code(address, channel, state, &code, &nbits);
124 
125  auto proto = this->protocol_.value(x...);
126  proto.transmit(dst, code, nbits);
127  }
128 };
129 
130 template<typename... Ts> class RCSwitchTypeCAction : public RemoteTransmitterActionBase<Ts...> {
131  public:
132  TEMPLATABLE_VALUE(RCSwitchBase, protocol);
133  TEMPLATABLE_VALUE(std::string, family);
134  TEMPLATABLE_VALUE(uint8_t, group);
135  TEMPLATABLE_VALUE(uint8_t, device);
136  TEMPLATABLE_VALUE(bool, state);
137 
138  void encode(RemoteTransmitData *dst, Ts... x) override {
139  auto family = this->family_.value(x...);
140  auto group = this->group_.value(x...);
141  auto device = this->device_.value(x...);
142  auto state = this->state_.value(x...);
143 
144  auto u_family = static_cast<uint8_t>(tolower(family[0]) - 'a');
145 
146  uint64_t code;
147  uint8_t nbits;
148  RCSwitchBase::type_c_code(u_family, group, device, state, &code, &nbits);
149 
150  auto proto = this->protocol_.value(x...);
151  proto.transmit(dst, code, nbits);
152  }
153 };
154 template<typename... Ts> class RCSwitchTypeDAction : public RemoteTransmitterActionBase<Ts...> {
155  public:
156  TEMPLATABLE_VALUE(RCSwitchBase, protocol);
157  TEMPLATABLE_VALUE(std::string, group);
158  TEMPLATABLE_VALUE(uint8_t, device);
159  TEMPLATABLE_VALUE(bool, state);
160 
161  void encode(RemoteTransmitData *dst, Ts... x) override {
162  auto group = this->group_.value(x...);
163  auto device = this->device_.value(x...);
164  auto state = this->state_.value(x...);
165 
166  auto u_group = static_cast<uint8_t>(tolower(group[0]) - 'a');
167 
168  uint64_t code;
169  uint8_t nbits;
170  RCSwitchBase::type_d_code(u_group, device, state, &code, &nbits);
171 
172  auto proto = this->protocol_.value(x...);
173  proto.transmit(dst, code, nbits);
174  }
175 };
176 
178  public:
179  void set_protocol(const RCSwitchBase &a_protocol) { this->protocol_ = a_protocol; }
180  void set_code(uint64_t code) { this->code_ = code; }
181  void set_code(const std::string &code) {
182  this->code_ = decode_binary_string(code);
183  this->mask_ = decode_binary_string_mask(code);
184  this->nbits_ = code.size();
185  }
186  void set_nbits(uint8_t nbits) { this->nbits_ = nbits; }
187  void set_type_a(const std::string &group, const std::string &device, bool state) {
188  uint8_t u_group = decode_binary_string(group);
189  uint8_t u_device = decode_binary_string(device);
190  RCSwitchBase::type_a_code(u_group, u_device, state, &this->code_, &this->nbits_);
191  }
192  void set_type_b(uint8_t address_code, uint8_t channel_code, bool state) {
193  RCSwitchBase::type_b_code(address_code, channel_code, state, &this->code_, &this->nbits_);
194  }
195  void set_type_c(std::string family, uint8_t group, uint8_t device, bool state) {
196  auto u_family = static_cast<uint8_t>(tolower(family[0]) - 'a');
197  RCSwitchBase::type_c_code(u_family, group, device, state, &this->code_, &this->nbits_);
198  }
199  void set_type_d(std::string group, uint8_t device, bool state) {
200  auto u_group = static_cast<uint8_t>(tolower(group[0]) - 'a');
201  RCSwitchBase::type_d_code(u_group, device, state, &this->code_, &this->nbits_);
202  }
203 
204  protected:
205  bool matches(RemoteReceiveData src) override;
206 
208  uint64_t code_;
209  uint64_t mask_{0xFFFFFFFFFFFFFFFF};
210  uint8_t nbits_;
211 };
212 
214  public:
215  bool dump(RemoteReceiveData src) override;
216 };
217 
219 
220 } // namespace remote_base
221 } // namespace esphome
uint16_t sync
Definition: sun_gtil2.cpp:14
uint16_t x
Definition: tt21100.cpp:17
static void type_d_code(uint8_t group, uint8_t device, bool state, uint64_t *out_code, uint8_t *out_nbits)
void encode(RemoteTransmitData *dst, Ts... x) override
void set_type_b(uint8_t address_code, uint8_t channel_code, bool state)
static void type_c_code(uint8_t family, uint8_t group, uint8_t device, bool state, uint64_t *out_code, uint8_t *out_nbits)
void set_type_a(const std::string &group, const std::string &device, bool state)
void set_type_c(std::string family, uint8_t group, uint8_t device, bool state)
static void type_a_code(uint8_t switch_group, uint8_t switch_device, bool state, uint64_t *out_code, uint8_t *out_nbits)
void encode(RemoteTransmitData *dst, Ts... x) override
uint64_t decode_binary_string_mask(const std::string &data)
void set_type_d(std::string group, uint8_t device, bool state)
const RCSwitchBase RC_SWITCH_PROTOCOLS[9]
void set_code(const std::string &code)
std::string size_t len
Definition: helpers.h:292
uint64_t decode_binary_string(const std::string &data)
static void type_b_code(uint8_t address_code, uint8_t channel_code, bool state, uint64_t *out_code, uint8_t *out_nbits)
bool operator==(const RCSwitchData &rhs) const
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void set_protocol(const RCSwitchBase &a_protocol)
void encode(RemoteTransmitData *dst, Ts... x) override
void encode(RemoteTransmitData *dst, Ts... x) override
void encode(RemoteTransmitData *dst, Ts... x) override
bool state
Definition: fan.h:34