sforkowany z mirror/meshtastic-firmware
#588 - Calculate TX air time
rodzic
ded2b86e55
commit
e321528a6d
|
@ -38,8 +38,8 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/n
|
|||
;upload_port = /dev/ttyUSB0
|
||||
;monitor_port = /dev/ttyUSB0
|
||||
|
||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
||||
;monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
upload_port = /dev/cu.SLAB_USBtoUART
|
||||
monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
|
||||
; the default is esptool
|
||||
; upload_protocol = esp-prog
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
|
||||
#define hoursToLog 48
|
||||
|
||||
// Here for convience and to avoid magic numbers.
|
||||
// A reminder that there are 3600 seconds in an hour so I don't have
|
||||
// to keep googling it.
|
||||
// This can be changed to a smaller number to speed up testing.
|
||||
//
|
||||
uint16_t secondsPerHour = 3600;
|
||||
uint32_t lastMillis = 0;
|
||||
uint32_t secSinceBoot = 0;
|
||||
|
||||
// Don't read out of this directly. Use the helper functions.
|
||||
struct airtimeStruct {
|
||||
|
@ -16,65 +21,63 @@ struct airtimeStruct {
|
|||
|
||||
void logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
||||
{
|
||||
currentHourIndexReset();
|
||||
|
||||
if (reportType == TX_LOG) {
|
||||
airtimes.hourTX[currentHourIndex()] = airtimes.hourTX[currentHourIndex()] + round(airtime_ms / 1000);
|
||||
airtimes.hourTX[0] = airtimes.hourTX[0] + round(airtime_ms / 1000);
|
||||
} else if (reportType == RX_LOG) {
|
||||
airtimes.hourRX[currentHourIndex()] = airtimes.hourRX[currentHourIndex()] + round(airtime_ms / 1000);
|
||||
airtimes.hourRX[0] = airtimes.hourRX[0] + round(airtime_ms / 1000);
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
airtimes.hourRX_ALL[currentHourIndex()] = airtimes.hourRX_ALL[currentHourIndex()] + round(airtime_ms / 1000);
|
||||
airtimes.hourRX_ALL[0] = airtimes.hourRX_ALL[0] + round(airtime_ms / 1000);
|
||||
} else {
|
||||
// Unknown report type
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// This will let us easily switch away from using millis at some point.
|
||||
// todo: Don't use millis, instead maintain our own count of time since
|
||||
// boot in seconds.
|
||||
uint32_t secondsSinceBoot()
|
||||
uint32_t getSecondsSinceBoot()
|
||||
{
|
||||
return millis() / 1000;
|
||||
return secSinceBoot;
|
||||
}
|
||||
|
||||
uint8_t currentHourIndex()
|
||||
{
|
||||
// return ((secondsSinceBoot() - (secondsSinceBoot() / (hoursToLog * secondsPerHour))) / secondsPerHour);
|
||||
return ((secondsSinceBoot() / secondsPerHour) % hoursToLog);
|
||||
return ((getSecondsSinceBoot() / secondsPerHour) % hoursToLog);
|
||||
}
|
||||
|
||||
// currentHourIndexReset() should be called every time we receive a packet to log (either RX or TX)
|
||||
// and every time we are asked to report on airtime usage.
|
||||
void currentHourIndexReset()
|
||||
void airtimeCalculator()
|
||||
{
|
||||
if (airtimes.lastHourIndex != currentHourIndex()) {
|
||||
airtimes.hourTX[currentHourIndex()] = 0;
|
||||
airtimes.hourRX[currentHourIndex()] = 0;
|
||||
airtimes.hourRX_ALL[currentHourIndex()] = 0;
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
secSinceBoot++;
|
||||
// DEBUG_MSG("------- lastHourIndex %i currentHourIndex %i\n", airtimes.lastHourIndex, currentHourIndex());
|
||||
if (airtimes.lastHourIndex != currentHourIndex()) {
|
||||
for (int i = hoursToLog - 2; i >= 0; --i) {
|
||||
airtimes.hourTX[i + 1] = airtimes.hourTX[i];
|
||||
airtimes.hourRX[i + 1] = airtimes.hourRX[i];
|
||||
airtimes.hourRX_ALL[i + 1] = airtimes.hourRX_ALL[i];
|
||||
}
|
||||
airtimes.hourTX[0] = 0;
|
||||
|
||||
airtimes.lastHourIndex = currentHourIndex();
|
||||
airtimes.lastHourIndex = currentHourIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t *airtimeReport(reportTypes reportType)
|
||||
{
|
||||
static uint16_t array[hoursToLog];
|
||||
// currentHourIndexReset();
|
||||
|
||||
currentHourIndexReset();
|
||||
|
||||
for (int i = 0; i < hoursToLog; i++) {
|
||||
if (reportType == TX_LOG) {
|
||||
array[i] = airtimes.hourTX[(airtimes.lastHourIndex + i) % hoursToLog];
|
||||
} else if (reportType == RX_LOG) {
|
||||
array[i] = airtimes.hourRX[(airtimes.lastHourIndex + i) % hoursToLog];
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
array[i] = airtimes.hourRX_ALL[(airtimes.lastHourIndex + i) % hoursToLog];
|
||||
} else {
|
||||
// Unknown report type
|
||||
return array;
|
||||
}
|
||||
if (reportType == TX_LOG) {
|
||||
return airtimes.hourTX;
|
||||
} else if (reportType == RX_LOG) {
|
||||
return airtimes.hourRX;
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
return airtimes.hourRX_ALL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return array;
|
||||
uint8_t getHoursToLog()
|
||||
{
|
||||
return hoursToLog;
|
||||
}
|
|
@ -8,9 +8,11 @@ enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
|
|||
|
||||
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
|
||||
|
||||
void currentHourIndexReset();
|
||||
uint8_t currentHourIndex();
|
||||
void airtimeCalculator();
|
||||
|
||||
uint32_t secondsSinceBoot();
|
||||
uint8_t currentHourIndex();
|
||||
uint8_t getHoursToLog();
|
||||
|
||||
uint32_t getSecondsSinceBoot();
|
||||
|
||||
uint16_t *airtimeReport(reportTypes reportType);
|
|
@ -5,6 +5,7 @@
|
|||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "UBloxGPS.h"
|
||||
#include "airtime.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "power.h"
|
||||
|
@ -558,4 +559,7 @@ void loop()
|
|||
// We want to sleep as long as possible here - because it saves power
|
||||
mainDelay.delay(delayMsec);
|
||||
// if (didWake) DEBUG_MSG("wake!\n");
|
||||
|
||||
// Handles cleanup for the airtime calculator.
|
||||
airtimeCalculator();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "meshwifi/meshhttp.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "airtime.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "meshhttpStatic.h"
|
||||
#include "meshwifi/meshwifi.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "sleep.h"
|
||||
#include <HTTPBodyParser.hpp>
|
||||
#include <HTTPMultipartBodyParser.hpp>
|
||||
|
@ -64,6 +65,7 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res);
|
|||
void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
|
||||
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
||||
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res);
|
||||
void handleReport(HTTPRequest *req, HTTPResponse *res);
|
||||
|
||||
void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function<void()> next);
|
||||
void middlewareSpeedUp160(HTTPRequest *req, HTTPResponse *res, std::function<void()> next);
|
||||
|
@ -80,7 +82,7 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"}
|
|||
{".js", "text/javascript"}, {".png", "image/png"},
|
||||
{".jpg", "image/jpg"}, {".gz", "application/gzip"},
|
||||
{".gif", "image/gif"}, {".json", "application/json"},
|
||||
{".css", "text/css"}, {".ico","image/vnd.microsoft.icon"},
|
||||
{".css", "text/css"}, {".ico", "image/vnd.microsoft.icon"},
|
||||
{".svg", "image/svg+xml"}, {"", ""}};
|
||||
|
||||
void handleWebResponse()
|
||||
|
@ -248,6 +250,7 @@ void initWebServer()
|
|||
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
||||
ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks);
|
||||
ResourceNode *nodeJsonBlinkLED = new ResourceNode("/json/blink", "POST", &handleBlinkLED);
|
||||
ResourceNode *nodeJsonReport = new ResourceNode("/json/report", "GET", &handleReport);
|
||||
ResourceNode *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static/", "GET", &handleSpiffsBrowseStatic);
|
||||
ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic);
|
||||
|
||||
|
@ -267,6 +270,7 @@ void initWebServer()
|
|||
secureServer->registerNode(nodeJsonBlinkLED);
|
||||
secureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||
secureServer->registerNode(nodeJsonDelete);
|
||||
secureServer->registerNode(nodeJsonReport);
|
||||
secureServer->setDefaultNode(node404);
|
||||
|
||||
secureServer->addMiddleware(&middlewareSpeedUp240);
|
||||
|
@ -287,6 +291,7 @@ void initWebServer()
|
|||
insecureServer->registerNode(nodeJsonBlinkLED);
|
||||
insecureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||
insecureServer->registerNode(nodeJsonDelete);
|
||||
insecureServer->registerNode(nodeJsonReport);
|
||||
insecureServer->setDefaultNode(node404);
|
||||
|
||||
insecureServer->addMiddleware(&middlewareSpeedUp160);
|
||||
|
@ -458,26 +463,26 @@ void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
|||
|
||||
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||
{
|
||||
ResourceParameters *params = req->getParams();
|
||||
std::string paramValDelete;
|
||||
ResourceParameters *params = req->getParams();
|
||||
std::string paramValDelete;
|
||||
|
||||
res->setHeader("Content-Type", "application/json");
|
||||
if (params->getQueryParameter("delete", paramValDelete)) {
|
||||
std::string pathDelete = "/" + paramValDelete;
|
||||
if (SPIFFS.remove(pathDelete.c_str())) {
|
||||
Serial.println(pathDelete.c_str());
|
||||
res->println("{");
|
||||
res->println("\"status\": \"ok\"");
|
||||
res->println("}");
|
||||
return;
|
||||
} else {
|
||||
Serial.println(pathDelete.c_str());
|
||||
res->println("{");
|
||||
res->println("\"status\": \"Error\"");
|
||||
res->println("}");
|
||||
return;
|
||||
res->setHeader("Content-Type", "application/json");
|
||||
if (params->getQueryParameter("delete", paramValDelete)) {
|
||||
std::string pathDelete = "/" + paramValDelete;
|
||||
if (SPIFFS.remove(pathDelete.c_str())) {
|
||||
Serial.println(pathDelete.c_str());
|
||||
res->println("{");
|
||||
res->println("\"status\": \"ok\"");
|
||||
res->println("}");
|
||||
return;
|
||||
} else {
|
||||
Serial.println(pathDelete.c_str());
|
||||
res->println("{");
|
||||
res->println("\"status\": \"Error\"");
|
||||
res->println("}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
|
||||
|
@ -1041,6 +1046,85 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
|
|||
res->println("}");
|
||||
}
|
||||
|
||||
void handleReport(HTTPRequest *req, HTTPResponse *res)
|
||||
{
|
||||
|
||||
ResourceParameters *params = req->getParams();
|
||||
std::string content;
|
||||
|
||||
if (!params->getQueryParameter("content", content)) {
|
||||
content = "json";
|
||||
}
|
||||
|
||||
if (content == "json") {
|
||||
res->setHeader("Content-Type", "application/json");
|
||||
|
||||
} else {
|
||||
res->setHeader("Content-Type", "text/html");
|
||||
res->println("<pre>");
|
||||
}
|
||||
|
||||
res->println("{");
|
||||
|
||||
res->println("\"data\": {");
|
||||
|
||||
res->println("\"airtime\": {");
|
||||
|
||||
uint16_t *logArray;
|
||||
|
||||
res->print("\"tx_log\": [");
|
||||
|
||||
logArray = airtimeReport(TX_LOG);
|
||||
for (int i = 0; i < getHoursToLog(); i++) {
|
||||
uint16_t tmp;
|
||||
tmp = *(logArray + i);
|
||||
res->printf("%d", tmp);
|
||||
if (i != getHoursToLog() - 1) {
|
||||
res->print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
res->println("],");
|
||||
res->print("\"rx_log\": [");
|
||||
|
||||
logArray = airtimeReport(RX_LOG);
|
||||
for (int i = 0; i < getHoursToLog(); i++) {
|
||||
uint16_t tmp;
|
||||
tmp = *(logArray + i);
|
||||
res->printf("%d", tmp);
|
||||
if (i != getHoursToLog() - 1) {
|
||||
res->print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
res->println("],");
|
||||
res->print("\"rx_all_log\": [");
|
||||
|
||||
logArray = airtimeReport(RX_ALL_LOG);
|
||||
for (int i = 0; i < getHoursToLog(); i++) {
|
||||
uint16_t tmp;
|
||||
tmp = *(logArray + i);
|
||||
res->printf("%d", tmp);
|
||||
if (i != getHoursToLog() - 1) {
|
||||
res->print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
res->println("],");
|
||||
res->printf("\"seconds_since_boot\": %u,\n", getSecondsSinceBoot());
|
||||
res->printf("\"hours_to_log\": %u\n", getHoursToLog());
|
||||
|
||||
res->println("},");
|
||||
|
||||
res->println("\"something\": 123,");
|
||||
res->println("\"something_else\": 123");
|
||||
|
||||
res->println("},");
|
||||
|
||||
res->println("\"status\": \"ok\"");
|
||||
res->println("}");
|
||||
}
|
||||
|
||||
void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
|
||||
{
|
||||
res->setHeader("Content-Type", "application/json");
|
||||
|
|
Ładowanie…
Reference in New Issue