1 """The Control4 integration."""
3 from __future__
import annotations
8 from aiohttp
import client_exceptions
9 from pyControl4.account
import C4Account
10 from pyControl4.director
import C4Director
11 from pyControl4.error_handling
import BadCredentials
30 CONF_CONTROLLER_UNIQUE_ID,
32 CONF_DIRECTOR_ALL_ITEMS,
34 CONF_DIRECTOR_SW_VERSION,
35 CONF_UI_CONFIGURATION,
36 DEFAULT_SCAN_INTERVAL,
40 _LOGGER = logging.getLogger(__name__)
42 PLATFORMS = [Platform.LIGHT, Platform.MEDIA_PLAYER]
46 """Call C4 API function and retry on failure."""
48 for i
in range(API_RETRY_TIMES):
50 return await func(*func_args)
51 except client_exceptions.ClientError
as exception:
52 _LOGGER.error(
"Error connecting to Control4 account API: %s", exception)
53 if i == API_RETRY_TIMES - 1:
58 """Set up Control4 from a config entry."""
59 hass.data.setdefault(DOMAIN, {})
60 entry_data = hass.data[DOMAIN].setdefault(entry.entry_id, {})
61 account_session = aiohttp_client.async_get_clientsession(hass)
64 account = C4Account(config[CONF_USERNAME], config[CONF_PASSWORD], account_session)
66 await account.getAccountBearerToken()
67 except client_exceptions.ClientError
as exception:
68 _LOGGER.error(
"Error connecting to Control4 account API: %s", exception)
69 raise ConfigEntryNotReady
from exception
70 except BadCredentials
as exception:
73 "Error authenticating with Control4 account API, incorrect username or"
79 entry_data[CONF_ACCOUNT] = account
81 controller_unique_id = config[CONF_CONTROLLER_UNIQUE_ID]
82 entry_data[CONF_CONTROLLER_UNIQUE_ID] = controller_unique_id
85 account.getDirectorBearerToken, controller_unique_id
88 director_session = aiohttp_client.async_get_clientsession(hass, verify_ssl=
False)
89 director = C4Director(
90 config[CONF_HOST], director_token_dict[CONF_TOKEN], director_session
92 entry_data[CONF_DIRECTOR] = director
94 controller_href = (await
call_c4_api_retry(account.getAccountControllers))[
"href"]
96 account.getControllerOSVersion, controller_href
99 _, model, mac_address = controller_unique_id.split(
"_", 3)
100 entry_data[CONF_DIRECTOR_MODEL] = model.upper()
102 device_registry = dr.async_get(hass)
103 device_registry.async_get_or_create(
104 config_entry_id=entry.entry_id,
105 identifiers={(DOMAIN, controller_unique_id)},
106 connections={(dr.CONNECTION_NETWORK_MAC, mac_address)},
107 manufacturer=
"Control4",
108 name=controller_unique_id,
109 model=entry_data[CONF_DIRECTOR_MODEL],
110 sw_version=entry_data[CONF_DIRECTOR_SW_VERSION],
114 director_all_items = await director.getAllItemInfo()
115 director_all_items = json.loads(director_all_items)
116 entry_data[CONF_DIRECTOR_ALL_ITEMS] = director_all_items
119 entry_data[CONF_UI_CONFIGURATION] =
None
120 if int(entry_data[CONF_DIRECTOR_SW_VERSION].split(
".")[0]) >= 3:
121 entry_data[CONF_UI_CONFIGURATION] = json.loads(
122 await director.getUiConfiguration()
126 entry_data[CONF_SCAN_INTERVAL] = entry.options.get(
127 CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
130 entry_data[CONF_CONFIG_LISTENER] = entry.add_update_listener(update_listener)
132 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
138 """Update when config_entry options update."""
139 _LOGGER.debug(
"Config entry was updated, rerunning setup")
140 await hass.config_entries.async_reload(config_entry.entry_id)
144 """Unload a config entry."""
145 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
147 hass.data[DOMAIN][entry.entry_id][CONF_CONFIG_LISTENER]()
149 hass.data[DOMAIN].pop(entry.entry_id)
150 _LOGGER.debug(
"Unloaded entry for %s", entry.entry_id)
156 """Return a list of all Control4 items with the specified category."""
157 director_all_items = hass.data[DOMAIN][entry.entry_id][CONF_DIRECTOR_ALL_ITEMS]
160 for item
in director_all_items
161 if "categories" in item
and category
in item[
"categories"]
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
def call_c4_api_retry(func, *func_args)
None update_listener(HomeAssistant hass, ConfigEntry config_entry)
def get_items_of_category(HomeAssistant hass, ConfigEntry entry, str category)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)