diff --git a/esphome/components/binary_sensor/binary_sensor.cpp b/esphome/components/binary_sensor/binary_sensor.cpp index 41da83aa3e..71422609d7 100644 --- a/esphome/components/binary_sensor/binary_sensor.cpp +++ b/esphome/components/binary_sensor/binary_sensor.cpp @@ -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; diff --git a/esphome/components/binary_sensor/binary_sensor.h b/esphome/components/binary_sensor/binary_sensor.h index 9c0d43fa98..ecf68de74c 100644 --- a/esphome/components/binary_sensor/binary_sensor.h +++ b/esphome/components/binary_sensor/binary_sensor.h @@ -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: diff --git a/esphome/components/cover/cover.cpp b/esphome/components/cover/cover.cpp index a8d3d691a4..21f35f14de 100644 --- a/esphome/components/cover/cover.cpp +++ b/esphome/components/cover/cover.cpp @@ -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; } diff --git a/esphome/components/cover/cover.h b/esphome/components/cover/cover.h index a67f8d2393..779e4a2a46 100644 --- a/esphome/components/cover/cover.h +++ b/esphome/components/cover/cover.h @@ -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 restore_state_(); diff --git a/esphome/components/integration/integration_sensor.cpp b/esphome/components/integration/integration_sensor.cpp index 2a398e5240..642116152c 100644 --- a/esphome/components/integration/integration_sensor.cpp +++ b/esphome/components/integration/integration_sensor.cpp @@ -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_; diff --git a/esphome/components/integration/integration_sensor.h b/esphome/components/integration/integration_sensor.h index 437649c1dd..1d46973086 100644 --- a/esphome/components/integration/integration_sensor.h +++ b/esphome/components/integration/integration_sensor.h @@ -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_; diff --git a/esphome/components/integration/sensor.py b/esphome/components/integration/sensor.py index 26c7c2871a..c35d42f385 100644 --- a/esphome/components/integration/sensor.py +++ b/esphome/components/integration/sensor.py @@ -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 + ), ) diff --git a/esphome/components/sensor/sensor.cpp b/esphome/components/sensor/sensor.cpp index 793ae170c3..73730f6482 100644 --- a/esphome/components/sensor/sensor.cpp +++ b/esphome/components/sensor/sensor.cpp @@ -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; } diff --git a/esphome/components/sensor/sensor.h b/esphome/components/sensor/sensor.h index 6cab46f7f9..794aecca95 100644 --- a/esphome/components/sensor/sensor.h +++ b/esphome/components/sensor/sensor.h @@ -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; diff --git a/esphome/components/total_daily_energy/sensor.py b/esphome/components/total_daily_energy/sensor.py index 0c20ccd27c..1af8db8332 100644 --- a/esphome/components/total_daily_energy/sensor.py +++ b/esphome/components/total_daily_energy/sensor.py @@ -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 + ), ) diff --git a/esphome/components/total_daily_energy/total_daily_energy.h b/esphome/components/total_daily_energy/total_daily_energy.h index 498f65891e..a35edfd11b 100644 --- a/esphome/components/total_daily_energy/total_daily_energy.h +++ b/esphome/components/total_daily_energy/total_daily_energy.h @@ -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); diff --git a/esphome/core/entity_helpers.py b/esphome/core/entity_helpers.py index 7f7d78aaa2..f921711ec2 100644 --- a/esphome/core/entity_helpers.py +++ b/esphome/core/entity_helpers.py @@ -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