Skip to content

Leave the duty cycle alone, and flood adverts every 47 hours - #24

Merged
matkam merged 1 commit into
mainfrom
flood-47-duty-opt-in
Sep 13, 2026
Merged

matkam merged 1 commit into
mainfrom
flood-47-duty-opt-in

Conversation

@matkam

@matkam matkam commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Two settings the page was opinionated about without needing to be.

The duty cycle is now opt-in

The box shipped at 100, so every paste led with set dutycycle 100 — or set af 0 on pre-1.15 — whether the operator meant it or not. Whoever flashed the node already made that choice, and the firmware's own default (50%) is a reasonable one; overwriting it unasked isn't this page's business.

Blank is now the default, following the same rule the flood interval and owner info already use. Nothing is sent, nothing is read back in the verification block, nothing is explained. Type a percentage and all three come back, set af conversion included.

North County SLO now generates:

set path.hash.mode 1
set flood.advert.interval 47
set loop.detect moderate
region def us west california centralcoast slo slonorth
region save

dutyValue() returns null when blank, and all four consumers gate on it — the command block, the verify block, the explanation, and the hint, which needed its own branch because the pre-1.15 one would otherwise render "null% rounds to set af NaN".

47 hours is not a taste call

The flood advert interval moves 24 → 47 because that is what the repeater firmware defaults to itself from 1.16 on:

examples/simple_repeater/MyMesh.cpp:904
  _prefs.flood_advert_interval = 47; // 47 hours
Tag Value
repeater-v1.15.0 = 12; // 12 hours
repeater-v1.16.0 = 47; // 47 hours
repeater-v1.17.1 = 47; // 47 hours

It changed in 40180b8, landing between the 1.15.0 and 1.16.0 releases.

I had first written the hint as "the firmware's own default is 12 hours, and 47 cuts that to about a quarter" — sourced from docs.meshcore.io/cli_commands, which still says "Default: 12 (Repeater)". That page is stale. caps() now carries floodAdvertDefault, and the hint quotes the default belonging to the version selected rather than asserting one number at everyone.

What to look at in the preview

  • Options opens with the duty cycle box empty, placeholder "Leave blank (don't send)"; the command block has no duty line and the verify block no get dutycycle
  • Type 100 → set dutycycle 100 leads the block and get dutycycle appears; switch to 1.10–1.13 → set af 0 / get af
  • Flood interval reads 47, and the hint says "47 is that default" on 1.16+ but "default is 12 hours" on 1.15 and older

Also in here

Two stale README examples that I was editing anyway: the North County block was missing the us root, and the 1.10–1.13 block was missing both the root and set flood.advert.interval, which is sent on every tier. Two region def snippets further down still omit us, but those illustrate branch syntax rather than real output, so I left them.

I checked the duty-cycle copy against the source while I was in there and it's right: the repeater sets airtime_factor = 1.0 and Dispatcher.cpp computes duty_cycle = 1.0f / (1.0f + airtime_budget_factor), so 50% is the real default and the site's af = 100/duty - 1 matches the firmware exactly.

Not in this PR: the version selector tops out at "1.16+" but 1.17.0/1.17.1 shipped in August. Nothing is wrong for 1.17 — every capability gate is >= — but the label and FW_HINTS don't mention it. Happy to add a tier separately if it's worth the row.

Tests

381 checks, 0 failures (was 379). New: a duty-cycle block in settings.mjs walking blank → 100 → set af on 1.10 → cleared, plus two checks pinning the version-aware flood default to both sides of the 1.16 split, and a blank-duty assertion in firmware.mjs.

Stripping the duty line from the four expected arrays in firmware.mjs means "no duty command at default" is now asserted on every tier, not just the two the new block walks explicitly. The two fill("#opt-duty", "100") calls that meant "reset to default" became "", since 100 no longer is one.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RvFSXfzU5ZTvdksaqxJMRW

Two settings the page was opinionated about without needing to be.

The duty cycle box shipped at 100, so every paste carried a
`set dutycycle 100` — or `set af 0` on pre-1.15 — whether the operator
meant it or not. Whoever flashed the node already chose; overwriting that
unasked is not this page's business. The box is now blank by default and
follows the blank-means-leave-alone rule the flood interval and owner info
already use: nothing sent, nothing read back in the verification block,
nothing explained. Type a percentage and it all comes back, af conversion
included.

The flood advert interval moves 24 -> 47, which is not a taste call: the
repeater firmware defaults to 47 hours itself from 1.16 on. It was 12
until commit 40180b8 raised it, so the hint now quotes whichever default
belongs to the version selected rather than asserting 12 at everyone.
docs.meshcore.io still says 12, but examples/simple_repeater/MyMesh.cpp
is the one that runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvFSXfzU5ZTvdksaqxJMRW
@github-actions

Copy link
Copy Markdown
Contributor

Preview: https://matkam.github.io/meshcore-settings/pr-24/

Served over HTTPS, so Web Serial and Web Bluetooth work — you can connect a
companion node and try the push panel against a real repeater. Updates on
every push to this branch and is deleted when the PR closes.


Generated by Claude Code

@matkam
matkam merged commit 331ffd2 into main Sep 13, 2026
3 checks passed
@matkam
matkam deleted the flood-47-duty-opt-in branch September 13, 2026 03:21
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