fix: align MQTT JSON transport with the Meshtastic protocol#18
fix: align MQTT JSON transport with the Meshtastic protocol#181Croydan1 wants to merge 2 commits into
Conversation
The MQTT transport's JSON did not match the Meshtastic JSON format it
documents (default broker mqtt.meshtastic.org / msh/REGION/2/json), so
as shipped it could neither receive text from the broker nor have its
downlinks transmitted by a gateway.
Inbound (msh/REGION/2/json/...):
- received text packets have type "text", not "sendtext" ("sendtext" is
the downlink verb and never appears on uplink), so the filter dropped
every real message
- attribute the message to `from` (the originating node), not `sender`
(the gateway that uploaded it to MQTT) — otherwise every sender in a
multi-node mesh collapses to the gateway
- `sender` is a node ID, not a display name, so stop surfacing it as one
Downlink (publish to msh/REGION/2/json/mqtt/):
- `payload` must be a plain string, not { text }
- use `from` (numeric gateway node ID) and `channel` (index), not
`sender` / `channel_name`
- publish to the documented ".../2/json/mqtt/" topic
- thread the numeric channelIndex through (mirroring the serial
transport) instead of parsing it out of the channel name
Verified end-to-end against a real Meshtastic gateway: an injected
uplink is now received and answered, and the reply downlink
{"from":<gw>,"type":"sendtext","payload":"42","channel":1} is accepted
by the gateway and transmitted on the mesh.
Ref: https://meshtastic.org/docs/software/integrations/mqtt/
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 18 minutes and 47 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughChannel selection is standardized from string-based names to numeric indices throughout the MQTT messaging pipeline. The MQTT client uplink parser now recognizes ChangesMQTT Channel Index Migration and Message Format Upgrade
🎯 3 (Moderate) | ⏱️ ~22 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
|
The OpenClaw 2026.5.x SDK-load incompatibility I mentioned is now filed separately as #19 (with the verified import mapping + an offer to do that migration PR). This PR is purely the Meshtastic JSON protocol fix and is independent of it. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/send.ts (1)
10-14:⚠️ Potential issue | 🟠 MajorFix:
channelNameoption is passed but ignored insendMessageMeshtastic
src/send.tsdefinesSendMeshtasticOptions.channelName, butsendMessageMeshtasticonly usesopts.channelIndexfor both MQTT (line ~82) and serial/HTTP (line ~90);opts.channelNameis never read.- A caller still passes
channelName(e.g.,src/inbound.tslines ~104-108:sendMessageMeshtastic(..., { ..., channelName: params.channelName })), so channel selection can be silently ignored whenchannelIndexis unset.- Remove/deprecate
channelNamefromSendMeshtasticOptions, or implementchannelName→channelIndexresolution (or throw whenchannelNameis provided withoutchannelIndex).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/send.ts` around lines 10 - 14, sendMessageMeshtastic currently ignores SendMeshtasticOptions.channelName; update sendMessageMeshtastic to handle channelName when channelIndex is not provided by resolving channelName→channelIndex (or throwing if resolution fails). Add a small helper (e.g., getChannelIndexByName) that looks up channel names from the Meshtastic device/config and returns the numeric index, then use that resolved index in the MQTT and serial/HTTP send branches inside sendMessageMeshtastic; ensure callers like inbound.ts that pass channelName continue to work. Alternatively, if you prefer deprecation, remove channelName from SendMeshtasticOptions and update all call sites (e.g., sendMessageMeshtastic and inbound.ts) to require channelIndex and throw a clear error when channelName is provided without channelIndex.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/send.ts`:
- Around line 10-14: sendMessageMeshtastic currently ignores
SendMeshtasticOptions.channelName; update sendMessageMeshtastic to handle
channelName when channelIndex is not provided by resolving
channelName→channelIndex (or throwing if resolution fails). Add a small helper
(e.g., getChannelIndexByName) that looks up channel names from the Meshtastic
device/config and returns the numeric index, then use that resolved index in the
MQTT and serial/HTTP send branches inside sendMessageMeshtastic; ensure callers
like inbound.ts that pass channelName continue to work. Alternatively, if you
prefer deprecation, remove channelName from SendMeshtasticOptions and update all
call sites (e.g., sendMessageMeshtastic and inbound.ts) to require channelIndex
and throw a clear error when channelName is provided without channelIndex.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 557ad033-6ce8-4b77-8c52-0ef8ccc2a2e0
📒 Files selected for processing (3)
src/monitor.tssrc/mqtt-client.tssrc/send.ts
Address review (PR Seeed-Solution#18): once the send path standardized on numeric channelIndex, SendMeshtasticOptions.channelName was no longer read anywhere — both the MQTT and serial branches use channelIndex. Leaving it invited silent channel-selection drops when only channelName was set. Remove it together with the now-redundant deliverMeshtasticReply plumbing in inbound.ts. The inbound message's own channelName (group routing) is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Good catch — fixed in the latest commit. After this PR standardized the send path on numeric |
Problem
The
mqtttransport documents the standard Meshtastic broker as its default(
mqtt.meshtastic.org,meshdev/large4cats,msh/US/2/json/#), but theJSON it produced and consumed did not match the Meshtastic JSON
protocol. As shipped
in v0.2.2 the transport cannot work against that broker:
What was wrong (vs. the spec)
main(v0.2.2)type:"text",payload:{text}type:"sendtext"❌type:"text"✅from=origin,sender=gatewaysender(gateway) ❌from✅payload{ text }❌from(num),channel(idx)sender(str),channel_name❌from,channel✅…/2/json/mqtt/…/mqtt(no slash)…/mqtt/✅"sendtext"is the downlink verb, so filtering inbound on it dropped allreal traffic. On uplink,
senderis the gateway that republished to MQTT whilefromis the actual author — preferringsendercollapses every node in amulti-hop mesh to the gateway (and breaks DM/allowlist matching).
senderis anode ID, not a display name, so it's no longer surfaced as
senderName.For downlinks the firmware expects
{from, type:"sendtext", payload:"<string>", channel?, to?}on
…/2/json/mqtt/. The numericchannelIndexis now threaded through(mirroring the serial transport's
sendText) instead of being parsed out of thechannel name.
Verification
No build/lint/test exists (per
AGENTS.mdthe host loads TS via esbuild), so Iverified end-to-end against a real Meshtastic gateway + OpenClaw. Injecting a
simulated uplink and capturing the broker:
Before this change the uplink was dropped and nothing was transmitted.
Scope
Code-only, 3 files. I kept it to the protocol fix. Separately I'll open an issue
for the
openclaw/plugin-sdk/irc+/matriximport paths that break loading oncurrent OpenClaw (2026.5.x) — that's an SDK-version concern, not a Meshtastic
one.
🤖 Generated with Claude Code
Summary by CodeRabbit