mirror of
https://github.com/esphome/esphome.git
synced 2024-12-26 23:41:45 +01:00
Adding last_reset_type to sensors that should support it. (#2039)
This commit is contained in:
parent
35b5c1ed56
commit
e19aa3bbe0
14 changed files with 153 additions and 15 deletions
|
@ -422,6 +422,12 @@ enum SensorStateClass {
|
|||
STATE_CLASS_MEASUREMENT = 1;
|
||||
}
|
||||
|
||||
enum SensorLastResetType {
|
||||
LAST_RESET_NONE = 0;
|
||||
LAST_RESET_NEVER = 1;
|
||||
LAST_RESET_AUTO = 2;
|
||||
}
|
||||
|
||||
message ListEntitiesSensorResponse {
|
||||
option (id) = 16;
|
||||
option (source) = SOURCE_SERVER;
|
||||
|
@ -438,6 +444,7 @@ message ListEntitiesSensorResponse {
|
|||
bool force_update = 8;
|
||||
string device_class = 9;
|
||||
SensorStateClass state_class = 10;
|
||||
SensorLastResetType last_reset_type = 11;
|
||||
}
|
||||
message SensorStateResponse {
|
||||
option (id) = 25;
|
||||
|
|
|
@ -399,6 +399,7 @@ bool APIConnection::send_sensor_info(sensor::Sensor *sensor) {
|
|||
msg.force_update = sensor->get_force_update();
|
||||
msg.device_class = sensor->get_device_class();
|
||||
msg.state_class = static_cast<enums::SensorStateClass>(sensor->state_class);
|
||||
msg.last_reset_type = static_cast<enums::SensorLastResetType>(sensor->last_reset_type);
|
||||
|
||||
return this->send_list_entities_sensor_response(msg);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,18 @@ template<> const char *proto_enum_to_string<enums::SensorStateClass>(enums::Sens
|
|||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
template<> const char *proto_enum_to_string<enums::SensorLastResetType>(enums::SensorLastResetType value) {
|
||||
switch (value) {
|
||||
case enums::LAST_RESET_NONE:
|
||||
return "LAST_RESET_NONE";
|
||||
case enums::LAST_RESET_NEVER:
|
||||
return "LAST_RESET_NEVER";
|
||||
case enums::LAST_RESET_AUTO:
|
||||
return "LAST_RESET_AUTO";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
template<> const char *proto_enum_to_string<enums::LogLevel>(enums::LogLevel value) {
|
||||
switch (value) {
|
||||
case enums::LOG_LEVEL_NONE:
|
||||
|
@ -1592,6 +1604,10 @@ bool ListEntitiesSensorResponse::decode_varint(uint32_t field_id, ProtoVarInt va
|
|||
this->state_class = value.as_enum<enums::SensorStateClass>();
|
||||
return true;
|
||||
}
|
||||
case 11: {
|
||||
this->last_reset_type = value.as_enum<enums::SensorLastResetType>();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1647,6 +1663,7 @@ void ListEntitiesSensorResponse::encode(ProtoWriteBuffer buffer) const {
|
|||
buffer.encode_bool(8, this->force_update);
|
||||
buffer.encode_string(9, this->device_class);
|
||||
buffer.encode_enum<enums::SensorStateClass>(10, this->state_class);
|
||||
buffer.encode_enum<enums::SensorLastResetType>(11, this->last_reset_type);
|
||||
}
|
||||
void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
||||
char buffer[64];
|
||||
|
@ -1692,6 +1709,10 @@ void ListEntitiesSensorResponse::dump_to(std::string &out) const {
|
|||
out.append(" state_class: ");
|
||||
out.append(proto_enum_to_string<enums::SensorStateClass>(this->state_class));
|
||||
out.append("\n");
|
||||
|
||||
out.append(" last_reset_type: ");
|
||||
out.append(proto_enum_to_string<enums::SensorLastResetType>(this->last_reset_type));
|
||||
out.append("\n");
|
||||
out.append("}");
|
||||
}
|
||||
bool SensorStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
|
||||
|
|
|
@ -36,6 +36,11 @@ enum SensorStateClass : uint32_t {
|
|||
STATE_CLASS_NONE = 0,
|
||||
STATE_CLASS_MEASUREMENT = 1,
|
||||
};
|
||||
enum SensorLastResetType : uint32_t {
|
||||
LAST_RESET_NONE = 0,
|
||||
LAST_RESET_NEVER = 1,
|
||||
LAST_RESET_AUTO = 2,
|
||||
};
|
||||
enum LogLevel : uint32_t {
|
||||
LOG_LEVEL_NONE = 0,
|
||||
LOG_LEVEL_ERROR = 1,
|
||||
|
@ -429,6 +434,7 @@ class ListEntitiesSensorResponse : public ProtoMessage {
|
|||
bool force_update{false};
|
||||
std::string device_class{};
|
||||
enums::SensorStateClass state_class{};
|
||||
enums::SensorLastResetType last_reset_type{};
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void dump_to(std::string &out) const override;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ from esphome.const import (
|
|||
ICON_EMPTY,
|
||||
ICON_LIGHTBULB,
|
||||
ICON_CURRENT_AC,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_HERTZ,
|
||||
UNIT_VOLT,
|
||||
|
@ -91,10 +92,20 @@ ATM90E32_PHASE_SCHEMA = cv.Schema(
|
|||
STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_FORWARD_ACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 2, DEVICE_CLASS_ENERGY, STATE_CLASS_MEASUREMENT
|
||||
UNIT_WATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_REVERSE_ACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 2, DEVICE_CLASS_ENERGY, STATE_CLASS_MEASUREMENT
|
||||
UNIT_WATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_GAIN_VOLTAGE, default=7305): cv.uint16_t,
|
||||
cv.Optional(CONF_GAIN_CT, default=27961): cv.uint16_t,
|
||||
|
|
|
@ -15,6 +15,7 @@ from esphome.const import (
|
|||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_CURRENT_AC,
|
||||
ICON_EMPTY,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_AMPERE,
|
||||
|
@ -121,14 +122,16 @@ CONFIG_SCHEMA = (
|
|||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_TOTAL_ENERGY_PRODUCTION): sensor.sensor_schema(
|
||||
UNIT_KILOWATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_TOTAL_GENERATION_TIME): sensor.sensor_schema(
|
||||
UNIT_HOURS,
|
||||
|
|
|
@ -19,8 +19,8 @@ from esphome.const import (
|
|||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
|
@ -67,7 +67,12 @@ CONFIG_SCHEMA = cv.Schema(
|
|||
UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER, STATE_CLASS_MEASUREMENT
|
||||
),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 1, DEVICE_CLASS_ENERGY, STATE_CLASS_NONE
|
||||
UNIT_WATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
1,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
|
||||
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
|
||||
|
|
|
@ -12,8 +12,8 @@ from esphome.const import (
|
|||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
|
@ -47,7 +47,8 @@ CONFIG_SCHEMA = (
|
|||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
|
|
@ -17,8 +17,8 @@ from esphome.const import (
|
|||
DEVICE_CLASS_ENERGY,
|
||||
ICON_EMPTY,
|
||||
ICON_CURRENT_AC,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_HERTZ,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
|
@ -54,7 +54,8 @@ CONFIG_SCHEMA = (
|
|||
ICON_EMPTY,
|
||||
0,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(
|
||||
UNIT_HERTZ,
|
||||
|
|
|
@ -25,8 +25,8 @@ from esphome.const import (
|
|||
ICON_CURRENT_AC,
|
||||
ICON_EMPTY,
|
||||
ICON_FLASH,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
STATE_CLASS_NONE,
|
||||
UNIT_AMPERE,
|
||||
UNIT_DEGREES,
|
||||
UNIT_EMPTY,
|
||||
|
@ -88,24 +88,36 @@ CONFIG_SCHEMA = (
|
|||
STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
cv.Optional(CONF_IMPORT_ACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 2, DEVICE_CLASS_ENERGY, STATE_CLASS_NONE
|
||||
UNIT_WATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_EXPORT_ACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 2, DEVICE_CLASS_ENERGY, STATE_CLASS_NONE
|
||||
UNIT_WATT_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_IMPORT_REACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_VOLT_AMPS_REACTIVE_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
cv.Optional(CONF_EXPORT_REACTIVE_ENERGY): sensor.sensor_schema(
|
||||
UNIT_VOLT_AMPS_REACTIVE_HOURS,
|
||||
ICON_EMPTY,
|
||||
2,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
STATE_CLASS_NONE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
|
|
@ -17,6 +17,7 @@ from esphome.const import (
|
|||
CONF_ICON,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_LAST_RESET_TYPE,
|
||||
CONF_ON_RAW_VALUE,
|
||||
CONF_ON_VALUE,
|
||||
CONF_ON_VALUE_RANGE,
|
||||
|
@ -30,6 +31,9 @@ from esphome.const import (
|
|||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
CONF_FORCE_UPDATE,
|
||||
LAST_RESET_TYPE_AUTO,
|
||||
LAST_RESET_TYPE_NEVER,
|
||||
LAST_RESET_TYPE_NONE,
|
||||
UNIT_EMPTY,
|
||||
ICON_EMPTY,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
|
@ -79,6 +83,15 @@ STATE_CLASSES = {
|
|||
}
|
||||
validate_state_class = cv.enum(STATE_CLASSES, lower=True, space="_")
|
||||
|
||||
LastResetTypes = sensor_ns.enum("LastResetType")
|
||||
LAST_RESET_TYPES = {
|
||||
LAST_RESET_TYPE_NONE: LastResetTypes.LAST_RESET_TYPE_NONE,
|
||||
LAST_RESET_TYPE_NEVER: LastResetTypes.LAST_RESET_TYPE_NEVER,
|
||||
LAST_RESET_TYPE_AUTO: LastResetTypes.LAST_RESET_TYPE_AUTO,
|
||||
}
|
||||
validate_last_reset_type = cv.enum(LAST_RESET_TYPES, lower=True, space="_")
|
||||
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
|
||||
|
@ -168,6 +181,7 @@ SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend(
|
|||
cv.Optional(CONF_ACCURACY_DECIMALS): accuracy_decimals,
|
||||
cv.Optional(CONF_DEVICE_CLASS): device_class,
|
||||
cv.Optional(CONF_STATE_CLASS): validate_state_class,
|
||||
cv.Optional(CONF_LAST_RESET_TYPE): validate_last_reset_type,
|
||||
cv.Optional(CONF_FORCE_UPDATE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_EXPIRE_AFTER): cv.All(
|
||||
cv.requires_component("mqtt"),
|
||||
|
@ -202,6 +216,7 @@ def sensor_schema(
|
|||
accuracy_decimals_: int,
|
||||
device_class_: Optional[str] = DEVICE_CLASS_EMPTY,
|
||||
state_class_: Optional[str] = STATE_CLASS_NONE,
|
||||
last_reset_type_: Optional[str] = LAST_RESET_TYPE_NONE,
|
||||
) -> cv.Schema:
|
||||
schema = SENSOR_SCHEMA
|
||||
if unit_of_measurement_ != UNIT_EMPTY:
|
||||
|
@ -230,6 +245,14 @@ def sensor_schema(
|
|||
schema = schema.extend(
|
||||
{cv.Optional(CONF_STATE_CLASS, default=state_class_): validate_state_class}
|
||||
)
|
||||
if last_reset_type_ != LAST_RESET_TYPE_NONE:
|
||||
schema = schema.extend(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_LAST_RESET_TYPE, default=last_reset_type_
|
||||
): validate_last_reset_type
|
||||
}
|
||||
)
|
||||
return schema
|
||||
|
||||
|
||||
|
@ -479,6 +502,8 @@ async def setup_sensor_core_(var, 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]))
|
||||
if CONF_LAST_RESET_TYPE in config:
|
||||
cg.add(var.set_last_reset_type(config[CONF_LAST_RESET_TYPE]))
|
||||
cg.add(var.set_force_update(config[CONF_FORCE_UPDATE]))
|
||||
if config.get(CONF_FILTERS): # must exist and not be empty
|
||||
filters = await build_filters(config[CONF_FILTERS])
|
||||
|
|
|
@ -16,6 +16,18 @@ const char *state_class_to_string(StateClass state_class) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *last_reset_type_to_string(LastResetType last_reset_type) {
|
||||
switch (last_reset_type) {
|
||||
case LAST_RESET_TYPE_NEVER:
|
||||
return "never";
|
||||
case LAST_RESET_TYPE_AUTO:
|
||||
return "auto";
|
||||
case LAST_RESET_TYPE_NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void Sensor::publish_state(float state) {
|
||||
this->raw_state = state;
|
||||
this->raw_callback_.call(state);
|
||||
|
@ -64,6 +76,7 @@ void Sensor::set_state_class(const std::string &state_class) {
|
|||
ESP_LOGW(TAG, "'%s' - Unrecognized state class %s", this->get_name().c_str(), state_class.c_str());
|
||||
}
|
||||
}
|
||||
void Sensor::set_last_reset_type(LastResetType last_reset_type) { this->last_reset_type = last_reset_type; }
|
||||
std::string Sensor::get_unit_of_measurement() {
|
||||
if (this->unit_of_measurement_.has_value())
|
||||
return *this->unit_of_measurement_;
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace sensor {
|
|||
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, (obj)->get_device_class().c_str()); \
|
||||
} \
|
||||
ESP_LOGCONFIG(TAG, "%s State Class: '%s'", prefix, state_class_to_string((obj)->state_class)); \
|
||||
if ((obj)->state_class == sensor::STATE_CLASS_MEASUREMENT && \
|
||||
(obj)->last_reset_type != sensor::LAST_RESET_TYPE_NONE) { \
|
||||
ESP_LOGCONFIG(TAG, "%s Last Reset Type: '%s'", prefix, last_reset_type_to_string((obj)->last_reset_type)); \
|
||||
} \
|
||||
ESP_LOGCONFIG(TAG, "%s Unit of Measurement: '%s'", prefix, (obj)->get_unit_of_measurement().c_str()); \
|
||||
ESP_LOGCONFIG(TAG, "%s Accuracy Decimals: %d", prefix, (obj)->get_accuracy_decimals()); \
|
||||
if (!(obj)->get_icon().empty()) { \
|
||||
|
@ -37,6 +41,20 @@ enum StateClass : uint8_t {
|
|||
|
||||
const char *state_class_to_string(StateClass state_class);
|
||||
|
||||
/**
|
||||
* Sensor last reset types
|
||||
*/
|
||||
enum LastResetType : uint8_t {
|
||||
/// This sensor does not support resetting. ie, it is not accumulative
|
||||
LAST_RESET_TYPE_NONE = 0,
|
||||
/// This sensor is expected to never reset its value
|
||||
LAST_RESET_TYPE_NEVER = 1,
|
||||
/// This sensor may reset and Home Assistant will watch for this
|
||||
LAST_RESET_TYPE_AUTO = 2,
|
||||
};
|
||||
|
||||
const char *last_reset_type_to_string(LastResetType last_reset_type);
|
||||
|
||||
/** Base-class for all sensors.
|
||||
*
|
||||
* A sensor has unit of measurement and can use publish_state to send out a new value with the specified accuracy.
|
||||
|
@ -155,6 +173,12 @@ class Sensor : public Nameable {
|
|||
*/
|
||||
virtual std::string device_class();
|
||||
|
||||
// The Last reset type of this sensor
|
||||
LastResetType last_reset_type{LAST_RESET_TYPE_NONE};
|
||||
|
||||
/// Manually set the Home Assistant last reset type for this sensor.
|
||||
void set_last_reset_type(LastResetType last_reset_type);
|
||||
|
||||
/** A unique ID for this sensor, empty for no unique id. See unique ID requirements:
|
||||
* https://developers.home-assistant.io/docs/en/entity_registry_index.html#unique-id-requirements
|
||||
*
|
||||
|
|
|
@ -297,6 +297,7 @@ CONF_KEY = "key"
|
|||
CONF_LAMBDA = "lambda"
|
||||
CONF_LAST_CONFIDENCE = "last_confidence"
|
||||
CONF_LAST_FINGER_ID = "last_finger_id"
|
||||
CONF_LAST_RESET_TYPE = "last_reset_type"
|
||||
CONF_LATITUDE = "latitude"
|
||||
CONF_LENGTH = "length"
|
||||
CONF_LEVEL = "level"
|
||||
|
@ -785,3 +786,10 @@ STATE_CLASS_NONE = ""
|
|||
|
||||
# The state represents a measurement in present time
|
||||
STATE_CLASS_MEASUREMENT = "measurement"
|
||||
|
||||
# This sensor does not support resetting. ie, it is not accumulative
|
||||
LAST_RESET_TYPE_NONE = ""
|
||||
# This sensor is expected to never reset its value
|
||||
LAST_RESET_TYPE_NEVER = "never"
|
||||
# This sensor may reset and Home Assistant will watch for this
|
||||
LAST_RESET_TYPE_AUTO = "auto"
|
||||
|
|
Loading…
Reference in a new issue