mirror of
https://github.com/esphome/esphome.git
synced 2026-11-06 13:15:57 +00:00
115 lines
4.4 KiB
C++
115 lines
4.4 KiB
C++
#include "homeassistant_text.h"
|
|
|
|
#include <cstring>
|
|
|
|
#include "esphome/components/api/api_pb2.h"
|
|
#include "esphome/components/api/api_server.h"
|
|
#include "esphome/core/helpers.h"
|
|
#include "esphome/core/log.h"
|
|
#include "esphome/core/progmem.h"
|
|
#include "esphome/core/string_ref.h"
|
|
|
|
namespace esphome::homeassistant {
|
|
|
|
ESPHOME_LOG_TAG(TAG, "homeassistant.text");
|
|
|
|
void HomeassistantText::state_changed_(StringRef state) {
|
|
if (state == this->state) {
|
|
return;
|
|
}
|
|
ESP_LOGD(TAG, "'%s': Got state %s", this->entity_id_, state.c_str());
|
|
this->publish_state(state.c_str(), state.size());
|
|
}
|
|
|
|
void HomeassistantText::min_retrieved_(StringRef min) {
|
|
auto min_value = parse_number<int>(min.c_str());
|
|
if (!min_value.has_value()) {
|
|
ESP_LOGE(TAG, "'%s': Can't convert 'min' value '%s' to number!", this->entity_id_, min.c_str());
|
|
return;
|
|
}
|
|
ESP_LOGD(TAG, "'%s': Min retrieved: %s", this->entity_id_, min.c_str());
|
|
this->traits.set_min_length(min_value.value());
|
|
}
|
|
|
|
void HomeassistantText::max_retrieved_(StringRef max) {
|
|
auto max_value = parse_number<int>(max.c_str());
|
|
if (!max_value.has_value()) {
|
|
ESP_LOGE(TAG, "'%s': Can't convert 'max' value '%s' to number!", this->entity_id_, max.c_str());
|
|
return;
|
|
}
|
|
ESP_LOGD(TAG, "'%s': Max retrieved: %s", this->entity_id_, max.c_str());
|
|
this->traits.set_max_length(max_value.value());
|
|
}
|
|
|
|
void HomeassistantText::mode_retrieved_(StringRef mode) {
|
|
if (mode == "text") {
|
|
this->traits.set_mode(text::TEXT_MODE_TEXT);
|
|
} else if (mode == "password") {
|
|
this->traits.set_mode(text::TEXT_MODE_PASSWORD);
|
|
} else {
|
|
ESP_LOGW(TAG, "'%s': Unknown 'mode' value '%s'", this->entity_id_, mode.c_str());
|
|
return;
|
|
}
|
|
ESP_LOGD(TAG, "'%s': Mode retrieved: %s", this->entity_id_, mode.c_str());
|
|
}
|
|
|
|
void HomeassistantText::setup() {
|
|
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, nullptr,
|
|
[this](StringRef state) { this->state_changed_(state); });
|
|
|
|
api::global_api_server->get_home_assistant_state(this->entity_id_, "min",
|
|
[this](StringRef min) { this->min_retrieved_(min); });
|
|
api::global_api_server->get_home_assistant_state(this->entity_id_, "max",
|
|
[this](StringRef max) { this->max_retrieved_(max); });
|
|
api::global_api_server->get_home_assistant_state(this->entity_id_, "mode",
|
|
[this](StringRef mode) { this->mode_retrieved_(mode); });
|
|
// The "pattern" attribute is not fetched: Home Assistant sends "None" when it is unset,
|
|
// and a runtime pattern would need its own buffer.
|
|
}
|
|
|
|
void HomeassistantText::dump_config() {
|
|
LOG_TEXT("", "Homeassistant Text", this);
|
|
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_);
|
|
}
|
|
|
|
float HomeassistantText::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
|
|
|
|
void HomeassistantText::control(const std::string &value) {
|
|
if (!api::global_api_server->is_connected()) {
|
|
ESP_LOGE(TAG, "No clients connected to API server");
|
|
return;
|
|
}
|
|
|
|
#ifdef USE_API_WIZARD_LINKED_INPUTS
|
|
if (this->entity_id_[0] == '\0') {
|
|
ESP_LOGW(TAG, "'%s': No entity ID set yet", LOG_STR_ARG(this->get_log_name()));
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// In flash on the ESP8266 and encoded from there
|
|
static const char SERVICE_TEXT[] PROGMEM = "text.set_value";
|
|
static const char SERVICE_INPUT_TEXT[] PROGMEM = "input_text.set_value";
|
|
static const char ENTITY_ID_KEY[] PROGMEM = "entity_id";
|
|
static const char VALUE_KEY[] PROGMEM = "value";
|
|
|
|
api::HomeassistantActionRequest resp;
|
|
// An input helper entity id starts with the "input_" its action name starts with
|
|
const bool input_helper = ESPHOME_strncmp_P(this->entity_id_, SERVICE_INPUT_TEXT, sizeof("input_") - 1) == 0;
|
|
resp.service =
|
|
input_helper ? ProgmemStringRef::from_lit(SERVICE_INPUT_TEXT) : ProgmemStringRef::from_lit(SERVICE_TEXT);
|
|
|
|
resp.data.init(2);
|
|
auto &entity_id_kv = resp.data.emplace_back();
|
|
entity_id_kv.key = ProgmemStringRef::from_lit(ENTITY_ID_KEY);
|
|
entity_id_kv.value = ProgmemStringRef(StringRef(this->entity_id_));
|
|
|
|
auto &value_kv = resp.data.emplace_back();
|
|
value_kv.key = ProgmemStringRef::from_lit(VALUE_KEY);
|
|
value_kv.value = ProgmemStringRef(value.data(), value.size());
|
|
|
|
api::global_api_server->send_homeassistant_action(resp);
|
|
}
|
|
|
|
} // namespace esphome::homeassistant
|