mirror of
https://github.com/home-assistant/core.git
synced 2026-02-15 07:36:16 +00:00
Add filling level sensors to miele (#157858)
This commit is contained in:
@@ -19,7 +19,12 @@ from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .api import AsyncConfigEntryAuth
|
||||
from .const import DOMAIN
|
||||
from .coordinator import MieleConfigEntry, MieleDataUpdateCoordinator
|
||||
from .coordinator import (
|
||||
MieleAuxDataUpdateCoordinator,
|
||||
MieleConfigEntry,
|
||||
MieleDataUpdateCoordinator,
|
||||
MieleRuntimeData,
|
||||
)
|
||||
from .services import async_setup_services
|
||||
|
||||
PLATFORMS: list[Platform] = [
|
||||
@@ -75,19 +80,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: MieleConfigEntry) -> boo
|
||||
) from err
|
||||
|
||||
# Setup MieleAPI and coordinator for data fetch
|
||||
api = MieleAPI(auth)
|
||||
coordinator = MieleDataUpdateCoordinator(hass, entry, api)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
entry.runtime_data = coordinator
|
||||
_api = MieleAPI(auth)
|
||||
_coordinator = MieleDataUpdateCoordinator(hass, entry, _api)
|
||||
await _coordinator.async_config_entry_first_refresh()
|
||||
_aux_coordinator = MieleAuxDataUpdateCoordinator(hass, entry, _api)
|
||||
await _aux_coordinator.async_config_entry_first_refresh()
|
||||
|
||||
entry.runtime_data = MieleRuntimeData(_api, _coordinator, _aux_coordinator)
|
||||
|
||||
entry.async_create_background_task(
|
||||
hass,
|
||||
coordinator.api.listen_events(
|
||||
data_callback=coordinator.callback_update_data,
|
||||
actions_callback=coordinator.callback_update_actions,
|
||||
entry.runtime_data.api.listen_events(
|
||||
data_callback=_coordinator.callback_update_data,
|
||||
actions_callback=_coordinator.callback_update_actions,
|
||||
),
|
||||
"pymiele event listener",
|
||||
)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
@@ -107,5 +116,5 @@ async def async_remove_config_entry_device(
|
||||
identifier
|
||||
for identifier in device_entry.identifiers
|
||||
if identifier[0] == DOMAIN
|
||||
and identifier[1] in config_entry.runtime_data.data.devices
|
||||
and identifier[1] in config_entry.runtime_data.coordinator.data.devices
|
||||
)
|
||||
|
||||
@@ -264,7 +264,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the binary sensor platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -112,7 +112,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the button platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -138,7 +138,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the climate platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -9,7 +9,13 @@ from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from aiohttp import ClientResponseError
|
||||
from pymiele import MieleAction, MieleAPI, MieleDevice
|
||||
from pymiele import (
|
||||
MieleAction,
|
||||
MieleAPI,
|
||||
MieleDevice,
|
||||
MieleFillingLevel,
|
||||
MieleFillingLevels,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -20,7 +26,16 @@ from .const import DOMAIN
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
type MieleConfigEntry = ConfigEntry[MieleDataUpdateCoordinator]
|
||||
@dataclass
|
||||
class MieleRuntimeData:
|
||||
"""Runtime data for the Miele integration."""
|
||||
|
||||
api: MieleAPI
|
||||
coordinator: MieleDataUpdateCoordinator
|
||||
aux_coordinator: MieleAuxDataUpdateCoordinator
|
||||
|
||||
|
||||
type MieleConfigEntry = ConfigEntry[MieleRuntimeData]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -31,8 +46,15 @@ class MieleCoordinatorData:
|
||||
actions: dict[str, MieleAction]
|
||||
|
||||
|
||||
@dataclass
|
||||
class MieleAuxCoordinatorData:
|
||||
"""Data class for storing auxiliary coordinator data."""
|
||||
|
||||
filling_levels: dict[str, MieleFillingLevel]
|
||||
|
||||
|
||||
class MieleDataUpdateCoordinator(DataUpdateCoordinator[MieleCoordinatorData]):
|
||||
"""Coordinator for Miele data."""
|
||||
"""Main coordinator for Miele data."""
|
||||
|
||||
config_entry: MieleConfigEntry
|
||||
new_device_callbacks: list[Callable[[dict[str, MieleDevice]], None]] = []
|
||||
@@ -66,6 +88,7 @@ class MieleDataUpdateCoordinator(DataUpdateCoordinator[MieleCoordinatorData]):
|
||||
}
|
||||
self.devices = devices
|
||||
actions = {}
|
||||
|
||||
for device_id in devices:
|
||||
try:
|
||||
actions_json = await self.api.get_actions(device_id)
|
||||
@@ -99,10 +122,7 @@ class MieleDataUpdateCoordinator(DataUpdateCoordinator[MieleCoordinatorData]):
|
||||
device_id: MieleDevice(device) for device_id, device in devices_json.items()
|
||||
}
|
||||
self.async_set_updated_data(
|
||||
MieleCoordinatorData(
|
||||
devices=devices,
|
||||
actions=self.data.actions,
|
||||
)
|
||||
MieleCoordinatorData(devices=devices, actions=self.data.actions)
|
||||
)
|
||||
|
||||
async def callback_update_actions(self, actions_json: dict[str, dict]) -> None:
|
||||
@@ -111,8 +131,34 @@ class MieleDataUpdateCoordinator(DataUpdateCoordinator[MieleCoordinatorData]):
|
||||
device_id: MieleAction(action) for device_id, action in actions_json.items()
|
||||
}
|
||||
self.async_set_updated_data(
|
||||
MieleCoordinatorData(
|
||||
devices=self.data.devices,
|
||||
actions=actions,
|
||||
)
|
||||
MieleCoordinatorData(devices=self.data.devices, actions=actions)
|
||||
)
|
||||
|
||||
|
||||
class MieleAuxDataUpdateCoordinator(DataUpdateCoordinator[MieleAuxCoordinatorData]):
|
||||
"""Coordinator for Miele data for slowly polled endpoints."""
|
||||
|
||||
config_entry: MieleConfigEntry
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: MieleConfigEntry,
|
||||
api: MieleAPI,
|
||||
) -> None:
|
||||
"""Initialize the Miele data coordinator."""
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
config_entry=config_entry,
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(seconds=60),
|
||||
)
|
||||
self.api = api
|
||||
|
||||
async def _async_update_data(self) -> MieleAuxCoordinatorData:
|
||||
"""Fetch data from the Miele API."""
|
||||
filling_levels_json = await self.api.get_filling_levels()
|
||||
return MieleAuxCoordinatorData(
|
||||
filling_levels=MieleFillingLevels(filling_levels_json).filling_levels
|
||||
)
|
||||
|
||||
@@ -38,13 +38,19 @@ async def async_get_config_entry_diagnostics(
|
||||
"devices": redact_identifiers(
|
||||
{
|
||||
device_id: device_data.raw
|
||||
for device_id, device_data in config_entry.runtime_data.data.devices.items()
|
||||
for device_id, device_data in config_entry.runtime_data.coordinator.data.devices.items()
|
||||
}
|
||||
),
|
||||
"filling_levels": redact_identifiers(
|
||||
{
|
||||
device_id: filling_level_data.raw
|
||||
for device_id, filling_level_data in config_entry.runtime_data.aux_coordinator.data.filling_levels.items()
|
||||
}
|
||||
),
|
||||
"actions": redact_identifiers(
|
||||
{
|
||||
device_id: action_data.raw
|
||||
for device_id, action_data in config_entry.runtime_data.data.actions.items()
|
||||
for device_id, action_data in config_entry.runtime_data.coordinator.data.actions.items()
|
||||
}
|
||||
),
|
||||
}
|
||||
@@ -68,13 +74,19 @@ async def async_get_device_diagnostics(
|
||||
"model_id": device.model_id,
|
||||
}
|
||||
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
aux_coordinator = config_entry.runtime_data.aux_coordinator
|
||||
|
||||
device_id = cast(str, device.serial_number)
|
||||
miele_data: dict[str, Any] = {
|
||||
"devices": {
|
||||
hash_identifier(device_id): coordinator.data.devices[device_id].raw
|
||||
},
|
||||
"filling_levels": {
|
||||
hash_identifier(device_id): aux_coordinator.data.filling_levels[
|
||||
device_id
|
||||
].raw
|
||||
},
|
||||
"actions": {
|
||||
hash_identifier(device_id): coordinator.data.actions[device_id].raw
|
||||
},
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
"""Entity base class for the Miele integration."""
|
||||
|
||||
from pymiele import MieleAction, MieleAPI, MieleDevice
|
||||
from pymiele import MieleAction, MieleAPI, MieleDevice, MieleFillingLevel
|
||||
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import EntityDescription
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DEVICE_TYPE_TAGS, DOMAIN, MANUFACTURER, MieleAppliance, StateStatus
|
||||
from .coordinator import MieleDataUpdateCoordinator
|
||||
from .coordinator import MieleAuxDataUpdateCoordinator, MieleDataUpdateCoordinator
|
||||
|
||||
|
||||
class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
class MieleBaseEntity[
|
||||
_MieleCoordinatorT: MieleDataUpdateCoordinator | MieleAuxDataUpdateCoordinator
|
||||
](CoordinatorEntity[_MieleCoordinatorT]):
|
||||
"""Base class for Miele entities."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
@@ -22,7 +24,7 @@ class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: MieleDataUpdateCoordinator,
|
||||
coordinator: _MieleCoordinatorT,
|
||||
device_id: str,
|
||||
description: EntityDescription,
|
||||
) -> None:
|
||||
@@ -30,7 +32,26 @@ class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
super().__init__(coordinator)
|
||||
self._device_id = device_id
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = MieleEntity.get_unique_id(device_id, description)
|
||||
self._attr_unique_id = MieleBaseEntity.get_unique_id(device_id, description)
|
||||
self._attr_device_info = DeviceInfo(identifiers={(DOMAIN, device_id)})
|
||||
|
||||
@property
|
||||
def api(self) -> MieleAPI:
|
||||
"""Return the api object."""
|
||||
return self.coordinator.api
|
||||
|
||||
|
||||
class MieleEntity(MieleBaseEntity[MieleDataUpdateCoordinator]):
|
||||
"""Base class for Miele entities that use the main data coordinator."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: MieleDataUpdateCoordinator,
|
||||
device_id: str,
|
||||
description: EntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
super().__init__(coordinator, device_id, description)
|
||||
|
||||
device = self.device
|
||||
appliance_type = DEVICE_TYPE_TAGS.get(MieleAppliance(device.device_type))
|
||||
@@ -61,11 +82,6 @@ class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
"""Return the actions object."""
|
||||
return self.coordinator.data.actions[self._device_id]
|
||||
|
||||
@property
|
||||
def api(self) -> MieleAPI:
|
||||
"""Return the api object."""
|
||||
return self.coordinator.api
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return the availability of the entity."""
|
||||
@@ -75,3 +91,12 @@ class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
and self._device_id in self.coordinator.data.devices
|
||||
and (self.device.state_status is not StateStatus.not_connected)
|
||||
)
|
||||
|
||||
|
||||
class MieleAuxEntity(MieleBaseEntity[MieleAuxDataUpdateCoordinator]):
|
||||
"""Base class for Miele entities that use the auxiliary data coordinator."""
|
||||
|
||||
@property
|
||||
def levels(self) -> MieleFillingLevel:
|
||||
"""Return the filling levels object."""
|
||||
return self.coordinator.data.filling_levels[self._device_id]
|
||||
|
||||
@@ -66,7 +66,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the fan platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
"plate_step_warming": "mdi:alpha-w-circle-outline"
|
||||
}
|
||||
},
|
||||
"power_disk_level": {
|
||||
"default": "mdi:car-coolant-level"
|
||||
},
|
||||
"program_id": {
|
||||
"default": "mdi:selection-ellipse-arrow-inside"
|
||||
},
|
||||
@@ -83,6 +86,12 @@
|
||||
"remaining_time": {
|
||||
"default": "mdi:clock-end"
|
||||
},
|
||||
"rinse_aid_level": {
|
||||
"default": "mdi:water-opacity"
|
||||
},
|
||||
"salt_level": {
|
||||
"default": "mdi:shaker-outline"
|
||||
},
|
||||
"spin_speed": {
|
||||
"default": "mdi:sync"
|
||||
},
|
||||
@@ -95,6 +104,12 @@
|
||||
"target_temperature": {
|
||||
"default": "mdi:thermometer-check"
|
||||
},
|
||||
"twin_dos_1_level": {
|
||||
"default": "mdi:car-coolant-level"
|
||||
},
|
||||
"twin_dos_2_level": {
|
||||
"default": "mdi:car-coolant-level"
|
||||
},
|
||||
"water_forecast": {
|
||||
"default": "mdi:water-outline"
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the light platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -71,7 +71,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the select platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
|
||||
import logging
|
||||
from typing import Any, Final, cast
|
||||
|
||||
from pymiele import MieleDevice, MieleTemperature
|
||||
from pymiele import MieleDevice, MieleFillingLevel, MieleTemperature
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
RestoreSensor,
|
||||
@@ -44,8 +44,12 @@ from .const import (
|
||||
StateProgramType,
|
||||
StateStatus,
|
||||
)
|
||||
from .coordinator import MieleConfigEntry, MieleDataUpdateCoordinator
|
||||
from .entity import MieleEntity
|
||||
from .coordinator import (
|
||||
MieleAuxDataUpdateCoordinator,
|
||||
MieleConfigEntry,
|
||||
MieleDataUpdateCoordinator,
|
||||
)
|
||||
from .entity import MieleAuxEntity, MieleEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
@@ -139,10 +143,13 @@ def _convert_finish_timestamp(
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class MieleSensorDescription(SensorEntityDescription):
|
||||
class MieleSensorDescription[T: (MieleDevice, MieleFillingLevel)](
|
||||
SensorEntityDescription
|
||||
):
|
||||
"""Class describing Miele sensor entities."""
|
||||
|
||||
value_fn: Callable[[MieleDevice], StateType | datetime]
|
||||
value_fn: Callable[[T], StateType | datetime]
|
||||
|
||||
end_value_fn: Callable[[StateType | datetime], StateType | datetime] | None = None
|
||||
extra_attributes: dict[str, Callable[[MieleDevice], StateType]] | None = None
|
||||
zone: int | None = None
|
||||
@@ -150,14 +157,14 @@ class MieleSensorDescription(SensorEntityDescription):
|
||||
|
||||
|
||||
@dataclass
|
||||
class MieleSensorDefinition:
|
||||
class MieleSensorDefinition[T: (MieleDevice, MieleFillingLevel)]:
|
||||
"""Class for defining sensor entities."""
|
||||
|
||||
types: tuple[MieleAppliance, ...]
|
||||
description: MieleSensorDescription
|
||||
description: MieleSensorDescription[T]
|
||||
|
||||
|
||||
SENSOR_TYPES: Final[tuple[MieleSensorDefinition, ...]] = (
|
||||
SENSOR_TYPES: Final[tuple[MieleSensorDefinition[MieleDevice], ...]] = (
|
||||
MieleSensorDefinition(
|
||||
types=(
|
||||
MieleAppliance.WASHING_MACHINE,
|
||||
@@ -689,6 +696,59 @@ SENSOR_TYPES: Final[tuple[MieleSensorDefinition, ...]] = (
|
||||
),
|
||||
)
|
||||
|
||||
POLLED_SENSOR_TYPES: Final[tuple[MieleSensorDefinition[MieleFillingLevel], ...]] = (
|
||||
MieleSensorDefinition(
|
||||
types=(MieleAppliance.WASHING_MACHINE,),
|
||||
description=MieleSensorDescription[MieleFillingLevel](
|
||||
key="twin_dos_1_level",
|
||||
translation_key="twin_dos_1_level",
|
||||
value_fn=lambda value: value.twin_dos_container_1_filling_level,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(MieleAppliance.WASHING_MACHINE,),
|
||||
description=MieleSensorDescription[MieleFillingLevel](
|
||||
key="twin_dos_2_level",
|
||||
translation_key="twin_dos_2_level",
|
||||
value_fn=lambda value: value.twin_dos_container_2_filling_level,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(MieleAppliance.DISHWASHER,),
|
||||
description=MieleSensorDescription[MieleFillingLevel](
|
||||
key="power_disk_level",
|
||||
translation_key="power_disk_level",
|
||||
value_fn=lambda value: None,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(MieleAppliance.DISHWASHER,),
|
||||
description=MieleSensorDescription[MieleFillingLevel](
|
||||
key="salt_level",
|
||||
translation_key="salt_level",
|
||||
value_fn=lambda value: value.salt_filling_level,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
types=(MieleAppliance.DISHWASHER,),
|
||||
description=MieleSensorDescription[MieleFillingLevel](
|
||||
key="rinse_aid_level",
|
||||
translation_key="rinse_aid_level",
|
||||
value_fn=lambda value: value.rinse_aid_filling_level,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
@@ -696,11 +756,14 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the sensor platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
aux_coordinator = config_entry.runtime_data.aux_coordinator
|
||||
added_devices: set[str] = set() # device_id
|
||||
added_entities: set[str] = set() # unique_id
|
||||
|
||||
def _get_entity_class(definition: MieleSensorDefinition) -> type[MieleSensor]:
|
||||
def _get_entity_class(
|
||||
definition: MieleSensorDefinition[MieleDevice],
|
||||
) -> type[MieleSensor]:
|
||||
"""Get the entity class for the sensor."""
|
||||
return {
|
||||
"state_status": MieleStatusSensor,
|
||||
@@ -725,7 +788,7 @@ async def async_setup_entry(
|
||||
)
|
||||
|
||||
def _is_sensor_enabled(
|
||||
definition: MieleSensorDefinition,
|
||||
definition: MieleSensorDefinition[MieleDevice],
|
||||
device: MieleDevice,
|
||||
unique_id: str,
|
||||
) -> bool:
|
||||
@@ -748,6 +811,15 @@ async def async_setup_entry(
|
||||
return False
|
||||
return True
|
||||
|
||||
def _enabled_aux_sensor(
|
||||
definition: MieleSensorDefinition[MieleFillingLevel], level: MieleFillingLevel
|
||||
) -> bool:
|
||||
"""Check if aux sensors are enabled."""
|
||||
return not (
|
||||
definition.description.value_fn is not None
|
||||
and definition.description.value_fn(level) is None
|
||||
)
|
||||
|
||||
def _async_add_devices() -> None:
|
||||
nonlocal added_devices, added_entities
|
||||
entities: list = []
|
||||
@@ -775,7 +847,11 @@ async def async_setup_entry(
|
||||
continue
|
||||
|
||||
# sensors is not enabled, skip
|
||||
if not _is_sensor_enabled(definition, device, unique_id):
|
||||
if not _is_sensor_enabled(
|
||||
definition,
|
||||
device,
|
||||
unique_id,
|
||||
):
|
||||
continue
|
||||
|
||||
added_entities.add(unique_id)
|
||||
@@ -787,6 +863,15 @@ async def async_setup_entry(
|
||||
config_entry.async_on_unload(coordinator.async_add_listener(_async_add_devices))
|
||||
_async_add_devices()
|
||||
|
||||
async_add_entities(
|
||||
MieleAuxSensor(aux_coordinator, device_id, definition.description)
|
||||
for device_id in aux_coordinator.data.filling_levels
|
||||
for definition in POLLED_SENSOR_TYPES
|
||||
if _enabled_aux_sensor(
|
||||
definition, aux_coordinator.data.filling_levels[device_id]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
APPLIANCE_ICONS = {
|
||||
MieleAppliance.WASHING_MACHINE: "mdi:washing-machine",
|
||||
@@ -885,6 +970,32 @@ class MieleRestorableSensor(MieleSensor, RestoreSensor):
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
|
||||
class MieleAuxSensor(MieleAuxEntity, SensorEntity):
|
||||
"""Representation of a filling level Sensor."""
|
||||
|
||||
entity_description: MieleSensorDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: MieleAuxDataUpdateCoordinator,
|
||||
device_id: str,
|
||||
description: MieleSensorDescription,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(coordinator, device_id, description)
|
||||
if description.unique_id_fn is not None:
|
||||
self._attr_unique_id = description.unique_id_fn(device_id, description)
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType | datetime:
|
||||
"""Return the state of the level sensor."""
|
||||
return (
|
||||
self.entity_description.value_fn(self.levels)
|
||||
if self.entity_description.value_fn is not None
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
class MielePlateSensor(MieleSensor):
|
||||
"""Representation of a Sensor."""
|
||||
|
||||
|
||||
@@ -257,6 +257,9 @@
|
||||
"plate_step_warm": "Warming"
|
||||
}
|
||||
},
|
||||
"power_disk_level": {
|
||||
"name": "PowerDisk level"
|
||||
},
|
||||
"program_id": {
|
||||
"name": "Program",
|
||||
"state": {
|
||||
@@ -1038,6 +1041,12 @@
|
||||
"remaining_time": {
|
||||
"name": "Remaining time"
|
||||
},
|
||||
"rinse_aid_level": {
|
||||
"name": "Rinse aid level"
|
||||
},
|
||||
"salt_level": {
|
||||
"name": "Salt level"
|
||||
},
|
||||
"spin_speed": {
|
||||
"name": "Spin speed"
|
||||
},
|
||||
@@ -1080,6 +1089,12 @@
|
||||
"temperature_zone_3": {
|
||||
"name": "Temperature zone 3"
|
||||
},
|
||||
"twin_dos_1_level": {
|
||||
"name": "TwinDos 1 level"
|
||||
},
|
||||
"twin_dos_2_level": {
|
||||
"name": "TwinDos 2 level"
|
||||
},
|
||||
"water_consumption": {
|
||||
"name": "Water consumption"
|
||||
},
|
||||
|
||||
@@ -117,7 +117,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the switch platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
added_devices: set[str] = set()
|
||||
|
||||
def _async_add_new_devices() -> None:
|
||||
|
||||
@@ -128,7 +128,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the vacuum platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
|
||||
async_add_entities(
|
||||
MieleVacuum(coordinator, device_id, definition.description)
|
||||
|
||||
@@ -111,11 +111,26 @@ async def programs_fixture(
|
||||
return load_json_value_fixture(load_programs_file, DOMAIN)
|
||||
|
||||
|
||||
@pytest.fixture(scope="package")
|
||||
def load_filling_levels_file() -> str:
|
||||
"""Fixture for loading filling levels file."""
|
||||
return "filling_levels.json"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def filling_levels_fixture(
|
||||
hass: HomeAssistant, load_filling_levels_file: str
|
||||
) -> JsonValueType:
|
||||
"""Fixture for filling levels."""
|
||||
return load_json_value_fixture(load_filling_levels_file, DOMAIN)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_miele_client(
|
||||
device_fixture,
|
||||
action_fixture,
|
||||
programs_fixture,
|
||||
filling_levels_fixture,
|
||||
) -> Generator[MagicMock]:
|
||||
"""Mock a Miele client."""
|
||||
|
||||
@@ -127,6 +142,7 @@ def mock_miele_client(
|
||||
|
||||
client.get_devices.return_value = device_fixture
|
||||
client.get_actions.return_value = action_fixture
|
||||
client.get_filling_levels.return_value = filling_levels_fixture
|
||||
client.get_programs.return_value = programs_fixture
|
||||
client.set_program.return_value = None
|
||||
|
||||
|
||||
257
tests/components/miele/fixtures/filling_levels.json
Normal file
257
tests/components/miele/fixtures/filling_levels.json
Normal file
@@ -0,0 +1,257 @@
|
||||
[
|
||||
{
|
||||
"deviceId": "Dummy_Appliance_3",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": 63,
|
||||
"twinDosContainer2FillingLevel": 20,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyWasher",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": 63,
|
||||
"twinDosContainer2FillingLevel": 20,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "Dummy_Appliance_5",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": 80.5,
|
||||
"saltFillingLevel": 75,
|
||||
"rinseAidFillingLevel": 25,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_18",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": 33,
|
||||
"fatFilterSaturation": 66,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "Dummy_Appliance_4",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_12",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_74",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_74_off",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "Dummy_Appliance_1",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "Dummy_Appliance_2",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyDryer",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyOven",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "Dummy_Vacuum_1",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_Fridge_Freezer",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_hob_w_extr",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_Fridge_Freezer_Offline",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": null,
|
||||
"degreasingCounter": null,
|
||||
"milkCleaningCounter": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "DummyAppliance_CoffeeSystem",
|
||||
"fillingLevels": {
|
||||
"twinDosContainer1FillingLevel": null,
|
||||
"twinDosContainer2FillingLevel": null,
|
||||
"powerDiscFillingLevel": null,
|
||||
"saltFillingLevel": null,
|
||||
"rinseAidFillingLevel": null,
|
||||
"coalFilterSaturation": null,
|
||||
"fatFilterSaturation": null,
|
||||
"descalingCounter": 1,
|
||||
"degreasingCounter": 2,
|
||||
"milkCleaningCounter": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -830,6 +830,212 @@
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'filling_levels': dict({
|
||||
'**REDACTED_019aa577ad1c330d': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_10582eaebd067ad3': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_262ba14529681b23': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': 80.5,
|
||||
'rinseAidFillingLevel': 25,
|
||||
'saltFillingLevel': 75,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_43eee10f37037b43': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_4b870e84d3e80013': dict({
|
||||
'coalFilterSaturation': 33,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': 66,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_4b9caddd6c8a75c4': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_4c9255e388336dab': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_53a963893a01dc04': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_57d53e72806e88b4': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_5aed38e9def460e6': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_9c332e79e3cb1202': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_a367c0b42fc12284': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_afeb069d963cd921': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': 63,
|
||||
'twinDosContainer2FillingLevel': 20,
|
||||
}),
|
||||
'**REDACTED_bd62a0d31ec35172': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': 2,
|
||||
'descalingCounter': 1,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': 3,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_c9fe55cdf70786ca': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': 63,
|
||||
'twinDosContainer2FillingLevel': 20,
|
||||
}),
|
||||
'**REDACTED_e7bc6793e305bf53': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
'**REDACTED_ecf06220046f162f': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
}),
|
||||
'missing_code_warnings': list([
|
||||
'None',
|
||||
]),
|
||||
@@ -1014,6 +1220,20 @@
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'filling_levels': dict({
|
||||
'**REDACTED_57d53e72806e88b4': dict({
|
||||
'coalFilterSaturation': None,
|
||||
'degreasingCounter': None,
|
||||
'descalingCounter': None,
|
||||
'fatFilterSaturation': None,
|
||||
'milkCleaningCounter': None,
|
||||
'powerDiscFillingLevel': None,
|
||||
'rinseAidFillingLevel': None,
|
||||
'saltFillingLevel': None,
|
||||
'twinDosContainer1FillingLevel': None,
|
||||
'twinDosContainer2FillingLevel': None,
|
||||
}),
|
||||
}),
|
||||
'missing_code_warnings': list([
|
||||
'None',
|
||||
]),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@ async def test_devices_multiple_created_count(
|
||||
"""Test that multiple devices are created."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert len(device_registry.devices) == 5
|
||||
assert len(device_registry.devices) == 7
|
||||
|
||||
|
||||
async def test_device_info(
|
||||
@@ -205,7 +205,7 @@ async def test_setup_all_platforms(
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(device_registry.devices) == prev_devices + 2
|
||||
assert len(device_registry.devices) == prev_devices + 1
|
||||
|
||||
# Check a sample sensor for each new device
|
||||
assert hass.states.get("sensor.dishwasher").state == "in_use"
|
||||
|
||||
Reference in New Issue
Block a user