The collector keyed ports by their UniFi name, so when two ports shared a name, the later one silently replaced the earlier. The 24-port switch showed 25 ports because ports 13 and 14 have the same name. A repeated name is now kept as <name> (Port N).
Port names are re-read from UniFi every poll, so a rename there shows up in Gandalf on the next cycle. Traffic rates are now matched to the previous poll by port number instead of name, so a renamed port no longer loses its rates for a cycle.
The bond-matching problem described in #8 doesn't occur today: every port on the aggregation switch already resolves its neighbor. What was missing is module information. UniFi reports it, but Gandalf discarded it.
Collected per cage: whether a module is present, its type (DAC or optic), vendor, part, serial and fault flags. DOM readings (RX/TX power, temperature, voltage, bias) are collected when the module reports them. Copper DACs don't.
Fault flags: switches and the UDM spell them differently, and both spellings are read.
Faceplate: empty cages, optics (LC sockets), DACs (cable boot) and unidentified modules are drawn differently, so an empty cage no longer looks like a module with no link. A faulted module is outlined in red.
Port panel: a new SFP Module section shows type, part, serial, faults and readings, with power bars.
DAC cable ends: both ends of a DAC report the cable's serial, so a DAC seen on two ports links to its other end.
Testing
New tests cover duplicate names, renames keeping their rates, module parsing (empty, optic, DAC by compliance or part number, unidentified, UDM fault spelling, unparseable readings) and DAC end pairing. All 233 tests, flake8 and eslint (no errors) pass.
Checked in a local preview with sample data shaped like the controller's real responses, on desktop and at 390px wide. There's no horizontal scroll, and the only console error is the avatar 404 the preview always has.
Closes #7
Closes #8
## Missing port (#7)
The collector keyed ports by their UniFi name, so when two ports shared a name, the later one silently replaced the earlier. The 24-port switch showed 25 ports because ports 13 and 14 have the same name. A repeated name is now kept as `<name> (Port N)`.
Port names are re-read from UniFi every poll, so a rename there shows up in Gandalf on the next cycle. Traffic rates are now matched to the previous poll by port number instead of name, so a renamed port no longer loses its rates for a cycle.
## SFP modules (#8)
The bond-matching problem described in #8 doesn't occur today: every port on the aggregation switch already resolves its neighbor. What was missing is module information. UniFi reports it, but Gandalf discarded it.
- **Collected per cage:** whether a module is present, its type (DAC or optic), vendor, part, serial and fault flags. DOM readings (RX/TX power, temperature, voltage, bias) are collected when the module reports them. Copper DACs don't.
- **Fault flags:** switches and the UDM spell them differently, and both spellings are read.
- **Faceplate:** empty cages, optics (LC sockets), DACs (cable boot) and unidentified modules are drawn differently, so an empty cage no longer looks like a module with no link. A faulted module is outlined in red.
- **Port panel:** a new **SFP Module** section shows type, part, serial, faults and readings, with power bars.
- **DAC cable ends:** both ends of a DAC report the cable's serial, so a DAC seen on two ports links to its other end.
## Testing
- New tests cover duplicate names, renames keeping their rates, module parsing (empty, optic, DAC by compliance or part number, unidentified, UDM fault spelling, unparseable readings) and DAC end pairing. All 233 tests, `flake8` and `eslint` (no errors) pass.
- Checked in a local preview with sample data shaped like the controller's real responses, on desktop and at 390px wide. There's no horizontal scroll, and the only console error is the avatar 404 the preview always has.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Ports were keyed by their UniFi name, so when two ports shared a name the
later one replaced the earlier. The 24-port switch lost port 13 this way
(ports 13 and 14 are both "Office TV"). A repeated name is now kept as
"<name> (Port N)".
Traffic rates are now matched to the previous poll by port number rather
than name. Names are re-read from UniFi every poll, so a port renamed
there keeps its rates instead of losing them for a cycle.
Collect what UniFi reports about each SFP cage: whether a module is
present, its type (DAC or optic), part, serial, fault flags, and DOM
readings when the module has them. The faceplate draws empty cages,
optics, DACs and unidentified modules differently and outlines a faulted
module in red. The port panel gets an SFP Module section. Both ends of a
DAC report the same cable serial, so each end links to the other.
Closes#7Closes#8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jared
merged commit afc7aae580 into main2026-11-10 14:44:49 -05:00
jared
deleted branch switch-ports-and-sfp-modules2026-11-10 14:44:50 -05:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #7
Closes #8
Missing port (#7)
The collector keyed ports by their UniFi name, so when two ports shared a name, the later one silently replaced the earlier. The 24-port switch showed 25 ports because ports 13 and 14 have the same name. A repeated name is now kept as
<name> (Port N).Port names are re-read from UniFi every poll, so a rename there shows up in Gandalf on the next cycle. Traffic rates are now matched to the previous poll by port number instead of name, so a renamed port no longer loses its rates for a cycle.
SFP modules (#8)
The bond-matching problem described in #8 doesn't occur today: every port on the aggregation switch already resolves its neighbor. What was missing is module information. UniFi reports it, but Gandalf discarded it.
Testing
flake8andeslint(no errors) pass.🤖 Generated with Claude Code