Skip to content

Commit 611feed

Browse files
astrandbkennedyshead
authored andcommitted
Handle missing Miele status codes gracefully (home-assistant#159124)
1 parent 0970632 commit 611feed

File tree

6 files changed

+87
-65
lines changed

6 files changed

+87
-65
lines changed

homeassistant/components/miele/const.py

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -98,50 +98,28 @@ class MieleAppliance(IntEnum):
9898
}
9999

100100

101-
class StateStatus(IntEnum):
101+
class StateStatus(MieleEnum, missing_to_none=True):
102102
"""Define appliance states."""
103103

104-
RESERVED = 0
105-
OFF = 1
106-
ON = 2
107-
PROGRAMMED = 3
108-
WAITING_TO_START = 4
109-
IN_USE = 5
110-
PAUSE = 6
111-
PROGRAM_ENDED = 7
112-
FAILURE = 8
113-
PROGRAM_INTERRUPTED = 9
114-
IDLE = 10
115-
RINSE_HOLD = 11
116-
SERVICE = 12
117-
SUPERFREEZING = 13
118-
SUPERCOOLING = 14
119-
SUPERHEATING = 15
120-
SUPERCOOLING_SUPERFREEZING = 146
121-
AUTOCLEANING = 147
122-
NOT_CONNECTED = 255
123-
124-
125-
STATE_STATUS_TAGS = {
126-
StateStatus.OFF: "off",
127-
StateStatus.ON: "on",
128-
StateStatus.PROGRAMMED: "programmed",
129-
StateStatus.WAITING_TO_START: "waiting_to_start",
130-
StateStatus.IN_USE: "in_use",
131-
StateStatus.PAUSE: "pause",
132-
StateStatus.PROGRAM_ENDED: "program_ended",
133-
StateStatus.FAILURE: "failure",
134-
StateStatus.PROGRAM_INTERRUPTED: "program_interrupted",
135-
StateStatus.IDLE: "idle",
136-
StateStatus.RINSE_HOLD: "rinse_hold",
137-
StateStatus.SERVICE: "service",
138-
StateStatus.SUPERFREEZING: "superfreezing",
139-
StateStatus.SUPERCOOLING: "supercooling",
140-
StateStatus.SUPERHEATING: "superheating",
141-
StateStatus.SUPERCOOLING_SUPERFREEZING: "supercooling_superfreezing",
142-
StateStatus.AUTOCLEANING: "autocleaning",
143-
StateStatus.NOT_CONNECTED: "not_connected",
144-
}
104+
reserved = 0
105+
off = 1
106+
on = 2
107+
programmed = 3
108+
waiting_to_start = 4
109+
in_use = 5
110+
pause = 6
111+
program_ended = 7
112+
failure = 8
113+
program_interrupted = 9
114+
idle = 10
115+
rinse_hold = 11
116+
service = 12
117+
superfreezing = 13
118+
supercooling = 14
119+
superheating = 15
120+
supercooling_superfreezing = 146
121+
autocleaning = 147
122+
not_connected = 255
145123

146124

147125
class MieleActions(IntEnum):

homeassistant/components/miele/entity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ def available(self) -> bool:
7373
return (
7474
super().available
7575
and self._device_id in self.coordinator.data.devices
76-
and (self.device.state_status is not StateStatus.NOT_CONNECTED)
76+
and (self.device.state_status is not StateStatus.not_connected)
7777
)

homeassistant/components/miele/sensor.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
DOMAIN,
3939
PROGRAM_IDS,
4040
PROGRAM_PHASE,
41-
STATE_STATUS_TAGS,
4241
MieleAppliance,
4342
PlatePowerStep,
4443
StateDryingStep,
@@ -195,7 +194,7 @@ class MieleSensorDefinition:
195194
translation_key="status",
196195
value_fn=lambda value: value.state_status,
197196
device_class=SensorDeviceClass.ENUM,
198-
options=sorted(set(STATE_STATUS_TAGS.values())),
197+
options=sorted(set(StateStatus.keys())),
199198
),
200199
),
201200
MieleSensorDefinition(
@@ -930,7 +929,7 @@ def __init__(
930929
@property
931930
def native_value(self) -> StateType:
932931
"""Return the state of the sensor."""
933-
return STATE_STATUS_TAGS.get(StateStatus(self.device.state_status))
932+
return StateStatus(self.device.state_status).name
934933

935934
@property
936935
def available(self) -> bool:
@@ -998,23 +997,27 @@ def _update_native_value(self) -> None:
998997
"""Update the last value of the sensor."""
999998

1000999
current_value = self.entity_description.value_fn(self.device)
1001-
current_status = StateStatus(self.device.state_status)
1000+
current_status = StateStatus(self.device.state_status).name
10021001

10031002
# report end-specific value when program ends (some devices are immediately reporting 0...)
10041003
if (
1005-
current_status == StateStatus.PROGRAM_ENDED
1004+
current_status == StateStatus.program_ended.name
10061005
and self.entity_description.end_value_fn is not None
10071006
):
10081007
self._attr_native_value = self.entity_description.end_value_fn(
10091008
self._attr_native_value
10101009
)
10111010

10121011
# keep value when program ends if no function is specified
1013-
elif current_status == StateStatus.PROGRAM_ENDED:
1012+
elif current_status == StateStatus.program_ended.name:
10141013
pass
10151014

10161015
# force unknown when appliance is not working (some devices are keeping last value until a new cycle starts)
1017-
elif current_status in (StateStatus.OFF, StateStatus.ON, StateStatus.IDLE):
1016+
elif current_status in (
1017+
StateStatus.off.name,
1018+
StateStatus.on.name,
1019+
StateStatus.idle.name,
1020+
):
10181021
self._attr_native_value = None
10191022

10201023
# otherwise, cache value and return it
@@ -1030,7 +1033,7 @@ class MieleAbsoluteTimeSensor(MieleRestorableSensor):
10301033
def _update_native_value(self) -> None:
10311034
"""Update the last value of the sensor."""
10321035
current_value = self.entity_description.value_fn(self.device)
1033-
current_status = StateStatus(self.device.state_status)
1036+
current_status = StateStatus(self.device.state_status).name
10341037

10351038
# The API reports with minute precision, to avoid changing
10361039
# the value too often, we keep the cached value if it differs
@@ -1043,11 +1046,15 @@ def _update_native_value(self) -> None:
10431046
< current_value
10441047
< self._previous_value + timedelta(seconds=90)
10451048
)
1046-
) or current_status == StateStatus.PROGRAM_ENDED:
1049+
) or current_status == StateStatus.program_ended.name:
10471050
return
10481051

