diff --git a/src/airtime.cpp b/src/airtime.cpp index c72a21d54..ae3b30811 100644 --- a/src/airtime.cpp +++ b/src/airtime.cpp @@ -117,6 +117,31 @@ float AirTime::utilizationTXPercent() return (float(sum) / float(MS_IN_HOUR)) * 100; } +bool AirTime::isTxAllowedChannelUtil(bool polite) +{ + uint8_t percentage = (polite ? polite_channel_util_percent : max_channel_util_percent); + if (channelUtilizationPercent() < percentage) { + return true; + } else { + LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage); + return false; + } +} + + +bool AirTime::isTxAllowedAirUtil() +{ + if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) { + if (utilizationTXPercent() < polite_tx_util_percent) { + return true; + } else { + LOG_WARN("Tx air utilization is >%d percent. Skipping this opportunity to send.\n", polite_tx_util_percent); + return false; + } + } + return true; +} + // Get the amount of minutes we have to be silent before we can send again uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle) { diff --git a/src/airtime.h b/src/airtime.h index 3f38f39f8..2d1f1e2d9 100644 --- a/src/airtime.h +++ b/src/airtime.h @@ -4,6 +4,7 @@ #include "configuration.h" #include #include +#include "MeshRadio.h" /* TX_LOG - Time on air this device has transmitted @@ -59,12 +60,17 @@ class AirTime : private concurrency::OSThread uint32_t getSecondsSinceBoot(); uint32_t *airtimeReport(reportTypes reportType); uint8_t getSilentMinutes(float txPercent, float dutyCycle); + bool isTxAllowedChannelUtil(bool polite=false); + bool isTxAllowedAirUtil(); private: bool firstTime = true; uint8_t lastUtilPeriod = 0; uint8_t lastUtilPeriodTX = 0; uint32_t secSinceBoot = 0; + uint8_t max_channel_util_percent = 40; + uint8_t polite_channel_util_percent = 25; + uint8_t polite_tx_util_percent = 5; struct airtimeStruct { uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted diff --git a/src/mesh/SinglePortModule.h b/src/mesh/SinglePortModule.h index 57db73221..2e587cb89 100644 --- a/src/mesh/SinglePortModule.h +++ b/src/mesh/SinglePortModule.h @@ -18,9 +18,6 @@ class SinglePortModule : public MeshModule SinglePortModule(const char *_name, PortNum _ourPortNum) : MeshModule(_name), ourPortNum(_ourPortNum) {} protected: - uint32_t max_channel_util_percent = 40; - uint32_t polite_channel_util_percent = 25; - /** * @return true if you want to receive the specified portnum */ diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index d8047c5f0..5dc05cd95 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -65,8 +65,10 @@ int32_t NodeInfoModule::runOnce() bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; - LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies); - sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) + if (airTime->isTxAllowedAirUtil()) { + LOG_INFO("Sending our nodeinfo to mesh (wantReplies=%d)\n", requestReplies); + sendOurNodeInfo(NODENUM_BROADCAST, requestReplies); // Send our info (don't request replies) + } return default_broadcast_interval_secs * 1000; -} \ No newline at end of file +} diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 6680eaba5..4d119043c 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -144,7 +144,7 @@ int32_t PositionModule::runOnce() if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) { // Only send packets if the channel is less than 40% utilized. - if (airTime->channelUtilizationPercent() < max_channel_util_percent) { + if (airTime->isTxAllowedChannelUtil()) { if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { lastGpsSend = now; @@ -158,14 +158,12 @@ int32_t PositionModule::runOnce() LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.timestamp, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies); } - } else { - LOG_WARN("Channel utilization is >40 percent. Skipping this opportunity to send.\n"); } } else if (config.position.position_broadcast_smart_enabled) { // Only send packets if the channel is less than 25% utilized. - if (airTime->channelUtilizationPercent() < polite_channel_util_percent) { + if (airTime->isTxAllowedChannelUtil(true)) { NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position @@ -208,8 +206,6 @@ int32_t PositionModule::runOnce() lastGpsSend = now; } } - } else { - LOG_WARN("Channel utilization is >25 percent. Skipping this opportunity to send.\n"); } } diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 109d8b5b1..5f96661e5 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -13,11 +13,10 @@ int32_t DeviceTelemetryModule::runOnce() { -#ifndef ARCH_PORTDUINO uint32_t now = millis(); if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.device_update_interval)) && - airTime->channelUtilizationPercent() < max_channel_util_percent) { + airTime->isTxAllowedChannelUtil() && airTime->isTxAllowedAirUtil()) { sendTelemetry(); lastSentToMesh = now; } else if (service.isToPhoneQueueEmpty()) { @@ -26,7 +25,6 @@ int32_t DeviceTelemetryModule::runOnce() sendTelemetry(NODENUM_BROADCAST, true); } return sendToPhoneIntervalMs; -#endif } bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 3bf303157..2a29405d3 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -107,7 +107,7 @@ int32_t EnvironmentTelemetryModule::runOnce() uint32_t now = millis(); if ((lastSentToMesh == 0 || (now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval)) && - airTime->channelUtilizationPercent() < max_channel_util_percent) { + airTime->isTxAllowedAirUtil()) { sendTelemetry(); lastSentToMesh = now; } else if (service.isToPhoneQueueEmpty()) { diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/esp32/RangeTestModule.cpp index 1624a972b..52a18def5 100644 --- a/src/modules/esp32/RangeTestModule.cpp +++ b/src/modules/esp32/RangeTestModule.cpp @@ -73,10 +73,8 @@ int32_t RangeTestModule::runOnce() LOG_INFO("fixed_position() %d\n", config.position.fixed_position); // Only send packets if the channel is less than 25% utilized. - if (airTime->channelUtilizationPercent() < 25) { + if (airTime->isTxAllowedChannelUtil(true)) { rangeTestModuleRadio->sendPayload(); - } else { - LOG_WARN("RangeTest - Channel utilization is >25 percent. Skipping this opportunity to send.\n"); } return (senderHeartbeat); diff --git a/src/modules/esp32/StoreForwardModule.cpp b/src/modules/esp32/StoreForwardModule.cpp index bf0421a9a..b5e0b1e65 100644 --- a/src/modules/esp32/StoreForwardModule.cpp +++ b/src/modules/esp32/StoreForwardModule.cpp @@ -21,7 +21,7 @@ int32_t StoreForwardModule::runOnce() // Send out the message queue. if (this->busy) { // Only send packets if the channel is less than 25% utilized. - if (airTime->channelUtilizationPercent() < polite_channel_util_percent) { + if (airTime->isTxAllowedChannelUtil(true)) { storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index); if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) { // Tell the client we're done sending @@ -34,12 +34,10 @@ int32_t StoreForwardModule::runOnce() } else { this->packetHistoryTXQueue_index++; } - } else { - LOG_WARN("*** Channel utilization is too high. Retrying later.\n"); } LOG_DEBUG("*** SF bitrate = %f bytes / sec\n", myNodeInfo.bitrate); - } else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && (airTime->channelUtilizationPercent() < polite_channel_util_percent)) { + } else if ((millis() - lastHeartbeat > (heartbeatInterval * 1000)) && airTime->isTxAllowedChannelUtil(true)) { lastHeartbeat = millis(); LOG_INFO("*** Sending heartbeat\n"); StoreAndForward sf = StoreAndForward_init_zero;