mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 01:07:45 +01:00
EntityBase Refactor (#2418)
* Renamed Nameable to EntityBase (cpp) * Renamed NAMEABLE_SCHEMA to ENTITY_BASE_SCHEMA (Python) * Renamed cg.Nameable to cg.EntityBase (Python) * Remove redundant use of CONF_NAME from esp32_touch * Remove redundant use of CONF_NAME from mcp3008 * Updated test * Moved EntityBase from Component.h and Component.cpp * Added icon property to EntityBase * Added CONF_ICON to ENTITY_BASE_SCHEMA and added setup_entity function to cpp_helpers * Added MQTT component getters for icon and disabled_by_default * Lint * Removed icon field from MQTT components * Code generation now uses setup_entity to setENTITY_BASE_SCHEMA fields * Removed unused import * Added cstdint include * Optimisation: don't set icon if it is empty * Remove icon from NumberTraits and SelectTraits * Removed unused import * Integration and Total Daily Energy sensors now inherit icons from their parents during code generation * Minor comment correction * Removed redundant icon-handling code from sensor, switch, and text_sensor * Update esphome/components/tsl2591/tsl2591.h Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl> * Added icon property to binary sensor, climate, cover, and fan component tests * Added icons for Binary Sensor, Climate, Cover, Fan, and Light to API * Consolidated EntityBase fields in MQTT components Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
parent
92b85f98e8
commit
471b82f727
83 changed files with 395 additions and 351 deletions
|
@ -67,7 +67,7 @@ from esphome.cpp_types import ( # noqa
|
|||
NAN,
|
||||
esphome_ns,
|
||||
App,
|
||||
Nameable,
|
||||
EntityBase,
|
||||
Component,
|
||||
ComponentPtr,
|
||||
PollingComponent,
|
||||
|
|
|
@ -215,6 +215,7 @@ message ListEntitiesBinarySensorResponse {
|
|||
string device_class = 5;
|
||||
bool is_status_binary_sensor = 6;
|
||||
bool disabled_by_default = 7;
|
||||
string icon = 8;
|
||||
}
|
||||
message BinarySensorStateResponse {
|
||||
option (id) = 21;
|
||||
|
@ -245,6 +246,7 @@ message ListEntitiesCoverResponse {
|
|||
bool supports_tilt = 7;
|
||||
string device_class = 8;
|
||||
bool disabled_by_default = 9;
|
||||
string icon = 10;
|
||||
}
|
||||
|
||||
enum LegacyCoverState {
|
||||
|
@ -313,6 +315,7 @@ message ListEntitiesFanResponse {
|
|||
bool supports_direction = 7;
|
||||
int32 supported_speed_count = 8;
|
||||
bool disabled_by_default = 9;
|
||||
string icon = 10;
|
||||
}
|
||||
enum FanSpeed {
|
||||
FAN_SPEED_LOW = 0;
|
||||
|
@ -388,6 +391,7 @@ message ListEntitiesLightResponse {
|
|||
float max_mireds = 10;
|
||||
repeated string effects = 11;
|
||||
bool disabled_by_default = 13;
|
||||
string icon = 14;
|
||||
}
|
||||
message LightStateResponse {
|
||||
option (id) = 24;
|
||||
|
@ -790,6 +794,7 @@ message ListEntitiesClimateResponse {
|
|||
repeated ClimatePreset supported_presets = 16;
|
||||
repeated string supported_custom_presets = 17;
|
||||
bool disabled_by_default = 18;
|
||||
string icon = 19;
|
||||
}
|
||||
message ClimateStateResponse {
|
||||
option (id) = 47;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "api_connection.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/components/network/util.h"
|
||||
#include "esphome/core/version.h"
|
||||
|
@ -143,8 +144,8 @@ void APIConnection::loop() {
|
|||
}
|
||||
}
|
||||
|
||||
std::string get_default_unique_id(const std::string &component_type, Nameable *nameable) {
|
||||
return App.get_name() + component_type + nameable->get_object_id();
|
||||
std::string get_default_unique_id(const std::string &component_type, EntityBase *entity) {
|
||||
return App.get_name() + component_type + entity->get_object_id();
|
||||
}
|
||||
|
||||
DisconnectResponse APIConnection::disconnect(const DisconnectRequest &msg) {
|
||||
|
@ -180,6 +181,7 @@ bool APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_
|
|||
msg.device_class = binary_sensor->get_device_class();
|
||||
msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
|
||||
msg.disabled_by_default = binary_sensor->is_disabled_by_default();
|
||||
msg.icon = binary_sensor->get_icon();
|
||||
return this->send_list_entities_binary_sensor_response(msg);
|
||||
}
|
||||
#endif
|
||||
|
@ -212,6 +214,7 @@ bool APIConnection::send_cover_info(cover::Cover *cover) {
|
|||
msg.supports_tilt = traits.get_supports_tilt();
|
||||
msg.device_class = cover->get_device_class();
|
||||
msg.disabled_by_default = cover->is_disabled_by_default();
|
||||
msg.icon = cover->get_icon();
|
||||
return this->send_list_entities_cover_response(msg);
|
||||
}
|
||||
void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
||||
|
@ -277,6 +280,7 @@ bool APIConnection::send_fan_info(fan::FanState *fan) {
|
|||
msg.supports_direction = traits.supports_direction();
|
||||
msg.supported_speed_count = traits.supported_speed_count();
|
||||
msg.disabled_by_default = fan->is_disabled_by_default();
|
||||
msg.icon = fan->get_icon();
|
||||
return this->send_list_entities_fan_response(msg);
|
||||
}
|
||||
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
||||
|
@ -339,6 +343,7 @@ bool APIConnection::send_light_info(light::LightState *light) {
|
|||
msg.unique_id = get_default_unique_id("light", light);
|
||||
|
||||
msg.disabled_by_default = light->is_disabled_by_default();
|
||||
msg.icon = light->get_icon();
|
||||
|
||||
for (auto mode : traits.get_supported_color_modes())
|
||||
msg.supported_color_modes.push_back(static_cast<enums::ColorMode>(mode));
|
||||
|
@ -529,6 +534,7 @@ bool APIConnection::send_climate_info(climate::Climate *climate) {
|
|||
msg.unique_id = get_default_unique_id("climate", climate);
|
||||
|
||||
msg.disabled_by_default = climate->is_disabled_by_default();
|
||||
msg.icon = climate->get_icon();
|
||||
|
||||
msg.supports_current_temperature = traits.get_supports_current_temperature();
|
||||
msg.supports_two_point_target_temperature = traits.get_supports_two_point_target_temperature();
|
||||
|
@ -601,7 +607,7 @@ bool APIConnection::send_number_info(number::Number *number) {
|
|||
msg.object_id = number->get_object_id();
|
||||
msg.name = number->get_name();
|
||||
msg.unique_id = get_default_unique_id("number", number);
|
||||
msg.icon = number->traits.get_icon();
|
||||
msg.icon = number->get_icon();
|
||||
msg.disabled_by_default = number->is_disabled_by_default();
|
||||
|
||||
msg.min_value = number->traits.get_min_value();
|
||||
|
@ -638,7 +644,7 @@ bool APIConnection::send_select_info(select::Select *select) {
|
|||
msg.object_id = select->get_object_id();
|
||||
msg.name = select->get_name();
|
||||
msg.unique_id = get_default_unique_id("select", select);
|
||||
msg.icon = select->traits.get_icon();
|
||||
msg.icon = select->get_icon();
|
||||
msg.disabled_by_default = select->is_disabled_by_default();
|
||||
|
||||
for (const auto &option : select->traits.get_options())
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// See scripts/api_protobuf/api_protobuf.py
|
||||
#include "api_pb2.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace esphome {
|
||||
namespace api {
|
||||
|
@ -532,6 +531,10 @@ bool ListEntitiesBinarySensorResponse::decode_length(uint32_t field_id, ProtoLen
|
|||
this->device_class = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 8: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -554,6 +557,7 @@ void ListEntitiesBinarySensorResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_string(5, this->device_class);
|
||||
buffer.encode_bool(6, this->is_status_binary_sensor);
|
||||
buffer.encode_bool(7, this->disabled_by_default);
|
||||
buffer.encode_string(8, this->icon);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const {
|
||||
|
@ -587,6 +591,10 @@ void ListEntitiesBinarySensorResponse::dump_to(std::string &out) const {
|
|||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
@ -678,6 +686,10 @@ bool ListEntitiesCoverResponse::decode_length(uint32_t field_id, ProtoLengthDeli
|
|||
this->device_class = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 10: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -702,6 +714,7 @@ void ListEntitiesCoverResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_bool(7, this->supports_tilt);
|
||||
buffer.encode_string(8, this->device_class);
|
||||
buffer.encode_bool(9, this->disabled_by_default);
|
||||
buffer.encode_string(10, this->icon);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesCoverResponse::dump_to(std::string &out) const {
|
||||
|
@ -743,6 +756,10 @@ void ListEntitiesCoverResponse::dump_to(std::string &out) const {
|
|||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
@ -949,6 +966,10 @@ bool ListEntitiesFanResponse::decode_length(uint32_t field_id, ProtoLengthDelimi
|
|||
this->unique_id = value.as_string();
|
||||
return true;
|
||||
}
|
||||
case 10: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -973,6 +994,7 @@ void ListEntitiesFanResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_bool(7, this->supports_direction);
|
||||
buffer.encode_int32(8, this->supported_speed_count);
|
||||
buffer.encode_bool(9, this->disabled_by_default);
|
||||
buffer.encode_string(10, this->icon);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesFanResponse::dump_to(std::string &out) const {
|
||||
|
@ -1015,6 +1037,10 @@ void ListEntitiesFanResponse::dump_to(std::string &out) const {
|
|||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
@ -1263,6 +1289,10 @@ bool ListEntitiesLightResponse::decode_length(uint32_t field_id, ProtoLengthDeli
|
|||
this->effects.push_back(value.as_string());
|
||||
return true;
|
||||
}
|
||||
case 14: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1303,6 +1333,7 @@ void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_string(11, it, true);
|
||||
}
|
||||
buffer.encode_bool(13, this->disabled_by_default);
|
||||
buffer.encode_string(14, this->icon);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesLightResponse::dump_to(std::string &out) const {
|
||||
|
@ -1366,6 +1397,10 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const {
|
|||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
@ -3073,6 +3108,10 @@ bool ListEntitiesClimateResponse::decode_length(uint32_t field_id, ProtoLengthDe
|
|||
this->supported_custom_presets.push_back(value.as_string());
|
||||
return true;
|
||||
}
|
||||
case 19: {
|
||||
this->icon = value.as_string();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -3130,6 +3169,7 @@ void ListEntitiesClimateResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_string(17, it, true);
|
||||
}
|
||||
buffer.encode_bool(18, this->disabled_by_default);
|
||||
buffer.encode_string(19, this->icon);
|
||||
}
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void ListEntitiesClimateResponse::dump_to(std::string &out) const {
|
||||
|
@ -3222,6 +3262,10 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const {
|
|||
out.append(" disabled_by_default: ");
|
||||
out.append(YESNO(this->disabled_by_default));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" icon: ");
|
||||
out.append("'").append(this->icon).append("'");
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -269,6 +269,7 @@ class ListEntitiesBinarySensorResponse : public ProtoMessage {
|
|||
std::string device_class{};
|
||||
bool is_status_binary_sensor{false};
|
||||
bool disabled_by_default{false};
|
||||
std::string icon{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
@ -304,6 +305,7 @@ class ListEntitiesCoverResponse : public ProtoMessage {
|
|||
bool supports_tilt{false};
|
||||
std::string device_class{};
|
||||
bool disabled_by_default{false};
|
||||
std::string icon{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
@ -360,6 +362,7 @@ class ListEntitiesFanResponse : public ProtoMessage {
|
|||
bool supports_direction{false};
|
||||
int32_t supported_speed_count{0};
|
||||
bool disabled_by_default{false};
|
||||
std::string icon{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
@ -424,6 +427,7 @@ class ListEntitiesLightResponse : public ProtoMessage {
|
|||
float max_mireds{0.0f};
|
||||
std::vector<std::string> effects{};
|
||||
bool disabled_by_default{false};
|
||||
std::string icon{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
@ -856,6 +860,7 @@ class ListEntitiesClimateResponse : public ProtoMessage {
|
|||
std::vector<enums::ClimatePreset> supported_presets{};
|
||||
std::vector<std::string> supported_custom_presets{};
|
||||
bool disabled_by_default{false};
|
||||
std::string icon{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
void dump_to(std::string &out) const override;
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from esphome import automation, core
|
||||
from esphome.automation import Condition, maybe_simple_id
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DELAY,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_FILTERS,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_INVALID_COOLDOWN,
|
||||
CONF_INVERTED,
|
||||
CONF_MAX_LENGTH,
|
||||
|
@ -88,7 +87,7 @@ DEVICE_CLASSES = [
|
|||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
binary_sensor_ns = cg.esphome_ns.namespace("binary_sensor")
|
||||
BinarySensor = binary_sensor_ns.class_("BinarySensor", cg.Nameable)
|
||||
BinarySensor = binary_sensor_ns.class_("BinarySensor", cg.EntityBase)
|
||||
BinarySensorInitiallyOff = binary_sensor_ns.class_(
|
||||
"BinarySensorInitiallyOff", BinarySensor
|
||||
)
|
||||
|
@ -314,7 +313,7 @@ def validate_multi_click_timing(value):
|
|||
|
||||
device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||
|
||||
BINARY_SENSOR_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
BINARY_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BinarySensor),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(
|
||||
|
@ -375,10 +374,8 @@ BINARY_SENSOR_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).exten
|
|||
|
||||
|
||||
async def setup_binary_sensor_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
if CONF_INVERTED in config:
|
||||
|
|
|
@ -42,7 +42,7 @@ void BinarySensor::send_state_internal(bool state, bool is_initial) {
|
|||
}
|
||||
}
|
||||
std::string BinarySensor::device_class() { return ""; }
|
||||
BinarySensor::BinarySensor(const std::string &name) : Nameable(name), state(false) {}
|
||||
BinarySensor::BinarySensor(const std::string &name) : EntityBase(name), state(false) {}
|
||||
BinarySensor::BinarySensor() : BinarySensor("") {}
|
||||
void BinarySensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
|
||||
std::string BinarySensor::get_device_class() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/binary_sensor/filter.h"
|
||||
|
||||
|
@ -22,7 +23,7 @@ namespace binary_sensor {
|
|||
* The sub classes should notify the front-end of new states via the publish_state() method which
|
||||
* handles inverted inputs for you.
|
||||
*/
|
||||
class BinarySensor : public Nameable {
|
||||
class BinarySensor : public EntityBase {
|
||||
public:
|
||||
explicit BinarySensor();
|
||||
/** Construct a binary sensor with the specified name
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from esphome import automation
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_AWAY,
|
||||
CONF_CUSTOM_FAN_MODE,
|
||||
CONF_CUSTOM_PRESET,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_MAX_TEMPERATURE,
|
||||
CONF_MIN_TEMPERATURE,
|
||||
CONF_MODE,
|
||||
|
@ -19,7 +18,6 @@ from esphome.const import (
|
|||
CONF_TEMPERATURE_STEP,
|
||||
CONF_VISUAL,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
CONF_FAN_MODE,
|
||||
CONF_SWING_MODE,
|
||||
)
|
||||
|
@ -30,7 +28,7 @@ IS_PLATFORM_COMPONENT = True
|
|||
CODEOWNERS = ["@esphome/core"]
|
||||
climate_ns = cg.esphome_ns.namespace("climate")
|
||||
|
||||
Climate = climate_ns.class_("Climate", cg.Nameable)
|
||||
Climate = climate_ns.class_("Climate", cg.EntityBase)
|
||||
ClimateCall = climate_ns.class_("ClimateCall")
|
||||
ClimateTraits = climate_ns.class_("ClimateTraits")
|
||||
|
||||
|
@ -88,7 +86,7 @@ validate_climate_swing_mode = cv.enum(CLIMATE_SWING_MODES, upper=True)
|
|||
# Actions
|
||||
ControlAction = climate_ns.class_("ControlAction", automation.Action)
|
||||
|
||||
CLIMATE_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
CLIMATE_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Climate),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTClimateComponent),
|
||||
|
@ -105,10 +103,8 @@ CLIMATE_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).ext
|
|||
|
||||
|
||||
async def setup_climate_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
visual = config[CONF_VISUAL]
|
||||
if CONF_MIN_TEMPERATURE in visual:
|
||||
cg.add(var.set_visual_min_temperature_override(visual[CONF_MIN_TEMPERATURE]))
|
||||
|
|
|
@ -440,7 +440,7 @@ void Climate::set_visual_max_temperature_override(float visual_max_temperature_o
|
|||
void Climate::set_visual_temperature_step_override(float visual_temperature_step_override) {
|
||||
this->visual_temperature_step_override_ = visual_temperature_step_override;
|
||||
}
|
||||
Climate::Climate(const std::string &name) : Nameable(name) {}
|
||||
Climate::Climate(const std::string &name) : EntityBase(name) {}
|
||||
Climate::Climate() : Climate("") {}
|
||||
ClimateCall Climate::make_call() { return ClimateCall(this); }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
@ -163,7 +164,7 @@ struct ClimateDeviceRestoreState {
|
|||
* mode etc). These are read-only for the user and rw for integrations. The reason these are public
|
||||
* is for simple access to them from lambdas `if (id(my_climate).mode == climate::CLIMATE_MODE_HEAT_COOL) ...`
|
||||
*/
|
||||
class Climate : public Nameable {
|
||||
class Climate : public EntityBase {
|
||||
public:
|
||||
/// Construct a climate device with empty name (will be set later).
|
||||
Climate();
|
||||
|
|
|
@ -4,18 +4,16 @@ from esphome import automation
|
|||
from esphome.automation import maybe_simple_id, Condition
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_STATE,
|
||||
CONF_POSITION,
|
||||
CONF_TILT,
|
||||
CONF_STOP,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
|
@ -36,7 +34,7 @@ DEVICE_CLASSES = [
|
|||
|
||||
cover_ns = cg.esphome_ns.namespace("cover")
|
||||
|
||||
Cover = cover_ns.class_("Cover", cg.Nameable)
|
||||
Cover = cover_ns.class_("Cover", cg.EntityBase)
|
||||
|
||||
COVER_OPEN = cover_ns.COVER_OPEN
|
||||
COVER_CLOSED = cover_ns.COVER_CLOSED
|
||||
|
@ -65,7 +63,7 @@ CoverPublishAction = cover_ns.class_("CoverPublishAction", automation.Action)
|
|||
CoverIsOpenCondition = cover_ns.class_("CoverIsOpenCondition", Condition)
|
||||
CoverIsClosedCondition = cover_ns.class_("CoverIsClosedCondition", Condition)
|
||||
|
||||
COVER_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
COVER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Cover),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTCoverComponent),
|
||||
|
@ -76,10 +74,8 @@ COVER_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).exten
|
|||
|
||||
|
||||
async def setup_cover_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ const char *cover_operation_to_str(CoverOperation op) {
|
|||
}
|
||||
}
|
||||
|
||||
Cover::Cover(const std::string &name) : Nameable(name), position{COVER_OPEN} {}
|
||||
Cover::Cover(const std::string &name) : EntityBase(name), position{COVER_OPEN} {}
|
||||
|
||||
uint32_t Cover::hash_base() { return 1727367479UL; }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "cover_traits.h"
|
||||
|
@ -107,7 +108,7 @@ const char *cover_operation_to_str(CoverOperation op);
|
|||
* to control all values of the cover. Also implement get_traits() to return what operations
|
||||
* the cover supports.
|
||||
*/
|
||||
class Cover : public Nameable {
|
||||
class Cover : public EntityBase {
|
||||
public:
|
||||
explicit Cover();
|
||||
explicit Cover(const std::string &name);
|
||||
|
|
|
@ -21,7 +21,7 @@ from esphome.components.esp32 import add_idf_sdkconfig_option
|
|||
DEPENDENCIES = ["esp32", "api"]
|
||||
|
||||
esp32_camera_ns = cg.esphome_ns.namespace("esp32_camera")
|
||||
ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.Nameable)
|
||||
ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.EntityBase)
|
||||
ESP32CameraFrameSize = esp32_camera_ns.enum("ESP32CameraFrameSize")
|
||||
FRAME_SIZES = {
|
||||
"160X120": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
|
||||
|
|
|
@ -172,7 +172,7 @@ void ESP32Camera::framebuffer_task(void *pv) {
|
|||
esp_camera_fb_return(framebuffer);
|
||||
}
|
||||
}
|
||||
ESP32Camera::ESP32Camera(const std::string &name) : Nameable(name) {
|
||||
ESP32Camera::ESP32Camera(const std::string &name) : EntityBase(name) {
|
||||
this->config_.pin_pwdn = -1;
|
||||
this->config_.pin_reset = -1;
|
||||
this->config_.pin_xclk = -1;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#ifdef USE_ESP32
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include <esp_camera.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
|
@ -50,7 +51,7 @@ enum ESP32CameraFrameSize {
|
|||
ESP32_CAMERA_SIZE_1600X1200, // UXGA
|
||||
};
|
||||
|
||||
class ESP32Camera : public Component, public Nameable {
|
||||
class ESP32Camera : public Component, public EntityBase {
|
||||
public:
|
||||
ESP32Camera(const std::string &name);
|
||||
void set_data_pins(std::array<uint8_t, 8> pins);
|
||||
|
|
|
@ -2,7 +2,6 @@ import esphome.codegen as cg
|
|||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import (
|
||||
CONF_NAME,
|
||||
CONF_PIN,
|
||||
CONF_THRESHOLD,
|
||||
CONF_ID,
|
||||
|
@ -55,7 +54,6 @@ async def to_code(config):
|
|||
hub = await cg.get_variable(config[CONF_ESP32_TOUCH_ID])
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
config[CONF_NAME],
|
||||
TOUCH_PADS[config[CONF_PIN]],
|
||||
config[CONF_THRESHOLD],
|
||||
config[CONF_WAKEUP_THRESHOLD],
|
||||
|
|
|
@ -159,9 +159,8 @@ void ESP32TouchComponent::on_shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
ESP32TouchBinarySensor::ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold,
|
||||
uint16_t wakeup_threshold)
|
||||
: BinarySensor(name), touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
|
||||
ESP32TouchBinarySensor::ESP32TouchBinarySensor(touch_pad_t touch_pad, uint16_t threshold, uint16_t wakeup_threshold)
|
||||
: BinarySensor(), touch_pad_(touch_pad), threshold_(threshold), wakeup_threshold_(wakeup_threshold) {}
|
||||
|
||||
} // namespace esp32_touch
|
||||
} // namespace esphome
|
||||
|
|
|
@ -64,7 +64,7 @@ class ESP32TouchComponent : public Component {
|
|||
/// Simple helper class to expose a touch pad value as a binary sensor.
|
||||
class ESP32TouchBinarySensor : public binary_sensor::BinarySensor {
|
||||
public:
|
||||
ESP32TouchBinarySensor(const std::string &name, touch_pad_t touch_pad, uint16_t threshold, uint16_t wakeup_threshold);
|
||||
ESP32TouchBinarySensor(touch_pad_t touch_pad, uint16_t threshold, uint16_t wakeup_threshold);
|
||||
|
||||
touch_pad_t get_touch_pad() const { return touch_pad_; }
|
||||
uint16_t get_threshold() const { return threshold_; }
|
||||
|
|
|
@ -4,9 +4,7 @@ from esphome import automation
|
|||
from esphome.automation import maybe_simple_id
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_MQTT_ID,
|
||||
CONF_OSCILLATING,
|
||||
CONF_OSCILLATION_COMMAND_TOPIC,
|
||||
|
@ -16,7 +14,6 @@ from esphome.const import (
|
|||
CONF_SPEED_LEVEL_STATE_TOPIC,
|
||||
CONF_SPEED_COMMAND_TOPIC,
|
||||
CONF_SPEED_STATE_TOPIC,
|
||||
CONF_NAME,
|
||||
CONF_ON_SPEED_SET,
|
||||
CONF_ON_TURN_OFF,
|
||||
CONF_ON_TURN_ON,
|
||||
|
@ -24,11 +21,12 @@ from esphome.const import (
|
|||
CONF_DIRECTION,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
fan_ns = cg.esphome_ns.namespace("fan")
|
||||
FanState = fan_ns.class_("FanState", cg.Nameable, cg.Component)
|
||||
FanState = fan_ns.class_("FanState", cg.EntityBase, cg.Component)
|
||||
MakeFan = cg.Application.struct("MakeFan")
|
||||
|
||||
FanDirection = fan_ns.enum("FanDirection")
|
||||
|
@ -50,7 +48,7 @@ FanSpeedSetTrigger = fan_ns.class_("FanSpeedSetTrigger", automation.Trigger.temp
|
|||
FanIsOnCondition = fan_ns.class_("FanIsOnCondition", automation.Condition.template())
|
||||
FanIsOffCondition = fan_ns.class_("FanIsOffCondition", automation.Condition.template())
|
||||
|
||||
FAN_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
FAN_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(FanState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
|
||||
|
@ -92,10 +90,7 @@ FAN_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
|||
|
||||
|
||||
async def setup_fan_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_MQTT_ID in config:
|
||||
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||
|
|
|
@ -12,7 +12,7 @@ void FanState::set_traits(const FanTraits &traits) { this->traits_ = traits; }
|
|||
void FanState::add_on_state_callback(std::function<void()> &&callback) {
|
||||
this->state_callback_.add(std::move(callback));
|
||||
}
|
||||
FanState::FanState(const std::string &name) : Nameable(name) {}
|
||||
FanState::FanState(const std::string &name) : EntityBase(name) {}
|
||||
|
||||
FanStateCall FanState::turn_on() { return this->make_call().set_state(true); }
|
||||
FanStateCall FanState::turn_off() { return this->make_call().set_state(false); }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
@ -66,7 +67,7 @@ class FanStateCall {
|
|||
optional<FanDirection> direction_{};
|
||||
};
|
||||
|
||||
class FanState : public Nameable, public Component {
|
||||
class FanState : public EntityBase, public Component {
|
||||
public:
|
||||
FanState() = default;
|
||||
/// Construct the fan state with name.
|
||||
|
|
|
@ -64,7 +64,6 @@ class IntegrationSensor : public sensor::Sensor, public Component {
|
|||
this->rtc_.save(&result_f);
|
||||
}
|
||||
std::string unit_of_measurement() override;
|
||||
std::string icon() override { return this->sensor_->get_icon(); }
|
||||
int8_t accuracy_decimals() override { return this->sensor_->get_accuracy_decimals() + 2; }
|
||||
|
||||
sensor::Sensor *sensor_;
|
||||
|
|
|
@ -2,7 +2,8 @@ import esphome.codegen as cg
|
|||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, CONF_SENSOR, CONF_RESTORE
|
||||
from esphome.const import CONF_ICON, CONF_ID, CONF_SENSOR, CONF_RESTORE
|
||||
from esphome.core.entity_helpers import inherit_property_from
|
||||
|
||||
integration_ns = cg.esphome_ns.namespace("integration")
|
||||
IntegrationSensor = integration_ns.class_(
|
||||
|
@ -29,7 +30,6 @@ CONF_TIME_UNIT = "time_unit"
|
|||
CONF_INTEGRATION_METHOD = "integration_method"
|
||||
CONF_MIN_SAVE_INTERVAL = "min_save_interval"
|
||||
|
||||
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(IntegrationSensor),
|
||||
|
@ -46,6 +46,19 @@ CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
|
|||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(IntegrationSensor),
|
||||
cv.Optional(CONF_ICON): cv.icon,
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
},
|
||||
extra=cv.ALLOW_EXTRA,
|
||||
),
|
||||
inherit_property_from(CONF_ICON, CONF_SENSOR),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
|
||||
|
|
|
@ -5,13 +5,10 @@ from esphome.components import mqtt, power_supply
|
|||
from esphome.const import (
|
||||
CONF_COLOR_CORRECT,
|
||||
CONF_DEFAULT_TRANSITION_LENGTH,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_EFFECTS,
|
||||
CONF_FLASH_TRANSITION_LENGTH,
|
||||
CONF_GAMMA_CORRECT,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
CONF_POWER_SUPPLY,
|
||||
CONF_RESTORE_MODE,
|
||||
|
@ -22,6 +19,7 @@ from esphome.const import (
|
|||
CONF_WARM_WHITE_COLOR_TEMPERATURE,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from .automation import light_control_to_code # noqa
|
||||
from .effects import (
|
||||
validate_effects,
|
||||
|
@ -54,7 +52,7 @@ RESTORE_MODES = {
|
|||
"RESTORE_INVERTED_DEFAULT_ON": LightRestoreMode.LIGHT_RESTORE_INVERTED_DEFAULT_ON,
|
||||
}
|
||||
|
||||
LIGHT_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
LIGHT_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(LightState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTJSONLightComponent),
|
||||
|
@ -126,10 +124,10 @@ def validate_color_temperature_channels(value):
|
|||
|
||||
|
||||
async def setup_light_core_(light_var, output_var, config):
|
||||
cg.add(light_var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
await setup_entity(light_var, config)
|
||||
|
||||
cg.add(light_var.set_restore_mode(config[CONF_RESTORE_MODE]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(light_var.set_internal(config[CONF_INTERNAL]))
|
||||
|
||||
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
||||
cg.add(
|
||||
light_var.set_default_transition_length(
|
||||
|
@ -167,7 +165,7 @@ async def setup_light_core_(light_var, output_var, config):
|
|||
|
||||
|
||||
async def register_light(output_var, config):
|
||||
light_var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME], output_var)
|
||||
light_var = cg.new_Pvariable(config[CONF_ID], output_var)
|
||||
cg.add(cg.App.register_light(light_var))
|
||||
await cg.register_component(light_var, config)
|
||||
await setup_light_core_(light_var, output_var, config)
|
||||
|
|
|
@ -8,7 +8,8 @@ namespace light {
|
|||
|
||||
static const char *const TAG = "light";
|
||||
|
||||
LightState::LightState(const std::string &name, LightOutput *output) : Nameable(name), output_(output) {}
|
||||
LightState::LightState(const std::string &name, LightOutput *output) : EntityBase(name), output_(output) {}
|
||||
LightState::LightState(LightOutput *output) : output_(output) {}
|
||||
|
||||
LightTraits LightState::get_traits() { return this->output_->get_traits(); }
|
||||
LightCall LightState::turn_on() { return this->make_call().set_state(true); }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/optional.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "light_call.h"
|
||||
|
@ -26,11 +27,13 @@ enum LightRestoreMode {
|
|||
/** This class represents the communication layer between the front-end MQTT layer and the
|
||||
* hardware output layer.
|
||||
*/
|
||||
class LightState : public Nameable, public Component {
|
||||
class LightState : public EntityBase, public Component {
|
||||
public:
|
||||
/// Construct this LightState using the provided traits and name.
|
||||
LightState(const std::string &name, LightOutput *output);
|
||||
|
||||
LightState(LightOutput *output);
|
||||
|
||||
LightTraits get_traits();
|
||||
|
||||
/// Make a light state call
|
||||
|
|
|
@ -3,7 +3,7 @@ from esphome import automation
|
|||
|
||||
# Base
|
||||
light_ns = cg.esphome_ns.namespace("light")
|
||||
LightState = light_ns.class_("LightState", cg.Nameable, cg.Component)
|
||||
LightState = light_ns.class_("LightState", cg.EntityBase, cg.Component)
|
||||
# Fake class for addressable lights
|
||||
AddressableLightState = light_ns.class_("LightState", LightState)
|
||||
LightOutput = light_ns.class_("LightOutput")
|
||||
|
|
|
@ -37,10 +37,8 @@ float MCP3008::read_data(uint8_t pin) {
|
|||
return data / 1023.0f;
|
||||
}
|
||||
|
||||
MCP3008Sensor::MCP3008Sensor(MCP3008 *parent, const std::string &name, uint8_t pin, float reference_voltage)
|
||||
: PollingComponent(1000), parent_(parent), pin_(pin), reference_voltage_(reference_voltage) {
|
||||
this->set_name(name);
|
||||
}
|
||||
MCP3008Sensor::MCP3008Sensor(MCP3008 *parent, uint8_t pin, float reference_voltage)
|
||||
: PollingComponent(1000), parent_(parent), pin_(pin), reference_voltage_(reference_voltage) {}
|
||||
|
||||
float MCP3008Sensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class MCP3008 : public Component,
|
|||
|
||||
class MCP3008Sensor : public PollingComponent, public sensor::Sensor, public voltage_sampler::VoltageSampler {
|
||||
public:
|
||||
MCP3008Sensor(MCP3008 *parent, const std::string &name, uint8_t pin, float reference_voltage);
|
||||
MCP3008Sensor(MCP3008 *parent, uint8_t pin, float reference_voltage);
|
||||
|
||||
void set_reference_voltage(float reference_voltage) { reference_voltage_ = reference_voltage; }
|
||||
void setup() override;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_NAME
|
||||
from esphome.const import CONF_ID, CONF_NUMBER
|
||||
from . import mcp3008_ns, MCP3008
|
||||
|
||||
AUTO_LOAD = ["voltage_sampler"]
|
||||
|
@ -29,7 +29,6 @@ async def to_code(config):
|
|||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
parent,
|
||||
config[CONF_NAME],
|
||||
config[CONF_NUMBER],
|
||||
config[CONF_REFERENCE_VOLTAGE],
|
||||
)
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace mqtt {
|
|||
static const char *const TAG = "mqtt.binary_sensor";
|
||||
|
||||
std::string MQTTBinarySensorComponent::component_type() const { return "binary_sensor"; }
|
||||
const EntityBase *MQTTBinarySensorComponent::get_entity() const { return this->binary_sensor_; }
|
||||
|
||||
void MQTTBinarySensorComponent::setup() {
|
||||
this->binary_sensor_->add_on_state_callback([this](bool state) { this->publish_state(state); });
|
||||
|
@ -25,7 +26,6 @@ MQTTBinarySensorComponent::MQTTBinarySensorComponent(binary_sensor::BinarySensor
|
|||
this->set_custom_state_topic(mqtt::global_mqtt_client->get_availability().topic);
|
||||
}
|
||||
}
|
||||
std::string MQTTBinarySensorComponent::friendly_name() const { return this->binary_sensor_->get_name(); }
|
||||
|
||||
void MQTTBinarySensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
if (!this->binary_sensor_->get_device_class().empty())
|
||||
|
@ -43,7 +43,6 @@ bool MQTTBinarySensorComponent::send_initial_state() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool MQTTBinarySensorComponent::is_internal() { return this->binary_sensor_->is_internal(); }
|
||||
bool MQTTBinarySensorComponent::publish_state(bool state) {
|
||||
if (this->binary_sensor_->is_status_binary_sensor())
|
||||
return true;
|
||||
|
|
|
@ -28,11 +28,10 @@ class MQTTBinarySensorComponent : public mqtt::MQTTComponent {
|
|||
|
||||
bool send_initial_state() override;
|
||||
bool publish_state(bool state);
|
||||
bool is_internal() override;
|
||||
|
||||
protected:
|
||||
std::string friendly_name() const override;
|
||||
std::string component_type() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
binary_sensor::BinarySensor *binary_sensor_;
|
||||
};
|
||||
|
|
|
@ -212,9 +212,9 @@ void MQTTClimateComponent::setup() {
|
|||
}
|
||||
MQTTClimateComponent::MQTTClimateComponent(Climate *device) : device_(device) {}
|
||||
bool MQTTClimateComponent::send_initial_state() { return this->publish_state_(); }
|
||||
bool MQTTClimateComponent::is_internal() { return this->device_->is_internal(); }
|
||||
std::string MQTTClimateComponent::component_type() const { return "climate"; }
|
||||
std::string MQTTClimateComponent::friendly_name() const { return this->device_->get_name(); }
|
||||
const EntityBase *MQTTClimateComponent::get_entity() const { return this->device_; }
|
||||
|
||||
bool MQTTClimateComponent::publish_state_() {
|
||||
auto traits = this->device_->get_traits();
|
||||
// mode
|
||||
|
|
|
@ -16,7 +16,6 @@ class MQTTClimateComponent : public mqtt::MQTTComponent {
|
|||
MQTTClimateComponent(climate::Climate *device);
|
||||
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
std::string component_type() const override;
|
||||
void setup() override;
|
||||
|
||||
|
@ -38,7 +37,7 @@ class MQTTClimateComponent : public mqtt::MQTTComponent {
|
|||
MQTT_COMPONENT_CUSTOM_TOPIC(swing_mode, command)
|
||||
|
||||
protected:
|
||||
std::string friendly_name() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
bool publish_state_();
|
||||
|
||||
|
|
|
@ -68,8 +68,13 @@ bool MQTTComponent::send_discovery_() {
|
|||
|
||||
this->send_discovery(root, config);
|
||||
|
||||
std::string name = this->friendly_name();
|
||||
root["name"] = name;
|
||||
// Fields from EntityBase
|
||||
root["name"] = this->friendly_name();
|
||||
if (this->is_disabled_by_default())
|
||||
root["enabled_by_default"] = false;
|
||||
if (!this->get_icon().empty())
|
||||
root["icon"] = this->get_icon();
|
||||
|
||||
if (config.state_topic)
|
||||
root["state_topic"] = this->get_state_topic_();
|
||||
if (config.command_topic)
|
||||
|
@ -199,6 +204,12 @@ void MQTTComponent::schedule_resend_state() { this->resend_state_ = true; }
|
|||
std::string MQTTComponent::unique_id() { return ""; }
|
||||
bool MQTTComponent::is_connected_() const { return global_mqtt_client->is_connected(); }
|
||||
|
||||
// Pull these properties from EntityBase if not overridden
|
||||
std::string MQTTComponent::friendly_name() const { return this->get_entity()->get_name(); }
|
||||
std::string MQTTComponent::get_icon() const { return this->get_entity()->get_icon(); }
|
||||
bool MQTTComponent::is_disabled_by_default() const { return this->get_entity()->is_disabled_by_default(); }
|
||||
bool MQTTComponent::is_internal() { return this->get_entity()->is_internal(); }
|
||||
|
||||
} // namespace mqtt
|
||||
} // namespace esphome
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <memory>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "mqtt_client.h"
|
||||
|
||||
namespace esphome {
|
||||
|
@ -73,7 +74,7 @@ class MQTTComponent : public Component {
|
|||
|
||||
virtual bool send_initial_state() = 0;
|
||||
|
||||
virtual bool is_internal() = 0;
|
||||
virtual bool is_internal();
|
||||
|
||||
/// Set whether state message should be retained.
|
||||
void set_retain(bool retain);
|
||||
|
@ -148,8 +149,10 @@ class MQTTComponent : public Component {
|
|||
*/
|
||||
std::string get_default_topic_for_(const std::string &suffix) const;
|
||||
|
||||
/// Get the friendly name of this MQTT component.
|
||||
virtual std::string friendly_name() const = 0;
|
||||
/**
|
||||
* Gets the Entity served by this MQTT component.
|
||||
*/
|
||||
virtual const EntityBase *get_entity() const = 0;
|
||||
|
||||
/** A unique ID for this MQTT component, empty for no unique id. See unique ID requirements:
|
||||
* https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements
|
||||
|
@ -158,6 +161,15 @@ class MQTTComponent : public Component {
|
|||
*/
|
||||
virtual std::string unique_id();
|
||||
|
||||
/// Get the friendly name of this MQTT component.
|
||||
virtual std::string friendly_name() const;
|
||||
|
||||
/// Get the icon field of this component
|
||||
virtual std::string get_icon() const;
|
||||
|
||||
/// Get whether the underlying Entity is disabled by default
|
||||
virtual bool is_disabled_by_default() const;
|
||||
|
||||
/// Get the MQTT topic that new states will be shared to.
|
||||
const std::string get_state_topic_() const;
|
||||
|
||||
|
|
|
@ -84,9 +84,9 @@ void MQTTCoverComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCon
|
|||
}
|
||||
|
||||
std::string MQTTCoverComponent::component_type() const { return "cover"; }
|
||||
std::string MQTTCoverComponent::friendly_name() const { return this->cover_->get_name(); }
|
||||
const EntityBase *MQTTCoverComponent::get_entity() const { return this->cover_; }
|
||||
|
||||
bool MQTTCoverComponent::send_initial_state() { return this->publish_state(); }
|
||||
bool MQTTCoverComponent::is_internal() { return this->cover_->is_internal(); }
|
||||
bool MQTTCoverComponent::publish_state() {
|
||||
auto traits = this->cover_->get_traits();
|
||||
bool success = true;
|
||||
|
|
|
@ -24,7 +24,6 @@ class MQTTCoverComponent : public mqtt::MQTTComponent {
|
|||
MQTT_COMPONENT_CUSTOM_TOPIC(tilt, state)
|
||||
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
|
||||
bool publish_state();
|
||||
|
||||
|
@ -32,7 +31,7 @@ class MQTTCoverComponent : public mqtt::MQTTComponent {
|
|||
|
||||
protected:
|
||||
std::string component_type() const override;
|
||||
std::string friendly_name() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
cover::Cover *cover_;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ MQTTFanComponent::MQTTFanComponent(FanState *state) : MQTTComponent(), state_(st
|
|||
|
||||
FanState *MQTTFanComponent::get_state() const { return this->state_; }
|
||||
std::string MQTTFanComponent::component_type() const { return "fan"; }
|
||||
const EntityBase *MQTTFanComponent::get_entity() const { return this->state_; }
|
||||
|
||||
void MQTTFanComponent::setup() {
|
||||
this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
|
||||
|
@ -113,7 +114,7 @@ void MQTTFanComponent::dump_config() {
|
|||
}
|
||||
|
||||
bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
|
||||
std::string MQTTFanComponent::friendly_name() const { return this->state_->get_name(); }
|
||||
|
||||
void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
if (this->state_->get_traits().supports_oscillation()) {
|
||||
root["oscillation_command_topic"] = this->get_oscillation_command_topic();
|
||||
|
@ -126,7 +127,6 @@ void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfi
|
|||
root["speed_state_topic"] = this->get_speed_state_topic();
|
||||
}
|
||||
}
|
||||
bool MQTTFanComponent::is_internal() { return this->state_->is_internal(); }
|
||||
bool MQTTFanComponent::publish_state() {
|
||||
const char *state_s = this->state_->state ? "ON" : "OFF";
|
||||
ESP_LOGD(TAG, "'%s' Sending state %s.", this->state_->get_name().c_str(), state_s);
|
||||
|
|
|
@ -39,10 +39,8 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
|
|||
|
||||
fan::FanState *get_state() const;
|
||||
|
||||
bool is_internal() override;
|
||||
|
||||
protected:
|
||||
std::string friendly_name() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
fan::FanState *state_;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ static const char *const TAG = "mqtt.light";
|
|||
using namespace esphome::light;
|
||||
|
||||
std::string MQTTJSONLightComponent::component_type() const { return "light"; }
|
||||
const EntityBase *MQTTJSONLightComponent::get_entity() const { return this->state_; }
|
||||
|
||||
void MQTTJSONLightComponent::setup() {
|
||||
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject &root) {
|
||||
|
@ -32,7 +33,7 @@ bool MQTTJSONLightComponent::publish_state_() {
|
|||
[this](JsonObject &root) { LightJSONSchema::dump_json(*this->state_, root); });
|
||||
}
|
||||
LightState *MQTTJSONLightComponent::get_state() const { return this->state_; }
|
||||
std::string MQTTJSONLightComponent::friendly_name() const { return this->state_->get_name(); }
|
||||
|
||||
void MQTTJSONLightComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
root["schema"] = "json";
|
||||
auto traits = this->state_->get_traits();
|
||||
|
@ -70,7 +71,6 @@ void MQTTJSONLightComponent::send_discovery(JsonObject &root, mqtt::SendDiscover
|
|||
}
|
||||
}
|
||||
bool MQTTJSONLightComponent::send_initial_state() { return this->publish_state_(); }
|
||||
bool MQTTJSONLightComponent::is_internal() { return this->state_->is_internal(); }
|
||||
void MQTTJSONLightComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "MQTT Light '%s':", this->state_->get_name().c_str());
|
||||
LOG_MQTT_COMPONENT(true, true)
|
||||
|
|
|
@ -25,11 +25,9 @@ class MQTTJSONLightComponent : public mqtt::MQTTComponent {
|
|||
|
||||
bool send_initial_state() override;
|
||||
|
||||
bool is_internal() override;
|
||||
|
||||
protected:
|
||||
std::string friendly_name() const override;
|
||||
std::string component_type() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
bool publish_state_();
|
||||
|
||||
|
|
|
@ -33,13 +33,11 @@ void MQTTNumberComponent::dump_config() {
|
|||
}
|
||||
|
||||
std::string MQTTNumberComponent::component_type() const { return "number"; }
|
||||
const EntityBase *MQTTNumberComponent::get_entity() const { return this->number_; }
|
||||
|
||||
std::string MQTTNumberComponent::friendly_name() const { return this->number_->get_name(); }
|
||||
void MQTTNumberComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
const auto &traits = number_->traits;
|
||||
// https://www.home-assistant.io/integrations/number.mqtt/
|
||||
if (!traits.get_icon().empty())
|
||||
root["icon"] = traits.get_icon();
|
||||
root["min"] = traits.get_min_value();
|
||||
root["max"] = traits.get_max_value();
|
||||
root["step"] = traits.get_step();
|
||||
|
@ -53,7 +51,6 @@ bool MQTTNumberComponent::send_initial_state() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool MQTTNumberComponent::is_internal() { return this->number_->is_internal(); }
|
||||
bool MQTTNumberComponent::publish_state(float value) {
|
||||
char buffer[64];
|
||||
snprintf(buffer, sizeof(buffer), "%f", value);
|
||||
|
|
|
@ -28,15 +28,13 @@ class MQTTNumberComponent : public mqtt::MQTTComponent {
|
|||
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
|
||||
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
|
||||
bool publish_state(float value);
|
||||
|
||||
protected:
|
||||
/// Override for MQTTComponent, returns "number".
|
||||
std::string component_type() const override;
|
||||
|
||||
std::string friendly_name() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
number::Number *number_;
|
||||
};
|
||||
|
|
|
@ -28,13 +28,11 @@ void MQTTSelectComponent::dump_config() {
|
|||
}
|
||||
|
||||
std::string MQTTSelectComponent::component_type() const { return "select"; }
|
||||
const EntityBase *MQTTSelectComponent::get_entity() const { return this->select_; }
|
||||
|
||||
std::string MQTTSelectComponent::friendly_name() const { return this->select_->get_name(); }
|
||||
void MQTTSelectComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
const auto &traits = select_->traits;
|
||||
// https://www.home-assistant.io/integrations/select.mqtt/
|
||||
if (!traits.get_icon().empty())
|
||||
root["icon"] = traits.get_icon();
|
||||
JsonArray &options = root.createNestedArray("options");
|
||||
for (const auto &option : traits.get_options())
|
||||
options.add(option);
|
||||
|
@ -48,7 +46,6 @@ bool MQTTSelectComponent::send_initial_state() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool MQTTSelectComponent::is_internal() { return this->select_->is_internal(); }
|
||||
bool MQTTSelectComponent::publish_state(const std::string &value) {
|
||||
return this->publish(this->get_state_topic_(), value);
|
||||
}
|
||||
|
|
|
@ -28,15 +28,13 @@ class MQTTSelectComponent : public mqtt::MQTTComponent {
|
|||
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
|
||||
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
|
||||
bool publish_state(const std::string &value);
|
||||
|
||||
protected:
|
||||
/// Override for MQTTComponent, returns "select".
|
||||
std::string component_type() const override;
|
||||
|
||||
std::string friendly_name() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
select::Select *select_;
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@ void MQTTSensorComponent::dump_config() {
|
|||
}
|
||||
|
||||
std::string MQTTSensorComponent::component_type() const { return "sensor"; }
|
||||
const EntityBase *MQTTSensorComponent::get_entity() const { return this->sensor_; }
|
||||
|
||||
uint32_t MQTTSensorComponent::get_expire_after() const {
|
||||
if (this->expire_after_.has_value())
|
||||
|
@ -38,7 +39,7 @@ uint32_t MQTTSensorComponent::get_expire_after() const {
|
|||
}
|
||||
void MQTTSensorComponent::set_expire_after(uint32_t expire_after) { this->expire_after_ = expire_after; }
|
||||
void MQTTSensorComponent::disable_expire_after() { this->expire_after_ = 0; }
|
||||
std::string MQTTSensorComponent::friendly_name() const { return this->sensor_->get_name(); }
|
||||
|
||||
void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
if (!this->sensor_->get_device_class().empty())
|
||||
root["device_class"] = this->sensor_->get_device_class();
|
||||
|
@ -49,9 +50,6 @@ void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo
|
|||
if (this->get_expire_after() > 0)
|
||||
root["expire_after"] = this->get_expire_after() / 1000;
|
||||
|
||||
if (!this->sensor_->get_icon().empty())
|
||||
root["icon"] = this->sensor_->get_icon();
|
||||
|
||||
if (this->sensor_->get_force_update())
|
||||
root["force_update"] = true;
|
||||
|
||||
|
@ -67,7 +65,6 @@ bool MQTTSensorComponent::send_initial_state() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool MQTTSensorComponent::is_internal() { return this->sensor_->is_internal(); }
|
||||
bool MQTTSensorComponent::publish_state(float value) {
|
||||
int8_t accuracy = this->sensor_->get_accuracy_decimals();
|
||||
return this->publish(this->get_state_topic_(), value_accuracy_to_string(value, accuracy));
|
||||
|
|
|
@ -41,14 +41,11 @@ class MQTTSensorComponent : public mqtt::MQTTComponent {
|
|||
|
||||
bool publish_state(float value);
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
|
||||
protected:
|
||||
/// Override for MQTTComponent, returns "sensor".
|
||||
std::string component_type() const override;
|
||||
|
||||
std::string friendly_name() const override;
|
||||
|
||||
const EntityBase *get_entity() const override;
|
||||
std::string unique_id() override;
|
||||
|
||||
sensor::Sensor *sensor_;
|
||||
|
|
|
@ -41,15 +41,13 @@ void MQTTSwitchComponent::dump_config() {
|
|||
}
|
||||
|
||||
std::string MQTTSwitchComponent::component_type() const { return "switch"; }
|
||||
const EntityBase *MQTTSwitchComponent::get_entity() const { return this->switch_; }
|
||||
void MQTTSwitchComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
if (!this->switch_->get_icon().empty())
|
||||
root["icon"] = this->switch_->get_icon();
|
||||
if (this->switch_->assumed_state())
|
||||
root["optimistic"] = true;
|
||||
}
|
||||
bool MQTTSwitchComponent::send_initial_state() { return this->publish_state(this->switch_->state); }
|
||||
bool MQTTSwitchComponent::is_internal() { return this->switch_->is_internal(); }
|
||||
std::string MQTTSwitchComponent::friendly_name() const { return this->switch_->get_name(); }
|
||||
|
||||
bool MQTTSwitchComponent::publish_state(bool state) {
|
||||
const char *state_s = state ? "ON" : "OFF";
|
||||
return this->publish(this->get_state_topic_(), state_s);
|
||||
|
|
|
@ -23,15 +23,13 @@ class MQTTSwitchComponent : public mqtt::MQTTComponent {
|
|||
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
|
||||
|
||||
bool send_initial_state() override;
|
||||
bool is_internal() override;
|
||||
|
||||
bool publish_state(bool state);
|
||||
|
||||
protected:
|
||||
std::string friendly_name() const override;
|
||||
|
||||
/// "switch" component type.
|
||||
std::string component_type() const override;
|
||||
const EntityBase *get_entity() const override;
|
||||
|
||||
switch_::Switch *switch_;
|
||||
};
|
||||
|
|
|
@ -13,9 +13,6 @@ using namespace esphome::text_sensor;
|
|||
|
||||
MQTTTextSensor::MQTTTextSensor(TextSensor *sensor) : MQTTComponent(), sensor_(sensor) {}
|
||||
void MQTTTextSensor::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
|
||||
if (!this->sensor_->get_icon().empty())
|
||||
root["icon"] = this->sensor_->get_icon();
|
||||
|
||||
config.command_topic = false;
|
||||
}
|
||||
void MQTTTextSensor::setup() {
|
||||
|
@ -35,9 +32,8 @@ bool MQTTTextSensor::send_initial_state() {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
bool MQTTTextSensor::is_internal() { return this->sensor_->is_internal(); }
|
||||
std::string MQTTTextSensor::component_type() const { return "sensor"; }
|
||||
std::string MQTTTextSensor::friendly_name() const { return this->sensor_->get_name(); }
|
||||
const EntityBase *MQTTTextSensor::get_entity() const { return this->sensor_; }
|
||||
std::string MQTTTextSensor::unique_id() { return this->sensor_->unique_id(); }
|
||||
|
||||
} // namespace mqtt
|
||||
|
|
|
@ -25,13 +25,9 @@ class MQTTTextSensor : public mqtt::MQTTComponent {
|
|||
|
||||
bool send_initial_state() override;
|
||||
|
||||
bool is_internal() override;
|
||||
|
||||
protected:
|
||||
std::string component_type() const override;
|
||||
|
||||
std::string friendly_name() const override;
|
||||
|
||||
const EntityBase *get_entity() const override;
|
||||
std::string unique_id() override;
|
||||
|
||||
text_sensor::TextSensor *sensor_;
|
||||
|
|
|
@ -6,25 +6,21 @@ from esphome.components import mqtt
|
|||
from esphome.const import (
|
||||
CONF_ABOVE,
|
||||
CONF_BELOW,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_ON_VALUE,
|
||||
CONF_ON_VALUE_RANGE,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
CONF_VALUE,
|
||||
ICON_EMPTY,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
number_ns = cg.esphome_ns.namespace("number")
|
||||
Number = number_ns.class_("Number", cg.Nameable)
|
||||
Number = number_ns.class_("Number", cg.EntityBase)
|
||||
NumberPtr = Number.operator("ptr")
|
||||
|
||||
# Triggers
|
||||
|
@ -46,11 +42,10 @@ NumberInRangeCondition = number_ns.class_(
|
|||
icon = cv.icon
|
||||
|
||||
|
||||
NUMBER_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
NUMBER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTNumberComponent),
|
||||
cv.GenerateID(): cv.declare_id(Number),
|
||||
cv.Optional(CONF_ICON, default=ICON_EMPTY): icon,
|
||||
cv.Optional(CONF_ON_VALUE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(NumberStateTrigger),
|
||||
|
@ -71,12 +66,8 @@ NUMBER_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
|||
async def setup_number_core_(
|
||||
var, config, *, min_value: float, max_value: float, step: Optional[float]
|
||||
):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
cg.add(var.traits.set_icon(config[CONF_ICON]))
|
||||
cg.add(var.traits.set_min_value(min_value))
|
||||
cg.add(var.traits.set_max_value(max_value))
|
||||
if step is not None:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
|
@ -9,8 +10,8 @@ namespace number {
|
|||
#define LOG_NUMBER(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
|
||||
if (!(obj)->traits.get_icon().empty()) { \
|
||||
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->traits.get_icon().c_str()); \
|
||||
if (!(obj)->get_icon().empty()) { \
|
||||
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -40,21 +41,18 @@ class NumberTraits {
|
|||
float get_max_value() const { return max_value_; }
|
||||
void set_step(float step) { step_ = step; }
|
||||
float get_step() const { return step_; }
|
||||
void set_icon(std::string icon) { icon_ = std::move(icon); }
|
||||
const std::string &get_icon() const { return icon_; }
|
||||
|
||||
protected:
|
||||
float min_value_ = NAN;
|
||||
float max_value_ = NAN;
|
||||
float step_ = NAN;
|
||||
std::string icon_;
|
||||
};
|
||||
|
||||
/** Base-class for all numbers.
|
||||
*
|
||||
* A number can use publish_state to send out a new value.
|
||||
*/
|
||||
class Number : public Nameable {
|
||||
class Number : public EntityBase {
|
||||
public:
|
||||
float state;
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import binary_sensor, remote_base
|
||||
from esphome.const import CONF_NAME
|
||||
|
||||
DEPENDENCIES = ["remote_receiver"]
|
||||
|
||||
|
@ -9,5 +7,4 @@ CONFIG_SCHEMA = remote_base.validate_binary_sensor
|
|||
|
||||
async def to_code(config):
|
||||
var = await remote_base.build_binary_sensor(config)
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
await binary_sensor.register_binary_sensor(var, config)
|
||||
|
|
|
@ -4,24 +4,20 @@ import esphome.config_validation as cv
|
|||
from esphome import automation
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_ON_VALUE,
|
||||
CONF_OPTION,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
ICON_EMPTY,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
select_ns = cg.esphome_ns.namespace("select")
|
||||
Select = select_ns.class_("Select", cg.Nameable)
|
||||
Select = select_ns.class_("Select", cg.EntityBase)
|
||||
SelectPtr = Select.operator("ptr")
|
||||
|
||||
# Triggers
|
||||
|
@ -35,11 +31,10 @@ SelectSetAction = select_ns.class_("SelectSetAction", automation.Action)
|
|||
icon = cv.icon
|
||||
|
||||
|
||||
SELECT_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
SELECT_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSelectComponent),
|
||||
cv.GenerateID(): cv.declare_id(Select),
|
||||
cv.Optional(CONF_ICON, default=ICON_EMPTY): icon,
|
||||
cv.Optional(CONF_ON_VALUE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SelectStateTrigger),
|
||||
|
@ -50,12 +45,8 @@ SELECT_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
|||
|
||||
|
||||
async def setup_select_core_(var, config, *, options: List[str]):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
cg.add(var.traits.set_icon(config[CONF_ICON]))
|
||||
cg.add(var.traits.set_options(options))
|
||||
|
||||
for conf in config.get(CONF_ON_VALUE, []):
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <set>
|
||||
#include <utility>
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
|
@ -11,8 +12,8 @@ namespace select {
|
|||
#define LOG_SELECT(prefix, type, obj) \
|
||||
if ((obj) != nullptr) { \
|
||||
ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
|
||||
if (!(obj)->traits.get_icon().empty()) { \
|
||||
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->traits.get_icon().c_str()); \
|
||||
if (!(obj)->get_icon().empty()) { \
|
||||
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -38,19 +39,16 @@ class SelectTraits {
|
|||
public:
|
||||
void set_options(std::vector<std::string> options) { this->options_ = std::move(options); }
|
||||
const std::vector<std::string> get_options() const { return this->options_; }
|
||||
void set_icon(std::string icon) { icon_ = std::move(icon); }
|
||||
const std::string &get_icon() const { return icon_; }
|
||||
|
||||
protected:
|
||||
std::vector<std::string> options_;
|
||||
std::string icon_;
|
||||
};
|
||||
|
||||
/** Base-class for all selects.
|
||||
*
|
||||
* A select can use publish_state to send out a new value.
|
||||
*/
|
||||
class Select : public Nameable {
|
||||
class Select : public EntityBase {
|
||||
public:
|
||||
std::string state;
|
||||
|
||||
|
|
|
@ -10,13 +10,11 @@ from esphome.const import (
|
|||
CONF_ACCURACY_DECIMALS,
|
||||
CONF_ALPHA,
|
||||
CONF_BELOW,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_EXPIRE_AFTER,
|
||||
CONF_FILTERS,
|
||||
CONF_FROM,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_ON_RAW_VALUE,
|
||||
CONF_ON_VALUE,
|
||||
CONF_ON_VALUE_RANGE,
|
||||
|
@ -27,7 +25,6 @@ from esphome.const import (
|
|||
CONF_TRIGGER_ID,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
CONF_WINDOW_SIZE,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
CONF_FORCE_UPDATE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
|
@ -59,6 +56,7 @@ from esphome.const import (
|
|||
DEVICE_CLASS_VOLTAGE,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from esphome.util import Registry
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
|
@ -136,7 +134,7 @@ def validate_datapoint(value):
|
|||
|
||||
# Base
|
||||
sensor_ns = cg.esphome_ns.namespace("sensor")
|
||||
Sensor = sensor_ns.class_("Sensor", cg.Nameable)
|
||||
Sensor = sensor_ns.class_("Sensor", cg.EntityBase)
|
||||
SensorPtr = Sensor.operator("ptr")
|
||||
|
||||
# Triggers
|
||||
|
@ -180,12 +178,11 @@ validate_accuracy_decimals = cv.int_
|
|||
validate_icon = cv.icon
|
||||
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||
|
||||
SENSOR_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSensorComponent),
|
||||
cv.GenerateID(): cv.declare_id(Sensor),
|
||||
cv.Optional(CONF_UNIT_OF_MEASUREMENT): validate_unit_of_measurement,
|
||||
cv.Optional(CONF_ICON): validate_icon,
|
||||
cv.Optional(CONF_ACCURACY_DECIMALS): validate_accuracy_decimals,
|
||||
cv.Optional(CONF_DEVICE_CLASS): validate_device_class,
|
||||
cv.Optional(CONF_STATE_CLASS): validate_state_class,
|
||||
|
@ -495,18 +492,14 @@ async def build_filters(config):
|
|||
|
||||
|
||||
async def setup_sensor_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_DEVICE_CLASS in config:
|
||||
cg.add(var.set_device_class(config[CONF_DEVICE_CLASS]))
|
||||
if CONF_STATE_CLASS in config:
|
||||
cg.add(var.set_state_class(config[CONF_STATE_CLASS]))
|
||||
if CONF_UNIT_OF_MEASUREMENT in config:
|
||||
cg.add(var.set_unit_of_measurement(config[CONF_UNIT_OF_MEASUREMENT]))
|
||||
if CONF_ICON in config:
|
||||
cg.add(var.set_icon(config[CONF_ICON]))
|
||||
if CONF_ACCURACY_DECIMALS in config:
|
||||
cg.add(var.set_accuracy_decimals(config[CONF_ACCURACY_DECIMALS]))
|
||||
cg.add(var.set_force_update(config[CONF_FORCE_UPDATE]))
|
||||
|
|
|
@ -18,7 +18,7 @@ std::string state_class_to_string(StateClass state_class) {
|
|||
}
|
||||
}
|
||||
|
||||
Sensor::Sensor(const std::string &name) : Nameable(name), state(NAN), raw_state(NAN) {}
|
||||
Sensor::Sensor(const std::string &name) : EntityBase(name), state(NAN), raw_state(NAN) {}
|
||||
Sensor::Sensor() : Sensor("") {}
|
||||
|
||||
std::string Sensor::get_unit_of_measurement() {
|
||||
|
@ -31,14 +31,6 @@ void Sensor::set_unit_of_measurement(const std::string &unit_of_measurement) {
|
|||
}
|
||||
std::string Sensor::unit_of_measurement() { return ""; }
|
||||
|
||||
std::string Sensor::get_icon() {
|
||||
if (this->icon_.has_value())
|
||||
return *this->icon_;
|
||||
return this->icon();
|
||||
}
|
||||
void Sensor::set_icon(const std::string &icon) { this->icon_ = icon; }
|
||||
std::string Sensor::icon() { return ""; }
|
||||
|
||||
int8_t Sensor::get_accuracy_decimals() {
|
||||
if (this->accuracy_decimals_.has_value())
|
||||
return *this->accuracy_decimals_;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/sensor/filter.h"
|
||||
|
||||
|
@ -43,7 +44,7 @@ std::string state_class_to_string(StateClass state_class);
|
|||
*
|
||||
* A sensor has unit of measurement and can use publish_state to send out a new value with the specified accuracy.
|
||||
*/
|
||||
class Sensor : public Nameable {
|
||||
class Sensor : public EntityBase {
|
||||
public:
|
||||
explicit Sensor();
|
||||
explicit Sensor(const std::string &name);
|
||||
|
@ -53,11 +54,6 @@ class Sensor : public Nameable {
|
|||
/// Manually set the unit of measurement.
|
||||
void set_unit_of_measurement(const std::string &unit_of_measurement);
|
||||
|
||||
/// Get the icon. Uses the manual override if specified or the default value instead.
|
||||
std::string get_icon();
|
||||
/// Manually set the icon, for example "mdi:flash".
|
||||
void set_icon(const std::string &icon);
|
||||
|
||||
/// Get the accuracy in decimals, using the manual override if set.
|
||||
int8_t get_accuracy_decimals();
|
||||
/// Manually set the accuracy in decimals.
|
||||
|
@ -157,9 +153,6 @@ class Sensor : public Nameable {
|
|||
/// Override this to set the default unit of measurement.
|
||||
virtual std::string unit_of_measurement(); // NOLINT
|
||||
|
||||
/// Override this to set the default icon.
|
||||
virtual std::string icon(); // NOLINT
|
||||
|
||||
/// Override this to set the default accuracy in decimals.
|
||||
virtual int8_t accuracy_decimals(); // NOLINT
|
||||
|
||||
|
@ -178,7 +171,6 @@ class Sensor : public Nameable {
|
|||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||
|
||||
optional<std::string> unit_of_measurement_; ///< Unit of measurement override
|
||||
optional<std::string> icon_; ///< Icon override
|
||||
optional<int8_t> accuracy_decimals_; ///< Accuracy in decimals override
|
||||
optional<std::string> device_class_; ///< Device class override
|
||||
optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
|
||||
|
|
|
@ -4,24 +4,21 @@ from esphome import automation
|
|||
from esphome.automation import Condition, maybe_simple_id
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_INVERTED,
|
||||
CONF_ON_TURN_OFF,
|
||||
CONF_ON_TURN_ON,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
switch_ns = cg.esphome_ns.namespace("switch_")
|
||||
Switch = switch_ns.class_("Switch", cg.Nameable)
|
||||
Switch = switch_ns.class_("Switch", cg.EntityBase)
|
||||
SwitchPtr = Switch.operator("ptr")
|
||||
|
||||
ToggleAction = switch_ns.class_("ToggleAction", automation.Action)
|
||||
|
@ -39,10 +36,9 @@ SwitchTurnOffTrigger = switch_ns.class_(
|
|||
|
||||
icon = cv.icon
|
||||
|
||||
SWITCH_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
SWITCH_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSwitchComponent),
|
||||
cv.Optional(CONF_ICON): icon,
|
||||
cv.Optional(CONF_INVERTED): cv.boolean,
|
||||
cv.Optional(CONF_ON_TURN_ON): automation.validate_automation(
|
||||
{
|
||||
|
@ -59,12 +55,8 @@ SWITCH_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).exte
|
|||
|
||||
|
||||
async def setup_switch_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
if CONF_ICON in config:
|
||||
cg.add(var.set_icon(config[CONF_ICON]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if CONF_INVERTED in config:
|
||||
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||
for conf in config.get(CONF_ON_TURN_ON, []):
|
||||
|
|
|
@ -6,17 +6,9 @@ namespace switch_ {
|
|||
|
||||
static const char *const TAG = "switch";
|
||||
|
||||
std::string Switch::icon() { return ""; }
|
||||
Switch::Switch(const std::string &name) : Nameable(name), state(false) {}
|
||||
Switch::Switch(const std::string &name) : EntityBase(name), state(false) {}
|
||||
Switch::Switch() : Switch("") {}
|
||||
|
||||
std::string Switch::get_icon() {
|
||||
if (this->icon_.has_value())
|
||||
return *this->icon_;
|
||||
return this->icon();
|
||||
}
|
||||
|
||||
void Switch::set_icon(const std::string &icon) { this->icon_ = icon; }
|
||||
void Switch::turn_on() {
|
||||
ESP_LOGD(TAG, "'%s' Turning ON.", this->get_name().c_str());
|
||||
this->write_state(!this->inverted_);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
|
@ -26,7 +27,7 @@ namespace switch_ {
|
|||
* A switch is basically just a combination of a binary sensor (for reporting switch values)
|
||||
* and a write_state method that writes a state to the hardware.
|
||||
*/
|
||||
class Switch : public Nameable {
|
||||
class Switch : public EntityBase {
|
||||
public:
|
||||
explicit Switch();
|
||||
explicit Switch(const std::string &name);
|
||||
|
@ -70,12 +71,6 @@ class Switch : public Nameable {
|
|||
*/
|
||||
void set_inverted(bool inverted);
|
||||
|
||||
/// Set the icon for this switch. "" for no icon.
|
||||
void set_icon(const std::string &icon);
|
||||
|
||||
/// Get the icon for this switch. Using icon() if not manually set
|
||||
std::string get_icon();
|
||||
|
||||
/** Set callback for state changes.
|
||||
*
|
||||
* @param callback The void(bool) callback.
|
||||
|
@ -104,18 +99,8 @@ class Switch : public Nameable {
|
|||
*/
|
||||
virtual void write_state(bool state) = 0;
|
||||
|
||||
/** Override this to set the Home Assistant icon for this switch.
|
||||
*
|
||||
* Return "" to disable this feature.
|
||||
*
|
||||
* @return The icon of this switch, for example "mdi:fan".
|
||||
*/
|
||||
virtual std::string icon(); // NOLINT
|
||||
|
||||
uint32_t hash_base() override;
|
||||
|
||||
optional<std::string> icon_{}; ///< The icon shown here. Not set means use default from switch. Empty means no icon.
|
||||
|
||||
CallbackManager<void(bool)> state_callback_{};
|
||||
bool inverted_{false};
|
||||
Deduplicator<bool> publish_dedup_;
|
||||
|
|
|
@ -3,21 +3,18 @@ import esphome.config_validation as cv
|
|||
from esphome import automation
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_FILTERS,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_ON_VALUE,
|
||||
CONF_ON_RAW_VALUE,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
CONF_STATE,
|
||||
CONF_FROM,
|
||||
CONF_TO,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
from esphome.cpp_helpers import setup_entity
|
||||
from esphome.util import Registry
|
||||
|
||||
|
||||
|
@ -25,7 +22,7 @@ IS_PLATFORM_COMPONENT = True
|
|||
|
||||
# pylint: disable=invalid-name
|
||||
text_sensor_ns = cg.esphome_ns.namespace("text_sensor")
|
||||
TextSensor = text_sensor_ns.class_("TextSensor", cg.Nameable)
|
||||
TextSensor = text_sensor_ns.class_("TextSensor", cg.EntityBase)
|
||||
TextSensorPtr = TextSensor.operator("ptr")
|
||||
|
||||
TextSensorStateTrigger = text_sensor_ns.class_(
|
||||
|
@ -111,10 +108,9 @@ async def substitute_filter_to_code(config, filter_id):
|
|||
|
||||
icon = cv.icon
|
||||
|
||||
TEXT_SENSOR_SCHEMA = cv.NAMEABLE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
TEXT_SENSOR_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
|
||||
{
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTTextSensor),
|
||||
cv.Optional(CONF_ICON): icon,
|
||||
cv.Optional(CONF_FILTERS): validate_filters,
|
||||
cv.Optional(CONF_ON_VALUE): automation.validate_automation(
|
||||
{
|
||||
|
@ -137,12 +133,7 @@ async def build_filters(config):
|
|||
|
||||
|
||||
async def setup_text_sensor_core_(var, config):
|
||||
cg.add(var.set_name(config[CONF_NAME]))
|
||||
cg.add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(var.set_internal(config[CONF_INTERNAL]))
|
||||
if CONF_ICON in config:
|
||||
cg.add(var.set_icon(config[CONF_ICON]))
|
||||
await setup_entity(var, config)
|
||||
|
||||
if config.get(CONF_FILTERS): # must exist and not be empty
|
||||
filters = await build_filters(config[CONF_FILTERS])
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace text_sensor {
|
|||
static const char *const TAG = "text_sensor";
|
||||
|
||||
TextSensor::TextSensor() : TextSensor("") {}
|
||||
TextSensor::TextSensor(const std::string &name) : Nameable(name) {}
|
||||
TextSensor::TextSensor(const std::string &name) : EntityBase(name) {}
|
||||
|
||||
void TextSensor::publish_state(const std::string &state) {
|
||||
this->raw_state = state;
|
||||
|
@ -68,14 +68,6 @@ void TextSensor::internal_send_state_to_frontend(const std::string &state) {
|
|||
this->callback_.call(state);
|
||||
}
|
||||
|
||||
void TextSensor::set_icon(const std::string &icon) { this->icon_ = icon; }
|
||||
std::string TextSensor::get_icon() {
|
||||
if (this->icon_.has_value())
|
||||
return *this->icon_;
|
||||
return this->icon();
|
||||
}
|
||||
std::string TextSensor::icon() { return ""; }
|
||||
|
||||
std::string TextSensor::unique_id() { return ""; }
|
||||
bool TextSensor::has_state() { return this->has_state_; }
|
||||
uint32_t TextSensor::hash_base() { return 334300109UL; }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/components/text_sensor/filter.h"
|
||||
|
||||
|
@ -18,7 +19,7 @@ namespace text_sensor {
|
|||
} \
|
||||
}
|
||||
|
||||
class TextSensor : public Nameable {
|
||||
class TextSensor : public EntityBase {
|
||||
public:
|
||||
explicit TextSensor();
|
||||
explicit TextSensor(const std::string &name);
|
||||
|
@ -30,8 +31,6 @@ class TextSensor : public Nameable {
|
|||
|
||||
void publish_state(const std::string &state);
|
||||
|
||||
void set_icon(const std::string &icon);
|
||||
|
||||
/// Add a filter to the filter chain. Will be appended to the back.
|
||||
void add_filter(Filter *filter);
|
||||
|
||||
|
@ -53,10 +52,6 @@ class TextSensor : public Nameable {
|
|||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
std::string get_icon();
|
||||
|
||||
virtual std::string icon();
|
||||
|
||||
virtual std::string unique_id();
|
||||
|
||||
bool has_state();
|
||||
|
@ -71,7 +66,6 @@ class TextSensor : public Nameable {
|
|||
|
||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||
|
||||
optional<std::string> icon_;
|
||||
bool has_state_{false};
|
||||
};
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@ import esphome.codegen as cg
|
|||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, time
|
||||
from esphome.const import (
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_TIME_ID,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
CONF_METHOD,
|
||||
STATE_CLASS_TOTAL_INCREASING,
|
||||
)
|
||||
from esphome.core.entity_helpers import inherit_property_from
|
||||
|
||||
DEPENDENCIES = ["time"]
|
||||
|
||||
|
@ -45,6 +47,18 @@ CONFIG_SCHEMA = (
|
|||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(TotalDailyEnergy),
|
||||
cv.Optional(CONF_ICON): cv.icon,
|
||||
cv.Required(CONF_POWER_ID): cv.use_id(sensor.Sensor),
|
||||
},
|
||||
extra=cv.ALLOW_EXTRA,
|
||||
),
|
||||
inherit_property_from(CONF_ICON, CONF_POWER_ID),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
|
|
|
@ -25,7 +25,6 @@ class TotalDailyEnergy : public sensor::Sensor, public Component {
|
|||
void dump_config() override;
|
||||
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||
std::string unit_of_measurement() override { return this->parent_->get_unit_of_measurement() + "h"; }
|
||||
std::string icon() override { return this->parent_->get_icon(); }
|
||||
int8_t accuracy_decimals() override { return this->parent_->get_accuracy_decimals() + 2; }
|
||||
void loop() override;
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ class TSL2591Component : public PollingComponent, public i2c::I2CDevice {
|
|||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
const char *name_; // TODO: extend esphome::Nameable
|
||||
const char *name_;
|
||||
sensor::Sensor *full_spectrum_sensor_;
|
||||
sensor::Sensor *infrared_sensor_;
|
||||
sensor::Sensor *visible_sensor_;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "web_server.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/util.h"
|
||||
#include "esphome/components/json/json_util.h"
|
||||
#include "esphome/components/network/util.h"
|
||||
|
@ -28,8 +29,8 @@ namespace web_server {
|
|||
|
||||
static const char *const TAG = "web_server";
|
||||
|
||||
void write_row(AsyncResponseStream *stream, Nameable *obj, const std::string &klass, const std::string &action,
|
||||
const std::function<void(AsyncResponseStream &stream, Nameable *obj)> &action_func = nullptr) {
|
||||
void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string &klass, const std::string &action,
|
||||
const std::function<void(AsyncResponseStream &stream, EntityBase *obj)> &action_func = nullptr) {
|
||||
if (obj->is_internal())
|
||||
return;
|
||||
stream->print("<tr class=\"");
|
||||
|
@ -225,7 +226,7 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) {
|
|||
|
||||
#ifdef USE_SELECT
|
||||
for (auto *obj : App.get_selects())
|
||||
write_row(stream, obj, "select", "", [](AsyncResponseStream &stream, Nameable *obj) {
|
||||
write_row(stream, obj, "select", "", [](AsyncResponseStream &stream, EntityBase *obj) {
|
||||
select::Select *select = (select::Select *) obj;
|
||||
stream.print("<select>");
|
||||
stream.print("<option></option>");
|
||||
|
|
|
@ -18,6 +18,7 @@ from esphome.const import (
|
|||
CONF_COMMAND_TOPIC,
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_DISCOVERY,
|
||||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_NAME,
|
||||
|
@ -1476,7 +1477,7 @@ class OnlyWith(Optional):
|
|||
pass
|
||||
|
||||
|
||||
def _nameable_validator(config):
|
||||
def _entity_base_validator(config):
|
||||
if CONF_NAME not in config and CONF_ID not in config:
|
||||
raise Invalid("At least one of 'id:' or 'name:' is required!")
|
||||
if CONF_NAME not in config:
|
||||
|
@ -1587,15 +1588,16 @@ MQTT_COMMAND_COMPONENT_SCHEMA = MQTT_COMPONENT_SCHEMA.extend(
|
|||
}
|
||||
)
|
||||
|
||||
NAMEABLE_SCHEMA = Schema(
|
||||
ENTITY_BASE_SCHEMA = Schema(
|
||||
{
|
||||
Optional(CONF_NAME): string,
|
||||
Optional(CONF_INTERNAL): boolean,
|
||||
Optional(CONF_DISABLED_BY_DEFAULT, default=False): boolean,
|
||||
Optional(CONF_ICON): icon,
|
||||
}
|
||||
)
|
||||
|
||||
NAMEABLE_SCHEMA.add_extra(_nameable_validator)
|
||||
ENTITY_BASE_SCHEMA.add_extra(_entity_base_validator)
|
||||
|
||||
COMPONENT_SCHEMA = Schema({Optional(CONF_SETUP_PRIORITY): float_})
|
||||
|
||||
|
|
|
@ -177,26 +177,6 @@ void PollingComponent::call_setup() {
|
|||
uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; }
|
||||
void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
|
||||
|
||||
const std::string &Nameable::get_name() const { return this->name_; }
|
||||
void Nameable::set_name(const std::string &name) {
|
||||
this->name_ = name;
|
||||
this->calc_object_id_();
|
||||
}
|
||||
Nameable::Nameable(std::string name) : name_(std::move(name)) { this->calc_object_id_(); }
|
||||
|
||||
const std::string &Nameable::get_object_id() { return this->object_id_; }
|
||||
bool Nameable::is_internal() const { return this->internal_; }
|
||||
void Nameable::set_internal(bool internal) { this->internal_ = internal; }
|
||||
void Nameable::calc_object_id_() {
|
||||
this->object_id_ = sanitize_string_allowlist(to_lowercase_underscore(this->name_), HOSTNAME_CHARACTER_ALLOWLIST);
|
||||
// FNV-1 hash
|
||||
this->object_id_hash_ = fnv1_hash(this->object_id_);
|
||||
}
|
||||
uint32_t Nameable::get_object_id_hash() { return this->object_id_hash_; }
|
||||
|
||||
bool Nameable::is_disabled_by_default() const { return this->disabled_by_default_; }
|
||||
void Nameable::set_disabled_by_default(bool disabled_by_default) { this->disabled_by_default_ = disabled_by_default; }
|
||||
|
||||
WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component)
|
||||
: started_(millis()), component_(component) {}
|
||||
WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {
|
||||
|
|
|
@ -264,40 +264,6 @@ class PollingComponent : public Component {
|
|||
uint32_t update_interval_;
|
||||
};
|
||||
|
||||
/// Helper class that enables naming of objects so that it doesn't have to be re-implement every time.
|
||||
class Nameable {
|
||||
public:
|
||||
Nameable() : Nameable("") {}
|
||||
explicit Nameable(std::string name);
|
||||
const std::string &get_name() const;
|
||||
void set_name(const std::string &name);
|
||||
/// Get the sanitized name of this nameable as an ID. Caching it internally.
|
||||
const std::string &get_object_id();
|
||||
uint32_t get_object_id_hash();
|
||||
|
||||
bool is_internal() const;
|
||||
void set_internal(bool internal);
|
||||
|
||||
/** Check if this object is declared to be disabled by default.
|
||||
*
|
||||
* That means that when the device gets added to Home Assistant (or other clients) it should
|
||||
* not be added to the default view by default, and a user action is necessary to manually add it.
|
||||
*/
|
||||
bool is_disabled_by_default() const;
|
||||
void set_disabled_by_default(bool disabled_by_default);
|
||||
|
||||
protected:
|
||||
virtual uint32_t hash_base() = 0;
|
||||
|
||||
void calc_object_id_();
|
||||
|
||||
std::string name_;
|
||||
std::string object_id_;
|
||||
uint32_t object_id_hash_;
|
||||
bool internal_{false};
|
||||
bool disabled_by_default_{false};
|
||||
};
|
||||
|
||||
class WarnIfComponentBlockingGuard {
|
||||
public:
|
||||
WarnIfComponentBlockingGuard(Component *component);
|
||||
|
|
40
esphome/core/entity_base.cpp
Normal file
40
esphome/core/entity_base.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include "esphome/core/entity_base.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
|
||||
static const char *const TAG = "entity_base";
|
||||
|
||||
EntityBase::EntityBase(std::string name) : name_(std::move(name)) { this->calc_object_id_(); }
|
||||
|
||||
// Entity Name
|
||||
const std::string &EntityBase::get_name() const { return this->name_; }
|
||||
void EntityBase::set_name(const std::string &name) {
|
||||
this->name_ = name;
|
||||
this->calc_object_id_();
|
||||
}
|
||||
|
||||
// Entity Internal
|
||||
bool EntityBase::is_internal() const { return this->internal_; }
|
||||
void EntityBase::set_internal(bool internal) { this->internal_ = internal; }
|
||||
|
||||
// Entity Disabled by Default
|
||||
bool EntityBase::is_disabled_by_default() const { return this->disabled_by_default_; }
|
||||
void EntityBase::set_disabled_by_default(bool disabled_by_default) { this->disabled_by_default_ = disabled_by_default; }
|
||||
|
||||
// Entity Icon
|
||||
const std::string &EntityBase::get_icon() const { return this->icon_; }
|
||||
void EntityBase::set_icon(const std::string &name) { this->icon_ = name; }
|
||||
|
||||
// Entity Object ID
|
||||
const std::string &EntityBase::get_object_id() { return this->object_id_; }
|
||||
|
||||
// Calculate Object ID Hash from Entity Name
|
||||
void EntityBase::calc_object_id_() {
|
||||
this->object_id_ = sanitize_string_allowlist(to_lowercase_underscore(this->name_), HOSTNAME_CHARACTER_ALLOWLIST);
|
||||
// FNV-1 hash
|
||||
this->object_id_hash_ = fnv1_hash(this->object_id_);
|
||||
}
|
||||
uint32_t EntityBase::get_object_id_hash() { return this->object_id_hash_; }
|
||||
|
||||
} // namespace esphome
|
50
esphome/core/entity_base.h
Normal file
50
esphome/core/entity_base.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// The generic Entity base class that provides an interface common to all Entities.
|
||||
class EntityBase {
|
||||
public:
|
||||
EntityBase() : EntityBase("") {}
|
||||
explicit EntityBase(std::string name);
|
||||
|
||||
// Get/set the name of this Entity
|
||||
const std::string &get_name() const;
|
||||
void set_name(const std::string &name);
|
||||
|
||||
// Get the sanitized name of this Entity as an ID. Caching it internally.
|
||||
const std::string &get_object_id();
|
||||
|
||||
// Get the unique Object ID of this Entity
|
||||
uint32_t get_object_id_hash();
|
||||
|
||||
// Get/set whether this Entity should be hidden from outside of ESPHome
|
||||
bool is_internal() const;
|
||||
void set_internal(bool internal);
|
||||
|
||||
// Check if this object is declared to be disabled by default.
|
||||
// That means that when the device gets added to Home Assistant (or other clients) it should
|
||||
// not be added to the default view by default, and a user action is necessary to manually add it.
|
||||
bool is_disabled_by_default() const;
|
||||
void set_disabled_by_default(bool disabled_by_default);
|
||||
|
||||
// Get/set this entity's icon
|
||||
const std::string &get_icon() const;
|
||||
void set_icon(const std::string &name);
|
||||
|
||||
protected:
|
||||
virtual uint32_t hash_base() = 0;
|
||||
void calc_object_id_();
|
||||
|
||||
std::string name_;
|
||||
std::string object_id_;
|
||||
std::string icon_;
|
||||
uint32_t object_id_hash_;
|
||||
bool internal_{false};
|
||||
bool disabled_by_default_{false};
|
||||
};
|
||||
|
||||
} // namespace esphome
|
32
esphome/core/entity_helpers.py
Normal file
32
esphome/core/entity_helpers.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import esphome.final_validate as fv
|
||||
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
|
||||
def inherit_property_from(property_to_inherit, parent_id_property):
|
||||
"""Validator that inherits a configuration property from another entity, for use with FINAL_VALIDATE_SCHEMA.
|
||||
|
||||
If a property is already set, it will not be inherited.
|
||||
|
||||
Keyword arguments:
|
||||
property_to_inherit -- the name of the property to inherit, e.g. CONF_ICON
|
||||
parent_id_property -- the name of the property that holds the ID of the parent, e.g. CONF_POWER_ID
|
||||
"""
|
||||
|
||||
def inherit_property(config):
|
||||
if property_to_inherit not in config:
|
||||
fconf = fv.full_config.get()
|
||||
|
||||
# Get config for the parent entity
|
||||
path = fconf.get_path_for_id(config[parent_id_property])[:-1]
|
||||
parent_config = fconf.get_config_for_path(path)
|
||||
|
||||
# If parent sensor has the property set, inherit it
|
||||
if property_to_inherit in parent_config:
|
||||
path = fconf.get_path_for_id(config[CONF_ID])[:-1]
|
||||
this_config = fconf.get_config_for_path(path)
|
||||
this_config[property_to_inherit] = parent_config[property_to_inherit]
|
||||
|
||||
return config
|
||||
|
||||
return inherit_property
|
|
@ -1,6 +1,10 @@
|
|||
import logging
|
||||
|
||||
from esphome.const import (
|
||||
CONF_DISABLED_BY_DEFAULT,
|
||||
CONF_ICON,
|
||||
CONF_INTERNAL,
|
||||
CONF_NAME,
|
||||
CONF_SETUP_PRIORITY,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
CONF_TYPE_ID,
|
||||
|
@ -90,6 +94,16 @@ async def register_parented(var, value):
|
|||
add(var.set_parent(paren))
|
||||
|
||||
|
||||
async def setup_entity(var, config):
|
||||
"""Set up generic properties of an Entity"""
|
||||
add(var.set_name(config[CONF_NAME]))
|
||||
add(var.set_disabled_by_default(config[CONF_DISABLED_BY_DEFAULT]))
|
||||
if CONF_INTERNAL in config:
|
||||
add(var.set_internal(config[CONF_INTERNAL]))
|
||||
if CONF_ICON in config:
|
||||
add(var.set_icon(config[CONF_ICON]))
|
||||
|
||||
|
||||
def extract_registry_entry_config(registry, full_config):
|
||||
# type: (Registry, ConfigType) -> RegistryEntry
|
||||
key, config = next((k, v) for k, v in full_config.items() if k in registry)
|
||||
|
|
|
@ -19,7 +19,7 @@ const_char_ptr = global_ns.namespace("const char *")
|
|||
NAN = global_ns.namespace("NAN")
|
||||
esphome_ns = global_ns # using namespace esphome;
|
||||
App = esphome_ns.App
|
||||
Nameable = esphome_ns.class_("Nameable")
|
||||
EntityBase = esphome_ns.class_("EntityBase")
|
||||
Component = esphome_ns.class_("Component")
|
||||
ComponentPtr = Component.operator("ptr")
|
||||
PollingComponent = esphome_ns.class_("PollingComponent", Component)
|
||||
|
|
|
@ -1708,6 +1708,7 @@ climate:
|
|||
name: Anova cooker
|
||||
ble_client_id: ble_blah
|
||||
unit_of_measurement: c
|
||||
icon: mdi:stove
|
||||
|
||||
script:
|
||||
- id: climate_custom
|
||||
|
@ -1986,6 +1987,7 @@ fan:
|
|||
direction_output: gpio_26
|
||||
- platform: speed
|
||||
id: fan_speed
|
||||
icon: mdi:weather-windy
|
||||
output: pca_6
|
||||
speed_count: 10
|
||||
name: 'Living Room Fan 2'
|
||||
|
@ -2287,6 +2289,7 @@ cover:
|
|||
name: 'Test AM43'
|
||||
id: am43_test
|
||||
ble_client_id: ble_foo
|
||||
icon: mdi:blinds
|
||||
|
||||
debug:
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ binary_sensor:
|
|||
- platform: gpio
|
||||
pin: GPIO0
|
||||
id: io0_button
|
||||
icon: mdi:gesture-tap-button
|
||||
|
||||
tlc5947:
|
||||
data_pin: GPIO12
|
||||
|
|
|
@ -59,7 +59,7 @@ from esphome import codegen as cg
|
|||
"NAN",
|
||||
"esphome_ns",
|
||||
"App",
|
||||
"Nameable",
|
||||
"EntityBase",
|
||||
"Component",
|
||||
"ComponentPtr",
|
||||
# from cpp_types
|
||||
|
|
Loading…
Reference in a new issue