10491052
# force unknown when appliance is not working (some devices are keeping last value until a new cycle starts)
1050-
if current_status in (StateStatus.OFF, StateStatus.ON, StateStatus.IDLE):
1053+
if current_status in (
1054+
StateStatus.off.name,
1055+
StateStatus.on.name,
1056+
StateStatus.idle.name,
1057+
):
10511058
self._attr_native_value = None
10521059

10531060
# otherwise, cache value and return it
@@ -1064,7 +1071,7 @@ class MieleConsumptionSensor(MieleRestorableSensor):
10641071
def _update_native_value(self) -> None:
10651072
"""Update the last value of the sensor."""
10661073
current_value = self.entity_description.value_fn(self.device)
1067-
current_status = StateStatus(self.device.state_status)
1074+
current_status = StateStatus(self.device.state_status).name
10681075
# Guard for corrupt restored value
10691076
restored_value = (
10701077
self._attr_native_value
@@ -1079,12 +1086,12 @@ def _update_native_value(self) -> None:
10791086

10801087
# Force unknown when appliance is not able to report consumption
10811088
if current_status in (
1082-
StateStatus.ON,
1083-
StateStatus.OFF,
1084-
StateStatus.PROGRAMMED,
1085-
StateStatus.WAITING_TO_START,
1086-
StateStatus.IDLE,
1087-
StateStatus.SERVICE,
1089+
StateStatus.on.name,
1090+
StateStatus.off.name,
1091+
StateStatus.programmed.name,
1092+
StateStatus.waiting_to_start.name,
1093+
StateStatus.idle.name,
1094+
StateStatus.service.name,
10881095
):
10891096
self._is_reporting = False
10901097
self._attr_native_value = None
@@ -1093,23 +1100,23 @@ def _update_native_value(self) -> None:
10931100
# only after a while, so it is necessary to force 0 until we see the 0 value coming from API, unless
10941101
# we already saw a valid value in this cycle from cache
10951102
elif (
1096-
current_status in (StateStatus.IN_USE, StateStatus.PAUSE)
1103+
current_status in (StateStatus.in_use.name, StateStatus.pause.name)
10971104
and not self._is_reporting
10981105
and last_value > 0
10991106
):
11001107
self._attr_native_value = current_value
11011108
self._is_reporting = True
11021109

11031110
elif (
1104-
current_status in (StateStatus.IN_USE, StateStatus.PAUSE)
1111+
current_status in (StateStatus.in_use.name, StateStatus.pause.name)
11051112
and not self._is_reporting
11061113
and current_value is not None
11071114
and cast(int, current_value) > 0
11081115
):
11091116
self._attr_native_value = 0
11101117

11111118
# keep value when program ends
1112-
elif current_status == StateStatus.PROGRAM_ENDED:
1119+
elif current_status == StateStatus.program_ended.name:
11131120
pass
11141121

11151122
else:

homeassistant/components/miele/strings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@
10611061
"program_ended": "Program ended",
10621062
"program_interrupted": "Program interrupted",
10631063
"programmed": "Programmed",
1064+
"reserved": "Reserved",
10641065
"rinse_hold": "Rinse hold",
10651066
"service": "Service",
10661067
"supercooling": "Supercooling",

homeassistant/components/miele/switch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class MieleSwitchDefinition:
5858
description=MieleSwitchDescription(
5959
key="supercooling",
6060
value_fn=lambda value: value.state_status,
61-
on_value=StateStatus.SUPERCOOLING,
61+
on_value=StateStatus.supercooling,
6262
translation_key="supercooling",
6363
on_cmd_data={PROCESS_ACTION: MieleActions.START_SUPERCOOL},
6464
off_cmd_data={PROCESS_ACTION: MieleActions.STOP_SUPERCOOL},
@@ -73,7 +73,7 @@ class MieleSwitchDefinition:
7373
description=MieleSwitchDescription(
7474
key="superfreezing",
7575
value_fn=lambda value: value.state_status,
76-
on_value=StateStatus.SUPERFREEZING,
76+
on_value=StateStatus.superfreezing,
7777
translation_key="superfreezing",
7878
on_cmd_data={PROCESS_ACTION: MieleActions.START_SUPERFREEZE},
7979
off_cmd_data={PROCESS_ACTION: MieleActions.STOP_SUPERFREEZE},

0 commit comments

Comments
 (0)