Add additional sensors to RainMachine (#80914)

This commit is contained in:
shbatm 2022-10-25 09:07:31 -05:00 committed by GitHub
parent 0018939142
commit e9a3982560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,11 +14,11 @@ from homeassistant.components.sensor import (
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TEMP_CELSIUS, VOLUME_CUBIC_METERS from homeassistant.const import TEMP_CELSIUS, VOLUME_CUBIC_METERS, VOLUME_LITERS
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utc_from_timestamp, utcnow
from . import RainMachineData, RainMachineEntity from . import RainMachineData, RainMachineEntity
from .const import ( from .const import (
@ -45,10 +45,14 @@ DEFAULT_ZONE_COMPLETION_TIME_WOBBLE_TOLERANCE = timedelta(seconds=5)
TYPE_FLOW_SENSOR_CLICK_M3 = "flow_sensor_clicks_cubic_meter" TYPE_FLOW_SENSOR_CLICK_M3 = "flow_sensor_clicks_cubic_meter"
TYPE_FLOW_SENSOR_CONSUMED_LITERS = "flow_sensor_consumed_liters" TYPE_FLOW_SENSOR_CONSUMED_LITERS = "flow_sensor_consumed_liters"
TYPE_FLOW_SENSOR_LEAK_CLICKS = "flow_sensor_leak_clicks"
TYPE_FLOW_SENSOR_LEAK_VOLUME = "flow_sensor_leak_volume"
TYPE_FLOW_SENSOR_START_INDEX = "flow_sensor_start_index" TYPE_FLOW_SENSOR_START_INDEX = "flow_sensor_start_index"
TYPE_FLOW_SENSOR_WATERING_CLICKS = "flow_sensor_watering_clicks" TYPE_FLOW_SENSOR_WATERING_CLICKS = "flow_sensor_watering_clicks"
TYPE_FREEZE_TEMP = "freeze_protect_temp" TYPE_FREEZE_TEMP = "freeze_protect_temp"
TYPE_LAST_LEAK_DETECTED = "last_leak_detected"
TYPE_PROGRAM_RUN_COMPLETION_TIME = "program_run_completion_time" TYPE_PROGRAM_RUN_COMPLETION_TIME = "program_run_completion_time"
TYPE_RAIN_SENSOR_RAIN_START = "rain_sensor_rain_start"
TYPE_ZONE_RUN_COMPLETION_TIME = "zone_run_completion_time" TYPE_ZONE_RUN_COMPLETION_TIME = "zone_run_completion_time"
@ -67,7 +71,7 @@ class RainMachineSensorCompletionTimerDescription(
RainMachineEntityDescription, RainMachineEntityDescription,
RainMachineEntityDescriptionMixinUid, RainMachineEntityDescriptionMixinUid,
): ):
"""Describe a RainMachine sensor.""" """Describe a RainMachine completion timer sensor."""
SENSOR_DESCRIPTIONS = ( SENSOR_DESCRIPTIONS = (
@ -87,12 +91,34 @@ SENSOR_DESCRIPTIONS = (
name="Flow sensor consumed liters", name="Flow sensor consumed liters",
icon="mdi:water-pump", icon="mdi:water-pump",
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement="liter", native_unit_of_measurement=VOLUME_LITERS,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
api_category=DATA_PROVISION_SETTINGS, api_category=DATA_PROVISION_SETTINGS,
data_key="flowSensorWateringClicks", data_key="flowSensorWateringClicks",
), ),
RainMachineSensorDataDescription(
key=TYPE_FLOW_SENSOR_LEAK_CLICKS,
name="Flow sensor leak clicks",
icon="mdi:pipe-leak",
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement="clicks",
entity_registry_enabled_default=False,
state_class=SensorStateClass.TOTAL_INCREASING,
api_category=DATA_PROVISION_SETTINGS,
data_key="flowSensorLeakClicks",
),
RainMachineSensorDataDescription(
key=TYPE_FLOW_SENSOR_LEAK_VOLUME,
name="Flow sensor leak volume",
icon="mdi:pipe-leak",
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=VOLUME_LITERS,
entity_registry_enabled_default=False,
state_class=SensorStateClass.TOTAL_INCREASING,
api_category=DATA_PROVISION_SETTINGS,
data_key="flowSensorLeakClicks",
),
RainMachineSensorDataDescription( RainMachineSensorDataDescription(
key=TYPE_FLOW_SENSOR_START_INDEX, key=TYPE_FLOW_SENSOR_START_INDEX,
name="Flow sensor start index", name="Flow sensor start index",
@ -110,7 +136,7 @@ SENSOR_DESCRIPTIONS = (
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement="clicks", native_unit_of_measurement="clicks",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.TOTAL_INCREASING,
api_category=DATA_PROVISION_SETTINGS, api_category=DATA_PROVISION_SETTINGS,
data_key="flowSensorWateringClicks", data_key="flowSensorWateringClicks",
), ),
@ -125,6 +151,28 @@ SENSOR_DESCRIPTIONS = (
api_category=DATA_RESTRICTIONS_UNIVERSAL, api_category=DATA_RESTRICTIONS_UNIVERSAL,
data_key="freezeProtectTemp", data_key="freezeProtectTemp",
), ),
RainMachineSensorDataDescription(
key=TYPE_LAST_LEAK_DETECTED,
name="Last leak detected",
icon="mdi:pipe-leak",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
device_class=SensorDeviceClass.TIMESTAMP,
state_class=SensorStateClass.MEASUREMENT,
api_category=DATA_PROVISION_SETTINGS,
data_key="lastLeakDetected",
),
RainMachineSensorDataDescription(
key=TYPE_RAIN_SENSOR_RAIN_START,
name="Rain sensor rain start",
icon="mdi:weather-pouring",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
device_class=SensorDeviceClass.TIMESTAMP,
state_class=SensorStateClass.MEASUREMENT,
api_category=DATA_PROVISION_SETTINGS,
data_key="rainSensorRainStart",
),
) )
@ -293,30 +341,36 @@ class ProvisionSettingsSensor(RainMachineEntity, SensorEntity):
@callback @callback
def update_from_latest_data(self) -> None: def update_from_latest_data(self) -> None:
"""Update the state.""" """Update the state."""
if self.entity_description.key == TYPE_FLOW_SENSOR_CLICK_M3: system = self.coordinator.data.get("system", {})
self._attr_native_value = self.coordinator.data.get("system", {}).get( new_value = system.get(self.entity_description.data_key)
"flowSensorClicksPerCubicMeter"
)
elif self.entity_description.key == TYPE_FLOW_SENSOR_CONSUMED_LITERS:
clicks = self.coordinator.data.get("system", {}).get(
"flowSensorWateringClicks"
)
clicks_per_m3 = self.coordinator.data.get("system", {}).get(
"flowSensorClicksPerCubicMeter"
)
if clicks and clicks_per_m3: # Calculate volumetric sensors
self._attr_native_value = (clicks * 1000) / clicks_per_m3 if (
self.entity_description.key
in {
TYPE_FLOW_SENSOR_CONSUMED_LITERS,
TYPE_FLOW_SENSOR_LEAK_VOLUME,
}
and new_value
):
if clicks_per_m3 := system.get("flowSensorClicksPerCubicMeter"):
self._attr_native_value = round((new_value * 1000) / clicks_per_m3, 1)
return
# Convert timestamp sensors to datetime
if self.entity_description.key in {
TYPE_LAST_LEAK_DETECTED,
TYPE_RAIN_SENSOR_RAIN_START,
}:
# Timestamp may return 0 instead of null, explicitly set to None
if new_value:
self._attr_native_value = utc_from_timestamp(new_value)
else: else:
self._attr_native_value = None self._attr_native_value = None
elif self.entity_description.key == TYPE_FLOW_SENSOR_START_INDEX: return
self._attr_native_value = self.coordinator.data.get("system", {}).get(
"flowSensorStartIndex" # Return all other sensor values or None
) self._attr_native_value = new_value
elif self.entity_description.key == TYPE_FLOW_SENSOR_WATERING_CLICKS:
self._attr_native_value = self.coordinator.data.get("system", {}).get(
"flowSensorWateringClicks"
)
class UniversalRestrictionsSensor(RainMachineEntity, SensorEntity): class UniversalRestrictionsSensor(RainMachineEntity, SensorEntity):