sforkowany z mirror/meshtastic-firmware
Merge pull request #596 from mc-hamster/master
#588 - Calculate air time. TX and RX logging is done. #601 - tbeam draws too much power from usb1.2-legacy
commit
b75c7ad179
|
@ -38,8 +38,8 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/n
|
||||||
;upload_port = /dev/ttyUSB0
|
;upload_port = /dev/ttyUSB0
|
||||||
;monitor_port = /dev/ttyUSB0
|
;monitor_port = /dev/ttyUSB0
|
||||||
|
|
||||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
upload_port = /dev/cu.SLAB_USBtoUART
|
||||||
;monitor_port = /dev/cu.SLAB_USBtoUART
|
monitor_port = /dev/cu.SLAB_USBtoUART
|
||||||
|
|
||||||
; the default is esptool
|
; the default is esptool
|
||||||
; upload_protocol = esp-prog
|
; upload_protocol = esp-prog
|
||||||
|
|
2
proto
2
proto
|
@ -1 +1 @@
|
||||||
Subproject commit 323b814f4392ae0f9c42a0f14557c6b9333efce3
|
Subproject commit ce422b7c448906c6fee3eef64bbd41adfbc990f0
|
|
@ -268,7 +268,9 @@ bool Power::axp192Init()
|
||||||
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
DEBUG_MSG("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
|
||||||
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
DEBUG_MSG("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
|
||||||
|
|
||||||
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA); // actual limit (in HW) on the tbeam is 450mA
|
//axp.setChargeControlCur(AXP1XX_CHARGE_CUR_1320MA); // actual limit (in HW) on the tbeam is 450mA
|
||||||
|
axp.setChargeControlCur(AXP1XX_CHARGE_CUR_450MA); // There's no HW limit on the tbeam. Setting to 450mz to be a good neighbor on the usb bus.
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
// Not connected
|
// Not connected
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#include "airtime.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define periodsToLog 48
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
uint32_t secondsPerPeriod = 3600;
|
||||||
|
uint32_t lastMillis = 0;
|
||||||
|
uint32_t secSinceBoot = 0;
|
||||||
|
|
||||||
|
// Don't read out of this directly. Use the helper functions.
|
||||||
|
struct airtimeStruct {
|
||||||
|
uint16_t periodTX[periodsToLog];
|
||||||
|
uint16_t periodRX[periodsToLog];
|
||||||
|
uint16_t periodRX_ALL[periodsToLog];
|
||||||
|
uint8_t lastPeriodIndex;
|
||||||
|
} airtimes;
|
||||||
|
|
||||||
|
void logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (reportType == TX_LOG) {
|
||||||
|
airtimes.periodTX[0] = airtimes.periodTX[0] + round(airtime_ms / 1000);
|
||||||
|
} else if (reportType == RX_LOG) {
|
||||||
|
airtimes.periodRX[0] = airtimes.periodRX[0] + round(airtime_ms / 1000);
|
||||||
|
} else if (reportType == RX_ALL_LOG) {
|
||||||
|
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + round(airtime_ms / 1000);
|
||||||
|
} else {
|
||||||
|
// Unknown report type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t currentPeriodIndex()
|
||||||
|
{
|
||||||
|
return ((getSecondsSinceBoot() / secondsPerPeriod) % periodsToLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void airtimeCalculator()
|
||||||
|
{
|
||||||
|
if (millis() - lastMillis > 1000) {
|
||||||
|
lastMillis = millis();
|
||||||
|
secSinceBoot++;
|
||||||
|
if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
|
||||||
|
for (int i = periodsToLog - 2; i >= 0; --i) {
|
||||||
|
airtimes.periodTX[i + 1] = airtimes.periodTX[i];
|
||||||
|
airtimes.periodRX[i + 1] = airtimes.periodRX[i];
|
||||||
|
airtimes.periodRX_ALL[i + 1] = airtimes.periodRX_ALL[i];
|
||||||
|
}
|
||||||
|
airtimes.periodTX[0] = 0;
|
||||||
|
airtimes.periodRX[0] = 0;
|
||||||
|
airtimes.periodRX_ALL[0] = 0;
|
||||||
|
|
||||||
|
airtimes.lastPeriodIndex = currentPeriodIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t *airtimeReport(reportTypes reportType)
|
||||||
|
{
|
||||||
|
// currentHourIndexReset();
|
||||||
|
|
||||||
|
if (reportType == TX_LOG) {
|
||||||
|
return airtimes.periodTX;
|
||||||
|
} else if (reportType == RX_LOG) {
|
||||||
|
return airtimes.periodRX;
|
||||||
|
} else if (reportType == RX_ALL_LOG) {
|
||||||
|
return airtimes.periodRX_ALL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getPeriodsToLog()
|
||||||
|
{
|
||||||
|
return periodsToLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSecondsPerPeriod()
|
||||||
|
{
|
||||||
|
return secondsPerPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSecondsSinceBoot()
|
||||||
|
{
|
||||||
|
return secSinceBoot;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/*
|
||||||
|
TX_LOG - Time on air this device has transmitted
|
||||||
|
|
||||||
|
RX_LOG - Time on air used by valid and routable mesh packets, does not include
|
||||||
|
TX air time
|
||||||
|
|
||||||
|
RX_ALL_LOG - Time of all received lora packets. This includes packets that are not
|
||||||
|
for meshtastic devices. Does not include TX air time.
|
||||||
|
|
||||||
|
Example analytics:
|
||||||
|
|
||||||
|
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel.
|
||||||
|
|
||||||
|
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel, including
|
||||||
|
other lora radios.
|
||||||
|
|
||||||
|
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
|
||||||
|
*/
|
||||||
|
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
|
||||||
|
|
||||||
|
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
|
||||||
|
|
||||||
|
void airtimeCalculator();
|
||||||
|
|
||||||
|
uint8_t currentPeriodIndex();
|
||||||
|
uint8_t getPeriodsToLog();
|
||||||
|
|
||||||
|
uint32_t getSecondsSinceBoot();
|
||||||
|
|
||||||
|
uint16_t *airtimeReport(reportTypes reportType);
|
||||||
|
|
||||||
|
uint32_t getSecondsPerPeriod();
|
|
@ -5,6 +5,7 @@
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
#include "UBloxGPS.h"
|
#include "UBloxGPS.h"
|
||||||
|
#include "airtime.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
@ -569,4 +570,7 @@ void loop()
|
||||||
// We want to sleep as long as possible here - because it saves power
|
// We want to sleep as long as possible here - because it saves power
|
||||||
mainDelay.delay(delayMsec);
|
mainDelay.delay(delayMsec);
|
||||||
// if (didWake) DEBUG_MSG("wake!\n");
|
// if (didWake) DEBUG_MSG("wake!\n");
|
||||||
|
|
||||||
|
// Handles cleanup for the airtime calculator.
|
||||||
|
airtimeCalculator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "MeshTypes.h"
|
#include "MeshTypes.h"
|
||||||
#include "Observer.h"
|
#include "Observer.h"
|
||||||
#include "PointerQueue.h"
|
#include "PointerQueue.h"
|
||||||
|
#include "airtime.h"
|
||||||
#include "mesh.pb.h"
|
#include "mesh.pb.h"
|
||||||
|
|
||||||
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
|
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
|
||||||
|
@ -36,7 +37,7 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* This defines the SOLE API for talking to radios (because soon we will have alternate radio implementations)
|
* This defines the SOLE API for talking to radios (because soon we will have alternate radio implementations)
|
||||||
*/
|
*/
|
||||||
class RadioInterface
|
class RadioInterface
|
||||||
{
|
{
|
||||||
friend class MeshRadio; // for debugging we let that class touch pool
|
friend class MeshRadio; // for debugging we let that class touch pool
|
||||||
PointerQueue<MeshPacket> *rxDest = NULL;
|
PointerQueue<MeshPacket> *rxDest = NULL;
|
||||||
|
|
|
@ -58,7 +58,6 @@ void INTERRUPT_ATTR RadioLibInterface::isrTxLevel0()
|
||||||
*/
|
*/
|
||||||
RadioLibInterface *RadioLibInterface::instance;
|
RadioLibInterface *RadioLibInterface::instance;
|
||||||
|
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||||
bool RadioLibInterface::canSendImmediately()
|
bool RadioLibInterface::canSendImmediately()
|
||||||
{
|
{
|
||||||
|
@ -96,6 +95,10 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count the packet toward our TX airtime utilization.
|
||||||
|
// We only count it if it can be added to the TX queue.
|
||||||
|
logAirtime(TX_LOG, xmitMsec);
|
||||||
|
|
||||||
// We want all sending/receiving to be done by our daemon thread, We use a delay here because this packet might have been sent
|
// We want all sending/receiving to be done by our daemon thread, We use a delay here because this packet might have been sent
|
||||||
// in response to a packet we just received. So we want to make sure the other side has had a chance to reconfigure its radio
|
// in response to a packet we just received. So we want to make sure the other side has had a chance to reconfigure its radio
|
||||||
startTransmitTimer(true);
|
startTransmitTimer(true);
|
||||||
|
@ -205,12 +208,16 @@ void RadioLibInterface::completeSending()
|
||||||
|
|
||||||
void RadioLibInterface::handleReceiveInterrupt()
|
void RadioLibInterface::handleReceiveInterrupt()
|
||||||
{
|
{
|
||||||
|
uint32_t xmitMsec;
|
||||||
assert(isReceiving);
|
assert(isReceiving);
|
||||||
isReceiving = false;
|
isReceiving = false;
|
||||||
|
|
||||||
// read the number of actually received bytes
|
// read the number of actually received bytes
|
||||||
size_t length = iface->getPacketLength();
|
size_t length = iface->getPacketLength();
|
||||||
|
|
||||||
|
xmitMsec = getPacketTime(length);
|
||||||
|
logAirtime(RX_ALL_LOG, xmitMsec);
|
||||||
|
|
||||||
int state = iface->readData(radiobuf, length);
|
int state = iface->readData(radiobuf, length);
|
||||||
if (state != ERR_NONE) {
|
if (state != ERR_NONE) {
|
||||||
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
DEBUG_MSG("ignoring received packet due to error=%d\n", state);
|
||||||
|
@ -250,11 +257,14 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||||
|
|
||||||
printPacket("Lora RX", mp);
|
printPacket("Lora RX", mp);
|
||||||
|
|
||||||
|
xmitMsec = getPacketTime(mp);
|
||||||
|
logAirtime(RX_LOG, xmitMsec);
|
||||||
|
|
||||||
deliverToReceiver(mp);
|
deliverToReceiver(mp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** start an immediate transmit */
|
/** start an immediate transmit */
|
||||||
void RadioLibInterface::startSend(MeshPacket *txp)
|
void RadioLibInterface::startSend(MeshPacket *txp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "meshwifi/meshhttp.h"
|
#include "meshwifi/meshhttp.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
|
#include "PowerFSM.h"
|
||||||
|
#include "airtime.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "meshhttpStatic.h"
|
#include "meshhttpStatic.h"
|
||||||
#include "meshwifi/meshwifi.h"
|
#include "meshwifi/meshwifi.h"
|
||||||
#include "PowerFSM.h"
|
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include <HTTPBodyParser.hpp>
|
#include <HTTPBodyParser.hpp>
|
||||||
#include <HTTPMultipartBodyParser.hpp>
|
#include <HTTPMultipartBodyParser.hpp>
|
||||||
|
@ -64,6 +65,7 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
|
void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res);
|
||||||
void handleBlinkLED(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 middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function<void()> next);
|
||||||
void middlewareSpeedUp160(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"},
|
{".js", "text/javascript"}, {".png", "image/png"},
|
||||||
{".jpg", "image/jpg"}, {".gz", "application/gzip"},
|
{".jpg", "image/jpg"}, {".gz", "application/gzip"},
|
||||||
{".gif", "image/gif"}, {".json", "application/json"},
|
{".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"}, {"", ""}};
|
{".svg", "image/svg+xml"}, {"", ""}};
|
||||||
|
|
||||||
void handleWebResponse()
|
void handleWebResponse()
|
||||||
|
@ -248,6 +250,7 @@ void initWebServer()
|
||||||
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
||||||
ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks);
|
ResourceNode *nodeJsonScanNetworks = new ResourceNode("/json/scanNetworks", "GET", &handleScanNetworks);
|
||||||
ResourceNode *nodeJsonBlinkLED = new ResourceNode("/json/blink", "POST", &handleBlinkLED);
|
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 *nodeJsonSpiffsBrowseStatic = new ResourceNode("/json/spiffs/browse/static/", "GET", &handleSpiffsBrowseStatic);
|
||||||
ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic);
|
ResourceNode *nodeJsonDelete = new ResourceNode("/json/spiffs/delete/static", "DELETE", &handleSpiffsDeleteStatic);
|
||||||
|
|
||||||
|
@ -267,6 +270,7 @@ void initWebServer()
|
||||||
secureServer->registerNode(nodeJsonBlinkLED);
|
secureServer->registerNode(nodeJsonBlinkLED);
|
||||||
secureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
secureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||||
secureServer->registerNode(nodeJsonDelete);
|
secureServer->registerNode(nodeJsonDelete);
|
||||||
|
secureServer->registerNode(nodeJsonReport);
|
||||||
secureServer->setDefaultNode(node404);
|
secureServer->setDefaultNode(node404);
|
||||||
|
|
||||||
secureServer->addMiddleware(&middlewareSpeedUp240);
|
secureServer->addMiddleware(&middlewareSpeedUp240);
|
||||||
|
@ -287,6 +291,7 @@ void initWebServer()
|
||||||
insecureServer->registerNode(nodeJsonBlinkLED);
|
insecureServer->registerNode(nodeJsonBlinkLED);
|
||||||
insecureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
insecureServer->registerNode(nodeJsonSpiffsBrowseStatic);
|
||||||
insecureServer->registerNode(nodeJsonDelete);
|
insecureServer->registerNode(nodeJsonDelete);
|
||||||
|
insecureServer->registerNode(nodeJsonReport);
|
||||||
insecureServer->setDefaultNode(node404);
|
insecureServer->setDefaultNode(node404);
|
||||||
|
|
||||||
insecureServer->addMiddleware(&middlewareSpeedUp160);
|
insecureServer->addMiddleware(&middlewareSpeedUp160);
|
||||||
|
@ -458,26 +463,26 @@ void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
|
||||||
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
ResourceParameters *params = req->getParams();
|
ResourceParameters *params = req->getParams();
|
||||||
std::string paramValDelete;
|
std::string paramValDelete;
|
||||||
|
|
||||||
res->setHeader("Content-Type", "application/json");
|
res->setHeader("Content-Type", "application/json");
|
||||||
if (params->getQueryParameter("delete", paramValDelete)) {
|
if (params->getQueryParameter("delete", paramValDelete)) {
|
||||||
std::string pathDelete = "/" + paramValDelete;
|
std::string pathDelete = "/" + paramValDelete;
|
||||||
if (SPIFFS.remove(pathDelete.c_str())) {
|
if (SPIFFS.remove(pathDelete.c_str())) {
|
||||||
Serial.println(pathDelete.c_str());
|
Serial.println(pathDelete.c_str());
|
||||||
res->println("{");
|
res->println("{");
|
||||||
res->println("\"status\": \"ok\"");
|
res->println("\"status\": \"ok\"");
|
||||||
res->println("}");
|
res->println("}");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Serial.println(pathDelete.c_str());
|
Serial.println(pathDelete.c_str());
|
||||||
res->println("{");
|
res->println("{");
|
||||||
res->println("\"status\": \"Error\"");
|
res->println("\"status\": \"Error\"");
|
||||||
res->println("}");
|
res->println("}");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
|
void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
|
||||||
|
@ -1041,6 +1046,98 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
|
||||||
res->println("}");
|
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 < getPeriodsToLog(); i++) {
|
||||||
|
uint16_t tmp;
|
||||||
|
tmp = *(logArray + i);
|
||||||
|
res->printf("%d", tmp);
|
||||||
|
if (i != getPeriodsToLog() - 1) {
|
||||||
|
res->print(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res->println("],");
|
||||||
|
res->print("\"rx_log\": [");
|
||||||
|
|
||||||
|
logArray = airtimeReport(RX_LOG);
|
||||||
|
for (int i = 0; i < getPeriodsToLog(); i++) {
|
||||||
|
uint16_t tmp;
|
||||||
|
tmp = *(logArray + i);
|
||||||
|
res->printf("%d", tmp);
|
||||||
|
if (i != getPeriodsToLog() - 1) {
|
||||||
|
res->print(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res->println("],");
|
||||||
|
res->print("\"rx_all_log\": [");
|
||||||
|
|
||||||
|
logArray = airtimeReport(RX_ALL_LOG);
|
||||||
|
for (int i = 0; i < getPeriodsToLog(); i++) {
|
||||||
|
uint16_t tmp;
|
||||||
|
tmp = *(logArray + i);
|
||||||
|
res->printf("%d", tmp);
|
||||||
|
if (i != 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->println("},");
|
||||||
|
|
||||||
|
res->println("\"wifi\": {");
|
||||||
|
|
||||||
|
res->println("\"rssi\": " + String(WiFi.RSSI()) + ",");
|
||||||
|
|
||||||
|
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
|
||||||
|
res->println("\"ip\": \"" + String(WiFi.softAPIP().toString().c_str()) + "\"");
|
||||||
|
} else {
|
||||||
|
res->println("\"ip\": \"" + String(WiFi.localIP().toString().c_str()) + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
res->println("},");
|
||||||
|
|
||||||
|
res->println("\"test\": 123");
|
||||||
|
|
||||||
|
res->println("},");
|
||||||
|
|
||||||
|
res->println("\"status\": \"ok\"");
|
||||||
|
res->println("}");
|
||||||
|
}
|
||||||
|
|
||||||
void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
|
void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
res->setHeader("Content-Type", "application/json");
|
res->setHeader("Content-Type", "application/json");
|
||||||
|
|
Ładowanie…
Reference in New Issue