Repository navigation
fix(dc.gate): measure true TX duty on dmc-dev, default threshold 35 - #25
Merged
Merged
Conversation
getTxDutyCyclePercent() reported how depleted the tx_budget_ms token
bucket was ("% of the airtime budget consumed"). On DMC repeaters that
budget is loose (airtime_factor 1.0 = 50% allowance over a 1h window),
so real traffic never dents it and the reading sat at ~0: the observer
duty-cycle chart was flat and the region gate never fired.
Report the real duty cycle instead: TX airtime / wall-clock over a
rolling 60s window (TxDutyWindow, 6x10s slots, idle-safe decay). The
tx_budget_ms compliance limiter and all TX pacing are untouched; only
the metric (and thus the gate input and observer telemetry) changes.
dc_gate_threshold now means a true TX duty %, not "% of allowance".
Default left at 70; operators with gating enabled should re-set it to a
realistic duty (~35) or it will effectively never fire.
Tests: 6 new TxDutyWindow cases plus the existing 20 gating cases green;
heltec_v4_repeater_observer_mqtt builds and links.
(cherry picked from commit 76072aa)
dc.gate.thresh now compares against the true TX duty cycle over 60 s (previous commit), not the share of the duty-cycle budget used. The old default of 70 belonged to the budget meaning and would rarely trip: on the EU 10% sub-band a repeater can only sustain about 10%. New default 35 (hysteresis 10, so regions re-open below 25%). That is well above what normal traffic sustains, while a repeater transmitting 35% of the time empties its 360 s/h airtime reserve in about 24 minutes, so gating steps in before pacing has to. The threshold is now stored as "dc_gate_duty" instead of "dc_gate_thr". Values saved under the old key were budget percentages; they are left behind so upgraded nodes start from the new default rather than a budget value that means something else now. Docs (cli_commands.md, dmc-docs nl/en/de, DMC_DEVSYNC.md) describe the true-duty meaning, suggested thresholds per sub-band, and the upgrade.
test_region_gating, including the TxDutyWindow cases, has its own env because it needs RegionMap and TransportKeyStore. The unit-test workflow only ran native and native_kiss_modem, so these tests never ran in CI.
Elektr0Vodka
added a commit
that referenced
this pull request
Oct 19, 2026
…filter limiters, true TX duty, SenseCAP GPS) into dmc-dev-packetlog
Elektr0Vodka
added a commit
that referenced
this pull request
Oct 19, 2026
…filter limiters, true TX duty, SenseCAP GPS) into dmc-observer-dev Conflict resolutions: - Dispatcher.h, build.sh: kept observer (radio watchdog; observer build.sh already emits partsig for every ESP32 env). - CommonCLI.cpp: kept observer's /mqtt.json-gated legacy migration, then the GPS_DEFAULT_ON apply; dropped the obsolete "old default 70" comment now that the prefs key is dc_gate_duty. - variants/sensecap_solar: took dmc-dev (ENV_INCLUDE_GPS + GPS_DEFAULT_ON). The observer's -UENV_INCLUDE_GPS came from the old bulk revert 22eb9b8, not a deliberate choice. - platformio.ini native env, docs/cli_commands.md: took dmc-dev additions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
dc.gate.threshmeant different things on the two branches:We're standardising on true TX duty on both branches.
Changes
fix(dispatcher): cherry-pick of 76072aa (-x).getTxDutyCyclePercent()reads a rolling 60 sTxDutyWindow(6 × 10 s slots). Thetx_budget_mspacing is unchanged. The only conflict was the observer-only watchdog fields in theDispatcherconstructor.feat(dc.gate): default threshold 70 → 35, hysteresis stays 10, so regions re-open below 25%.dc_gate_thrtodc_gate_duty. Values saved under the old key were budget percentages, so they are deliberately left behind and upgraded nodes start at 35.cli_commands.md, dmc-docs nl/en/de,DMC_DEVSYNC.md. They now cover what is measured, how it differs fromset dutycycle, suggested thresholds per sub-band, and an upgrade note.ci:run-unit-tests.ymlnow also runsnative_region_gating. Until now the region-gating tests (includingTxDutyWindow) never ran in CI.Test
pio test -e native -e native_region_gating: 272/272 pass, including the 6TxDutyWindowcases.pio run -e Heltec_v3_repeaterbuilds.Before merging
dc.gatewill see the threshold reset to 35 after upgrading; this needs a line in the release notes.descriptions.nl/de.ts,firmwareRegistry.ts) still say "budget, default 70" and need a matching change in the toolbox repo.🤖 Generated with Claude Code