mirror of
https://github.com/home-assistant/core.git
synced 2025-12-27 06:28:31 +00:00
Handle missing Miele status codes gracefully (#159124)
This commit is contained in:
@@ -98,50 +98,28 @@ DEVICE_TYPE_TAGS = {
|
||||
}
|
||||
|
||||
|
||||
class StateStatus(IntEnum):
|
||||
class StateStatus(MieleEnum, missing_to_none=True):
|
||||
"""Define appliance states."""
|
||||
|
||||
RESERVED = 0
|
||||
OFF = 1
|
||||
ON = 2
|
||||
PROGRAMMED = 3
|
||||
WAITING_TO_START = 4
|
||||
IN_USE = 5
|
||||
PAUSE = 6
|
||||
PROGRAM_ENDED = 7
|
||||
FAILURE = 8
|
||||
PROGRAM_INTERRUPTED = 9
|
||||
IDLE = 10
|
||||
RINSE_HOLD = 11
|
||||
SERVICE = 12
|
||||
SUPERFREEZING = 13
|
||||
SUPERCOOLING = 14
|
||||
SUPERHEATING = 15
|
||||
SUPERCOOLING_SUPERFREEZING = 146
|
||||
AUTOCLEANING = 147
|
||||
NOT_CONNECTED = 255
|
||||
|
||||
|
||||
STATE_STATUS_TAGS = {
|
||||
StateStatus.OFF: "off",
|
||||
StateStatus.ON: "on",
|
||||
StateStatus.PROGRAMMED: "programmed",
|
||||
StateStatus.WAITING_TO_START: "waiting_to_start",
|
||||
StateStatus.IN_USE: "in_use",
|
||||
StateStatus.PAUSE: "pause",
|
||||
StateStatus.PROGRAM_ENDED: "program_ended",
|
||||
StateStatus.FAILURE: "failure",
|
||||
StateStatus.PROGRAM_INTERRUPTED: "program_interrupted",
|
||||
StateStatus.IDLE: "idle",
|
||||
StateStatus.RINSE_HOLD: "rinse_hold",
|
||||
StateStatus.SERVICE: "service",
|
||||
StateStatus.SUPERFREEZING: "superfreezing",
|
||||
StateStatus.SUPERCOOLING: "supercooling",
|
||||
StateStatus.SUPERHEATING: "superheating",
|
||||
StateStatus.SUPERCOOLING_SUPERFREEZING: "supercooling_superfreezing",
|
||||
StateStatus.AUTOCLEANING: "autocleaning",
|
||||
StateStatus.NOT_CONNECTED: "not_connected",
|
||||
}
|
||||
reserved = 0
|
||||
off = 1
|
||||
on = 2
|
||||
programmed = 3
|
||||
waiting_to_start = 4
|
||||
in_use = 5
|
||||
pause = 6
|
||||
program_ended = 7
|
||||
failure = 8
|
||||
program_interrupted = 9
|
||||
idle = 10
|
||||
rinse_hold = 11
|
||||
service = 12
|
||||
superfreezing = 13
|
||||
supercooling = 14
|
||||
superheating = 15
|
||||
supercooling_superfreezing = 146
|
||||
autocleaning = 147
|
||||
not_connected = 255
|
||||
|
||||
|
||||
class MieleActions(IntEnum):
|
||||
|
||||
@@ -73,5 +73,5 @@ class MieleEntity(CoordinatorEntity[MieleDataUpdateCoordinator]):
|
||||
return (
|
||||
super().available
|
||||
and self._device_id in self.coordinator.data.devices
|
||||
and (self.device.state_status is not StateStatus.NOT_CONNECTED)
|
||||
and (self.device.state_status is not StateStatus.not_connected)
|
||||
)
|
||||
|
||||
@@ -38,7 +38,6 @@ from .const import (
|
||||
DOMAIN,
|
||||
PROGRAM_IDS,
|
||||
PROGRAM_PHASE,
|
||||
STATE_STATUS_TAGS,
|
||||
MieleAppliance,
|
||||
PlatePowerStep,
|
||||
StateDryingStep,
|
||||
@@ -195,7 +194,7 @@ SENSOR_TYPES: Final[tuple[MieleSensorDefinition, ...]] = (
|
||||
translation_key="status",
|
||||
value_fn=lambda value: value.state_status,
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=sorted(set(STATE_STATUS_TAGS.values())),
|
||||
options=sorted(set(StateStatus.keys())),
|
||||
),
|
||||
),
|
||||
MieleSensorDefinition(
|
||||
@@ -930,7 +929,7 @@ class MieleStatusSensor(MieleSensor):
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the sensor."""
|
||||
return STATE_STATUS_TAGS.get(StateStatus(self.device.state_status))
|
||||
return StateStatus(self.device.state_status).name
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
@@ -998,11 +997,11 @@ class MieleTimeSensor(MieleRestorableSensor):
|
||||
"""Update the last value of the sensor."""
|
||||
|
||||
current_value = self.entity_description.value_fn(self.device)
|
||||
current_status = StateStatus(self.device.state_status)
|
||||
current_status = StateStatus(self.device.state_status).name
|
||||
|
||||
# report end-specific value when program ends (some devices are immediately reporting 0...)
|
||||
if (
|
||||
current_status == StateStatus.PROGRAM_ENDED
|
||||
current_status == StateStatus.program_ended.name
|
||||
and self.entity_description.end_value_fn is not None
|
||||
):
|
||||
self._attr_native_value = self.entity_description.end_value_fn(
|
||||
@@ -1010,11 +1009,15 @@ class MieleTimeSensor(MieleRestorableSensor):
|
||||
)
|
||||
|
||||
# keep value when program ends if no function is specified
|
||||
elif current_status == StateStatus.PROGRAM_ENDED:
|
||||
elif current_status == StateStatus.program_ended.name:
|
||||
pass
|
||||
|
||||
# force unknown when appliance is not working (some devices are keeping last value until a new cycle starts)
|
||||
elif current_status in (StateStatus.OFF, StateStatus.ON, StateStatus.IDLE):
|
||||
elif current_status in (
|
||||
StateStatus.off.name,
|
||||
StateStatus.on.name,
|
||||
StateStatus.idle.name,
|
||||
):
|
||||
self._attr_native_value = None
|
||||
|
||||
# otherwise, cache value and return it
|
||||
@@ -1030,7 +1033,7 @@ class MieleAbsoluteTimeSensor(MieleRestorableSensor):
|
||||
def _update_native_value(self) -> None:
|
||||
"""Update the last value of the sensor."""
|
||||
current_value = self.entity_description.value_fn(self.device)
|
||||
current_status = StateStatus(self.device.state_status)
|
||||
current_status = StateStatus(self.device.state_status).name
|
||||
|
||||
# The API reports with minute precision, to avoid changing
|
||||
# the value too often, we keep the cached value if it differs
|
||||
@@ -1043,11 +1046,15 @@ class MieleAbsoluteTimeSensor(MieleRestorableSensor):
|
||||
< current_value
|
||||
< self._previous_value + timedelta(seconds=90)
|
||||
)
|
||||
) or current_status == StateStatus.PROGRAM_ENDED:
|
||||
) or current_status == StateStatus.program_ended.name:
|
||||
return
|
||||
|
||||
# force unknown when appliance is not working (some devices are keeping last value until a new cycle starts)
|
||||
if current_status in (StateStatus.OFF, StateStatus.ON, StateStatus.IDLE):
|
||||
if current_status in (
|
||||
StateStatus.off.name,
|
||||
StateStatus.on.name,
|
||||
StateStatus.idle.name,
|
||||
):
|
||||
self._attr_native_value = None
|
||||
|
||||
# otherwise, cache value and return it
|
||||
@@ -1064,7 +1071,7 @@ class MieleConsumptionSensor(MieleRestorableSensor):
|
||||
def _update_native_value(self) -> None:
|
||||
"""Update the last value of the sensor."""
|
||||
current_value = self.entity_description.value_fn(self.device)
|
||||
current_status = StateStatus(self.device.state_status)
|
||||
current_status = StateStatus(self.device.state_status).name
|
||||
# Guard for corrupt restored value
|
||||
restored_value = (
|
||||
self._attr_native_value
|
||||
@@ -1079,12 +1086,12 @@ class MieleConsumptionSensor(MieleRestorableSensor):
|
||||
|
||||
# Force unknown when appliance is not able to report consumption
|
||||
if current_status in (
|
||||
StateStatus.ON,
|
||||
StateStatus.OFF,
|
||||
StateStatus.PROGRAMMED,
|
||||
StateStatus.WAITING_TO_START,
|
||||
StateStatus.IDLE,
|
||||
StateStatus.SERVICE,
|
||||
StateStatus.on.name,
|
||||
StateStatus.off.name,
|
||||
StateStatus.programmed.name,
|
||||
StateStatus.waiting_to_start.name,
|
||||
StateStatus.idle.name,
|
||||
StateStatus.service.name,
|
||||
):
|
||||
self._is_reporting = False
|
||||
self._attr_native_value = None
|
||||
@@ -1093,7 +1100,7 @@ class MieleConsumptionSensor(MieleRestorableSensor):
|
||||
# only after a while, so it is necessary to force 0 until we see the 0 value coming from API, unless
|
||||
# we already saw a valid value in this cycle from cache
|
||||
elif (
|
||||
current_status in (StateStatus.IN_USE, StateStatus.PAUSE)
|
||||
current_status in (StateStatus.in_use.name, StateStatus.pause.name)
|
||||
and not self._is_reporting
|
||||
and last_value > 0
|
||||
):
|
||||
@@ -1101,7 +1108,7 @@ class MieleConsumptionSensor(MieleRestorableSensor):
|
||||
self._is_reporting = True
|
||||
|
||||
elif (
|
||||
current_status in (StateStatus.IN_USE, StateStatus.PAUSE)
|
||||
current_status in (StateStatus.in_use.name, StateStatus.pause.name)
|
||||
and not self._is_reporting
|
||||
and current_value is not None
|
||||
and cast(int, current_value) > 0
|
||||
@@ -1109,7 +1116,7 @@ class MieleConsumptionSensor(MieleRestorableSensor):
|
||||
self._attr_native_value = 0
|
||||
|
||||
# keep value when program ends
|
||||
elif current_status == StateStatus.PROGRAM_ENDED:
|
||||
elif current_status == StateStatus.program_ended.name:
|
||||
pass
|
||||
|
||||
else:
|
||||
|
||||
@@ -1061,6 +1061,7 @@
|
||||
"program_ended": "Program ended",
|
||||
"program_interrupted": "Program interrupted",
|
||||
"programmed": "Programmed",
|
||||
"reserved": "Reserved",
|
||||
"rinse_hold": "Rinse hold",
|
||||
"service": "Service",
|
||||
"supercooling": "Supercooling",
|
||||
|
||||
@@ -58,7 +58,7 @@ SWITCH_TYPES: Final[tuple[MieleSwitchDefinition, ...]] = (
|
||||
description=MieleSwitchDescription(
|
||||
key="supercooling",
|
||||
value_fn=lambda value: value.state_status,
|
||||
on_value=StateStatus.SUPERCOOLING,
|
||||
on_value=StateStatus.supercooling,
|
||||
translation_key="supercooling",
|
||||
on_cmd_data={PROCESS_ACTION: MieleActions.START_SUPERCOOL},
|
||||
off_cmd_data={PROCESS_ACTION: MieleActions.STOP_SUPERCOOL},
|
||||
@@ -73,7 +73,7 @@ SWITCH_TYPES: Final[tuple[MieleSwitchDefinition, ...]] = (
|
||||
description=MieleSwitchDescription(
|
||||
key="superfreezing",
|
||||
value_fn=lambda value: value.state_status,
|
||||
on_value=StateStatus.SUPERFREEZING,
|
||||
on_value=StateStatus.superfreezing,
|
||||
translation_key="superfreezing",
|
||||
on_cmd_data={PROCESS_ACTION: MieleActions.START_SUPERFREEZE},
|
||||
off_cmd_data={PROCESS_ACTION: MieleActions.STOP_SUPERFREEZE},
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -73,6 +74,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -367,6 +369,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -423,6 +426,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -458,6 +462,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -514,6 +519,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1431,6 +1437,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1487,6 +1494,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1522,6 +1530,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1578,6 +1587,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1613,6 +1623,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1669,6 +1680,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1872,6 +1884,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -1928,6 +1941,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2453,6 +2467,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2509,6 +2524,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2600,6 +2616,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2656,6 +2673,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2691,6 +2709,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -2747,6 +2766,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -3706,6 +3726,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -3762,6 +3783,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -3853,6 +3875,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -3909,6 +3932,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -4823,6 +4847,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -4879,6 +4904,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -4970,6 +4996,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -5026,6 +5053,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -5061,6 +5089,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -5117,6 +5146,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -6076,6 +6106,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -6132,6 +6163,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -6223,6 +6255,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -6279,6 +6312,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -7193,6 +7227,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
@@ -7249,6 +7284,7 @@
|
||||
'program_ended',
|
||||
'program_interrupted',
|
||||
'programmed',
|
||||
'reserved',
|
||||
'rinse_hold',
|
||||
'service',
|
||||
'supercooling',
|
||||
|
||||
Reference in New Issue
Block a user