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