From 25a540c28b384191db6da0e3d18e1742fcbd6d5e Mon Sep 17 00:00:00 2001 From: Jm Casler Date: Sat, 15 Jan 2022 09:44:29 -0800 Subject: [PATCH] Add airtime tx calculation as a 1hr rolling window --- src/airtime.cpp | 38 ++++++++++++++++++- src/airtime.h | 7 +++- src/mesh/generated/admin.pb.h | 2 +- src/mesh/generated/deviceonly.pb.h | 2 +- src/mesh/generated/mesh.pb.h | 13 ++++--- src/mesh/generated/radioconfig.pb.c | 1 + src/mesh/generated/radioconfig.pb.h | 58 ++++++++++++++++++++++++++--- src/mesh/http/ContentHandler.cpp | 3 +- 8 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/airtime.cpp b/src/airtime.cpp index eac58cfc9..b559c29e3 100644 --- a/src/airtime.cpp +++ b/src/airtime.cpp @@ -11,12 +11,16 @@ AirTime *airTime; void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms) { - // TODO: Is the airtimes array still necessary? It's now in myNodeInfo anyway + uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; + uint8_t channelUtilTXPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; if (reportType == TX_LOG) { DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms); 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); this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms; @@ -26,8 +30,9 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms) this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms; } - uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS; + // Log all airtime type for channel utilization this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms; + } uint8_t AirTime::currentPeriodIndex() @@ -100,6 +105,16 @@ float AirTime::channelUtilizationPercent() 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() @@ -107,10 +122,17 @@ 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; @@ -138,9 +160,21 @@ int32_t AirTime::runOnce() this->channelUtilization[utilPeriod] = 0; } + if (lastUtilPeriodTX != utilPeriodTX) { + lastUtilPeriodTX = utilPeriodTX; + + this->utilizationTX[utilPeriodTX] = 0; + } + // Update channel_utilization every second. myNodeInfo.channel_utilization = airTime->channelUtilizationPercent(); + + // Update channel_utilization every second. + myNodeInfo.air_util_tx = airTime->utilizationTXPercent(); + } + DEBUG_MSG("Minutes %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent()); + return (1000 * 1); } \ No newline at end of file diff --git a/src/airtime.h b/src/airtime.h index bf78ac3a9..58e0b53f4 100644 --- a/src/airtime.h +++ b/src/airtime.h @@ -27,7 +27,7 @@ #define CHANNEL_UTILIZATION_PERIODS 6 #define SECONDS_PER_PERIOD 3600 #define PERIODS_TO_LOG 24 - +#define MINUTES_IN_HOUR 60 enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG }; @@ -43,7 +43,11 @@ class AirTime : private concurrency::OSThread void logAirtime(reportTypes reportType, uint32_t airtime_ms); float channelUtilizationPercent(); + float utilizationTXPercent(); + + float UtilizationPercentTX(); uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS]; + uint32_t utilizationTX[MINUTES_IN_HOUR]; uint8_t currentPeriodIndex(); void airtimeRotatePeriod(); @@ -55,6 +59,7 @@ class AirTime : private concurrency::OSThread private: bool firstTime = true; uint8_t lastUtilPeriod = 0; + uint8_t lastUtilPeriodTX = 0; uint32_t secSinceBoot = 0; struct airtimeStruct { diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h index 2fced6a29..2468faa85 100644 --- a/src/mesh/generated/admin.pb.h +++ b/src/mesh/generated/admin.pb.h @@ -86,7 +86,7 @@ extern const pb_msgdesc_t AdminMessage_msg; #define AdminMessage_fields &AdminMessage_msg /* Maximum encoded size of messages (where known) */ -#define AdminMessage_size 535 +#define AdminMessage_size 1619 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index 34338b9c4..076649b21 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -125,7 +125,7 @@ extern const pb_msgdesc_t ChannelFile_msg; /* Maximum encoded size of messages (where known) */ #define LegacyRadioConfig_size 4 #define LegacyRadioConfig_LegacyPreferences_size 2 -#define DeviceState_size 9967 +#define DeviceState_size 9973 #define ChannelFile_size 832 #ifdef __cplusplus diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index c5c980a35..b2701e9b1 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -166,6 +166,7 @@ typedef struct _MyNodeInfo { uint32_t air_period_rx[24]; bool has_wifi; float channel_utilization; + float air_util_tx; } MyNodeInfo; typedef struct _Position { @@ -336,7 +337,7 @@ extern "C" { #define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0} #define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} -#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0} +#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} @@ -348,7 +349,7 @@ extern "C" { #define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0} #define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} -#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0} +#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}} @@ -383,6 +384,7 @@ extern "C" { #define MyNodeInfo_air_period_rx_tag 17 #define MyNodeInfo_has_wifi_tag 18 #define MyNodeInfo_channel_utilization_tag 19 +#define MyNodeInfo_air_util_tx_tag 20 #define Position_latitude_i_tag 1 #define Position_longitude_i_tag 2 #define Position_altitude_tag 3 @@ -569,7 +571,8 @@ X(a, STATIC, SINGULAR, UINT32, max_channels, 15) \ X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \ X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \ X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \ -X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) +X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) \ +X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 20) #define MyNodeInfo_CALLBACK NULL #define MyNodeInfo_DEFAULT NULL @@ -647,9 +650,9 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg; #define Data_size 260 #define MeshPacket_size 320 #define NodeInfo_size 270 -#define MyNodeInfo_size 451 +#define MyNodeInfo_size 457 #define LogRecord_size 81 -#define FromRadio_size 460 +#define FromRadio_size 466 #define ToRadio_size 323 #define ToRadio_PeerInfo_size 8 diff --git a/src/mesh/generated/radioconfig.pb.c b/src/mesh/generated/radioconfig.pb.c index 26930ae3c..040c62fb2 100644 --- a/src/mesh/generated/radioconfig.pb.c +++ b/src/mesh/generated/radioconfig.pb.c @@ -20,3 +20,4 @@ PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2) + diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index 255b5a88e..3e6eea360 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -79,6 +79,17 @@ typedef enum _PositionFlags { PositionFlags_POS_TIMESTAMP = 256 } PositionFlags; +typedef enum _InputEventChar { + InputEventChar_NULL = 0, + InputEventChar_UP = 17, + InputEventChar_DOWN = 18, + InputEventChar_LEFT = 19, + InputEventChar_RIGHT = 20, + InputEventChar_SELECT = 10, + InputEventChar_BACK = 27, + InputEventChar_CANCEL = 24 +} InputEventChar; + typedef enum _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType { RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 = 0, RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 = 1 @@ -157,6 +168,17 @@ typedef struct _RadioConfig_UserPreferences { char mqtt_password[32]; bool is_lora_tx_disabled; bool is_power_saving; + bool rotary1_enabled; + uint32_t rotary1_pin_a; + uint32_t rotary1_pin_b; + uint32_t rotary1_pin_press; + InputEventChar rotary1_event_cw; + InputEventChar rotary1_event_ccw; + InputEventChar rotary1_event_press; + bool canned_message_plugin_enabled; + char canned_message_plugin_allow_input_origin[16]; + char canned_message_plugin_messages[1024]; + bool canned_message_plugin_send_bell; } RadioConfig_UserPreferences; typedef struct _RadioConfig { @@ -190,6 +212,10 @@ typedef struct _RadioConfig { #define _PositionFlags_MAX PositionFlags_POS_TIMESTAMP #define _PositionFlags_ARRAYSIZE ((PositionFlags)(PositionFlags_POS_TIMESTAMP+1)) +#define _InputEventChar_MIN InputEventChar_NULL +#define _InputEventChar_MAX InputEventChar_BACK +#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_BACK+1)) + #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 #define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20+1)) @@ -201,9 +227,9 @@ extern "C" { /* Initializer values for message structs */ #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, "", "", 0} /* Field tags (for use in manual encoding/decoding) */ #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 @@ -276,6 +302,17 @@ extern "C" { #define RadioConfig_UserPreferences_mqtt_password_tag 156 #define RadioConfig_UserPreferences_is_lora_tx_disabled_tag 157 #define RadioConfig_UserPreferences_is_power_saving_tag 158 +#define RadioConfig_UserPreferences_rotary1_enabled_tag 160 +#define RadioConfig_UserPreferences_rotary1_pin_a_tag 161 +#define RadioConfig_UserPreferences_rotary1_pin_b_tag 162 +#define RadioConfig_UserPreferences_rotary1_pin_press_tag 163 +#define RadioConfig_UserPreferences_rotary1_event_cw_tag 164 +#define RadioConfig_UserPreferences_rotary1_event_ccw_tag 165 +#define RadioConfig_UserPreferences_rotary1_event_press_tag 166 +#define RadioConfig_UserPreferences_canned_message_plugin_enabled_tag 170 +#define RadioConfig_UserPreferences_canned_message_plugin_allow_input_origin_tag 171 +#define RadioConfig_UserPreferences_canned_message_plugin_messages_tag 172 +#define RadioConfig_UserPreferences_canned_message_plugin_send_bell_tag 173 #define RadioConfig_preferences_tag 1 /* Struct field encoding specification for nanopb */ @@ -355,7 +392,18 @@ X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \ X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \ X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) \ X(a, STATIC, SINGULAR, BOOL, is_lora_tx_disabled, 157) \ -X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) +X(a, STATIC, SINGULAR, BOOL, is_power_saving, 158) \ +X(a, STATIC, SINGULAR, BOOL, rotary1_enabled, 160) \ +X(a, STATIC, SINGULAR, UINT32, rotary1_pin_a, 161) \ +X(a, STATIC, SINGULAR, UINT32, rotary1_pin_b, 162) \ +X(a, STATIC, SINGULAR, UINT32, rotary1_pin_press, 163) \ +X(a, STATIC, SINGULAR, UENUM, rotary1_event_cw, 164) \ +X(a, STATIC, SINGULAR, UENUM, rotary1_event_ccw, 165) \ +X(a, STATIC, SINGULAR, UENUM, rotary1_event_press, 166) \ +X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_enabled, 170) \ +X(a, STATIC, SINGULAR, STRING, canned_message_plugin_allow_input_origin, 171) \ +X(a, STATIC, SINGULAR, STRING, canned_message_plugin_messages, 172) \ +X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_send_bell, 173) #define RadioConfig_UserPreferences_CALLBACK NULL #define RadioConfig_UserPreferences_DEFAULT NULL @@ -367,8 +415,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg; #define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg /* Maximum encoded size of messages (where known) */ -#define RadioConfig_size 532 -#define RadioConfig_UserPreferences_size 529 +#define RadioConfig_size 1616 +#define RadioConfig_UserPreferences_size 1613 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 1676359e7..72755e62b 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -624,6 +624,8 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) } res->println("],"); + res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent()); + res->printf("\"utilization_tx\": %3.2f%,\n", airTime->utilizationTXPercent()); 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()); @@ -661,7 +663,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->println("},"); res->println("\"device\": {"); - res->printf("\"channel_utilization\": %3.2f%,\n", airTime->channelUtilizationPercent()); res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count); res->println("},");