Browse Source

* improved api (now webApi)

* converted index to static page
pull/283/head
lumapu 2 years ago
parent
commit
440d386ec0
  1. 18
      tools/esp8266/app.cpp
  2. 5
      tools/esp8266/app.h
  3. 6
      tools/esp8266/defines.h
  4. 65
      tools/esp8266/html/api.js
  5. 37
      tools/esp8266/html/convert.py
  6. 74
      tools/esp8266/html/index.html
  7. 144
      tools/esp8266/html/setup.html
  8. 71
      tools/esp8266/web.cpp
  9. 19
      tools/esp8266/web.h
  10. 53
      tools/esp8266/webApi.cpp
  11. 12
      tools/esp8266/webApi.h

18
tools/esp8266/app.cpp

@ -42,7 +42,7 @@ void app::setup(uint32_t timeout) {
#endif
mSys->setup(&mConfig);
mWebInst = new web(this, &mSysConfig, &mConfig, mVersion);
mWebInst = new web(this, &mSysConfig, &mConfig, &mStat, mVersion);
mWebInst->setup();
}
@ -88,7 +88,7 @@ void app::loop(void) {
DPRINT(DBG_INFO, "RX " + String(len) + "B Ch" + String(p->rxCh) + " | ");
mSys->Radio.dumpBuf(NULL, p->packet, len);
}
mFrameCnt++;
mStat.frmCnt++;
if(0 != len) {
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
@ -231,7 +231,7 @@ void app::loop(void) {
processPayload(false);
if(!mPayload[iv->id].complete) {
mRxFailed++;
mStat.rxFail++;
iv->setQueuedCmdFinished(); // command failed
if(mConfig.serialDebug) {
DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout"));
@ -358,7 +358,7 @@ void app::processPayload(bool retransmit) {
DPRINT(DBG_INFO, F("Payload (") + String(offs) + "): ");
mSys->Radio.dumpBuf(NULL, payload, offs);
}
mRxSuccess++;
mStat.rxSuccess++;
iv->getAssignment(); // choose the parser
for(uint8_t i = 0; i < iv->listLen; i++) {
@ -498,9 +498,9 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
//-----------------------------------------------------------------------------
String app::getStatistics(void) {
String content = F("Receive success: ") + String(mRxSuccess) + "\n";
content += F("Receive fail: ") + String(mRxFailed) + "\n";
content += F("Frames received: ") + String(mFrameCnt) + "\n";
String content = F("Receive success: ") + String(mStat.rxSuccess) + "\n";
content += F("Receive fail: ") + String(mStat.rxFail) + "\n";
content += F("Frames received: ") + String(mStat.frmCnt) + "\n";
content += F("Send Cnt: ") + String(mSys->Radio.mSendCnt) + String("\n\n");
Inverter<> *iv;
@ -686,9 +686,7 @@ void app::resetSystem(void) {
memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t)));
mRxFailed = 0;
mRxSuccess = 0;
mFrameCnt = 0;
memset(&mStat, 0, sizeof(statistics_t));
mLastPacketId = 0x00;
}

5
tools/esp8266/app.h

@ -48,7 +48,6 @@ typedef struct {
bool requested;
} invPayload_t;
class ahoywifi;
class web;
@ -239,9 +238,7 @@ class app {
uint8_t mSendLastIvId;
invPayload_t mPayload[MAX_NUM_INVERTERS];
uint32_t mRxFailed;
uint32_t mRxSuccess;
uint32_t mFrameCnt;
statistics_t mStat;
uint8_t mLastPacketId;
// timer

6
tools/esp8266/defines.h

@ -154,6 +154,12 @@ typedef struct {
} /*__attribute__((__packed__))*/ config_t;
#pragma pack(pop) // restore original alignment from stack
typedef struct {
uint32_t rxFail;
uint32_t rxSuccess;
uint32_t frmCnt;
} statistics_t;
#define CFG_MQTT_LEN MQTT_ADDR_LEN + 2 + MQTT_USER_LEN + MQTT_PWD_LEN +MQTT_TOPIC_LEN
#define CFG_SYS_LEN DEVNAME_LEN + SSID_LEN + PWD_LEN + 1

65
tools/esp8266/html/api.js

@ -0,0 +1,65 @@
function toggle(name, hide) {
var elm = document.getElementsByName(name)[0];
if(hide) {
if(!elm.classList.contains("hide"))
elm.classList.add("hide");
}
else
elm.classList.remove('hide');
}
function getAjax(url, ptr) {
var http = new XMLHttpRequest();
if(http != null) {
http.open("GET", url, true);
http.onreadystatechange = p;
http.send(null);
}
function p() {
if(http.readyState == 4)
ptr(JSON.parse(http.responseText));
}
}
function des(val) {
e = document.createElement('p');
e.classList.add("subdes");
e.innerHTML = val;
return e;
}
function lbl(id, val) {
e = document.createElement('label');
e.htmlFor = id;
e.innerHTML = val;
return e;
}
function inp(name, val, max=32, cl=["text"]) {
e = document.createElement('input');
e.classList.add(...cl);
e.name = name;
e.value = val;
e.maxLength = max;
return e;
}
function sel(name, opt, selId) {
e = document.createElement('select');
e.name = name;
for(it of opt) {
o = document.createElement('option');
o.value = it[0];
o.innerHTML = it[1];
if(it[0] == selId)
o.selected = true;
e.appendChild(o);
}
return e;
}
function div(cl) {
e = document.createElement('div');
e.classList.add(cl);
return e;
}

37
tools/esp8266/html/convert.py

@ -7,30 +7,36 @@ def convert2Header(inFile, compress):
define = inFile.split(".")[0].upper()
define2 = inFile.split(".")[1].upper()
inFileVarName = inFile.replace(".", "_")
print(inFile + ", compress: " + str(compress))
if os.getcwd()[-4:] != "html":
print("ok")
outName = "html/" + "h/" + inFileVarName + ".h"
inFile = "html/" + inFile
else:
outName = "h/" + inFileVarName + ".h"
f = open(inFile, "r")
data = f.read().replace('\n', '')
data = f.read()
f.close()
if False == compress:
if fileType == "html":
if fileType == "html":
if False == compress:
data = data.replace('\n', '')
data = re.sub(r"\>\s+\<", '><', data) # whitespaces between xml tags
data = re.sub(r"(\s?\;|\}|\>|\{|\=)\s+", r'\1', data) # whitespaces inner javascript
length = len(data) # get unescaped length
data = re.sub(r"\"", '\\\"', data) # escape quotation marks
else:
data = re.sub(r"(\;|\}|\:|\{)\s+", r'\1', data) # whitespaces inner css
length = len(data) # get unescaped length
else:
data = re.sub(r"\>\s+\<", '><', data) # whitespaces between xml tags
data = re.sub(r"(\;|\}|\>|\{)\s+", r'\1', data) # whitespaces inner javascript
data = re.sub(r"(\r\n|\r|\n)(\s+|\s?)", '', data) # whitespaces inner javascript
length = len(data) # get unescaped length
if False == compress:
data = re.sub(r"\"", '\\\"', data) # escape quotation marks
elif fileType == "js":
#data = re.sub(r"(\r\n|\r|\n)(\s+|\s?)", '', data) # whitespaces inner javascript
#data = re.sub(r"\s?(\=|\!\=|\{|,)+\s?", r'\1', data) # whitespaces inner javascript
length = len(data) # get unescaped length
if False == compress:
data = re.sub(r"\"", '\\\"', data) # escape quotation marks
else:
data = data.replace('\n', '')
data = re.sub(r"(\;|\}|\:|\{)\s+", r'\1', data) # whitespaces inner css
length = len(data) # get unescaped length # get unescaped length
f = open(outName, "w")
f.write("#ifndef __{}_{}_H__\n".format(define, define2))
@ -52,8 +58,9 @@ def convert2Header(inFile, compress):
f.write("#endif /*__{}_{}_H__*/\n".format(define, define2))
f.close()
convert2Header("index.html", False)
convert2Header("index.html", True)
convert2Header("setup.html", True)
convert2Header("visualization.html", False)
convert2Header("update.html", False)
convert2Header("style.css", False)
convert2Header("style.css", True)
convert2Header("api.js", True)

74
tools/esp8266/html/index.html

@ -1,44 +1,13 @@
<!doctype html>
<html>
<head>
<title>Index - {DEVICE}</title>
<title>Index</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript">
getAjax('/uptime', 'uptime');
getAjax('/cmdstat', 'cmds');
window.setInterval("getAjax('/uptime', 'uptime')", {JS_TS});
window.setInterval("getAjax('/cmdstat', 'cmds')", {JS_TS});
function getAjax(url, resid) {
var http = null;
http = new XMLHttpRequest();
if(http != null) {
http.open("GET", url, true);
http.onreadystatechange = print;
http.send(null);
}
function print() {
if(http.readyState == 4) {
document.getElementById(resid).innerHTML = http.responseText;
}
}
}
function getInverterInfo(data){
var http = null;
http = new XMLHttpRequest();
if(http != null) {
http.open("POST", "/api");
http.setRequestHeader("Accept", "application/json");
http.setRequestHeader("Content-Type", "application/json");
http.send(data);
}
}
</script>
<script type="text/javascript" src="api.js"></script>
</head>
<body>
<h1>AHOY - {DEVICE}</h1>
<h1>AHOY</h1>
<div id="content" class="content">
<p>
<a href="/visualization">Visualization</a><br/>
@ -46,7 +15,7 @@
<a href="/setup">Setup</a><br/>
</p>
<p><span class="des">Uptime: </span><span id="uptime"></span></p>
<p><span class="des">Statistics: </span><pre id="cmds"></pre></p>
<p><span class="des">Statistics: </span><pre id="stat"></pre></p>
<p>Every {TS}seconds the values are updated</p>
<div id="note">
@ -64,9 +33,40 @@
<div id="footer">
<p class="left">&copy 2022</p>
<p class="left"><a href="/update">Update Firmware</a></p>
<p class="right">AHOY :: {VERSION}</p>
<p class="right" id="version"></p>
<p class="right"><a href="/reboot">Reboot</a></p>
<p class="right">Git SHA: {BUILD}</p>
</div>
<script type="text/javascript">
function parseSys(obj) {
document.getElementById("version").innerHTML = "Git SHA: " + obj["build"] + " :: " + obj["version"];
var date = new Date(obj["ts_now"] * 1000);
var up = obj["ts_uptime"];
var days = parseInt(up / 86400) % 365;
var hrs = parseInt(up / 3600) % 24;
var min = parseInt(up / 60) % 60;
var sec = up % 60;
document.getElementById("uptime").innerHTML = days + " Days, "
+ ("0"+hrs).substr(-2) + ":"
+ ("0"+min).substr(-2) + ":"
+ ("0"+sec).substr(-2) + "; now: "
+ ("0"+date.getHours()).substr(-2) + ":"
+ ("0"+date.getMinutes()).substr(-2) + ":"
+ ("0"+date.getSeconds()).substr(-2);
}
function parseStat(obj) {
document.getElementById("stat").innerHTML = "RX success: " + obj["rx_success"]
+ "\nRX fail: " + obj["rx_fail"]
+ "\nFrames received: " + obj["frame_cnt"]
+ "\nTX Cnt: " + obj["tx_cnt"];
}
window.setInterval("getAjax('/api/system', parseSys)", 30000);
window.setInterval("getAjax('/api/system', parseStat)", 30000);
getAjax("/api/system", parseSys);
getAjax("/api/statistics", parseStat);
</script>
</body>
</html>

144
tools/esp8266/html/setup.html

@ -4,49 +4,7 @@
<title>Setup</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript">
function toggle(name, hide) {
var elm = document.getElementsByName(name)[0];
if(hide) {
if(!elm.classList.contains("hide"))
elm.classList.add("hide");
}
else
elm.classList.remove('hide');
}
function load() {
document.querySelectorAll('input[name^="inv"][name$="Addr"]').forEach(elm => {
elm.addEventListener("keyup", (e) => {
serial = elm.value.substring(0,4);
iv = elm.name.substring(3,4);
max = 0;
for(i=0;i<4;i++) {
toggle("inv"+iv+"ModPwr"+i, true);
toggle("inv"+iv+"ModName"+i, true);
}
toggle("lbl"+iv+"ModPwr", true);
toggle("lbl"+iv+"ModName", true);
if(serial == "1161") max = 4;
else if(serial == "1141") max = 2;
else if(serial == "1121") max = 1;
for(i=0;i<max;i++) {
toggle("inv"+iv+"ModPwr"+i, false);
toggle("inv"+iv+"ModName"+i, false);
}
if(max != 0) {
toggle("lbl"+iv+"ModPwr", false);
toggle("lbl"+iv+"ModName", false);
}
});
evt = document.createEvent("HTMLEvents");
evt.initEvent("keyup", false, true);
elm.dispatchEvent(evt);
});
}
</script>
<script type="text/javascript" src="api.js"></script>
</head>
<body onload="load()">
<h1>Setup</h1>
@ -141,7 +99,6 @@
</form>
</div>
</div>
<div id="footer">
<p class="left"><a href="/">Home</a></p>
<p class="left"><a href="/update">Update Firmware</a></p>
@ -149,14 +106,45 @@
<p class="right"><a href="/factory">Factory Reset</a></p>
<p class="right"><a href="/reboot">Reboot</a></p>
</div>
<script type="text/javascript">
for(it of document.getElementsByClassName("s_collapsible")) {
it.addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
content.style.display = (content.style.display === "block") ? "none" : "block";
function load() {
document.querySelectorAll('input[name^="inv"][name$="Addr"]').forEach(elm => {
elm.addEventListener("keyup", (e) => {
serial = elm.value.substring(0,4);
iv = elm.name.substring(3,4);
max = 0;
for(i=0;i<4;i++) {
toggle("inv"+iv+"ModPwr"+i, true);
toggle("inv"+iv+"ModName"+i, true);
}
toggle("lbl"+iv+"ModPwr", true);
toggle("lbl"+iv+"ModName", true);
if(serial == "1161") max = 4;
else if(serial == "1141") max = 2;
else if(serial == "1121") max = 1;
for(i=0;i<max;i++) {
toggle("inv"+iv+"ModPwr"+i, false);
toggle("inv"+iv+"ModName"+i, false);
}
if(max != 0) {
toggle("lbl"+iv+"ModPwr", false);
toggle("lbl"+iv+"ModName", false);
}
});
evt = document.createEvent("HTMLEvents");
evt.initEvent("keyup", false, true);
elm.dispatchEvent(evt);
});
for(it of document.getElementsByClassName("s_collapsible")) {
it.addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
content.style.display = (content.style.display === "block") ? "none" : "block";
});
}
}
var highestId = 0;
@ -167,62 +155,6 @@
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""],"power_limit":1500,"power_limit_option":65535}'), highestId + 1);
});
function getAjax(url, ptr) {
var http = new XMLHttpRequest();
if(http != null) {
http.open("GET", url, true);
http.onreadystatechange = p;
http.send(null);
}
function p() {
if(http.readyState == 4)
ptr(JSON.parse(http.responseText));
}
}
function des(val) {
e = document.createElement('p');
e.classList.add("subdes");
e.innerHTML = val;
return e;
}
function lbl(id, val) {
e = document.createElement('label');
e.htmlFor = id;
e.innerHTML = val;
return e;
}
function inp(name, val, max=32, cl=["text"]) {
e = document.createElement('input');
e.classList.add(...cl);
e.name = name;
e.value = val;
e.maxLength = max;
return e;
}
function sel(name, opt, selId) {
e = document.createElement('select');
e.name = name;
for(it of opt) {
o = document.createElement('option');
o.value = it[0];
o.innerHTML = it[1];
if(it[0] == selId)
o.selected = true;
e.appendChild(o);
}
return e;
}
function div(cl) {
e = document.createElement('div');
e.classList.add(cl);
return e;
}
function ivHtml(obj, id) {
highestId = id;
if(highestId == (maxInv - 1))

71
tools/esp8266/web.cpp

@ -12,6 +12,7 @@
#include "html/h/index_html.h"
#include "html/h/style_css.h"
#include "html/h/api_js.h"
#include "html/h/favicon_ico_gz.h"
#include "html/h/setup_html.h"
#include "html/h/visualization_html.h"
@ -20,15 +21,16 @@
const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq"};
//-----------------------------------------------------------------------------
web::web(app *main, sysConfig_t *sysCfg, config_t *config, char version[]) {
web::web(app *main, sysConfig_t *sysCfg, config_t *config, statistics_t *stat, char version[]) {
mMain = main;
mSysCfg = sysCfg;
mConfig = config;
mStat = stat;
mVersion = version;
mWeb = new AsyncWebServer(80);
//mEvts = new AsyncEventSource("/events");
mApi = new api(mWeb, main, sysCfg, config, version);
mApi = new webApi(mWeb, main, sysCfg, config, stat, version);
}
@ -37,16 +39,16 @@ void web::setup(void) {
DPRINTLN(DBG_VERBOSE, F("app::setup-begin"));
mWeb->begin();
DPRINTLN(DBG_VERBOSE, F("app::setup-on"));
mWeb->on("/", HTTP_ANY, std::bind(&web::showIndex, this, std::placeholders::_1));
mWeb->on("/style.css", HTTP_ANY, std::bind(&web::showCss, this, std::placeholders::_1));
mWeb->on("/favicon.ico", HTTP_ANY, std::bind(&web::showFavicon, this, std::placeholders::_1));
mWeb->on("/", HTTP_GET, std::bind(&web::onIndex, this, std::placeholders::_1));
mWeb->on("/style.css", HTTP_GET, std::bind(&web::onCss, this, std::placeholders::_1));
mWeb->on("/api.js", HTTP_GET, std::bind(&web::onApiJs, this, std::placeholders::_1));
mWeb->on("/favicon.ico", HTTP_GET, std::bind(&web::onFavicon, this, std::placeholders::_1));
mWeb->onNotFound ( std::bind(&web::showNotFound, this, std::placeholders::_1));
mWeb->on("/uptime", HTTP_ANY, std::bind(&web::showUptime, this, std::placeholders::_1));
mWeb->on("/reboot", HTTP_ANY, std::bind(&web::showReboot, this, std::placeholders::_1));
mWeb->on("/erase", HTTP_ANY, std::bind(&web::showErase, this, std::placeholders::_1));
mWeb->on("/factory", HTTP_ANY, std::bind(&web::showFactoryRst, this, std::placeholders::_1));
mWeb->on("/setup", HTTP_ANY, std::bind(&web::showSetup, this, std::placeholders::_1));
mWeb->on("/setup", HTTP_GET, std::bind(&web::onSetup, this, std::placeholders::_1));
mWeb->on("/save", HTTP_ANY, std::bind(&web::showSave, this, std::placeholders::_1));
mWeb->on("/cmdstat", HTTP_ANY, std::bind(&web::showStatistics, this, std::placeholders::_1));
@ -85,26 +87,41 @@ void web::loop(void) {
//-----------------------------------------------------------------------------
void web::showIndex(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showIndex"));
String html = FPSTR(index_html);
html.replace(F("{DEVICE}"), mSysCfg->deviceName);
html.replace(F("{VERSION}"), mVersion);
void web::onIndex(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onIndex"));
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), index_html, index_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
/*
html.replace(F("{TS}"), String(mConfig->sendInterval) + " ");
html.replace(F("{JS_TS}"), String(mConfig->sendInterval * 1000));
html.replace(F("{BUILD}"), String(AUTO_GIT_HASH));
request->send(200, "text/html", html);
request->send(200, "text/html", html);*/
}
//-----------------------------------------------------------------------------
void web::showCss(AsyncWebServerRequest *request) {
request->send(200, "text/css", FPSTR(style_css));
void web::onCss(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), style_css, style_css_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::showFavicon(AsyncWebServerRequest *request) {
void web::onApiJs(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onApiJs"));
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/javascript"), api_js, api_js_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::onFavicon(AsyncWebServerRequest *request) {
static const char favicon_type[] PROGMEM = "image/x-icon";
AsyncWebServerResponse *response = request->beginResponse_P(200, favicon_type, favicon_ico_gz, favicon_ico_gz_len);
response->addHeader(F("Content-Encoding"), "gzip");
@ -131,22 +148,6 @@ void web::showNotFound(AsyncWebServerRequest *request) {
}
//-----------------------------------------------------------------------------
void web::showUptime(AsyncWebServerRequest *request) {
char time[21] = {0};
uint32_t uptime = mMain->getUptime();
uint32_t upTimeSc = uint32_t((uptime) % 60);
uint32_t upTimeMn = uint32_t((uptime / (60)) % 60);
uint32_t upTimeHr = uint32_t((uptime / (60 * 60)) % 24);
uint32_t upTimeDy = uint32_t((uptime / (60 * 60 * 24)) % 365);
snprintf(time, 20, "%d Days, %02d:%02d:%02d", upTimeDy, upTimeHr, upTimeMn, upTimeSc);
request->send(200, "text/plain", String(time) + "; now: " + mMain->getDateTimeStr(mMain->getTimestamp()));
}
//-----------------------------------------------------------------------------
void web::showReboot(AsyncWebServerRequest *request) {
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Rebooting ...</title><meta http-equiv=\"refresh\" content=\"10; URL=/\"></head><body>rebooting ... auto reload after 10s</body></html>"));
@ -193,8 +194,8 @@ void web::showFactoryRst(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void web::showSetup(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("app::showSetup"));
void web::onSetup(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onSetup"));
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), setup_html, setup_html_len);
response->addHeader(F("Content-Encoding"), "gzip");

19
tools/esp8266/web.h

@ -10,15 +10,15 @@
#include "ESPAsyncTCP.h"
#include "ESPAsyncWebServer.h"
#include "app.h"
#include "api.h"
#include "webApi.h"
#include "tmplProc.h"
class app;
class api;
class webApi;
class web {
public:
web(app *main, sysConfig_t *sysCfg, config_t *config, char version[]);
web(app *main, sysConfig_t *sysCfg, config_t *config, statistics_t *stat, char version[]);
~web() {}
void setup(void);
@ -26,15 +26,15 @@ class web {
void onConnect(AsyncEventSourceClient *client);
void showIndex(AsyncWebServerRequest *request);
void showCss(AsyncWebServerRequest *request);
void showFavicon(AsyncWebServerRequest *request);
void onIndex(AsyncWebServerRequest *request);
void onCss(AsyncWebServerRequest *request);
void onApiJs(AsyncWebServerRequest *request);
void onFavicon(AsyncWebServerRequest *request);
void showNotFound(AsyncWebServerRequest *request);
void showUptime(AsyncWebServerRequest *request);
void showReboot(AsyncWebServerRequest *request);
void showErase(AsyncWebServerRequest *request);
void showFactoryRst(AsyncWebServerRequest *request);
void showSetup(AsyncWebServerRequest *request);
void onSetup(AsyncWebServerRequest *request);
void showSave(AsyncWebServerRequest *request);
void showStatistics(AsyncWebServerRequest *request);
@ -56,9 +56,10 @@ class web {
config_t *mConfig;
sysConfig_t *mSysCfg;
statistics_t *mStat;
char *mVersion;
app *mMain;
api *mApi;
webApi *mApi;
};
#endif /*__WEB_H__*/

53
tools/esp8266/api.cpp → tools/esp8266/webApi.cpp

@ -8,39 +8,41 @@
#define F(sl) (sl)
#endif
#include "api.h"
#include "webApi.h"
#include "AsyncJson.h"
//-----------------------------------------------------------------------------
api::api(AsyncWebServer *srv, app *app, sysConfig_t *sysCfg, config_t *config, char version[]) {
webApi::webApi(AsyncWebServer *srv, app *app, sysConfig_t *sysCfg, config_t *config, statistics_t *stat, char version[]) {
mSrv = srv;
mApp = app;
mSysCfg = sysCfg;
mConfig = config;
mStat = stat;
mVersion = version;
}
//-----------------------------------------------------------------------------
void api::setup(void) {
mSrv->on("/api/system", HTTP_GET, std::bind(&api::onSystem, this, std::placeholders::_1));
mSrv->on("/api/inverter/list", HTTP_GET, std::bind(&api::onInverterList, this, std::placeholders::_1));
mSrv->on("/api/mqtt", HTTP_GET, std::bind(&api::onMqtt, this, std::placeholders::_1));
mSrv->on("/api/ntp", HTTP_GET, std::bind(&api::onNtp, this, std::placeholders::_1));
mSrv->on("/api/pinout", HTTP_GET, std::bind(&api::onPinout, this, std::placeholders::_1));
mSrv->on("/api/radio", HTTP_GET, std::bind(&api::onRadio, this, std::placeholders::_1));
mSrv->on("/api/serial", HTTP_GET, std::bind(&api::onSerial, this, std::placeholders::_1));
void webApi::setup(void) {
mSrv->on("/api/system", HTTP_GET, std::bind(&webApi::onSystem, this, std::placeholders::_1));
mSrv->on("/api/statistics", HTTP_GET, std::bind(&webApi::onStatistics, this, std::placeholders::_1));
mSrv->on("/api/inverter/list", HTTP_GET, std::bind(&webApi::onInverterList, this, std::placeholders::_1));
mSrv->on("/api/mqtt", HTTP_GET, std::bind(&webApi::onMqtt, this, std::placeholders::_1));
mSrv->on("/api/ntp", HTTP_GET, std::bind(&webApi::onNtp, this, std::placeholders::_1));
mSrv->on("/api/pinout", HTTP_GET, std::bind(&webApi::onPinout, this, std::placeholders::_1));
mSrv->on("/api/radio", HTTP_GET, std::bind(&webApi::onRadio, this, std::placeholders::_1));
mSrv->on("/api/serial", HTTP_GET, std::bind(&webApi::onSerial, this, std::placeholders::_1));
}
//-----------------------------------------------------------------------------
void api::loop(void) {
void webApi::loop(void) {
}
//-----------------------------------------------------------------------------
void api::onSystem(AsyncWebServerRequest *request) {
void webApi::onSystem(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
@ -59,7 +61,22 @@ void api::onSystem(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onInverterList(AsyncWebServerRequest *request) {
void webApi::onStatistics(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
root[F("rx_success")] = mStat->rxSuccess;
root[F("rx_fail")] = mStat->rxFail;
root[F("frame_cnt")] = mStat->frmCnt;
root[F("tx_cnt")] = mApp->mSys->Radio.mSendCnt;
response->setLength();
request->send(response);
}
//-----------------------------------------------------------------------------
void webApi::onInverterList(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
JsonArray invArr = root.createNestedArray("inverter");
@ -94,7 +111,7 @@ void api::onInverterList(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onMqtt(AsyncWebServerRequest *request) {
void webApi::onMqtt(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
@ -110,7 +127,7 @@ void api::onMqtt(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onNtp(AsyncWebServerRequest *request) {
void webApi::onNtp(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
@ -123,7 +140,7 @@ void api::onNtp(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onPinout(AsyncWebServerRequest *request) {
void webApi::onPinout(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
@ -137,7 +154,7 @@ void api::onPinout(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onRadio(AsyncWebServerRequest *request) {
void webApi::onRadio(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
@ -150,7 +167,7 @@ void api::onRadio(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void api::onSerial(AsyncWebServerRequest *request) {
void webApi::onSerial(AsyncWebServerRequest *request) {
AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject root = response->getRoot();

12
tools/esp8266/api.h → tools/esp8266/webApi.h

@ -1,5 +1,5 @@
#ifndef __API_H__
#define __API_H__
#ifndef __WEB_API_H__
#define __WEB_API_H__
#include "dbg.h"
#include "ESPAsyncTCP.h"
@ -9,15 +9,16 @@
class app;
class api {
class webApi {
public:
api(AsyncWebServer *srv, app *app, sysConfig_t *sysCfg, config_t *config, char version[]);
webApi(AsyncWebServer *srv, app *app, sysConfig_t *sysCfg, config_t *config, statistics_t *stat, char version[]);
void setup(void);
void loop(void);
private:
void onSystem(AsyncWebServerRequest *request);
void onStatistics(AsyncWebServerRequest *request);
void onInverterList(AsyncWebServerRequest *request);
void onMqtt(AsyncWebServerRequest *request);
void onNtp(AsyncWebServerRequest *request);
@ -30,7 +31,8 @@ class api {
config_t *mConfig;
sysConfig_t *mSysCfg;
statistics_t *mStat;
char *mVersion;
};
#endif /*__API_H__*/
#endif /*__WEB_API_H__*/
Loading…
Cancel
Save