Skip to content

Fix setup crash on newer device interface type codes - #145

Open
giuseppe99barchetta wants to merge 2 commits into
HarvsG:masterfrom
giuseppe99barchetta:master
Open

Fix setup crash on newer device interface type codes#145
giuseppe99barchetta wants to merge 2 commits into
HarvsG:masterfrom
giuseppe99barchetta:master

Conversation

@giuseppe99barchetta

Copy link
Copy Markdown

Summary

Fixes a setup crash when GL-iNet routers, such as the BE9300, report newer client interface type codes.

The previous implementation used list(DeviceInterfaceType)[type] to map router API type indexes to enum values. Because UNKNOWN2 has the same enum value as UNKNOWN, Python treats it as an alias and omits it from list(DeviceInterfaceType). This shifts/collapses the index mapping and can raise IndexError when newer routers report higher type codes.

This change adds an explicit interface type mapping tuple that preserves the router API index positions, plus a safe helper that falls back to UNKNOWN for invalid or out-of-range values.

Testing

Tested manually on Home Assistant with a GL-iNet BE9300. The integration setup now completes successfully and the integration works again with this fix.

@HarvsG

HarvsG commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR, will review in a couple of weeks when life is less busy. Feel free to nudge me if I forget

Comment thread custom_components/glinet/router.py Outdated
WIFI_6_GUEST = "6GHz Guest"


DEVICE_INTERFACE_TYPES: tuple[DeviceInterfaceType, ...] = (

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this tuple?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for your time! Hope to see a fix soon, as this issue is currently blocking support for newer GL-iNet routers.

To answer your question:

The GL-iNet API returns a numeric type value (0, 1, 2, ...), so we need a structure where index N always maps to API code N.

Using the enum directly doesn't work because UNKNOWN and UNKNOWN2 both have the value "Unknown". Python treats UNKNOWN2 as an alias of UNKNOWN, so it disappears when iterating over the enum.

That shifts all indices after position 8, causing some API type codes to resolve incorrectly and raise an IndexError.

The tuple simply preserves the original API index mapping, including both positions 5 and 8, even though they currently map to the same enum value.

Let me know if I can clarify anything else! Thanks again for your work!

@HarvsG HarvsG Jun 18, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I don't think we need both this and the strEnum? Can you consolidate into one class with a method that safely handles out of range access?

Also it would be great to log a warning or info for out of range indices that includes some device model and some key dev_info with a note to open an issue so I can continue to expand the class with accurate info over time

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I consolidated the mapping into DeviceInterfaceType by adding from_index() class method.

It now uses __members__, which preserves aliases and declaration order, unlike enum. Invalid, non-numeric, or out-of-range values safely fall back to UNKNOWN.

I also added a warning containing the router model, firmware version, online state, and available dev_info fields, with a request to open an issue.

Let me know!

@shauneccles

Copy link
Copy Markdown

Thanks for this — having read through it, it's a solid fix. Using cls.__members__ to preserve the enum index order (so WIFI_6_GUEST at index 12 resolves correctly while keeping the duplicate member) is neat, and the log-once _log_unsupported with model/firmware context is a nice touch for collecting unknown codes from the field.

One robustness suggestion: the router also returns a self-describing iface string per client ("2.4G", "5G", "6G", "cable", …) alongside the integer type. Resolving from that string first — and falling back to the integer index, as you already do — makes interface labelling resilient to firmware that renumbers the type codes; the integer-index approach silently mislabels if that order ever changes. Removing the duplicate UNKNOWN2 = "Unknown" member outright (rather than relying on __members__ ordering) also closes the list(enum) foot-gun that caused the original bug for good.

I prototyped that approach here if any of it is useful to fold in: master...shauneccles:ha-glinet4-integration:pr/wifi7-crash — no worries either way, your PR fixes the crash; I'm just flagging the iface-string angle as belt-and-braces.

For context, I've opened two follow-ups that build on the crash being fixed: #146 (device-tracker discovery + randomized-MAC handling, #139) and #147 (dynamic WiFi-interface switches, #103). They deliberately leave interface-type resolution to this PR.

shauneccles added a commit to shauneccles/ha-glinet4-integration that referenced this pull request Jun 26, 2026
The old `list(DeviceInterfaceType)[dev_info["type"]]` lookup crashed with an
IndexError on Wi-Fi 7 / MLO clients (newer routers report higher type codes),
and the duplicate UNKNOWN2 enum alias silently shifted every index past 8.

Resolve the interface from the router's self-describing `iface` string first
("2.4G", "5G", "6G", "MLO", "cable", guest variants), falling back to a
bounds-checked integer `type` map. Resolving from the string survives firmware
that renumbers the integer codes; the fallback never raises and unknown
interfaces become UNKNOWN (so the device is still tracked) and are logged once
with model/firmware context for adding support over time.

Supersedes HarvsG#145, whose fix targets router.py (removed by this refactor); folds
in the iface-string angle raised in that PR's review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants