From 9d38543cb02b034e38dcffbe41c1833a813ad413 Mon Sep 17 00:00:00 2001 From: Paul Nicholls Date: Tue, 26 Jan 2021 17:44:10 +1300 Subject: [PATCH] Add support for string-type Tuya datapoints (#1488) --- esphome/components/tuya/tuya.cpp | 18 +++++++++++++++++- esphome/components/tuya/tuya.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/esphome/components/tuya/tuya.cpp b/esphome/components/tuya/tuya.cpp index 2fd4b27937..75514dde19 100644 --- a/esphome/components/tuya/tuya.cpp +++ b/esphome/components/tuya/tuya.cpp @@ -42,6 +42,8 @@ void Tuya::dump_config() { ESP_LOGCONFIG(TAG, " Datapoint %d: switch (value: %s)", info.id, ONOFF(info.value_bool)); else if (info.type == TuyaDatapointType::INTEGER) ESP_LOGCONFIG(TAG, " Datapoint %d: int value (value: %d)", info.id, info.value_int); + else if (info.type == TuyaDatapointType::STRING) + ESP_LOGCONFIG(TAG, " Datapoint %d: string value (value: %s)", info.id, info.value_string.c_str()); else if (info.type == TuyaDatapointType::ENUM) ESP_LOGCONFIG(TAG, " Datapoint %d: enum (value: %d)", info.id, info.value_enum); else if (info.type == TuyaDatapointType::BITMASK) @@ -283,6 +285,9 @@ void Tuya::handle_datapoint_(const uint8_t *buffer, size_t len) { return; datapoint.value_uint = encode_uint32(data[0], data[1], data[2], data[3]); break; + case TuyaDatapointType::STRING: + datapoint.value_string = std::string(reinterpret_cast(data), data_len); + break; case TuyaDatapointType::ENUM: if (data_len != 1) return; @@ -339,7 +344,13 @@ void Tuya::set_datapoint_value(TuyaDatapoint datapoint) { ESP_LOGV(TAG, "Datapoint %u set to %u", datapoint.id, datapoint.value_uint); for (auto &other : this->datapoints_) { if (other.id == datapoint.id) { - if (other.value_uint == datapoint.value_uint) { + // String value is stored outside the union; must be checked separately. + if (datapoint.type == TuyaDatapointType::STRING) { + if (other.value_string == datapoint.value_string) { + ESP_LOGV(TAG, "Not sending unchanged value"); + return; + } + } else if (other.value_uint == datapoint.value_uint) { ESP_LOGV(TAG, "Not sending unchanged value"); return; } @@ -359,6 +370,11 @@ void Tuya::set_datapoint_value(TuyaDatapoint datapoint) { data.push_back(datapoint.value_uint >> 8); data.push_back(datapoint.value_uint >> 0); break; + case TuyaDatapointType::STRING: + for (char const &c : datapoint.value_string) { + data.push_back(c); + } + break; case TuyaDatapointType::ENUM: data.push_back(datapoint.value_enum); break; diff --git a/esphome/components/tuya/tuya.h b/esphome/components/tuya/tuya.h index ba20cfd314..ddbbb48edf 100644 --- a/esphome/components/tuya/tuya.h +++ b/esphome/components/tuya/tuya.h @@ -30,6 +30,7 @@ struct TuyaDatapoint { uint8_t value_enum; uint16_t value_bitmask; }; + std::string value_string; }; struct TuyaDatapointListener {