Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The Enphase Envoy integration."""
2 
3 from __future__ import annotations
4 
5 import httpx
6 from pyenphase import Envoy
7 
8 from homeassistant.config_entries import ConfigEntry
9 from homeassistant.const import CONF_HOST
10 from homeassistant.core import HomeAssistant
11 from homeassistant.exceptions import ConfigEntryNotReady
12 from homeassistant.helpers import device_registry as dr
13 from homeassistant.helpers.httpx_client import get_async_client
14 
15 from .const import (
16  DOMAIN,
17  OPTION_DISABLE_KEEP_ALIVE,
18  OPTION_DISABLE_KEEP_ALIVE_DEFAULT_VALUE,
19  PLATFORMS,
20 )
21 from .coordinator import EnphaseConfigEntry, EnphaseUpdateCoordinator
22 
23 
24 async def async_setup_entry(hass: HomeAssistant, entry: EnphaseConfigEntry) -> bool:
25  """Set up Enphase Envoy from a config entry."""
26 
27  host = entry.data[CONF_HOST]
28  options = entry.options
29  envoy = (
30  Envoy(
31  host,
32  httpx.AsyncClient(
33  verify=False, limits=httpx.Limits(max_keepalive_connections=0)
34  ),
35  )
36  if options.get(
37  OPTION_DISABLE_KEEP_ALIVE, OPTION_DISABLE_KEEP_ALIVE_DEFAULT_VALUE
38  )
39  else Envoy(host, get_async_client(hass, verify_ssl=False))
40  )
41  coordinator = EnphaseUpdateCoordinator(hass, envoy, entry)
42 
43  await coordinator.async_config_entry_first_refresh()
44  if not entry.unique_id:
45  hass.config_entries.async_update_entry(entry, unique_id=envoy.serial_number)
46 
47  if entry.unique_id != envoy.serial_number:
48  # If the serial number of the device does not match the unique_id
49  # of the config entry, it likely means the DHCP lease has expired
50  # and the device has been assigned a new IP address. We need to
51  # wait for the next discovery to find the device at its new address
52  # and update the config entry so we do not mix up devices.
53  raise ConfigEntryNotReady(
54  f"Unexpected device found at {host}; expected {entry.unique_id}, "
55  f"found {envoy.serial_number}"
56  )
57 
58  entry.runtime_data = coordinator
59 
60  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
61 
62  # Reload entry when it is updated.
63  entry.async_on_unload(entry.add_update_listener(async_reload_entry))
64 
65  return True
66 
67 
68 async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
69  """Reload the config entry when it changed."""
70  await hass.config_entries.async_reload(entry.entry_id)
71 
72 
73 async def async_unload_entry(hass: HomeAssistant, entry: EnphaseConfigEntry) -> bool:
74  """Unload a config entry."""
75  coordinator: EnphaseUpdateCoordinator = entry.runtime_data
76  coordinator.async_cancel_token_refresh()
77  return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
78 
79 
81  hass: HomeAssistant, config_entry: EnphaseConfigEntry, device_entry: dr.DeviceEntry
82 ) -> bool:
83  """Remove an enphase_envoy config entry from a device."""
84  dev_ids = {dev_id[1] for dev_id in device_entry.identifiers if dev_id[0] == DOMAIN}
85  coordinator = config_entry.runtime_data
86  envoy_data = coordinator.envoy.data
87  envoy_serial_num = config_entry.unique_id
88  if envoy_serial_num in dev_ids:
89  return False
90  if envoy_data:
91  if envoy_data.inverters:
92  for inverter in envoy_data.inverters:
93  if str(inverter) in dev_ids:
94  return False
95  if envoy_data.encharge_inventory:
96  for encharge in envoy_data.encharge_inventory:
97  if str(encharge) in dev_ids:
98  return False
99  if envoy_data.enpower:
100  if str(envoy_data.enpower.serial_number) in dev_ids:
101  return False
102  return True
bool async_setup_entry(HomeAssistant hass, EnphaseConfigEntry entry)
Definition: __init__.py:24
bool async_unload_entry(HomeAssistant hass, EnphaseConfigEntry entry)
Definition: __init__.py:73
bool async_remove_config_entry_device(HomeAssistant hass, EnphaseConfigEntry config_entry, dr.DeviceEntry device_entry)
Definition: __init__.py:82
None async_reload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:68
httpx.AsyncClient get_async_client(HomeAssistant hass, bool verify_ssl=True)
Definition: httpx_client.py:41