diff --git a/src/airtime.cpp b/src/airtime.cpp index 683b8f2c0..657f72689 100644 --- a/src/airtime.cpp +++ b/src/airtime.cpp @@ -1,17 +1,11 @@ -#include "configuration.h" #include "airtime.h" #include "NodeDB.h" +#include "configuration.h" #define periodsToLog 24 AirTime *airTime; -uint32_t secondsPerPeriod = 3600; -uint32_t lastMillis = 0; -uint32_t secSinceBoot = 0; - -// AirTime at; - // Don't read out of this directly. Use the helper functions. struct airtimeStruct { uint32_t periodTX[periodsToLog]; // AirTime transmitted @@ -36,14 +30,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms) } else { DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n"); } + + uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; + this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms; } -uint8_t currentPeriodIndex() +uint8_t AirTime::currentPeriodIndex() { - return ((getSecondsSinceBoot() / secondsPerPeriod) % periodsToLog); + return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % periodsToLog); } -void airtimeRotatePeriod() +void AirTime::airtimeRotatePeriod() { if (airtimes.lastPeriodIndex != currentPeriodIndex()) { @@ -64,7 +61,6 @@ void airtimeRotatePeriod() myNodeInfo.air_period_tx[0] = 0; myNodeInfo.air_period_rx[0] = 0; - airtimes.lastPeriodIndex = currentPeriodIndex(); } } @@ -82,36 +78,63 @@ uint32_t *airtimeReport(reportTypes reportType) return 0; } -uint8_t getPeriodsToLog() +uint8_t AirTime::getPeriodsToLog() { return periodsToLog; } -uint32_t getSecondsPerPeriod() +uint32_t AirTime::getSecondsPerPeriod() { - return secondsPerPeriod; + return SECONDS_PER_PERIOD; } -uint32_t getSecondsSinceBoot() +uint32_t AirTime::getSecondsSinceBoot() { - return secSinceBoot; + 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; } AirTime::AirTime() : concurrency::OSThread("AirTime") {} int32_t AirTime::runOnce() { - //DEBUG_MSG("AirTime::runOnce()\n"); - - airtimeRotatePeriod(); secSinceBoot++; - /* - This actually doesn't need to be run once per second but we currently use it for the - secSinceBoot counter. + uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; + + if (firstTime) { + // DEBUG_MSG("AirTime::runOnce()\n"); + + airtimeRotatePeriod(); + + for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) { + this->channelUtilization[i] = 0; + } + + firstTime = false; + lastUtilPeriod = utilPeriod; + + } else { + + // Reset the channelUtilization window when we roll over + if (lastUtilPeriod != utilPeriod) { + lastUtilPeriod = utilPeriod; + + this->channelUtilization[utilPeriod] = 0; + } + + DEBUG_MSG("Channel Utilization percent %3.1f\n", airTime->channelUtilizationPercent()); + } - If we have a better counter of how long the device has been online (and not millis()) - then we can change this to something less frequent. Maybe once ever 5 seconds? - */ return (1000 * 1); } \ No newline at end of file diff --git a/src/airtime.h b/src/airtime.h index 134bad47d..9c67759c3 100644 --- a/src/airtime.h +++ b/src/airtime.h @@ -23,21 +23,16 @@ RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel. */ + +#define CHANNEL_UTILIZATION_PERIODS 6 +#define SECONDS_PER_PERIOD 3600 + enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG }; void logAirtime(reportTypes reportType, uint32_t airtime_ms); -void airtimeRotatePeriod(); - -uint8_t currentPeriodIndex(); -uint8_t getPeriodsToLog(); - -uint32_t getSecondsSinceBoot(); - uint32_t *airtimeReport(reportTypes reportType); -uint32_t getSecondsPerPeriod(); - class AirTime : private concurrency::OSThread { @@ -45,6 +40,19 @@ class AirTime : private concurrency::OSThread AirTime(); void logAirtime(reportTypes reportType, uint32_t airtime_ms); + float channelUtilizationPercent(); + uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS]; + + uint8_t currentPeriodIndex(); + void airtimeRotatePeriod(); + uint8_t getPeriodsToLog(); + uint32_t getSecondsPerPeriod(); + uint32_t getSecondsSinceBoot(); + + private: + bool firstTime = true; + uint8_t lastUtilPeriod = 0; + uint32_t secSinceBoot = 0; protected: virtual int32_t runOnce() override; diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 502c60b02..cdf5ab1a5 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1398,11 +1398,11 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime); -#ifndef NO_ESP32 - // Show CPU Frequency. - display->drawString(x + SCREEN_WIDTH - display->getStringWidth("CPU " + String(getCpuFrequencyMhz()) + "MHz"), - y + FONT_HEIGHT_SMALL * 1, "CPU " + String(getCpuFrequencyMhz()) + "MHz"); -#endif + // Display Channel Utilization + char chUtil[13]; + sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent()); + display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), + y + FONT_HEIGHT_SMALL * 1, chUtil); // Line 3 if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 4174c0a23..b5ac29500 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -503,11 +503,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->print("\"tx_log\": ["); logArray = airtimeReport(TX_LOG); - for (int i = 0; i < getPeriodsToLog(); i++) { + for (int i = 0; i < airTime->getPeriodsToLog(); i++) { uint32_t tmp; tmp = *(logArray + i); res->printf("%d", tmp); - if (i != getPeriodsToLog() - 1) { + if (i != airTime->getPeriodsToLog() - 1) { res->print(", "); } } @@ -516,11 +516,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->print("\"rx_log\": ["); logArray = airtimeReport(RX_LOG); - for (int i = 0; i < getPeriodsToLog(); i++) { + for (int i = 0; i < airTime->getPeriodsToLog(); i++) { uint32_t tmp; tmp = *(logArray + i); res->printf("%d", tmp); - if (i != getPeriodsToLog() - 1) { + if (i != airTime->getPeriodsToLog() - 1) { res->print(", "); } } @@ -529,19 +529,19 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->print("\"rx_all_log\": ["); logArray = airtimeReport(RX_ALL_LOG); - for (int i = 0; i < getPeriodsToLog(); i++) { + for (int i = 0; i < airTime->getPeriodsToLog(); i++) { uint32_t tmp; tmp = *(logArray + i); res->printf("%d", tmp); - if (i != getPeriodsToLog() - 1) { + if (i != airTime->getPeriodsToLog() - 1) { res->print(", "); } } res->println("],"); - res->printf("\"seconds_since_boot\": %u,\n", getSecondsSinceBoot()); - res->printf("\"seconds_per_period\": %u,\n", getSecondsPerPeriod()); - res->printf("\"periods_to_log\": %u\n", getPeriodsToLog()); + res->printf("\"seconds_since_boot\": %u,\n", airTime->getSecondsSinceBoot()); + res->printf("\"seconds_per_period\": %u,\n", airTime->getSecondsPerPeriod()); + res->printf("\"periods_to_log\": %u\n", airTime->getPeriodsToLog()); res->println("},");