fix Respeaker USB Mic Array v2 LEDs#357
Conversation
Fix ReSpeaker USB LED control and suppress stale peripheral disconnect replay
|
I discovered another issue testing this fix. There is a race between the LVA registering to HA and peripheral registering to the LVA. @omaramin-2000 shall I add fix here, or shall I create independent fix? The patch will goes as well into peripheral_api.py |
Yes, do it in a separate PR, better. |
|
What device is respeaker usb mic v2? |
|
This one: https://www.seeedstudio.com/ReSpeaker-Mic-Array-v3-0.html Actually predecesor, as I see there is already V3 on the market. It is exactly the device described in the DOCS of this peripheral integration. |
|
@florian-asche I see PR checks failing on missing PR Labels. Is there anything I shall do? There is now also additional testing result available now from @tobuh reported in #354 . |
@omaramin-2000 I just open the PR #373 as discussed here. |
What does this implement/fix?
Fix ReSpeaker Mic Array v2 USB LED control and suppress stale peripheral disconnect replay as reported in the #354
With help of AI ;-)
Related issue (if applicable):
Types of changes
bugfixnew-featureenhancementbreaking-changerefactordocumentationmaintenancecidependenciesChecklist
./script/lintpasses../script/testspasses, and tests have been added/updated undertests/where applicable.Summary
This pull request fixes two related issues affecting the ReSpeaker Mic Array v2.0 USB peripheral integration:
disconnectedevent immediately after connecting, even when Home Assistant was already connected, which forced the LED controller back into the red "not ready" animation.Together, these fixes make the ReSpeaker USB LED behavior consistent with the reference
pixel_ringimplementation and prevent false disconnect state from overriding valid Home Assistant state.Changes
1. Fix ReSpeaker USB LED transport and device handling
Updated
examples/ReSpeaker Mic Array v2.0 (USB)/respeaker_usb_mic_array.pyto use the same USB vendor-command protocol as the copied reference implementation under the localpixel_ringdirectory.What changed
0x06for LED frame updates0x20for brightness updateswIndex = 0x1C, matching the reference implementation.Why this was necessary
The local ReSpeaker USB example was treating the device like a raw APA102 transport target, but the USB firmware actually expects higher-level vendor commands. Sending the wrong payload format can cause the firmware to misinterpret LED data, which explains symptoms like the ring going fully white or otherwise behaving incorrectly.
The previous version also detached the kernel driver during USB initialization. For this hardware, that is unnecessary for LED control and risks interfering with the audio side of the device.
Result
2. Fix peripheral state initialization and recovery in the ReSpeaker USB example
Updated event handling in
examples/ReSpeaker Mic Array v2.0 (USB)/respeaker_usb_mic_array.pyso the LED controller correctly transitions out ofNOT_READY.What changed
snapshothandling now derives the initial assist state from:mutedha_connectedmutedhandling now supports both mute and unmute transitions.zeroconfhandling now restores the LED state toIDLEorMUTEDwhen Home Assistant reconnects.Why this was necessary
The peripheral could receive valid
light_commandupdates, but still remain in the red twinkle animation because its localassist_statenever leftNOT_READY. In that situation, color and brightness changes were being stored, but the active animation selection kept choosing the disconnected/not-ready path.Result
IDLEand render the configured light color.3. Prevent stale
disconnectedreplay to newly connected peripheralsUpdated peripheral_api.py in the snapshot replay path.
What changed
disconnectedevent to a newly connected peripheral whenstate.connectedis alreadyTrue.Why this was necessary
The peripheral API sends a snapshot immediately on connect, then replays the current cached event state so peripherals can restore the correct animation. The bug was that the cached event could still be
DISCONNECTEDfrom an earlier Home Assistant outage, even though the current connection state had already recovered.This produced a misleading sequence:
snapshotwithha_connected: truedisconnectedThat made the LED controller appear disconnected even when Home Assistant was actually available.
Result
IDLEor other valid states instead of being forced back to twinkle.Root Cause
There were two separate but compounding issues:
Because of that combination, the LED ring could both misrender LED commands and also remain visually stuck in a disconnected state even after the backend had recovered.
Validation
The chnages were validated on the user deployment.
Files Changed
examples/ReSpeaker Mic Array v2.0 (USB)/respeaker_usb_mic_array.pyUser Impact
After deploying this PR: