Fritz device_trackers for non mesh devices (#67006)

pull/67101/head
Simone Chemelli 2022-02-23 01:35:48 +01:00 committed by GitHub
parent b8590fde40
commit c76d2c4283
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 38 deletions

View File

@ -39,6 +39,8 @@ from homeassistant.helpers.entity import DeviceInfo
from homeassistant.util import dt as dt_util
from .const import (
CONF_OLD_DISCOVERY,
DEFAULT_CONF_OLD_DISCOVERY,
DEFAULT_DEVICE_NAME,
DEFAULT_HOST,
DEFAULT_PORT,
@ -325,27 +327,33 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
"""Wrap up FritzboxTools class scan."""
await self.hass.async_add_executor_job(self.scan_devices, now)
def manage_device_info(
self, dev_info: Device, dev_mac: str, consider_home: bool
) -> bool:
"""Update device lists."""
_LOGGER.debug("Client dev_info: %s", dev_info)
if dev_mac in self._devices:
self._devices[dev_mac].update(dev_info, consider_home)
return False
device = FritzDevice(dev_mac, dev_info.name)
device.update(dev_info, consider_home)
self._devices[dev_mac] = device
return True
def send_signal_device_update(self, new_device: bool) -> None:
"""Signal device data updated."""
dispatcher_send(self.hass, self.signal_device_update)
if new_device:
dispatcher_send(self.hass, self.signal_device_new)
def scan_devices(self, now: datetime | None = None) -> None:
"""Scan for new devices and return a list of found device ids."""
_LOGGER.debug("Checking host info for FRITZ!Box device %s", self.host)
self._update_available, self._latest_firmware = self._update_device_info()
topology: dict = {}
if (
"Hosts1" not in self.connection.services
or "X_AVM-DE_GetMeshListPath"
not in self.connection.services["Hosts1"].actions
):
self.mesh_role = MeshRoles.NONE
else:
try:
topology = self.fritz_hosts.get_mesh_topology()
except FritzActionError:
self.mesh_role = MeshRoles.SLAVE
# Avoid duplicating device trackers
return
_LOGGER.debug("Checking devices for FRITZ!Box device %s", self.host)
_default_consider_home = DEFAULT_CONSIDER_HOME.total_seconds()
if self._options:
@ -371,6 +379,32 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
wan_access=None,
)
if (
"Hosts1" not in self.connection.services
or "X_AVM-DE_GetMeshListPath"
not in self.connection.services["Hosts1"].actions
) or (
self._options
and self._options.get(CONF_OLD_DISCOVERY, DEFAULT_CONF_OLD_DISCOVERY)
):
_LOGGER.debug(
"Using old hosts discovery method. (Mesh not supported or user option)"
)
self.mesh_role = MeshRoles.NONE
for mac, info in hosts.items():
if self.manage_device_info(info, mac, consider_home):
new_device = True
self.send_signal_device_update(new_device)
return
try:
if not (topology := self.fritz_hosts.get_mesh_topology()):
raise Exception("Mesh supported but empty topology reported")
except FritzActionError:
self.mesh_role = MeshRoles.SLAVE
# Avoid duplicating device trackers
return
mesh_intf = {}
# first get all meshed devices
for node in topology.get("nodes", []):
@ -414,19 +448,11 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
dev_info.connected_to = intf["device"]
dev_info.connection_type = intf["type"]
dev_info.ssid = intf.get("ssid")
_LOGGER.debug("Client dev_info: %s", dev_info)
if dev_mac in self._devices:
self._devices[dev_mac].update(dev_info, consider_home)
else:
device = FritzDevice(dev_mac, dev_info.name)
device.update(dev_info, consider_home)
self._devices[dev_mac] = device
if self.manage_device_info(dev_info, dev_mac, consider_home):
new_device = True
dispatcher_send(self.hass, self.signal_device_update)
if new_device:
dispatcher_send(self.hass, self.signal_device_new)
self.send_signal_device_update(new_device)
async def async_trigger_firmware_update(self) -> bool:
"""Trigger firmware update."""

View File

@ -21,6 +21,8 @@ from homeassistant.data_entry_flow import FlowResult
from .common import AvmWrapper
from .const import (
CONF_OLD_DISCOVERY,
DEFAULT_CONF_OLD_DISCOVERY,
DEFAULT_HOST,
DEFAULT_PORT,
DOMAIN,
@ -107,6 +109,7 @@ class FritzBoxToolsFlowHandler(ConfigFlow, domain=DOMAIN):
},
options={
CONF_CONSIDER_HOME: DEFAULT_CONSIDER_HOME.total_seconds(),
CONF_OLD_DISCOVERY: DEFAULT_CONF_OLD_DISCOVERY,
},
)
@ -296,6 +299,12 @@ class FritzBoxToolsOptionsFlowHandler(OptionsFlow):
CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME.total_seconds()
),
): vol.All(vol.Coerce(int), vol.Clamp(min=0, max=900)),
vol.Optional(
CONF_OLD_DISCOVERY,
default=self.config_entry.options.get(
CONF_OLD_DISCOVERY, DEFAULT_CONF_OLD_DISCOVERY
),
): bool,
}
)
return self.async_show_form(step_id="init", data_schema=data_schema)

View File

@ -32,6 +32,9 @@ PLATFORMS = [
Platform.SWITCH,
]
CONF_OLD_DISCOVERY = "old_discovery"
DEFAULT_CONF_OLD_DISCOVERY = False
DATA_FRITZ = "fritz_data"
DSL_CONNECTION: Literal["dsl"] = "dsl"

View File

@ -45,7 +45,8 @@
"step": {
"init": {
"data": {
"consider_home": "Seconds to consider a device at 'home'"
"consider_home": "Seconds to consider a device at 'home'",
"old_discovery": "Enable old discovery method"
}
}
}

View File

@ -9,7 +9,6 @@
"already_configured": "Device is already configured",
"already_in_progress": "Configuration flow is already in progress",
"cannot_connect": "Failed to connect",
"connection_error": "Failed to connect",
"invalid_auth": "Invalid authentication"
},
"flow_title": "{name}",
@ -30,16 +29,6 @@
"description": "Update FRITZ!Box Tools credentials for: {host}.\n\nFRITZ!Box Tools is unable to log in to your FRITZ!Box.",
"title": "Updating FRITZ!Box Tools - credentials"
},
"start_config": {
"data": {
"host": "Host",
"password": "Password",
"port": "Port",
"username": "Username"
},
"description": "Setup FRITZ!Box Tools to control your FRITZ!Box.\nMinimum needed: username, password.",
"title": "Setup FRITZ!Box Tools - mandatory"
},
"user": {
"data": {
"host": "Host",
@ -56,7 +45,8 @@
"step": {
"init": {
"data": {
"consider_home": "Seconds to consider a device at 'home'"
"consider_home": "Seconds to consider a device at 'home'",
"old_discovery": "Enable old discovery method"
}
}
}