1 """Support for Netgear routers."""
3 from __future__
import annotations
5 from datetime
import timedelta
19 KEY_COORDINATOR_FIRMWARE,
21 KEY_COORDINATOR_SPEED,
22 KEY_COORDINATOR_TRAFFIC,
27 from .errors
import CannotLoginException
28 from .router
import NetgearRouter
30 _LOGGER = logging.getLogger(__name__)
38 """Set up Netgear component."""
41 if not await router.async_setup():
42 raise ConfigEntryNotReady
43 except CannotLoginException
as ex:
44 raise ConfigEntryNotReady
from ex
46 port = entry.data.get(CONF_PORT)
47 ssl = entry.data.get(CONF_SSL)
48 if port != router.port
or ssl != router.ssl:
49 data = {**entry.data, CONF_PORT: router.port, CONF_SSL: router.ssl}
50 hass.config_entries.async_update_entry(entry, data=data)
53 "Netgear port-SSL combination updated from (%i, %r) to (%i, %r), "
54 "this should only occur after a firmware update"
62 hass.data.setdefault(DOMAIN, {})
64 entry.async_on_unload(entry.add_update_listener(update_listener))
66 async
def async_update_devices() -> bool:
67 """Fetch data from the router."""
68 if router.track_devices:
69 return await router.async_update_device_trackers()
72 async
def async_update_traffic_meter() -> dict[str, Any] | None:
73 """Fetch data from the router."""
74 return await router.async_get_traffic_meter()
76 async
def async_update_speed_test() -> dict[str, Any] | None:
77 """Fetch data from the router."""
78 return await router.async_get_speed_test()
80 async
def async_check_firmware() -> dict[str, Any] | None:
81 """Check for new firmware of the router."""
82 return await router.async_check_new_firmware()
84 async
def async_update_utilization() -> dict[str, Any] | None:
85 """Fetch data from the router."""
86 return await router.async_get_utilization()
88 async
def async_check_link_status() -> dict[str, Any] | None:
89 """Fetch data from the router."""
90 return await router.async_get_link_status()
97 name=f
"{router.device_name} Devices",
98 update_method=async_update_devices,
99 update_interval=SCAN_INTERVAL,
105 name=f
"{router.device_name} Traffic meter",
106 update_method=async_update_traffic_meter,
107 update_interval=SCAN_INTERVAL,
113 name=f
"{router.device_name} Speed test",
114 update_method=async_update_speed_test,
115 update_interval=SPEED_TEST_INTERVAL,
121 name=f
"{router.device_name} Firmware",
122 update_method=async_check_firmware,
123 update_interval=SCAN_INTERVAL_FIRMWARE,
129 name=f
"{router.device_name} Utilization",
130 update_method=async_update_utilization,
131 update_interval=SCAN_INTERVAL,
137 name=f
"{router.device_name} Ethernet Link Status",
138 update_method=async_check_link_status,
139 update_interval=SCAN_INTERVAL,
142 if router.track_devices:
143 await coordinator.async_config_entry_first_refresh()
144 await coordinator_traffic_meter.async_config_entry_first_refresh()
145 await coordinator_firmware.async_config_entry_first_refresh()
146 await coordinator_utilization.async_config_entry_first_refresh()
147 await coordinator_link.async_config_entry_first_refresh()
149 hass.data[DOMAIN][entry.entry_id] = {
151 KEY_COORDINATOR: coordinator,
152 KEY_COORDINATOR_TRAFFIC: coordinator_traffic_meter,
153 KEY_COORDINATOR_SPEED: coordinator_speed_test,
154 KEY_COORDINATOR_FIRMWARE: coordinator_firmware,
155 KEY_COORDINATOR_UTIL: coordinator_utilization,
156 KEY_COORDINATOR_LINK: coordinator_link,
159 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
165 """Unload a config entry."""
166 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
168 router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER]
171 hass.data[DOMAIN].pop(entry.entry_id)
172 if not hass.data[DOMAIN]:
173 hass.data.pop(DOMAIN)
175 if not router.track_devices:
178 device_registry = dr.async_get(hass)
179 devices = dr.async_entries_for_config_entry(device_registry, entry.entry_id)
180 for device_entry
in devices:
181 if device_entry.via_device_id
is None:
182 router_id = device_entry.id
184 device_registry.async_update_device(
185 device_entry.id, remove_config_entry_id=entry.entry_id
188 entity_registry = er.async_get(hass)
189 entries = er.async_entries_for_config_entry(entity_registry, entry.entry_id)
190 for entity_entry
in entries:
191 if entity_entry.device_id
is not router_id:
192 entity_registry.async_remove(entity_entry.entity_id)
198 """Handle options update."""
199 await hass.config_entries.async_reload(config_entry.entry_id)
203 hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry
205 """Remove a device from a config entry."""
206 router = hass.data[DOMAIN][config_entry.entry_id][KEY_ROUTER]
209 for connection
in device_entry.connections:
210 if connection[0] == dr.CONNECTION_NETWORK_MAC:
211 device_mac = connection[1]
214 if device_mac
is None:
217 if device_mac
not in router.devices:
220 return not router.devices[device_mac][
"active"]
None update_listener(HomeAssistant hass, ConfigEntry config_entry)
bool async_remove_config_entry_device(HomeAssistant hass, ConfigEntry config_entry, dr.DeviceEntry device_entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)