Refrain from transmitting if duty cycle exceeded

This commit is contained in:
GUVWAF 2022-11-26 20:50:00 +01:00
parent dfec37dfd0
commit 3b1e34efa1
4 changed files with 30 additions and 0 deletions

View File

@ -117,6 +117,20 @@ float AirTime::utilizationTXPercent()
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
// Get the amount of minutes we have to be silent before we can send again
uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
{
float newTxPercent = txPercent;
for (int8_t i = MINUTES_IN_HOUR-1; i >= 0; --i) {
newTxPercent -= ((float)this->utilizationTX[i] / (MS_IN_MINUTE * MINUTES_IN_HOUR / 100));
if (newTxPercent < dutyCycle)
return MINUTES_IN_HOUR-1-i;
}
return MINUTES_IN_HOUR;
}
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
}

View File

@ -29,6 +29,7 @@
#define PERIODS_TO_LOG 8
#define MINUTES_IN_HOUR 60
#define SECONDS_IN_MINUTE 60
#define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000)
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
@ -57,6 +58,7 @@ class AirTime : private concurrency::OSThread
uint32_t getSecondsPerPeriod();
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
private:
bool firstTime = true;

View File

@ -162,6 +162,7 @@ void NodeDB::installDefaultConfig()
config.has_network = true;
config.has_bluetooth = true;
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
config.lora.override_duty_cycle = false;
config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST;
config.lora.hop_limit = HOP_RELIABLE;

View File

@ -2,6 +2,7 @@
#include "Channels.h"
#include "CryptoEngine.h"
#include "NodeDB.h"
#include "MeshRadio.h"
#include "RTC.h"
#include "configuration.h"
#include "main.h"
@ -188,6 +189,18 @@ ErrorCode Router::send(MeshPacket *p)
{
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
// Abort sending if we are violating the duty cycle
if (!config.lora.override_duty_cycle && myRegion->dutyCycle != 100) {
float hourlyTxPercent = airTime->utilizationTXPercent();
if (hourlyTxPercent > myRegion->dutyCycle) {
uint8_t silentMinutes = airTime->getSilentMinutes(hourlyTxPercent, myRegion->dutyCycle);
DEBUG_MSG("WARNING: Duty cycle limit exceeded. Aborting send for now, you can send again in %d minutes.\n", silentMinutes);
Routing_Error err = Routing_Error_DUTY_CYCLE_LIMIT;
abortSendAndNak(err, p);
return err;
}
}
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
// assert(!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with
// assert