Skip to content

UDP port seggregation#172

Open
ewowi wants to merge 3 commits intomainfrom
udp-port-seggregation
Open

UDP port seggregation#172
ewowi wants to merge 3 commits intomainfrom
udp-port-seggregation

Conversation

@ewowi
Copy link
Copy Markdown
Collaborator

@ewowi ewowi commented May 4, 2026

Summary by CodeRabbit

  • Documentation
    • Added a full developer reference for the local-network discovery/control protocol and updated site navigation.
  • New Features
    • Redesigned Devices view with a detailed device table, click-throughs, and clarified "Last Sync".
  • Behavior
    • Group sync refined to avoid loop/false-match propagation using hostname-boundary rules; discovery and control now use separate network channels.
  • Documentation
    • Clarified WLED coexistence and discovery limitations for WLED devices.

ModuleDevices:
- Replace UDPMessage.rommel[6] (all-zeros) with proper UDPWLEDHeader (44 bytes)
  matching WLED/StarLight packet format (token=255, id=1, ip, name, type, version)
- static_assert(sizeof(UDPWLEDHeader)==44) enforces layout at build time
- lightsOn encoded in header.type bit 7, matching WLED convention
- Add UDPControlMessage for port 65507 (MoonLight-only, WLED never sees this)
- Move ALL control (broadcast + unicast) to port 65507; port 65506 carries
  discovery packets only — WLED can no longer receive MoonLight control commands
- receiveUDP: size-based dispatch — 44 bytes = WLED, sizeof(UDPMessage) = MoonLight
- Add updateDevicesWLED() for 44-byte WLED packets (name/ip/lightsOn available)
- Track deviceControlUDPConnected separately; guard sendUDP(true) on it
- partOfGroup comment: corrected "dots" to "hyphens"

Docs:
- Add docs/develop/devices.md: UDP protocol reference for developers
- Update docs/moonbase/devices.md: end-user description including WLED coexistence
- Add develop/devices.md to mkdocs.yml nav
- Replace stale ModuleDevices section in docs/develop/network.md with pointer
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

Walkthrough

Adds a dual-socket UDP protocol for ModuleDevices: WLED-compatible discovery on UDP/65506 and MoonLight-only control on UDP/65507. Introduces packed wire structs (UDPWLEDHeader, revised UDPMessage, UDPControlMessage), exact-size packet dispatch by socket, sender/group control semantics with loop prevention, UI → control message wiring, docs, and navigation updates.

Changes

ModuleDevices — UDP dual-socket protocol & device-table sync

Layer / File(s) Summary
Protocol Definition
src/MoonBase/Modules/ModuleDevices.h
Add UDPWLEDHeader (44 bytes), replace old UDPMessage with one embedding UDPWLEDHeader (101 bytes asserted), and add UDPControlMessage (80 bytes asserted).
Public State
src/MoonBase/Modules/ModuleDevices.h
Add deviceControlUDPConnected and keep distinct ports: discovery 65506, control 65507.
Socket Binding & Lifecycle
src/MoonBase/Modules/ModuleDevices.h
loop10s() binds discovery/control sockets independently; each socket may be retried/operate separately. Discovery/status broadcasts sent when discovery socket is bound.
Reception & Dispatch
src/MoonBase/Modules/ModuleDevices.h
receiveUDP() now parses by exact sizeof(...) per socket: 44→updateDevicesWLED, 101→updateDevices, 80→processControlMessage; validates WLED token==255 && id==1 and rejects other sizes.
Discovery Parsing
src/MoonBase/Modules/ModuleDevices.h
updateDevices() handles full MoonLight discovery fields; updateDevicesWLED() handles 44‑byte WLED header and fills MoonLight-only fields with defaults.
Control Processing
src/MoonBase/Modules/ModuleDevices.h
processControlMessage() ignores self-echo, distinguishes unicast (targetName set) vs group (empty targetName + partOfGroup()), converts message → control state, and calls _moduleControl->update() with origin "unicast" or "group". Re-broadcast suppressed when originId == "group".
Outbound Send Logic
src/MoonBase/Modules/ModuleDevices.h
sendUDP(true) sends UDPControlMessage on 65507 (group when targetName empty); sendUDP(false) broadcasts discovery UDPMessage on 65506 and immediately updates local device table. onUpdate() serializes UI edits to UDPControlMessage, applies locally if target is local, or unicasts to targetIP:65507 (requires control socket connected).
Helpers & Conversions
src/MoonBase/Modules/ModuleDevices.h
Add infoToHeader, infoToMessage, infoToControlMessage, messageToControlState, controlStateToControlMessage, and deviceToControlMessage to map UI/device state to/from wire formats.
Grouping Logic
src/MoonBase/Modules/ModuleDevices.h
partOfGroup() now enforces hyphen-boundary prefix matching (avoid false prefix matches).
Device Table Finalization
src/MoonBase/Modules/ModuleDevices.h
finaliseDeviceUpdate() filters stale entries (>1 day), sorts by name/ip, and batches UI/document updates.
Developer Docs
docs/develop/devices.md
New developer reference documenting ports 65506/65507, packet layouts (44/101/80 bytes), exact-size dispatch, token/id validation, socket lifecycle, control/group semantics, loop prevention, and versioning implications tied to packageSize/struct size.
User Docs
docs/moonbase/devices.md
Rewrite of Devices panel docs: device table columns, click behavior, “Last Sync”, WLED discovery limitations (no brightness/palette/preset), Group sync description, and WLED coexistence (shared discovery port vs MoonLight control port).
Navigation
mkdocs.yml, docs/develop/network.md
Add develop/devices.md to Develop nav and replace inline UDP details in develop/network.md with a link to the new developer page.
Build Flags
firmware/esp32-d0.ini
Add -mtext-section-literals to [env:esp32-d0-wrover] build_flags to address literal pool out-of-range issues.

Sequence Diagram(s)

sequenceDiagram
    participant UI as UI
    participant MB as ModuleDevices
    participant Sock65506 as UDP Socket (65506)
    participant Sock65507 as UDP Socket (65507)
    participant Device as Remote Device

    Note over Sock65506,Sock65507: Discovery (65506) & Control (65507) split

    UI->>MB: onUpdate(device, state)
    alt target == local
        MB->>MB: apply locally via _moduleControl->update(origin="unicast")
    else
        MB->>Sock65507: send UDPControlMessage -> targetIP:65507 (unicast) or broadcast (group, targetName="")
    end

    Note over Device,Sock65507: Group broadcast propagation
    Sock65507->>Device: receive UDPControlMessage (group)
    Device->>Sock65507: possibly re-broadcast unless originId == "group"

    Note over Device,Sock65506: Discovery flows
    Device->>Sock65506: broadcast UDPWLEDHeader (44) or UDPMessage (101)
    Sock65506->>MB: receiveUDP()
    alt size==44
        MB->>MB: updateDevicesWLED(header, IP)
    else size==101
        MB->>MB: updateDevices(message, IP)
    end
    MB->>MB: finaliseDeviceUpdate()
    MB->>UI: update device table
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 Hopping through packets on ports six-five-five-oh-six and seven,

Discovery greets the network, control finds its heaven,
Names joined by hyphens, groups find their tune,
No echo, no loops — sync hums under the moon,
A rabbit cheers: "Lights aligned — network's in bloom!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'UDP port seggregation' directly corresponds to the main changes: implementing UDP port segregation (ports 65506 for shared discovery and 65507 for MoonLight-only control) across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch udp-port-seggregation

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/MoonBase/Modules/ModuleDevices.h (2)

149-170: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Decouple the control socket lifecycle from the discovery socket.

deviceControlUDP.begin() is only retried while deviceUDPConnected is false, and loop20ms() stops polling entirely when 65506 is down. That means one transient bind failure on 65507, or any ongoing failure on 65506, can disable MoonLight control even though the other socket is still usable.

Suggested change
   void loop20ms() override {
     Module::loop20ms();
 
     if (!networkIsConnected()) return;
-
-    if (!deviceUDPConnected) return;
+    if (!deviceUDPConnected && !deviceControlUDPConnected) return;
 
     receiveUDP();  // and updateDevices
   }
 
   void loop10s() override {
     if (!networkIsConnected()) return;
 
     if (!deviceUDPConnected) {
       deviceUDPConnected = deviceUDP.begin(deviceUDPPort);
-      deviceControlUDPConnected = deviceControlUDP.begin(deviceControlUDPPort);  // Initialize control UDP on separate port
+    }
+    if (!deviceControlUDPConnected) {
+      deviceControlUDPConnected = deviceControlUDP.begin(deviceControlUDPPort);  // Initialize control UDP on separate port
       EXT_LOGD(MB_TAG, "deviceUDP:%d p:%d, controlUDP:%d p:%d",
                deviceUDPConnected, deviceUDPPort, deviceControlUDPConnected, deviceControlUDPPort);
       if (!deviceControlUDPConnected)
         EXT_LOGW(MB_TAG, "Failed to bind control UDP on port %d", deviceControlUDPPort);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MoonBase/Modules/ModuleDevices.h` around lines 149 - 170, The control UDP
socket lifecycle is currently tied to deviceUDPConnected causing control to stop
if the discovery socket or its bind (deviceUDP.begin/deviceUDPConnected) fails;
update loop10s() and loop20ms() so deviceControlUDP.begin(deviceControlUDPPort)
is attempted and retried independently of deviceUDPConnected, use
deviceControlUDPConnected as its own flag, and ensure loop20ms() still
polls/receives from the control socket (and/or calls the control-specific
receive path) even when deviceUDPConnected is false; keep existing logs
(EXT_LOGD/EXT_LOGW) but reflect independent bind attempts for
deviceControlUDPConnected and do not gate sendUDP/receive of control traffic
behind deviceUDPConnected.

464-473: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Require a hyphen boundary when matching groups.

device.startsWith(base.substring(0, pos)) will treat kitchen-1 as part of the same group as kitchenette-2, stage-1 as matching stagecoach-3, etc. Grouping here is hyphen-delimited, so the prefix match needs to respect that boundary.

Suggested change
-    return device.startsWith(base.substring(0, pos));
+    String prefix = base.substring(0, pos);
+    return device == prefix || device.startsWith(prefix + "-");
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MoonBase/Modules/ModuleDevices.h` around lines 464 - 473, The current
suffix-group check uses device.startsWith(base.substring(0, pos)) which can
falsely match names like "kitchenette-2"; update the final condition to enforce
a hyphen boundary at the split point: after finding pos (index of the hyphen in
base) require that device starts with base.substring(0, pos) AND that device has
a hyphen at the same position (e.g., device.length() > pos and
device.charAt(pos) == '-') so only true hyphen-delimited group members match;
keep the existing exact-match return (base == device) path unchanged.
🧹 Nitpick comments (1)
src/MoonBase/Modules/ModuleDevices.h (1)

41-61: ⚡ Quick win

Add compile-time size checks for the full wire packets.

receiveUDP() dispatches by exact sizeof(UDPMessage) / sizeof(UDPControlMessage), and the docs now call out fixed sizes. Right now only UDPWLEDHeader is guarded, so any future change to Char<32> or packing will break interoperability silently.

Suggested change
 struct UDPMessage {
   UDPWLEDHeader header; // 44 bytes — WLED-compatible
   Char<32> versionStr;  // human-readable version string
   char build[16];       // build date string
   uint32_t uptime;
   uint16_t packageSize; // sizeof(UDPMessage) — used by receiver to validate packet type
   uint8_t brightness;
   uint8_t palette;
   uint8_t preset;
 } __attribute__((packed));  // Force no padding
+static_assert(sizeof(UDPMessage) == 101, "UDPMessage must be exactly 101 bytes");
 
 // MoonLight-only control message sent exclusively on port 65507.
 // WLED does not listen on port 65507, so it never receives these packets.
 struct UDPControlMessage {
   UDPWLEDHeader header; // 44 bytes: sender identification
   char targetName[32];  // unicast: receiver hostname; group broadcast: empty string
   uint8_t brightness;
   uint8_t lightsOn;
   uint8_t palette;
   uint8_t preset;
 } __attribute__((packed));  // Force no padding
+static_assert(sizeof(UDPControlMessage) == 80, "UDPControlMessage must be exactly 80 bytes");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MoonBase/Modules/ModuleDevices.h` around lines 41 - 61, Add compile-time
size assertions for the full wire structs by inserting static_assert checks
immediately after the UDPMessage and UDPControlMessage definitions that verify
sizeof(UDPMessage) == 101 and sizeof(UDPControlMessage) == 80 (these totals come
from UDPWLEDHeader == 44 plus the declared field sizes), and provide clear
diagnostic messages so any accidental change to Char<32>, packing, or field
sizes fails at compile time; reference the UDPMessage and UDPControlMessage
symbols when adding these assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/develop/devices.md`:
- Around line 24-32: Update the three fenced code blocks that show the packet
layout to include a language identifier so markdownlint MD040 is satisfied: add
"text" after each opening triple-backtick for the block starting with "byte 0:  
token   — must be 255 (WLED validates this)" and the two blocks beginning with
"[UDPWLEDHeader — 44 bytes]". Ensure you change only the opening fence (``` ->
```text) for those blocks so rendering is unchanged.

In `@src/MoonBase/Modules/ModuleDevices.h`:
- Around line 293-328: Network-sourced fixed-size string fields must be
NUL-terminated before any strcmp/logging/JSON use: after reading packets in
receiveUDP (after deviceUDP.read / deviceControlUDP.read), explicitly set the
final byte to '\0' on any char arrays like UDPWLEDHeader::name,
UDPMessage::targetName (and any other fixed-size char buffers in UDPWLEDHeader,
UDPMessage, UDPControlMessage) so they cannot run past the buffer when used by
updateDevicesWLED, updateDevices, processControlMessage or logging. Ensure you
apply this for both discovery (UDPWLEDHeader/header and UDPMessage/message) and
control (UDPControlMessage/msg) reads immediately after read returns. />

---

Outside diff comments:
In `@src/MoonBase/Modules/ModuleDevices.h`:
- Around line 149-170: The control UDP socket lifecycle is currently tied to
deviceUDPConnected causing control to stop if the discovery socket or its bind
(deviceUDP.begin/deviceUDPConnected) fails; update loop10s() and loop20ms() so
deviceControlUDP.begin(deviceControlUDPPort) is attempted and retried
independently of deviceUDPConnected, use deviceControlUDPConnected as its own
flag, and ensure loop20ms() still polls/receives from the control socket (and/or
calls the control-specific receive path) even when deviceUDPConnected is false;
keep existing logs (EXT_LOGD/EXT_LOGW) but reflect independent bind attempts for
deviceControlUDPConnected and do not gate sendUDP/receive of control traffic
behind deviceUDPConnected.
- Around line 464-473: The current suffix-group check uses
device.startsWith(base.substring(0, pos)) which can falsely match names like
"kitchenette-2"; update the final condition to enforce a hyphen boundary at the
split point: after finding pos (index of the hyphen in base) require that device
starts with base.substring(0, pos) AND that device has a hyphen at the same
position (e.g., device.length() > pos and device.charAt(pos) == '-') so only
true hyphen-delimited group members match; keep the existing exact-match return
(base == device) path unchanged.

---

Nitpick comments:
In `@src/MoonBase/Modules/ModuleDevices.h`:
- Around line 41-61: Add compile-time size assertions for the full wire structs
by inserting static_assert checks immediately after the UDPMessage and
UDPControlMessage definitions that verify sizeof(UDPMessage) == 101 and
sizeof(UDPControlMessage) == 80 (these totals come from UDPWLEDHeader == 44 plus
the declared field sizes), and provide clear diagnostic messages so any
accidental change to Char<32>, packing, or field sizes fails at compile time;
reference the UDPMessage and UDPControlMessage symbols when adding these
assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 19c69f48-24e8-4883-b44c-46138ebbdccd

📥 Commits

Reviewing files that changed from the base of the PR and between 9a8b914 and 73847bc.

📒 Files selected for processing (5)
  • docs/develop/devices.md
  • docs/develop/network.md
  • docs/moonbase/devices.md
  • mkdocs.yml
  • src/MoonBase/Modules/ModuleDevices.h

Comment thread docs/develop/devices.md Outdated
Comment thread src/MoonBase/Modules/ModuleDevices.h
… match, static_asserts, doc fences

- receiveUDP(): NUL-terminate all char arrays after udp.read() to guard against non-terminated network data
- loop10s/loop20ms: bind discovery and control sockets independently; poll control even when discovery is unbound
- partOfGroup(): require device.charAt(pos)=='-' to prevent "kitchenette" matching the "kitchen" group
- Add static_assert for UDPMessage (101 bytes) and UDPControlMessage (80 bytes)
- docs/develop/devices.md: add `text` language identifier to three fenced code blocks
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/MoonBase/Modules/ModuleDevices.h`:
- Around line 295-299: Unicast controls are being treated as module-origin group
updates because update(...) is called with _moduleName as the origin, which
causes addUpdateHandler to treat it as a remote-origin and call sendUDP(true);
change the origin argument so group broadcasts still use "group" but
unicast-controlled updates use a non-module origin (e.g. "unicast" or empty
string) instead of _moduleName: modify the call to
_moduleControl->update(newState, ModuleState::update, isGroupBroadcast ? "group"
: "unicast") so addUpdateHandler won't re-broadcast unicast as group; verify
related logic in addUpdateHandler/sendUDP still interprets "group" as
suppressing rebroadcast.
- Around line 281-283: The pointer stored in myName comes from a temporary
String returned by esp32sveltekit.getSystemHostname(), leaving myName dangling
when later used (e.g., in strcmp); fix this by capturing the returned String in
a persistent local variable (e.g., myNameStr) before taking c_str(), so myName
points into a String that remains alive for the strcmp/usage; update the code
around senderName, myName and getSystemHostname() in ModuleDevices.h
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8be2e0c1-033b-4334-955b-91d9116573c3

📥 Commits

Reviewing files that changed from the base of the PR and between 73847bc and 792be90.

📒 Files selected for processing (2)
  • docs/develop/devices.md
  • src/MoonBase/Modules/ModuleDevices.h
✅ Files skipped from review due to trivial changes (1)
  • docs/develop/devices.md

Comment thread src/MoonBase/Modules/ModuleDevices.h
Comment thread src/MoonBase/Modules/ModuleDevices.h
…teral pool, and status broadcast

- processControlMessage: store getSystemHostname() in String (not const char*) to fix dangling pointer that prevented unicast control from applying
- addUpdateHandler: always call sendUDP(false) so remote device tables update immediately on any control change; suppress sendUDP(true) for both "group" and "unicast" origins
- Apply received unicast control with origin "unicast" (not _moduleName) so addUpdateHandler skips group re-broadcast
- UDPMessage::versionStr: char[32] instead of Char<32> (POD, avoids GCC packed-struct warning); update all call sites to strlcpy/direct index
- onUpdate() remote path: guard on deviceControlUDPConnected and log beginPacket failures
- receiveUDP() control port: guard on deviceControlUDPConnected before parsePacket loop
- esp32-d0-wrover: add -mtext-section-literals to fix l32r literal target out of range linker error
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/MoonBase/Modules/ModuleDevices.h (1)

128-135: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Treat self-targeted row edits as unicast, not module-origin group control.

When targetIP == activeIP, this calls _moduleControl->update(..., _moduleName). The handler on Lines 79-84 treats any origin other than "group"/"unicast" as a local control change and calls sendUDP(true), so editing the local device row fans out to the whole group while the remote-row path stays targeted. Using "unicast" here keeps the self-target path consistent with the network unicast path and avoids accidental group propagation.

Suggested fix
-        _moduleControl->update(newState, ModuleState::update, _moduleName);  // Do not add server in the originID as that blocks updates, see execOnUpdate
+        _moduleControl->update(newState, ModuleState::update, "unicast");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MoonBase/Modules/ModuleDevices.h` around lines 128 - 135, When handling
self-targeted UDP control (where targetIP == activeIP), don't pass the module's
name as the origin to _moduleControl->update (which causes the handler to treat
it as a local/group-origin change); instead use the unicast origin identifier so
the update is treated as a unicast/network-targeted change. Locate the block
that calls messageToControlState(...) and _moduleControl->update(newState,
ModuleState::update, _moduleName) and change the origin argument to the
equivalent "unicast" origin string used elsewhere so the handler will not call
sendUDP(true) and will keep the self-targeted edit as unicast.
🧹 Nitpick comments (1)
firmware/esp32-d0.ini (1)

53-59: ⚡ Quick win

Uncomment and update the platform version to ensure toolchain stability.

The recommendation to pin the platform is already noted in line 48, but line 49 remains commented. Since -mtext-section-literals is a compiler-specific Xtensa flag and now required for livescripts, uncomment the platform pin and update it to espressif32@6.13.0 (or verify against the latest stable release) to prevent toolchain drift and ensure reproducible builds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/esp32-d0.ini` around lines 53 - 59, Uncomment and set the Platform
pin to a fixed espressif32 toolchain version to avoid toolchain drift: locate
the existing commented platform pin near the build_flags block (the same env
that uses -mtext-section-literals and build_flags) and replace the commented
line with platform = espressif32@6.13.0 (or the latest verified stable), then
save so the -mtext-section-literals flag and livescripts build_flags use a
reproducible toolchain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/MoonBase/Modules/ModuleDevices.h`:
- Around line 128-135: When handling self-targeted UDP control (where targetIP
== activeIP), don't pass the module's name as the origin to
_moduleControl->update (which causes the handler to treat it as a
local/group-origin change); instead use the unicast origin identifier so the
update is treated as a unicast/network-targeted change. Locate the block that
calls messageToControlState(...) and _moduleControl->update(newState,
ModuleState::update, _moduleName) and change the origin argument to the
equivalent "unicast" origin string used elsewhere so the handler will not call
sendUDP(true) and will keep the self-targeted edit as unicast.

---

Nitpick comments:
In `@firmware/esp32-d0.ini`:
- Around line 53-59: Uncomment and set the Platform pin to a fixed espressif32
toolchain version to avoid toolchain drift: locate the existing commented
platform pin near the build_flags block (the same env that uses
-mtext-section-literals and build_flags) and replace the commented line with
platform = espressif32@6.13.0 (or the latest verified stable), then save so the
-mtext-section-literals flag and livescripts build_flags use a reproducible
toolchain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 57f56c83-40f3-41cf-9e9f-300409358fc8

📥 Commits

Reviewing files that changed from the base of the PR and between 792be90 and 6b23182.

📒 Files selected for processing (2)
  • firmware/esp32-d0.ini
  • src/MoonBase/Modules/ModuleDevices.h

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.

1 participant