mirror of
https://github.com/home-assistant/core.git
synced 2025-09-09 23:01:40 +02:00
Add min/max values as extra attributes for measurements for fyta (#150562)
This commit is contained in:
@@ -2,3 +2,8 @@
|
|||||||
|
|
||||||
DOMAIN = "fyta"
|
DOMAIN = "fyta"
|
||||||
CONF_EXPIRATION = "expiration"
|
CONF_EXPIRATION = "expiration"
|
||||||
|
|
||||||
|
CONF_MAX_ACCEPTABLE = "max_acceptable"
|
||||||
|
CONF_MAX_GOOD = "max_good"
|
||||||
|
CONF_MIN_ACCEPTABLE = "min_acceptable"
|
||||||
|
CONF_MIN_GOOD = "min_good"
|
||||||
|
@@ -25,6 +25,12 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
CONF_MAX_ACCEPTABLE,
|
||||||
|
CONF_MAX_GOOD,
|
||||||
|
CONF_MIN_ACCEPTABLE,
|
||||||
|
CONF_MIN_GOOD,
|
||||||
|
)
|
||||||
from .coordinator import FytaConfigEntry, FytaCoordinator
|
from .coordinator import FytaConfigEntry, FytaCoordinator
|
||||||
from .entity import FytaPlantEntity
|
from .entity import FytaPlantEntity
|
||||||
|
|
||||||
@@ -36,6 +42,13 @@ class FytaSensorEntityDescription(SensorEntityDescription):
|
|||||||
value_fn: Callable[[Plant], StateType | datetime]
|
value_fn: Callable[[Plant], StateType | datetime]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class FytaMeasurementSensorEntityDescription(FytaSensorEntityDescription):
|
||||||
|
"""Describes Fyta sensor entity."""
|
||||||
|
|
||||||
|
attribute_fn: Callable[[Plant], dict[str, float | None]]
|
||||||
|
|
||||||
|
|
||||||
PLANT_STATUS_LIST: list[str] = ["deleted", "doing_great", "need_attention", "no_sensor"]
|
PLANT_STATUS_LIST: list[str] = ["deleted", "doing_great", "need_attention", "no_sensor"]
|
||||||
PLANT_MEASUREMENT_STATUS_LIST: list[str] = [
|
PLANT_MEASUREMENT_STATUS_LIST: list[str] = [
|
||||||
"no_data",
|
"no_data",
|
||||||
@@ -95,35 +108,6 @@ SENSORS: Final[list[FytaSensorEntityDescription]] = [
|
|||||||
options=PLANT_MEASUREMENT_STATUS_LIST,
|
options=PLANT_MEASUREMENT_STATUS_LIST,
|
||||||
value_fn=lambda plant: plant.salinity_status.name.lower(),
|
value_fn=lambda plant: plant.salinity_status.name.lower(),
|
||||||
),
|
),
|
||||||
FytaSensorEntityDescription(
|
|
||||||
key="temperature",
|
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
value_fn=lambda plant: plant.temperature,
|
|
||||||
),
|
|
||||||
FytaSensorEntityDescription(
|
|
||||||
key="light",
|
|
||||||
translation_key="light",
|
|
||||||
native_unit_of_measurement="μmol/s⋅m²",
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
value_fn=lambda plant: plant.light,
|
|
||||||
),
|
|
||||||
FytaSensorEntityDescription(
|
|
||||||
key="moisture",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
device_class=SensorDeviceClass.MOISTURE,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
value_fn=lambda plant: plant.moisture,
|
|
||||||
),
|
|
||||||
FytaSensorEntityDescription(
|
|
||||||
key="salinity",
|
|
||||||
translation_key="salinity",
|
|
||||||
native_unit_of_measurement=UnitOfConductivity.MILLISIEMENS_PER_CM,
|
|
||||||
device_class=SensorDeviceClass.CONDUCTIVITY,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
value_fn=lambda plant: plant.salinity,
|
|
||||||
),
|
|
||||||
FytaSensorEntityDescription(
|
FytaSensorEntityDescription(
|
||||||
key="ph",
|
key="ph",
|
||||||
device_class=SensorDeviceClass.PH,
|
device_class=SensorDeviceClass.PH,
|
||||||
@@ -152,6 +136,62 @@ SENSORS: Final[list[FytaSensorEntityDescription]] = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
MEASUREMENT_SENSORS: Final[list[FytaMeasurementSensorEntityDescription]] = [
|
||||||
|
FytaMeasurementSensorEntityDescription(
|
||||||
|
key="temperature",
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
attribute_fn=lambda plant: {
|
||||||
|
CONF_MAX_ACCEPTABLE: plant.temperature_max_acceptable,
|
||||||
|
CONF_MAX_GOOD: plant.temperature_max_good,
|
||||||
|
CONF_MIN_ACCEPTABLE: plant.temperature_min_acceptable,
|
||||||
|
CONF_MIN_GOOD: plant.temperature_min_good,
|
||||||
|
},
|
||||||
|
value_fn=lambda plant: plant.temperature,
|
||||||
|
),
|
||||||
|
FytaMeasurementSensorEntityDescription(
|
||||||
|
key="light",
|
||||||
|
translation_key="light",
|
||||||
|
native_unit_of_measurement="μmol/s⋅m²",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
attribute_fn=lambda plant: {
|
||||||
|
CONF_MAX_ACCEPTABLE: plant.light_max_acceptable,
|
||||||
|
CONF_MAX_GOOD: plant.light_max_good,
|
||||||
|
CONF_MIN_ACCEPTABLE: plant.light_min_acceptable,
|
||||||
|
CONF_MIN_GOOD: plant.light_min_good,
|
||||||
|
},
|
||||||
|
value_fn=lambda plant: plant.light,
|
||||||
|
),
|
||||||
|
FytaMeasurementSensorEntityDescription(
|
||||||
|
key="moisture",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
device_class=SensorDeviceClass.MOISTURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
attribute_fn=lambda plant: {
|
||||||
|
CONF_MAX_ACCEPTABLE: plant.moisture_max_acceptable,
|
||||||
|
CONF_MAX_GOOD: plant.moisture_max_good,
|
||||||
|
CONF_MIN_ACCEPTABLE: plant.moisture_min_acceptable,
|
||||||
|
CONF_MIN_GOOD: plant.moisture_min_good,
|
||||||
|
},
|
||||||
|
value_fn=lambda plant: plant.moisture,
|
||||||
|
),
|
||||||
|
FytaMeasurementSensorEntityDescription(
|
||||||
|
key="salinity",
|
||||||
|
translation_key="salinity",
|
||||||
|
native_unit_of_measurement=UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||||
|
device_class=SensorDeviceClass.CONDUCTIVITY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
attribute_fn=lambda plant: {
|
||||||
|
CONF_MAX_ACCEPTABLE: plant.salinity_max_acceptable,
|
||||||
|
CONF_MAX_GOOD: plant.salinity_max_good,
|
||||||
|
CONF_MIN_ACCEPTABLE: plant.salinity_min_acceptable,
|
||||||
|
CONF_MIN_GOOD: plant.salinity_min_good,
|
||||||
|
},
|
||||||
|
value_fn=lambda plant: plant.salinity,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@@ -168,14 +208,28 @@ async def async_setup_entry(
|
|||||||
if sensor.key in dir(coordinator.data.get(plant_id))
|
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
plant_entities.extend(
|
||||||
|
FytaPlantMeasurementSensor(coordinator, entry, sensor, plant_id)
|
||||||
|
for plant_id in coordinator.fyta.plant_list
|
||||||
|
for sensor in MEASUREMENT_SENSORS
|
||||||
|
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||||
|
)
|
||||||
|
|
||||||
async_add_entities(plant_entities)
|
async_add_entities(plant_entities)
|
||||||
|
|
||||||
def _async_add_new_device(plant_id: int) -> None:
|
def _async_add_new_device(plant_id: int) -> None:
|
||||||
async_add_entities(
|
plant_entities = [
|
||||||
FytaPlantSensor(coordinator, entry, sensor, plant_id)
|
FytaPlantSensor(coordinator, entry, sensor, plant_id)
|
||||||
for sensor in SENSORS
|
for sensor in SENSORS
|
||||||
if sensor.key in dir(coordinator.data.get(plant_id))
|
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||||
|
]
|
||||||
|
|
||||||
|
plant_entities.extend(
|
||||||
|
FytaPlantMeasurementSensor(coordinator, entry, sensor, plant_id)
|
||||||
|
for sensor in MEASUREMENT_SENSORS
|
||||||
|
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||||
)
|
)
|
||||||
|
async_add_entities(plant_entities)
|
||||||
|
|
||||||
coordinator.new_device_callbacks.append(_async_add_new_device)
|
coordinator.new_device_callbacks.append(_async_add_new_device)
|
||||||
|
|
||||||
@@ -190,3 +244,15 @@ class FytaPlantSensor(FytaPlantEntity, SensorEntity):
|
|||||||
"""Return the state for this sensor."""
|
"""Return the state for this sensor."""
|
||||||
|
|
||||||
return self.entity_description.value_fn(self.plant)
|
return self.entity_description.value_fn(self.plant)
|
||||||
|
|
||||||
|
|
||||||
|
class FytaPlantMeasurementSensor(FytaPlantSensor):
|
||||||
|
"""Represents a Fyta measurement sensor."""
|
||||||
|
|
||||||
|
entity_description: FytaMeasurementSensorEntityDescription
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> dict[str, float | None]:
|
||||||
|
"""Return the device state attributes."""
|
||||||
|
|
||||||
|
return self.entity_description.attribute_fn(self.plant)
|
||||||
|
@@ -138,10 +138,64 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"light": {
|
"light": {
|
||||||
"name": "Light"
|
"name": "Light",
|
||||||
|
"state_attributes": {
|
||||||
|
"max_acceptable": { "name": "Maximum acceptable" },
|
||||||
|
"max_good": { "name": "Maximum good" },
|
||||||
|
"min_acceptable": { "name": "Minimum acceptable" },
|
||||||
|
"min_good": { "name": "Minimum good" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"moisture": {
|
||||||
|
"name": "[%key:component::sensor::entity_component::moisture::name%]",
|
||||||
|
"state_attributes": {
|
||||||
|
"max_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"max_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_good::name%]"
|
||||||
|
},
|
||||||
|
"min_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"min_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_good::name%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"salinity": {
|
"salinity": {
|
||||||
"name": "Salinity"
|
"name": "Salinity",
|
||||||
|
"state_attributes": {
|
||||||
|
"max_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"max_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_good::name%]"
|
||||||
|
},
|
||||||
|
"min_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"min_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_good::name%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "[%key:component::sensor::entity_component::temperature::name%]",
|
||||||
|
"state_attributes": {
|
||||||
|
"max_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"max_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::max_good::name%]"
|
||||||
|
},
|
||||||
|
"min_acceptable": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_acceptable::name%]"
|
||||||
|
},
|
||||||
|
"min_good": {
|
||||||
|
"name": "[%key:component::fyta::entity::sensor::light::state_attributes::min_good::name%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"last_fertilised": {
|
"last_fertilised": {
|
||||||
"name": "Last fertilized"
|
"name": "Last fertilized"
|
||||||
|
@@ -142,6 +142,10 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'Gummibaum Light',
|
'friendly_name': 'Gummibaum Light',
|
||||||
|
'max_acceptable': 675.0,
|
||||||
|
'max_good': 450.0,
|
||||||
|
'min_acceptable': 18.0,
|
||||||
|
'min_good': 20.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 'μmol/s⋅m²',
|
'unit_of_measurement': 'μmol/s⋅m²',
|
||||||
}),
|
}),
|
||||||
@@ -261,6 +265,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'moisture',
|
'device_class': 'moisture',
|
||||||
'friendly_name': 'Gummibaum Moisture',
|
'friendly_name': 'Gummibaum Moisture',
|
||||||
|
'max_acceptable': 80.0,
|
||||||
|
'max_good': 70.0,
|
||||||
|
'min_acceptable': 25.0,
|
||||||
|
'min_good': 35.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': '%',
|
'unit_of_measurement': '%',
|
||||||
}),
|
}),
|
||||||
@@ -612,6 +620,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'conductivity',
|
'device_class': 'conductivity',
|
||||||
'friendly_name': 'Gummibaum Salinity',
|
'friendly_name': 'Gummibaum Salinity',
|
||||||
|
'max_acceptable': 1.2,
|
||||||
|
'max_good': 1.0,
|
||||||
|
'min_acceptable': 0.4,
|
||||||
|
'min_good': 0.6,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||||
}),
|
}),
|
||||||
@@ -782,6 +794,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'temperature',
|
'device_class': 'temperature',
|
||||||
'friendly_name': 'Gummibaum Temperature',
|
'friendly_name': 'Gummibaum Temperature',
|
||||||
|
'max_acceptable': 42.0,
|
||||||
|
'max_good': 36.0,
|
||||||
|
'min_acceptable': 10.0,
|
||||||
|
'min_good': 17.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||||
}),
|
}),
|
||||||
@@ -1002,6 +1018,10 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'friendly_name': 'Kakaobaum Light',
|
'friendly_name': 'Kakaobaum Light',
|
||||||
|
'max_acceptable': 675.0,
|
||||||
|
'max_good': 450.0,
|
||||||
|
'min_acceptable': 18.0,
|
||||||
|
'min_good': 20.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 'μmol/s⋅m²',
|
'unit_of_measurement': 'μmol/s⋅m²',
|
||||||
}),
|
}),
|
||||||
@@ -1121,6 +1141,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'moisture',
|
'device_class': 'moisture',
|
||||||
'friendly_name': 'Kakaobaum Moisture',
|
'friendly_name': 'Kakaobaum Moisture',
|
||||||
|
'max_acceptable': 80.0,
|
||||||
|
'max_good': 70.0,
|
||||||
|
'min_acceptable': 25.0,
|
||||||
|
'min_good': 35.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': '%',
|
'unit_of_measurement': '%',
|
||||||
}),
|
}),
|
||||||
@@ -1472,6 +1496,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'conductivity',
|
'device_class': 'conductivity',
|
||||||
'friendly_name': 'Kakaobaum Salinity',
|
'friendly_name': 'Kakaobaum Salinity',
|
||||||
|
'max_acceptable': 1.2,
|
||||||
|
'max_good': 1.0,
|
||||||
|
'min_acceptable': 0.4,
|
||||||
|
'min_good': 0.6,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||||
}),
|
}),
|
||||||
@@ -1642,6 +1670,10 @@
|
|||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'device_class': 'temperature',
|
'device_class': 'temperature',
|
||||||
'friendly_name': 'Kakaobaum Temperature',
|
'friendly_name': 'Kakaobaum Temperature',
|
||||||
|
'max_acceptable': 42.0,
|
||||||
|
'max_good': 36.0,
|
||||||
|
'min_acceptable': 10.0,
|
||||||
|
'min_good': 17.0,
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||||
}),
|
}),
|
||||||
|
Reference in New Issue
Block a user