mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Add binary sensors to fyta (#134900)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
ec7d2f3731
commit
99e65c38b0
@ -24,6 +24,7 @@ from .coordinator import FytaCoordinator
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.SENSOR,
|
||||
]
|
||||
type FytaConfigEntry = ConfigEntry[FytaCoordinator]
|
||||
|
117
homeassistant/components/fyta/binary_sensor.py
Normal file
117
homeassistant/components/fyta/binary_sensor.py
Normal file
@ -0,0 +1,117 @@
|
||||
"""Binary sensors for Fyta."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Final
|
||||
|
||||
from fyta_cli.fyta_models import Plant
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import FytaConfigEntry
|
||||
from .entity import FytaPlantEntity
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class FytaBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Describes Fyta binary sensor entity."""
|
||||
|
||||
value_fn: Callable[[Plant], bool]
|
||||
|
||||
|
||||
BINARY_SENSORS: Final[list[FytaBinarySensorEntityDescription]] = [
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="low_battery",
|
||||
device_class=BinarySensorDeviceClass.BATTERY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda plant: plant.low_battery,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="notification_light",
|
||||
translation_key="notification_light",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda plant: plant.notification_light,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="notification_nutrition",
|
||||
translation_key="notification_nutrition",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda plant: plant.notification_nutrition,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="notification_temperature",
|
||||
translation_key="notification_temperature",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda plant: plant.notification_temperature,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="notification_water",
|
||||
translation_key="notification_water",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda plant: plant.notification_water,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="sensor_update_available",
|
||||
device_class=BinarySensorDeviceClass.UPDATE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda plant: plant.sensor_update_available,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="productive_plant",
|
||||
translation_key="productive_plant",
|
||||
value_fn=lambda plant: plant.productive_plant,
|
||||
),
|
||||
FytaBinarySensorEntityDescription(
|
||||
key="repotted",
|
||||
translation_key="repotted",
|
||||
value_fn=lambda plant: plant.repotted,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: FytaConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the FYTA binary sensors."""
|
||||
coordinator = entry.runtime_data
|
||||
|
||||
async_add_entities(
|
||||
FytaPlantBinarySensor(coordinator, entry, sensor, plant_id)
|
||||
for plant_id in coordinator.fyta.plant_list
|
||||
for sensor in BINARY_SENSORS
|
||||
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||
)
|
||||
|
||||
def _async_add_new_device(plant_id: int) -> None:
|
||||
async_add_entities(
|
||||
FytaPlantBinarySensor(coordinator, entry, sensor, plant_id)
|
||||
for sensor in BINARY_SENSORS
|
||||
if sensor.key in dir(coordinator.data.get(plant_id))
|
||||
)
|
||||
|
||||
coordinator.new_device_callbacks.append(_async_add_new_device)
|
||||
|
||||
|
||||
class FytaPlantBinarySensor(FytaPlantEntity, BinarySensorEntity):
|
||||
"""Represents a Fyta binary sensor."""
|
||||
|
||||
entity_description: FytaBinarySensorEntityDescription
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return value of the binary sensor."""
|
||||
|
||||
return self.entity_description.value_fn(self.plant)
|
@ -2,8 +2,8 @@
|
||||
|
||||
from fyta_cli.fyta_models import Plant
|
||||
|
||||
from homeassistant.components.sensor import SensorEntityDescription
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import EntityDescription
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from . import FytaConfigEntry
|
||||
@ -20,7 +20,7 @@ class FytaPlantEntity(CoordinatorEntity[FytaCoordinator]):
|
||||
self,
|
||||
coordinator: FytaCoordinator,
|
||||
entry: FytaConfigEntry,
|
||||
description: SensorEntityDescription,
|
||||
description: EntityDescription,
|
||||
plant_id: int,
|
||||
) -> None:
|
||||
"""Initialize the Fyta sensor."""
|
||||
|
@ -1,5 +1,25 @@
|
||||
{
|
||||
"entity": {
|
||||
"binary_sensor": {
|
||||
"notification_light": {
|
||||
"default": "mdi:lightbulb-alert-outline"
|
||||
},
|
||||
"notification_nutrition": {
|
||||
"default": "mdi:beaker-alert-outline"
|
||||
},
|
||||
"notification_temperature": {
|
||||
"default": "mdi:thermometer-alert"
|
||||
},
|
||||
"notification_water": {
|
||||
"default": "mdi:watering-can-outline"
|
||||
},
|
||||
"productive_plant": {
|
||||
"default": "mdi:fruit-grapes"
|
||||
},
|
||||
"repotted": {
|
||||
"default": "mdi:shovel"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"status": {
|
||||
"default": "mdi:flower"
|
||||
|
@ -38,6 +38,29 @@
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"binary_sensor": {
|
||||
"notification_light": {
|
||||
"name": "Light notification"
|
||||
},
|
||||
"notification_nutrition": {
|
||||
"name": "Nutrition notification"
|
||||
},
|
||||
"notification_temperature": {
|
||||
"name": "Temperature notification"
|
||||
},
|
||||
"notification_water": {
|
||||
"name": "Water notification"
|
||||
},
|
||||
"productive_plant": {
|
||||
"name": "Productive plant"
|
||||
},
|
||||
"repotted": {
|
||||
"name": "Repotted"
|
||||
},
|
||||
"sensor_update_available": {
|
||||
"name": "Sensor update available"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"scientific_name": {
|
||||
"name": "Scientific name"
|
||||
|
@ -1,6 +1,9 @@
|
||||
{
|
||||
"battery_level": 80,
|
||||
"low_battery": true,
|
||||
"fertilisation": {
|
||||
"was_repotted": true
|
||||
},
|
||||
"low_battery": false,
|
||||
"last_updated": "2023-01-10 10:10:00",
|
||||
"light": 2,
|
||||
"light_status": 3,
|
||||
@ -10,7 +13,7 @@
|
||||
"moisture_status": 3,
|
||||
"sensor_available": true,
|
||||
"sensor_id": "FD:1D:B7:E3:D0:E2",
|
||||
"sensor_update_available": false,
|
||||
"sensor_update_available": true,
|
||||
"sw_version": "1.0",
|
||||
"status": 1,
|
||||
"online": true,
|
||||
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"battery_level": 80,
|
||||
"fertilisation": {
|
||||
"was_repotted": true
|
||||
},
|
||||
"low_battery": true,
|
||||
"last_updated": "2023-01-02 10:10:00",
|
||||
"light": 2,
|
||||
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"battery_level": 80,
|
||||
"fertilisation": {
|
||||
"was_repotted": false
|
||||
},
|
||||
"low_battery": true,
|
||||
"last_updated": "2023-01-02 10:10:00",
|
||||
"light": 2,
|
||||
|
741
tests/components/fyta/snapshots/test_binary_sensor.ambr
Normal file
741
tests/components/fyta/snapshots/test_binary_sensor.ambr
Normal file
@ -0,0 +1,741 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[binary_sensor.gummibaum_battery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_battery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Battery',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-low_battery',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_battery-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'battery',
|
||||
'friendly_name': 'Gummibaum Battery',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_battery',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_light_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_light_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Light notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_light',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-notification_light',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_light_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Light notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_light_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_nutrition_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_nutrition_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Nutrition notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_nutrition',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-notification_nutrition',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_nutrition_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Nutrition notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_nutrition_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_productive_plant-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.gummibaum_productive_plant',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Productive plant',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'productive_plant',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-productive_plant',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_productive_plant-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Productive plant',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_productive_plant',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_repotted-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.gummibaum_repotted',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Repotted',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'repotted',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-repotted',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_repotted-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Repotted',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_repotted',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_temperature_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_temperature_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Temperature notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_temperature',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-notification_temperature',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_temperature_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Temperature notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_temperature_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_update-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_update',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.UPDATE: 'update'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Update',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-sensor_update_available',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_update-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'update',
|
||||
'friendly_name': 'Gummibaum Update',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_update',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_water_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.gummibaum_water_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Water notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_water',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-notification_water',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.gummibaum_water_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Gummibaum Water notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.gummibaum_water_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_battery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_battery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Battery',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-low_battery',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_battery-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'battery',
|
||||
'friendly_name': 'Kakaobaum Battery',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_battery',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_light_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_light_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Light notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_light',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-notification_light',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_light_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Light notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_light_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_nutrition_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_nutrition_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Nutrition notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_nutrition',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-notification_nutrition',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_nutrition_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Nutrition notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_nutrition_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_productive_plant-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.kakaobaum_productive_plant',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Productive plant',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'productive_plant',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-productive_plant',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_productive_plant-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Productive plant',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_productive_plant',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_repotted-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.kakaobaum_repotted',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Repotted',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'repotted',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-repotted',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_repotted-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Repotted',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_repotted',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_temperature_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_temperature_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Temperature notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_temperature',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-notification_temperature',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_temperature_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Temperature notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_temperature_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_update-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_update',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.UPDATE: 'update'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Update',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-sensor_update_available',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_update-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'update',
|
||||
'friendly_name': 'Kakaobaum Update',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_update',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_water_notification-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_water_notification',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Water notification',
|
||||
'platform': 'fyta',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'notification_water',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-notification_water',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.kakaobaum_water_notification-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Kakaobaum Water notification',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.kakaobaum_water_notification',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
@ -31,7 +31,7 @@
|
||||
'last_updated': '2023-01-10T10:10:00',
|
||||
'light': 2.0,
|
||||
'light_status': 3,
|
||||
'low_battery': True,
|
||||
'low_battery': False,
|
||||
'moisture': 61.0,
|
||||
'moisture_status': 3,
|
||||
'name': 'Gummibaum',
|
||||
@ -46,14 +46,14 @@
|
||||
'plant_origin_path': '',
|
||||
'plant_thumb_path': '',
|
||||
'productive_plant': False,
|
||||
'repotted': False,
|
||||
'repotted': True,
|
||||
'salinity': 1.0,
|
||||
'salinity_status': 4,
|
||||
'scientific_name': 'Ficus elastica',
|
||||
'sensor_available': True,
|
||||
'sensor_id': 'FD:1D:B7:E3:D0:E2',
|
||||
'sensor_status': 0,
|
||||
'sensor_update_available': False,
|
||||
'sensor_update_available': True,
|
||||
'status': 1,
|
||||
'sw_version': '1.0',
|
||||
'temperature': 25.2,
|
||||
@ -81,7 +81,7 @@
|
||||
'plant_origin_path': '',
|
||||
'plant_thumb_path': '',
|
||||
'productive_plant': False,
|
||||
'repotted': False,
|
||||
'repotted': True,
|
||||
'salinity': 1.0,
|
||||
'salinity_status': 4,
|
||||
'scientific_name': 'Theobroma cacao',
|
||||
|
95
tests/components/fyta/test_binary_sensor.py
Normal file
95
tests/components/fyta/test_binary_sensor.py
Normal file
@ -0,0 +1,95 @@
|
||||
"""Test the Home Assistant fyta binary sensor module."""
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from fyta_cli.fyta_exceptions import FytaConnectionError, FytaPlantError
|
||||
from fyta_cli.fyta_models import Plant
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.fyta.const import DOMAIN as FYTA_DOMAIN
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import setup_platform
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_time_changed,
|
||||
load_json_object_fixture,
|
||||
snapshot_platform,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_all_entities(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test all entities."""
|
||||
|
||||
await setup_platform(hass, mock_config_entry, [Platform.BINARY_SENSOR])
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
[
|
||||
FytaConnectionError,
|
||||
FytaPlantError,
|
||||
],
|
||||
)
|
||||
async def test_connection_error(
|
||||
hass: HomeAssistant,
|
||||
exception: Exception,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test connection error."""
|
||||
await setup_platform(hass, mock_config_entry, [Platform.BINARY_SENSOR])
|
||||
|
||||
mock_fyta_connector.update_all_plants.side_effect = exception
|
||||
|
||||
freezer.tick(delta=timedelta(hours=12))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
hass.states.get("binary_sensor.gummibaum_repotted").state == STATE_UNAVAILABLE
|
||||
)
|
||||
|
||||
|
||||
async def test_add_remove_entities(
|
||||
hass: HomeAssistant,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test if entities are added and old are removed."""
|
||||
await setup_platform(hass, mock_config_entry, [Platform.BINARY_SENSOR])
|
||||
|
||||
assert hass.states.get("binary_sensor.gummibaum_repotted").state == STATE_ON
|
||||
|
||||
plants: dict[int, Plant] = {
|
||||
0: Plant.from_dict(load_json_object_fixture("plant_status1.json", FYTA_DOMAIN)),
|
||||
2: Plant.from_dict(load_json_object_fixture("plant_status3.json", FYTA_DOMAIN)),
|
||||
}
|
||||
mock_fyta_connector.update_all_plants.return_value = plants
|
||||
mock_fyta_connector.plant_list = {
|
||||
0: "Kautschukbaum",
|
||||
2: "Tomatenpflanze",
|
||||
}
|
||||
|
||||
freezer.tick(delta=timedelta(minutes=10))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get("binary_sensor.kakaobaum_repotted") is None
|
||||
assert hass.states.get("binary_sensor.tomatenpflanze_repotted").state == STATE_OFF
|
Loading…
x
Reference in New Issue
Block a user