Duty cycle afleiden uit de ETSI sub-band van de ingestelde frequentie 馃馃 - #5
Open
efiten wants to merge 2 commits into
Open
Duty cycle afleiden uit de ETSI sub-band van de ingestelde frequentie 馃馃#5efiten wants to merge 2 commits into
efiten wants to merge 2 commits into
Conversation
The shipped default was airtime_factor 1.0, which get dutycycle reports as
50%. The default frequency is 869.618 MHz (platformio.ini:29), and the
869.4 to 869.65 sub-band is capped at 10% by ETSI EN 300 220-2. The default
therefore allowed five times what its own default frequency permits.
A single constant cannot express the limit, because it differs per sub-band:
868.5 is 1%, 869.0 is 0.1%, and 910 or 915 MHz carry no ETSI limit at all.
New src/helpers/DutyCycleLimits.{h,cpp} maps a frequency to its sub-band
limit, covering 863 to 870 MHz only. Every other frequency reports
DUTY_CYCLE_UNLIMITED, so US and ANZ builds keep the behaviour they had.
A frequency on a boundary takes the lower of the two sub-bands, and a gap
inside the band takes the tightest limit of the band.
New pref dutycycle_auto, default 1, serialized as dc_auto. While it is set,
the five getAirtimeBudgetFactor() overrides return the derived factor rather
than the stored one. Dispatcher::updateTxBudget() re-evaluates that call on
every pass (src/Dispatcher.cpp:42), so the limit follows set freq and
set radio without a restart and without touching Dispatcher.
set dutycycle <n>, set af and the companion CMD_SET_TUNING_PARAMS clear the
flag, so an explicit value stays in force until set dutycycle auto restores
it. get dutycycle, get af and CMD_GET_TUNING_PARAMS report the factor that
is actually in force.
Existing nodes migrate to auto: neither the legacy /com_prefs layout nor an
existing prefs.json carries dc_auto, so the struct default applies. A node
on 869.618 that never had its duty cycle changed drops from 50% to 10%.
simple_secure_chat is the exception: it writes its prefs struct as raw bytes
and dutycycle_auto reuses one of its unused padding bytes, which reads back
as 0 from a file written before this change, so those nodes keep their
stored airtime factor until set af or a factory reset.
Not addressed here: applyTempRadioParams (src/helpers/CommonCLI.cpp:251)
sets a temporary frequency without touching _prefs.freq, so during tempradio
the limit stays that of the stored frequency.
Refs Dutch-MeshCore#4
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJ6qztG9Mcx2cQ2rdJ8LCq
Records set dutycycle auto, the sub-band table it uses, the boundary and gap rules, and that get af now reports the factor in force rather than the stored value. Refs Dutch-MeshCore#4 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJ6qztG9Mcx2cQ2rdJ8LCq
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.
Fixes #4.
Probleem
De uitgeleverde default is
airtime_factor = 1.0, watget dutycycleals 50% rapporteert. De default frequentie is 869.618 MHz (platformio.ini:29), en de sub-band 869.4 tot 869.65 is door ETSI EN 300 220-2 begrensd op 10%. De default staat dus vijf keer hoger dan wat op zijn eigen default frequentie is toegestaan.Een enkele build-constante kan die limiet niet uitdrukken, want hij verschilt per sub-band: 868.5 mag 1%, 869.0 mag 0.1%, en op 910 of 915 MHz geldt er geen ETSI-limiet.
Wijziging
Nieuw
src/helpers/DutyCycleLimits.h/.cpp.getMaxDutyCyclePercent(freq)zoekt de sub-band op,dutyCycleToAirtimeFactor(percent)doet de conversie dieset dutycycleal gebruikte, engetEffectiveAirtimeFactor()combineert beide met de auto-vlag.De tabel dekt alleen 863 tot 870 MHz. Elke andere frequentie geeft
DUTY_CYCLE_UNLIMITED, dus US- en ANZ-builds houden het gedrag dat ze hadden. Een frequentie precies op een grens neemt de lagere van de twee sub-banden, een gat binnen de band neemt de strengste limiet van de band.Dit dekt ook de land-presets binnen de EU. Een preset die alleen in SF verschilt, zoals NL op SF7, zit op dezelfde sub-band als de algemene EU-preset en krijgt dezelfde limiet. Alleen de frequentie raakt de regelgeving.
Nieuwe pref
dutycycle_auto, default 1, geserialiseerd alsdc_auto. Zolang die aan staat geven de vijfgetAirtimeBudgetFactor()overrides de afgeleide factor terug in plaats van de opgeslagen.Dispatcher::updateTxBudget()roept die functie bij elke pas opnieuw aan (src/Dispatcher.cpp:42), dus de limiet volgtset freqenset radiozonder herstart en zonder wijziging inDispatcher.set dutycycle <n>,set afen de companionCMD_SET_TUNING_PARAMSzetten de vlag uit, zodat een expliciete waarde blijft staan totset dutycycle autohem terugzet.get dutycycle,get afenCMD_GET_TUNING_PARAMSrapporteren de factor die daadwerkelijk geldt.Gedragsverandering
Bestaande nodes migreren naar auto. Noch de legacy
/com_prefslayout, noch een bestaandeprefs.jsonbevatdc_auto, dus de struct-default geldt. Een node op 869.618 die zijn duty cycle nooit heeft aangepast, zakt van 50% naar 10%.simple_secure_chatis de uitzondering. Dat voorbeeld schrijft zijn prefs-struct als ruwe bytes endutycycle_autohergebruikt een van de bestaande padding-bytes, die uit een oudere file als 0 terugkomt. Die nodes houden hun opgeslagen airtime factor totset afof een factory reset.Buiten scope
applyTempRadioParams(src/helpers/CommonCLI.cpp:251) zet een tijdelijke frequentie zonder_prefs.freqaan te raken, dus tijdenstempradioblijft de limiet die van de opgeslagen frequentie. Dat is een aparte wijziging.De bestaande clamp
constrain(airtime_factor, 0, 9.0f)inloadPrefsInt()en de bovengrens van 100 inset dutycyclezijn ongemoeid gelaten. Daardoor kanautowel op 0.1% uitkomen terwijlset dutycycleniet lager dan 1 accepteert.Testen
test/test_duty_cycle_limits/bevat 8 gtest cases over de tabel, de grenzen, de gaten, de conversie en de auto-vlag, en[env:native]compileert nuDutyCycleLimits.cppmee.pio test -e nativekon ik hier niet draaien, op deze machine staat geen g++. In plaats daarvan zijn dezelfde 29 assertions als los C++ programma gecompileerd en uitgevoerd met g++ 14.2 op een Debian 12 host: alle 29 slagen. De gtest-suite zelf is dus nog niet gedraaid, alleen de logica die hij controleert.Compile-coverage voor alle vijf de node-types, plus beide takken van de gewijzigde include in de repeater-header:
Niet getest op hardware.
馃 Generated with Claude Code