mirror of
https://github.com/safijari/openpuck.git
synced 2026-11-03 22:30:22 +00:00
[GH-ISSUE #285] Multi-Controller RF Sessions Fail After First Connected Controller (0.9.51) #132
Labels
No labels
pull-request
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
safijari/openpuck#132
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @J-A-McCrae on GitHub (Sep 10, 2026).
Original GitHub issue: https://github.com/safijari/openpuck/issues/285
Environment
scpair.pytestingController serials used:
Primary OpenPuck:
Secondary OpenPuck:
Summary
There appear to be two related multi-controller problems when using Steam Controller 2 units with OpenPuck:
Steam can instantiate a single physical Steam Controller 2 multiple times when pairing additional controllers to OpenPuck.
Even when bypassing Steam entirely and creating four correct independent bonds with
scpair.py, OpenPuck only allows one controller to maintain a live RF connection at a time.Official Valve pucks do not show these behaviours with the same controllers.
The latest testing therefore suggests that bond storage itself is not the root cause. The fault appears more likely to involve OpenPuck's multi-controller RF/session handling and/or the way active controller sessions are exposed through its per-slot USB interfaces to Steam.
Initial Steam pairing reproduction
Starting from a factory-reset OpenPuck with all slots empty:
Pair Controller 1 through Steam.
Pair Controller 2.
Pair Controller 3.
Steam Controller Puck.I repeated the test using a different controller order:
This initially suggested the fault followed the third pairing position rather than any particular controller.
Steam controller logs confirmed that the same physical controller serial was instantiated simultaneously as multiple wireless controller numbers.
Reproduction on a second OpenPuck
The duplication behaviour was also reproduced on a second OpenPuck.
On that unit, the failure occurred while pairing the second controller rather than the third.
This shows that:
In this reproduction, the second controller was shown multiple times by Steam and the first controller's pairing appeared to be overwritten.
Control test with official Valve puck
The same four Steam Controller 2 units pair normally using official Valve pucks.
No duplication was observed through all four controllers.
The controllers themselves therefore do not appear to be the source of the problem.
Direct pairing test using
scpair.pyTo remove Steam from the pairing process entirely, I tested under Linux using OpenPuck's
scpair.py.OpenPuck was factory-reset and the relevant controller-side puck slots were cleared.
Using OpenPuck firmware 0.9.31 with the matching 0.9.31 source branch, four controllers were explicitly paired one-by-one to four separate OpenPuck slots:
Each controller's own controller-side slot contained the corresponding OpenPuck serial and exactly matching bond key.
The bond data was therefore valid and independent on both sides.
The OpenPuck was subsequently upgraded to firmware 0.9.51 without factory reset, and all four bond records survived intact.
Using the matching/current
scpair.py, each wired controller independently reports the correct OpenPuck serial and corresponding bond key.Individual wireless connection test
On firmware 0.9.51, with four correct bonds stored:
With no controllers powered on:
Powering on Controller 1 alone works correctly:
Powering on Controller 2 alone also works correctly:
The other controllers likewise work correctly when used individually.
Simultaneous wireless connection failure
If Controller 1 is powered on first, it connects normally.
If Controller 2 is then powered on while Controller 1 remains connected, Controller 2 powers on but never establishes a live RF connection.
scpair.py listcontinues to show only Controller 1:There is no second wireless controller entry.
The same behaviour is visible in the OpenPuck web UI and in Steam on Windows:
This reproduces independently of Steam's pairing mechanism.
Controlled Windows retest after HID/PnP cleanup
To rule out stale Windows HID/PnP state, all stale Valve
VID_28DEdevices were removed from Windows while all Valve hardware was disconnected.Windows was then rebooted.
The secondary OpenPuck was:
Controller 1 and Controller 2 had their secondary controller-side pairing slots explicitly cleared using
scpair.py.The controllers were then paired one at a time through the Steam UI using those secondary slots.
Controller 1 paired normally.
When Controller 2 was paired, Steam again duplicated it.
This reproduction therefore occurred after:
Stale Windows HID devices are therefore unlikely to be the primary cause.
Important latest finding: duplication with a correct OpenPuck bond table
After the above clean reproduction, the secondary OpenPuck bond table was inspected directly under Linux:
This bond table is completely correct.
There is:
Despite this, Steam instantiated Controller 2 twice as two simultaneous wireless controllers.
Steam's controller log showed the same physical serial:
first as wireless Controller 0 and then, approximately four seconds later, as wireless Controller 1.
Both instances reported the same:
This demonstrates that Steam-side duplication can occur even when OpenPuck's persistent bond table is correct.
Linux runtime state after the duplicate Steam reproduction
With only Controller 2 powered wirelessly and the same OpenPuck connected to Linux,
scpair.py listreported:The controller itself reported:
This is internally consistent:
Therefore, in this latest reproduction, Linux does not show the controller simultaneously active on multiple OpenPuck slots, even though Steam on Windows instantiated it twice.
This suggests the Steam duplication can occur independently of persistent bond corruption and independently of an obviously duplicated RF session at the
scpair.pylevel.Earlier 0.9.51 multi-slot active-state anomaly
During earlier direct-pairing testing on firmware 0.9.51, there were also cases where one physical wireless controller appeared active through more than one populated OpenPuck slot.
For example:
In another state, when Controller 1 was powered on:
This caused the current
scpair.py listimplementation to encounterNoneTypeerrors while attempting to interrogate the phantom active controller interface.This behaviour is not reproduced in every test and may represent a separate or state-dependent active-interface routing problem.
It may nevertheless be related to the duplicate logical controllers observed by Steam.
Steam UI pairing indication is not reliable in this failure state
Steam's pairing-state UI also appears capable of disagreeing with the actual controller/OpenPuck state.
For example, Steam has reported that a controller was not paired while the controller was actively controlling the Windows mouse through gyro input.
Direct
scpair.pyinspection subsequently confirmed valid controller-side and OpenPuck-side bonds.Therefore, for these tests I consider the following more authoritative than Steam's pairing-status UI:
scpair.py;scpair.py;connected to controller ...state;Steam's displayed "paired/unpaired" status should therefore be treated as an additional symptom rather than reliable evidence of actual bond state.
Expected behaviour
OpenPuck exposes four independent bond slots and is intended to support multiple Steam Controller 2 units simultaneously:
Each bonded controller should be able to establish an independent RF session concurrently.
Each active controller should also be exposed to the host exactly once.
Actual behaviour
Persistent bond storage can be made fully correct.
Each controller can also connect correctly when tested individually.
However:
Current interpretation
The persistent pairing database does not appear to be the fundamental problem.
The direct
scpair.pytests demonstrate that:The latest Windows reproduction additionally demonstrates that Steam can duplicate one physical wireless controller even while the OpenPuck persistent bond table remains correct.
This suggests there may be two closely related runtime issues:
OpenPuck multi-controller RF/session handling
Per-slot USB/active-session presentation to Steam
Likely areas to investigate
Useful areas to inspect may include:
MI_02–MI_05puck HID interfaces;scpair.pyreports only one active OpenPuck slot.The simultaneous-connection failure reproduces on Linux without Steam once multiple valid bonds are present, so the core multi-controller RF problem does not appear to require Steam.
The Steam duplication behaviour may be a second manifestation of incorrect per-slot runtime/interface state rather than incorrect persistent pairing data.