Skip to content

Commit 75613c6

Browse files
authored
Merge pull request #72 from plugwise/up111_2
Upstreaming PR #36219 first changes
2 parents ba7af16 + aee9566 commit 75613c6

File tree

7 files changed

+267
-341
lines changed

7 files changed

+267
-341
lines changed

custom_components/plugwise-beta/__init__.py

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@
33
import asyncio
44
import logging
55
from datetime import timedelta
6-
from typing import Optional
7-
import voluptuous as vol
6+
from typing import Dict
87

8+
from Plugwise_Smile.Smile import Smile
99
import async_timeout
10+
import voluptuous as vol
1011

1112
from homeassistant.config_entries import ConfigEntry
1213
from homeassistant.core import HomeAssistant
1314
from homeassistant.exceptions import ConfigEntryNotReady
1415
from homeassistant.helpers import device_registry as dr
1516
from homeassistant.helpers.aiohttp_client import async_get_clientsession
1617
from homeassistant.helpers.entity import Entity
17-
from homeassistant.helpers.event import async_track_time_interval
1818
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
19-
from Plugwise_Smile.Smile import Smile
2019

21-
from .const import DOMAIN
20+
from .const import DOMAIN, THERMOSTAT_ICON
2221

2322
CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)
2423

@@ -27,6 +26,7 @@
2726
SENSOR_PLATFORMS = ["sensor"]
2827
ALL_PLATFORMS = ["binary_sensor", "climate", "sensor", "switch"]
2928

29+
3030
async def async_setup(hass: HomeAssistant, config: dict):
3131
"""Set up the Plugwise platform."""
3232
return True
@@ -76,8 +76,6 @@ async def async_update_data():
7676
raise UpdateFailed("Smile update failed %s", api.smile_type)
7777

7878

79-
api.get_all_devices()
80-
8179
coordinator = DataUpdateCoordinator(
8280
hass,
8381
_LOGGER,
@@ -87,6 +85,8 @@ async def async_update_data():
8785

8886
await coordinator.async_refresh()
8987

88+
api.get_all_devices()
89+
9090
if not coordinator.last_update_success:
9191
raise ConfigEntryNotReady
9292

@@ -145,10 +145,15 @@ class SmileGateway(Entity):
145145
"""Represent Smile Gateway."""
146146

147147
def __init__(self, api, coordinator):
148-
"""Initialise the sensor."""
148+
"""Initialise the gateway."""
149149
self._api = api
150150
self._coordinator = coordinator
151151
self._unique_id = None
152+
self._name = None
153+
self._icon = None
154+
self._dev_id = None
155+
self._model = None
156+
self._gateway_id = None
152157

153158
@property
154159
def unique_id(self):
@@ -165,8 +170,41 @@ def available(self):
165170
"""Return True if entity is available."""
166171
return self._coordinator.last_update_success
167172

173+
@property
174+
def name(self):
175+
"""Return the name of the entity, if any."""
176+
if not self._name:
177+
pass
178+
return self._name
179+
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+
187+
@property
188+
def device_info(self) -> Dict[str, any]:
189+
"""Return the device information."""
190+
191+
device_information = {
192+
"identifiers": {(DOMAIN, self._dev_id)},
193+
"name": self._name,
194+
"manufacturer": "Plugwise",
195+
}
196+
197+
if self._model is not None:
198+
device_information["model"] = self._model.replace("_", " ").title()
199+
200+
if self._dev_id != self._gateway_id:
201+
device_information["via_device"] = (DOMAIN, self._gateway_id)
202+
203+
return device_information
204+
168205
async def async_added_to_hass(self):
169206
"""Subscribe to updates."""
207+
self._process_data()
170208
self.async_on_remove(
171209
self._coordinator.async_add_listener(self._process_data)
172210
)
@@ -178,3 +216,4 @@ def _process_data(self):
178216
async def async_update(self):
179217
"""Update the entity."""
180218
await self._coordinator.async_request_refresh()
219+

custom_components/plugwise-beta/binary_sensor.py

Lines changed: 24 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
WATER_ICON,
1818
)
1919

20-
from . import SmileGateway
20+
from .sensor import SmileSensor
2121

