mirror of
https://github.com/nuttytree/ESPHome-Devices.git
synced 2024-08-30 18:12:19 +00:00
Update Tuya component to match the eventual state of the ESPHome version (#13)
This commit is contained in:
parent
e0a37dac9d
commit
ae2ef5d478
@ -11,7 +11,7 @@ static const int COMMAND_DELAY = 50;
|
||||
static const int RECEIVE_TIMEOUT = 300;
|
||||
|
||||
void Tuya::setup() {
|
||||
this->set_interval("heartbeat", 10000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
||||
this->set_interval("heartbeat", 15000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
||||
}
|
||||
|
||||
void Tuya::loop() {
|
||||
@ -379,7 +379,7 @@ void Tuya::send_command_(TuyaCommand command) {
|
||||
}
|
||||
|
||||
void Tuya::send_empty_command_(TuyaCommandType command) {
|
||||
send_command_(TuyaCommand{.cmd = command, .payload = std::vector<uint8_t>{0x04}});
|
||||
send_command_(TuyaCommand{.cmd = command, .payload = std::vector<uint8_t>{}});
|
||||
}
|
||||
|
||||
void Tuya::send_wifi_status_() {
|
||||
@ -432,42 +432,38 @@ void Tuya::send_local_time_() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void Tuya::set_datapoint_value(uint8_t datapoint_id, uint32_t value) {
|
||||
ESP_LOGD(TAG, "Setting datapoint %u to %u", datapoint_id, value);
|
||||
void Tuya::set_raw_datapoint_value(uint8_t datapoint_id, const std::vector<uint8_t> &value) {
|
||||
ESP_LOGD(TAG, "Setting datapoint %u to %s", datapoint_id, hexencode(value).c_str());
|
||||
optional<TuyaDatapoint> datapoint = this->get_datapoint_(datapoint_id);
|
||||
if (!datapoint.has_value()) {
|
||||
ESP_LOGE(TAG, "Attempt to set unknown datapoint %u", datapoint_id);
|
||||
ESP_LOGW(TAG, "Setting unknown datapoint %u", datapoint_id);
|
||||
} else if (datapoint->type != TuyaDatapointType::RAW) {
|
||||
ESP_LOGE(TAG, "Attempt to set datapoint %u with incorrect type", datapoint_id);
|
||||
return;
|
||||
}
|
||||
if (datapoint->value_uint == value) {
|
||||
} else if (datapoint->value_raw == value) {
|
||||
ESP_LOGV(TAG, "Not sending unchanged value");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
switch (datapoint->len) {
|
||||
case 4:
|
||||
data.push_back(value >> 24);
|
||||
data.push_back(value >> 16);
|
||||
case 2:
|
||||
data.push_back(value >> 8);
|
||||
case 1:
|
||||
data.push_back(value >> 0);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unexpected datapoint length %zu", datapoint->len);
|
||||
return;
|
||||
}
|
||||
this->send_datapoint_command_(datapoint->id, datapoint->type, data);
|
||||
this->send_datapoint_command_(datapoint_id, TuyaDatapointType::RAW, value);
|
||||
}
|
||||
|
||||
void Tuya::set_datapoint_value(uint8_t datapoint_id, std::string value) {
|
||||
void Tuya::set_boolean_datapoint_value(uint8_t datapoint_id, bool value) {
|
||||
this->set_numeric_datapoint_value_(datapoint_id, TuyaDatapointType::BOOLEAN, value, 1);
|
||||
}
|
||||
|
||||
void Tuya::set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value) {
|
||||
this->set_numeric_datapoint_value_(datapoint_id, TuyaDatapointType::INTEGER, value, 4);
|
||||
}
|
||||
|
||||
void Tuya::set_string_datapoint_value(uint8_t datapoint_id, const std::string &value) {
|
||||
ESP_LOGD(TAG, "Setting datapoint %u to %s", datapoint_id, value.c_str());
|
||||
optional<TuyaDatapoint> datapoint = this->get_datapoint_(datapoint_id);
|
||||
if (!datapoint.has_value()) {
|
||||
ESP_LOGE(TAG, "Attempt to set unknown datapoint %u", datapoint_id);
|
||||
}
|
||||
if (datapoint->value_string == value) {
|
||||
ESP_LOGW(TAG, "Setting unknown datapoint %u", datapoint_id);
|
||||
} else if (datapoint->type != TuyaDatapointType::STRING) {
|
||||
ESP_LOGE(TAG, "Attempt to set datapoint %u with incorrect type", datapoint_id);
|
||||
return;
|
||||
} else if (datapoint->value_string == value) {
|
||||
ESP_LOGV(TAG, "Not sending unchanged value");
|
||||
return;
|
||||
}
|
||||
@ -478,20 +474,12 @@ void Tuya::set_datapoint_value(uint8_t datapoint_id, std::string value) {
|
||||
this->send_datapoint_command_(datapoint->id, datapoint->type, data);
|
||||
}
|
||||
|
||||
void Tuya::set_datapoint_value(uint8_t datapoint_id, bool value) {
|
||||
ESP_LOGD(TAG, "Setting datapoint %u to %s", datapoint_id, TRUEFALSE(value));
|
||||
optional<TuyaDatapoint> datapoint = this->get_datapoint_(datapoint_id);
|
||||
if (!datapoint.has_value()) {
|
||||
ESP_LOGE(TAG, "Attempt to set unknown datapoint %u", datapoint_id);
|
||||
}
|
||||
else if (datapoint->value_bool == value) {
|
||||
ESP_LOGV(TAG, "Not sending unchanged value");
|
||||
return;
|
||||
}
|
||||
void Tuya::set_enum_datapoint_value(uint8_t datapoint_id, uint8_t value) {
|
||||
this->set_numeric_datapoint_value_(datapoint_id, TuyaDatapointType::ENUM, value, 1);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
data.push_back(value >> 0);
|
||||
this->send_datapoint_command_(datapoint_id, TuyaDatapointType::BOOLEAN, data);
|
||||
void Tuya::set_bitmask_datapoint_value(uint8_t datapoint_id, uint32_t value, uint8_t length) {
|
||||
this->set_numeric_datapoint_value_(datapoint_id, TuyaDatapointType::BITMASK, value, length);
|
||||
}
|
||||
|
||||
optional<TuyaDatapoint> Tuya::get_datapoint_(uint8_t datapoint_id) {
|
||||
@ -501,6 +489,37 @@ optional<TuyaDatapoint> Tuya::get_datapoint_(uint8_t datapoint_id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
void Tuya::set_numeric_datapoint_value_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, const uint32_t value,
|
||||
uint8_t length) {
|
||||
ESP_LOGD(TAG, "Setting datapoint %u to %u", datapoint_id, value);
|
||||
optional<TuyaDatapoint> datapoint = this->get_datapoint_(datapoint_id);
|
||||
if (!datapoint.has_value()) {
|
||||
ESP_LOGW(TAG, "Setting unknown datapoint %u", datapoint_id);
|
||||
} else if (datapoint->type != datapoint_type) {
|
||||
ESP_LOGE(TAG, "Attempt to set datapoint %u with incorrect type", datapoint_id);
|
||||
return;
|
||||
} else if (datapoint->value_uint == value) {
|
||||
ESP_LOGV(TAG, "Not sending unchanged value");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
switch (length) {
|
||||
case 4:
|
||||
data.push_back(value >> 24);
|
||||
data.push_back(value >> 16);
|
||||
case 2:
|
||||
data.push_back(value >> 8);
|
||||
case 1:
|
||||
data.push_back(value >> 0);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unexpected datapoint length %u", length);
|
||||
return;
|
||||
}
|
||||
this->send_datapoint_command_(datapoint_id, datapoint_type, data);
|
||||
}
|
||||
|
||||
void Tuya::send_datapoint_command_(uint8_t datapoint_id, TuyaDatapointType datapoint_type, std::vector<uint8_t> data) {
|
||||
std::vector<uint8_t> buffer;
|
||||
buffer.push_back(datapoint_id);
|
||||
|
@ -75,9 +75,12 @@ class Tuya : public Component, public uart::UARTDevice {
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
void register_listener(uint8_t datapoint_id, const std::function<void(TuyaDatapoint)> &func);
|
||||
void set_datapoint_value(uint8_t datapoint_id, uint32_t value);
|
||||
void set_datapoint_value(uint8_t datapoint_id, std::string value);
|
||||
void set_datapoint_value(uint8_t datapoint_id, bool value);
|
||||
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
|
||||
@ -96,6 +99,8 @@ class Tuya : public Component, public uart::UARTDevice {
|
||||
void process_command_queue_();
|
||||
void send_command_(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_();
|
||||
|
||||
@ -114,7 +119,7 @@ class Tuya : public Component, public uart::UARTDevice {
|
||||
std::vector<uint8_t> rx_message_;
|
||||
std::vector<uint8_t> ignore_mcu_update_on_datapoints_{};
|
||||
std::vector<TuyaCommand> command_queue_;
|
||||
optional<TuyaCommandType> expected_response_{};
|
||||
optional<TuyaCommandType> expected_response_{};
|
||||
uint8_t wifi_status_ = -1;
|
||||
};
|
||||
|
||||
|
@ -20,14 +20,14 @@ void TuyaDimmerAsFan::setup() {
|
||||
this->parent_->register_listener(*this->dimmer_id_, [this](const TuyaDatapoint &datapoint) {
|
||||
if (datapoint.value_int != this->dimmer_max_value_)
|
||||
{
|
||||
this->parent_->set_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
|
||||
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
|
||||
}
|
||||
});
|
||||
|
||||
this->fan_->add_on_state_callback([this]() { this->parent_->set_datapoint_value(*this->switch_id_, this->fan_->state); });
|
||||
this->fan_->add_on_state_callback([this]() { this->parent_->set_boolean_datapoint_value(*this->switch_id_, this->fan_->state); });
|
||||
|
||||
// Make sure we start at the max value
|
||||
this->parent_->set_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
|
||||
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, this->dimmer_max_value_);
|
||||
}
|
||||
|
||||
void TuyaDimmerAsFan::dump_config() {
|
||||
|
@ -12,7 +12,7 @@ void TuyaLightPlus::setup()
|
||||
this->parent_->register_listener(*this->switch_id_, [this](tuya::TuyaDatapoint datapoint) { this->handle_tuya_datapoint_(datapoint); });
|
||||
this->parent_->register_listener(*this->dimmer_id_, [this](tuya::TuyaDatapoint datapoint) { this->handle_tuya_datapoint_(datapoint); });
|
||||
if (this->min_value_datapoint_id_.has_value()) {
|
||||
this->parent_->set_datapoint_value(*this->min_value_datapoint_id_, this->min_value_);
|
||||
this->parent_->set_integer_datapoint_value(*this->min_value_datapoint_id_, this->min_value_);
|
||||
}
|
||||
|
||||
this->register_service(&TuyaLightPlus::set_default_brightness, "set_default_brightness", {"brightness"});
|
||||
@ -52,13 +52,13 @@ void TuyaLightPlus::write_state(light::LightState *state)
|
||||
|
||||
if (brightness == 0.0f) {
|
||||
this->tuya_state_is_on_ = false;
|
||||
this->parent_->set_datapoint_value(*this->switch_id_, false);
|
||||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->tuya_state_is_on_ = true;
|
||||
this->parent_->set_datapoint_value(*this->dimmer_id_, this->brightness_to_tuya_level_(brightness));
|
||||
this->parent_->set_datapoint_value(*this->switch_id_, true);
|
||||
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, this->brightness_to_tuya_level_(brightness));
|
||||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ void TuyaLightPlus::handle_tuya_datapoint_(tuya::TuyaDatapoint datapoint)
|
||||
{
|
||||
ESP_LOGD(TAG, "Switch was double clicked while on");
|
||||
|
||||
this->parent_->set_datapoint_value(*this->switch_id_, false);
|
||||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, false);
|
||||
|
||||
this->double_click_while_on_timeout_ = 0;
|
||||
this->double_click_while_on_callback_.call();
|
||||
@ -149,7 +149,7 @@ void TuyaLightPlus::handle_tuya_datapoint_(tuya::TuyaDatapoint datapoint)
|
||||
if (this->double_click_while_off_timeout_ == 0)
|
||||
{
|
||||
// Turn the light back off and wait to see if we get a double click
|
||||
this->parent_->set_datapoint_value(*this->switch_id_, false);
|
||||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, false);
|
||||
this->double_click_while_off_timeout_ = millis() + DOUBLE_CLICK_TIMEOUT;
|
||||
return;
|
||||
}
|
||||
@ -164,7 +164,7 @@ void TuyaLightPlus::handle_tuya_datapoint_(tuya::TuyaDatapoint datapoint)
|
||||
// Double click while off can be configured to result in the light being off or on
|
||||
if (this->double_click_while_off_stays_off_)
|
||||
{
|
||||
this->parent_->set_datapoint_value(*this->switch_id_, false);
|
||||
this->parent_->set_boolean_datapoint_value(*this->switch_id_, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ void TuyaLightPlus::handle_tuya_datapoint_(tuya::TuyaDatapoint datapoint)
|
||||
// When the light is turned on at the switch the level of the Tuya device will stll be 0 so we set it to the current state value
|
||||
float brightness;
|
||||
this->state_->current_values_as_brightness(&brightness);
|
||||
this->parent_->set_datapoint_value(*this->dimmer_id_, this->brightness_to_tuya_level_(brightness));
|
||||
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, this->brightness_to_tuya_level_(brightness));
|
||||
}
|
||||
|
||||
// Turned off with the physical button
|
||||
@ -195,7 +195,7 @@ void TuyaLightPlus::handle_tuya_datapoint_(tuya::TuyaDatapoint datapoint)
|
||||
// default brightness set the current brightness value to the default so that if it is turned on remotely it will be at the default value
|
||||
if (!datapoint.value_bool)
|
||||
{
|
||||
this->parent_->set_datapoint_value(*this->dimmer_id_, static_cast<uint32_t>(0));
|
||||
this->parent_->set_integer_datapoint_value(*this->dimmer_id_, 0);
|
||||
if (this->default_brightness_.has_value())
|
||||
{
|
||||
this->state_->current_values.set_brightness(*this->default_brightness_);
|
||||
|
@ -6,11 +6,6 @@ substitutions:
|
||||
api_pwd: !secret office_light_api_pwd
|
||||
ap_wifi_pwd: !secret office_light_ap_wifi_pwd
|
||||
|
||||
script:
|
||||
- id: double_click
|
||||
then:
|
||||
- logger.log: "Double click script has been run!"
|
||||
|
||||
packages:
|
||||
feit_dimmer: !include ../packages/feit_dimmer.yaml
|
||||
|
||||
@ -31,8 +26,3 @@ light:
|
||||
night_default_brightness: 1
|
||||
day_auto_off_time: 0 min
|
||||
night_auto_off_time: 15 min
|
||||
on_double_click_while_off:
|
||||
- script.execute: double_click
|
||||
double_click_while_off_stays_off: true
|
||||
on_double_click_while_on:
|
||||
- script.execute: double_click
|
||||
|
Loading…
Reference in New Issue
Block a user