1 """UniFi Protect Platform."""
3 from __future__
import annotations
5 from datetime
import timedelta
8 from aiohttp.client_exceptions
import ServerDisconnectedError
9 from uiprotect.api
import DEVICE_UPDATE_INTERVAL
10 from uiprotect.data
import Bootstrap
11 from uiprotect.data.types
import FirmwareReleaseChannel
12 from uiprotect.exceptions
import ClientError, NotAuthorized
17 from uiprotect.test_util.anonymize
import anonymize_data
23 config_validation
as cv,
24 device_registry
as dr,
35 MIN_REQUIRED_PROTECT_V,
39 from .data
import ProtectData, UFPConfigEntry
40 from .discovery
import async_start_discovery
41 from .migrate
import async_migrate_data
42 from .services
import async_setup_services
44 _async_unifi_mac_from_hass,
45 async_create_api_client,
48 from .views
import ThumbnailProxyView, VideoEventProxyView, VideoProxyView
50 _LOGGER = logging.getLogger(__name__)
52 SCAN_INTERVAL =
timedelta(seconds=DEVICE_UPDATE_INTERVAL)
54 CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
57 "https://www.home-assistant.io/integrations/unifiprotect#software-support"
61 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
62 """Set up the UniFi Protect."""
70 """Set up the UniFi Protect config entries."""
72 _LOGGER.debug(
"Connect to UniFi Protect")
75 await protect.update()
76 except NotAuthorized
as err:
77 retry_key = f
"{entry.entry_id}_auth"
78 retries = hass.data.setdefault(DOMAIN, {}).
get(retry_key, 0)
79 if retries < AUTH_RETRIES:
81 hass.data[DOMAIN][retry_key] = retries
82 raise ConfigEntryNotReady
from err
84 except (TimeoutError, ClientError, ServerDisconnectedError)
as err:
85 raise ConfigEntryNotReady
from err
87 data_service =
ProtectData(hass, protect, SCAN_INTERVAL, entry)
88 bootstrap = protect.bootstrap
89 nvr_info = bootstrap.nvr
90 auth_user = bootstrap.users.get(bootstrap.auth_user_id)
91 if auth_user
and auth_user.cloud_account:
92 ir.async_create_issue(
98 learn_more_url=
"https://www.home-assistant.io/integrations/unifiprotect/#local-user",
99 severity=IssueSeverity.ERROR,
100 translation_key=
"cloud_user",
101 data={
"entry_id": entry.entry_id},
104 if nvr_info.version < MIN_REQUIRED_PROTECT_V:
106 OUTDATED_LOG_MESSAGE,
108 MIN_REQUIRED_PROTECT_V,
112 if entry.unique_id
is None:
113 hass.config_entries.async_update_entry(entry, unique_id=nvr_info.mac)
115 entry.runtime_data = data_service
116 entry.async_on_unload(entry.add_update_listener(_async_options_updated))
117 entry.async_on_unload(
118 hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, data_service.async_stop)
121 if not entry.options.get(CONF_ALLOW_EA,
False)
and (
122 await nvr_info.get_is_prerelease()
123 or nvr_info.release_channel != FirmwareReleaseChannel.RELEASE
125 ir.async_create_issue(
128 "ea_channel_warning",
131 learn_more_url=EARLY_ACCESS_URL,
132 severity=IssueSeverity.WARNING,
133 translation_key=
"ea_channel_warning",
134 translation_placeholders={
"version":
str(nvr_info.version)},
135 data={
"entry_id": entry.entry_id},
140 except Exception
as err:
141 if await nvr_info.get_is_prerelease():
145 ir.async_create_issue(
148 f
"ea_setup_failed_{nvr_info.version}",
151 learn_more_url=
"https://www.home-assistant.io/integrations/unifiprotect#about-unifi-early-access",
152 severity=IssueSeverity.ERROR,
153 translation_key=
"ea_setup_failed",
154 translation_placeholders={
156 "version":
str(nvr_info.version),
159 ir.async_delete_issue(hass, DOMAIN,
"ea_channel_warning")
160 _LOGGER.exception(
"Error setting up UniFi Protect integration")
168 entry: UFPConfigEntry,
169 data_service: ProtectData,
170 bootstrap: Bootstrap,
173 data_service.async_setup()
174 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
181 """Update options."""
182 await hass.config_entries.async_reload(entry.entry_id)
186 """Unload UniFi Protect config entry."""
187 if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
188 await entry.runtime_data.async_stop()
193 hass: HomeAssistant, config_entry: UFPConfigEntry, device_entry: dr.DeviceEntry
195 """Remove ufp config entry from a device."""
198 for connection
in device_entry.connections
199 if connection[0] == dr.CONNECTION_NETWORK_MAC
201 api = config_entry.runtime_data.api
202 if api.bootstrap.nvr.mac
in unifi_macs:
205 if device.is_adopted_by_us
and device.mac
in unifi_macs:
web.Response get(self, web.Request request, str config_key)
None async_setup_services(HomeAssistant hass)
None async_start_discovery(HomeAssistant hass)
None async_migrate_data(HomeAssistant hass, UFPConfigEntry entry, ProtectApiClient protect, Bootstrap bootstrap)
str _async_unifi_mac_from_hass(str mac)
ProtectApiClient async_create_api_client(HomeAssistant hass, UFPConfigEntry entry)
Generator[ProtectAdoptableDeviceModel] async_get_devices(Bootstrap bootstrap, Iterable[ModelType] model_type)
bool async_unload_entry(HomeAssistant hass, UFPConfigEntry entry)
bool async_setup(HomeAssistant hass, ConfigType config)
None _async_setup_entry(HomeAssistant hass, UFPConfigEntry entry, ProtectData data_service, Bootstrap bootstrap)
None _async_options_updated(HomeAssistant hass, UFPConfigEntry entry)
bool async_remove_config_entry_device(HomeAssistant hass, UFPConfigEntry config_entry, dr.DeviceEntry device_entry)
bool async_setup_entry(HomeAssistant hass, UFPConfigEntry entry)