Discover WiFi-interface switches without a reload (#103) - #147
Open
shauneccles wants to merge 6 commits into
Open
Discover WiFi-interface switches without a reload (#103)#147shauneccles wants to merge 6 commits into
shauneccles wants to merge 6 commits into
Conversation
update_device_trackers() skipped any client that had neither a name nor an alias. Many IoT devices (bulbs, sensors) and some phones report blank names, so most of the network was silently untracked. Track every connected client instead; ClientDevInfo.update() already falls back to a MAC-derived name for unnamed devices. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sG#139) Two device-tracker fixes: 1. New devices appeared only after a reload. update_device_trackers() fires signal_device_new when it discovers a previously unseen client, but async_setup_entry called update_router() once at setup and never subscribed to that signal. Connect update_router() to signal_device_new (via entry.async_on_unload) so new devices get entities on the 30s poll. 2. hostname/ip_address/mac_address were cached_property values snapshotted in __init__, so a device's reported IP stayed frozen at entity-creation time. Read them (and the name) live from the underlying ClientDevInfo, which async_on_demand_update refreshes each poll. Also set should_poll=False, since updates are pushed via the dispatcher (the old value of True contradicted its own "No polling needed" docstring). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Log how many clients connected_clients returns (and their MACs), and each newly discovered tracked device. This makes "missing devices" reports (e.g. issue HarvsG#139) diagnosable from a debug log without external probing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
router.setup() registered a SCAN_INTERVAL poller via async_track_time_interval but never stored its unsub, so each config-entry reload leaked another timer that kept polling the router forever (observed as multiple concurrent pollers after a few reloads). Register the unsub with entry.async_on_unload so it is cancelled on unload/reload. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removing the name filter means every connected client is tracked, including phones that use MAC randomization. Those present a fresh address on each (re)connection, so without handling they pile up as stale trackers. - Detect locally-administered (randomized) MACs from the address itself (is_randomized_mac in utils.py); HA core provides no helper for this. - Expose a `mac_randomized` attribute on every tracker. - Add a `track_randomized_mac` option (options flow): "enabled" tracks them with the entity enabled by default, "disabled" registers them disabled by default (the default), "ignore" skips creating the entity entirely. - entity_registry_enabled_default composes with HA's ScannerEntity heuristic: randomized MACs honour the option; every other client defers to core, which enables a tracker only when its MAC maps to a known device. - Register the previously-unwired options update listener so option changes reload the entry and take effect. Covered by unit tests for is_randomized_mac. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
WiFi access-point switches were created only in switch.async_setup_entry, so an interface enabled after setup (e.g. MLO, or a guest/IoT SSID toggled on later) never got a switch until the integration was reloaded. Add a signal_iface_new dispatcher that update_wifi_ifaces_state() fires when it first sees a new interface name, and have the switch platform subscribe to it (mirroring the device_tracker pattern) so new WiFi interfaces get switches on the regular poll. Also replaces a ternary with `or` in WifiApSwitch.name to keep the file ruff-clean (pre-existing FURB110). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Open
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #103.
WiFi access-point switches were only created in
switch.async_setup_entry, so an interface enabled after setup (e.g. MLO, or a guest/IoT SSID toggled on later) never got a switch until the integration was reloaded.Change
Adds a
signal_iface_newdispatcher thatupdate_wifi_ifaces_state()fires when it first sees a new interface name, and subscribes the switch platform to it (mirroring the device-tracker discovery pattern). New WiFi interfaces now get switches on the regular poll. Also replaces a ternary withorinWifiApSwitch.nameto keep the file ruff-clean.Stacked on #146
This is stacked on #146 (#139 device-tracking). Until #146 merges, this PR's diff also shows #146's commits — please review/merge #146 first, after which only the switch commit remains here.
Testing
Validated live on a GL-iNet MT6000: renaming/enabling a WiFi interface relabels its existing switch (keyed on the stable interface name) without churn. The new-interface dispatcher mirrors the device-tracker discovery path that was confirmed live with a phone join; the MT6000 (Wi-Fi 6) has no spare interface slot to create a brand-new
ifacename, so the MLO trigger is validated by analogy to that identical pattern.🤖 Generated with Claude Code