mirror of
https://github.com/esphome/esphome.git
synced 2024-12-02 19:54:14 +01:00
6144ce1fe0
Co-authored-by: Chris Nussbaum <chris.nussbaum@protolabs.com> Co-authored-by: Trevor North <trevor@freedisc.co.uk>
128 lines
3.9 KiB
C++
128 lines
3.9 KiB
C++
#pragma once
|
|
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/defines.h"
|
|
#include "esphome/components/uart/uart.h"
|
|
|
|
#ifdef USE_TIME
|
|
#include "esphome/components/time/real_time_clock.h"
|
|
#endif
|
|
|
|
namespace esphome {
|
|
namespace tuya {
|
|
|
|
enum class TuyaDatapointType : uint8_t {
|
|
RAW = 0x00, // variable length
|
|
BOOLEAN = 0x01, // 1 byte (0/1)
|
|
INTEGER = 0x02, // 4 byte
|
|
STRING = 0x03, // variable length
|
|
ENUM = 0x04, // 1 byte
|
|
BITMASK = 0x05, // 1/2/4 bytes
|
|
};
|
|
|
|
struct TuyaDatapoint {
|
|
uint8_t id;
|
|
TuyaDatapointType type;
|
|
size_t len;
|
|
union {
|
|
bool value_bool;
|
|
int value_int;
|
|
uint32_t value_uint;
|
|
uint8_t value_enum;
|
|
uint32_t value_bitmask;
|
|
};
|
|
std::string value_string;
|
|
std::vector<uint8_t> value_raw;
|
|
};
|
|
|
|
struct TuyaDatapointListener {
|
|
uint8_t datapoint_id;
|
|
std::function<void(TuyaDatapoint)> on_datapoint;
|
|
};
|
|
|
|
enum class TuyaCommandType : uint8_t {
|
|
HEARTBEAT = 0x00,
|
|
PRODUCT_QUERY = 0x01,
|
|
CONF_QUERY = 0x02,
|
|
WIFI_STATE = 0x03,
|
|
WIFI_RESET = 0x04,
|
|
WIFI_SELECT = 0x05,
|
|
DATAPOINT_DELIVER = 0x06,
|
|
DATAPOINT_REPORT = 0x07,
|
|
DATAPOINT_QUERY = 0x08,
|
|
WIFI_TEST = 0x0E,
|
|
LOCAL_TIME_QUERY = 0x1C,
|
|
};
|
|
|
|
enum class TuyaInitState : uint8_t {
|
|
INIT_HEARTBEAT = 0x00,
|
|
INIT_PRODUCT,
|
|
INIT_CONF,
|
|
INIT_WIFI,
|
|
INIT_DATAPOINT,
|
|
INIT_DONE,
|
|
};
|
|
|
|
struct TuyaCommand {
|
|
TuyaCommandType cmd;
|
|
std::vector<uint8_t> payload;
|
|
};
|
|
|
|
class Tuya : public Component, public uart::UARTDevice {
|
|
public:
|
|
float get_setup_priority() const override { return setup_priority::LATE; }
|
|
void setup() override;
|
|
void loop() override;
|
|
void dump_config() override;
|
|
void register_listener(uint8_t datapoint_id, const std::function<void(TuyaDatapoint)> &func);
|
|
void set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value);
|
|
void set_boolean_datapoint_value(uint8_t datapoint_id, bool value);
|
|
void set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value);
|
|
void set_string_datapoint_value(uint8_t datapoint_id, const std::string &value);
|
|
void set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value);
|
|
void set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length);
|
|
#ifdef USE_TIME
|
|
void set_time_id(time::RealTimeClock *time_id) { this->time_id_ = time_id; }
|
|
#endif
|
|
void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints) {
|
|
this->ignore_mcu_update_on_datapoints_.push_back(ignore_mcu_update_on_datapoints);
|
|
}
|
|
|
|
protected:
|
|
void handle_char_(uint8_t c);
|
|
void handle_datapoint_(const uint8_t *buffer, size_t len);
|
|
optional<TuyaDatapoint> get_datapoint_(uint8_t datapoint_id);
|
|
bool validate_message_();
|
|
|
|
void handle_command_(uint8_t command, uint8_t version, const uint8_t *buffer, size_t len);
|
|
void send_raw_command_(TuyaCommand command);
|
|
void process_command_queue_();
|
|
void send_command_(const TuyaCommand &command);
|
|
void send_empty_command_(TuyaCommandType command);
|
|
void set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, uint32_t value,
|
|
uint8_t length);
|
|
void send_datapoint_command_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, std::vector<uint8_t> data);
|
|
void send_wifi_status_();
|
|
|
|
#ifdef USE_TIME
|
|
void send_local_time_();
|
|
optional<time::RealTimeClock *> time_id_{};
|
|
#endif
|
|
TuyaInitState init_state_ = TuyaInitState::INIT_HEARTBEAT;
|
|
uint8_t protocol_version_ = -1;
|
|
int gpio_status_ = -1;
|
|
int gpio_reset_ = -1;
|
|
uint32_t last_command_timestamp_ = 0;
|
|
uint32_t last_rx_char_timestamp_ = 0;
|
|
std::string product_ = "";
|
|
std::vector<TuyaDatapointListener> listeners_;
|
|
std::vector<TuyaDatapoint> datapoints_;
|
|
std::vector<uint8_t> rx_message_;
|
|
std::vector<uint8_t> ignore_mcu_update_on_datapoints_{};
|
|
std::vector<TuyaCommand> command_queue_;
|
|
optional<TuyaCommandType> expected_response_{};
|
|
uint8_t wifi_status_ = -1;
|
|
};
|
|
|
|
} // namespace tuya
|
|
} // namespace esphome
|