Skip to content

Commit 857146f

Browse files
committed
entity: move common entity helpers
1 parent b420304 commit 857146f

File tree

5 files changed

+237
-187
lines changed

5 files changed

+237
-187
lines changed

custom_components/myheat/api.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
"dataActual": bool,
9696
"severity": int,
9797
"severityDesc": str,
98-
"weatherTemp": float,
98+
"weatherTemp": vol.Coerce(float),
9999
"city": str,
100100
},
101101
extra=vol.ALLOW_EXTRA,

custom_components/myheat/binary_sensor.py

+86-106
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from homeassistant.helpers.entity_platform import AddEntitiesCallback
1010

1111
from .const import CONF_NAME, DEFAULT_NAME, DOMAIN
12-
from .entity import MhEntity
12+
from .entity import MhEngEntity, MhEntity, MhEnvEntity, MhHeaterEntity
1313

1414
_logger = logging.getLogger(__package__)
1515

@@ -27,6 +27,7 @@ async def async_setup_entry(
2727
async_add_entities(
2828
[
2929
MhSeverityBinarySensor(coordinator, entry),
30+
MhDataActualBinarySensor(coordinator, entry),
3031
]
3132
+ list(
3233
chain.from_iterable(
@@ -39,150 +40,129 @@ async def async_setup_entry(
3940
)
4041
)
4142
+ list(
42-
MhEngBinarySensor(coordinator, entry, eng)
43-
for eng in coordinator.data.get("engs", [])
43+
MhEnvSeverityBinarySensor(coordinator, entry, env)
44+
for env in coordinator.data.get("envs", [])
45+
)
46+
+ list(
47+
chain.from_iterable(
48+
[
49+
MhEngTurnedOnBinarySensor(coordinator, entry, eng),
50+
MhEngSeverityBinarySensor(coordinator, entry, eng),
51+
]
52+
for eng in coordinator.data.get("engs", [])
53+
)
4454
)
4555
)
4656

4757

48-
class MhHeaterBinarySensor(MhEntity, BinarySensorEntity):
49-
"""myheat Binary Sensor class."""
50-
51-
_key = ""
58+
class MhDataActualBinarySensor(MhEntity, BinarySensorEntity):
59+
"""myheat Data Actual (connected) Binary Sensor class."""
5260

53-
def __init__(self, coordinator, config_entry, heater: dict):
54-
super().__init__(coordinator, config_entry)
55-
self.heater_name = heater["name"]
56-
self.heater_id = heater["id"]
61+
_attr_device_class = "connectivity"
5762

5863
@property
59-
def name(self):
60-
"""Return the name of the sensor."""
61-
name = self.config_entry.data.get(CONF_NAME, DEFAULT_NAME)
62-
return f"{name} {self.heater_name} {self._key}"
64+
def name(self) -> str:
65+
return f"{self._mh_name} dataActual"
6366

6467
@property
6568
def unique_id(self):
66-
"""Return a unique ID to use for this entity."""
67-
return f"{super().unique_id}htr{self.heater_id}{self._key}"
68-
69-
@property
70-
def is_on(self):
71-
"""Return true if the binary_sensor is on."""
72-
return self._heater().get(self._key)
73-
74-
@property
75-
def _mh_dev_name_suffix(self):
76-
return f" {self.heater_name}"
69+
return f"{super().unique_id}dataActual"
7770

7871
@property
79-
def _mh_identifiers(self):
80-
return (DOMAIN, f"{super().unique_id}htr{self.heater_id}")
81-
82-
def _heater(self) -> dict:
83-
if not self.coordinator.data.get("dataActual", False):
84-
_logger.warninig("data not actual! %s", self.coordinator.data)
85-
return {}
86-
87-
heaters = self.coordinator.data.get("heaters", [])
88-
for h in heaters:
89-
if h["id"] == self.heater_id:
90-
return h
91-
return {}
92-
93-
94-
class MhHeaterDisabledBinarySensor(MhHeaterBinarySensor):
95-
_key = "disabled"
96-
_attr_icon = "mdi:electric-switch"
97-
_attr_device_class = None
98-
99-
100-
class MhHeaterBurnerWaterBinarySensor(MhHeaterBinarySensor):
101-
_key = "burnerWater"
102-
_attr_icon = "mdi:fire"
103-
_attr_device_class = "heat"
104-
105-
106-
class MhHeaterBurnerHeatingBinarySensor(MhHeaterBinarySensor):
107-
_key = "burnerHeating"
108-
_attr_icon = "mdi:fire"
109-
_attr_device_class = "heat"
110-
72+
def is_on(self) -> bool | None:
73+
return self.coordinator.data.get("dataActual")
11174

112-
class MhSeverityBinarySensor(MhEntity, BinarySensorEntity):
113-
"""myheat Binary Sensor class."""
11475

76+
class MhSeverityBinarySensorBase(BinarySensorEntity):
11577
_attr_device_class = "problem"
116-
_attr_icon = "mdi:water-boiler-alert"
11778

118-
@property
119-
def name(self) -> str:
120-
"""Return the name of the sensor."""
121-
name = self.config_entry.data.get(CONF_NAME, DEFAULT_NAME)
122-
return f"{name} severity"
123-
124-
@property
125-
def unique_id(self):
126-
"""Return a unique ID to use for this entity."""
127-
return f"{super().unique_id}severity"
79+
def _severity(self) -> (int | None, str | None):
80+
return None, None
12881

12982
@property
13083
def is_on(self) -> bool | None:
131-
"""Return true if the binary_sensor is on."""
132-
133-
severity = self.coordinator.data.get("severity")
84+
severity, _ = self._severity()
13485
if severity is None:
13586
return None
13687

137-
return severity > 1
88+
# device_class:problem -> on means problem detected
89+
return severity != 1
13890

13991
@property
14092
def extra_state_attributes(self):
141-
desc = self.coordinator.data.get("severityDesc")
93+
severity, desc = self._severity()
14294
return {
95+
"value": severity,
14396
"description": desc,
14497
}
14598

14699

147-
class MhEngBinarySensor(MhEntity, BinarySensorEntity):
148-
"""myheat Binary Sensor class."""
100+
class MhSeverityBinarySensor(MhEntity, MhSeverityBinarySensorBase):
101+
_attr_icon = "mdi:water-boiler-alert"
149102

150-
def __init__(self, coordinator, config_entry, eng: dict):
151-
super().__init__(coordinator, config_entry)
152-
self.eng_name = eng["name"]
153-
self.eng_id = eng["id"]
103+
def _severity(self) -> (int | None, str | None):
104+
return (
105+
self.coordinator.data.get("severity"),
106+
self.coordinator.data.get("severityDesc"),
107+
)
154108

155109
@property
156-
def name(self):
157-
"""Return the name of the sensor."""
158-
name = self.config_entry.data.get(CONF_NAME, DEFAULT_NAME)
159-
return f"{name} {self.eng_name}"
110+
def name(self) -> str:
111+
return f"{self._mh_name} severity"
160112

161113
@property
162114
def unique_id(self):
163-
"""Return a unique ID to use for this entity."""
164-
return f"{super().unique_id}eng{self.eng_id}"
115+
return f"{super().unique_id}severity"
165116

117+
118+
class MhEnvSeverityBinarySensor(MhEnvEntity, MhSeverityBinarySensorBase):
119+
_key = "severity"
120+
_attr_icon = "mdi:water-boiler-alert"
121+
122+
def _severity(self) -> (int | None, str | None):
123+
e = self.get_env()
124+
return (
125+
e.get("severity"),
126+
e.get("severityDesc"),
127+
)
128+
129+
130+
class MhEngSeverityBinarySensor(MhEngEntity, MhSeverityBinarySensorBase):
131+
_key = "severity"
132+
133+
def _severity(self) -> (int | None, str | None):
134+
e = self.get_eng()
135+
return (
136+
e.get("severity"),
137+
e.get("severityDesc"),
138+
)
139+
140+
141+
class MhHeaterBinarySensor(MhHeaterEntity, BinarySensorEntity):
166142
@property
167143
def is_on(self):
168-
"""Return true if the binary_sensor is on."""
169-
return self._eng().get("turnedOn")
144+
return self.get_heater().get(self._key)
170145

171-
@property
172-
def _mh_dev_name_suffix(self):
173-
return f" {self.eng_name}"
174146

147+
class MhHeaterDisabledBinarySensor(MhHeaterBinarySensor):
148+
_key = "disabled"
149+
_attr_icon = "mdi:electric-switch"
150+
_attr_device_class = None
151+
152+
153+
class MhHeaterBurnerWaterBinarySensor(MhHeaterBinarySensor):
154+
_key = "burnerWater"
155+
_attr_icon = "mdi:fire"
156+
_attr_device_class = "heat"
157+
158+
159+
class MhHeaterBurnerHeatingBinarySensor(MhHeaterBinarySensor):
160+
_key = "burnerHeating"
161+
_attr_icon = "mdi:fire"
162+
_attr_device_class = "heat"
163+
164+
165+
class MhEngTurnedOnBinarySensor(MhEngEntity, BinarySensorEntity):
175166
@property
176-
def _mh_identifiers(self):
177-
return (DOMAIN, f"{super().unique_id}eng{self.eng_id}")
178-
179-
def _eng(self) -> dict:
180-
if not self.coordinator.data.get("dataActual", False):
181-
_logger.warninig("data not actual! %s", self.coordinator.data)
182-
return {}
183-
184-
engs = self.coordinator.data.get("engs", [])
185-
for e in engs:
186-
if e["id"] == self.eng_id:
187-
return e
188-
return {}
167+
def is_on(self):
168+
return self.get_eng().get("turnedOn")

custom_components/myheat/climate.py

+6-39
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
from homeassistant.core import HomeAssistant, callback
2222
from homeassistant.helpers.entity_platform import AddEntitiesCallback
2323

24-
from .const import CONF_NAME, DEFAULT_NAME, DOMAIN
25-
from .entity import MhEntity
24+
from .const import DOMAIN
25+
from .entity import MhEnvEntity
2626

2727
_logger = logging.getLogger(__package__)
2828

@@ -56,13 +56,11 @@ async def async_setup_entry(
5656
)
5757

5858

59-
class MhEnvClimate(MhEntity, ClimateEntity):
59+
class MhEnvClimate(MhEnvEntity, ClimateEntity):
6060
"""myheat Climate class."""
6161

6262
def __init__(self, coordinator, config_entry, env: dict):
63-
super().__init__(coordinator, config_entry)
64-
self.env_name = env["name"]
65-
self.env_id = env["id"]
63+
super().__init__(coordinator, config_entry, env)
6664

6765
self._attr_supported_features = (
6866
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
@@ -100,17 +98,6 @@ def __init__(self, coordinator, config_entry, env: dict):
10098

10199
self._attr_temperature_unit = UnitOfTemperature.CELSIUS
102100

103-
@property
104-
def name(self):
105-
"""Return the name of the sensor."""
106-
name = self.config_entry.data.get(CONF_NAME, DEFAULT_NAME)
107-
return f"{name} {self.env_name}"
108-
109-
@property
110-
def unique_id(self):
111-
"""Return a unique ID to use for this entity."""
112-
return f"{super().unique_id}env{self.env_id}"
113-
114101
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
115102
"""Set new target hvac mode."""
116103

@@ -132,15 +119,15 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
132119

133120
async def async_set_temperature(self, **kwargs) -> None:
134121
"""Set new target temperature."""
135-
goal = kwargs.get("temperature", 0)
122+
goal = kwargs.get("temperature", 0.0)
136123
await self.coordinator.api.async_set_env_goal(obj_id=self.env_id, goal=goal)
137124
await self.coordinator.async_request_refresh()
138125

139126
@callback
140127
def _handle_coordinator_update(self):
141128
"""Get the latest state from the thermostat."""
142129

143-
e = self._env()
130+
e = self.get_env()
144131

145132
self._attr_current_temperature = e.get("value")
146133
self._attr_target_temperature = e.get("target")
@@ -156,23 +143,3 @@ def _handle_coordinator_update(self):
156143
)
157144

158145
self.async_write_ha_state()
159-
160-
@property
161-
def _mh_dev_name_suffix(self):
162-
return f" {self.env_name}"
163-
164-
@property
165-
def _mh_identifiers(self):
166-
return (DOMAIN, f"{super().unique_id}env{self.env_id}")
167-
168-
def _env(self) -> dict:
169-
if not self.coordinator.data.get("dataActual", False):
170-
_logger.warninig("data not actual! %s", self.coordinator.data)
171-
return {}
172-
173-
envs = self.coordinator.data.get("envs", [])
174-
for e in envs:
175-
if e["id"] == self.env_id:
176-
return e
177-
178-
return {}

0 commit comments

Comments
 (0)