Initial checkin for Airtime Utilization

https://github.com/meshtastic/Meshtastic-device/issues/1034
This commit is contained in:
Jm Casler 2021-12-28 23:34:49 -08:00
parent f1c029d6da
commit 10dc8233ea
4 changed files with 79 additions and 48 deletions

View File

@ -1,17 +1,11 @@
#include "configuration.h"
#include "airtime.h" #include "airtime.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "configuration.h"
#define periodsToLog 24 #define periodsToLog 24
AirTime *airTime; 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. // Don't read out of this directly. Use the helper functions.
struct airtimeStruct { struct airtimeStruct {
uint32_t periodTX[periodsToLog]; // AirTime transmitted uint32_t periodTX[periodsToLog]; // AirTime transmitted
@ -36,14 +30,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
} else { } else {
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n"); 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()) { if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
@ -64,7 +61,6 @@ void airtimeRotatePeriod()
myNodeInfo.air_period_tx[0] = 0; myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0; myNodeInfo.air_period_rx[0] = 0;
airtimes.lastPeriodIndex = currentPeriodIndex(); airtimes.lastPeriodIndex = currentPeriodIndex();
} }
} }
@ -82,36 +78,63 @@ uint32_t *airtimeReport(reportTypes reportType)
return 0; return 0;
} }
uint8_t getPeriodsToLog() uint8_t AirTime::getPeriodsToLog()
{ {
return periodsToLog; 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") {} AirTime::AirTime() : concurrency::OSThread("AirTime") {}
int32_t AirTime::runOnce() int32_t AirTime::runOnce()
{ {
secSinceBoot++;
uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
if (firstTime) {
// DEBUG_MSG("AirTime::runOnce()\n"); // DEBUG_MSG("AirTime::runOnce()\n");
airtimeRotatePeriod(); airtimeRotatePeriod();
secSinceBoot++;
/* for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
This actually doesn't need to be run once per second but we currently use it for the this->channelUtilization[i] = 0;
secSinceBoot counter. }
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); return (1000 * 1);
} }

View File

@ -23,21 +23,16 @@
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel. 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 }; enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms); 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 *airtimeReport(reportTypes reportType);
uint32_t getSecondsPerPeriod();
class AirTime : private concurrency::OSThread class AirTime : private concurrency::OSThread
{ {
@ -45,6 +40,19 @@ class AirTime : private concurrency::OSThread
AirTime(); AirTime();
void logAirtime(reportTypes reportType, uint32_t airtime_ms); 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: protected:
virtual int32_t runOnce() override; virtual int32_t runOnce() override;

View File

@ -1398,11 +1398,11 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime); display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime);
#ifndef NO_ESP32 // Display Channel Utilization
// Show CPU Frequency. char chUtil[13];
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("CPU " + String(getCpuFrequencyMhz()) + "MHz"), sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
y + FONT_HEIGHT_SMALL * 1, "CPU " + String(getCpuFrequencyMhz()) + "MHz"); display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil),
#endif y + FONT_HEIGHT_SMALL * 1, chUtil);
// Line 3 // Line 3
if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude

View File

@ -503,11 +503,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->print("\"tx_log\": ["); res->print("\"tx_log\": [");
logArray = airtimeReport(TX_LOG); logArray = airtimeReport(TX_LOG);
for (int i = 0; i < getPeriodsToLog(); i++) { for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
uint32_t tmp; uint32_t tmp;
tmp = *(logArray + i); tmp = *(logArray + i);
res->printf("%d", tmp); res->printf("%d", tmp);
if (i != getPeriodsToLog() - 1) { if (i != airTime->getPeriodsToLog() - 1) {
res->print(", "); res->print(", ");
} }
} }
@ -516,11 +516,11 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->print("\"rx_log\": ["); res->print("\"rx_log\": [");
logArray = airtimeReport(RX_LOG); logArray = airtimeReport(RX_LOG);
for (int i = 0; i < getPeriodsToLog(); i++) { for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
uint32_t tmp; uint32_t tmp;
tmp = *(logArray + i); tmp = *(logArray + i);
res->printf("%d", tmp); res->printf("%d", tmp);
if (i != getPeriodsToLog() - 1) { if (i != airTime->getPeriodsToLog() - 1) {
res->print(", "); res->print(", ");
} }
} }
@ -529,19 +529,19 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->print("\"rx_all_log\": ["); res->print("\"rx_all_log\": [");
logArray = airtimeReport(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; uint32_t tmp;
tmp = *(logArray + i); tmp = *(logArray + i);
res->printf("%d", tmp); res->printf("%d", tmp);
if (i != getPeriodsToLog() - 1) { if (i != airTime->getPeriodsToLog() - 1) {
res->print(", "); res->print(", ");
} }
} }
res->println("],"); res->println("],");
res->printf("\"seconds_since_boot\": %u,\n", getSecondsSinceBoot()); res->printf("\"seconds_since_boot\": %u,\n", airTime->getSecondsSinceBoot());
res->printf("\"seconds_per_period\": %u,\n", getSecondsPerPeriod()); res->printf("\"seconds_per_period\": %u,\n", airTime->getSecondsPerPeriod());
res->printf("\"periods_to_log\": %u\n", getPeriodsToLog()); res->printf("\"periods_to_log\": %u\n", airTime->getPeriodsToLog());
res->println("},"); res->println("},");