2222
BINARY_SENSOR_LIST = [
2323
"dhw_state",
@@ -63,7 +63,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
6363
async_add_entities(devices, True)
6464

6565

66-
class PwBinarySensor(SmileGateway, BinarySensorEntity):
66+
class PwBinarySensor(SmileSensor, BinarySensorEntity):
6767
"""Representation of a Plugwise binary_sensor."""
6868

6969
def __init__(self, api, coordinator, name, binary_sensor, dev_id, model):
@@ -72,74 +72,28 @@ def __init__(self, api, coordinator, name, binary_sensor, dev_id, model):
7272

7373
self._api = api
7474
self._dev_id = dev_id
75-
self._model = model
76-
self._name = name
75+
self._entity_name = name
7776
self._binary_sensor = binary_sensor
7877
self._is_on = False
78+
self._state = None
79+
self._dev_class = None
7980

8081
if self._dev_id == self._api.heater_id:
81-
self._name = f"Auxiliary"
82+
self._entity_name = f"Auxiliary"
8283

8384
if self._dev_id == self._api.gateway_id:
84-
self._name = f"Smile {self._name}"
85+
self._entity_name = f"Smile {self._name}"
8586

8687
bsensorname = binary_sensor.replace("_", " ").title()
87-
self._sensorname = f"{self._name} {bsensorname}"
88+
self._name = f"{self._entity_name} {bsensorname}"
8889

89-
self._unique_id = f"bs-{dev_id}-{self._name}-{binary_sensor}"
90-
91-
@property
92-
def name(self):
93-
"""Return the name of the thermostat, if any."""
94-
return self._sensorname
90+
self._unique_id = f"bs-{dev_id}-{self._entity_name}-{binary_sensor}"
9591

9692
@property
9793
def is_on(self):
9894
"""Return true if the binary sensor is on."""
9995
return self.is_on
10096

101-
@property
102-
def state(self):
103-
"""Return the state of the binary sensor."""
104-
if self._is_on:
105-
return STATE_ON
106-
return STATE_OFF
107-
108-
@property
109-
def device_info(self) -> Dict[str, any]:
110-
"""Return the device information."""
111-
112-
device_information = {
113-
"identifiers": {(DOMAIN, self._dev_id)},
114-
"name": self._name,
115-
"manufacturer": "Plugwise",
116-
"model": self._model,
117-
}
118-
119-
if self._dev_id != self._api.gateway_id:
120-
device_information["via_device"] = (DOMAIN, self._api.gateway_id)
121-
122-
return device_information
123-
124-
@property
125-
def icon(self):
126-
"""Return the icon to use in the frontend."""
127-
if self._binary_sensor == "dhw_state":
128-
return WATER_ICON
129-
if self._binary_sensor == "slave_boiler_state":
130-
return FLAME_ICON
131-
if self._binary_sensor == "valve_position":
132-
if self._is_on:
133-
return VALVE_OPEN_ICON
134-
return VALVE_CLOSED_ICON
135-
136-
@property
137-
def device_class(self):
138-
"""Return the class of this device, from component DEVICE_CLASSES."""
139-
if self._binary_sensor == "valve_position":
140-
return DEVICE_CLASS_OPENING
141-
return "none"
142-
14397
def _process_data(self):
14498
"""Update the entity."""
14599
_LOGGER.debug("Update binary_sensor called")
@@ -149,8 +103,23 @@ def _process_data(self):
149103
_LOGGER.error("Received no data for device %s.", self._binary_sensor)
150104
else:
151105
if self._binary_sensor in data:
106+
self._state = STATE_OFF
107+
152108
if isinstance(data[self._binary_sensor], float):
153109
self._is_on = data[self._binary_sensor] == 1.0
154110
self._is_on = data[self._binary_sensor]
155111

112+
if self._is_on:
113+
self._state = STATE_ON
114+
115+
if self._binary_sensor == "dhw_state":
116+
self._icon = WATER_ICON
117+
if self._binary_sensor == "slave_boiler_state":
118+
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
124+
156125
self.async_write_ha_state()

custom_components/plugwise-beta/climate.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Plugwise Climate component for Home Assistant."""
22

33
import logging
4-
from typing import Dict
54
from Plugwise_Smile.Smile import Smile
65

76
from homeassistant.components.climate import ClimateEntity
@@ -84,6 +83,7 @@ def __init__(self, api, coordinator, name, dev_id, loc_id, model, min_temp, max_
8483
super().__init__(api, coordinator)
8584

8685
self._api = api
86+
self._gateway_id = self._api.gateway_id
8787
self._name = name
8888
self._dev_id = dev_id
8989
self._loc_id = loc_id
@@ -96,9 +96,9 @@ def __init__(self, api, coordinator, name, dev_id, loc_id, model, min_temp, max_
9696
self._preset_mode = None
9797
self._presets = None
9898
self._presets_list = None
99-
self._boiler_state = None
10099
self._heating_state = None
101100
self._cooling_state = None
101+
self._compressor_state = None
102102
self._dhw_state = None
103103
self._hvac_mode = None
104104
self._schema_names = None
@@ -109,48 +109,23 @@ def __init__(self, api, coordinator, name, dev_id, loc_id, model, min_temp, max_
109109
self._schedule_temp = None
110110
self._hvac_mode = None
111111
self._single_thermostat = self._api.single_master_thermostat()
112+
self._icon = THERMOSTAT_ICON
112113
self._unique_id = f"cl-{dev_id}-{self._name}"
113114

114115
@property
115116
def hvac_action(self):
116117
"""Return the current action."""
117118
if self._single_thermostat:
118-
if self._heating_state or self._boiler_state:
119+
if self._heating_state:
119120
return CURRENT_HVAC_HEAT
120121
if self._cooling_state:
121122
return CURRENT_HVAC_COOL
122123
return CURRENT_HVAC_IDLE
123-
if self._heating_state is not None or self._boiler_state is not None:
124+
if self._heating_state is not None:
124125
if self._setpoint > self._temperature:
125126
return CURRENT_HVAC_HEAT
126127
return CURRENT_HVAC_IDLE
127128

128-
@property
129-
def name(self):
130-
"""Return the name of the thermostat, if any."""
131-
return self._name
132-
133-
@property
134-
def device_info(self) -> Dict[str, any]:
135-
"""Return the device information."""
136-
137-
device_information = {
138-
"identifiers": {(DOMAIN, self._dev_id)},
139-
"name": self._name,
140-
"manufacturer": "Plugwise",
141-
"model": self._model.replace("_", " ").title(),
142-
}
143-
144-
if self._dev_id != self._api.gateway_id:
145-
device_information["via_device"] = (DOMAIN, self._api.gateway_id)
146-
147-
return device_information
148-
149-
@property
150-
def icon(self):
151-
"""Return the icon to use in the frontend."""
152-
return THERMOSTAT_ICON
153-
154129
@property
155130
def supported_features(self):
156131
"""Return the list of supported features."""
@@ -174,8 +149,8 @@ def preset_modes(self):
174149
@property
175150
def hvac_modes(self):
176151
"""Return the available hvac modes list."""
177-
if self._heating_state is not None or self._boiler_state is not None:
178-
if self._cooling_state is not None:
152+
if self._heating_state is not None:
153+
if self._compressor_state is not None:
179154
return HVAC_MODES_HEAT_COOL
180155
return HVAC_MODES_HEAT_ONLY
181156

@@ -300,21 +275,18 @@ def _process_data(self):
300275
_LOGGER.error("Received no heater_central_data for device %s.", self._name)
301276
else:
302277
_LOGGER.debug("Heater_central_data collected from Plugwise API")
303-
if "boiler_state" in heater_central_data:
304-
if heater_central_data["boiler_state"] is not None:
305-
self._boiler_state = heater_central_data["boiler_state"]
306-
if "heating_state" in heater_central_data:
307-
if heater_central_data["heating_state"] is not None:
308-
self._heating_state = heater_central_data["heating_state" ]
309-
if "cooling_state" in heater_central_data:
310-
if heater_central_data["cooling_state"] is not None:
311-
self._cooling_state = heater_central_data["cooling_state"]
278+
if heater_central_data.get("heating_state") is not None:
279+
self._heating_state = heater_central_data["heating_state"]
280+
if heater_central_data.get("cooling_state") is not None:
281+
self._cooling_state = heater_central_data["cooling_state"]
282+
if heater_central_data.get("compressor_state") is not None:
283+
self._compressor_state = heater_central_data["compressor_state"]
312284

313285
if self._schema_status:
314286
self._hvac_mode = HVAC_MODE_AUTO
315-
elif self._heating_state is not None or self._boiler_state is not None:
287+
elif self._heating_state is not None:
316288
self._hvac_mode = HVAC_MODE_HEAT
317-
if self._cooling_state is not None:
289+
if self._compressor_state is not None:
318290
self._hvac_mode = HVAC_MODE_HEAT_COOL
319291

320292
self.async_write_ha_state()

custom_components/plugwise-beta/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
CONF_SOLAR = "solar"
2525
CONF_GAS = "gas"
2626

27-
ATTR_ILLUMINANCE = "illuminance"
2827
CURRENT_HVAC_DHW = "hot_water"
2928
DEVICE_STATE = "device_state"
29+
UNIT_LUMEN = "lm"
3030

3131
SCHEDULE_ON = "true"
3232
SCHEDULE_OFF = "false"

custom_components/plugwise-beta/manifest.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
"domain": "plugwise-beta",
33
"name": "Plugwise Beta for Home Assistant",
44
"documentation": "https://github.com/plugwise/plugwise-beta",
5-
"requirements": ["Plugwise_Smile==0.2.12"],
6-
"dependencies": [],
5+
"requirements": ["Plugwise_Smile==0.2.13"],
76
"codeowners": ["@CoMPaTech","@bouwew"],
87
"config_flow": true
98
}

0 commit comments

Comments
 (0)