diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 8d20a4ee..9846184a 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -549,74 +549,6 @@ String app::getStatistics(void) { } -//----------------------------------------------------------------------------- -String app::getJson(void) { - DPRINTLN(DBG_VERBOSE, F("app::showJson")); - String modJson; - - modJson = F("{\n"); - for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { - Inverter<> *iv = mSys->getInverterByPos(id); - if(NULL != iv) { - char topic[40], val[25]; - snprintf(topic, 30, "\"%s\": {\n", iv->name); - modJson += String(topic); - for(uint8_t i = 0; i < iv->listLen; i++) { - snprintf(topic, 40, "\t\"ch%d/%s\"", iv->assign[i].ch, iv->getFieldName(i)); - snprintf(val, 25, "[%.3f, \"%s\"]", iv->getValue(i), iv->getUnit(i)); - modJson += String(topic) + ": " + String(val) + F(",\n"); - } - modJson += F("\t\"last_msg\": \"") + getDateTimeStr(iv->ts) + F("\"\n\t},\n"); - } - } - modJson += F("\"json_ts\": \"") + String(getDateTimeStr(mTimestamp)) + F("\"\n}\n"); - - return modJson; -} - -//----------------------------------------------------------------------------- -std::pair app::convertToPromUnits(String shortUnit) { - - if(shortUnit == "A") return {"amplere", "gauge"}; - if(shortUnit == "V") return {"volts", "gauge"}; - if(shortUnit == "%") return {"ratio", "gauge"}; - if(shortUnit == "W") return {"watts", "gauge"}; - if(shortUnit == "Wh") return {"watts_daily", "counter"}; - if(shortUnit == "kWh") return {"watts_total", "counter"}; - if(shortUnit == "°C") return {"celsius", "gauge"}; - - return {"", "gauge"}; -} - - -String app::getMetrics(void) { - DPRINTLN(DBG_VERBOSE, F("app::showMetrics")); - String metrics; - char headline[80]; - - snprintf(headline, 80, "ahoy_solar_info{version=\"%s\",image=\"\",devicename=\"%s\"} 1", mVersion, mSysConfig.deviceName); - metrics += "# TYPE ahoy_solar_info gauge\n" + String(headline) + "\n"; - - for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { - Inverter<> *iv = mSys->getInverterByPos(id); - if(NULL != iv) { - char type[60], topic[60], val[25]; - for(uint8_t i = 0; i < iv->listLen; i++) { - uint8_t channel = iv->assign[i].ch; - if(channel == 0) { - String promUnit, promType; - std::tie(promUnit, promType) = convertToPromUnits( iv->getUnit(i) ); - snprintf(type, 60, "# TYPE ahoy_solar_%s_%s %s", iv->getFieldName(i), promUnit.c_str(), promType.c_str()); - snprintf(topic, 60, "ahoy_solar_%s_%s{inverter=\"%s\"}", iv->getFieldName(i), promUnit.c_str(), iv->name); - snprintf(val, 25, "%.3f", iv->getValue(i)); - metrics += String(type) + "\n" + String(topic) + " " + String(val) + "\n"; - } - } - } - } - return metrics; -} - //----------------------------------------------------------------------------- bool app::getWifiApActive(void) { return mWifi->getApActive(); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index fd719d32..99ce2e18 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -71,8 +71,6 @@ class app { void saveValues(void); void resetPayload(Inverter<>* iv); String getStatistics(void); - String getJson(void); - String getMetrics(void); bool getWifiApActive(void); @@ -146,6 +144,7 @@ class app { } HmSystemType *mSys; + uint32_t mTimestamp; private: void resetSystem(void); @@ -157,8 +156,6 @@ class app { void processPayload(bool retransmit); void processPayload(bool retransmit, uint8_t cmd); - std::pair convertToPromUnits(String shortUnit); - void sendMqttDiscoveryConfig(void); const char* getFieldDeviceClass(uint8_t fieldId); const char* getFieldStateClass(uint8_t fieldId); @@ -236,7 +233,7 @@ class app { bool mSettingsValid; eep *mEep; - uint32_t mTimestamp; + bool mShowRebootRequest; diff --git a/tools/esp8266/config_override_example.h b/tools/esp8266/config_override_example.h index dbaf54df..b74cd7b9 100644 --- a/tools/esp8266/config_override_example.h +++ b/tools/esp8266/config_override_example.h @@ -27,4 +27,11 @@ #undef DTU_RADIO_ID #define DTU_RADIO_ID ((uint64_t)0x1234567802ULL) +// To enable the json endpoint at /json +// #define ENABLE_JSON_EP + +// To enable the endpoint for prometheus to scrape data from at /metrics +// #define ENABLE_PROMETHEUS_EP + + #endif /*__CONFIG_OVERRIDE_H__*/ diff --git a/tools/esp8266/web.cpp b/tools/esp8266/web.cpp index 5f6c2a38..ce318afc 100644 --- a/tools/esp8266/web.cpp +++ b/tools/esp8266/web.cpp @@ -70,8 +70,14 @@ void web::setup(void) { mWeb->on("/cmdstat", std::bind(&web::showStatistics, this)); mWeb->on("/visualization", std::bind(&web::showVisualization, this)); mWeb->on("/livedata", std::bind(&web::showLiveData, this)); + +#ifdef ENABLE_JSON_EP mWeb->on("/json", std::bind(&web::showJson, this)); +#endif +#ifdef ENABLE_PROMETHEUS_EP mWeb->on("/metrics", std::bind(&web::showMetrics, this)); +#endif + mWeb->on("/api", HTTP_POST, std::bind(&web::showWebApi, this)); } @@ -564,16 +570,79 @@ void web::showLiveData(void) { //----------------------------------------------------------------------------- +#ifdef ENABLE_JSON_EP void web::showJson(void) { DPRINTLN(DBG_VERBOSE, F("web::showJson")); - mWeb->send(200, F("application/json"), mMain->getJson()); + + String modJson; + + modJson = F("{\n"); + for(uint8_t id = 0; id < mMain->mSys->getNumInverters(); id++) { + Inverter<> *iv = mMain->mSys->getInverterByPos(id); + if(NULL != iv) { + char topic[40], val[25]; + snprintf(topic, 30, "\"%s\": {\n", iv->name); + modJson += String(topic); + for(uint8_t i = 0; i < iv->listLen; i++) { + snprintf(topic, 40, "\t\"ch%d/%s\"", iv->assign[i].ch, iv->getFieldName(i)); + snprintf(val, 25, "[%.3f, \"%s\"]", iv->getValue(i), iv->getUnit(i)); + modJson += String(topic) + ": " + String(val) + F(",\n"); + } + modJson += F("\t\"last_msg\": \"") + mMain->getDateTimeStr(iv->ts) + F("\"\n\t},\n"); + } + } + modJson += F("\"json_ts\": \"") + String(mMain->getDateTimeStr(mMain->mTimestamp)) + F("\"\n}\n"); + + mWeb->send(200, F("application/json"), modJson); } +#endif //----------------------------------------------------------------------------- +#ifdef ENABLE_PROMETHEUS_EP + +std::pair web::convertToPromUnits(String shortUnit) { + + if(shortUnit == "A") return {"amplere", "gauge"}; + if(shortUnit == "V") return {"volts", "gauge"}; + if(shortUnit == "%") return {"ratio", "gauge"}; + if(shortUnit == "W") return {"watts", "gauge"}; + if(shortUnit == "Wh") return {"watts_daily", "counter"}; + if(shortUnit == "kWh") return {"watts_total", "counter"}; + if(shortUnit == "°C") return {"celsius", "gauge"}; + + return {"", "gauge"}; +} + void web::showMetrics(void) { DPRINTLN(DBG_VERBOSE, F("web::showMetrics")); - mWeb->send(200, F("text/plain"), mMain->getMetrics()); + + String metrics; + char headline[80]; + + snprintf(headline, 80, "ahoy_solar_info{version=\"%s\",image=\"\",devicename=\"%s\"} 1", mVersion, mSysCfg->deviceName); + metrics += "# TYPE ahoy_solar_info gauge\n" + String(headline) + "\n"; + + for(uint8_t id = 0; id < mMain->mSys->getNumInverters(); id++) { + Inverter<> *iv = mMain->mSys->getInverterByPos(id); + if(NULL != iv) { + char type[60], topic[60], val[25]; + for(uint8_t i = 0; i < iv->listLen; i++) { + uint8_t channel = iv->assign[i].ch; + if(channel == 0) { + String promUnit, promType; + std::tie(promUnit, promType) = convertToPromUnits( iv->getUnit(i) ); + snprintf(type, 60, "# TYPE ahoy_solar_%s_%s %s", iv->getFieldName(i), promUnit.c_str(), promType.c_str()); + snprintf(topic, 60, "ahoy_solar_%s_%s{inverter=\"%s\"}", iv->getFieldName(i), promUnit.c_str(), iv->name); + snprintf(val, 25, "%.3f", iv->getValue(i)); + metrics += String(type) + "\n" + String(topic) + " " + String(val) + "\n"; + } + } + } + } + + mWeb->send(200, F("text/plain"), metrics); } +#endif //----------------------------------------------------------------------------- void web::showWebApi(void) diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h index f5c9cb06..82417c73 100644 --- a/tools/esp8266/web.h +++ b/tools/esp8266/web.h @@ -41,8 +41,14 @@ class web { void showStatistics(void); void showVisualization(void); void showLiveData(void); + +#ifdef ENABLE_JSON_EP void showJson(void); +#endif +#ifdef ENABLE_PROMETHEUS_EP void showMetrics(void); +#endif + void showWebApi(void); private: @@ -54,6 +60,10 @@ class web { HTTPUpdateServer *mUpdater; #endif +#ifdef ENABLE_PROMETHEUS_EP + std::pair convertToPromUnits(String shortUnit); +#endif + config_t *mConfig; sysConfig_t *mSysCfg; char *mVersion;