ESPHome  2022.9.3
tuya.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include "esphome/core/defines.h"
5 #include "esphome/core/helpers.h"
7 
8 #ifdef USE_TIME
10 #endif
11 
12 namespace esphome {
13 namespace tuya {
14 
15 enum class TuyaDatapointType : uint8_t {
16  RAW = 0x00, // variable length
17  BOOLEAN = 0x01, // 1 byte (0/1)
18  INTEGER = 0x02, // 4 byte
19  STRING = 0x03, // variable length
20  ENUM = 0x04, // 1 byte
21  BITMASK = 0x05, // 1/2/4 bytes
22 };
23 
24 struct TuyaDatapoint {
25  uint8_t id;
27  size_t len;
28  union {
29  bool value_bool;
30  int value_int;
31  uint32_t value_uint;
32  uint8_t value_enum;
33  uint32_t value_bitmask;
34  };
35  std::string value_string;
36  std::vector<uint8_t> value_raw;
37 };
38 
40  uint8_t datapoint_id;
41  std::function<void(TuyaDatapoint)> on_datapoint;
42 };
43 
44 enum class TuyaCommandType : uint8_t {
45  HEARTBEAT = 0x00,
46  PRODUCT_QUERY = 0x01,
47  CONF_QUERY = 0x02,
48  WIFI_STATE = 0x03,
49  WIFI_RESET = 0x04,
50  WIFI_SELECT = 0x05,
51  DATAPOINT_DELIVER = 0x06,
52  DATAPOINT_REPORT = 0x07,
53  DATAPOINT_QUERY = 0x08,
54  WIFI_TEST = 0x0E,
55  LOCAL_TIME_QUERY = 0x1C,
56 };
57 
58 enum class TuyaInitState : uint8_t {
59  INIT_HEARTBEAT = 0x00,
61  INIT_CONF,
62  INIT_WIFI,
64  INIT_DONE,
65 };
66 
67 struct TuyaCommand {
69  std::vector<uint8_t> payload;
70 };
71 
72 class Tuya : public Component, public uart::UARTDevice {
73  public:
74  float get_setup_priority() const override { return setup_priority::LATE; }
75  void setup() override;
76  void loop() override;
77  void dump_config() override;
78  void register_listener(uint8_t datapoint_id, const std::function<void(TuyaDatapoint)> &func);
79  void set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value);
80  void set_boolean_datapoint_value(uint8_t datapoint_id, bool value);
81  void set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value);
82  void set_status_pin(InternalGPIOPin *status_pin) { this->status_pin_ = status_pin; }
83  void set_string_datapoint_value(uint8_t datapoint_id, const std::string &value);
84  void set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value);
85  void set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length);
86  void force_set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value);
87  void force_set_boolean_datapoint_value(uint8_t datapoint_id, bool value);
88  void force_set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value);
89  void force_set_string_datapoint_value(uint8_t datapoint_id, const std::string &value);
90  void force_set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value);
91  void force_set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length);
92  TuyaInitState get_init_state();
93 #ifdef USE_TIME
94  void set_time_id(time::RealTimeClock *time_id) { this->time_id_ = time_id; }
95 #endif
96  void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints) {
97  this->ignore_mcu_update_on_datapoints_.push_back(ignore_mcu_update_on_datapoints);
98  }
99  void add_on_initialized_callback(std::function<void()> callback) {
100  this->initialized_callback_.add(std::move(callback));
101  }
102 
103  protected:
104  void handle_char_(uint8_t c);
105  void handle_datapoints_(const uint8_t *buffer, size_t len);
106  optional<TuyaDatapoint> get_datapoint_(uint8_t datapoint_id);
107  bool validate_message_();
108 
109  void handle_command_(uint8_t command, uint8_t version, const uint8_t *buffer, size_t len);
110  void send_raw_command_(TuyaCommand command);
111  void process_command_queue_();
112  void send_command_(const TuyaCommand &command);
113  void send_empty_command_(TuyaCommandType command);
114  void set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, uint32_t value,
115  uint8_t length, bool forced);
116  void set_string_datapoint_value_(uint8_t datapoint_id, const std::string &value, bool forced);
117  void set_raw_datapoint_value_(uint8_t datapoint_id, const std::vector<uint8_t> &value, bool forced);
118  void send_datapoint_command_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, std::vector<uint8_t> data);
119  void set_status_pin_();
120  void send_wifi_status_();
121 
122 #ifdef USE_TIME
123  void send_local_time_();
125 #endif
127  bool init_failed_{false};
128  int init_retries_{0};
129  uint8_t protocol_version_ = -1;
131  int status_pin_reported_ = -1;
132  int reset_pin_reported_ = -1;
133  uint32_t last_command_timestamp_ = 0;
134  uint32_t last_rx_char_timestamp_ = 0;
135  std::string product_ = "";
136  std::vector<TuyaDatapointListener> listeners_;
137  std::vector<TuyaDatapoint> datapoints_;
138  std::vector<uint8_t> rx_message_;
139  std::vector<uint8_t> ignore_mcu_update_on_datapoints_{};
140  std::vector<TuyaCommand> command_queue_;
141  optional<TuyaCommandType> expected_response_{};
142  uint8_t wifi_status_ = -1;
143  CallbackManager<void()> initialized_callback_{};
144 };
145 
146 } // namespace tuya
147 } // namespace esphome
void setup()
void loop()
TuyaDatapointType type
Definition: tuya.h:26
TuyaCommandType
Definition: tuya.h:44
float get_setup_priority() const override
Definition: tuya.h:74
The RealTimeClock class exposes common timekeeping functions via the device&#39;s local real-time clock...
const float LATE
For components that should be initialized at the very end of the setup process.
Definition: component.cpp:26
void set_time_id(time::RealTimeClock *time_id)
Definition: tuya.h:94
TuyaDatapointType
Definition: tuya.h:15
std::vector< TuyaDatapointListener > listeners_
Definition: tuya.h:136
void add_on_initialized_callback(std::function< void()> callback)
Definition: tuya.h:99
std::vector< TuyaDatapoint > datapoints_
Definition: tuya.h:137
std::vector< uint8_t > rx_message_
Definition: tuya.h:138
TuyaCommandType cmd
Definition: tuya.h:68
std::string value_string
Definition: tuya.h:35
std::function< void(TuyaDatapoint)> on_datapoint
Definition: tuya.h:41
std::vector< uint8_t > payload
Definition: tuya.h:69
void set_status_pin(InternalGPIOPin *status_pin)
Definition: tuya.h:82
std::string size_t len
Definition: helpers.h:281
Definition: a4988.cpp:4
std::vector< TuyaCommand > command_queue_
Definition: tuya.h:140
TuyaInitState
Definition: tuya.h:58
std::vector< uint8_t > value_raw
Definition: tuya.h:36
void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints)
Definition: tuya.h:96