mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Add *_get_info in json format
This commit is contained in:
parent
06ee1a3c78
commit
6a34490d4e
@ -573,6 +573,83 @@ void haspSetPage(uint8_t pageid)
|
||||
}
|
||||
}
|
||||
|
||||
void hasp_get_info(JsonDocument& doc)
|
||||
{
|
||||
std::string buffer;
|
||||
buffer.reserve(64);
|
||||
char size_buf[32];
|
||||
JsonObject info = doc.createNestedObject(F(D_MANUFACTURER));
|
||||
|
||||
haspGetVersion(size_buf, sizeof(size_buf));
|
||||
info[F("Version")] = size_buf;
|
||||
|
||||
buffer = __DATE__;
|
||||
buffer += (" ");
|
||||
buffer += __TIME__;
|
||||
buffer += (" UTC"); // Github buildservers are in UTC
|
||||
info[F("Build DateTime")] = buffer;
|
||||
|
||||
unsigned long time = millis() / 1000;
|
||||
uint16_t day = time / 86400;
|
||||
time = time % 86400;
|
||||
uint8_t hour = time / 3600;
|
||||
time = time % 3600;
|
||||
uint8_t min = time / 60;
|
||||
time = time % 60;
|
||||
uint8_t sec = time;
|
||||
|
||||
buffer.clear();
|
||||
if(day > 0) {
|
||||
itoa(day, size_buf, DEC);
|
||||
buffer += size_buf;
|
||||
buffer += "d ";
|
||||
}
|
||||
if(day > 0 || hour > 0) {
|
||||
itoa(hour, size_buf, DEC);
|
||||
buffer += size_buf;
|
||||
buffer += "h ";
|
||||
}
|
||||
if(day > 0 || hour > 0 || min > 0) {
|
||||
itoa(min, size_buf, DEC);
|
||||
buffer += size_buf;
|
||||
buffer += "m ";
|
||||
}
|
||||
itoa(sec, size_buf, DEC);
|
||||
buffer += size_buf;
|
||||
buffer += "s";
|
||||
info[F("Uptime")] = buffer;
|
||||
|
||||
info = doc.createNestedObject(F("Device Memory"));
|
||||
Parser::format_bytes(haspDevice.get_free_heap(), size_buf, sizeof(size_buf));
|
||||
info[F("Free Heap")] = size_buf;
|
||||
Parser::format_bytes(haspDevice.get_free_max_block(), size_buf, sizeof(size_buf));
|
||||
info[F("Free Block")] = size_buf;
|
||||
info[F("Fragmentation")] = haspDevice.get_heap_fragmentation();
|
||||
|
||||
#if ARDUINO_ARCH_ESP32
|
||||
if(psramFound()) {
|
||||
Parser::format_bytes(ESP.getFreePsram(), size_buf, sizeof(size_buf));
|
||||
info[F("Free PSRam")] = size_buf;
|
||||
Parser::format_bytes(ESP.getPsramSize(), size_buf, sizeof(size_buf));
|
||||
info[F("PSRam Size")] = size_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
info = doc.createNestedObject(F("LVGL Memory"));
|
||||
lv_mem_monitor_t mem_mon;
|
||||
lv_mem_monitor(&mem_mon);
|
||||
Parser::format_bytes(mem_mon.total_size, size_buf, sizeof(size_buf));
|
||||
info[F("Total")] = size_buf;
|
||||
Parser::format_bytes(mem_mon.free_size, size_buf, sizeof(size_buf));
|
||||
info[F("Free")] = size_buf;
|
||||
info[F("Fragmentation")] = mem_mon.frag_pct;
|
||||
|
||||
info = doc.createNestedObject(F("HASP State"));
|
||||
hasp_get_sleep_state(size_buf);
|
||||
info[F("Idle")] = size_buf;
|
||||
info[F("Active Page")] = haspPages.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if HASP_USE_CONFIG > 0
|
||||
bool haspGetConfig(const JsonObject& settings)
|
||||
|
@ -77,6 +77,8 @@ void hasp_disable_wakeup_touch();
|
||||
void hasp_init(void);
|
||||
void hasp_load_json(void);
|
||||
|
||||
void hasp_get_info(JsonDocument& info);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -34,6 +34,7 @@ int mqtt_send_discovery(const char* payload, size_t len);
|
||||
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain);
|
||||
|
||||
bool mqttIsConnected();
|
||||
void mqtt_get_info(JsonDocument& doc);
|
||||
|
||||
#if HASP_USE_CONFIG > 0
|
||||
bool mqttGetConfig(const JsonObject& settings);
|
||||
|
@ -59,6 +59,9 @@ std::string mqttGroupTopic;
|
||||
std::string mqttLwtTopic;
|
||||
bool mqttEnabled = false;
|
||||
bool mqttHAautodiscover = true;
|
||||
uint32_t mqttPublishCount;
|
||||
uint32_t mqttReceiveCount;
|
||||
uint32_t mqttFailedCount;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// These defaults may be overwritten with values saved by the web interface
|
||||
@ -117,9 +120,11 @@ void connlost(void* context, char* cause)
|
||||
static void mqtt_message_cb(char* topic, char* payload, size_t length)
|
||||
{ // Handle incoming commands from MQTT
|
||||
if(length + 1 >= MQTT_MAX_PACKET_SIZE) {
|
||||
mqttFailedCount++;
|
||||
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), (uint32_t)length);
|
||||
return;
|
||||
} else {
|
||||
mqttReceiveCount++;
|
||||
payload[length] = '\0';
|
||||
}
|
||||
|
||||
@ -198,7 +203,10 @@ void mqtt_subscribe(void* context, const char* topic)
|
||||
|
||||
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
|
||||
{
|
||||
if(!mqttIsConnected()) return MQTT_ERR_NO_CONN;
|
||||
if(!mqttIsConnected()) {
|
||||
mqttFailedCount++;
|
||||
return MQTT_ERR_NO_CONN;
|
||||
}
|
||||
|
||||
MQTTClient_message pubmsg = MQTTClient_message_initializer;
|
||||
MQTTClient_deliveryToken token;
|
||||
@ -212,10 +220,12 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
|
||||
int rc = MQTTClient_waitForCompletion(mqtt_client, token, TIMEOUT); // time to wait in milliseconds
|
||||
|
||||
if(rc != MQTTCLIENT_SUCCESS) {
|
||||
mqttFailedCount++;
|
||||
LOG_ERROR(TAG_MQTT_PUB, F(D_MQTT_FAILED " '%s' => %s"), topic, payload);
|
||||
return MQTT_ERR_PUB_FAIL;
|
||||
} else {
|
||||
// LOG_TRACE(TAG_MQTT_PUB, F("'%s' => %s OK"), topic, payload);
|
||||
mqttPublishCount++;
|
||||
return MQTT_ERR_OK;
|
||||
}
|
||||
}
|
||||
@ -383,5 +393,26 @@ void mqttLoop()
|
||||
|
||||
void mqttEvery5Seconds(bool wifiIsConnected){};
|
||||
|
||||
void mqtt_get_info(JsonDocument& doc)
|
||||
{
|
||||
char mqttClientId[64];
|
||||
|
||||
JsonObject info = doc.createNestedObject(F("MQTT"));
|
||||
info[F("Server")] = mqttServer;
|
||||
info[F("User")] = mqttUser;
|
||||
info[F("ClientID")] = haspDevice.get_hostname();
|
||||
|
||||
if(mqttIsConnected()) { // Check MQTT connection
|
||||
info[F("Status")] = F("Connected");
|
||||
} else {
|
||||
info[F("Status")] = F("<font color='red'><b>Disconnected</b></font>, return code: ");
|
||||
// +String(mqttClient.returnCode());
|
||||
}
|
||||
|
||||
info[F("Received")] = mqttReceiveCount;
|
||||
info[F("Published")] = mqttPublishCount;
|
||||
info[F("Failed")] = mqttFailedCount;
|
||||
}
|
||||
|
||||
#endif // USE_PAHO
|
||||
#endif // USE_MQTT
|
||||
|
@ -50,6 +50,9 @@ char mqttNodeTopic[24];
|
||||
char mqttGroupTopic[24];
|
||||
bool mqttEnabled = false;
|
||||
bool mqttHAautodiscover = true;
|
||||
uint32_t mqttPublishCount;
|
||||
uint32_t mqttReceiveCount;
|
||||
uint32_t mqttFailedCount;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// These defaults may be overwritten with values saved by the web interface
|
||||
@ -95,11 +98,13 @@ int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
|
||||
if(!mqttClient.connected()) return MQTT_ERR_NO_CONN;
|
||||
|
||||
if(mqttClient.beginPublish(topic, len, retain)) {
|
||||
mqttPublishCount++;
|
||||
mqttClient.write((uint8_t*)payload, len);
|
||||
mqttClient.endPublish();
|
||||
return MQTT_ERR_OK;
|
||||
}
|
||||
|
||||
mqttFailedCount++;
|
||||
return MQTT_ERR_PUB_FAIL;
|
||||
}
|
||||
|
||||
@ -156,9 +161,11 @@ int mqtt_send_discovery(const char* payload, size_t len)
|
||||
static void mqtt_message_cb(char* topic, byte* payload, unsigned int length)
|
||||
{ // Handle incoming commands from MQTT
|
||||
if(length + 1 >= mqttClient.getBufferSize()) {
|
||||
mqttFailedCount++;
|
||||
LOG_ERROR(TAG_MQTT_RCV, F(D_MQTT_PAYLOAD_TOO_LONG), (uint32_t)length);
|
||||
return;
|
||||
} else {
|
||||
mqttReceiveCount++;
|
||||
payload[length] = '\0';
|
||||
}
|
||||
|
||||
@ -372,6 +379,33 @@ void mqttStop()
|
||||
}
|
||||
}
|
||||
|
||||
void mqtt_get_info(JsonDocument& doc)
|
||||
{
|
||||
char mqttClientId[64];
|
||||
String mac((char*)0);
|
||||
mac.reserve(64);
|
||||
|
||||
JsonObject info = doc.createNestedObject(F("MQTT"));
|
||||
info[F("Server")] = mqttServer;
|
||||
info[F("User")] = mqttUser;
|
||||
|
||||
mac = halGetMacAddress(3, "");
|
||||
mac.toLowerCase();
|
||||
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%s"), haspDevice.get_hostname(), mac.c_str());
|
||||
info[F("ClientID")] = mqttClientId;
|
||||
|
||||
if(mqttIsConnected()) { // Check MQTT connection
|
||||
info[F("Status")] = F("Connected");
|
||||
} else {
|
||||
info[F("Status")] = F("<font color='red'><b>Disconnected</b></font>, return code: ");
|
||||
// +String(mqttClient.returnCode());
|
||||
}
|
||||
|
||||
info[F("Received")] = mqttReceiveCount;
|
||||
info[F("Published")] = mqttPublishCount;
|
||||
info[F("Failed")] = mqttFailedCount;
|
||||
}
|
||||
|
||||
#if HASP_USE_CONFIG > 0
|
||||
bool mqttGetConfig(const JsonObject& settings)
|
||||
{
|
||||
|
@ -70,4 +70,25 @@ void ethernet_get_statusupdate(char* buffer, size_t len)
|
||||
eth_connected ? F("on") : F("off"), ETH.linkSpeed(), ETH.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
void ethernet_get_info(JsonDocument& doc)
|
||||
{
|
||||
char size_buf[32];
|
||||
String buffer((char*)0);
|
||||
buffer.reserve(64);
|
||||
|
||||
JsonObject info = doc.createNestedObject(F("Ethernet"));
|
||||
|
||||
buffer = ETH.linkSpeed();
|
||||
buffer += F(" Mbps");
|
||||
if(ETH.fullDuplex()) {
|
||||
buffer += F(" FULL_DUPLEX");
|
||||
}
|
||||
|
||||
info[F("Link Speed")] = buffer;
|
||||
info[F("IP Address")] = ETH.localIP().toString();
|
||||
info[F("Gateway")] = ETH.gatewayIP().toString();
|
||||
info[F("DNS Server")] = ETH.dnsIP().toString();
|
||||
info[F("MAC Address")] = ETH.macAddress();
|
||||
}
|
||||
|
||||
#endif
|
@ -4,6 +4,8 @@
|
||||
#ifndef HASP_ETHERNET_ESP32_H
|
||||
#define HASP_ETHERNET_ESP32_H
|
||||
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void ethernetSetup();
|
||||
@ -13,4 +15,6 @@ bool ethernetEverySecond();
|
||||
bool ethernetEvery5Seconds();
|
||||
void ethernet_get_statusupdate(char* buffer, size_t len);
|
||||
|
||||
void ethernet_get_info(JsonDocument& doc);
|
||||
|
||||
#endif
|
@ -4,6 +4,8 @@
|
||||
#ifndef HASP_ETHERNET_STM32_H
|
||||
#define HASP_ETHERNET_STM32_H
|
||||
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
static bool eth_connected = false;
|
||||
|
||||
void ethernetSetup();
|
||||
@ -13,4 +15,6 @@ bool ethernetEverySecond();
|
||||
bool ethernetEvery5Seconds();
|
||||
void ethernet_get_statusupdate(char* buffer, size_t len);
|
||||
|
||||
void ethernet_get_info(JsonDocument& doc);
|
||||
|
||||
#endif
|
@ -132,4 +132,15 @@ void network_get_statusupdate(char* buffer, size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
void network_get_info(JsonDocument& doc)
|
||||
{
|
||||
#if HASP_USE_ETHERNET > 0
|
||||
ethernet_get_info(doc);
|
||||
#endif
|
||||
|
||||
#if HASP_USE_WIFI > 0
|
||||
wifi_get_info(doc);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -16,6 +16,7 @@ void networkStop(void);
|
||||
|
||||
/* ===== Getter and Setter Functions ===== */
|
||||
void network_get_statusupdate(char* buffer, size_t len);
|
||||
void network_get_info(JsonDocument& doc);
|
||||
|
||||
/* ===== Read/Write Configuration ===== */
|
||||
|
||||
|
@ -519,6 +519,51 @@ void wifi_get_statusupdate(char* buffer, size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
void wifi_get_info(JsonDocument& doc)
|
||||
{
|
||||
String buffer((char*)0);
|
||||
buffer.reserve(64);
|
||||
|
||||
JsonObject info = doc.createNestedObject(F("Wifi"));
|
||||
|
||||
int8_t rssi = WiFi.RSSI();
|
||||
buffer += String(rssi);
|
||||
buffer += F("dBm (");
|
||||
|
||||
if(rssi >= -50) {
|
||||
buffer += F("Excellent)");
|
||||
} else if(rssi >= -60) {
|
||||
buffer += F("Good)");
|
||||
} else if(rssi >= -70) {
|
||||
buffer += F("Fair)");
|
||||
} else if(rssi >= -80) {
|
||||
buffer += F("Weak)");
|
||||
} else {
|
||||
buffer += F("Very Bad)");
|
||||
}
|
||||
|
||||
info[F("SSID")] = String(WiFi.SSID());
|
||||
info[F("Signal Strength")] = buffer;
|
||||
|
||||
#if defined(STM32F4xx)
|
||||
byte mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
char macAddress[16];
|
||||
snprintf_P(macAddress, sizeof(macAddress), PSTR("%02x%02x%02x"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
httpMessage += F("</br><b>IP Address: </b>");
|
||||
httpMessage += String(WiFi.localIP());
|
||||
httpMessage += F("</br><b>Gateway: </b>");
|
||||
httpMessage += String(WiFi.gatewayIP());
|
||||
httpMessage += F("</br><b>MAC Address: </b>");
|
||||
httpMessage += String(macAddress);
|
||||
#else
|
||||
info[F("IP Address")] = WiFi.localIP().toString();
|
||||
info[F("Gateway")] = WiFi.gatewayIP().toString();
|
||||
info[F("DNS Server")] = WiFi.dnsIP().toString();
|
||||
info[F("MAC Address")] = WiFi.macAddress();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ============ Confiuration =============================================================== */
|
||||
#if HASP_USE_CONFIG > 0
|
||||
bool wifiGetConfig(const JsonObject& settings)
|
||||
|
@ -15,6 +15,8 @@ void wifiStop(void);
|
||||
bool wifiValidateSsid(const char* ssid, const char* pass);
|
||||
void wifi_get_statusupdate(char* buffer, size_t len);
|
||||
|
||||
void wifi_get_info(JsonDocument& doc);
|
||||
|
||||
#if HASP_USE_CONFIG > 0
|
||||
bool wifiGetConfig(const JsonObject& settings);
|
||||
bool wifiSetConfig(const JsonObject& settings);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "hasp_config.h"
|
||||
|
||||
#if HASP_USE_HTTP > 0
|
||||
#include "sys/net/hasp_network.h"
|
||||
|
||||
// #ifdef USE_CONFIG_OVERRIDE
|
||||
// #include "user_config_override.h"
|
||||
@ -200,6 +201,22 @@ static void add_form_button(String& str, const __FlashStringHelper* label, const
|
||||
close_form(str);
|
||||
}
|
||||
|
||||
static String getContentType(const String& path)
|
||||
{
|
||||
char buff[sizeof(mime::mimeTable[0].mimeType)];
|
||||
// Check all entries but last one for match, return if found
|
||||
for(size_t i = 0; i < sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1; i++) {
|
||||
strcpy_P(buff, mime::mimeTable[i].endsWith);
|
||||
if(path.endsWith(buff)) {
|
||||
strcpy_P(buff, mime::mimeTable[i].mimeType);
|
||||
return String(buff);
|
||||
}
|
||||
}
|
||||
// Fall-through and just return default type
|
||||
strcpy_P(buff, mime::mimeTable[sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1].mimeType);
|
||||
return String(buff);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void webHandleHaspConfig();
|
||||
|
||||
@ -522,6 +539,49 @@ void webHandleAbout()
|
||||
webSendFooter();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void add_json(String& data, JsonDocument& doc)
|
||||
{
|
||||
char buffer[512];
|
||||
size_t len = serializeJson(doc, buffer, sizeof(buffer));
|
||||
if(len <= 2) return; // empty document
|
||||
|
||||
buffer[len - 1] = ',';
|
||||
char* start = buffer + 1;
|
||||
data += String(start);
|
||||
doc.clear();
|
||||
}
|
||||
|
||||
void webHandleInfoJson()
|
||||
{ // http://plate01/
|
||||
if(!httpIsAuthenticated(F("infojson"))) return;
|
||||
|
||||
String htmldata((char*)0);
|
||||
htmldata.reserve(HTTP_PAGE_SIZE);
|
||||
DynamicJsonDocument doc(512);
|
||||
|
||||
htmldata = "{";
|
||||
|
||||
hasp_get_info(doc);
|
||||
add_json(htmldata, doc);
|
||||
|
||||
#if HASP_USE_MQTT > 0
|
||||
mqtt_get_info(doc);
|
||||
add_json(htmldata, doc);
|
||||
#endif
|
||||
|
||||
network_get_info(doc);
|
||||
add_json(htmldata, doc);
|
||||
|
||||
// haspDevice.get_info(doc);
|
||||
// add_json(htmldata, doc);
|
||||
|
||||
htmldata[htmldata.length() - 1] = '}'; // Replace last comma with a bracket
|
||||
String path = F(".json");
|
||||
webServer.send(200, getContentType(path), htmldata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void webHandleInfo()
|
||||
{ // http://plate01/
|
||||
@ -730,52 +790,6 @@ void webHandleInfo()
|
||||
webSendFooter();
|
||||
}
|
||||
|
||||
// String getContentType(String filename)
|
||||
// {
|
||||
// if(webServer.hasArg(F("download"))) {
|
||||
// return F("application/octet-stream");
|
||||
// } else if(filename.endsWith(F(".htm")) || filename.endsWith(F(".html"))) {
|
||||
// return F("text/html");
|
||||
// } else if(filename.endsWith(F(".css"))) {
|
||||
// return F("text/css");
|
||||
// } else if(filename.endsWith(F(".js"))) {
|
||||
// return F("application/javascript");
|
||||
// } else if(filename.endsWith(F(".png"))) {
|
||||
// return F("image/png");
|
||||
// } else if(filename.endsWith(F(".gif"))) {
|
||||
// return F("image/gif");
|
||||
// } else if(filename.endsWith(F(".jpg"))) {
|
||||
// return F("image/jpeg");
|
||||
// } else if(filename.endsWith(F(".ico"))) {
|
||||
// return F("image/x-icon");
|
||||
// } else if(filename.endsWith(F(".xml"))) {
|
||||
// return F("text/xml");
|
||||
// } else if(filename.endsWith(F(".pdf"))) {
|
||||
// return F("application/x-pdf");
|
||||
// } else if(filename.endsWith(F(".zip"))) {
|
||||
// return F("application/x-zip");
|
||||
// } else if(filename.endsWith(F(".gz"))) {
|
||||
// return F("application/x-gzip");
|
||||
// }
|
||||
// return F("text/plain");
|
||||
// }
|
||||
|
||||
static String getContentType(const String& path)
|
||||
{
|
||||
char buff[sizeof(mime::mimeTable[0].mimeType)];
|
||||
// Check all entries but last one for match, return if found
|
||||
for(size_t i = 0; i < sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1; i++) {
|
||||
strcpy_P(buff, mime::mimeTable[i].endsWith);
|
||||
if(path.endsWith(buff)) {
|
||||
strcpy_P(buff, mime::mimeTable[i].mimeType);
|
||||
return String(buff);
|
||||
}
|
||||
}
|
||||
// Fall-through and just return default type
|
||||
strcpy_P(buff, mime::mimeTable[sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1].mimeType);
|
||||
return String(buff);
|
||||
}
|
||||
|
||||
/* String urldecode(String str)
|
||||
{
|
||||
String encodedString = "";
|
||||
@ -2108,6 +2122,7 @@ void httpSetup()
|
||||
|
||||
webServer.on(F("/"), webHandleRoot);
|
||||
webServer.on(F("/info"), webHandleInfo);
|
||||
webServer.on(F("/infojson"), webHandleInfoJson);
|
||||
webServer.on(F("/screenshot"), webHandleScreenshot);
|
||||
webServer.on(F("/firmware"), webHandleFirmware);
|
||||
webServer.on(F("/reboot"), httpHandleReboot);
|
||||
|
Loading…
x
Reference in New Issue
Block a user