mirror of
https://github.com/esphome/esphome.git
synced 2024-12-04 20:48:21 +01:00
Add attribute support to Home Assistant sensors (#1770)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
9a7a205510
commit
5645be4e0f
19 changed files with 113 additions and 25 deletions
|
@ -561,6 +561,7 @@ message SubscribeHomeAssistantStateResponse {
|
||||||
option (id) = 39;
|
option (id) = 39;
|
||||||
option (source) = SOURCE_SERVER;
|
option (source) = SOURCE_SERVER;
|
||||||
string entity_id = 1;
|
string entity_id = 1;
|
||||||
|
string attribute = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message HomeAssistantStateResponse {
|
message HomeAssistantStateResponse {
|
||||||
|
@ -570,6 +571,7 @@ message HomeAssistantStateResponse {
|
||||||
|
|
||||||
string entity_id = 1;
|
string entity_id = 1;
|
||||||
string state = 2;
|
string state = 2;
|
||||||
|
string attribute = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== IMPORT TIME ====================
|
// ==================== IMPORT TIME ====================
|
||||||
|
|
|
@ -642,9 +642,10 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
||||||
}
|
}
|
||||||
void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) {
|
void APIConnection::on_home_assistant_state_response(const HomeAssistantStateResponse &msg) {
|
||||||
for (auto &it : this->parent_->get_state_subs())
|
for (auto &it : this->parent_->get_state_subs())
|
||||||
if (it.entity_id == msg.entity_id)
|
if (it.entity_id == msg.entity_id && it.attribute.value() == msg.attribute) {
|
||||||
it.callback(msg.state);
|
it.callback(msg.state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto *service : this->parent_->get_user_services()) {
|
for (auto *service : this->parent_->get_user_services()) {
|
||||||
|
@ -660,6 +661,7 @@ void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistant
|
||||||
for (auto &it : this->parent_->get_state_subs()) {
|
for (auto &it : this->parent_->get_state_subs()) {
|
||||||
SubscribeHomeAssistantStateResponse resp;
|
SubscribeHomeAssistantStateResponse resp;
|
||||||
resp.entity_id = it.entity_id;
|
resp.entity_id = it.entity_id;
|
||||||
|
resp.attribute = it.attribute.value();
|
||||||
if (!this->send_subscribe_home_assistant_state_response(resp)) {
|
if (!this->send_subscribe_home_assistant_state_response(resp)) {
|
||||||
this->on_fatal_error();
|
this->on_fatal_error();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2123,12 +2123,17 @@ bool SubscribeHomeAssistantStateResponse::decode_length(uint32_t field_id, Proto
|
||||||
this->entity_id = value.as_string();
|
this->entity_id = value.as_string();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 2: {
|
||||||
|
this->attribute = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
|
void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
buffer.encode_string(1, this->entity_id);
|
buffer.encode_string(1, this->entity_id);
|
||||||
|
buffer.encode_string(2, this->attribute);
|
||||||
}
|
}
|
||||||
void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const {
|
void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
|
@ -2136,6 +2141,10 @@ void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const {
|
||||||
out.append(" entity_id: ");
|
out.append(" entity_id: ");
|
||||||
out.append("'").append(this->entity_id).append("'");
|
out.append("'").append(this->entity_id).append("'");
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" attribute: ");
|
||||||
|
out.append("'").append(this->attribute).append("'");
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
|
||||||
|
@ -2148,6 +2157,10 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel
|
||||||
this->state = value.as_string();
|
this->state = value.as_string();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case 3: {
|
||||||
|
this->attribute = value.as_string();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2155,6 +2168,7 @@ bool HomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDel
|
||||||
void HomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
|
void HomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
|
||||||
buffer.encode_string(1, this->entity_id);
|
buffer.encode_string(1, this->entity_id);
|
||||||
buffer.encode_string(2, this->state);
|
buffer.encode_string(2, this->state);
|
||||||
|
buffer.encode_string(3, this->attribute);
|
||||||
}
|
}
|
||||||
void HomeAssistantStateResponse::dump_to(std::string &out) const {
|
void HomeAssistantStateResponse::dump_to(std::string &out) const {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
|
@ -2166,6 +2180,10 @@ void HomeAssistantStateResponse::dump_to(std::string &out) const {
|
||||||
out.append(" state: ");
|
out.append(" state: ");
|
||||||
out.append("'").append(this->state).append("'");
|
out.append("'").append(this->state).append("'");
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
|
|
||||||
|
out.append(" attribute: ");
|
||||||
|
out.append("'").append(this->attribute).append("'");
|
||||||
|
out.append("\n");
|
||||||
out.append("}");
|
out.append("}");
|
||||||
}
|
}
|
||||||
void GetTimeRequest::encode(ProtoWriteBuffer buffer) const {}
|
void GetTimeRequest::encode(ProtoWriteBuffer buffer) const {}
|
||||||
|
|
|
@ -557,6 +557,7 @@ class SubscribeHomeAssistantStatesRequest : public ProtoMessage {
|
||||||
class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
class SubscribeHomeAssistantStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
std::string entity_id{};
|
std::string entity_id{};
|
||||||
|
std::string attribute{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
|
|
||||||
|
@ -567,6 +568,7 @@ class HomeAssistantStateResponse : public ProtoMessage {
|
||||||
public:
|
public:
|
||||||
std::string entity_id{};
|
std::string entity_id{};
|
||||||
std::string state{};
|
std::string state{};
|
||||||
|
std::string attribute{};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void dump_to(std::string &out) const override;
|
void dump_to(std::string &out) const override;
|
||||||
|
|
||||||
|
|
|
@ -208,9 +208,11 @@ void APIServer::send_homeassistant_service_call(const HomeassistantServiceRespon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
APIServer::APIServer() { global_api_server = this; }
|
APIServer::APIServer() { global_api_server = this; }
|
||||||
void APIServer::subscribe_home_assistant_state(std::string entity_id, std::function<void(std::string)> f) {
|
void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
|
||||||
|
std::function<void(std::string)> f) {
|
||||||
this->state_subs_.push_back(HomeAssistantStateSubscription{
|
this->state_subs_.push_back(HomeAssistantStateSubscription{
|
||||||
.entity_id = std::move(entity_id),
|
.entity_id = std::move(entity_id),
|
||||||
|
.attribute = std::move(attribute),
|
||||||
.callback = std::move(f),
|
.callback = std::move(f),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,12 @@ class APIServer : public Component, public Controller {
|
||||||
|
|
||||||
struct HomeAssistantStateSubscription {
|
struct HomeAssistantStateSubscription {
|
||||||
std::string entity_id;
|
std::string entity_id;
|
||||||
|
optional<std::string> attribute;
|
||||||
std::function<void(std::string)> callback;
|
std::function<void(std::string)> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
void subscribe_home_assistant_state(std::string entity_id, std::function<void(std::string)> f);
|
void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
|
||||||
|
std::function<void(std::string)> f);
|
||||||
const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
|
const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
|
||||||
const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
|
const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
|
||||||
|
|
||||||
|
|
|
@ -76,13 +76,13 @@ class CustomAPIDevice {
|
||||||
global_api_server->register_user_service(service);
|
global_api_server->register_user_service(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Subscribe to the state of an entity from Home Assistant.
|
/** Subscribe to the state (or attribute state) of an entity from Home Assistant.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
*
|
*
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* void setup() override {
|
* void setup() override {
|
||||||
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "sensor.weather_forecast");
|
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "climate.kitchen", "current_temperature");
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void on_state_changed(std::string state) {
|
* void on_state_changed(std::string state) {
|
||||||
|
@ -93,17 +93,19 @@ class CustomAPIDevice {
|
||||||
* @tparam T The class type creating the service, automatically deduced from the function pointer.
|
* @tparam T The class type creating the service, automatically deduced from the function pointer.
|
||||||
* @param callback The member function to call when the entity state changes.
|
* @param callback The member function to call when the entity state changes.
|
||||||
* @param entity_id The entity_id to track.
|
* @param entity_id The entity_id to track.
|
||||||
|
* @param attribute The entity state attribute to track.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id) {
|
void subscribe_homeassistant_state(void (T::*callback)(std::string), const std::string &entity_id,
|
||||||
|
const std::string &attribute = "") {
|
||||||
auto f = std::bind(callback, (T *) this, std::placeholders::_1);
|
auto f = std::bind(callback, (T *) this, std::placeholders::_1);
|
||||||
global_api_server->subscribe_home_assistant_state(entity_id, f);
|
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Subscribe to the state of an entity from Home Assistant.
|
/** Subscribe to the state (or attribute state) of an entity from Home Assistant.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
*
|
*å
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* void setup() override {
|
* void setup() override {
|
||||||
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "sensor.weather_forecast");
|
* subscribe_homeassistant_state(&CustomNativeAPI::on_state_changed, "sensor.weather_forecast");
|
||||||
|
@ -117,11 +119,13 @@ class CustomAPIDevice {
|
||||||
* @tparam T The class type creating the service, automatically deduced from the function pointer.
|
* @tparam T The class type creating the service, automatically deduced from the function pointer.
|
||||||
* @param callback The member function to call when the entity state changes.
|
* @param callback The member function to call when the entity state changes.
|
||||||
* @param entity_id The entity_id to track.
|
* @param entity_id The entity_id to track.
|
||||||
|
* @param attribute The entity state attribute to track.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id) {
|
void subscribe_homeassistant_state(void (T::*callback)(std::string, std::string), const std::string &entity_id,
|
||||||
|
const std::string &attribute = "") {
|
||||||
auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
|
auto f = std::bind(callback, (T *) this, entity_id, std::placeholders::_1);
|
||||||
global_api_server->subscribe_home_assistant_state(entity_id, f);
|
global_api_server->subscribe_home_assistant_state(entity_id, optional<std::string>(attribute), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call a Home Assistant service from ESPHome.
|
/** Call a Home Assistant service from ESPHome.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import binary_sensor
|
from esphome.components import binary_sensor
|
||||||
from esphome.const import CONF_ENTITY_ID, CONF_ID
|
from esphome.const import CONF_ATTRIBUTE, CONF_ENTITY_ID, CONF_ID
|
||||||
from .. import homeassistant_ns
|
from .. import homeassistant_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["api"]
|
DEPENDENCIES = ["api"]
|
||||||
|
@ -13,6 +13,7 @@ CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(HomeassistantBinarySensor),
|
cv.GenerateID(): cv.declare_id(HomeassistantBinarySensor),
|
||||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||||
|
cv.Optional(CONF_ATTRIBUTE): cv.string,
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
@ -23,3 +24,5 @@ def to_code(config):
|
||||||
yield binary_sensor.register_binary_sensor(var, config)
|
yield binary_sensor.register_binary_sensor(var, config)
|
||||||
|
|
||||||
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
||||||
|
if CONF_ATTRIBUTE in config:
|
||||||
|
cg.add(var.set_attribute(config[CONF_ATTRIBUTE]))
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace homeassistant {
|
||||||
static const char *TAG = "homeassistant.binary_sensor";
|
static const char *TAG = "homeassistant.binary_sensor";
|
||||||
|
|
||||||
void HomeassistantBinarySensor::setup() {
|
void HomeassistantBinarySensor::setup() {
|
||||||
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, [this](std::string state) {
|
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, this->attribute_, [this](std::string state) {
|
||||||
auto val = parse_on_off(state.c_str());
|
auto val = parse_on_off(state.c_str());
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case PARSE_NONE:
|
case PARSE_NONE:
|
||||||
|
@ -18,7 +18,12 @@ void HomeassistantBinarySensor::setup() {
|
||||||
case PARSE_ON:
|
case PARSE_ON:
|
||||||
case PARSE_OFF:
|
case PARSE_OFF:
|
||||||
bool new_state = val == PARSE_ON;
|
bool new_state = val == PARSE_ON;
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGD(TAG, "'%s::%s': Got attribute state %s", this->entity_id_.c_str(), this->attribute_.value().c_str(),
|
||||||
|
ONOFF(new_state));
|
||||||
|
} else {
|
||||||
ESP_LOGD(TAG, "'%s': Got state %s", this->entity_id_.c_str(), ONOFF(new_state));
|
ESP_LOGD(TAG, "'%s': Got state %s", this->entity_id_.c_str(), ONOFF(new_state));
|
||||||
|
}
|
||||||
if (this->initial_)
|
if (this->initial_)
|
||||||
this->publish_initial_state(new_state);
|
this->publish_initial_state(new_state);
|
||||||
else
|
else
|
||||||
|
@ -31,6 +36,9 @@ void HomeassistantBinarySensor::setup() {
|
||||||
void HomeassistantBinarySensor::dump_config() {
|
void HomeassistantBinarySensor::dump_config() {
|
||||||
LOG_BINARY_SENSOR("", "Homeassistant Binary Sensor", this);
|
LOG_BINARY_SENSOR("", "Homeassistant Binary Sensor", this);
|
||||||
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Attribute: '%s'", this->attribute_.value().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
float HomeassistantBinarySensor::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
float HomeassistantBinarySensor::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,14 @@ namespace homeassistant {
|
||||||
class HomeassistantBinarySensor : public binary_sensor::BinarySensor, public Component {
|
class HomeassistantBinarySensor : public binary_sensor::BinarySensor, public Component {
|
||||||
public:
|
public:
|
||||||
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
||||||
|
void set_attribute(const std::string &attribute) { attribute_ = attribute; }
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string entity_id_;
|
std::string entity_id_;
|
||||||
|
optional<std::string> attribute_;
|
||||||
bool initial_{true};
|
bool initial_{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import sensor
|
from esphome.components import sensor
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
|
CONF_ATTRIBUTE,
|
||||||
CONF_ENTITY_ID,
|
CONF_ENTITY_ID,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
ICON_EMPTY,
|
ICON_EMPTY,
|
||||||
|
@ -22,6 +23,7 @@ CONFIG_SCHEMA = sensor.sensor_schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(HomeassistantSensor),
|
cv.GenerateID(): cv.declare_id(HomeassistantSensor),
|
||||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||||
|
cv.Optional(CONF_ATTRIBUTE): cv.string,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,3 +34,5 @@ def to_code(config):
|
||||||
yield sensor.register_sensor(var, config)
|
yield sensor.register_sensor(var, config)
|
||||||
|
|
||||||
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
||||||
|
if CONF_ATTRIBUTE in config:
|
||||||
|
cg.add(var.set_attribute(config[CONF_ATTRIBUTE]))
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace homeassistant {
|
||||||
static const char *TAG = "homeassistant.sensor";
|
static const char *TAG = "homeassistant.sensor";
|
||||||
|
|
||||||
void HomeassistantSensor::setup() {
|
void HomeassistantSensor::setup() {
|
||||||
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, [this](std::string state) {
|
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, this->attribute_, [this](std::string state) {
|
||||||
auto val = parse_float(state);
|
auto val = parse_float(state);
|
||||||
if (!val.has_value()) {
|
if (!val.has_value()) {
|
||||||
ESP_LOGW(TAG, "Can't convert '%s' to number!", state.c_str());
|
ESP_LOGW(TAG, "Can't convert '%s' to number!", state.c_str());
|
||||||
|
@ -16,13 +16,21 @@ void HomeassistantSensor::setup() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGD(TAG, "'%s::%s': Got attribute state %.2f", this->entity_id_.c_str(), this->attribute_.value().c_str(),
|
||||||
|
*val);
|
||||||
|
} else {
|
||||||
ESP_LOGD(TAG, "'%s': Got state %.2f", this->entity_id_.c_str(), *val);
|
ESP_LOGD(TAG, "'%s': Got state %.2f", this->entity_id_.c_str(), *val);
|
||||||
|
}
|
||||||
this->publish_state(*val);
|
this->publish_state(*val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
void HomeassistantSensor::dump_config() {
|
void HomeassistantSensor::dump_config() {
|
||||||
LOG_SENSOR("", "Homeassistant Sensor", this);
|
LOG_SENSOR("", "Homeassistant Sensor", this);
|
||||||
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Attribute: '%s'", this->attribute_.value().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
float HomeassistantSensor::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
|
float HomeassistantSensor::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,14 @@ namespace homeassistant {
|
||||||
class HomeassistantSensor : public sensor::Sensor, public Component {
|
class HomeassistantSensor : public sensor::Sensor, public Component {
|
||||||
public:
|
public:
|
||||||
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
||||||
|
void set_attribute(const std::string &attribute) { attribute_ = attribute; }
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string entity_id_;
|
std::string entity_id_;
|
||||||
|
optional<std::string> attribute_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace homeassistant
|
} // namespace homeassistant
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import text_sensor
|
from esphome.components import text_sensor
|
||||||
from esphome.const import CONF_ENTITY_ID, CONF_ID
|
from esphome.const import CONF_ATTRIBUTE, CONF_ENTITY_ID, CONF_ID
|
||||||
from .. import homeassistant_ns
|
from .. import homeassistant_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["api"]
|
DEPENDENCIES = ["api"]
|
||||||
|
@ -14,6 +14,7 @@ CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(HomeassistantTextSensor),
|
cv.GenerateID(): cv.declare_id(HomeassistantTextSensor),
|
||||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||||
|
cv.Optional(CONF_ATTRIBUTE): cv.string,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,3 +25,5 @@ def to_code(config):
|
||||||
yield text_sensor.register_text_sensor(var, config)
|
yield text_sensor.register_text_sensor(var, config)
|
||||||
|
|
||||||
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
cg.add(var.set_entity_id(config[CONF_ENTITY_ID]))
|
||||||
|
if CONF_ATTRIBUTE in config:
|
||||||
|
cg.add(var.set_attribute(config[CONF_ATTRIBUTE]))
|
||||||
|
|
|
@ -7,16 +7,24 @@ namespace homeassistant {
|
||||||
|
|
||||||
static const char *TAG = "homeassistant.text_sensor";
|
static const char *TAG = "homeassistant.text_sensor";
|
||||||
|
|
||||||
void HomeassistantTextSensor::dump_config() {
|
|
||||||
LOG_TEXT_SENSOR("", "Homeassistant Text Sensor", this);
|
|
||||||
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
|
||||||
}
|
|
||||||
void HomeassistantTextSensor::setup() {
|
void HomeassistantTextSensor::setup() {
|
||||||
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, [this](std::string state) {
|
api::global_api_server->subscribe_home_assistant_state(this->entity_id_, this->attribute_, [this](std::string state) {
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGD(TAG, "'%s::%s': Got attribute state '%s'", this->entity_id_.c_str(), this->attribute_.value().c_str(),
|
||||||
|
state.c_str());
|
||||||
|
} else {
|
||||||
ESP_LOGD(TAG, "'%s': Got state '%s'", this->entity_id_.c_str(), state.c_str());
|
ESP_LOGD(TAG, "'%s': Got state '%s'", this->entity_id_.c_str(), state.c_str());
|
||||||
|
}
|
||||||
this->publish_state(state);
|
this->publish_state(state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
void HomeassistantTextSensor::dump_config() {
|
||||||
|
LOG_TEXT_SENSOR("", "Homeassistant Text Sensor", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Entity ID: '%s'", this->entity_id_.c_str());
|
||||||
|
if (this->attribute_.has_value()) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Attribute: '%s'", this->attribute_.value().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float HomeassistantTextSensor::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
|
||||||
} // namespace homeassistant
|
} // namespace homeassistant
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -9,11 +9,14 @@ namespace homeassistant {
|
||||||
class HomeassistantTextSensor : public text_sensor::TextSensor, public Component {
|
class HomeassistantTextSensor : public text_sensor::TextSensor, public Component {
|
||||||
public:
|
public:
|
||||||
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
void set_entity_id(const std::string &entity_id) { entity_id_ = entity_id; }
|
||||||
void dump_config() override;
|
void set_attribute(const std::string &attribute) { attribute_ = attribute; }
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string entity_id_;
|
std::string entity_id_;
|
||||||
|
optional<std::string> attribute_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace homeassistant
|
} // namespace homeassistant
|
||||||
|
|
|
@ -66,6 +66,7 @@ CONF_ARGS = "args"
|
||||||
CONF_ASSUMED_STATE = "assumed_state"
|
CONF_ASSUMED_STATE = "assumed_state"
|
||||||
CONF_AT = "at"
|
CONF_AT = "at"
|
||||||
CONF_ATTENUATION = "attenuation"
|
CONF_ATTENUATION = "attenuation"
|
||||||
|
CONF_ATTRIBUTE = "attribute"
|
||||||
CONF_AUTH = "auth"
|
CONF_AUTH = "auth"
|
||||||
CONF_AUTO_MODE = "auto_mode"
|
CONF_AUTO_MODE = "auto_mode"
|
||||||
CONF_AUTOMATION_ID = "automation_id"
|
CONF_AUTOMATION_ID = "automation_id"
|
||||||
|
|
|
@ -49,6 +49,7 @@ class CustomNativeAPI : public Component, public CustomAPIDevice {
|
||||||
register_service(&CustomNativeAPI::on_start_dryer, "start_dryer", {"value"});
|
register_service(&CustomNativeAPI::on_start_dryer, "start_dryer", {"value"});
|
||||||
register_service(&CustomNativeAPI::on_many_values, "many_values", {"bool", "int", "float", "str1", "str2"});
|
register_service(&CustomNativeAPI::on_many_values, "many_values", {"bool", "int", "float", "str1", "str2"});
|
||||||
subscribe_homeassistant_state(&CustomNativeAPI::on_light_state, "light.my_light");
|
subscribe_homeassistant_state(&CustomNativeAPI::on_light_state, "light.my_light");
|
||||||
|
subscribe_homeassistant_state(&CustomNativeAPI::on_brightness_state, "light.my_light", "brightness");
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_hello_world() { ESP_LOGD("custom_api", "Hello World from native API service!"); }
|
void on_hello_world() { ESP_LOGD("custom_api", "Hello World from native API service!"); }
|
||||||
|
@ -69,4 +70,5 @@ class CustomNativeAPI : public Component, public CustomAPIDevice {
|
||||||
call_homeassistant_service("homeassistant.restart");
|
call_homeassistant_service("homeassistant.restart");
|
||||||
}
|
}
|
||||||
void on_light_state(std::string state) { ESP_LOGD("custom_api", "Got state %s", state.c_str()); }
|
void on_light_state(std::string state) { ESP_LOGD("custom_api", "Got state %s", state.c_str()); }
|
||||||
|
void on_brightness_state(std::string state) { ESP_LOGD("custom_api", "Got attribute state %s", state.c_str()); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -63,6 +63,10 @@ sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
entity_id: sensor.hello_world
|
entity_id: sensor.hello_world
|
||||||
id: ha_hello_world
|
id: ha_hello_world
|
||||||
|
- platform: homeassistant
|
||||||
|
entity_id: climate.living_room
|
||||||
|
attribute: temperature
|
||||||
|
id: ha_hello_world_temperature
|
||||||
- platform: ble_rssi
|
- platform: ble_rssi
|
||||||
mac_address: AC:37:43:77:5F:4C
|
mac_address: AC:37:43:77:5F:4C
|
||||||
name: 'BLE Google Home Mini RSSI value'
|
name: 'BLE Google Home Mini RSSI value'
|
||||||
|
@ -246,6 +250,10 @@ binary_sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
entity_id: binary_sensor.hello_world
|
entity_id: binary_sensor.hello_world
|
||||||
id: ha_hello_world_binary
|
id: ha_hello_world_binary
|
||||||
|
- platform: homeassistant
|
||||||
|
entity_id: binary_sensor.hello
|
||||||
|
attribute: world
|
||||||
|
id: ha_hello_world_binary_attribute
|
||||||
- platform: ble_presence
|
- platform: ble_presence
|
||||||
mac_address: AC:37:43:77:5F:4C
|
mac_address: AC:37:43:77:5F:4C
|
||||||
name: 'ESP32 BLE Tracker Google Home Mini'
|
name: 'ESP32 BLE Tracker Google Home Mini'
|
||||||
|
@ -355,6 +363,10 @@ text_sensor:
|
||||||
- platform: homeassistant
|
- platform: homeassistant
|
||||||
entity_id: sensor.hello_world2
|
entity_id: sensor.hello_world2
|
||||||
id: ha_hello_world2
|
id: ha_hello_world2
|
||||||
|
- platform: homeassistant
|
||||||
|
entity_id: sensor.hello_world3
|
||||||
|
id: ha_hello_world3
|
||||||
|
attribute: some_attribute
|
||||||
- platform: ble_scanner
|
- platform: ble_scanner
|
||||||
name: Scanner
|
name: Scanner
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue