show HUB75 and DMX pins in usermods pin dropdown#336
Conversation
these pins were wrongly shown as "available", because the are not stored in the cfg.json part related to LEDs settings.
📝 WalkthroughWalkthroughServer now emits HUB75 and DMX pin arrays ( Changes
Sequence Diagram(s)mermaid Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@wled00/data/settings_um.htm`:
- Around line 272-273: The code accesses d.h_pins and d.x_pins (in the loops
that append "HUB75 🔴" and "DMX 🔴") but those properties may be undefined and
cause a TypeError when reading .length; initialize them as empty arrays
alongside the other defaults (e.g., where d.rsvd and d.ro_gpio are set) by
adding d.h_pins = [] and d.x_pins = [] so the loops safely run even if the
server JS fails to populate them.
isFirstHub => isFirstPin
|
@coderabbitai there is a problem in the dropDown where i need your expertise to understand how the code could be fixed: The line for pin 2 is wrongly disabled and labeled as " matrix". The root cause seems to be that for HUB75 types (100-120) and other network outputs (type >=80) the pin array stores other information but not pin numbers. I have attached the cfg.json from the board. The most relevant part is |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 6507 🏁 Script executed: Length of output: 5943 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 4734 🏁 Script executed: Length of output: 5439 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 11955 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 3063 🏁 Script executed: Length of output: 4979 🏁 Script executed: Length of output: 2875 🏁 Script executed: Length of output: 5209 🏁 Script executed: Length of output: 3683 🏁 Script executed: Length of output: 540 🏁 Script executed: Length of output: 18665 🏁 Script executed: Length of output: 1206 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 16106 🏁 Script executed: Length of output: 994 🏁 Script executed: Length of output: 1933 🏁 Script executed: Length of output: 1181 🏁 Script executed: Length of output: 68 🏁 Script executed: Length of output: 660
Problem AnalysisThe issue occurs because the
In your case with type 103 (HUB75), the value The actual HUB75 GPIO pins are hardcoded in Proposed FixModify the function getPins(o) {
if (isO(o)) {
// Check if this object is a bus instance with a "type" field
let busType = o.type !== undefined ? o.type : -1;
for (const [k,v] of Object.entries(o)) {
if (isO(v)) {
owner = k;
getPins(v);
continue;
}
if (k.replace("[]","").substr(-3)=="pin") {
// Skip pin arrays for special bus types where pin array doesn't contain GPIO numbers
if (busType >= 80 && busType < 96) continue; // Network buses - pin array stores IP address
if (busType >= 100 && busType <= 110) continue; // HUB75 buses - pin array stores chain length
if (Array.isArray(v)) {
for (var i=0; i<v.length; i++) if (v[i]>=0) { pins.push(v[i]); pinO.push(owner); }
} else {
if (v>=0) { pins.push(v); pinO.push(owner); }
}
} else if (Array.isArray(v)) {
for (var i=0; i<v.length; i++) getPins(v[i]);
}
}
}
}This fix:
The actual HUB75 and DMX GPIO pins will still be correctly shown via the 🧠 Learnings used |
@coderabbitai "blindly" collecting all keys ending in "pin" is desired behaviour, because other keys may also contain pins; for example Relay pin or buttons. Will the code you propose still collect these, and just filter out the ones related to HUB75 and network? |
|
Tip For best results, initiate chat on the files or code changes.
How the Filtering WorksThe let busType = o.type !== undefined ? o.type : -1;
The filtering conditions only trigger when if (busType >= 80 && busType < 96) continue; // Network buses
if (busType >= 100 && busType <= 110) continue; // HUB75 busesSince Example Flow
So the code preserves the "collect all keys ending in 'pin'" behavior, while adding surgical filtering only for the problematic bus types! 🧠 Learnings used |
Skips pin arrays for special bus types where pin array doesn't contain GPIO numbers, but allows all other entries
|
@coderabbitai please validate the new filtering code against my example provided earlier. Some non-bus entries seem to also have a "type", and should be allowed for pin extraction. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain
🏁 Script executed: Length of output: 674 🏁 Script executed: Length of output: 6904
Objects with
|
| Object | Type | Pin Values | Filtered? | Reason |
|---|---|---|---|---|
| LED Bus (HUB75) | 103 | [2] |
✅ YES | 103 >= 100 && 103 <= 110 → Skip (chain length, not GPIO) |
| Buttons (4×) | 0 | [-1] |
❌ NO | 0 < 80 && 0 < 100 → Collect normally |
| IR | 0 | -1 |
❌ NO | 0 < 80 && 0 < 100 → Collect normally |
| AudioReactive | 1 | [3,15,14,4,-1,-1] |
❌ NO | 1 < 80 && 1 < 100 → Collect normally (GPIOs 3,15,14,4) |
| Relay | (none) | 12 |
❌ NO | No type field → busType = -1 → Collect normally |
Validation Result
✅ The proposed filtering code is correct!
- HUB75 bus (type 103): Pin array
[2]will be skipped ✓- Value 2 represents chain length, not GPIO pin 2
- Buttons (type 0): Pin arrays will be collected ✓
- Valid pin configurations for button inputs
- AudioReactive (type 1): Pin array
[3,15,14,4]will be collected ✓- Valid GPIO pins for I2S digital microphone (sd, ws, sck, mclk)
- Relay (no type): Pin 12 will be collected ✓
- Standard relay GPIO configuration
The filtering ranges [80-95] and [100-110] specifically target only the problematic bus types where the pin array has special meaning, while allowing all other configurations to pass through unchanged.
🧠 Learnings used
Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 0
File: :0-0
Timestamp: 2026-02-04T22:42:15.433Z
Learning: In MoonModules/WLED-MM LED bus configuration, the `pin` array has different meanings depending on bus type: for HUB75 types (100-110) it stores chain length, for network buses (80-95) it stores IP address components, and only for standard buses does it contain actual GPIO pin numbers. The JavaScript pin collection in settings_um.htm must check bus type to avoid misinterpreting these values as GPIO pins.
Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 270
File: usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h:155-157
Timestamp: 2025-10-22T21:50:25.839Z
Learning: In WLED-MM PR `#270`, only Effect (Mode) IDs are migrated to 16-bit; Palette IDs and counts remain 8-bit. Usermod code should widen mode-related indices/loops to uint16_t while keeping palette-related indices/loops as uint8_t.
Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 270
File: wled00/fcn_declare.h:403-406
Timestamp: 2025-10-22T21:59:24.331Z
Learning: In MoonModules/WLED-MM PR `#270`, the out-of-bounds null-terminator write in wled00/util.cpp (extractModeSlider) is deferred and tracked in Issue `#272`; do not address it within PR `#270`.
Learnt from: softhack007
Repo: MoonModules/WLED-MM PR: 0
File: :0-0
Timestamp: 2025-11-02T22:07:15.689Z
Learning: In MoonModules/WLED-MM, WLEDMM_FASTPATH will become the default code path. Code inside "#ifndef WLEDMM_FASTPATH" blocks represents deprecated paths that are being phased out and should be ignored during reviews.
Previously the pins allocated to HUB75 and DMX were wrongly shown as available 🟢 in the pin dropdown.
now it looks like this

Summary by CodeRabbit
New Features
Style / UI