Skip to content

Commit

Permalink
Merge device info
Browse files Browse the repository at this point in the history
When getting connected devices merge the device info retrieved by each
method. When the router is running in AP mode the neighbour check does
not return IP addresses for the devices it returns while the wl and arp
checks do seem to. However, because the neighbour check happens last the
Device entries that it produces overwrite those produced for the same
MACs by the previous two checks.

This change makes the merging of those sets also attempt to merge the
fields of the Device. One risk here is that the new device and old
device both have valid but different values for a field. This is
considered an error so I just log and carry on. This has the effect of
making the values in the first device seen for a MAC take precedence
while previously it would have been the last device that would have. I
think this difference is a low risk as either way it's unexpected
behaviour if they don't match up.
  • Loading branch information
robyoung committed May 19, 2022
1 parent 0409d74 commit 770a612
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions aioasuswrt/asuswrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,14 +426,14 @@ async def async_get_connected_devices(self, use_cache=True):

devices = {}
dev = await self.async_get_wl()
devices.update(dev)
merge_devices(devices, dev)
dev = await self.async_get_arp()
devices.update(dev)
merge_devices(devices, dev)
dev = await self.async_get_neigh(devices)
devices.update(dev)
merge_devices(devices, dev)
if not self.mode == "ap":
dev = await self.async_get_leases(devices)
devices.update(dev)
merge_devices(devices, dev)

filter_devices = await self.async_filter_dev_list(devices)
ret_devices = {
Expand Down Expand Up @@ -587,3 +587,31 @@ async def async_get_temperature(self):
@property
def is_connected(self):
return self.connection.is_connected


def merge_devices(devices, new_devices):
"""Merge a new list of devices into an existing list
This merge fills in any null values in the base list if the device
in the new list has values for them."""
for mac, device in new_devices.items():
if mac not in devices:
devices[mac] = device
elif any(val is None for val in devices[mac]):
mismatches = [
f"{Device._fields[field]}({val1} != {val2})"
for field, (val1, val2) in enumerate(zip(devices[mac], device))
if val1 and val2 and val1 != val2
]
if mismatches:
# if filled values do not match between devices from found from different sources
# then something is wrong. Log a warning and carry on.
_LOGGER.warning(
"Mismatched values for device {}: {}".format(
mac, ", ".join(mismatches)
)
)
else:
devices[mac] = Device(
*(val1 or val2 for val1, val2 in zip(devices[mac], device))
)

0 comments on commit 770a612

Please sign in to comment.