Skip to content

Commit 31cc483

Browse files
authored
Merge pull request #74 from plugwise/up111_3
Upstreaming PR #36219 second batch of changes
2 parents 75613c6 + d5b334a commit 31cc483

File tree

7 files changed

+260
-329
lines changed

7 files changed

+260
-329
lines changed

custom_components/plugwise-beta/__init__.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@
55
from datetime import timedelta
66
from typing import Dict
77

8-
from Plugwise_Smile.Smile import Smile
98
import async_timeout
109
import voluptuous as vol
10+
from Plugwise_Smile.Smile import Smile
1111

1212
from homeassistant.config_entries import ConfigEntry
13-
from homeassistant.core import HomeAssistant
13+
from homeassistant.core import HomeAssistant, callback
1414
from homeassistant.exceptions import ConfigEntryNotReady
1515
from homeassistant.helpers import device_registry as dr
1616
from homeassistant.helpers.aiohttp_client import async_get_clientsession
1717
from homeassistant.helpers.entity import Entity
1818
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
1919

20-
from .const import DOMAIN, THERMOSTAT_ICON
20+
from .const import DOMAIN
2121

2222
CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)
2323

@@ -43,7 +43,6 @@ async def async_setup_entry(hass, entry):
4343
connected = await api.connect()
4444

4545
if not connected:
46-
_LOGGER.error("Unable to connect to Smile: %s",api.smile_status)
4746
raise ConfigEntryNotReady
4847

4948
except Smile.InvalidAuthentication:
@@ -73,15 +72,15 @@ async def async_update_data():
7372
return True
7473
except Smile.XMLDataMissingError:
7574
_LOGGER.debug("Updating Smile failed %s", api.smile_type)
76-
raise UpdateFailed("Smile update failed %s", api.smile_type)
77-
75+
raise UpdateFailed("Smile update failed")
7876

7977
coordinator = DataUpdateCoordinator(
8078
hass,
8179
_LOGGER,
8280
name="Smile",
8381
update_method=async_update_data,
84-
update_interval=update_interval)
82+
update_interval=update_interval,
83+
)
8584

8685
await coordinator.async_refresh()
8786

@@ -92,7 +91,10 @@ async def async_update_data():
9291

9392
_LOGGER.debug("Async update interval %s", update_interval)
9493

95-
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { "api": api, "coordinator": coordinator }
94+
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
95+
"api": api,
96+
"coordinator": coordinator,
97+
}
9698

9799
_LOGGER.debug("Gateway is %s", api.gateway_id)
98100

@@ -111,9 +113,10 @@ async def async_update_data():
111113
sw_version=api.smile_version[0],
112114
)
113115

116+
platforms = ALL_PLATFORMS
117+
114118
single_master_thermostat = api.single_master_thermostat()
115119
_LOGGER.debug("Single master thermostat = %s", single_master_thermostat)
116-
platforms = ALL_PLATFORMS
117120
if single_master_thermostat is None:
118121
platforms = SENSOR_PLATFORMS
119122

@@ -144,16 +147,17 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
144147
class SmileGateway(Entity):
145148
"""Represent Smile Gateway."""
146149

147-
def __init__(self, api, coordinator):
150+
def __init__(self, api, coordinator, name, dev_id):
148151
"""Initialise the gateway."""
149152
self._api = api
150153
self._coordinator = coordinator
154+
self._name = name
155+
self._dev_id = dev_id
156+
151157
self._unique_id = None
152-
self._name = None
153-
self._icon = None
154-
self._dev_id = None
155158
self._model = None
156-
self._gateway_id = None
159+
160+
self._entity_name = self._name
157161

158162
@property
159163
def unique_id(self):
@@ -177,43 +181,35 @@ def name(self):
177181
pass
178182
return self._name
179183

