Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Support for OpenTherm Gateway devices."""
2 
3 import asyncio
4 from datetime import date, datetime
5 import logging
6 
7 from pyotgw import OpenThermGateway
8 import pyotgw.vars as gw_vars
9 from serial import SerialException
10 import voluptuous as vol
11 
12 from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
13 from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
14 from homeassistant.const import (
15  ATTR_DATE,
16  ATTR_ID,
17  ATTR_MODE,
18  ATTR_TEMPERATURE,
19  ATTR_TIME,
20  CONF_DEVICE,
21  CONF_ID,
22  CONF_NAME,
23  EVENT_HOMEASSISTANT_STOP,
24  PRECISION_HALVES,
25  PRECISION_TENTHS,
26  PRECISION_WHOLE,
27  Platform,
28 )
29 from homeassistant.core import HomeAssistant, ServiceCall
30 from homeassistant.exceptions import ConfigEntryNotReady
31 from homeassistant.helpers import (
32  config_validation as cv,
33  device_registry as dr,
34  entity_registry as er,
35  issue_registry as ir,
36 )
37 from homeassistant.helpers.dispatcher import async_dispatcher_send
38 from homeassistant.helpers.typing import ConfigType
39 
40 from .const import (
41  ATTR_CH_OVRD,
42  ATTR_DHW_OVRD,
43  ATTR_GW_ID,
44  ATTR_LEVEL,
45  ATTR_TRANSP_ARG,
46  ATTR_TRANSP_CMD,
47  CONF_CLIMATE,
48  CONF_FLOOR_TEMP,
49  CONF_PRECISION,
50  CONNECTION_TIMEOUT,
51  DATA_GATEWAYS,
52  DATA_OPENTHERM_GW,
53  DOMAIN,
54  SERVICE_RESET_GATEWAY,
55  SERVICE_SEND_TRANSP_CMD,
56  SERVICE_SET_CH_OVRD,
57  SERVICE_SET_CLOCK,
58  SERVICE_SET_CONTROL_SETPOINT,
59  SERVICE_SET_GPIO_MODE,
60  SERVICE_SET_HOT_WATER_OVRD,
61  SERVICE_SET_HOT_WATER_SETPOINT,
62  SERVICE_SET_LED_MODE,
63  SERVICE_SET_MAX_MOD,
64  SERVICE_SET_OAT,
65  SERVICE_SET_SB_TEMP,
66  OpenThermDataSource,
67  OpenThermDeviceIdentifier,
68 )
69 
70 _LOGGER = logging.getLogger(__name__)
71 
72 # *_SCHEMA required for deprecated import from configuration.yaml, can be removed in 2025.4.0
73 CLIMATE_SCHEMA = vol.Schema(
74  {
75  vol.Optional(CONF_PRECISION): vol.In(
76  [PRECISION_TENTHS, PRECISION_HALVES, PRECISION_WHOLE]
77  ),
78  vol.Optional(CONF_FLOOR_TEMP, default=False): cv.boolean,
79  }
80 )
81 
82 CONFIG_SCHEMA = vol.Schema(
83  {
84  DOMAIN: cv.schema_with_slug_keys(
85  {
86  vol.Required(CONF_DEVICE): cv.string,
87  vol.Optional(CONF_CLIMATE, default={}): CLIMATE_SCHEMA,
88  vol.Optional(CONF_NAME): cv.string,
89  }
90  )
91  },
92  extra=vol.ALLOW_EXTRA,
93 )
94 
95 PLATFORMS = [
96  Platform.BINARY_SENSOR,
97  Platform.BUTTON,
98  Platform.CLIMATE,
99  Platform.SELECT,
100  Platform.SENSOR,
101  Platform.SWITCH,
102 ]
103 
104 
105 async def options_updated(hass: HomeAssistant, entry: ConfigEntry) -> None:
106  """Handle options update."""
107  gateway = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][entry.data[CONF_ID]]
108  async_dispatcher_send(hass, gateway.options_update_signal, entry)
109 
110 
111 async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
112  """Set up the OpenTherm Gateway component."""
113  if DATA_OPENTHERM_GW not in hass.data:
114  hass.data[DATA_OPENTHERM_GW] = {DATA_GATEWAYS: {}}
115 
116  gateway = OpenThermGatewayHub(hass, config_entry)
117  hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][config_entry.data[CONF_ID]] = gateway
118 
119  # Migration can be removed in 2025.4.0
120  dev_reg = dr.async_get(hass)
121  if (
122  migrate_device := dev_reg.async_get_device(
123  {(DOMAIN, config_entry.data[CONF_ID])}
124  )
125  ) is not None:
126  dev_reg.async_update_device(
127  migrate_device.id,
128  new_identifiers={
129  (
130  DOMAIN,
131  f"{config_entry.data[CONF_ID]}-{OpenThermDeviceIdentifier.GATEWAY}",
132  )
133  },
134  )
135 
136  # Migration can be removed in 2025.4.0
137  ent_reg = er.async_get(hass)
138  if (
139  entity_id := ent_reg.async_get_entity_id(
140  CLIMATE_DOMAIN, DOMAIN, config_entry.data[CONF_ID]
141  )
142  ) is not None:
143  ent_reg.async_update_entity(
144  entity_id,
145  new_unique_id=f"{config_entry.data[CONF_ID]}-{OpenThermDeviceIdentifier.THERMOSTAT}-thermostat_entity",
146  )
147 
148  config_entry.add_update_listener(options_updated)
149 
150  try:
151  async with asyncio.timeout(CONNECTION_TIMEOUT):
152  await gateway.connect_and_subscribe()
153  except (TimeoutError, ConnectionError, SerialException) as ex:
154  await gateway.cleanup()
155  raise ConfigEntryNotReady(
156  f"Could not connect to gateway at {gateway.device_path}: {ex}"
157  ) from ex
158 
159  await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
160 
161  register_services(hass)
162  return True
163 
164 
165 # Deprecated import from configuration.yaml, can be removed in 2025.4.0
166 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
167  """Set up the OpenTherm Gateway component."""
168  if DOMAIN in config:
169  ir.async_create_issue(
170  hass,
171  DOMAIN,
172  "deprecated_import_from_configuration_yaml",
173  breaks_in_ha_version="2025.4.0",
174  is_fixable=False,
175  is_persistent=False,
176  severity=ir.IssueSeverity.WARNING,
177  translation_key="deprecated_import_from_configuration_yaml",
178  )
179  if not hass.config_entries.async_entries(DOMAIN) and DOMAIN in config:
180  conf = config[DOMAIN]
181  for device_id, device_config in conf.items():
182  device_config[CONF_ID] = device_id
183 
184  hass.async_create_task(
185  hass.config_entries.flow.async_init(
186  DOMAIN, context={"source": SOURCE_IMPORT}, data=device_config
187  )
188  )
189  return True
190 
191 
192 def register_services(hass: HomeAssistant) -> None:
193  """Register services for the component."""
194  service_reset_schema = vol.Schema(
195  {
196  vol.Required(ATTR_GW_ID): vol.All(
197  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
198  )
199  }
200  )
201  service_set_central_heating_ovrd_schema = vol.Schema(
202  {
203  vol.Required(ATTR_GW_ID): vol.All(
204  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
205  ),
206  vol.Required(ATTR_CH_OVRD): cv.boolean,
207  }
208  )
209  service_set_clock_schema = vol.Schema(
210  {
211  vol.Required(ATTR_GW_ID): vol.All(
212  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
213  ),
214  vol.Optional(ATTR_DATE, default=date.today): cv.date,
215  vol.Optional(ATTR_TIME, default=lambda: datetime.now().time()): cv.time,
216  }
217  )
218  service_set_control_setpoint_schema = vol.Schema(
219  {
220  vol.Required(ATTR_GW_ID): vol.All(
221  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
222  ),
223  vol.Required(ATTR_TEMPERATURE): vol.All(
224  vol.Coerce(float), vol.Range(min=0, max=90)
225  ),
226  }
227  )
228  service_set_hot_water_setpoint_schema = service_set_control_setpoint_schema
229  service_set_hot_water_ovrd_schema = vol.Schema(
230  {
231  vol.Required(ATTR_GW_ID): vol.All(
232  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
233  ),
234  vol.Required(ATTR_DHW_OVRD): vol.Any(
235  vol.Equal("A"), vol.All(vol.Coerce(int), vol.Range(min=0, max=1))
236  ),
237  }
238  )
239  service_set_gpio_mode_schema = vol.Schema(
240  vol.Any(
241  vol.Schema(
242  {
243  vol.Required(ATTR_GW_ID): vol.All(
244  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
245  ),
246  vol.Required(ATTR_ID): vol.Equal("A"),
247  vol.Required(ATTR_MODE): vol.All(
248  vol.Coerce(int), vol.Range(min=0, max=6)
249  ),
250  }
251  ),
252  vol.Schema(
253  {
254  vol.Required(ATTR_GW_ID): vol.All(
255  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
256  ),
257  vol.Required(ATTR_ID): vol.Equal("B"),
258  vol.Required(ATTR_MODE): vol.All(
259  vol.Coerce(int), vol.Range(min=0, max=7)
260  ),
261  }
262  ),
263  )
264  )
265  service_set_led_mode_schema = vol.Schema(
266  {
267  vol.Required(ATTR_GW_ID): vol.All(
268  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
269  ),
270  vol.Required(ATTR_ID): vol.In("ABCDEF"),
271  vol.Required(ATTR_MODE): vol.In("RXTBOFHWCEMP"),
272  }
273  )
274  service_set_max_mod_schema = vol.Schema(
275  {
276  vol.Required(ATTR_GW_ID): vol.All(
277  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
278  ),
279  vol.Required(ATTR_LEVEL): vol.All(
280  vol.Coerce(int), vol.Range(min=-1, max=100)
281  ),
282  }
283  )
284  service_set_oat_schema = vol.Schema(
285  {
286  vol.Required(ATTR_GW_ID): vol.All(
287  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
288  ),
289  vol.Required(ATTR_TEMPERATURE): vol.All(
290  vol.Coerce(float), vol.Range(min=-40, max=99)
291  ),
292  }
293  )
294  service_set_sb_temp_schema = vol.Schema(
295  {
296  vol.Required(ATTR_GW_ID): vol.All(
297  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
298  ),
299  vol.Required(ATTR_TEMPERATURE): vol.All(
300  vol.Coerce(float), vol.Range(min=0, max=30)
301  ),
302  }
303  )
304  service_send_transp_cmd_schema = vol.Schema(
305  {
306  vol.Required(ATTR_GW_ID): vol.All(
307  cv.string, vol.In(hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS])
308  ),
309  vol.Required(ATTR_TRANSP_CMD): vol.All(
310  cv.string, vol.Length(min=2, max=2), vol.Coerce(str.upper)
311  ),
312  vol.Required(ATTR_TRANSP_ARG): vol.All(
313  cv.string, vol.Length(min=1, max=12)
314  ),
315  }
316  )
317 
318  async def reset_gateway(call: ServiceCall) -> None:
319  """Reset the OpenTherm Gateway."""
320  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
321  mode_rst = gw_vars.OTGW_MODE_RESET
322  await gw_hub.gateway.set_mode(mode_rst)
323 
324  hass.services.async_register(
325  DOMAIN, SERVICE_RESET_GATEWAY, reset_gateway, service_reset_schema
326  )
327 
328  async def set_ch_ovrd(call: ServiceCall) -> None:
329  """Set the central heating override on the OpenTherm Gateway."""
330  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
331  await gw_hub.gateway.set_ch_enable_bit(1 if call.data[ATTR_CH_OVRD] else 0)
332 
333  hass.services.async_register(
334  DOMAIN,
335  SERVICE_SET_CH_OVRD,
336  set_ch_ovrd,
337  service_set_central_heating_ovrd_schema,
338  )
339 
340  async def set_control_setpoint(call: ServiceCall) -> None:
341  """Set the control setpoint on the OpenTherm Gateway."""
342  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
343  await gw_hub.gateway.set_control_setpoint(call.data[ATTR_TEMPERATURE])
344 
345  hass.services.async_register(
346  DOMAIN,
347  SERVICE_SET_CONTROL_SETPOINT,
348  set_control_setpoint,
349  service_set_control_setpoint_schema,
350  )
351 
352  async def set_dhw_ovrd(call: ServiceCall) -> None:
353  """Set the domestic hot water override on the OpenTherm Gateway."""
354  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
355  await gw_hub.gateway.set_hot_water_ovrd(call.data[ATTR_DHW_OVRD])
356 
357  hass.services.async_register(
358  DOMAIN,
359  SERVICE_SET_HOT_WATER_OVRD,
360  set_dhw_ovrd,
361  service_set_hot_water_ovrd_schema,
362  )
363 
364  async def set_dhw_setpoint(call: ServiceCall) -> None:
365  """Set the domestic hot water setpoint on the OpenTherm Gateway."""
366  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
367  await gw_hub.gateway.set_dhw_setpoint(call.data[ATTR_TEMPERATURE])
368 
369  hass.services.async_register(
370  DOMAIN,
371  SERVICE_SET_HOT_WATER_SETPOINT,
372  set_dhw_setpoint,
373  service_set_hot_water_setpoint_schema,
374  )
375 
376  async def set_device_clock(call: ServiceCall) -> None:
377  """Set the clock on the OpenTherm Gateway."""
378  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
379  attr_date = call.data[ATTR_DATE]
380  attr_time = call.data[ATTR_TIME]
381  await gw_hub.gateway.set_clock(datetime.combine(attr_date, attr_time))
382 
383  hass.services.async_register(
384  DOMAIN, SERVICE_SET_CLOCK, set_device_clock, service_set_clock_schema
385  )
386 
387  async def set_gpio_mode(call: ServiceCall) -> None:
388  """Set the OpenTherm Gateway GPIO modes."""
389  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
390  gpio_id = call.data[ATTR_ID]
391  gpio_mode = call.data[ATTR_MODE]
392  await gw_hub.gateway.set_gpio_mode(gpio_id, gpio_mode)
393 
394  hass.services.async_register(
395  DOMAIN, SERVICE_SET_GPIO_MODE, set_gpio_mode, service_set_gpio_mode_schema
396  )
397 
398  async def set_led_mode(call: ServiceCall) -> None:
399  """Set the OpenTherm Gateway LED modes."""
400  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
401  led_id = call.data[ATTR_ID]
402  led_mode = call.data[ATTR_MODE]
403  await gw_hub.gateway.set_led_mode(led_id, led_mode)
404 
405  hass.services.async_register(
406  DOMAIN, SERVICE_SET_LED_MODE, set_led_mode, service_set_led_mode_schema
407  )
408 
409  async def set_max_mod(call: ServiceCall) -> None:
410  """Set the max modulation level."""
411  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
412  level = call.data[ATTR_LEVEL]
413  if level == -1:
414  # Backend only clears setting on non-numeric values.
415  level = "-"
416  await gw_hub.gateway.set_max_relative_mod(level)
417 
418  hass.services.async_register(
419  DOMAIN, SERVICE_SET_MAX_MOD, set_max_mod, service_set_max_mod_schema
420  )
421 
422  async def set_outside_temp(call: ServiceCall) -> None:
423  """Provide the outside temperature to the OpenTherm Gateway."""
424  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
425  await gw_hub.gateway.set_outside_temp(call.data[ATTR_TEMPERATURE])
426 
427  hass.services.async_register(
428  DOMAIN, SERVICE_SET_OAT, set_outside_temp, service_set_oat_schema
429  )
430 
431  async def set_setback_temp(call: ServiceCall) -> None:
432  """Set the OpenTherm Gateway SetBack temperature."""
433  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
434  await gw_hub.gateway.set_setback_temp(call.data[ATTR_TEMPERATURE])
435 
436  hass.services.async_register(
437  DOMAIN, SERVICE_SET_SB_TEMP, set_setback_temp, service_set_sb_temp_schema
438  )
439 
440  async def send_transparent_cmd(call: ServiceCall) -> None:
441  """Send a transparent OpenTherm Gateway command."""
442  gw_hub = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][call.data[ATTR_GW_ID]]
443  transp_cmd = call.data[ATTR_TRANSP_CMD]
444  transp_arg = call.data[ATTR_TRANSP_ARG]
445  await gw_hub.gateway.send_transparent_command(transp_cmd, transp_arg)
446 
447  hass.services.async_register(
448  DOMAIN,
449  SERVICE_SEND_TRANSP_CMD,
450  send_transparent_cmd,
451  service_send_transp_cmd_schema,
452  )
453 
454 
455 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
456  """Cleanup and disconnect from gateway."""
457  unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
458  gateway = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][entry.data[CONF_ID]]
459  await gateway.cleanup()
460  return unload_ok
461 
462 
464  """OpenTherm Gateway hub class."""
465 
466  def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
467  """Initialize the OpenTherm Gateway."""
468  self.hasshass = hass
469  self.device_pathdevice_path = config_entry.data[CONF_DEVICE]
470  self.hub_idhub_id = config_entry.data[CONF_ID]
471  self.namename = config_entry.data[CONF_NAME]
472  self.climate_configclimate_config = config_entry.options
473  self.config_entry_idconfig_entry_id = config_entry.entry_id
474  self.update_signalupdate_signal = f"{DATA_OPENTHERM_GW}_{self.hub_id}_update"
475  self.options_update_signaloptions_update_signal = f"{DATA_OPENTHERM_GW}_{self.hub_id}_options_update"
476  self.gatewaygateway = OpenThermGateway()
477  self.gw_versiongw_version = None
478 
479  async def cleanup(self, event=None) -> None:
480  """Reset overrides on the gateway."""
481  await self.gatewaygateway.set_control_setpoint(0)
482  await self.gatewaygateway.set_max_relative_mod("-")
483  await self.gatewaygateway.disconnect()
484 
485  async def connect_and_subscribe(self) -> None:
486  """Connect to serial device and subscribe report handler."""
487  status = await self.gatewaygateway.connect(self.device_pathdevice_path)
488  if not status:
489  await self.cleanupcleanup()
490  raise ConnectionError
491  version_string = status[OpenThermDataSource.GATEWAY].get(gw_vars.OTGW_ABOUT)
492  self.gw_versiongw_version = version_string[18:] if version_string else None
493  _LOGGER.debug(
494  "Connected to OpenTherm Gateway %s at %s", self.gw_versiongw_version, self.device_pathdevice_path
495  )
496  dev_reg = dr.async_get(self.hasshass)
497  gw_dev = dev_reg.async_get_or_create(
498  config_entry_id=self.config_entry_idconfig_entry_id,
499  identifiers={
500  (DOMAIN, f"{self.hub_id}-{OpenThermDeviceIdentifier.GATEWAY}")
501  },
502  manufacturer="Schelte Bron",
503  model="OpenTherm Gateway",
504  translation_key="gateway_device",
505  sw_version=self.gw_versiongw_version,
506  )
507  if gw_dev.sw_version != self.gw_versiongw_version:
508  dev_reg.async_update_device(gw_dev.id, sw_version=self.gw_versiongw_version)
509 
510  boiler_device = dev_reg.async_get_or_create(
511  config_entry_id=self.config_entry_idconfig_entry_id,
512  identifiers={(DOMAIN, f"{self.hub_id}-{OpenThermDeviceIdentifier.BOILER}")},
513  translation_key="boiler_device",
514  )
515  thermostat_device = dev_reg.async_get_or_create(
516  config_entry_id=self.config_entry_idconfig_entry_id,
517  identifiers={
518  (DOMAIN, f"{self.hub_id}-{OpenThermDeviceIdentifier.THERMOSTAT}")
519  },
520  translation_key="thermostat_device",
521  )
522 
523  self.hasshass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, self.cleanupcleanup)
524 
525  async def handle_report(status):
526  """Handle reports from the OpenTherm Gateway."""
527  _LOGGER.debug("Received report: %s", status)
528  async_dispatcher_send(self.hasshass, self.update_signalupdate_signal, status)
529 
530  dev_reg.async_update_device(
531  boiler_device.id,
532  manufacturer=status[OpenThermDataSource.BOILER].get(
533  gw_vars.DATA_SLAVE_MEMBERID
534  ),
535  model_id=status[OpenThermDataSource.BOILER].get(
536  gw_vars.DATA_SLAVE_PRODUCT_TYPE
537  ),
538  hw_version=status[OpenThermDataSource.BOILER].get(
539  gw_vars.DATA_SLAVE_PRODUCT_VERSION
540  ),
541  sw_version=status[OpenThermDataSource.BOILER].get(
542  gw_vars.DATA_SLAVE_OT_VERSION
543  ),
544  )
545 
546  dev_reg.async_update_device(
547  thermostat_device.id,
548  manufacturer=status[OpenThermDataSource.THERMOSTAT].get(
549  gw_vars.DATA_MASTER_MEMBERID
550  ),
551  model_id=status[OpenThermDataSource.THERMOSTAT].get(
552  gw_vars.DATA_MASTER_PRODUCT_TYPE
553  ),
554  hw_version=status[OpenThermDataSource.THERMOSTAT].get(
555  gw_vars.DATA_MASTER_PRODUCT_VERSION
556  ),
557  sw_version=status[OpenThermDataSource.THERMOSTAT].get(
558  gw_vars.DATA_MASTER_OT_VERSION
559  ),
560  )
561 
562  self.gatewaygateway.subscribe(handle_report)
563 
564  @property
565  def connected(self):
566  """Report whether or not we are connected to the gateway."""
567  return self.gatewaygateway.connection.connected
None __init__(self, HomeAssistant hass, ConfigEntry config_entry)
Definition: __init__.py:466
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
Callable[[], None] subscribe(HomeAssistant hass, str topic, MessageCallbackType msg_callback, int qos=DEFAULT_QOS, str encoding="utf-8")
Definition: client.py:247
OpenThermSelectLEDMode|None set_led_mode(str led_id, OpenThermGatewayHub gw_hub, str mode)
Definition: select.py:124
OpenThermSelectGPIOMode|None set_gpio_mode(str gpio_id, OpenThermGatewayHub gw_hub, str mode)
Definition: select.py:110
None register_services(HomeAssistant hass)
Definition: __init__.py:192
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:455
bool async_setup_entry(HomeAssistant hass, ConfigEntry config_entry)
Definition: __init__.py:111
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:166
None options_updated(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:105
bool time(HomeAssistant hass, dt_time|str|None before=None, dt_time|str|None after=None, str|Container[str]|None weekday=None)
Definition: condition.py:802
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193