>(), "/", 10);
+
+ // create json output structure
+ Json filesystemObj = Json::object{
+ {"total", String(FSCom.totalBytes()).c_str()},
+ {"used", String(FSCom.usedBytes()).c_str()},
+ {"free", String(FSCom.totalBytes() - FSCom.usedBytes()).c_str()},
+ };
+
+ Json jsonObjInner = Json::object{{"files", Json(*fileList)},
+ {"filesystem", filesystemObj}
+ };
+
+ Json jsonObjOuter = Json::object{{"data", jsonObjInner}, {"status", "ok"}};
+
+ // serialize and write it to the stream
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
+}
void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
{
+ using namespace json11;
+
ResourceParameters *params = req->getParams();
std::string paramValDelete;
@@ -375,15 +376,15 @@ void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res)
std::string pathDelete = "/" + paramValDelete;
if (FSCom.remove(pathDelete.c_str())) {
Serial.println(pathDelete.c_str());
- res->println("{");
- res->println("\"status\": \"ok\"");
- res->println("}");
+ Json jsonObjOuter = Json::object{{"status", "ok"}};
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
return;
} else {
Serial.println(pathDelete.c_str());
- res->println("{");
- res->println("\"status\": \"Error\"");
- res->println("}");
+ Json jsonObjOuter = Json::object{{"status", "Error"}};
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
return;
}
}
@@ -600,6 +601,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
void handleReport(HTTPRequest *req, HTTPResponse *res)
{
+ using namespace json11;
ResourceParameters *params = req->getParams();
std::string content;
@@ -618,104 +620,89 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)
res->println("");
}
- res->println("{");
-
- res->println("\"data\": {");
-
- res->println("\"airtime\": {");
-
+ // data->airtime->tx_log
+ std::vector txLogValues;
uint32_t *logArray;
-
- res->print("\"tx_log\": [");
-
logArray = airTime->airtimeReport(TX_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
uint32_t tmp;
tmp = *(logArray + i);
- res->printf("%d", tmp);
- if (i != airTime->getPeriodsToLog() - 1) {
- res->print(", ");
- }
+ txLogValues.push_back(String(tmp));
}
- res->println("],");
- res->print("\"rx_log\": [");
-
+ // data->airtime->rx_log
+ std::vector rxLogValues;
logArray = airTime->airtimeReport(RX_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
uint32_t tmp;
tmp = *(logArray + i);
- res->printf("%d", tmp);
- if (i != airTime->getPeriodsToLog() - 1) {
- res->print(", ");
- }
+ rxLogValues.push_back(String(tmp));
}
- res->println("],");
- res->print("\"rx_all_log\": [");
-
+ // data->airtime->rx_all_log
+ std::vector rxAllLogValues;
logArray = airTime->airtimeReport(RX_ALL_LOG);
for (int i = 0; i < airTime->getPeriodsToLog(); i++) {
uint32_t tmp;
tmp = *(logArray + i);
- res->printf("%d", tmp);
- if (i != airTime->getPeriodsToLog() - 1) {
- res->print(", ");
- }
+ rxAllLogValues.push_back(String(tmp));
}
- 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());
-
- res->println("},");
-
- res->println("\"wifi\": {");
-
- res->println("\"rssi\": " + String(WiFi.RSSI()) + ",");
+ Json jsonObjAirtime = Json::object{
+ {"tx_log", Json(txLogValues)},
+ {"rx_log", Json(rxLogValues)},
+ {"rx_all_log", Json(rxAllLogValues)},
+ {"channel_utilization", Json(airTime->channelUtilizationPercent())},
+ {"utilization_tx", Json(airTime->utilizationTXPercent())},
+ {"seconds_since_boot", Json(int(airTime->getSecondsSinceBoot()))},
+ {"seconds_per_period", Json(int(airTime->getSecondsPerPeriod()))},
+ {"periods_to_log", Json(airTime->getPeriodsToLog())},
+ };
+ // data->wifi
+ String ipStr;
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
- res->println("\"ip\": \"" + String(WiFi.softAPIP().toString().c_str()) + "\"");
+ ipStr = String(WiFi.softAPIP().toString());
} else {
- res->println("\"ip\": \"" + String(WiFi.localIP().toString().c_str()) + "\"");
+ ipStr = String(WiFi.localIP().toString());
}
+ Json jsonObjWifi = Json::object{
+ {"rssi", String(WiFi.RSSI())},
+ {"ip", ipStr.c_str()}
+ };
- res->println("},");
+ // data->memory
+ Json jsonObjMemory = Json::object{{"heap_total", Json(int(ESP.getHeapSize()))},
+ {"heap_free", Json(int(ESP.getFreeHeap()))},
+ {"psram_total", Json(int(ESP.getPsramSize()))},
+ {"psram_free", Json(int(ESP.getFreePsram()))},
+ {"fs_total", String(FSCom.totalBytes()).c_str()},
+ {"fs_used", String(FSCom.usedBytes()).c_str()},
+ {"fs_free", String(FSCom.totalBytes() - FSCom.usedBytes()).c_str()}};
- res->println("\"memory\": {");
- res->printf("\"heap_total\": %d,\n", ESP.getHeapSize());
- res->printf("\"heap_free\": %d,\n", ESP.getFreeHeap());
- res->printf("\"psram_total\": %d,\n", ESP.getPsramSize());
- res->printf("\"psram_free\": %d,\n", ESP.getFreePsram());
- res->println("\"fs_total\" : " + String(FSCom.totalBytes()) + ",");
- res->println("\"fs_used\" : " + String(FSCom.usedBytes()) + ",");
- res->println("\"fs_free\" : " + String(FSCom.totalBytes() - FSCom.usedBytes()));
- res->println("},");
+ // data->power
+ Json jsonObjPower = Json::object{{"battery_percent", Json(powerStatus->getBatteryChargePercent())},
+ {"battery_voltage_mv", Json(powerStatus->getBatteryVoltageMv())},
+ {"has_battery", BoolToString(powerStatus->getHasBattery())},
+ {"has_usb", BoolToString(powerStatus->getHasUSB())},
+ {"is_charging", BoolToString(powerStatus->getIsCharging())}};
- res->println("\"power\": {");
- res->printf("\"battery_percent\": %u,\n", powerStatus->getBatteryChargePercent());
- res->printf("\"battery_voltage_mv\": %u,\n", powerStatus->getBatteryVoltageMv());
- res->printf("\"has_battery\": %s,\n", BoolToString(powerStatus->getHasBattery()));
- res->printf("\"has_usb\": %s,\n", BoolToString(powerStatus->getHasUSB()));
- res->printf("\"is_charging\": %s\n", BoolToString(powerStatus->getIsCharging()));
- res->println("},");
+ // data->device
+ Json jsonObjDevice = Json::object{{"reboot_counter", Json(int(myNodeInfo.reboot_count))}};
- res->println("\"device\": {");
- res->printf("\"reboot_counter\": %d\n", myNodeInfo.reboot_count);
- res->println("},");
+ // data->radio
+ Json jsonObjRadio = Json::object{{"frequency", Json(RadioLibInterface::instance->getFreq())},
+ {"lora_channel", Json(int(RadioLibInterface::instance->getChannelNum()))}};
- res->println("\"radio\": {");
- res->printf("\"frequecy\": %f,\n", RadioLibInterface::instance->getFreq());
- res->printf("\"lora_channel\": %d\n", RadioLibInterface::instance->getChannelNum());
- res->println("}");
+ // collect data to inner data object
+ Json jsonObjInner = Json::object{{"airtime", jsonObjAirtime}, {"wifi", jsonObjWifi}, {"memory", jsonObjMemory},
+ {"power", jsonObjPower}, {"device", jsonObjDevice}, {"radio", jsonObjRadio}};
- res->println("},");
-
- res->println("\"status\": \"ok\"");
- res->println("}");
+ // create json output structure
+ Json jsonObjOuter = Json::object{{"data", jsonObjInner}, {"status", "ok"}};
+ // serialize and write it to the stream
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
}
/*
@@ -912,6 +899,8 @@ void handleRestart(HTTPRequest *req, HTTPResponse *res)
void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
{
+ using namespace json11;
+
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "POST");
@@ -938,28 +927,25 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
screen->blink();
}
- res->println("{");
- res->println("\"status\": \"ok\"");
- res->println("}");
+ Json jsonObjOuter = Json::object{{"status", "ok"}};
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
}
void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
{
+ using namespace json11;
+
res->setHeader("Content-Type", "application/json");
res->setHeader("Access-Control-Allow-Origin", "*");
res->setHeader("Access-Control-Allow-Methods", "GET");
// res->setHeader("Content-Type", "text/html");
int n = WiFi.scanNetworks();
- res->println("{");
- res->println("\"data\": {");
- if (n == 0) {
- // No networks found.
- res->println("\"networks\": []");
-
- } else {
- res->println("\"networks\": [");
+ // build list of network objects
+ std::vector networkObjs;
+ if (n > 0) {
for (int i = 0; i < n; ++i) {
char ssidArray[50];
String ssidString = String(WiFi.SSID(i));
@@ -967,19 +953,20 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res)
ssidString.toCharArray(ssidArray, 50);
if (WiFi.encryptionType(i) != WIFI_AUTH_OPEN) {
- res->printf("{\"ssid\": \"%s\",\"rssi\": %d}", ssidArray, WiFi.RSSI(i));
- if (i != n - 1) {
- res->printf(",");
- }
+ Json thisNetwork = Json::object{{"ssid", ssidArray}, {"rssi", WiFi.RSSI(i)}};
+ networkObjs.push_back(thisNetwork);
}
// Yield some cpu cycles to IP stack.
// This is important in case the list is large and it takes us time to return
// to the main loop.
yield();
}
- res->println("]");
}
- res->println("},");
- res->println("\"status\": \"ok\"");
- res->println("}");
+
+ // build output structure
+ Json jsonObjOuter = Json::object{{"data", networkObjs}, {"status", "ok"}};
+
+ // serialize and write it to the stream
+ std::string jsonStr = jsonObjOuter.dump();
+ res->print(jsonStr.c_str());
}
diff --git a/variants/nano-g1/platformio.ini b/variants/nano-g1/platformio.ini
new file mode 100644
index 000000000..a3107423e
--- /dev/null
+++ b/variants/nano-g1/platformio.ini
@@ -0,0 +1,8 @@
+; The 1.0 release of the nano-g1 board
+[env:nano-g1]
+extends = esp32_base
+board = ttgo-t-beam
+lib_deps =
+ ${esp32_base.lib_deps}
+build_flags =
+ ${esp32_base.build_flags} -D NANO_G1 -I variants/nano-g1
\ No newline at end of file
diff --git a/variants/nano-g1/variant.h b/variants/nano-g1/variant.h
new file mode 100644
index 000000000..0915013a0
--- /dev/null
+++ b/variants/nano-g1/variant.h
@@ -0,0 +1,30 @@
+// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
+
+#define I2C_SDA 21
+#define I2C_SCL 22
+
+#define BUTTON_PIN 36 // The middle button GPIO on the Nano G1
+//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
+#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
+
+// common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
+// not found then probe for SX1262
+#define USE_RF95
+#define USE_SX1262
+
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 23
+#define LORA_DIO1 33 // SX1262 IRQ
+#define LORA_DIO2 32 // SX1262 BUSY
+#define LORA_DIO3 // Not connected on PCB
+
+#ifdef USE_SX1262
+#define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_DIO2
+#define SX126X_RESET LORA_RESET
+#define SX126X_E22 // Not really an E22
+// Internally the module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
+// code)
+#endif
+
diff --git a/version.properties b/version.properties
index 8ec26fb45..df418fa9b 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 1
minor = 3
-build = 4
+build = 5