mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-10 07:26:38 +02:00
* improved api
* finished index page
This commit is contained in:
parent
015c0132b9
commit
1f6db2ffdb
7 changed files with 130 additions and 93 deletions
|
@ -53,13 +53,11 @@ void app::loop(void) {
|
|||
bool apActive = mWifi->loop();
|
||||
mWebInst->loop();
|
||||
|
||||
if(checkTicker(&mUptimeTicker, mUptimeInterval)) {
|
||||
if(millis() - mPrevMillis >= 1000) {
|
||||
mPrevMillis += 1000;
|
||||
mUptimeSecs++;
|
||||
if(0 != mTimestamp)
|
||||
mTimestamp++;
|
||||
}
|
||||
if(millis() - mPrevMillis >= 1000) {
|
||||
mPrevMillis += 1000;
|
||||
mUptimeSecs++;
|
||||
if(0 != mTimestamp)
|
||||
mTimestamp++;
|
||||
}
|
||||
|
||||
if(checkTicker(&mNtpRefreshTicker, mNtpRefreshInterval)) {
|
||||
|
@ -500,56 +498,6 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) {
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
String app::getStatistics(void) {
|
||||
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;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||
iv = mSys->getInverterByPos(i);
|
||||
content += F("Inverter #") + String(i) + F(": ");
|
||||
if(NULL != iv) {
|
||||
bool avail = true;
|
||||
content += String(iv->name) + F(" (v") + String(iv->fwVersion) +F(")") + F(" is ");
|
||||
if(!iv->isAvailable(mTimestamp)) {
|
||||
content += F("not ");
|
||||
avail = false;
|
||||
}
|
||||
content += F("available and is ");
|
||||
if(!iv->isProducing(mTimestamp))
|
||||
content += F("not ");
|
||||
content += F("producing\n");
|
||||
|
||||
if(!avail) {
|
||||
if(iv->getLastTs() > 0)
|
||||
content += F("-> last successful transmission: ") + getDateTimeStr(iv->getLastTs()) + "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
content += F("n/a\n");
|
||||
}
|
||||
|
||||
if(!mSys->Radio.isChipConnected())
|
||||
content += F("WARNING! your NRF24 module can't be reached, check the wiring and pinout (<a href=\"/setup\">setup</a>)\n");
|
||||
|
||||
if(mShowRebootRequest)
|
||||
content += F("INFO: reboot your ESP to apply all your configuration changes!\n");
|
||||
|
||||
if(!mSettingsValid)
|
||||
content += F("INFO: your settings are invalid, please switch to <a href=\"/setup\">Setup</a> to correct this.\n");
|
||||
|
||||
content += F("MQTT: ");
|
||||
if(!mMqtt.isConnected())
|
||||
content += F("not ");
|
||||
content += F("connected\n");
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
String app::getJson(void) {
|
||||
DPRINTLN(DBG_VERBOSE, F("app::showJson"));
|
||||
|
@ -664,8 +612,6 @@ const char* app::getFieldStateClass(uint8_t fieldId) {
|
|||
//-----------------------------------------------------------------------------
|
||||
void app::resetSystem(void) {
|
||||
mUptimeSecs = 0;
|
||||
mUptimeTicker = 0xffffffff;
|
||||
mUptimeInterval = 500; // [ms]
|
||||
mPrevMillis = 0;
|
||||
|
||||
mNtpRefreshTicker = 0;
|
||||
|
|
|
@ -62,7 +62,6 @@ class app {
|
|||
void cbMqtt(char* topic, byte* payload, unsigned int length);
|
||||
void saveValues(void);
|
||||
void resetPayload(Inverter<>* iv);
|
||||
String getStatistics(void);
|
||||
String getJson(void);
|
||||
bool getWifiApActive(void);
|
||||
|
||||
|
@ -135,6 +134,10 @@ class app {
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool mqttIsConnected(void) { return mMqtt.isConnected(); }
|
||||
inline bool getSettingsValid(void) { return mSettingsValid; }
|
||||
inline bool getRebootRequestState(void) { return mShowRebootRequest; }
|
||||
|
||||
HmSystemType *mSys;
|
||||
bool mShouldReboot;
|
||||
|
||||
|
@ -214,8 +217,6 @@ class app {
|
|||
}
|
||||
|
||||
|
||||
uint32_t mUptimeTicker;
|
||||
uint16_t mUptimeInterval;
|
||||
uint32_t mUptimeSecs;
|
||||
uint32_t mPrevMillis;
|
||||
uint8_t mHeapStatCnt;
|
||||
|
|
|
@ -15,8 +15,14 @@
|
|||
<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="stat"></pre></p>
|
||||
<p>Every {TS}seconds the values are updated</p>
|
||||
<p><span class="des">ESP-Time: </span><span id="date"></span></p>
|
||||
<p>
|
||||
<span class="des">Statistics: </span>
|
||||
<pre id="stat"></pre>
|
||||
<pre id="iv"></pre>
|
||||
<pre id="warn_info"></pre>
|
||||
</p>
|
||||
<p>Every <span id="refresh"></span> seconds the values are updated</p>
|
||||
|
||||
<div id="note">
|
||||
This project was started from <a href="https://www.mikrocontroller.net/topic/525778" target="_blank">this discussion. (Mikrocontroller.net)</a><br/>
|
||||
|
@ -35,8 +41,10 @@
|
|||
<p class="left"><a href="/update">Update Firmware</a></p>
|
||||
<p class="right" id="version"></p>
|
||||
<p class="right"><a href="/reboot">Reboot</a></p>
|
||||
<p class="right"><a href="/api">REST API</a></p>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var intervalSet = false;
|
||||
function parseSys(obj) {
|
||||
document.getElementById("version").innerHTML = "Git SHA: " + obj["build"] + " :: " + obj["version"];
|
||||
|
||||
|
@ -49,10 +57,8 @@
|
|||
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);
|
||||
+ ("0"+sec).substr(-2);
|
||||
document.getElementById("date").innerHTML = date.toLocaleString('de-DE', {timeZone: 'UTC'});
|
||||
}
|
||||
|
||||
function parseStat(obj) {
|
||||
|
@ -62,11 +68,48 @@
|
|||
+ "\nTX Cnt: " + obj["tx_cnt"];
|
||||
}
|
||||
|
||||
window.setInterval("getAjax('/api/system', parseSys)", 30000);
|
||||
window.setInterval("getAjax('/api/statistics', parseStat)", 30000);
|
||||
function parseIv(obj) {
|
||||
var html = "";
|
||||
for(var i of obj) {
|
||||
html += "Inverter #" + i["id"] + ": " + i["name"] + " (v" + i["version"] + ") is ";
|
||||
if(false == i["is_avail"])
|
||||
html += "not ";
|
||||
html += "available and is ";
|
||||
if(false == i["is_producing"])
|
||||
html += "not ";
|
||||
html += "producing\n";
|
||||
|
||||
getAjax("/api/system", parseSys);
|
||||
getAjax("/api/statistics", parseStat);
|
||||
if(false == i["is_avail"]) {
|
||||
var date = new Date(i["ts_last_succes"] * 1000);
|
||||
html += "-> last successful transmission: " + date.toLocaleString('de-DE', {timeZone: 'UTC'});
|
||||
}
|
||||
|
||||
}
|
||||
document.getElementById("iv").innerHTML = html;
|
||||
}
|
||||
|
||||
function parseWarnInfo(warn, info) {
|
||||
var html = "";
|
||||
for(var w of warn) {
|
||||
html += "WARN: " + w + "\n";
|
||||
}
|
||||
for(var i of info) {
|
||||
html += "INFO: " + i + "\n";
|
||||
}
|
||||
document.getElementById("warn_info").innerHTML = html;
|
||||
}
|
||||
|
||||
function parse(obj) {
|
||||
parseSys(obj["system"]);
|
||||
parseStat(obj["statistics"]);
|
||||
parseIv(obj["inverter"]);
|
||||
parseWarnInfo(obj["warnings"], obj["infos"]);
|
||||
document.getElementById("refresh").innerHTML = obj["refresh_interval"];
|
||||
if(false == intervalSet)
|
||||
window.setInterval("getAjax('/api/index', parse)", obj["refresh_interval"] * 1000);
|
||||
}
|
||||
|
||||
getAjax("/api/index", parse);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -51,7 +51,6 @@ void web::setup(void) {
|
|||
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));
|
||||
mWeb->on("/visualization", HTTP_ANY, std::bind(&web::showVisualization, this, std::placeholders::_1));
|
||||
mWeb->on("/livedata", HTTP_ANY, std::bind(&web::showLiveData, this, std::placeholders::_1));
|
||||
mWeb->on("/json", HTTP_ANY, std::bind(&web::showJson, this, std::placeholders::_1));
|
||||
|
@ -319,13 +318,6 @@ void web::showSave(AsyncWebServerRequest *request) {
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void web::showStatistics(AsyncWebServerRequest *request) {
|
||||
DPRINTLN(DBG_VERBOSE, F("web::showStatistics"));
|
||||
request->send(200, F("text/plain"), mMain->getStatistics());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void web::showVisualization(AsyncWebServerRequest *request) {
|
||||
DPRINTLN(DBG_VERBOSE, F("web::showVisualization"));
|
||||
|
|
|
@ -37,7 +37,6 @@ class web {
|
|||
void onSetup(AsyncWebServerRequest *request);
|
||||
void showSave(AsyncWebServerRequest *request);
|
||||
|
||||
void showStatistics(AsyncWebServerRequest *request);
|
||||
void showVisualization(AsyncWebServerRequest *request);
|
||||
void showLiveData(AsyncWebServerRequest *request);
|
||||
void showJson(AsyncWebServerRequest *request);
|
||||
|
|
|
@ -46,13 +46,14 @@ void webApi::onApi(AsyncWebServerRequest *request) {
|
|||
else if(path == "pinout") getPinout(root);
|
||||
else if(path == "radio") getRadio(root);
|
||||
else if(path == "serial") getSerial(root);
|
||||
else if(path == "index") getIndex(root);
|
||||
else if(path == "setup") getSetup(root);
|
||||
else
|
||||
root["info"] = "not found"; //root["url"] = request->url();
|
||||
getNotFound(root, F("http://") + request->host() + F("/api/"));
|
||||
|
||||
response->setLength();
|
||||
//response->addHeader("Access-Control-Allow-Origin", "*");
|
||||
//response->addHeader("Access-Control-Allow-Headers", "content-type");
|
||||
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||
response->addHeader("Access-Control-Allow-Headers", "content-type");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
|
@ -79,7 +80,7 @@ void webApi::getStatistics(JsonObject obj) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
void webApi::getInverterList(JsonObject obj) {
|
||||
JsonArray invArr = obj.createNestedArray("inverter");
|
||||
JsonArray invArr = obj.createNestedArray(F("inverter"));
|
||||
|
||||
Inverter<> *iv;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
|
@ -147,12 +148,65 @@ void webApi::getSerial(JsonObject obj) {
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void webApi::getSetup(JsonObject obj) {
|
||||
getSystem(obj.createNestedObject("system"));
|
||||
getInverterList(obj.createNestedObject("inverter"));
|
||||
getMqtt(obj.createNestedObject("mqtt"));
|
||||
getNtp(obj.createNestedObject("ntp"));
|
||||
getPinout(obj.createNestedObject("pinout"));
|
||||
getRadio(obj.createNestedObject("radio"));
|
||||
getSerial(obj.createNestedObject("serial"));
|
||||
void webApi::getNotFound(JsonObject obj, String url) {
|
||||
JsonObject ep = obj.createNestedObject("avail_endpoints");
|
||||
ep[F("system")] = url + F("system");
|
||||
ep[F("statistics")] = url + F("statistics");
|
||||
ep[F("inverter/list")] = url + F("inverter/list");
|
||||
ep[F("mqtt")] = url + F("mqtt");
|
||||
ep[F("ntp")] = url + F("ntp");
|
||||
ep[F("pinout")] = url + F("pinout");
|
||||
ep[F("radio")] = url + F("radio");
|
||||
ep[F("serial")] = url + F("serial");
|
||||
ep[F("index")] = url + F("index");
|
||||
ep[F("setup")] = url + F("setup");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void webApi::getIndex(JsonObject obj) {
|
||||
getSystem(obj.createNestedObject(F("system")));
|
||||
getStatistics(obj.createNestedObject(F("statistics")));
|
||||
obj["refresh_interval"] = SEND_INTERVAL;
|
||||
|
||||
JsonArray inv = obj.createNestedArray(F("inverter"));
|
||||
Inverter<> *iv;
|
||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||
iv = mApp->mSys->getInverterByPos(i);
|
||||
if(NULL != iv) {
|
||||
JsonObject invObj = inv.createNestedObject();
|
||||
invObj[F("id")] = i;
|
||||
invObj[F("name")] = String(iv->name);
|
||||
invObj[F("version")] = String(iv->fwVersion);
|
||||
invObj[F("is_avail")] = iv->isAvailable(mApp->getTimestamp());
|
||||
invObj[F("is_producing")] = iv->isProducing(mApp->getTimestamp());
|
||||
invObj[F("ts_last_success")] = iv->getLastTs();
|
||||
}
|
||||
}
|
||||
|
||||
JsonArray warn = obj.createNestedArray(F("warnings"));
|
||||
if(!mApp->mSys->Radio.isChipConnected())
|
||||
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
||||
if(!mApp->mqttIsConnected())
|
||||
warn.add(F("MQTT is not connected"));
|
||||
|
||||
JsonArray info = obj.createNestedArray(F("infos"));
|
||||
if(mApp->getRebootRequestState())
|
||||
info.add(F("reboot your ESP to apply all your configuration changes!"));
|
||||
if(!mApp->getSettingsValid())
|
||||
info.add(F("your settings are invalid"));
|
||||
if(mApp->mqttIsConnected())
|
||||
info.add(F("MQTT is connected"));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void webApi::getSetup(JsonObject obj) {
|
||||
getSystem(obj.createNestedObject(F("system")));
|
||||
getInverterList(obj.createNestedObject(F("inverter")));
|
||||
getMqtt(obj.createNestedObject(F("mqtt")));
|
||||
getNtp(obj.createNestedObject(F("ntp")));
|
||||
getPinout(obj.createNestedObject(F("pinout")));
|
||||
getRadio(obj.createNestedObject(F("radio")));
|
||||
getSerial(obj.createNestedObject(F("serial")));
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ class webApi {
|
|||
void getRadio(JsonObject obj);
|
||||
void getSerial(JsonObject obj);
|
||||
|
||||
void getNotFound(JsonObject obj, String url);
|
||||
void getIndex(JsonObject obj);
|
||||
void getSetup(JsonObject obj);
|
||||
|
||||
AsyncWebServer *mSrv;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue