Fix "internet access" switch for Fritz connected device without known IP address (#65190)

* fix get wan access

* small improvement
- default wan_access to None
- test if dev_info.ip_address is not empty
This commit is contained in:
Michael 2022-01-30 22:22:32 +01:00 committed by Paulus Schoutsen
parent 14c969ef6d
commit d6527953c3
2 changed files with 24 additions and 11 deletions

View File

@ -107,7 +107,7 @@ class Device:
ip_address: str ip_address: str
name: str name: str
ssid: str | None ssid: str | None
wan_access: bool = True wan_access: bool | None = None
class Interface(TypedDict): class Interface(TypedDict):
@ -277,6 +277,14 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
) )
return bool(version), version return bool(version), version
def _get_wan_access(self, ip_address: str) -> bool | None:
"""Get WAN access rule for given IP address."""
return not self.connection.call_action(
"X_AVM-DE_HostFilter:1",
"GetWANAccessByIP",
NewIPv4Address=ip_address,
).get("NewDisallow")
async def async_scan_devices(self, now: datetime | None = None) -> None: async def async_scan_devices(self, now: datetime | None = None) -> None:
"""Wrap up FritzboxTools class scan.""" """Wrap up FritzboxTools class scan."""
await self.hass.async_add_executor_job(self.scan_devices, now) await self.hass.async_add_executor_job(self.scan_devices, now)
@ -315,7 +323,7 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
connection_type="", connection_type="",
ip_address=host["ip"], ip_address=host["ip"],
ssid=None, ssid=None,
wan_access=False, wan_access=None,
) )
mesh_intf = {} mesh_intf = {}
@ -352,12 +360,10 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
for link in interf["node_links"]: for link in interf["node_links"]:
intf = mesh_intf.get(link["node_interface_1_uid"]) intf = mesh_intf.get(link["node_interface_1_uid"])
if intf is not None: if intf is not None:
if intf["op_mode"] != "AP_GUEST": if intf["op_mode"] != "AP_GUEST" and dev_info.ip_address:
dev_info.wan_access = not self.connection.call_action( dev_info.wan_access = self._get_wan_access(
"X_AVM-DE_HostFilter:1", dev_info.ip_address
"GetWANAccessByIP", )
NewIPv4Address=dev_info.ip_address,
).get("NewDisallow")
dev_info.connected_to = intf["device"] dev_info.connected_to = intf["device"]
dev_info.connection_type = intf["type"] dev_info.connection_type = intf["type"]
@ -762,7 +768,7 @@ class FritzDevice:
self._mac = mac self._mac = mac
self._name = name self._name = name
self._ssid: str | None = None self._ssid: str | None = None
self._wan_access = False self._wan_access: bool | None = False
def update(self, dev_info: Device, consider_home: float) -> None: def update(self, dev_info: Device, consider_home: float) -> None:
"""Update device info.""" """Update device info."""
@ -830,7 +836,7 @@ class FritzDevice:
return self._ssid return self._ssid
@property @property
def wan_access(self) -> bool: def wan_access(self) -> bool | None:
"""Return device wan access.""" """Return device wan access."""
return self._wan_access return self._wan_access

View File

@ -477,10 +477,17 @@ class FritzBoxProfileSwitch(FritzDeviceBase, SwitchEntity):
self._attr_entity_category = EntityCategory.CONFIG self._attr_entity_category = EntityCategory.CONFIG
@property @property
def is_on(self) -> bool: def is_on(self) -> bool | None:
"""Switch status.""" """Switch status."""
return self._avm_wrapper.devices[self._mac].wan_access return self._avm_wrapper.devices[self._mac].wan_access
@property
def available(self) -> bool:
"""Return availability of the switch."""
if self._avm_wrapper.devices[self._mac].wan_access is None:
return False
return super().available
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return the device information.""" """Return the device information."""