Deprecate virtual methods to set entity properties (#3021)

This commit is contained in:
Oxan van Leeuwen 2022-01-10 13:32:39 +01:00 committed by GitHub
parent 41bcc8c0f4
commit 073828235f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 76 additions and 32 deletions

View file

@ -48,7 +48,10 @@ void BinarySensor::set_device_class(const std::string &device_class) { this->dev
std::string BinarySensor::get_device_class() {
if (this->device_class_.has_value())
return *this->device_class_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->device_class();
#pragma GCC diagnostic pop
}
void BinarySensor::add_filter(Filter *filter) {
filter->parent_ = this;

View file

@ -75,6 +75,7 @@ class BinarySensor : public EntityBase {
// ========== OVERRIDE METHODS ==========
// (You'll only need this when creating your own custom binary sensor)
/// Get the default device class for this sensor, or empty string for no default.
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string device_class();
protected:

View file

@ -210,7 +210,10 @@ Cover::Cover() : Cover("") {}
std::string Cover::get_device_class() {
if (this->device_class_override_.has_value())
return *this->device_class_override_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->device_class();
#pragma GCC diagnostic pop
}
bool Cover::is_fully_open() const { return this->position == COVER_OPEN; }
bool Cover::is_fully_closed() const { return this->position == COVER_CLOSED; }

View file

@ -169,6 +169,7 @@ class Cover : public EntityBase {
friend CoverCall;
virtual void control(const CoverCall &call) = 0;
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string device_class();
optional<CoverRestoreState> restore_state_();

View file

@ -23,31 +23,6 @@ void IntegrationSensor::setup() {
this->sensor_->add_on_state_callback([this](float state) { this->process_sensor_value_(state); });
}
void IntegrationSensor::dump_config() { LOG_SENSOR("", "Integration Sensor", this); }
std::string IntegrationSensor::unit_of_measurement() {
std::string suffix;
switch (this->time_) {
case INTEGRATION_SENSOR_TIME_MILLISECOND:
suffix = "ms";
break;
case INTEGRATION_SENSOR_TIME_SECOND:
suffix = "s";
break;
case INTEGRATION_SENSOR_TIME_MINUTE:
suffix = "min";
break;
case INTEGRATION_SENSOR_TIME_HOUR:
suffix = "h";
break;
case INTEGRATION_SENSOR_TIME_DAY:
suffix = "d";
break;
}
std::string base = this->sensor_->get_unit_of_measurement();
if (str_endswith(base, "/" + suffix)) {
return base.substr(0, base.size() - suffix.size() - 1);
}
return base + suffix;
}
void IntegrationSensor::process_sensor_value_(float value) {
const uint32_t now = millis();
const double old_value = this->last_value_;

View file

@ -63,8 +63,6 @@ class IntegrationSensor : public sensor::Sensor, public Component {
this->last_save_ = now;
this->rtc_.save(&result_f);
}
std::string unit_of_measurement() override;
int8_t accuracy_decimals() override { return this->sensor_->get_accuracy_decimals() + 2; }
sensor::Sensor *sensor_;
IntegrationSensorTime time_;

View file

@ -2,7 +2,14 @@ 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_ICON, CONF_ID, CONF_SENSOR, CONF_RESTORE
from esphome.const import (
CONF_ICON,
CONF_ID,
CONF_SENSOR,
CONF_RESTORE,
CONF_UNIT_OF_MEASUREMENT,
CONF_ACCURACY_DECIMALS,
)
from esphome.core.entity_helpers import inherit_property_from
integration_ns = cg.esphome_ns.namespace("integration")
@ -30,6 +37,18 @@ CONF_TIME_UNIT = "time_unit"
CONF_INTEGRATION_METHOD = "integration_method"
CONF_MIN_SAVE_INTERVAL = "min_save_interval"
def inherit_unit_of_measurement(uom, config):
suffix = config[CONF_TIME_UNIT]
if uom.endswith("/" + suffix):
return uom[0 : -len("/" + suffix)]
return uom + suffix
def inherit_accuracy_decimals(decimals, config):
return decimals + 2
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(IntegrationSensor),
@ -51,11 +70,19 @@ FINAL_VALIDATE_SCHEMA = cv.All(
{
cv.Required(CONF_ID): cv.use_id(IntegrationSensor),
cv.Optional(CONF_ICON): cv.icon,
cv.Optional(CONF_UNIT_OF_MEASUREMENT): sensor.validate_unit_of_measurement,
cv.Optional(CONF_ACCURACY_DECIMALS): sensor.validate_accuracy_decimals,
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
},
extra=cv.ALLOW_EXTRA,
),
inherit_property_from(CONF_ICON, CONF_SENSOR),
inherit_property_from(
CONF_UNIT_OF_MEASUREMENT, CONF_SENSOR, transform=inherit_unit_of_measurement
),
inherit_property_from(
CONF_ACCURACY_DECIMALS, CONF_SENSOR, transform=inherit_accuracy_decimals
),
)

View file

@ -24,7 +24,10 @@ Sensor::Sensor() : Sensor("") {}
std::string Sensor::get_unit_of_measurement() {
if (this->unit_of_measurement_.has_value())
return *this->unit_of_measurement_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->unit_of_measurement();
#pragma GCC diagnostic pop
}
void Sensor::set_unit_of_measurement(const std::string &unit_of_measurement) {
this->unit_of_measurement_ = unit_of_measurement;
@ -34,7 +37,10 @@ std::string Sensor::unit_of_measurement() { return ""; }
int8_t Sensor::get_accuracy_decimals() {
if (this->accuracy_decimals_.has_value())
return *this->accuracy_decimals_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->accuracy_decimals();
#pragma GCC diagnostic pop
}
void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; }
int8_t Sensor::accuracy_decimals() { return 0; }
@ -42,7 +48,10 @@ int8_t Sensor::accuracy_decimals() { return 0; }
std::string Sensor::get_device_class() {
if (this->device_class_.has_value())
return *this->device_class_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->device_class();
#pragma GCC diagnostic pop
}
void Sensor::set_device_class(const std::string &device_class) { this->device_class_ = device_class; }
std::string Sensor::device_class() { return ""; }
@ -51,7 +60,10 @@ void Sensor::set_state_class(StateClass state_class) { this->state_class_ = stat
StateClass Sensor::get_state_class() {
if (this->state_class_.has_value())
return *this->state_class_;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
return this->state_class();
#pragma GCC diagnostic pop
}
StateClass Sensor::state_class() { return StateClass::STATE_CLASS_NONE; }

View file

@ -151,15 +151,19 @@ class Sensor : public EntityBase {
protected:
/// Override this to set the default unit of measurement.
ESPDEPRECATED("unit_of_measurement() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string unit_of_measurement(); // NOLINT
/// Override this to set the default accuracy in decimals.
ESPDEPRECATED("accuracy_decimals() is deprecated, set property during config validation instead.", "2022.01")
virtual int8_t accuracy_decimals(); // NOLINT
/// Override this to set the default device class.
ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01")
virtual std::string device_class(); // NOLINT
/// Override this to set the default state class.
ESPDEPRECATED("state_class() is deprecated, set property during config validation instead.", "2022.01")
virtual StateClass state_class(); // NOLINT
uint32_t hash_base() override;

View file

@ -9,6 +9,8 @@ from esphome.const import (
DEVICE_CLASS_ENERGY,
CONF_METHOD,
STATE_CLASS_TOTAL_INCREASING,
CONF_UNIT_OF_MEASUREMENT,
CONF_ACCURACY_DECIMALS,
)
from esphome.core.entity_helpers import inherit_property_from
@ -27,6 +29,15 @@ TotalDailyEnergy = total_daily_energy_ns.class_(
"TotalDailyEnergy", sensor.Sensor, cg.Component
)
def inherit_unit_of_measurement(uom, config):
return uom + "h"
def inherit_accuracy_decimals(decimals, config):
return decimals + 2
CONFIG_SCHEMA = (
sensor.sensor_schema(
device_class=DEVICE_CLASS_ENERGY,
@ -54,11 +65,19 @@ FINAL_VALIDATE_SCHEMA = cv.All(
{
cv.Required(CONF_ID): cv.use_id(TotalDailyEnergy),
cv.Optional(CONF_ICON): cv.icon,
cv.Optional(CONF_UNIT_OF_MEASUREMENT): sensor.validate_unit_of_measurement,
cv.Optional(CONF_ACCURACY_DECIMALS): sensor.validate_accuracy_decimals,
cv.Required(CONF_POWER_ID): cv.use_id(sensor.Sensor),
},
extra=cv.ALLOW_EXTRA,
),
inherit_property_from(CONF_ICON, CONF_POWER_ID),
inherit_property_from(
CONF_UNIT_OF_MEASUREMENT, CONF_POWER_ID, transform=inherit_unit_of_measurement
),
inherit_property_from(
CONF_ACCURACY_DECIMALS, CONF_POWER_ID, transform=inherit_accuracy_decimals
),
)

View file

@ -25,8 +25,6 @@ class TotalDailyEnergy : public sensor::Sensor, public Component {
void setup() override;
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"; }
int8_t accuracy_decimals() override { return this->parent_->get_accuracy_decimals() + 2; }
void loop() override;
void publish_state_and_save(float state);

View file

@ -3,7 +3,7 @@ import esphome.final_validate as fv
from esphome.const import CONF_ID
def inherit_property_from(property_to_inherit, parent_id_property):
def inherit_property_from(property_to_inherit, parent_id_property, transform=None):
"""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:
@ -47,7 +47,10 @@ def inherit_property_from(property_to_inherit, parent_id_property):
this_config = _walk_config(
fconf.get_config_for_path(path), property_path
)
this_config[property] = parent_config[property]
value = parent_config[property]
if transform:
value = transform(value, config)
this_config[property] = value
return config