From d6105d397f62f4bca05c2c57ec945224cb893c23 Mon Sep 17 00:00:00 2001 From: cyr-ius Date: Wed, 8 Nov 2023 08:32:07 +0100 Subject: [PATCH] Update setup_entry --- custom_components/truenas/binary_sensor.py | 81 +++++++++++++++++++--- custom_components/truenas/entity.py | 17 +++-- custom_components/truenas/sensor.py | 4 +- custom_components/truenas/update.py | 2 +- 4 files changed, 85 insertions(+), 19 deletions(-) diff --git a/custom_components/truenas/binary_sensor.py b/custom_components/truenas/binary_sensor.py index dd40437..a73790f 100644 --- a/custom_components/truenas/binary_sensor.py +++ b/custom_components/truenas/binary_sensor.py @@ -4,6 +4,7 @@ from dataclasses import dataclass, field from logging import getLogger +from homeassistant.components import persistent_notification from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, @@ -15,7 +16,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import ( + CONF_NOTIFY, DOMAIN, + EXTRA_ATTRS_ALERT, EXTRA_ATTRS_CHART, EXTRA_ATTRS_JAIL, EXTRA_ATTRS_POOL, @@ -67,7 +70,7 @@ class TruenasBinarySensorEntityDescription(BinarySensorEntityDescription): key="pool_healthy", icon_enabled="mdi:database", icon_disabled="mdi:database-off", - category="System", + category="Pool", refer="pools", attr="healthy", reference="guid", @@ -82,9 +85,9 @@ class TruenasBinarySensorEntityDescription(BinarySensorEntityDescription): attr="state", reference="id", extra_attributes=EXTRA_ATTRS_JAIL, - func=lambda *args: JailBinarySensor( + func=lambda *args: JailBinarySensor( # pylint: disable=unnecessary-lambda *args - ), # pylint: disable=unnecessary-lambda + ), ), TruenasBinarySensorEntityDescription( key="vm", @@ -106,9 +109,9 @@ class TruenasBinarySensorEntityDescription(BinarySensorEntityDescription): attr="running", reference="service", extra_attributes=EXTRA_ATTRS_SERVICE, - func=lambda *args: ServiceBinarySensor( + func=lambda *args: ServiceBinarySensor( # pylint: disable=unnecessary-lambda *args - ), # pylint: disable=unnecessary-lambda + ), ), TruenasBinarySensorEntityDescription( key="app", @@ -119,9 +122,33 @@ class TruenasBinarySensorEntityDescription(BinarySensorEntityDescription): attr="running", reference="id", extra_attributes=EXTRA_ATTRS_CHART, - func=lambda *args: ChartBinarySensor( + func=lambda *args: ChartBinarySensor( # pylint: disable=unnecessary-lambda + *args + ), + ), + TruenasBinarySensorEntityDescription( + key="alert", + icon_enabled="mdi:bell", + icon_disabled="mdi:bell-off", + category="System", + refer="alerts", + attr="level", + extra_attributes=EXTRA_ATTRS_ALERT, + func=lambda *args: AlertBinarySensor( # pylint: disable=unnecessary-lambda *args - ), # pylint: disable=unnecessary-lambda + ), + ), + TruenasBinarySensorEntityDescription( + key="smart", + icon_enabled="mdi:bell", + icon_disabled="mdi:bell-off", + name="Smart status", + category="Disk", + refer="smarts", + attr="smartdisk", + reference="name", + extra_attributes=EXTRA_ATTRS_ALERT, + func=lambda *args: BinarySensor(*args), # pylint: disable=unnecessary-lambda ), ) @@ -152,7 +179,7 @@ async def async_setup_entry( entities = [] for description in RESOURCE_LIST: if description.reference: - for key, value in coordinator.data.get(description.refer, {}).items(): + for value in coordinator.data.get(description.refer, {}): entities.append( description.func( coordinator, description, value[description.reference] @@ -176,7 +203,7 @@ def is_on(self) -> bool: def icon(self) -> str: """Return the icon.""" if self.entity_description.icon_enabled: - if self.datas.get(self.entity_description.attr): + if self.is_on: return self.entity_description.icon_enabled else: return self.entity_description.icon_disabled @@ -433,3 +460,39 @@ async def stop(self): "scale_options": {"replica_count": 0}, }, ) + + +class AlertBinarySensor(BinarySensor): + """Define a Truenas Applications Binary Sensor.""" + + @property + def name(self): + return f"Alert" + + @property + def is_on(self) -> bool: + """Return true if device is on.""" + status = False + for alert in self.datas: + if alert.get(self.entity_description.attr) != "INFO": + if self.coordinator.config_entry.options.get(CONF_NOTIFY): + persistent_notification.create( + self.hass, + alert["formatted"], + title=f"{alert['level']} {alert['klass']}", + notification_id=alert["uuid"], + ) + status = True + + return status + + @property + def extra_state_attributes(self) -> Mapping[str, Any]: + """Return extra attributes.""" + return { + "msg": { + alert["uuid"]: alert["formatted"] + for alert in self.datas + if alert["level"] != "INFO" + } + } diff --git a/custom_components/truenas/entity.py b/custom_components/truenas/entity.py index 797f451..264cfbc 100644 --- a/custom_components/truenas/entity.py +++ b/custom_components/truenas/entity.py @@ -30,8 +30,10 @@ def __init__( self.entity_description = entity_description self.uid = uid self.datas = coordinator.data.get(entity_description.refer, {}) - if uid: - self.datas = self.datas.get(uid, {}) + if uid is not None: + for data in self.datas: + if data[entity_description.reference] == uid: + self.datas = data self._attr_name = None if isinstance(entity_description.name, str): @@ -71,11 +73,12 @@ def __init__( @callback def _handle_coordinator_update(self) -> None: refer = self.entity_description.refer - self.datas = ( - self.coordinator.data.getr(refer, {}).get(self.uid) - if self.uid - else self.coordinator.data.getr(refer) - ) + reference = self.entity_description.reference + self.datas = self.coordinator.data.get(refer, {}) + if self.uid is not None: + for data in self.datas: + if data[reference] == self.uid: + self.datas = data self.async_write_ha_state() super()._handle_coordinator_update() diff --git a/custom_components/truenas/sensor.py b/custom_components/truenas/sensor.py index 80fdcb2..16272ca 100644 --- a/custom_components/truenas/sensor.py +++ b/custom_components/truenas/sensor.py @@ -186,7 +186,7 @@ class TruenasSensorEntityDescription(SensorEntityDescription): icon="mdi:database-settings", native_unit_of_measurement=UnitOfInformation.GIBIBYTES, state_class=SensorStateClass.MEASUREMENT, - category="System", + category="Pool", refer="pools", attr="available_gib", extra_attributes=EXTRA_ATTRS_POOL, @@ -290,7 +290,7 @@ async def async_setup_entry( entities = [] for description in RESOURCE_LIST: if description.reference: - for key, value in coordinator.data.get(description.refer, {}).items(): + for value in coordinator.data.get(description.refer, {}): entities.append( description.func( coordinator, description, value[description.reference] diff --git a/custom_components/truenas/update.py b/custom_components/truenas/update.py index a9bd410..00c848e 100644 --- a/custom_components/truenas/update.py +++ b/custom_components/truenas/update.py @@ -57,7 +57,7 @@ async def async_setup_entry( dispatcher = {"UpdateSensor": UpdateSensor} for description in RESOURCE_LIST: if description.reference: - for key, value in coordinator.data.get(description.refer, {}).items(): + for value in coordinator.data.get(description.refer, {}): entities.append( dispatcher[description.func]( coordinator, description, value[description.reference]