Files
firmware/src/airtime.cpp

180 lines
5.3 KiB
C++
Raw Normal View History

#include "airtime.h"
#include "NodeDB.h"
#include "configuration.h"
AirTime *airTime;
// Don't read out of this directly. Use the helper functions.
2021-12-29 00:45:36 -08:00
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
2021-12-29 00:45:36 -08:00
uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
uint8_t channelUtilTXPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
2021-12-29 00:45:36 -08:00
if (reportType == TX_LOG) {
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
2021-12-29 00:45:36 -08:00
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
this->utilizationTX[channelUtilTXPeriod] = channelUtilization[channelUtilTXPeriod] + airtime_ms;
} else if (reportType == RX_LOG) {
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
2021-12-29 00:45:36 -08:00
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
2021-12-29 00:45:36 -08:00
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
}
// Log all airtime type for channel utilization
this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms;
}
uint8_t AirTime::currentPeriodIndex()
{
2021-12-29 00:36:15 -08:00
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
}
void AirTime::airtimeRotatePeriod()
{
2021-12-29 00:45:36 -08:00
if (this->airtimes.lastPeriodIndex != currentPeriodIndex()) {
2022-01-15 09:50:10 -08:00
//DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex());
2021-12-29 00:36:15 -08:00
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
2021-12-29 00:45:36 -08:00
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
2020-12-26 22:39:43 -08:00
}
2021-12-29 00:45:36 -08:00
this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0;
myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0;
2021-12-29 00:45:36 -08:00
this->airtimes.lastPeriodIndex = currentPeriodIndex();
}
}
2021-12-29 00:45:36 -08:00
uint32_t *AirTime::airtimeReport(reportTypes reportType)
{
2020-12-26 22:39:43 -08:00
if (reportType == TX_LOG) {
2021-12-29 00:45:36 -08:00
return this->airtimes.periodTX;
2020-12-26 22:39:43 -08:00
} else if (reportType == RX_LOG) {
2021-12-29 00:45:36 -08:00
return this->airtimes.periodRX;
2020-12-26 22:39:43 -08:00
} else if (reportType == RX_ALL_LOG) {
2021-12-29 00:45:36 -08:00
return this->airtimes.periodRX_ALL;
}
2020-12-26 22:39:43 -08:00
return 0;
}
uint8_t AirTime::getPeriodsToLog()
{
2021-12-29 00:36:15 -08:00
return PERIODS_TO_LOG;
}
uint32_t AirTime::getSecondsPerPeriod()
2020-12-26 22:39:43 -08:00
{
return SECONDS_PER_PERIOD;
}
uint32_t AirTime::getSecondsSinceBoot()
{
return this->secSinceBoot;
}
float AirTime::channelUtilizationPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i];
// DEBUG_MSG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
}
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
}
float AirTime::utilizationTXPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
sum += this->utilizationTX[i];
}
return (float(sum) / float(MINUTES_IN_HOUR * 10 * 1000)) * 100;
}
AirTime::AirTime() : concurrency::OSThread("AirTime") {}
int32_t AirTime::runOnce()
{
secSinceBoot++;
uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
uint8_t utilPeriodTX = (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
if (firstTime) {
airtimeRotatePeriod();
// Init utilizationTX window to all 0
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
this->utilizationTX[i] = 0;
}
// Init channelUtilization window to all 0
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
this->channelUtilization[i] = 0;
}
// Init airtime windows to all 0
for (int i = 0; i < PERIODS_TO_LOG; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;
//myNodeInfo.air_period_tx[i] = 0;
//myNodeInfo.air_period_rx[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
} else {
// Reset the channelUtilization window when we roll over
if (lastUtilPeriod != utilPeriod) {
lastUtilPeriod = utilPeriod;
this->channelUtilization[utilPeriod] = 0;
}
if (lastUtilPeriodTX != utilPeriodTX) {
lastUtilPeriodTX = utilPeriodTX;
this->utilizationTX[utilPeriodTX] = 0;
}
2021-12-28 23:37:23 -08:00
// Update channel_utilization every second.
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
// Update channel_utilization every second.
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
2022-01-15 09:50:10 -08:00
//DEBUG_MSG("Minutes %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
return (1000 * 1);
}