180-
@property
181-
def icon(self):
182-
"""Return the icon to use in the frontend."""
183-
if not self._icon:
184-
return THERMOSTAT_ICON
185-
return self._icon
186-
187184
@property
188185
def device_info(self) -> Dict[str, any]:
189186
"""Return the device information."""
190-
191187
device_information = {
192188
"identifiers": {(DOMAIN, self._dev_id)},
193-
"name": self._name,
189+
"name": self._entity_name,
194190
"manufacturer": "Plugwise",
195191
}
196192

197193
if self._model is not None:
198194
device_information["model"] = self._model.replace("_", " ").title()
199195

200-
if self._dev_id != self._gateway_id:
201-
device_information["via_device"] = (DOMAIN, self._gateway_id)
196+
if self._dev_id != self._api.gateway_id:
197+
device_information["via_device"] = (DOMAIN, self._api.gateway_id)
202198

203199
return device_information
204200

205201
async def async_added_to_hass(self):
206202
"""Subscribe to updates."""
207-
self._process_data()
203+
self._async_process_data()
208204
self.async_on_remove(
209-
self._coordinator.async_add_listener(self._process_data)
205+
self._coordinator.async_add_listener(self._async_process_data)
210206
)
211-
212-
def _process_data(self):
207+
208+
@callback
209+
def _async_process_data(self):
213210
"""Interpret and process API data."""
214211
raise NotImplementedError
215212

216213
async def async_update(self):
217214
"""Update the entity."""
218215
await self._coordinator.async_request_refresh()
219-
Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
11
"""Plugwise Binary Sensor component for Home Assistant."""
22

33
import logging
4-
from typing import Dict
54

6-
from homeassistant.components.binary_sensor import (
7-
DEVICE_CLASS_OPENING,
8-
BinarySensorEntity,
9-
)
5+
from homeassistant.components.binary_sensor import BinarySensorEntity, DEVICE_CLASS_OPENING
106
from homeassistant.const import STATE_OFF, STATE_ON
7+
from homeassistant.core import callback
118

12-
from .const import (
13-
DOMAIN,
14-
FLAME_ICON,
15-
VALVE_CLOSED_ICON,
16-
VALVE_OPEN_ICON,
17-
WATER_ICON,
18-
)
19-
9+
from .const import DOMAIN, FLOW_OFF_ICON, FLOW_ON_ICON, IDLE_ICON, FLAME_ICON
2010
from .sensor import SmileSensor
2111

22-
BINARY_SENSOR_LIST = [
23-
"dhw_state",
24-
"slave_boiler_state",
25-
"valve_position",
26-
]
12+
BINARY_SENSOR_MAP = {
13+
"dhw_state": ["Domestic Hot Water State", None],
14+
"slave_boiler_state": ["Secondary Heater Device State", None],
15+
}
2716

2817
_LOGGER = logging.getLogger(__name__)
2918

@@ -33,59 +22,45 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
3322
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
3423
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
3524

