Skip to content

Commit f9575a3

Browse files
authored
Add "profile" extra attribute to Miele program sensor on coffee machines (#145073)
1 parent bbde98b commit f9575a3

File tree

6 files changed

+550
-3
lines changed

6 files changed

+550
-3
lines changed

homeassistant/components/miele/const.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,14 @@ class StateDryingStep(MieleEnum):
850850
24813: "appliance_settings", # modify profile name
851851
}
852852

853+
COFFEE_SYSTEM_PROFILE: dict[range, str] = {
854+
range(24000, 24032): "profile_1",
855+
range(24032, 24064): "profile_2",
856+
range(24064, 24096): "profile_3",
857+
range(24096, 24128): "profile_4",
858+
range(24128, 24160): "profile_5",
859+
}
860+
853861
STEAM_OVEN_MICRO_PROGRAM_ID: dict[int, str] = {
854862
8: "steam_cooking",
855863
19: "microwave",

homeassistant/components/miele/sensor.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
from __future__ import annotations
44

5-
from collections.abc import Callable
5+
from collections.abc import Callable, Mapping
66
from dataclasses import dataclass
77
import logging
8-
from typing import Final, cast
8+
from typing import Any, Final, cast
99

1010
from pymiele import MieleDevice, MieleTemperature
1111

@@ -30,6 +30,7 @@
3030
from homeassistant.helpers.typing import StateType
3131

3232
from .const import (
33+
COFFEE_SYSTEM_PROFILE,
3334
DISABLED_TEMP_ENTITIES,
3435
DOMAIN,
3536
STATE_PROGRAM_ID,
@@ -61,6 +62,8 @@
6162
"KMX": 6,
6263
}
6364

65+
ATTRIBUTE_PROFILE = "profile"
66+
6467

6568
def _get_plate_count(tech_type: str) -> int:
6669
"""Get number of zones for hob."""
@@ -88,11 +91,21 @@ def _convert_temperature(
8891
return raw_value
8992

9093

94+
def _get_coffee_profile(value: MieleDevice) -> str | None:
95+
"""Get coffee profile from value."""
96+
if value.state_program_id is not None:
97+
for key_range, profile in COFFEE_SYSTEM_PROFILE.items():
98+
if value.state_program_id in key_range:
99+
return profile
100+
return None
101+
102+
91103
@dataclass(frozen=True, kw_only=True)
92104
class MieleSensorDescription(SensorEntityDescription):
93105
"""Class describing Miele sensor entities."""
94106

95107
value_fn: Callable[[MieleDevice], StateType]
108+
extra_attributes: dict[str, Callable[[MieleDevice], StateType]] | None = None
96109
zone: int | None = None
97110
unique_id_fn: Callable[[str, MieleSensorDescription], str] | None = None
98111

@@ -157,7 +170,6 @@ class MieleSensorDefinition:
157170
MieleAppliance.OVEN_MICROWAVE,
158171
MieleAppliance.STEAM_OVEN,
159172
MieleAppliance.MICROWAVE,
160-
MieleAppliance.COFFEE_SYSTEM,
161173
MieleAppliance.ROBOT_VACUUM_CLEANER,
162174
MieleAppliance.WASHER_DRYER,
163175
MieleAppliance.STEAM_OVEN_COMBI,
@@ -172,6 +184,18 @@ class MieleSensorDefinition:
172184
value_fn=lambda value: value.state_program_id,
173185
),
174186
),
187+
MieleSensorDefinition(
188+
types=(MieleAppliance.COFFEE_SYSTEM,),
189+
description=MieleSensorDescription(
190+
key="state_program_id",
191+
translation_key="program_id",
192+
device_class=SensorDeviceClass.ENUM,
193+
value_fn=lambda value: value.state_program_id,
194+
extra_attributes={
195+
ATTRIBUTE_PROFILE: _get_coffee_profile,
196+
},
197+
),
198+
),
175199
MieleSensorDefinition(
176200
types=(
177201
MieleAppliance.WASHING_MACHINE,
@@ -710,6 +734,16 @@ def native_value(self) -> StateType:
710734
"""Return the state of the sensor."""
711735
return self.entity_description.value_fn(self.device)
712736

737+
@property
738+
def extra_state_attributes(self) -> Mapping[str, Any] | None:
739+
"""Return extra_state_attributes."""
740+
if self.entity_description.extra_attributes is None:
741+
return None
742+
attr = {}
743+
for key, value in self.entity_description.extra_attributes.items():
744+
attr[key] = value(self.device)
745+
return attr
746+
713747

714748
class MielePlateSensor(MieleSensor):
715749
"""Representation of a Sensor."""
@@ -792,6 +826,8 @@ def options(self) -> list[str]:
792826
class MieleProgramIdSensor(MieleSensor):
793827
"""Representation of the program id sensor."""
794828

829+
_unrecorded_attributes = frozenset({ATTRIBUTE_PROFILE})
830+
795831
@property
796832
def native_value(self) -> StateType:
797833
"""Return the state of the sensor."""

homeassistant/components/miele/strings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,18 @@
991991
"yom_tov": "Yom tov",
992992
"yorkshire_pudding": "Yorkshire pudding",
993993
"zander_fillet": "Zander (fillet)"
994+
},
995+
"state_attributes": {
996+
"profile": {
997+
"name": "Profile",
998+
"state": {
999+
"profile_1": "Profile 1",
1000+
"profile_2": "Profile 2",
1001+
"profile_3": "Profile 3",
1002+
"profile_4": "Profile 4",
1003+
"profile_5": "Profile 5"
1004+
}
1005+
}
9941006
}
9951007
},
9961008
"spin_speed": {
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
{
2+
"DummyAppliance_CoffeeSystem": {
3+
"ident": {
4+
"type": {
5+
"key_localized": "Device type",
6+
"value_raw": 17,
7+
"value_localized": "Coffee machine"
8+
},
9+
"deviceName": "",
10+
"protocolVersion": 4,
11+
"deviceIdentLabel": {
12+
"fabNumber": "**REDACTED**",
13+
"fabIndex": "11",
14+
"techType": "CM6160",
15+
"matNumber": "11488670",
16+
"swids": []
17+
},
18+
"xkmIdentLabel": {
19+
"techType": "EK037",
20+
"releaseVersion": "04.05"
21+
}
22+
},
23+
"state": {
24+
"ProgramID": {
25+
"value_raw": 24001,
26+
"value_localized": "espresso",
27+
"key_localized": "Program name"
28+
},
29+
"status": {
30+
"value_raw": 5,
31+
"value_localized": "In use",
32+
"key_localized": "status"
33+
},
34+
"programType": {
35+
"value_raw": 1,
36+
"value_localized": "Program",
37+
"key_localized": "Program type"
38+
},
39+
"programPhase": {
40+
"value_raw": 4353,
41+
"value_localized": "Espresso",
42+
"key_localized": "Program phase"
43+
},
44+
"remainingTime": [0, 0],
45+
"startTime": [0, 0],
46+
"targetTemperature": [
47+
{
48+
"value_raw": -32768,
49+
"value_localized": null,
50+
"unit": "Celsius"
51+
},
52+
{
53+
"value_raw": -32768,
54+
"value_localized": null,
55+
"unit": "Celsius"
56+
},
57+
{
58+
"value_raw": -32768,
59+
"value_localized": null,
60+
"unit": "Celsius"
61+
}
62+
],
63+
"coreTargetTemperature": [
64+
{
65+
"value_raw": -32768,
66+
"value_localized": null,
67+
"unit": "Celsius"
68+
}
69+
],
70+
"temperature": [
71+
{
72+
"value_raw": -32768,
73+
"value_localized": null,
74+
"unit": "Celsius"
75+
},
76+
{
77+
"value_raw": -32768,
78+
"value_localized": null,
79+
"unit": "Celsius"
80+
},
81+
{
82+
"value_raw": -32768,
83+
"value_localized": null,
84+
"unit": "Celsius"
85+
}
86+
],
87+
"coreTemperature": [
88+
{
89+
"value_raw": -32768,
90+
"value_localized": null,
91+
"unit": "Celsius"
92+
}
93+
],
94+
"signalInfo": false,
95+
"signalFailure": false,
96+
"signalDoor": false,
97+
"remoteEnable": {
98+
"fullRemoteControl": true,
99+
"smartGrid": false,
100+
"mobileStart": false
101+
},
102+
"ambientLight": null,
103+
"light": 1,
104+
"elapsedTime": [],
105+
"spinningSpeed": {
106+
"unit": "rpm",
107+
"value_raw": null,
108+
"value_localized": null,
109+
"key_localized": "Spin speed"
110+
},
111+
"dryingStep": {
112+
"value_raw": null,
113+
"value_localized": "",
114+
"key_localized": "Drying level"
115+
},
116+
"ventilationStep": {
117+
"value_raw": null,
118+
"value_localized": "",
119+
"key_localized": "Fan level"
120+
},
121+
"plateStep": [],
122+
"ecoFeedback": null,
123+
"batteryLevel": null
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)