ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
tuya.h
Go to the documentation of this file.
1#pragma once
2
3#include <cinttypes>
4#include <memory>
5#include <vector>
6
11
12#ifdef USE_TIME
14#include "esphome/core/time.h"
15#endif
16
17namespace esphome::tuya {
18
19enum class TuyaDatapointType : uint8_t {
20 RAW = 0x00, // variable length
21 BOOLEAN = 0x01, // 1 byte (0/1)
22 INTEGER = 0x02, // 4 byte
23 STRING = 0x03, // variable length
24 ENUM = 0x04, // 1 byte
25 BITMASK = 0x05, // 1/2/4 bytes
26};
27
29 uint8_t id;
31 size_t len;
32 union {
36 uint8_t value_enum;
38 };
39 std::string value_string;
40 std::vector<uint8_t> value_raw;
41
43 const TuyaDatapoint &expect_type(TuyaDatapointType expected) const;
44};
45
50
51enum class TuyaCommandType : uint8_t {
52 HEARTBEAT = 0x00,
53 PRODUCT_QUERY = 0x01,
54 CONF_QUERY = 0x02,
55 WIFI_STATE = 0x03,
56 WIFI_RESET = 0x04,
57 WIFI_SELECT = 0x05,
58 DATAPOINT_DELIVER = 0x06,
60 DATAPOINT_QUERY = 0x08,
61 GMT_TIME_QUERY = 0x0C,
62 WIFI_TEST = 0x0E,
63 LOCAL_TIME_QUERY = 0x1C,
66 WIFI_RSSI = 0x24,
67 VACUUM_MAP_UPLOAD = 0x28,
68 GET_NETWORK_STATUS = 0x2B,
69 EXTENDED_SERVICES = 0x34,
70};
71
72enum class TuyaExtendedServicesCommandType : uint8_t {
73 RESET_NOTIFICATION = 0x04,
74 MODULE_RESET = 0x05,
75 UPDATE_IN_PROGRESS = 0x0A,
76};
77
78enum class TuyaInitState : uint8_t {
79 INIT_HEARTBEAT = 0x00,
85};
86
89 std::vector<uint8_t> payload;
90};
91
92class Tuya final : public Component, public uart::UARTDevice {
93 public:
94 float get_setup_priority() const override { return setup_priority::LATE; }
95 void setup() override;
96 void loop() override;
97 void dump_config() override;
98 template<typename F> void register_listener(uint8_t datapoint_id, F &&func) {
99 this->register_listener_(datapoint_id, Callback<void(const TuyaDatapoint &)>::create(std::forward<F>(func)));
100 }
101 void set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value);
102 void set_boolean_datapoint_value(uint8_t datapoint_id, bool value);
103 void set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value);
104 void set_status_pin(InternalGPIOPin *status_pin) { this->status_pin_ = status_pin; }
105 void set_string_datapoint_value(uint8_t datapoint_id, const std::string &value);
106 void set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value);
107 void set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length);
108 void force_set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value);
109 void force_set_boolean_datapoint_value(uint8_t datapoint_id, bool value);
110 void force_set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value);
111 void force_set_string_datapoint_value(uint8_t datapoint_id, const std::string &value);
112 void force_set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value);
113 void force_set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length);
115#ifdef USE_TIME
116 void set_time_id(time::RealTimeClock *time_id) { this->time_id_ = time_id; }
117 void set_force_time_sync(bool force_time_sync) { this->force_time_sync_ = force_time_sync; }
118#endif
119 void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints) {
120 this->ignore_mcu_update_on_datapoints_.push_back(ignore_mcu_update_on_datapoints);
121 }
122 template<typename F> void add_on_initialized_callback(F &&callback) {
123 this->initialized_callback_.add(std::forward<F>(callback));
124 }
125
126 protected:
127 void register_listener_(uint8_t datapoint_id, Callback<void(const TuyaDatapoint &)> func);
128 void handle_char_(uint8_t c);
129 void handle_datapoints_(const uint8_t *buffer, size_t len);
130 optional<TuyaDatapoint> get_datapoint_(uint8_t datapoint_id);
131 bool validate_message_();
132
133 void handle_command_(uint8_t command, uint8_t version, const uint8_t *buffer, size_t len);
134 void send_raw_command_(TuyaCommand command);
136 void send_command_(const TuyaCommand &command);
138 void set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, uint32_t value,
139 uint8_t length, bool forced);
140 void set_string_datapoint_value_(uint8_t datapoint_id, const std::string &value, bool forced);
141 void set_raw_datapoint_value_(uint8_t datapoint_id, const std::vector<uint8_t> &value, bool forced);
142 void send_datapoint_command_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, std::vector<uint8_t> data);
143 void set_status_pin_();
144 void send_wifi_status_();
145 uint8_t get_wifi_status_code_();
146 uint8_t get_wifi_rssi_();
147
148#ifdef USE_TIME
151 void send_local_time_(bool periodic = false);
152 void send_gmt_time_();
154 bool force_time_sync_{false};
155 uint8_t last_force_time_sync_minute_{0xFF}; // 0xFF: no minute seen yet
158#endif
160 bool init_failed_{false};
162 uint8_t protocol_version_ = -1;
168 std::unique_ptr<char[]> product_;
169 std::vector<TuyaDatapointListener> listeners_;
170 std::vector<TuyaDatapoint> datapoints_;
171 std::vector<uint8_t> rx_message_;
172 std::vector<uint8_t> ignore_mcu_update_on_datapoints_{};
173 std::vector<TuyaCommand> command_queue_;
174 optional<TuyaCommandType> expected_response_{};
175 uint8_t wifi_status_ = -1;
176 bool product_invalid_{false};
178};
179
180} // namespace esphome::tuya
The RealTimeClock class exposes common timekeeping functions via the device's local real-time clock.
void send_datapoint_command_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, std::vector< uint8_t > data)
Definition tuya.cpp:818
void set_status_pin(InternalGPIOPin *status_pin)
Definition tuya.h:104
void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints)
Definition tuya.h:119
void set_time_id(time::RealTimeClock *time_id)
Definition tuya.h:116
void set_string_datapoint_value(uint8_t datapoint_id, const std::string &value)
Definition tuya.cpp:706
optional< TuyaDatapoint > get_datapoint_(uint8_t datapoint_id)
Definition tuya.cpp:742
void send_empty_command_(TuyaCommandType command)
Definition tuya.cpp:576
void setup() override
Definition tuya.cpp:42
uint8_t get_wifi_rssi_()
Definition tuya.cpp:606
uint8_t get_wifi_status_code_()
Definition tuya.cpp:585
void dump_config() override
Definition tuya.cpp:74
time::RealTimeClock * time_id_
Definition tuya.h:153
CallbackManager< void()> initialized_callback_
Definition tuya.h:177
void set_boolean_datapoint_value(uint8_t datapoint_id, bool value)
Definition tuya.cpp:698
bool force_time_sync_
Definition tuya.h:154
TuyaInitState init_state_
Definition tuya.h:159
float get_setup_priority() const override
Definition tuya.h:94
int status_pin_reported_
Definition tuya.h:164
bool product_invalid_
Definition tuya.h:176
void set_raw_datapoint_value_(uint8_t datapoint_id, const std::vector< uint8_t > &value, bool forced)
Definition tuya.cpp:783
bool validate_message_()
Definition tuya.cpp:120
void check_force_time_sync_()
Definition tuya.cpp:636
InternalGPIOPin * status_pin_
Definition tuya.h:163
void force_set_raw_datapoint_value(uint8_t datapoint_id, const std::vector< uint8_t > &value)
Definition tuya.cpp:718
uint8_t protocol_version_
Definition tuya.h:162
void set_string_datapoint_value_(uint8_t datapoint_id, const std::string &value, bool forced)
Definition tuya.cpp:799
void force_set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value)
Definition tuya.cpp:726
uint32_t last_rx_char_timestamp_
Definition tuya.h:167
void process_command_queue_()
Definition tuya.cpp:540
void send_local_time_(bool periodic=false)
Definition tuya.cpp:644
void send_gmt_time_()
Definition tuya.cpp:673
std::unique_ptr< char[]> product_
Definition tuya.h:168
uint32_t last_command_timestamp_
Definition tuya.h:166
std::vector< TuyaDatapointListener > listeners_
Definition tuya.h:169
std::vector< TuyaCommand > command_queue_
Definition tuya.h:173
std::vector< TuyaDatapoint > datapoints_
Definition tuya.h:170
std::vector< uint8_t > ignore_mcu_update_on_datapoints_
Definition tuya.h:172
std::vector< uint8_t > rx_message_
Definition tuya.h:171
void handle_command_(uint8_t command, uint8_t version, const uint8_t *buffer, size_t len)
Definition tuya.cpp:186
void register_listener(uint8_t datapoint_id, F &&func)
Definition tuya.h:98
void set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value)
Definition tuya.cpp:710
void set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, uint32_t value, uint8_t length, bool forced)
Definition tuya.cpp:750
TuyaInitState get_init_state()
Definition tuya.cpp:850
uint8_t last_force_time_sync_minute_
Definition tuya.h:155
void set_status_pin_()
Definition tuya.cpp:580
void add_on_initialized_callback(F &&callback)
Definition tuya.h:122
void handle_char_(uint8_t c)
Definition tuya.cpp:177
void force_set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length)
Definition tuya.cpp:738
void handle_datapoints_(const uint8_t *buffer, size_t len)
Definition tuya.cpp:390
void send_wifi_status_()
Definition tuya.cpp:615
void send_command_(const TuyaCommand &command)
Definition tuya.cpp:571
void force_set_boolean_datapoint_value(uint8_t datapoint_id, bool value)
Definition tuya.cpp:722
void set_raw_datapoint_value(uint8_t datapoint_id, const std::vector< uint8_t > &value)
Definition tuya.cpp:694
optional< TuyaCommandType > expected_response_
Definition tuya.h:174
void send_raw_command_(TuyaCommand command)
Definition tuya.cpp:501
void force_set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value)
Definition tuya.cpp:734
void force_set_string_datapoint_value(uint8_t datapoint_id, const std::string &value)
Definition tuya.cpp:730
bool time_sync_callback_registered_
Definition tuya.h:156
void set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length)
Definition tuya.cpp:714
int reset_pin_reported_
Definition tuya.h:165
uint8_t wifi_status_
Definition tuya.h:175
void register_listener_(uint8_t datapoint_id, Callback< void(const TuyaDatapoint &)> func)
Definition tuya.cpp:829
void set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value)
Definition tuya.cpp:702
void set_force_time_sync(bool force_time_sync)
Definition tuya.h:117
bool gmt_time_sync_callback_registered_
Definition tuya.h:157
void loop() override
Definition tuya.cpp:56
void register_local_time_sync_callback_()
Definition tuya.cpp:628
uint32_t buffer
Definition gif.cpp:50
constexpr float LATE
For components that should be initialized at the very end of the setup process.
Definition component.h:59
TuyaExtendedServicesCommandType
Definition tuya.h:72
TuyaCommandType
Definition tuya.h:51
TuyaDatapointType
Definition tuya.h:19
const void size_t len
Definition hal.h:68
static void uint32_t
Lightweight type-erased callback (8 bytes on 32-bit) that avoids std::function overhead.
Definition helpers.h:1806
TuyaCommandType cmd
Definition tuya.h:88
std::vector< uint8_t > payload
Definition tuya.h:89
std::string value_string
Definition tuya.h:39
std::vector< uint8_t > value_raw
Definition tuya.h:40
const TuyaDatapoint & expect_type(TuyaDatapointType expected) const
Log a warning when this datapoint is not of type expected, and return it.
Definition tuya.cpp:842
TuyaDatapointType type
Definition tuya.h:30
Callback< void(const TuyaDatapoint &)> on_datapoint
Definition tuya.h:48