36-
devices = []
37-
binary_sensor_classes = [
38-
"heater_central",
39-
"thermo_sensor",
40-
"thermostatic_radiator_valve",
41-
]
25+
entities = []
26+
4227
all_devices = api.get_all_devices()
43-
for dev_id, device in all_devices.items():
44-
if device["class"] in binary_sensor_classes:
45-
_LOGGER.debug("Plugwise device_class %s found", device["class"])
28+
for dev_id, device_properties in all_devices.items():
29+
if device_properties["class"] == "heater_central":
30+
_LOGGER.debug("Plugwise device_class %s found", device_properties["class"])
4631
data = api.get_device_data(dev_id)
47-
for binary_sensor in BINARY_SENSOR_LIST:
32+
for binary_sensor, b_s_type in BINARY_SENSOR_MAP.items():
4833
_LOGGER.debug("Binary_sensor: %s", binary_sensor)
4934
if binary_sensor in data:
50-
_LOGGER.debug("Plugwise binary_sensor Dev %s", device["name"])
51-
devices.append(
35+
_LOGGER.debug(
36+
"Plugwise binary_sensor Dev %s", device_properties["name"]
37+
)
38+
entities.append(
5239
PwBinarySensor(
5340
api,
5441
coordinator,
55-
device["name"],
42+
device_properties["name"],
5643
binary_sensor,
5744
dev_id,
58-
device["class"],
45+
device_properties["class"],
5946
)
6047
)
61-
_LOGGER.info("Added binary_sensor.%s", device["name"])
48+
_LOGGER.info("Added binary_sensor.%s", device_properties["name"])
6249

63-
async_add_entities(devices, True)
50+
async_add_entities(entities, True)
6451

6552

6653
class PwBinarySensor(SmileSensor, BinarySensorEntity):
6754
"""Representation of a Plugwise binary_sensor."""
6855

6956
def __init__(self, api, coordinator, name, binary_sensor, dev_id, model):
7057
"""Set up the Plugwise API."""
71-
super().__init__(api, coordinator)
58+
super().__init__(api, coordinator, name, dev_id, binary_sensor)
7259

73-
self._api = api
74-
self._dev_id = dev_id
75-
self._entity_name = name
7660
self._binary_sensor = binary_sensor
77-
self._is_on = False
78-
self._state = None
79-
self._dev_class = None
80-
81-
if self._dev_id == self._api.heater_id:
82-
self._entity_name = f"Auxiliary"
83-
84-
if self._dev_id == self._api.gateway_id:
85-
self._entity_name = f"Smile {self._name}"
8661

87-
bsensorname = binary_sensor.replace("_", " ").title()
88-
self._name = f"{self._entity_name} {bsensorname}"
62+
self._is_on = False
63+
self._icon = None
8964

9065
self._unique_id = f"bs-{dev_id}-{self._entity_name}-{binary_sensor}"
9166

@@ -94,32 +69,35 @@ def is_on(self):
9469
"""Return true if the binary sensor is on."""
9570
return self.is_on
9671

97-
def _process_data(self):
72+
@property
73+
def icon(self):
74+
"""Return the icon to use in the frontend."""
75+
return self._icon
76+
77+
@callback
78+
def _async_process_data(self):
9879
"""Update the entity."""
9980
_LOGGER.debug("Update binary_sensor called")
10081
data = self._api.get_device_data(self._dev_id)
10182

10283
if not data:
10384
_LOGGER.error("Received no data for device %s.", self._binary_sensor)
104-
else:
105-
if self._binary_sensor in data:
106-
self._state = STATE_OFF
107-
108-
if isinstance(data[self._binary_sensor], float):
109-
self._is_on = data[self._binary_sensor] == 1.0
110-
self._is_on = data[self._binary_sensor]
111-
112-
if self._is_on:
113-
self._state = STATE_ON
114-
85+
self.async_write_ha_state()
86+
return
87+
88+
if self._binary_sensor in data:
89+
self._is_on = data[self._binary_sensor]
90+
91+
self._state = STATE_OFF
92+
if self._binary_sensor == "dhw_state":
93+
self._icon = FLOW_OFF_ICON
94+
if self._binary_sensor == "slave_boiler_state":
95+
self._icon = IDLE_ICON
96+
if self._is_on:
97+
self._state = STATE_ON
11598
if self._binary_sensor == "dhw_state":
116-
self._icon = WATER_ICON
99+
self._icon = FLOW_ON_ICON
117100
if self._binary_sensor == "slave_boiler_state":
118101
self._icon = FLAME_ICON
119-
if self._binary_sensor == "valve_position":
120-
self._dev_class = DEVICE_CLASS_OPENING
121-
self._icon = VALVE_CLOSED_ICON
122-
if self._is_on:
123-
self._icon = VALVE_OPEN_ICON
124102

125-
self.async_write_ha_state()
103+
self.async_write_ha_state()

0 commit comments

Comments
 (0)