From e1c713fb003f2114171110417755191adc1b88ef Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 12 Aug 2022 15:41:27 +0200 Subject: [PATCH 01/10] * make mClient in mqtt private again (#145) * v0.5.10 --- tools/esp8266/app.cpp | 2 +- tools/esp8266/defines.h | 2 +- tools/esp8266/mqtt.h | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 23c8b575..c4bf5ece 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -163,7 +163,7 @@ void app::setup(uint32_t timeout) { mqttPort = 1883; mMqtt.setup(mqttAddr, mqttTopic, mqttUser, mqttPwd, mqttDevName, mqttPort); - mMqtt.mClient->setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mMqttTicker = 0; #ifdef __MQTT_TEST__ diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index f229e1da..0361d0b7 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -21,7 +21,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 9 +#define VERSION_PATCH 10 //------------------------------------- diff --git a/tools/esp8266/mqtt.h b/tools/esp8266/mqtt.h index f8e0389e..eab0d043 100644 --- a/tools/esp8266/mqtt.h +++ b/tools/esp8266/mqtt.h @@ -12,8 +12,6 @@ class mqtt { public: - PubSubClient *mClient; - mqtt() { mClient = new PubSubClient(mEspClient); mAddressSet = false; @@ -42,8 +40,8 @@ class mqtt { mClient->setBufferSize(MQTT_MAX_PACKET_SIZE); } - void setCallback(void (*func)(const char* topic, byte* payload, unsigned int length)){ - mClient->setCallback(func); + void setCallback(MQTT_CALLBACK_SIGNATURE){ + mClient->setCallback(callback); } void sendMsg(const char *topic, const char *msg) { @@ -131,6 +129,7 @@ class mqtt { } WiFiClient mEspClient; + PubSubClient *mClient; bool mAddressSet; uint16_t mPort; From c6e3cd39bab7e9306a8045eafd77d132f02c5ada Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 01:07:59 +0200 Subject: [PATCH 02/10] * started refactoring --- tools/esp8266/app.cpp | 66 ++++------- tools/esp8266/app.h | 5 - tools/esp8266/esp8266.cpp | 4 + tools/esp8266/main.cpp | 224 +++++++------------------------------- tools/esp8266/main.h | 94 ++++++++++------ 5 files changed, 121 insertions(+), 272 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index c4bf5ece..c4c6acdc 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -6,7 +6,6 @@ #include "app.h" #include "favicon.h" -#include "html/h/index_html.h" #include "html/h/setup_html.h" #include "html/h/hoymiles_html.h" #include @@ -17,7 +16,6 @@ app::app() : Main() { DPRINTLN(DBG_VERBOSE, F("app::app():Main")); mSendTicker = 0xffff; - mSendInterval = SEND_INTERVAL; mMqttTicker = 0xffff; mMqttInterval = MQTT_INTERVAL; mSerialTicker = 0xffff; @@ -55,11 +53,9 @@ void app::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("app::setup")); Main::setup(timeout); - mWeb->on("/", std::bind(&app::showIndex, this)); mWeb->on("/favicon.ico", std::bind(&app::showFavicon, this)); - mWeb->on("/setup", std::bind(&app::showSetup, this)); - mWeb->on("/save", std::bind(&app::showSave, this)); - mWeb->on("/erase", std::bind(&app::showErase, this)); + //mWeb->on("/setup", std::bind(&app::showSetup, this)); + //mWeb->on("/save", std::bind(&app::showSave, this)); mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this)); mWeb->on("/livedata", std::bind(&app::showLiveData, this)); @@ -67,10 +63,10 @@ void app::setup(uint32_t timeout) { mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this)); if(mSettingsValid) { - mEep->read(ADDR_INV_INTERVAL, &mSendInterval); - if(mSendInterval < MIN_SEND_INTERVAL) - mSendInterval = MIN_SEND_INTERVAL; - mSendTicker = mSendInterval; + mEep->read(ADDR_INV_INTERVAL, &config.sendInterval); + if(config.sendInterval < MIN_SEND_INTERVAL) + config.sendInterval = MIN_SEND_INTERVAL; + mSendTicker = config.sendInterval; // inverter uint64_t invSerial; @@ -97,7 +93,7 @@ void app::setup(uint32_t timeout) { } - mMqttInterval += mSendInterval; + mMqttInterval += config.sendInterval; } } @@ -175,7 +171,7 @@ void app::setup(uint32_t timeout) { if(mqttAddr[0] > 0) { char topic[30]; mMqtt.sendMsg("device", mqttDevName); - mMqtt.sendMsg("version", mVersion); + mMqtt.sendMsg("version", config.version); for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { iv = mSys->getInverterByPos(i); if(NULL != iv) { @@ -210,7 +206,7 @@ void app::setup(uint32_t timeout) { DPRINTLN(DBG_INFO, F("\n\n----------------------------------------")); DPRINTLN(DBG_INFO, F("Welcome to AHOY!")); DPRINT(DBG_INFO, F("\npoint your browser to http://")); - if(mApActive) + if(config.apActive) DBGPRINTLN(F("192.168.1.1")); else DBGPRINTLN(WiFi.localIP()); @@ -404,7 +400,7 @@ void app::loop(void) { } } - if(++mSendTicker >= mSendInterval) { + if(++mSendTicker >= config.sendInterval) { mSendTicker = 0; if(0 != mTimestamp) { @@ -587,20 +583,7 @@ void app::processPayload(bool retransmit) { //----------------------------------------------------------------------------- -void app::showIndex(void) { - DPRINTLN(DBG_VERBOSE, F("app::showIndex")); - String html = FPSTR(index_html); - html.replace(F("{DEVICE}"), mDeviceName); - html.replace(F("{VERSION}"), mVersion); - html.replace(F("{TS}"), String(mSendInterval) + " "); - html.replace(F("{JS_TS}"), String(mSendInterval * 1000)); - html.replace(F("{BUILD}"), String(AUTO_GIT_HASH)); - mWeb->send(200, "text/html", html); -} - - -//----------------------------------------------------------------------------- -void app::showSetup(void) { +/*void app::showSetup(void) { DPRINTLN(DBG_VERBOSE, F("app::showSetup")); // overrides same method in main.cpp @@ -737,17 +720,10 @@ void app::showSetup(void) { //----------------------------------------------------------------------------- void app::showSave(void) { DPRINTLN(DBG_VERBOSE, F("app::showSave")); - saveValues(true); -} + //saveValues(true); +}*/ -//----------------------------------------------------------------------------- -void app::showErase() { - DPRINTLN(DBG_VERBOSE, F("app::showErase")); - eraseSettings(); - showReboot(); -} - //----------------------------------------------------------------------------- void app::cbMqtt(char* topic, byte* payload, unsigned int length) { // callback handling on subscribed devcontrol topic @@ -893,10 +869,10 @@ void app::webapi(void) { // ToDo void app::showHoymiles(void) { DPRINTLN(DBG_VERBOSE, F("app::showHoymiles")); String html = FPSTR(hoymiles_html); - html.replace(F("{DEVICE}"), mDeviceName); - html.replace(F("{VERSION}"), mVersion); - html.replace(F("{TS}"), String(mSendInterval) + " "); - html.replace(F("{JS_TS}"), String(mSendInterval * 1000)); + html.replace(F("{DEVICE}"), config.deviceName); + html.replace(F("{VERSION}"), config.version); + html.replace(F("{TS}"), String(config.sendInterval) + " "); + html.replace(F("{JS_TS}"), String(config.sendInterval * 1000)); mWeb->send(200, F("text/html"), html); } @@ -1014,7 +990,7 @@ void app::showJSON(void) { //----------------------------------------------------------------------------- -void app::saveValues(bool webSend = true) { +/*void app::saveValues(bool webSend = true) { DPRINTLN(DBG_VERBOSE, F("app::saveValues")); Main::saveValues(false); // general configuration @@ -1127,11 +1103,11 @@ void app::saveValues(bool webSend = true) { mWeb->send(200, F("text/html"), F("Error" "

Error while saving

")); } -} +}*/ //----------------------------------------------------------------------------- -void app::updateCrc(void) { +/*void app::updateCrc(void) { DPRINTLN(DBG_VERBOSE, F("app::updateCrc")); Main::updateCrc(); @@ -1139,7 +1115,7 @@ void app::updateCrc(void) { crc = buildEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT) - (ADDR_START_SETTINGS))); DPRINTLN(DBG_DEBUG, F("new CRC: ") + String(crc, HEX)); mEep->write(ADDR_SETTINGS_CRC, crc); -} +}*/ void app::sendMqttDiscoveryConfig(void) { DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 8c563fe1..9b751598 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -69,10 +69,8 @@ class app : public Main { void processPayload(bool retransmit); void showFavicon(void); - void showIndex(void); void showSetup(void); void showSave(void); - void showErase(void); void showStatistics(void); void showHoymiles(void); void showLiveData(void); @@ -80,8 +78,6 @@ class app : public Main { void webapi(void); - void saveValues(bool webSend); - void updateCrc(void); void sendMqttDiscoveryConfig(void); const char* getFieldDeviceClass(uint8_t fieldId); const char* getFieldStateClass(uint8_t fieldId); @@ -106,7 +102,6 @@ class app : public Main { HmSystemType *mSys; uint16_t mSendTicker; - uint16_t mSendInterval; uint8_t mSendLastIvId; invPayload_t mPayload[MAX_NUM_INVERTERS]; diff --git a/tools/esp8266/esp8266.cpp b/tools/esp8266/esp8266.cpp index 72caa280..fe44abc7 100644 --- a/tools/esp8266/esp8266.cpp +++ b/tools/esp8266/esp8266.cpp @@ -7,7 +7,10 @@ #include "app.h" #include "config.h" +#include "web.h" + app myApp; +web *mWebInst; //----------------------------------------------------------------------------- IRAM_ATTR void handleIntr(void) { @@ -18,6 +21,7 @@ IRAM_ATTR void handleIntr(void) { //----------------------------------------------------------------------------- void setup() { myApp.setup(WIFI_TRY_CONNECT_TIME); + mWebInst = new web(&myApp); // TODO: move to HmRadio attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING); diff --git a/tools/esp8266/main.cpp b/tools/esp8266/main.cpp index 14ed8667..11568fa9 100644 --- a/tools/esp8266/main.cpp +++ b/tools/esp8266/main.cpp @@ -6,18 +6,15 @@ #include "main.h" #include "version.h" -#include "html/h/style_css.h" -#include "html/h/setup_html.h" - - //----------------------------------------------------------------------------- Main::Main(void) { mDns = new DNSServer(); mWeb = new ESP8266WebServer(80); - mUpdater = new ESP8266HTTPUpdateServer(); mUdp = new WiFiUDP(); - mApActive = true; + memset(&config, 0, sizeof(config_t)); + + config.apActive = true; mWifiSettingsValid = false; mSettingsValid = false; @@ -25,9 +22,11 @@ Main::Main(void) { mNextTryTs = 0; mApLastTick = 0; - snprintf(mVersion, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); + // default config + snprintf(config.version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); + config.apActive = false; + config.sendInterval = SEND_INTERVAL; - memset(&mDeviceName, 0, DEVNAME_LEN); mEep = new eep(); Serial.begin(115200); @@ -50,17 +49,9 @@ Main::Main(void) { //----------------------------------------------------------------------------- void Main::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("Main::setup")); - bool startAp = mApActive; + bool startAp = config.apActive; mLimit = timeout; - mWeb->on("/setup", std::bind(&Main::showSetup, this)); - mWeb->on("/save", std::bind(&Main::showSave, this)); - mWeb->on("/uptime", std::bind(&Main::showUptime, this)); - mWeb->on("/time", std::bind(&Main::showTime, this)); - mWeb->on("/style.css", std::bind(&Main::showCss, this)); - mWeb->on("/reboot", std::bind(&Main::showReboot, this)); - mWeb->on("/factory", std::bind(&Main::showFactoryRst, this)); - mWeb->onNotFound ( std::bind(&Main::showNotFound, this)); startAp = getConfig(); @@ -69,8 +60,7 @@ void Main::setup(uint32_t timeout) { startAp = setupStation(timeout); #endif - mUpdater->setup(mWeb); - mApActive = startAp; + config.apActive = startAp; mStActive = !startAp; } @@ -78,12 +68,12 @@ void Main::setup(uint32_t timeout) { //----------------------------------------------------------------------------- void Main::loop(void) { //DPRINTLN(DBG_VERBOSE, F("M")); - if(mApActive) { + if(config.apActive) { mDns->processNextRequest(); #ifndef AP_ONLY if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { - mApActive = setupStation(mLimit); - if(mApActive) { + config.apActive = setupStation(mLimit); + if(config.apActive) { if(strlen(WIFI_AP_PWD) < 8) DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); mApLastTick = millis(); @@ -111,7 +101,7 @@ void Main::loop(void) { if(0 != mTimestamp) mTimestamp++; else { - if(!mApActive) { + if(!config.apActive) { mTimestamp = getNtpTime(); DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); } @@ -132,24 +122,24 @@ void Main::loop(void) { //----------------------------------------------------------------------------- bool Main::getConfig(void) { DPRINTLN(DBG_VERBOSE, F("Main::getConfig")); - bool mApActive = false; + config.apActive = false; mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); if(mWifiSettingsValid) { - mEep->read(ADDR_SSID, mStationSsid, SSID_LEN); - mEep->read(ADDR_PWD, mStationPwd, PWD_LEN); - mEep->read(ADDR_DEVNAME, mDeviceName, DEVNAME_LEN); + mEep->read(ADDR_SSID, config.stationSsid, SSID_LEN); + mEep->read(ADDR_PWD, config.stationPwd, PWD_LEN); + mEep->read(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); } - if((!mWifiSettingsValid) || (mStationSsid[0] == 0xff)) { - snprintf(mStationSsid, SSID_LEN, "%s", FB_WIFI_SSID); - snprintf(mStationPwd, PWD_LEN, "%s", FB_WIFI_PWD); - snprintf(mDeviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + if((!mWifiSettingsValid) || (config.stationSsid[0] == 0xff)) { + snprintf(config.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); + snprintf(config.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); + snprintf(config.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); } - return mApActive; + return config.apActive; } @@ -171,12 +161,12 @@ void Main::setupAp(const char *ssid, const char *pwd) { mDns->start(mDnsPort, "*", apIp); - mWeb->onNotFound([&]() { + /*mWeb->onNotFound([&]() { showSetup(); }); mWeb->on("/", std::bind(&Main::showSetup, this)); - mWeb->begin(); + mWeb->begin();*/ } @@ -194,12 +184,12 @@ bool Main::setupStation(uint32_t timeout) { } WiFi.mode(WIFI_STA); - WiFi.begin(mStationSsid, mStationPwd); - if(String(mDeviceName) != "") - WiFi.hostname(mDeviceName); + WiFi.begin(config.stationSsid, config.stationPwd); + if(String(config.deviceName) != "") + WiFi.hostname(config.deviceName); delay(2000); - DPRINTLN(DBG_INFO, F("connect to network '") + String(mStationSsid) + F("' ...")); + DPRINTLN(DBG_INFO, F("connect to network '") + String(config.stationSsid) + F("' ...")); while (WiFi.status() != WL_CONNECTED) { delay(100); if(cnt % 100 == 0) @@ -230,68 +220,21 @@ bool Main::setupStation(uint32_t timeout) { } -//----------------------------------------------------------------------------- -void Main::showSetup(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showSetup")); - String html = FPSTR(setup_html); - html.replace(F("{SSID}"), mStationSsid); - // PWD will be left at the default value (for protection) - // -> the PWD will only be changed if it does not match the default "{PWD}" - html.replace(F("{DEVICE}"), String(mDeviceName)); - html.replace(F("{VERSION}"), String(mVersion)); - if(mApActive) - html.replace("{IP}", String(F("http://192.168.1.1"))); - else - html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); - - mWeb->send(200, F("text/html"), html); -} - - -//----------------------------------------------------------------------------- -void Main::showCss(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showCss")); - mWeb->send(200, "text/css", FPSTR(style_css)); -} - - -//----------------------------------------------------------------------------- -void Main::showSave(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showSave")); - saveValues(true); -} - //----------------------------------------------------------------------------- -void Main::saveValues(bool webSend = true) { +void Main::saveValues(uint32_t saveMask = 0) { DPRINTLN(DBG_VERBOSE, F("Main::saveValues")); - if(mWeb->args() > 0) { - if(mWeb->arg("ssid") != "") { - memset(mStationSsid, 0, SSID_LEN); - mWeb->arg("ssid").toCharArray(mStationSsid, SSID_LEN); - mEep->write(ADDR_SSID, mStationSsid, SSID_LEN); - - if(mWeb->arg("pwd") != "{PWD}") { - memset(mStationPwd, 0, PWD_LEN); - mWeb->arg("pwd").toCharArray(mStationPwd, PWD_LEN); - mEep->write(ADDR_PWD, mStationPwd, PWD_LEN); - } - } - - memset(mDeviceName, 0, DEVNAME_LEN); - mWeb->arg("device").toCharArray(mDeviceName, DEVNAME_LEN); - mEep->write(ADDR_DEVNAME, mDeviceName, DEVNAME_LEN); - mEep->commit(); + if(CHK_MSK(saveMask, SAVE_SSID)) + mEep->write(ADDR_SSID, config.stationSsid, SSID_LEN); + if(CHK_MSK(saveMask, SAVE_PWD)) + mEep->write(ADDR_PWD, config.stationPwd, SSID_LEN); + if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) + mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); + if(saveMask > 0) { updateCrc(); - if(webSend) { - if(mWeb->arg("reboot") == "on") - showReboot(); - else // TODO: add device name as redirect in AP-mode - mWeb->send(200, F("text/html"), F("Setup saved" - "

saved

")); - } + mEep->commit(); } } @@ -307,87 +250,6 @@ void Main::updateCrc(void) { } -//----------------------------------------------------------------------------- -void Main::showUptime(void) { - //DPRINTLN(DBG_VERBOSE, F("Main::showUptime")); - char time[20] = {0}; - - int upTimeSc = uint32_t((mUptimeSecs) % 60); - int upTimeMn = uint32_t((mUptimeSecs / (60)) % 60); - int upTimeHr = uint32_t((mUptimeSecs / (60 * 60)) % 24); - int upTimeDy = uint32_t((mUptimeSecs / (60 * 60 * 24)) % 365); - - snprintf(time, 20, "%d Tage, %02d:%02d:%02d", upTimeDy, upTimeHr, upTimeMn, upTimeSc); - - mWeb->send(200, "text/plain", String(time)); -} - - -//----------------------------------------------------------------------------- -void Main::showTime(void) { - //DPRINTLN(DBG_VERBOSE, F("Main::showTime")); - mWeb->send(200, "text/plain", getDateTimeStr(mTimestamp)); -} - - -//----------------------------------------------------------------------------- -void Main::showNotFound(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showNotFound - ") + mWeb->uri()); - String msg = F("File Not Found\n\nURI: "); - msg += mWeb->uri(); - msg += F("\nMethod: "); - msg += ( mWeb->method() == HTTP_GET ) ? "GET" : "POST"; - msg += F("\nArguments: "); - msg += mWeb->args(); - msg += "\n"; - - for(uint8_t i = 0; i < mWeb->args(); i++ ) { - msg += " " + mWeb->argName(i) + ": " + mWeb->arg(i) + "\n"; - } - - mWeb->send(404, F("text/plain"), msg); -} - - -//----------------------------------------------------------------------------- -void Main::showReboot(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showReboot")); - mWeb->send(200, F("text/html"), F("Rebooting ...rebooting ... auto reload after 10s")); - delay(1000); - ESP.restart(); -} - - - -//----------------------------------------------------------------------------- -void Main::showFactoryRst(void) { - DPRINTLN(DBG_VERBOSE, F("Main::showFactoryRst")); - String content = ""; - int refresh = 3; - if(mWeb->args() > 0) { - if(mWeb->arg("reset").toInt() == 1) { - eraseSettings(true); - content = F("factory reset: success\n\nrebooting ... "); - refresh = 10; - } - else { - content = F("factory reset: aborted"); - refresh = 3; - } - } - else { - content = F("

Factory Reset

" - "

RESET

CANCEL

"); - refresh = 120; - } - mWeb->send(200, F("text/html"), F("Factory Reset") + content + F("")); - if(refresh == 10) { - delay(1000); - ESP.restart(); - } -} - - //----------------------------------------------------------------------------- time_t Main::getNtpTime(void) { //DPRINTLN(DBG_VERBOSE, F("Main::getNtpTime")); @@ -447,18 +309,6 @@ void Main::sendNTPpacket(IPAddress& address) { } -//----------------------------------------------------------------------------- -String Main::getDateTimeStr(time_t t) { - //DPRINTLN(DBG_VERBOSE, F("Main::getDateTimeStr")); - char str[20] = {0}; - if(0 == t) - sprintf(str, "n/a"); - else - sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); - return String(str); -} - - //----------------------------------------------------------------------------- // calculates the daylight saving time for middle Europe. Input: Unixtime in UTC // from: https://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536 diff --git a/tools/esp8266/main.h b/tools/esp8266/main.h index 8f114f09..044984d3 100644 --- a/tools/esp8266/main.h +++ b/tools/esp8266/main.h @@ -13,8 +13,6 @@ #include #include -#include - // NTP #include #include @@ -32,17 +30,72 @@ const byte mDnsPort = 53; #define NTP_PACKET_SIZE 48 #define TIMEZONE 1 // Central European time +1 + +typedef struct { + char version[12]; + char deviceName[DEVNAME_LEN]; + + // wifi + char stationSsid[SSID_LEN]; + char stationPwd[PWD_LEN]; + bool apActive; + + // nrf24 + uint16_t sendInterval; +} config_t; + + +#define SAVE_SSID 0x00000001 +#define SAVE_PWD 0x00000002 +#define SAVE_DEVICE_NAME 0x00000004 + +#define CHK_MSK(v, m) ((m & v) == m) + class Main { public: Main(void); virtual void setup(uint32_t timeout); virtual void loop(); - String getDateTimeStr (time_t t); + void saveValues(uint32_t saveMask); + + String getDateTimeStr(time_t t) { + char str[20] = {0}; + if(0 == t) + sprintf(str, "n/a"); + else + sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); + return String(str); + } + + inline uint32_t getUptime(void) { + return mUptimeSecs; + } + + inline uint32_t getTimestamp(void) { + return mTimestamp; + } + + void eraseSettings(bool all = false) { + //DPRINTLN(DBG_VERBOSE, F("main.h:eraseSettings")); + uint8_t buf[64] = {0}; + uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS; + uint16_t end; + do { + end = addr + 64; + if(end > (ADDR_SETTINGS_CRC + 2)) + end = (ADDR_SETTINGS_CRC + 2); + DPRINTLN(DBG_DEBUG, F("erase: 0x") + String(addr, HEX) + " - 0x" + String(end, HEX)); + mEep->write(addr, buf, (end-addr)); + addr = end; + } while(addr < (ADDR_SETTINGS_CRC + 2)); + mEep->commit(); + } + + ESP8266WebServer *mWeb; + config_t config; protected: - void showReboot(void); - virtual void saveValues(bool webSend); virtual void updateCrc(void); inline uint16_t buildEEpCrc(uint32_t start, uint32_t length) { @@ -71,22 +124,6 @@ class Main { return (crcCheck == crcRd); } - void eraseSettings(bool all = false) { - //DPRINTLN(DBG_VERBOSE, F("main.h:eraseSettings")); - uint8_t buf[64] = {0}; - uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS; - uint16_t end; - do { - end = addr + 64; - if(end > (ADDR_SETTINGS_CRC + 2)) - end = (ADDR_SETTINGS_CRC + 2); - DPRINTLN(DBG_DEBUG, F("erase: 0x") + String(addr, HEX) + " - 0x" + String(end, HEX)); - mEep->write(addr, buf, (end-addr)); - addr = end; - } while(addr < (ADDR_SETTINGS_CRC + 2)); - mEep->commit(); - } - inline bool checkTicker(uint32_t *ticker, uint32_t interval) { //DPRINTLN(DBG_VERBOSE, F("c")); uint32_t mil = millis(); @@ -113,15 +150,10 @@ class Main { DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag)); } - char mStationSsid[SSID_LEN]; - char mStationPwd[PWD_LEN]; bool mWifiSettingsValid; bool mSettingsValid; - bool mApActive; bool mStActive; - ESP8266WebServer *mWeb; - char mVersion[9]; - char mDeviceName[DEVNAME_LEN]; + eep *mEep; uint32_t mTimestamp; uint32_t mLimit; @@ -133,13 +165,6 @@ class Main { void setupAp(const char *ssid, const char *pwd); bool setupStation(uint32_t timeout); - void showNotFound(void); - virtual void showSetup(void); - virtual void showSave(void); - void showUptime(void); - void showTime(void); - void showCss(void); - void showFactoryRst(void); time_t getNtpTime(void); void sendNTPpacket(IPAddress& address); @@ -151,7 +176,6 @@ class Main { uint8_t mHeapStatCnt; DNSServer *mDns; - ESP8266HTTPUpdateServer *mUpdater; WiFiUDP *mUdp; // for time server }; From ccb9fb537ddcb0ed3d107a9ea3a4059623629486 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 02:15:56 +0200 Subject: [PATCH 03/10] * main in app integriert, Zwischenstand --- tools/esp8266/app.cpp | 406 +++++++++++++++++++++++++++++++------ tools/esp8266/app.h | 221 ++++++++++++++++++-- tools/esp8266/hmInverter.h | 2 +- tools/esp8266/hmSystem.h | 4 +- tools/esp8266/main.cpp | 328 ------------------------------ tools/esp8266/main.h | 183 ----------------- tools/esp8266/web.h | 218 ++++++++++++++++++++ 7 files changed, 759 insertions(+), 603 deletions(-) delete mode 100644 tools/esp8266/main.cpp delete mode 100644 tools/esp8266/main.h create mode 100644 tools/esp8266/web.h diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index c4c6acdc..406fb509 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -5,16 +5,49 @@ #include "app.h" -#include "favicon.h" -#include "html/h/setup_html.h" #include "html/h/hoymiles_html.h" #include - //----------------------------------------------------------------------------- -app::app() : Main() { - DPRINTLN(DBG_VERBOSE, F("app::app():Main")); +app::app() { + DPRINTLN(DBG_VERBOSE, F("app::app")); + mDns = new DNSServer(); + mWeb = new ESP8266WebServer(80); + mUdp = new WiFiUDP(); + + memset(&config, 0, sizeof(config_t)); + + config.apActive = true; + mWifiSettingsValid = false; + mSettingsValid = false; + + mLimit = 10; + mNextTryTs = 0; + mApLastTick = 0; + + // default config + snprintf(config.version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); + config.apActive = false; + config.sendInterval = SEND_INTERVAL; + + + mEep = new eep(); + Serial.begin(115200); + DPRINTLN(DBG_VERBOSE, F("Main::Main")); + + mUptimeSecs = 0; + mUptimeTicker = 0xffffffff; + mUptimeInterval = 1000; + +#ifdef AP_ONLY + mTimestamp = 1; +#else + mTimestamp = 0; +#endif + + mHeapStatCnt = 0; + mSendTicker = 0xffff; mMqttTicker = 0xffff; mMqttInterval = MQTT_INTERVAL; @@ -51,9 +84,8 @@ app::~app(void) { //----------------------------------------------------------------------------- void app::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("app::setup")); - Main::setup(timeout); + Mainsetup(timeout); - mWeb->on("/favicon.ico", std::bind(&app::showFavicon, this)); //mWeb->on("/setup", std::bind(&app::showSetup, this)); //mWeb->on("/save", std::bind(&app::showSave, this)); mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); @@ -97,9 +129,9 @@ void app::setup(uint32_t timeout) { } } - mEep->read(ADDR_INV_MAX_RTRY, &mMaxRetransPerPyld); - if(0 == mMaxRetransPerPyld) - mMaxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; + mEep->read(ADDR_INV_MAX_RTRY, &config.maxRetransPerPyld); + if(0 == config.maxRetransPerPyld) + config.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; // pinout mEep->read(ADDR_PINOUT, &mSys->Radio.pinCs); @@ -219,7 +251,7 @@ void app::setup(uint32_t timeout) { //----------------------------------------------------------------------------- void app::loop(void) { DPRINTLN(DBG_VERBOSE, F("app::loop")); - Main::loop(); + MainLoop(); mSys->Radio.loop(); @@ -510,7 +542,7 @@ void app::processPayload(bool retransmit) { if(!buildPayload(iv->id)) { if(mPayload[iv->id].requested) { if(retransmit) { - if(mPayload[iv->id].retransmits < mMaxRetransPerPyld) { + if(mPayload[iv->id].retransmits < config.maxRetransPerPyld) { mPayload[iv->id].retransmits++; if(mPayload[iv->id].maxPackId != 0) { for(uint8_t i = 0; i < (mPayload[iv->id].maxPackId-1); i ++) { @@ -684,7 +716,7 @@ void app::processPayload(bool retransmit) { if(mSettingsValid) { html.replace(F("{INV_INTVL}"), String(mSendInterval)); - html.replace(F("{INV_RETRIES}"), String(mMaxRetransPerPyld)); + html.replace(F("{INV_RETRIES}"), String(maxRetransPerPyld)); uint8_t tmp; mEep->read(ADDR_SER_ENABLE, &tmp); @@ -877,15 +909,6 @@ void app::showHoymiles(void) { } -//----------------------------------------------------------------------------- -void app::showFavicon(void) { - DPRINTLN(DBG_VERBOSE, F("app::showFavicon")); - static const char favicon_type[] PROGMEM = "image/x-icon"; - static const char favicon_content[] PROGMEM = FAVICON_PANEL_16; - mWeb->send_P(200, favicon_type, favicon_content, sizeof(favicon_content)); -} - - //----------------------------------------------------------------------------- void app::showLiveData(void) { DPRINTLN(DBG_VERBOSE, F("app::showLiveData")); @@ -998,42 +1021,7 @@ void app::showJSON(void) { char buf[20] = {0}; uint8_t i = 0; uint16_t interval; - uint16_t activepowerlimit=-1; - // inverter - serial_u addr; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - // address - mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20); - if(strlen(buf) == 0) - memset(buf, 0, 20); - addr.u64 = Serial2u64(buf); - mEep->write(ADDR_INV_ADDR + (i * 8), addr.u64); - - // active power limit - activepowerlimit = mWeb->arg("inv" + String(i) + "ActivePowerLimit").toInt(); - if (activepowerlimit != 0xffff && activepowerlimit > 0) { - mEep->write(ADDR_INV_PWR_LIM + i * 2,activepowerlimit); - } - - // name - mWeb->arg("inv" + String(i) + "Name").toCharArray(buf, 20); - mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), buf, MAX_NAME_LENGTH); - - // max channel power / name - for(uint8_t j = 0; j < 4; j++) { - uint16_t pwr = mWeb->arg("inv" + String(i) + "ModPwr" + String(j)).toInt(); - mEep->write(ADDR_INV_CH_PWR + (i * 2 * 4) + (j*2), pwr); - memset(buf, 0, 20); - mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(buf, 20); - mEep->write(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, buf, MAX_NAME_LENGTH); - } - } - - interval = mWeb->arg("invInterval").toInt(); - mEep->write(ADDR_INV_INTERVAL, interval); - i = mWeb->arg("invRetry").toInt(); - mEep->write(ADDR_INV_MAX_RTRY, i); // pinout @@ -1106,16 +1094,6 @@ void app::showJSON(void) { }*/ -//----------------------------------------------------------------------------- -/*void app::updateCrc(void) { - DPRINTLN(DBG_VERBOSE, F("app::updateCrc")); - Main::updateCrc(); - - uint16_t crc; - crc = buildEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT) - (ADDR_START_SETTINGS))); - DPRINTLN(DBG_DEBUG, F("new CRC: ") + String(crc, HEX)); - mEep->write(ADDR_SETTINGS_CRC, crc); -}*/ void app::sendMqttDiscoveryConfig(void) { DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); @@ -1187,3 +1165,297 @@ const char* app::getFieldStateClass(uint8_t fieldId) { } return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId]; } + + + +//----------------------------------------------------------------------------- +void app::Mainsetup(uint32_t timeout) { + DPRINTLN(DBG_VERBOSE, F("Main::setup")); + bool startAp = config.apActive; + mLimit = timeout; + + + startAp = getConfig(); + +#ifndef AP_ONLY + if(false == startAp) + startAp = setupStation(timeout); +#endif + + config.apActive = startAp; + mStActive = !startAp; +} + + +//----------------------------------------------------------------------------- +void app::MainLoop(void) { + //DPRINTLN(DBG_VERBOSE, F("M")); + if(config.apActive) { + mDns->processNextRequest(); +#ifndef AP_ONLY + if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { + config.apActive = setupStation(mLimit); + if(config.apActive) { + if(strlen(WIFI_AP_PWD) < 8) + DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); + mApLastTick = millis(); + mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); + setupAp(WIFI_AP_SSID, WIFI_AP_PWD); + } + } + else { + if(millis() - mApLastTick > 10000) { + uint8_t cnt = WiFi.softAPgetStationNum(); + if(cnt > 0) { + DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); + mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); + } + mApLastTick = millis(); + DPRINTLN(DBG_INFO, F("AP will be closed in ") + String((mNextTryTs - mApLastTick) / 1000) + F(" seconds")); + } + } +#endif + } + mWeb->handleClient(); + + if(checkTicker(&mUptimeTicker, mUptimeInterval)) { + mUptimeSecs++; + if(0 != mTimestamp) + mTimestamp++; + else { + if(!config.apActive) { + mTimestamp = getNtpTime(); + DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); + } + } + + /*if(++mHeapStatCnt >= 10) { + mHeapStatCnt = 0; + stats(); + }*/ + } + if (WiFi.status() != WL_CONNECTED) { + DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); + mStActive = false; + } +} + + +//----------------------------------------------------------------------------- +bool app::getConfig(void) { + DPRINTLN(DBG_VERBOSE, F("app::getConfig")); + config.apActive = false; + + mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); + mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); + + if(mWifiSettingsValid) { + mEep->read(ADDR_SSID, config.stationSsid, SSID_LEN); + mEep->read(ADDR_PWD, config.stationPwd, PWD_LEN); + mEep->read(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); + } + + if((!mWifiSettingsValid) || (config.stationSsid[0] == 0xff)) { + snprintf(config.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); + snprintf(config.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); + snprintf(config.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + } + + return config.apActive; +} + + +//----------------------------------------------------------------------------- +void app::setupAp(const char *ssid, const char *pwd) { + DPRINTLN(DBG_VERBOSE, F("app::setupAp")); + IPAddress apIp(192, 168, 1, 1); + + DPRINTLN(DBG_INFO, F("\n---------\nAP MODE\nSSID: ") + + String(ssid) + F("\nPWD: ") + + String(pwd) + F("\nActive for: ") + + String(WIFI_AP_ACTIVE_TIME) + F(" seconds") + + F("\n---------\n")); + DPRINTLN(DBG_DEBUG, String(mNextTryTs)); + + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(apIp, apIp, IPAddress(255, 255, 255, 0)); + WiFi.softAP(ssid, pwd); + + mDns->start(mDnsPort, "*", apIp); + + /*mWeb->onNotFound([&]() { + showSetup(); + }); + mWeb->on("/", std::bind(&app::showSetup, this)); + + mWeb->begin();*/ +} + + +//----------------------------------------------------------------------------- +bool app::setupStation(uint32_t timeout) { + DPRINTLN(DBG_VERBOSE, F("app::setupStation")); + int32_t cnt; + bool startAp = false; + + if(timeout >= 3) + cnt = (timeout - 3) / 2 * 10; + else { + timeout = 1; + cnt = 1; + } + + WiFi.mode(WIFI_STA); + WiFi.begin(config.stationSsid, config.stationPwd); + if(String(config.deviceName) != "") + WiFi.hostname(config.deviceName); + + delay(2000); + DPRINTLN(DBG_INFO, F("connect to network '") + String(config.stationSsid) + F("' ...")); + while (WiFi.status() != WL_CONNECTED) { + delay(100); + if(cnt % 100 == 0) + Serial.println("."); + else + Serial.print("."); + + if(timeout > 0) { // limit == 0 -> no limit + if(--cnt <= 0) { + if(WiFi.status() != WL_CONNECTED) { + startAp = true; + WiFi.disconnect(); + } + delay(100); + break; + } + } + } + Serial.println("."); + + if(false == startAp) { + mWeb->begin(); + } + + delay(1000); + + return startAp; +} + + + +//----------------------------------------------------------------------------- +void app::saveValues(uint32_t saveMask = 0) { + DPRINTLN(DBG_VERBOSE, F("app::saveValues")); + + if(CHK_MSK(saveMask, SAVE_SSID)) + mEep->write(ADDR_SSID, config.stationSsid, SSID_LEN); + if(CHK_MSK(saveMask, SAVE_PWD)) + mEep->write(ADDR_PWD, config.stationPwd, SSID_LEN); + if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) + mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); + + Inverter<> *iv; + if(CHK_MSK(saveMask, SAVE_INVERTERS)) { + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + iv = mSys->getInverterByPos(i); + if(NULL != iv) { + mEep->write(ADDR_INV_ADDR + (i * 8), iv->serial.u64); + mEep->write(ADDR_INV_PWR_LIM + i * 2, iv->powerLimit[0]); + mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), iv->name, MAX_NAME_LENGTH); + // max channel power / name + for(uint8_t j = 0; j < 4; j++) { + mEep->write(ADDR_INV_CH_PWR + (i * 2 * 4) + (j*2), iv->chMaxPwr[j]); + mEep->write(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH); + } + } + } + } + if(CHK_MSK(saveMask, SAVE_INV_SEND_INTERVAL)) + mEep->write(ADDR_INV_INTERVAL, config.sendInterval); + if(CHK_MSK(saveMask, SAVE_INV_RETRY)) + mEep->write(ADDR_INV_MAX_RTRY, config.maxRetransPerPyld); + + if(saveMask > 0) { + updateCrc(); + mEep->commit(); + } +} + + + +//----------------------------------------------------------------------------- +time_t app::getNtpTime(void) { + //DPRINTLN(DBG_VERBOSE, F("app::getNtpTime")); + time_t date = 0; + IPAddress timeServer; + uint8_t buf[NTP_PACKET_SIZE]; + uint8_t retry = 0; + + WiFi.hostByName(NTP_SERVER_NAME, timeServer); + mUdp->begin(NTP_LOCAL_PORT); + + + sendNTPpacket(timeServer); + + while(retry++ < 5) { + int wait = 150; + while(--wait) { + if(NTP_PACKET_SIZE <= mUdp->parsePacket()) { + uint64_t secsSince1900; + mUdp->read(buf, NTP_PACKET_SIZE); + secsSince1900 = (buf[40] << 24); + secsSince1900 |= (buf[41] << 16); + secsSince1900 |= (buf[42] << 8); + secsSince1900 |= (buf[43] ); + + date = secsSince1900 - 2208988800UL; // UTC time + date += (TIMEZONE + offsetDayLightSaving(date)) * 3600; + break; + } + else + delay(10); + } + } + + return date; +} + + +//----------------------------------------------------------------------------- +void app::sendNTPpacket(IPAddress& address) { + //DPRINTLN(DBG_VERBOSE, F("app::sendNTPpacket")); + uint8_t buf[NTP_PACKET_SIZE] = {0}; + + buf[0] = B11100011; // LI, Version, Mode + buf[1] = 0; // Stratum + buf[2] = 6; // Max Interval between messages in seconds + buf[3] = 0xEC; // Clock Precision + // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset + buf[12] = 49; // four-byte reference ID identifying + buf[13] = 0x4E; + buf[14] = 49; + buf[15] = 52; + + mUdp->beginPacket(address, 123); // NTP request, port 123 + mUdp->write(buf, NTP_PACKET_SIZE); + mUdp->endPacket(); +} + + +//----------------------------------------------------------------------------- +// calculates the daylight saving time for middle Europe. Input: Unixtime in UTC +// from: https://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536 +time_t app::offsetDayLightSaving (uint32_t local_t) { + //DPRINTLN(DBG_VERBOSE, F("app::offsetDayLightSaving")); + int m = month (local_t); + if(m < 3 || m > 10) return 0; // no DSL in Jan, Feb, Nov, Dez + if(m > 3 && m < 10) return 1; // DSL in Apr, May, Jun, Jul, Aug, Sep + int y = year (local_t); + int h = hour (local_t); + int hToday = (h + 24 * day(local_t)); + if((m == 3 && hToday >= (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 4) % 7))) + || (m == 10 && hToday < (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 1) % 7))) ) + return 1; + else + return 0; +} diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 9b751598..90d6dcd1 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -6,12 +6,24 @@ #ifndef __APP_H__ #define __APP_H__ -#include "main.h" +#include "dbg.h" +#include "Arduino.h" + +#include +#include + +// NTP +#include +#include +#include + #include #include #include +#include "eep.h" #include "defines.h" +#include "crc.h" #include "CircularBuffer.h" #include "hmSystem.h" @@ -48,8 +60,41 @@ typedef struct { bool requested; } invPayload_t; +const byte mDnsPort = 53; + +/* NTP TIMESERVER CONFIG */ +#define NTP_SERVER_NAME "pool.ntp.org" +#define NTP_LOCAL_PORT 8888 +#define NTP_PACKET_SIZE 48 +#define TIMEZONE 1 // Central European time +1 + + +typedef struct { + char version[12]; + char deviceName[DEVNAME_LEN]; + + // wifi + char stationSsid[SSID_LEN]; + char stationPwd[PWD_LEN]; + bool apActive; + + // nrf24 + uint16_t sendInterval; + uint8_t maxRetransPerPyld; + +} config_t; + -class app : public Main { +#define SAVE_SSID 0x00000001 +#define SAVE_PWD 0x00000002 +#define SAVE_DEVICE_NAME 0x00000004 +#define SAVE_INVERTERS 0x00000008 +#define SAVE_INV_SEND_INTERVAL 0x00000010 +#define SAVE_INV_RETRY 0x00000020 + +#define CHK_MSK(v, m) ((m & v) == m) + +class app { public: app(); ~app(); @@ -63,24 +108,7 @@ class app : public Main { uint8_t getIrqPin(void) { return mSys->Radio.pinIrq; } - - private: - bool buildPayload(uint8_t id); - void processPayload(bool retransmit); - - void showFavicon(void); - void showSetup(void); - void showSave(void); - void showStatistics(void); - void showHoymiles(void); - void showLiveData(void); - void showJSON(void); - void webapi(void); - - - void sendMqttDiscoveryConfig(void); - const char* getFieldDeviceClass(uint8_t fieldId); - const char* getFieldStateClass(uint8_t fieldId); + HmSystemType *mSys; uint64_t Serial2u64(const char *val) { char tmp[3] = {0}; @@ -96,10 +124,160 @@ class app : public Main { } return ret; } + void saveValues(uint32_t saveMask); + + String getDateTimeStr(time_t t) { + char str[20] = {0}; + if(0 == t) + sprintf(str, "n/a"); + else + sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); + return String(str); + } + + inline uint32_t getUptime(void) { + return mUptimeSecs; + } + + inline uint32_t getTimestamp(void) { + return mTimestamp; + } + + void eraseSettings(bool all = false) { + //DPRINTLN(DBG_VERBOSE, F("main.h:eraseSettings")); + uint8_t buf[64] = {0}; + uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS; + uint16_t end; + do { + end = addr + 64; + if(end > (ADDR_SETTINGS_CRC + 2)) + end = (ADDR_SETTINGS_CRC + 2); + DPRINTLN(DBG_DEBUG, F("erase: 0x") + String(addr, HEX) + " - 0x" + String(end, HEX)); + mEep->write(addr, buf, (end-addr)); + addr = end; + } while(addr < (ADDR_SETTINGS_CRC + 2)); + mEep->commit(); + } + + ESP8266WebServer *mWeb; + config_t config; + + private: + void MainLoop(void); + void Mainsetup(uint32_t timeout); + bool getConfig(void); + void setupAp(const char *ssid, const char *pwd); + bool setupStation(uint32_t timeout); + + + time_t getNtpTime(void); + void sendNTPpacket(IPAddress& address); + time_t offsetDayLightSaving (uint32_t local_t); + + uint32_t mUptimeTicker; + uint16_t mUptimeInterval; + uint32_t mUptimeSecs; + uint8_t mHeapStatCnt; + + DNSServer *mDns; + + WiFiUDP *mUdp; // for time server + + + inline uint16_t buildEEpCrc(uint32_t start, uint32_t length) { + DPRINTLN(DBG_VERBOSE, F("main.h:buildEEpCrc")); + uint8_t buf[32]; + uint16_t crc = 0xffff; + uint8_t len; + + while(length > 0) { + len = (length < 32) ? length : 32; + mEep->read(start, buf, len); + crc = crc16(buf, len, crc); + start += len; + length -= len; + } + return crc; + } + + void updateCrc(void) { + DPRINTLN(DBG_VERBOSE, F("app::updateCrc")); + uint16_t crc; + + crc = buildEEpCrc(ADDR_START, ADDR_WIFI_CRC); + DPRINTLN(DBG_DEBUG, F("new Wifi CRC: ") + String(crc, HEX)); + mEep->write(ADDR_WIFI_CRC, crc); + + crc = buildEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT) - (ADDR_START_SETTINGS))); + DPRINTLN(DBG_DEBUG, F("new Settings CRC: ") + String(crc, HEX)); + mEep->write(ADDR_SETTINGS_CRC, crc); + + mEep->commit(); + } + + bool checkEEpCrc(uint32_t start, uint32_t length, uint32_t crcPos) { + DPRINTLN(DBG_VERBOSE, F("main.h:checkEEpCrc")); + DPRINTLN(DBG_DEBUG, F("start: ") + String(start) + F(", length: ") + String(length)); + uint16_t crcRd, crcCheck; + crcCheck = buildEEpCrc(start, length); + mEep->read(crcPos, &crcRd); + DPRINTLN(DBG_DEBUG, "CRC RD: " + String(crcRd, HEX) + " CRC CALC: " + String(crcCheck, HEX)); + return (crcCheck == crcRd); + } + + inline bool checkTicker(uint32_t *ticker, uint32_t interval) { + //DPRINTLN(DBG_VERBOSE, F("c")); + uint32_t mil = millis(); + if(mil >= *ticker) { + *ticker = mil + interval; + return true; + } + else if(mil < (*ticker - interval)) { + *ticker = mil + interval; + return true; + } + + return false; + } + + void stats(void) { + DPRINTLN(DBG_VERBOSE, F("main.h:stats")); + uint32_t free; + uint16_t max; + uint8_t frag; + ESP.getHeapStats(&free, &max, &frag); + DPRINT(DBG_VERBOSE, F("free: ") + String(free)); + DPRINT(DBG_VERBOSE, F(" - max: ") + String(max) + "%"); + DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag)); + } + + bool mWifiSettingsValid; + bool mSettingsValid; + bool mStActive; + + eep *mEep; + uint32_t mTimestamp; + uint32_t mLimit; + uint32_t mNextTryTs; + uint32_t mApLastTick; + + + bool buildPayload(uint8_t id); + void processPayload(bool retransmit); + + void showStatistics(void); + void showHoymiles(void); + void showLiveData(void); + void showJSON(void); + void webapi(void); + + + void sendMqttDiscoveryConfig(void); + const char* getFieldDeviceClass(uint8_t fieldId); + const char* getFieldStateClass(uint8_t fieldId); bool mShowRebootRequest; - HmSystemType *mSys; uint16_t mSendTicker; uint8_t mSendLastIvId; @@ -109,7 +287,6 @@ class app : public Main { uint32_t mRxSuccess; uint32_t mFrameCnt; uint8_t mLastPacketId; - uint8_t mMaxRetransPerPyld; // timer uint32_t mTicker; diff --git a/tools/esp8266/hmInverter.h b/tools/esp8266/hmInverter.h index f7a50cf7..88b3356a 100644 --- a/tools/esp8266/hmInverter.h +++ b/tools/esp8266/hmInverter.h @@ -83,7 +83,7 @@ class Inverter { Inverter() { ts = 0; - powerLimit[0] = -1; // 65535 W Limit -> unlimited + powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited powerLimit[1] = 0x0001; // 0x0000 --> set temporary , 0x0001 --> set persistent devControlRequest = false; devControlCmd = 0xff; diff --git a/tools/esp8266/hmSystem.h b/tools/esp8266/hmSystem.h index 3d7f7f2b..06307696 100644 --- a/tools/esp8266/hmSystem.h +++ b/tools/esp8266/hmSystem.h @@ -86,9 +86,9 @@ class HmSystem { return NULL; } - INVERTERTYPE *getInverterByPos(uint8_t pos) { + INVERTERTYPE *getInverterByPos(uint8_t pos, bool check = true) { DPRINTLN(DBG_VERBOSE, F("hmSystem.h:getInverterByPos")); - if(mInverter[pos].serial.u64 != 0ULL) + if((mInverter[pos].serial.u64 != 0ULL) || false == check) return &mInverter[pos]; else return NULL; diff --git a/tools/esp8266/main.cpp b/tools/esp8266/main.cpp deleted file mode 100644 index 11568fa9..00000000 --- a/tools/esp8266/main.cpp +++ /dev/null @@ -1,328 +0,0 @@ -//----------------------------------------------------------------------------- -// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778 -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ -//----------------------------------------------------------------------------- - -#include "main.h" -#include "version.h" - -//----------------------------------------------------------------------------- -Main::Main(void) { - mDns = new DNSServer(); - mWeb = new ESP8266WebServer(80); - mUdp = new WiFiUDP(); - - memset(&config, 0, sizeof(config_t)); - - config.apActive = true; - mWifiSettingsValid = false; - mSettingsValid = false; - - mLimit = 10; - mNextTryTs = 0; - mApLastTick = 0; - - // default config - snprintf(config.version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); - config.apActive = false; - config.sendInterval = SEND_INTERVAL; - - - mEep = new eep(); - Serial.begin(115200); - DPRINTLN(DBG_VERBOSE, F("Main::Main")); - - mUptimeSecs = 0; - mUptimeTicker = 0xffffffff; - mUptimeInterval = 1000; - -#ifdef AP_ONLY - mTimestamp = 1; -#else - mTimestamp = 0; -#endif - - mHeapStatCnt = 0; -} - - -//----------------------------------------------------------------------------- -void Main::setup(uint32_t timeout) { - DPRINTLN(DBG_VERBOSE, F("Main::setup")); - bool startAp = config.apActive; - mLimit = timeout; - - - startAp = getConfig(); - -#ifndef AP_ONLY - if(false == startAp) - startAp = setupStation(timeout); -#endif - - config.apActive = startAp; - mStActive = !startAp; -} - - -//----------------------------------------------------------------------------- -void Main::loop(void) { - //DPRINTLN(DBG_VERBOSE, F("M")); - if(config.apActive) { - mDns->processNextRequest(); -#ifndef AP_ONLY - if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { - config.apActive = setupStation(mLimit); - if(config.apActive) { - if(strlen(WIFI_AP_PWD) < 8) - DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); - mApLastTick = millis(); - mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); - setupAp(WIFI_AP_SSID, WIFI_AP_PWD); - } - } - else { - if(millis() - mApLastTick > 10000) { - uint8_t cnt = WiFi.softAPgetStationNum(); - if(cnt > 0) { - DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); - mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); - } - mApLastTick = millis(); - DPRINTLN(DBG_INFO, F("AP will be closed in ") + String((mNextTryTs - mApLastTick) / 1000) + F(" seconds")); - } - } -#endif - } - mWeb->handleClient(); - - if(checkTicker(&mUptimeTicker, mUptimeInterval)) { - mUptimeSecs++; - if(0 != mTimestamp) - mTimestamp++; - else { - if(!config.apActive) { - mTimestamp = getNtpTime(); - DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); - } - } - - /*if(++mHeapStatCnt >= 10) { - mHeapStatCnt = 0; - stats(); - }*/ - } - if (WiFi.status() != WL_CONNECTED) { - DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); - mStActive = false; - } -} - - -//----------------------------------------------------------------------------- -bool Main::getConfig(void) { - DPRINTLN(DBG_VERBOSE, F("Main::getConfig")); - config.apActive = false; - - mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); - mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); - - if(mWifiSettingsValid) { - mEep->read(ADDR_SSID, config.stationSsid, SSID_LEN); - mEep->read(ADDR_PWD, config.stationPwd, PWD_LEN); - mEep->read(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); - } - - if((!mWifiSettingsValid) || (config.stationSsid[0] == 0xff)) { - snprintf(config.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); - snprintf(config.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); - snprintf(config.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); - } - - return config.apActive; -} - - -//----------------------------------------------------------------------------- -void Main::setupAp(const char *ssid, const char *pwd) { - DPRINTLN(DBG_VERBOSE, F("Main::setupAp")); - IPAddress apIp(192, 168, 1, 1); - - DPRINTLN(DBG_INFO, F("\n---------\nAP MODE\nSSID: ") - + String(ssid) + F("\nPWD: ") - + String(pwd) + F("\nActive for: ") - + String(WIFI_AP_ACTIVE_TIME) + F(" seconds") - + F("\n---------\n")); - DPRINTLN(DBG_DEBUG, String(mNextTryTs)); - - WiFi.mode(WIFI_AP); - WiFi.softAPConfig(apIp, apIp, IPAddress(255, 255, 255, 0)); - WiFi.softAP(ssid, pwd); - - mDns->start(mDnsPort, "*", apIp); - - /*mWeb->onNotFound([&]() { - showSetup(); - }); - mWeb->on("/", std::bind(&Main::showSetup, this)); - - mWeb->begin();*/ -} - - -//----------------------------------------------------------------------------- -bool Main::setupStation(uint32_t timeout) { - DPRINTLN(DBG_VERBOSE, F("Main::setupStation")); - int32_t cnt; - bool startAp = false; - - if(timeout >= 3) - cnt = (timeout - 3) / 2 * 10; - else { - timeout = 1; - cnt = 1; - } - - WiFi.mode(WIFI_STA); - WiFi.begin(config.stationSsid, config.stationPwd); - if(String(config.deviceName) != "") - WiFi.hostname(config.deviceName); - - delay(2000); - DPRINTLN(DBG_INFO, F("connect to network '") + String(config.stationSsid) + F("' ...")); - while (WiFi.status() != WL_CONNECTED) { - delay(100); - if(cnt % 100 == 0) - Serial.println("."); - else - Serial.print("."); - - if(timeout > 0) { // limit == 0 -> no limit - if(--cnt <= 0) { - if(WiFi.status() != WL_CONNECTED) { - startAp = true; - WiFi.disconnect(); - } - delay(100); - break; - } - } - } - Serial.println("."); - - if(false == startAp) { - mWeb->begin(); - } - - delay(1000); - - return startAp; -} - - - -//----------------------------------------------------------------------------- -void Main::saveValues(uint32_t saveMask = 0) { - DPRINTLN(DBG_VERBOSE, F("Main::saveValues")); - - if(CHK_MSK(saveMask, SAVE_SSID)) - mEep->write(ADDR_SSID, config.stationSsid, SSID_LEN); - if(CHK_MSK(saveMask, SAVE_PWD)) - mEep->write(ADDR_PWD, config.stationPwd, SSID_LEN); - if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) - mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); - - if(saveMask > 0) { - updateCrc(); - mEep->commit(); - } -} - - -//----------------------------------------------------------------------------- -void Main::updateCrc(void) { - DPRINTLN(DBG_VERBOSE, F("Main::updateCrc")); - uint16_t crc; - crc = buildEEpCrc(ADDR_START, ADDR_WIFI_CRC); - //Serial.println("new CRC: " + String(crc, HEX)); - mEep->write(ADDR_WIFI_CRC, crc); - mEep->commit(); -} - - -//----------------------------------------------------------------------------- -time_t Main::getNtpTime(void) { - //DPRINTLN(DBG_VERBOSE, F("Main::getNtpTime")); - time_t date = 0; - IPAddress timeServer; - uint8_t buf[NTP_PACKET_SIZE]; - uint8_t retry = 0; - - WiFi.hostByName(NTP_SERVER_NAME, timeServer); - mUdp->begin(NTP_LOCAL_PORT); - - - sendNTPpacket(timeServer); - - while(retry++ < 5) { - int wait = 150; - while(--wait) { - if(NTP_PACKET_SIZE <= mUdp->parsePacket()) { - uint64_t secsSince1900; - mUdp->read(buf, NTP_PACKET_SIZE); - secsSince1900 = (buf[40] << 24); - secsSince1900 |= (buf[41] << 16); - secsSince1900 |= (buf[42] << 8); - secsSince1900 |= (buf[43] ); - - date = secsSince1900 - 2208988800UL; // UTC time - date += (TIMEZONE + offsetDayLightSaving(date)) * 3600; - break; - } - else - delay(10); - } - } - - return date; -} - - -//----------------------------------------------------------------------------- -void Main::sendNTPpacket(IPAddress& address) { - //DPRINTLN(DBG_VERBOSE, F("Main::sendNTPpacket")); - uint8_t buf[NTP_PACKET_SIZE] = {0}; - - buf[0] = B11100011; // LI, Version, Mode - buf[1] = 0; // Stratum - buf[2] = 6; // Max Interval between messages in seconds - buf[3] = 0xEC; // Clock Precision - // bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset - buf[12] = 49; // four-byte reference ID identifying - buf[13] = 0x4E; - buf[14] = 49; - buf[15] = 52; - - mUdp->beginPacket(address, 123); // NTP request, port 123 - mUdp->write(buf, NTP_PACKET_SIZE); - mUdp->endPacket(); -} - - -//----------------------------------------------------------------------------- -// calculates the daylight saving time for middle Europe. Input: Unixtime in UTC -// from: https://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536 -time_t Main::offsetDayLightSaving (uint32_t local_t) { - //DPRINTLN(DBG_VERBOSE, F("Main::offsetDayLightSaving")); - int m = month (local_t); - if(m < 3 || m > 10) return 0; // no DSL in Jan, Feb, Nov, Dez - if(m > 3 && m < 10) return 1; // DSL in Apr, May, Jun, Jul, Aug, Sep - int y = year (local_t); - int h = hour (local_t); - int hToday = (h + 24 * day(local_t)); - if((m == 3 && hToday >= (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 4) % 7))) - || (m == 10 && hToday < (1 + TIMEZONE + 24 * (31 - (5 * y /4 + 1) % 7))) ) - return 1; - else - return 0; -} diff --git a/tools/esp8266/main.h b/tools/esp8266/main.h deleted file mode 100644 index 044984d3..00000000 --- a/tools/esp8266/main.h +++ /dev/null @@ -1,183 +0,0 @@ -//----------------------------------------------------------------------------- -// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778 -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ -//----------------------------------------------------------------------------- - -#ifndef __MAIN_H__ -#define __MAIN_H__ - -#include "dbg.h" -#include "Arduino.h" - -#include -#include -#include - -// NTP -#include -#include - -#include "eep.h" -#include "defines.h" -#include "crc.h" - - -const byte mDnsPort = 53; - -/* NTP TIMESERVER CONFIG */ -#define NTP_SERVER_NAME "pool.ntp.org" -#define NTP_LOCAL_PORT 8888 -#define NTP_PACKET_SIZE 48 -#define TIMEZONE 1 // Central European time +1 - - -typedef struct { - char version[12]; - char deviceName[DEVNAME_LEN]; - - // wifi - char stationSsid[SSID_LEN]; - char stationPwd[PWD_LEN]; - bool apActive; - - // nrf24 - uint16_t sendInterval; -} config_t; - - -#define SAVE_SSID 0x00000001 -#define SAVE_PWD 0x00000002 -#define SAVE_DEVICE_NAME 0x00000004 - -#define CHK_MSK(v, m) ((m & v) == m) - -class Main { - public: - Main(void); - virtual void setup(uint32_t timeout); - virtual void loop(); - void saveValues(uint32_t saveMask); - - String getDateTimeStr(time_t t) { - char str[20] = {0}; - if(0 == t) - sprintf(str, "n/a"); - else - sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t)); - return String(str); - } - - inline uint32_t getUptime(void) { - return mUptimeSecs; - } - - inline uint32_t getTimestamp(void) { - return mTimestamp; - } - - void eraseSettings(bool all = false) { - //DPRINTLN(DBG_VERBOSE, F("main.h:eraseSettings")); - uint8_t buf[64] = {0}; - uint16_t addr = (all) ? ADDR_START : ADDR_START_SETTINGS; - uint16_t end; - do { - end = addr + 64; - if(end > (ADDR_SETTINGS_CRC + 2)) - end = (ADDR_SETTINGS_CRC + 2); - DPRINTLN(DBG_DEBUG, F("erase: 0x") + String(addr, HEX) + " - 0x" + String(end, HEX)); - mEep->write(addr, buf, (end-addr)); - addr = end; - } while(addr < (ADDR_SETTINGS_CRC + 2)); - mEep->commit(); - } - - ESP8266WebServer *mWeb; - config_t config; - - - protected: - virtual void updateCrc(void); - - inline uint16_t buildEEpCrc(uint32_t start, uint32_t length) { - DPRINTLN(DBG_VERBOSE, F("main.h:buildEEpCrc")); - uint8_t buf[32]; - uint16_t crc = 0xffff; - uint8_t len; - - while(length > 0) { - len = (length < 32) ? length : 32; - mEep->read(start, buf, len); - crc = crc16(buf, len, crc); - start += len; - length -= len; - } - return crc; - } - - bool checkEEpCrc(uint32_t start, uint32_t length, uint32_t crcPos) { - DPRINTLN(DBG_VERBOSE, F("main.h:checkEEpCrc")); - DPRINTLN(DBG_DEBUG, F("start: ") + String(start) + F(", length: ") + String(length)); - uint16_t crcRd, crcCheck; - crcCheck = buildEEpCrc(start, length); - mEep->read(crcPos, &crcRd); - DPRINTLN(DBG_DEBUG, "CRC RD: " + String(crcRd, HEX) + " CRC CALC: " + String(crcCheck, HEX)); - return (crcCheck == crcRd); - } - - inline bool checkTicker(uint32_t *ticker, uint32_t interval) { - //DPRINTLN(DBG_VERBOSE, F("c")); - uint32_t mil = millis(); - if(mil >= *ticker) { - *ticker = mil + interval; - return true; - } - else if(mil < (*ticker - interval)) { - *ticker = mil + interval; - return true; - } - - return false; - } - - void stats(void) { - DPRINTLN(DBG_VERBOSE, F("main.h:stats")); - uint32_t free; - uint16_t max; - uint8_t frag; - ESP.getHeapStats(&free, &max, &frag); - DPRINT(DBG_VERBOSE, F("free: ") + String(free)); - DPRINT(DBG_VERBOSE, F(" - max: ") + String(max) + "%"); - DPRINTLN(DBG_VERBOSE, F(" - frag: ") + String(frag)); - } - - bool mWifiSettingsValid; - bool mSettingsValid; - bool mStActive; - - eep *mEep; - uint32_t mTimestamp; - uint32_t mLimit; - uint32_t mNextTryTs; - uint32_t mApLastTick; - - private: - bool getConfig(void); - void setupAp(const char *ssid, const char *pwd); - bool setupStation(uint32_t timeout); - - - time_t getNtpTime(void); - void sendNTPpacket(IPAddress& address); - time_t offsetDayLightSaving (uint32_t local_t); - - uint32_t mUptimeTicker; - uint16_t mUptimeInterval; - uint32_t mUptimeSecs; - uint8_t mHeapStatCnt; - - DNSServer *mDns; - - WiFiUDP *mUdp; // for time server -}; - -#endif /*__MAIN_H__*/ diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h new file mode 100644 index 00000000..4c77e07c --- /dev/null +++ b/tools/esp8266/web.h @@ -0,0 +1,218 @@ +//----------------------------------------------------------------------------- +// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778 +// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +//----------------------------------------------------------------------------- + +#ifndef __WEB_H__ +#define __WEB_H__ + +#include "dbg.h" +#include +#include + +#include "app.h" + +#include "html/h/index_html.h" +#include "html/h/style_css.h" +#include "favicon.h" +#include "html/h/setup_html.h" + + +class web { + public: + web(app *main) { + mMain = main; + mWeb = main->mWeb; + //mWeb = new ESP8266WebServer(80); + mUpdater = new ESP8266HTTPUpdateServer(); + mUpdater->setup(mWeb); + } + + void setup(void) { + mWeb->on("/", std::bind(&web::showIndex, this)); + mWeb->on("/style.css", std::bind(&web::showCss, this)); + mWeb->on("/favicon.ico", std::bind(&web::showFavicon, this)); + mWeb->onNotFound ( std::bind(&web::showNotFound, this)); + mWeb->on("/uptime", std::bind(&web::showUptime, this)); + mWeb->on("/reboot", std::bind(&web::showReboot, this)); + mWeb->on("/erase", std::bind(&web::showErase, this)); + mWeb->on("/factory", std::bind(&web::showFactoryRst, this)); + + mWeb->on("/setup", std::bind(&web::showSetup, this)); + mWeb->on("/save", std::bind(&web::showSave, this)); + } + + void showIndex(void) { + DPRINTLN(DBG_VERBOSE, F("showIndex")); + String html = FPSTR(index_html); + html.replace(F("{DEVICE}"), mMain->config.deviceName); + html.replace(F("{VERSION}"), mMain->config.version); + html.replace(F("{TS}"), String(mMain->config.sendInterval) + " "); + html.replace(F("{JS_TS}"), String(mMain->config.sendInterval * 1000)); + html.replace(F("{BUILD}"), String(AUTO_GIT_HASH)); + mWeb->send(200, "text/html", html); + } + + void showCss(void) { + mWeb->send(200, "text/css", FPSTR(style_css)); + } + + void showFavicon(void) { + static const char favicon_type[] PROGMEM = "image/x-icon"; + static const char favicon_content[] PROGMEM = FAVICON_PANEL_16; + mWeb->send_P(200, favicon_type, favicon_content, sizeof(favicon_content)); + } + + void showNotFound(void) { + DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + mWeb->uri()); + String msg = F("File Not Found\n\nURI: "); + msg += mWeb->uri(); + mWeb->send(404, F("text/plain"), msg); + } + + void showUptime(void) { + 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); + + mWeb->send(200, "text/plain", String(time) + mMain->getDateTimeStr(mMain->getTimestamp())); + } + + void showReboot(void) { + mWeb->send(200, F("text/html"), F("Rebooting ...rebooting ... auto reload after 10s")); + delay(1000); + ESP.restart(); + } + + void showErase() { + DPRINTLN(DBG_VERBOSE, F("showErase")); + mMain->eraseSettings(); + showReboot(); + } + + void showFactoryRst(void) { + DPRINTLN(DBG_VERBOSE, F("showFactoryRst")); + String content = ""; + int refresh = 3; + if(mWeb->args() > 0) { + if(mWeb->arg("reset").toInt() == 1) { + mMain->eraseSettings(true); + content = F("factory reset: success\n\nrebooting ... "); + refresh = 10; + } + else { + content = F("factory reset: aborted"); + refresh = 3; + } + } + else { + content = F("

Factory Reset

" + "

RESET

CANCEL

"); + refresh = 120; + } + mWeb->send(200, F("text/html"), F("Factory Reset") + content + F("")); + if(refresh == 10) { + delay(1000); + ESP.restart(); + } + } + + void showSetup(void) { + DPRINTLN(DBG_VERBOSE, F("showSetup")); + String html = FPSTR(setup_html); + html.replace(F("{SSID}"), mMain->config.stationSsid); + // PWD will be left at the default value (for protection) + // -> the PWD will only be changed if it does not match the default "{PWD}" + html.replace(F("{DEVICE}"), String(mMain->config.deviceName)); + html.replace(F("{VERSION}"), String(mMain->config.version)); + if(mMain->config.apActive) + html.replace("{IP}", String(F("http://192.168.1.1"))); + else + html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); + + mWeb->send(200, F("text/html"), html); + } + + void showSave(void) { + DPRINTLN(DBG_VERBOSE, F("showSave")); + + if(mWeb->args() > 0) { + uint32_t saveMask = 0; + char buf[20] = {0}; + + // general + if(mWeb->arg("ssid") != "") { + mWeb->arg("ssid").toCharArray(mMain->config.stationSsid, SSID_LEN); + saveMask |= SAVE_SSID; + } + if(mWeb->arg("pwd") != "{PWD}") { + mWeb->arg("pwd").toCharArray(mMain->config.stationPwd, PWD_LEN); + saveMask |= SAVE_PWD; + } + if(mWeb->arg("device") != "") { + mWeb->arg("device").toCharArray(mMain->config.deviceName, DEVNAME_LEN); + saveMask |= SAVE_DEVICE_NAME; + } + + // inverter + Inverter<> *iv; + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + iv = mMain->mSys->getInverterByPos(i, false); + // address + mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20); + if(strlen(buf) == 0) + memset(buf, 0, 20); + else + saveMask |= SAVE_INVERTERS; + iv->serial.u64 = mMain->Serial2u64(buf); + + // active power limit + uint16_t actPwrLimit = mWeb->arg("inv" + String(i) + "ActivePowerLimit").toInt(); + if (actPwrLimit != 0xffff && actPwrLimit > 0) + iv->powerLimit[0] = actPwrLimit; + + // name + mWeb->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH); + + // max channel power / name + for(uint8_t j = 0; j < 4; j++) { + iv->chMaxPwr[j] = mWeb->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff; + mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH); + } + } + if(mWeb->arg("invInterval") != "") { + mMain->config.sendInterval = mWeb->arg("invInterval").toInt(); + saveMask |= SAVE_INV_SEND_INTERVAL; + } + if(mWeb->arg("invRetry") != "") { + mMain->config.sendInterval = mWeb->arg("invRetry").toInt(); + saveMask |= SAVE_INV_RETRY; + } + + mMain->saveValues(saveMask); + + if(mWeb->arg("reboot") == "on") + showReboot(); + else + mWeb->send(200, F("text/html"), F("Setup saved" + "

saved

")); + } + } + + + + + private: + ESP8266WebServer *mWeb; + ESP8266HTTPUpdateServer *mUpdater; + app *mMain; + +}; + +#endif /*__WEB_H__*/ From f92a9509a1db217d5fa613d0840548580be6ac45 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 02:50:34 +0200 Subject: [PATCH 04/10] * Zwischenstand, compile ok --- tools/esp8266/app.cpp | 315 ++++++++++++++++++------------------------ tools/esp8266/app.h | 27 +++- tools/esp8266/web.h | 43 ++++++ 3 files changed, 203 insertions(+), 182 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 406fb509..e74152c2 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -31,6 +31,10 @@ app::app() { config.apActive = false; config.sendInterval = SEND_INTERVAL; + config.serialInterval = SERIAL_INTERVAL; + config.serialShowIv = true; + config.serialDebug = false; + mEep = new eep(); Serial.begin(115200); @@ -52,7 +56,6 @@ app::app() { mMqttTicker = 0xffff; mMqttInterval = MQTT_INTERVAL; mSerialTicker = 0xffff; - mSerialInterval = SERIAL_INTERVAL; mMqttActive = false; mTicker = 0; @@ -62,8 +65,6 @@ app::app() { mShowRebootRequest = false; - mSerialValues = true; - mSerialDebug = false; memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t))); mRxFailed = 0; @@ -81,6 +82,80 @@ app::~app(void) { } + +//----------------------------------------------------------------------------- +void app::Mainsetup(uint32_t timeout) { + DPRINTLN(DBG_VERBOSE, F("Main::setup")); + bool startAp = config.apActive; + mLimit = timeout; + + + startAp = getConfig(); + +#ifndef AP_ONLY + if(false == startAp) + startAp = setupStation(timeout); +#endif + + config.apActive = startAp; + mStActive = !startAp; +} + + +//----------------------------------------------------------------------------- +void app::MainLoop(void) { + //DPRINTLN(DBG_VERBOSE, F("M")); + if(config.apActive) { + mDns->processNextRequest(); +#ifndef AP_ONLY + if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { + config.apActive = setupStation(mLimit); + if(config.apActive) { + if(strlen(WIFI_AP_PWD) < 8) + DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); + mApLastTick = millis(); + mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); + setupAp(WIFI_AP_SSID, WIFI_AP_PWD); + } + } + else { + if(millis() - mApLastTick > 10000) { + uint8_t cnt = WiFi.softAPgetStationNum(); + if(cnt > 0) { + DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); + mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); + } + mApLastTick = millis(); + DPRINTLN(DBG_INFO, F("AP will be closed in ") + String((mNextTryTs - mApLastTick) / 1000) + F(" seconds")); + } + } +#endif + } + mWeb->handleClient(); + + if(checkTicker(&mUptimeTicker, mUptimeInterval)) { + mUptimeSecs++; + if(0 != mTimestamp) + mTimestamp++; + else { + if(!config.apActive) { + mTimestamp = getNtpTime(); + DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); + } + } + + /*if(++mHeapStatCnt >= 10) { + mHeapStatCnt = 0; + stats(); + }*/ + } + if (WiFi.status() != WL_CONNECTED) { + DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); + mStActive = false; + } +} + + //----------------------------------------------------------------------------- void app::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("app::setup")); @@ -148,14 +223,14 @@ void app::setup(uint32_t timeout) { // serial console uint8_t tmp; - mEep->read(ADDR_SER_INTERVAL, &mSerialInterval); - if(mSerialInterval < MIN_SERIAL_INTERVAL) - mSerialInterval = MIN_SERIAL_INTERVAL; + mEep->read(ADDR_SER_INTERVAL, &config.serialInterval); + if(config.serialInterval < MIN_SERIAL_INTERVAL) + config.serialInterval = MIN_SERIAL_INTERVAL; mEep->read(ADDR_SER_ENABLE, &tmp); - mSerialValues = (tmp == 0x01); + config.serialShowIv = (tmp == 0x01); mEep->read(ADDR_SER_DEBUG, &tmp); - mSerialDebug = (tmp == 0x01); - mSys->Radio.mSerialDebug = mSerialDebug; + config.serialDebug = (tmp == 0x01); + mSys->Radio.mSerialDebug = config.serialDebug; // ntp char ntpAddr[NTP_ADDR_LEN]; @@ -270,7 +345,7 @@ void app::loop(void) { if(mSys->Radio.checkPaketCrc(p->packet, &len, p->rxCh)) { // process buffer only on first occurrence - if(mSerialDebug) { + if(config.serialDebug) { DPRINT(DBG_INFO, "RX " + String(len) + "B Ch" + String(p->rxCh) + " | "); mSys->Radio.dumpBuf(NULL, p->packet, len); } @@ -408,8 +483,8 @@ void app::loop(void) { #endif } - if(mSerialValues) { - if(++mSerialTicker >= mSerialInterval) { + if(config.serialShowIv) { + if(++mSerialTicker >= config.serialInterval) { mSerialTicker = 0; char topic[30], val[10]; for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { @@ -436,11 +511,11 @@ void app::loop(void) { mSendTicker = 0; if(0 != mTimestamp) { - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_DEBUG, F("Free heap: 0x") + String(ESP.getFreeHeap(), HEX)); if(!mSys->BufCtrl.empty()) { - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_DEBUG, F("recbuf not empty! #") + String(mSys->BufCtrl.getFill())); } @@ -459,7 +534,7 @@ void app::loop(void) { if(!mPayload[iv->id].complete) { mRxFailed++; - if(mSerialDebug) { + if(config.serialDebug) { DPRINT(DBG_INFO, F("Inverter #") + String(iv->id) + " "); DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload[iv->id].retransmits) + ")"); } @@ -474,11 +549,11 @@ void app::loop(void) { mPayload[iv->id].ts = mTimestamp; yield(); - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()) ); DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX)); if(iv->devControlRequest && iv->powerLimit[0] > 0){ // prevent to "switch off" - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0])); mSys->Radio.sendControlPacket(iv->radioId.u64,iv->devControlCmd ,iv->powerLimit); } else { @@ -487,7 +562,7 @@ void app::loop(void) { } } } - else if(mSerialDebug) + else if(config.serialDebug) DPRINTLN(DBG_WARN, F("time not set, can't request inverter!")); yield(); } @@ -547,7 +622,7 @@ void app::processPayload(bool retransmit) { if(mPayload[iv->id].maxPackId != 0) { for(uint8_t i = 0; i < (mPayload[iv->id].maxPackId-1); i ++) { if(mPayload[iv->id].len[i] == 0) { - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_ERROR, F("while retrieving data: Frame ") + String(i+1) + F(" missing: Request Retransmit")); mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME+i), true); break; // only retransmit one frame per loop @@ -556,7 +631,7 @@ void app::processPayload(bool retransmit) { } } else { - if(mSerialDebug) + if(config.serialDebug) DPRINTLN(DBG_ERROR, F("while retrieving data: last frame missing: Request Retransmit")); if(0x00 != mLastPacketId) mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, mLastPacketId, true); @@ -579,7 +654,7 @@ void app::processPayload(bool retransmit) { yield(); } offs-=2; - if(mSerialDebug) { + if(config.serialDebug) { DPRINT(DBG_INFO, F("Payload (") + String(offs) + "): "); mSys->Radio.dumpBuf(NULL, payload, offs); } @@ -1012,88 +1087,6 @@ void app::showJSON(void) { } -//----------------------------------------------------------------------------- -/*void app::saveValues(bool webSend = true) { - DPRINTLN(DBG_VERBOSE, F("app::saveValues")); - Main::saveValues(false); // general configuration - - if(mWeb->args() > 0) { - char buf[20] = {0}; - uint8_t i = 0; - uint16_t interval; - - - - // pinout - for(uint8_t i = 0; i < 3; i ++) { - uint8_t pin = mWeb->arg(String(pinArgNames[i])).toInt(); - mEep->write(ADDR_PINOUT + i, pin); - } - - - // nrf24 amplifier power - mSys->Radio.AmplifierPower = mWeb->arg("rf24Power").toInt() & 0x03; - mEep->write(ADDR_RF24_AMP_PWR, mSys->Radio.AmplifierPower); - - // ntp - char ntpAddr[NTP_ADDR_LEN] = {0}; - uint16_t ntpPort; - mWeb->arg("ntpAddr").toCharArray(ntpAddr, NTP_ADDR_LEN); - ntpPort = mWeb->arg("ntpPort").toInt(); - mEep->write(ADDR_NTP_ADDR, ntpAddr, NTP_ADDR_LEN); - mEep->write(ADDR_NTP_PORT, ntpPort); - - // mqtt - char mqttAddr[MQTT_ADDR_LEN] = {0}; - uint16_t mqttPort; - char mqttUser[MQTT_USER_LEN]; - char mqttPwd[MQTT_PWD_LEN]; - char mqttTopic[MQTT_TOPIC_LEN]; - mWeb->arg("mqttAddr").toCharArray(mqttAddr, MQTT_ADDR_LEN); - mWeb->arg("mqttUser").toCharArray(mqttUser, MQTT_USER_LEN); - mWeb->arg("mqttPwd").toCharArray(mqttPwd, MQTT_PWD_LEN); - mWeb->arg("mqttTopic").toCharArray(mqttTopic, MQTT_TOPIC_LEN); - //interval = mWeb->arg("mqttIntvl").toInt(); - mqttPort = mWeb->arg("mqttPort").toInt(); - mEep->write(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN); - mEep->write(ADDR_MQTT_PORT, mqttPort); - mEep->write(ADDR_MQTT_USER, mqttUser, MQTT_USER_LEN); - mEep->write(ADDR_MQTT_PWD, mqttPwd, MQTT_PWD_LEN); - mEep->write(ADDR_MQTT_TOPIC, mqttTopic, MQTT_TOPIC_LEN); - //mEep->write(ADDR_MQTT_INTERVAL, interval); - - - // serial console - bool tmp; - interval = mWeb->arg("serIntvl").toInt(); - mEep->write(ADDR_SER_INTERVAL, interval); - tmp = (mWeb->arg("serEn") == "on"); - mEep->write(ADDR_SER_ENABLE, (uint8_t)((tmp) ? 0x01 : 0x00)); - mSerialDebug = (mWeb->arg("serDbg") == "on"); - mEep->write(ADDR_SER_DEBUG, (uint8_t)((mSerialDebug) ? 0x01 : 0x00)); - DPRINT(DBG_INFO, "Serial debug is "); - if(mSerialDebug) DPRINTLN(DBG_INFO, "on"); else DPRINTLN(DBG_INFO, "off"); - mSys->Radio.mSerialDebug = mSerialDebug; - - updateCrc(); - mEep->commit(); - if((mWeb->arg("reboot") == "on")) - showReboot(); - else { - mShowRebootRequest = true; - mWeb->send(200, F("text/html"), F("Setup saved" - "

saved

")); - } - } - else { - updateCrc(); - mEep->commit(); - mWeb->send(200, F("text/html"), F("Error" - "

Error while saving

")); - } -}*/ - - void app::sendMqttDiscoveryConfig(void) { DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); @@ -1167,80 +1160,6 @@ const char* app::getFieldStateClass(uint8_t fieldId) { } - -//----------------------------------------------------------------------------- -void app::Mainsetup(uint32_t timeout) { - DPRINTLN(DBG_VERBOSE, F("Main::setup")); - bool startAp = config.apActive; - mLimit = timeout; - - - startAp = getConfig(); - -#ifndef AP_ONLY - if(false == startAp) - startAp = setupStation(timeout); -#endif - - config.apActive = startAp; - mStActive = !startAp; -} - - -//----------------------------------------------------------------------------- -void app::MainLoop(void) { - //DPRINTLN(DBG_VERBOSE, F("M")); - if(config.apActive) { - mDns->processNextRequest(); -#ifndef AP_ONLY - if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { - config.apActive = setupStation(mLimit); - if(config.apActive) { - if(strlen(WIFI_AP_PWD) < 8) - DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); - mApLastTick = millis(); - mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); - setupAp(WIFI_AP_SSID, WIFI_AP_PWD); - } - } - else { - if(millis() - mApLastTick > 10000) { - uint8_t cnt = WiFi.softAPgetStationNum(); - if(cnt > 0) { - DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); - mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); - } - mApLastTick = millis(); - DPRINTLN(DBG_INFO, F("AP will be closed in ") + String((mNextTryTs - mApLastTick) / 1000) + F(" seconds")); - } - } -#endif - } - mWeb->handleClient(); - - if(checkTicker(&mUptimeTicker, mUptimeInterval)) { - mUptimeSecs++; - if(0 != mTimestamp) - mTimestamp++; - else { - if(!config.apActive) { - mTimestamp = getNtpTime(); - DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); - } - } - - /*if(++mHeapStatCnt >= 10) { - mHeapStatCnt = 0; - stats(); - }*/ - } - if (WiFi.status() != WL_CONNECTED) { - DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); - mStActive = false; - } -} - - //----------------------------------------------------------------------------- bool app::getConfig(void) { DPRINTLN(DBG_VERBOSE, F("app::getConfig")); @@ -1354,8 +1273,8 @@ void app::saveValues(uint32_t saveMask = 0) { if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); - Inverter<> *iv; if(CHK_MSK(saveMask, SAVE_INVERTERS)) { + Inverter<> *iv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { iv = mSys->getInverterByPos(i); if(NULL != iv) { @@ -1375,7 +1294,45 @@ void app::saveValues(uint32_t saveMask = 0) { if(CHK_MSK(saveMask, SAVE_INV_RETRY)) mEep->write(ADDR_INV_MAX_RTRY, config.maxRetransPerPyld); - if(saveMask > 0) { + + if(CHK_MSK(saveMask, SAVE_PINOUT)) { + uint8_t pin; + for(uint8_t i = 0; i < 3; i ++) { + switch(i) { + default: pin = mSys->Radio.pinCs; break; + case 1: pin = mSys->Radio.pinCe; break; + case 2: pin = mSys->Radio.pinIrq; break; + } + mEep->write(ADDR_PINOUT + i, pin); + } + } + + if(CHK_MSK(saveMask, SAVE_RF24)) + mEep->write(ADDR_RF24_AMP_PWR, mSys->Radio.AmplifierPower); + + if(CHK_MSK(saveMask, SAVE_NTP)) { + mEep->write(ADDR_NTP_ADDR, config.ntpAddr, NTP_ADDR_LEN); + mEep->write(ADDR_NTP_PORT, config.ntpPort); + } + + if(CHK_MSK(saveMask, SAVE_MQTT)) { + mEep->write(ADDR_MQTT_ADDR, config.mqtt.broker, MQTT_ADDR_LEN); + mEep->write(ADDR_MQTT_PORT, config.mqtt.port); + mEep->write(ADDR_MQTT_USER, config.mqtt.user, MQTT_USER_LEN); + mEep->write(ADDR_MQTT_PWD, config.mqtt.pwd, MQTT_PWD_LEN); + mEep->write(ADDR_MQTT_TOPIC, config.mqtt.topic, MQTT_TOPIC_LEN); + } + + if(CHK_MSK(saveMask, SAVE_SERIAL)) { + DPRINT(DBG_INFO, "Serial debug is "); + if(config.serialDebug) DPRINTLN(DBG_INFO, "on"); else DPRINTLN(DBG_INFO, "off"); + mSys->Radio.mSerialDebug = config.serialDebug; + mEep->write(ADDR_SER_INTERVAL, config.serialInterval); + mEep->write(ADDR_SER_ENABLE, (uint8_t)((config.serialShowIv) ? 0x01 : 0x00)); + mEep->write(ADDR_SER_DEBUG, (uint8_t)((config.serialDebug) ? 0x01 : 0x00)); + } + + if(0 < saveMask) { updateCrc(); mEep->commit(); } diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 90d6dcd1..01ee00f8 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -68,6 +68,14 @@ const byte mDnsPort = 53; #define NTP_PACKET_SIZE 48 #define TIMEZONE 1 // Central European time +1 +typedef struct { + char broker[MQTT_ADDR_LEN]; + uint16_t port; + char user[MQTT_USER_LEN]; + char pwd[MQTT_PWD_LEN]; + char topic[MQTT_TOPIC_LEN]; + char devName[DEVNAME_LEN]; +} mqttConfig_t; typedef struct { char version[12]; @@ -82,6 +90,17 @@ typedef struct { uint16_t sendInterval; uint8_t maxRetransPerPyld; + // ntp + char ntpAddr[NTP_ADDR_LEN]; + uint16_t ntpPort; + + // mqtt + mqttConfig_t mqtt; + + // serial + uint16_t serialInterval; + bool serialShowIv; + bool serialDebug; } config_t; @@ -91,6 +110,11 @@ typedef struct { #define SAVE_INVERTERS 0x00000008 #define SAVE_INV_SEND_INTERVAL 0x00000010 #define SAVE_INV_RETRY 0x00000020 +#define SAVE_PINOUT 0x00000040 +#define SAVE_RF24 0x00000080 +#define SAVE_NTP 0x00000100 +#define SAVE_MQTT 0x00000200 +#define SAVE_SERIAL 0x00000400 #define CHK_MSK(v, m) ((m & v) == m) @@ -290,8 +314,6 @@ class app { // timer uint32_t mTicker; - bool mSerialValues; - bool mSerialDebug; uint32_t mRxTicker; @@ -304,7 +326,6 @@ class app { // serial uint16_t mSerialTicker; - uint16_t mSerialInterval; }; #endif /*__APP_H__*/ diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h index 4c77e07c..0b76ba85 100644 --- a/tools/esp8266/web.h +++ b/tools/esp8266/web.h @@ -195,6 +195,49 @@ class web { saveMask |= SAVE_INV_RETRY; } + // pinout + uint8_t pin; + for(uint8_t i = 0; i < 3; i ++) { + pin = mWeb->arg(String(pinArgNames[i])).toInt(); + switch(i) { + default: mMain->mSys->Radio.pinCs = pin; break; + case 1: mMain->mSys->Radio.pinCe = pin; break; + case 2: mMain->mSys->Radio.pinIrq = pin; break; + } + } + saveMask |= SAVE_PINOUT; + + // nrf24 amplifier power + mMain->mSys->Radio.AmplifierPower = mWeb->arg("rf24Power").toInt() & 0x03; + saveMask |= SAVE_RF24; + + // ntp + if(mWeb->arg("ntpAddr") != "") { + mWeb->arg("ntpAddr").toCharArray(mMain->config.ntpAddr, NTP_ADDR_LEN); + mMain->config.ntpPort = mWeb->arg("ntpPort").toInt() & 0xffff; + saveMask |= SAVE_NTP; + } + + // mqtt + if(mWeb->arg("mqttAddr") != "") { + mWeb->arg("mqttAddr").toCharArray(mMain->config.mqtt.broker, MQTT_ADDR_LEN); + mWeb->arg("mqttUser").toCharArray(mMain->config.mqtt.user, MQTT_USER_LEN); + mWeb->arg("mqttPwd").toCharArray(mMain->config.mqtt.pwd, MQTT_PWD_LEN); + mWeb->arg("mqttTopic").toCharArray(mMain->config.mqtt.topic, MQTT_TOPIC_LEN); + mMain->config.mqtt.port = mWeb->arg("mqttPort").toInt(); + saveMask |= SAVE_MQTT; + } + + // serial console + if(mWeb->arg("serIntvl") != "") { + mMain->config.serialInterval = mWeb->arg("serIntvl").toInt() & 0xffff; + + mMain->config.serialDebug = (mWeb->arg("serEn") == "on"); + mMain->config.serialShowIv = (mWeb->arg("serDbg") == "on"); + saveMask |= SAVE_SERIAL; + } + + mMain->saveValues(saveMask); if(mWeb->arg("reboot") == "on") From f1b19bccfe1471df41152405372c845c92d1f7d2 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 03:07:09 +0200 Subject: [PATCH 05/10] * improved mqtt settings --- tools/esp8266/app.cpp | 31 +++++++++------------- tools/esp8266/app.h | 34 ------------------------ tools/esp8266/defines.h | 38 ++++++++++++++++++++++++++ tools/esp8266/mqtt.h | 59 +++++++---------------------------------- 4 files changed, 59 insertions(+), 103 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index e74152c2..46f61b32 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -240,21 +240,14 @@ void app::setup(uint32_t timeout) { // TODO set ntpAddr & ntpPort in main // mqtt - uint16_t mqttPort; - char mqttAddr[MQTT_ADDR_LEN]; - char mqttUser[MQTT_USER_LEN]; - char mqttPwd[MQTT_PWD_LEN]; - char mqttTopic[MQTT_TOPIC_LEN]; - char mqttDevName[DEVNAME_LEN]; - mEep->read(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN); - mEep->read(ADDR_MQTT_USER, mqttUser, MQTT_USER_LEN); - mEep->read(ADDR_MQTT_PWD, mqttPwd, MQTT_PWD_LEN); - mEep->read(ADDR_MQTT_TOPIC, mqttTopic, MQTT_TOPIC_LEN); - mEep->read(ADDR_DEVNAME, mqttDevName, DEVNAME_LEN); + mEep->read(ADDR_MQTT_ADDR, config.mqtt.broker, MQTT_ADDR_LEN); + mEep->read(ADDR_MQTT_USER, config.mqtt.user, MQTT_USER_LEN); + mEep->read(ADDR_MQTT_PWD, config.mqtt.pwd, MQTT_PWD_LEN); + mEep->read(ADDR_MQTT_TOPIC, config.mqtt.topic, MQTT_TOPIC_LEN); + mEep->read(ADDR_MQTT_PORT, &config.mqtt.port); //mEep->read(ADDR_MQTT_INTERVAL, &mMqttInterval); - mEep->read(ADDR_MQTT_PORT, &mqttPort); - if(mqttAddr[0] > 0) { + if(config.mqtt.broker[0] > 0) { mMqttActive = true; if(mMqttInterval < MIN_MQTT_INTERVAL) mMqttInterval = MIN_MQTT_INTERVAL; @@ -262,10 +255,10 @@ void app::setup(uint32_t timeout) { else mMqttInterval = 0xffff; - if(0 == mqttPort) - mqttPort = 1883; + if(0 == config.mqtt.port) + config.mqtt.port = 1883; - mMqtt.setup(mqttAddr, mqttTopic, mqttUser, mqttPwd, mqttDevName, mqttPort); + mMqtt.setup(&config.mqtt, config.deviceName); mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mMqttTicker = 0; @@ -275,9 +268,9 @@ void app::setup(uint32_t timeout) { #endif mSerialTicker = 0; - if(mqttAddr[0] > 0) { + if(config.mqtt.broker[0] > 0) { char topic[30]; - mMqtt.sendMsg("device", mqttDevName); + mMqtt.sendMsg("device", config.deviceName); mMqtt.sendMsg("version", config.version); for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { iv = mSys->getInverterByPos(i); @@ -1109,7 +1102,7 @@ void app::sendMqttDiscoveryConfig(void) { } else { snprintf(name, 32, "%s CH%d %s", iv->name, iv->assign[i].ch, iv->getFieldName(i)); } - snprintf(stateTopic, 64, "%s/%s/ch%d/%s", mMqtt.getTopic(), iv->name, iv->assign[i].ch, iv->getFieldName(i)); + snprintf(stateTopic, 64, "%s/%s/ch%d/%s", config.mqtt.topic, iv->name, iv->assign[i].ch, iv->getFieldName(i)); snprintf(discoveryTopic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->name, iv->assign[i].ch, iv->getFieldName(i)); snprintf(uniq_id, 32, "ch%d_%s", iv->assign[i].ch, iv->getFieldName(i)); const char* devCls = getFieldDeviceClass(iv->assign[i].fieldId); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 01ee00f8..9f5b9cd7 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -68,40 +68,6 @@ const byte mDnsPort = 53; #define NTP_PACKET_SIZE 48 #define TIMEZONE 1 // Central European time +1 -typedef struct { - char broker[MQTT_ADDR_LEN]; - uint16_t port; - char user[MQTT_USER_LEN]; - char pwd[MQTT_PWD_LEN]; - char topic[MQTT_TOPIC_LEN]; - char devName[DEVNAME_LEN]; -} mqttConfig_t; - -typedef struct { - char version[12]; - char deviceName[DEVNAME_LEN]; - - // wifi - char stationSsid[SSID_LEN]; - char stationPwd[PWD_LEN]; - bool apActive; - - // nrf24 - uint16_t sendInterval; - uint8_t maxRetransPerPyld; - - // ntp - char ntpAddr[NTP_ADDR_LEN]; - uint16_t ntpPort; - - // mqtt - mqttConfig_t mqtt; - - // serial - uint16_t serialInterval; - bool serialShowIv; - bool serialDebug; -} config_t; #define SAVE_SSID 0x00000001 diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 0361d0b7..74f9f916 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -24,6 +24,7 @@ #define VERSION_PATCH 10 + //------------------------------------- typedef struct { uint8_t rxCh; @@ -157,4 +158,41 @@ typedef enum { #pragma error "Configure less inverters? (MAX_NUM_INVERTERS=" + MAX_NUM_INVERTERS +")" #endif + +//------------------------------------- +typedef struct { + char broker[MQTT_ADDR_LEN]; + uint16_t port; + char user[MQTT_USER_LEN]; + char pwd[MQTT_PWD_LEN]; + char topic[MQTT_TOPIC_LEN]; +} mqttConfig_t; + +typedef struct { + char version[12]; + char deviceName[DEVNAME_LEN]; + + // wifi + char stationSsid[SSID_LEN]; + char stationPwd[PWD_LEN]; + bool apActive; + + // nrf24 + uint16_t sendInterval; + uint8_t maxRetransPerPyld; + + // ntp + char ntpAddr[NTP_ADDR_LEN]; + uint16_t ntpPort; + + // mqtt + mqttConfig_t mqtt; + + // serial + uint16_t serialInterval; + bool serialShowIv; + bool serialDebug; +} config_t; + + #endif /*__DEFINES_H__*/ diff --git a/tools/esp8266/mqtt.h b/tools/esp8266/mqtt.h index eab0d043..789cec0c 100644 --- a/tools/esp8266/mqtt.h +++ b/tools/esp8266/mqtt.h @@ -16,27 +16,19 @@ class mqtt { mClient = new PubSubClient(mEspClient); mAddressSet = false; - memset(mBroker, 0, MQTT_ADDR_LEN); - memset(mUser, 0, MQTT_USER_LEN); - memset(mPwd, 0, MQTT_PWD_LEN); - memset(mTopic, 0, MQTT_TOPIC_LEN); memset(mDevName, 0, DEVNAME_LEN); } ~mqtt() { } - void setup(const char *broker, const char *topic, const char *user, const char *pwd, const char *devname, uint16_t port) { + void setup(mqttConfig_t *cfg, const char *devname) { DPRINTLN(DBG_VERBOSE, F("mqtt.h:setup")); mAddressSet = true; - mPort = port; - snprintf(mBroker, MQTT_ADDR_LEN, "%s", broker); - snprintf(mUser, MQTT_USER_LEN, "%s", user); - snprintf(mPwd, MQTT_PWD_LEN, "%s", pwd); - snprintf(mTopic, MQTT_TOPIC_LEN, "%s", topic); + mCfg = cfg; snprintf(mDevName, DEVNAME_LEN, "%s", devname); - mClient->setServer(mBroker, mPort); + mClient->setServer(mCfg->broker, mCfg->port); mClient->setBufferSize(MQTT_MAX_PACKET_SIZE); } @@ -47,7 +39,7 @@ class mqtt { void sendMsg(const char *topic, const char *msg) { //DPRINTLN(DBG_VERBOSE, F("mqtt.h:sendMsg")); char top[64]; - snprintf(top, 64, "%s/%s", mTopic, topic); + snprintf(top, 64, "%s/%s", mCfg->topic, topic); sendMsg2(top, msg, false); } @@ -67,35 +59,6 @@ class mqtt { return mClient->connected(); } - char *getBroker(void) { - //DPRINTLN(DBG_VERBOSE, F("mqtt.h:getBroker")); - return mBroker; - } - - char *getUser(void) { - //DPRINTLN(DBG_VERBOSE, F("mqtt.h:getUser")); - return mUser; - } - - char *getPwd(void) { - //DPRINTLN(DBG_VERBOSE, F("mqtt.h:getPwd")); - return mPwd; - } - - char *getTopic(void) { - //DPRINTLN(DBG_VERBOSE, F("mqtt.h:getTopic")); - return mTopic; - } - - char *getDevName(void) { - //DPRINTLN(DBG_VERBOSE, F("mqtt.h:getDevName")); - return mDevName; - } - - uint16_t getPort(void) { - return mPort; - } - void loop() { //DPRINT(F("m")); if(!mClient->connected()) @@ -112,17 +75,17 @@ class mqtt { if(strlen(mDevName) > 0) { // der Server und der Port müssen neu gesetzt werden, // da ein MQTT_CONNECTION_LOST -3 die Werte zerstört hat. - mClient->setServer(mBroker, mPort); + mClient->setServer(mCfg->broker, mCfg->port); mClient->setBufferSize(MQTT_MAX_PACKET_SIZE); - if((strlen(mUser) > 0) && (strlen(mPwd) > 0)) - mClient->connect(mDevName, mUser, mPwd); + if((strlen(mCfg->user) > 0) && (strlen(mCfg->pwd) > 0)) + mClient->connect(mDevName, mCfg->user, mCfg->pwd); else mClient->connect(mDevName); } // ein Subscribe ist nur nach einem connect notwendig char topic[MQTT_TOPIC_LEN + 13 ]; // "/devcontrol/#" --> + 6 byte // ToDo: "/devcontrol/#" is hardcoded - snprintf(topic, MQTT_TOPIC_LEN + 13, "%s/devcontrol/#", mTopic); + snprintf(topic, MQTT_TOPIC_LEN + 13, "%s/devcontrol/#", mCfg->topic); DPRINTLN(DBG_INFO, F("subscribe to ") + String(topic)); mClient->subscribe(topic); // subscribe to mTopic + "/devcontrol/#" } @@ -132,11 +95,7 @@ class mqtt { PubSubClient *mClient; bool mAddressSet; - uint16_t mPort; - char mBroker[MQTT_ADDR_LEN]; - char mUser[MQTT_USER_LEN]; - char mPwd[MQTT_PWD_LEN]; - char mTopic[MQTT_TOPIC_LEN]; + mqttConfig_t *mCfg; char mDevName[DEVNAME_LEN]; }; From 778f209eb5be9d3db52a71dc26cc114019703c15 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 23:16:33 +0200 Subject: [PATCH 06/10] * improved read / save to eep --- tools/esp8266/app.cpp | 373 +++++++++++------------- tools/esp8266/app.h | 13 +- tools/esp8266/config.h | 21 ++ tools/esp8266/defines.h | 54 +++- tools/esp8266/eep.h | 2 +- tools/esp8266/{esp8266.cpp => main.cpp} | 0 tools/esp8266/web.h | 18 +- 7 files changed, 245 insertions(+), 236 deletions(-) rename tools/esp8266/{esp8266.cpp => main.cpp} (100%) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 46f61b32..48651e45 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -15,28 +15,18 @@ app::app() { mDns = new DNSServer(); mWeb = new ESP8266WebServer(80); mUdp = new WiFiUDP(); + mEep = new eep(); - memset(&config, 0, sizeof(config_t)); + loadDefaultConfig(); - config.apActive = true; - mWifiSettingsValid = false; - mSettingsValid = false; + mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); + mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); - mLimit = 10; + mWifiStationTimeout = 10; mNextTryTs = 0; mApLastTick = 0; - // default config - snprintf(config.version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); - config.apActive = false; - config.sendInterval = SEND_INTERVAL; - config.serialInterval = SERIAL_INTERVAL; - config.serialShowIv = true; - config.serialDebug = false; - - - mEep = new eep(); Serial.begin(115200); DPRINTLN(DBG_VERBOSE, F("Main::Main")); @@ -82,35 +72,15 @@ app::~app(void) { } - -//----------------------------------------------------------------------------- -void app::Mainsetup(uint32_t timeout) { - DPRINTLN(DBG_VERBOSE, F("Main::setup")); - bool startAp = config.apActive; - mLimit = timeout; - - - startAp = getConfig(); - -#ifndef AP_ONLY - if(false == startAp) - startAp = setupStation(timeout); -#endif - - config.apActive = startAp; - mStActive = !startAp; -} - - //----------------------------------------------------------------------------- void app::MainLoop(void) { //DPRINTLN(DBG_VERBOSE, F("M")); - if(config.apActive) { + if(sysConfig.apActive) { mDns->processNextRequest(); #ifndef AP_ONLY if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { - config.apActive = setupStation(mLimit); - if(config.apActive) { + sysConfig.apActive = setupStation(mWifiStationTimeout); + if(sysConfig.apActive) { if(strlen(WIFI_AP_PWD) < 8) DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); mApLastTick = millis(); @@ -138,7 +108,7 @@ void app::MainLoop(void) { if(0 != mTimestamp) mTimestamp++; else { - if(!config.apActive) { + if(!sysConfig.apActive) { mTimestamp = getNtpTime(); DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); } @@ -151,7 +121,7 @@ void app::MainLoop(void) { } if (WiFi.status() != WL_CONNECTED) { DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); - mStActive = false; + setupStation(mWifiStationTimeout); } } @@ -159,7 +129,13 @@ void app::MainLoop(void) { //----------------------------------------------------------------------------- void app::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("app::setup")); - Mainsetup(timeout); + mWifiStationTimeout = timeout; + + +#ifndef AP_ONLY + if(false == sysConfig.apActive) + sysConfig.apActive = setupStation(mWifiStationTimeout); +#endif //mWeb->on("/setup", std::bind(&app::showSetup, this)); //mWeb->on("/save", std::bind(&app::showSave, this)); @@ -169,134 +145,8 @@ void app::setup(uint32_t timeout) { mWeb->on("/json", std::bind(&app::showJSON, this)); mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this)); - if(mSettingsValid) { - mEep->read(ADDR_INV_INTERVAL, &config.sendInterval); - if(config.sendInterval < MIN_SEND_INTERVAL) - config.sendInterval = MIN_SEND_INTERVAL; - mSendTicker = config.sendInterval; - - // inverter - uint64_t invSerial; - char name[MAX_NAME_LENGTH + 1] = {0}; - uint16_t modPwr[4]; - Inverter<> *iv; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial); - mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), name, MAX_NAME_LENGTH); - mEep->read(ADDR_INV_CH_PWR + (i * 2 * 4), modPwr, 4); - if(0ULL != invSerial) { - iv = mSys->addInverter(name, invSerial, modPwr); - if(NULL != iv) { - mEep->read(ADDR_INV_PWR_LIM + (i * 2),(uint16_t *)&(iv->powerLimit[0])); - if (iv->powerLimit[0] != 0xffff) { // only set it, if it is changed by user. Default value in the html setup page is -1 = 0xffff - iv->powerLimit[1] = 0x0001; // set the limit as persistent - iv->devControlCmd = ActivePowerContr; // set active power limit - iv->devControlRequest = true; // set to true to update the active power limit from setup html page - DPRINTLN(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX) + ", Power Limit: " + String(iv->powerLimit[0])); - } - for(uint8_t j = 0; j < 4; j++) { - mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH); - } - } - - - mMqttInterval += config.sendInterval; - } - } - - mEep->read(ADDR_INV_MAX_RTRY, &config.maxRetransPerPyld); - if(0 == config.maxRetransPerPyld) - config.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; - - // pinout - mEep->read(ADDR_PINOUT, &mSys->Radio.pinCs); - mEep->read(ADDR_PINOUT+1, &mSys->Radio.pinCe); - mEep->read(ADDR_PINOUT+2, &mSys->Radio.pinIrq); - if(mSys->Radio.pinCs == mSys->Radio.pinCe) { - mSys->Radio.pinCs = RF24_CS_PIN; - mSys->Radio.pinCe = RF24_CE_PIN; - mSys->Radio.pinIrq = RF24_IRQ_PIN; - } - - // nrf24 amplifier power - mEep->read(ADDR_RF24_AMP_PWR, &mSys->Radio.AmplifierPower); - - // serial console - uint8_t tmp; - mEep->read(ADDR_SER_INTERVAL, &config.serialInterval); - if(config.serialInterval < MIN_SERIAL_INTERVAL) - config.serialInterval = MIN_SERIAL_INTERVAL; - mEep->read(ADDR_SER_ENABLE, &tmp); - config.serialShowIv = (tmp == 0x01); - mEep->read(ADDR_SER_DEBUG, &tmp); - config.serialDebug = (tmp == 0x01); - mSys->Radio.mSerialDebug = config.serialDebug; - - // ntp - char ntpAddr[NTP_ADDR_LEN]; - uint16_t ntpPort; - mEep->read(ADDR_NTP_ADDR, ntpAddr, NTP_ADDR_LEN); - mEep->read(ADDR_NTP_PORT, &ntpPort); - // TODO set ntpAddr & ntpPort in main - - // mqtt - mEep->read(ADDR_MQTT_ADDR, config.mqtt.broker, MQTT_ADDR_LEN); - mEep->read(ADDR_MQTT_USER, config.mqtt.user, MQTT_USER_LEN); - mEep->read(ADDR_MQTT_PWD, config.mqtt.pwd, MQTT_PWD_LEN); - mEep->read(ADDR_MQTT_TOPIC, config.mqtt.topic, MQTT_TOPIC_LEN); - mEep->read(ADDR_MQTT_PORT, &config.mqtt.port); - //mEep->read(ADDR_MQTT_INTERVAL, &mMqttInterval); - - if(config.mqtt.broker[0] > 0) { - mMqttActive = true; - if(mMqttInterval < MIN_MQTT_INTERVAL) - mMqttInterval = MIN_MQTT_INTERVAL; - } - else - mMqttInterval = 0xffff; - - if(0 == config.mqtt.port) - config.mqtt.port = 1883; - - mMqtt.setup(&config.mqtt, config.deviceName); - mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - mMqttTicker = 0; - -#ifdef __MQTT_TEST__ - // für mqtt test - mMqttTicker = mMqttInterval -10; -#endif - mSerialTicker = 0; - - if(config.mqtt.broker[0] > 0) { - char topic[30]; - mMqtt.sendMsg("device", config.deviceName); - mMqtt.sendMsg("version", config.version); - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - iv = mSys->getInverterByPos(i); - if(NULL != iv) { - for(uint8_t i = 0; i < 4; i++) { - if(0 != iv->chName[i][0]) { - snprintf(topic, 30, "%s/ch%d/%s", iv->name, i+1, "name"); - mMqtt.sendMsg(topic, iv->chName[i]); - yield(); - } - } - } - } - } - } - else { - DPRINTLN(DBG_DEBUG, F("CRC pos: ") + String(ADDR_SETTINGS_CRC)); - DPRINTLN(DBG_DEBUG, F("NXT pos: ") + String(ADDR_NEXT)); - DPRINTLN(DBG_INFO, F("Settings not valid, erasing ...")); - eraseSettings(); - saveValues(false); - delay(100); - DPRINTLN(DBG_INFO, F("... restarting ...")); - delay(100); - ESP.restart(); - } + loadEEpconfig(); + setupMqtt(); mSys->setup(); @@ -306,7 +156,7 @@ void app::setup(uint32_t timeout) { DPRINTLN(DBG_INFO, F("\n\n----------------------------------------")); DPRINTLN(DBG_INFO, F("Welcome to AHOY!")); DPRINT(DBG_INFO, F("\npoint your browser to http://")); - if(config.apActive) + if(sysConfig.apActive) DBGPRINTLN(F("192.168.1.1")); else DBGPRINTLN(WiFi.localIP()); @@ -969,8 +819,8 @@ void app::webapi(void) { // ToDo void app::showHoymiles(void) { DPRINTLN(DBG_VERBOSE, F("app::showHoymiles")); String html = FPSTR(hoymiles_html); - html.replace(F("{DEVICE}"), config.deviceName); - html.replace(F("{VERSION}"), config.version); + html.replace(F("{DEVICE}"), sysConfig.deviceName); + html.replace(F("{VERSION}"), version); html.replace(F("{TS}"), String(config.sendInterval) + " "); html.replace(F("{JS_TS}"), String(config.sendInterval * 1000)); mWeb->send(200, F("text/html"), html); @@ -1153,30 +1003,6 @@ const char* app::getFieldStateClass(uint8_t fieldId) { } -//----------------------------------------------------------------------------- -bool app::getConfig(void) { - DPRINTLN(DBG_VERBOSE, F("app::getConfig")); - config.apActive = false; - - mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); - mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); - - if(mWifiSettingsValid) { - mEep->read(ADDR_SSID, config.stationSsid, SSID_LEN); - mEep->read(ADDR_PWD, config.stationPwd, PWD_LEN); - mEep->read(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); - } - - if((!mWifiSettingsValid) || (config.stationSsid[0] == 0xff)) { - snprintf(config.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); - snprintf(config.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); - snprintf(config.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); - } - - return config.apActive; -} - - //----------------------------------------------------------------------------- void app::setupAp(const char *ssid, const char *pwd) { DPRINTLN(DBG_VERBOSE, F("app::setupAp")); @@ -1218,12 +1044,12 @@ bool app::setupStation(uint32_t timeout) { } WiFi.mode(WIFI_STA); - WiFi.begin(config.stationSsid, config.stationPwd); - if(String(config.deviceName) != "") - WiFi.hostname(config.deviceName); + WiFi.begin(sysConfig.stationSsid, sysConfig.stationPwd); + if(String(sysConfig.deviceName) != "") + WiFi.hostname(sysConfig.deviceName); delay(2000); - DPRINTLN(DBG_INFO, F("connect to network '") + String(config.stationSsid) + F("' ...")); + DPRINTLN(DBG_INFO, F("connect to network '") + String(sysConfig.stationSsid) + F("' ...")); while (WiFi.status() != WL_CONNECTED) { delay(100); if(cnt % 100 == 0) @@ -1254,17 +1080,154 @@ bool app::setupStation(uint32_t timeout) { } +//----------------------------------------------------------------------------- +void app::loadDefaultConfig(void) { + memset(&sysConfig, 0, sizeof(sysConfig_t)); + memset(&config, 0, sizeof(config_t)); + snprintf(version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); + + snprintf(sysConfig.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + + // wifi + snprintf(sysConfig.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); + snprintf(sysConfig.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); + sysConfig.apActive = false; + + // nrf24 + config.sendInterval = SEND_INTERVAL; + config.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; + + // ntp + snprintf(config.ntpAddr, NTP_ADDR_LEN, "%s", NTP_SERVER_NAME); + config.ntpPort = NTP_LOCAL_PORT; + + // mqtt + snprintf(config.mqtt.broker, MQTT_ADDR_LEN, "%s", DEF_MQTT_BROKER); + config.mqtt.port = DEF_MQTT_PORT; + snprintf(config.mqtt.user, MQTT_USER_LEN, "%s", DEF_MQTT_USER); + snprintf(config.mqtt.pwd, MQTT_PWD_LEN, "%s", DEF_MQTT_PWD); + snprintf(config.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); + + // serial + config.serialInterval = SERIAL_INTERVAL; + config.serialShowIv = true; + config.serialDebug = false; +} + + +//----------------------------------------------------------------------------- +void app::loadEEpconfig(void) { + DPRINTLN(DBG_VERBOSE, F("app::loadEEpconfig")); + + if(mWifiSettingsValid) + mEep->read(ADDR_CFG_SYS, (uint8_t*) &sysConfig, CFG_SYS_LEN); + if(mSettingsValid) { + mEep->read(ADDR_CFG, (uint8_t*) &config, CFG_LEN); + + mSendTicker = config.sendInterval; + mSerialTicker = 0; + + // inverter + uint64_t invSerial; + char name[MAX_NAME_LENGTH + 1] = {0}; + uint16_t modPwr[4]; + Inverter<> *iv; + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial); + mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), name, MAX_NAME_LENGTH); + mEep->read(ADDR_INV_CH_PWR + (i * 2 * 4), modPwr, 4); + if(0ULL != invSerial) { + iv = mSys->addInverter(name, invSerial, modPwr); + if(NULL != iv) { + mEep->read(ADDR_INV_PWR_LIM + (i * 2),(uint16_t *)&(iv->powerLimit[0])); + if (iv->powerLimit[0] != 0xffff) { // only set it, if it is changed by user. Default value in the html setup page is -1 = 0xffff + iv->powerLimit[1] = 0x0001; // set the limit as persistent + iv->devControlCmd = ActivePowerContr; // set active power limit + iv->devControlRequest = true; // set to true to update the active power limit from setup html page + DPRINTLN(DBG_INFO, F("add inverter: ") + String(name) + ", SN: " + String(invSerial, HEX) + ", Power Limit: " + String(iv->powerLimit[0])); + } + for(uint8_t j = 0; j < 4; j++) { + mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH); + } + } + + + mMqttInterval += config.sendInterval; + } + } + } +} + + +//----------------------------------------------------------------------------- +void app::setupMqtt(void) { + if(mSettingsValid) { + if(config.mqtt.broker[0] > 0) { + mMqttActive = true; + if(mMqttInterval < MIN_MQTT_INTERVAL) + mMqttInterval = MIN_MQTT_INTERVAL; + } + else + mMqttInterval = 0xffff; + + mMqttTicker = 0; + mMqtt.setup(&config.mqtt, sysConfig.deviceName); + mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + + + if(mMqttActive) { + mMqtt.sendMsg("version", version); + if(mMqtt.isConnected()) + mMqtt.sendMsg("device", sysConfig.deviceName); + + /*char topic[30]; + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + iv = mSys->getInverterByPos(i); + if(NULL != iv) { + for(uint8_t i = 0; i < 4; i++) { + if(0 != iv->chName[i][0]) { + snprintf(topic, 30, "%s/ch%d/%s", iv->name, i+1, "name"); + mMqtt.sendMsg(topic, iv->chName[i]); + yield(); + } + } + } + }*/ + } + } +} + //----------------------------------------------------------------------------- void app::saveValues(uint32_t saveMask = 0) { DPRINTLN(DBG_VERBOSE, F("app::saveValues")); - if(CHK_MSK(saveMask, SAVE_SSID)) - mEep->write(ADDR_SSID, config.stationSsid, SSID_LEN); + mEep->write(ADDR_CFG_SYS, (uint8_t*)&sysConfig, CFG_SYS_LEN); + mEep->write(ADDR_CFG, (uint8_t*)&config, CFG_LEN); + Inverter<> *iv; + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + iv = mSys->getInverterByPos(i); + if(NULL != iv) { + mEep->write(ADDR_INV_ADDR + (i * 8), iv->serial.u64); + mEep->write(ADDR_INV_PWR_LIM + i * 2, iv->powerLimit[0]); + mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), iv->name, MAX_NAME_LENGTH); + // max channel power / name + for(uint8_t j = 0; j < 4; j++) { + mEep->write(ADDR_INV_CH_PWR + (i * 2 * 4) + (j*2), iv->chMaxPwr[j]); + mEep->write(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH); + } + } + } + + updateCrc(); + mEep->commit(); + + /*if(CHK_MSK(saveMask, SAVE_SSID)) + mEep->write(ADDR_SSID, sysConfig.stationSsid, SSID_LEN); if(CHK_MSK(saveMask, SAVE_PWD)) - mEep->write(ADDR_PWD, config.stationPwd, SSID_LEN); + mEep->write(ADDR_PWD, sysConfig.stationPwd, SSID_LEN); if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) - mEep->write(ADDR_DEVNAME, config.deviceName, DEVNAME_LEN); + mEep->write(ADDR_DEVNAME, sysConfig.deviceName, DEVNAME_LEN); if(CHK_MSK(saveMask, SAVE_INVERTERS)) { Inverter<> *iv; @@ -1328,7 +1291,7 @@ void app::saveValues(uint32_t saveMask = 0) { if(0 < saveMask) { updateCrc(); mEep->commit(); - } + }*/ } diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 9f5b9cd7..e794239a 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -63,13 +63,10 @@ typedef struct { const byte mDnsPort = 53; /* NTP TIMESERVER CONFIG */ -#define NTP_SERVER_NAME "pool.ntp.org" -#define NTP_LOCAL_PORT 8888 #define NTP_PACKET_SIZE 48 #define TIMEZONE 1 // Central European time +1 - #define SAVE_SSID 0x00000001 #define SAVE_PWD 0x00000002 #define SAVE_DEVICE_NAME 0x00000004 @@ -150,15 +147,18 @@ class app { } ESP8266WebServer *mWeb; + sysConfig_t sysConfig; config_t config; + char version[12]; private: void MainLoop(void); - void Mainsetup(uint32_t timeout); - bool getConfig(void); void setupAp(const char *ssid, const char *pwd); bool setupStation(uint32_t timeout); + void loadDefaultConfig(void); + void loadEEpconfig(void); + void setupMqtt(void); time_t getNtpTime(void); void sendNTPpacket(IPAddress& address); @@ -243,11 +243,10 @@ class app { bool mWifiSettingsValid; bool mSettingsValid; - bool mStActive; eep *mEep; uint32_t mTimestamp; - uint32_t mLimit; + uint32_t mWifiStationTimeout; uint32_t mNextTryTs; uint32_t mApLastTick; diff --git a/tools/esp8266/config.h b/tools/esp8266/config.h index 9851caef..0a28423e 100644 --- a/tools/esp8266/config.h +++ b/tools/esp8266/config.h @@ -67,4 +67,25 @@ // changes the style of "/setup" page, visualized = nicer #define LIVEDATA_VISUALIZED +// default ntp server uri +#define NTP_SERVER_NAME "pool.ntp.org" + +// default ntp server port +#define NTP_LOCAL_PORT 8888 + +// default MQTT broker uri +#define DEF_MQTT_BROKER "\0" + +// default MQTT port +#define DEF_MQTT_PORT 1883 + +// default MQTT user +#define DEF_MQTT_USER "\0" + +// default MQTT pwd +#define DEF_MQTT_PWD "\0" + +// default MQTT topic +#define DEF_MQTT_TOPIC "inverter" + #endif /*__CONFIG_H__*/ diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 74f9f916..6379fda8 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -111,7 +111,7 @@ typedef enum { #define SER_DEBUG_LEN 1 // uint8_t #define SER_INTERVAL_LEN 2 // uint16_t - +/* #define ADDR_START 0 #define ADDR_SSID ADDR_START #define ADDR_PWD ADDR_SSID + SSID_LEN @@ -145,18 +145,7 @@ typedef enum { #define ADDR_SER_DEBUG ADDR_SER_ENABLE + SER_ENABLE_LEN #define ADDR_SER_INTERVAL ADDR_SER_DEBUG + SER_DEBUG_LEN #define ADDR_NEXT ADDR_SER_INTERVAL + SER_INTERVAL_LEN - -// #define ADDR_SETTINGS_CRC 950 -#define ADDR_SETTINGS_CRC ADDR_NEXT + 2 - -#if(ADDR_SETTINGS_CRC <= ADDR_NEXT) -#pragma error "address overlap! (ADDR_SETTINGS_CRC="+ ADDR_SETTINGS_CRC +", ADDR_NEXT="+ ADDR_NEXT +")" -#endif - -#if(ADDR_SETTINGS_CRC >= 4096 - CRC_LEN) -#pragma error "EEPROM size exceeded! (ADDR_SETTINGS_CRC="+ ADDR_SETTINGS_CRC +", CRC_LEN="+ CRC_LEN +")" -#pragma error "Configure less inverters? (MAX_NUM_INVERTERS=" + MAX_NUM_INVERTERS +")" -#endif +*/ //------------------------------------- @@ -169,14 +158,15 @@ typedef struct { } mqttConfig_t; typedef struct { - char version[12]; char deviceName[DEVNAME_LEN]; // wifi char stationSsid[SSID_LEN]; char stationPwd[PWD_LEN]; bool apActive; +} sysConfig_t; +typedef struct { // nrf24 uint16_t sendInterval; uint8_t maxRetransPerPyld; @@ -194,5 +184,41 @@ typedef struct { bool serialDebug; } config_t; +// eeprom new +#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 +#define CFG_LEN 2 + 1 + NTP_ADDR_LEN + 2 + CFG_MQTT_LEN + 2 + 1 + 1 + +#define ADDR_START 0 +#define ADDR_CFG_SYS ADDR_START +#define ADDR_WIFI_CRC ADDR_CFG_SYS + CFG_SYS_LEN +#define ADDR_START_SETTINGS ADDR_WIFI_CRC + CRC_LEN + +#define ADDR_CFG ADDR_START_SETTINGS +#define ADDR_CFG_INVERTER ADDR_CFG + CFG_LEN + +#define ADDR_INV_ADDR ADDR_CFG_INVERTER +#define ADDR_INV_NAME ADDR_INV_ADDR + INV_ADDR_LEN +#define ADDR_INV_CH_PWR ADDR_INV_NAME + INV_NAME_LEN +#define ADDR_INV_CH_NAME ADDR_INV_CH_PWR + INV_CH_CH_PWR_LEN +#define ADDR_INV_INTERVAL ADDR_INV_CH_NAME + INV_CH_CH_NAME_LEN +#define ADDR_INV_MAX_RTRY ADDR_INV_INTERVAL + INV_INTERVAL_LEN +#define ADDR_INV_PWR_LIM ADDR_INV_MAX_RTRY + INV_MAX_RTRY_LEN + +#define ADDR_NEXT ADDR_INV_PWR_LIM + INV_PWR_LIM_LEN + + +#define ADDR_SETTINGS_CRC ADDR_NEXT + 2 + +#if(ADDR_SETTINGS_CRC <= ADDR_NEXT) +#pragma error "address overlap! (ADDR_SETTINGS_CRC="+ ADDR_SETTINGS_CRC +", ADDR_NEXT="+ ADDR_NEXT +")" +#endif + +#if(ADDR_SETTINGS_CRC >= 4096 - CRC_LEN) +#pragma error "EEPROM size exceeded! (ADDR_SETTINGS_CRC="+ ADDR_SETTINGS_CRC +", CRC_LEN="+ CRC_LEN +")" +#pragma error "Configure less inverters? (MAX_NUM_INVERTERS=" + MAX_NUM_INVERTERS +")" +#endif + + #endif /*__DEFINES_H__*/ diff --git a/tools/esp8266/eep.h b/tools/esp8266/eep.h index 52907d5b..b66d2cf7 100644 --- a/tools/esp8266/eep.h +++ b/tools/esp8266/eep.h @@ -130,7 +130,7 @@ class eep { EEPROM.write(addr++, (value ) & 0xff); } - void write(uint64_t addr, uint64_t value) { + void write(uint32_t addr, uint64_t value) { EEPROM.write(addr++, (value >> 56) & 0xff); EEPROM.write(addr++, (value >> 48) & 0xff); EEPROM.write(addr++, (value >> 40) & 0xff); diff --git a/tools/esp8266/esp8266.cpp b/tools/esp8266/main.cpp similarity index 100% rename from tools/esp8266/esp8266.cpp rename to tools/esp8266/main.cpp diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h index 0b76ba85..7ce5d74c 100644 --- a/tools/esp8266/web.h +++ b/tools/esp8266/web.h @@ -45,8 +45,8 @@ class web { void showIndex(void) { DPRINTLN(DBG_VERBOSE, F("showIndex")); String html = FPSTR(index_html); - html.replace(F("{DEVICE}"), mMain->config.deviceName); - html.replace(F("{VERSION}"), mMain->config.version); + html.replace(F("{DEVICE}"), mMain->sysConfig.deviceName); + html.replace(F("{VERSION}"), mMain->version); html.replace(F("{TS}"), String(mMain->config.sendInterval) + " "); html.replace(F("{JS_TS}"), String(mMain->config.sendInterval * 1000)); html.replace(F("{BUILD}"), String(AUTO_GIT_HASH)); @@ -126,12 +126,12 @@ class web { void showSetup(void) { DPRINTLN(DBG_VERBOSE, F("showSetup")); String html = FPSTR(setup_html); - html.replace(F("{SSID}"), mMain->config.stationSsid); + html.replace(F("{SSID}"), mMain->sysConfig.stationSsid); // PWD will be left at the default value (for protection) // -> the PWD will only be changed if it does not match the default "{PWD}" - html.replace(F("{DEVICE}"), String(mMain->config.deviceName)); - html.replace(F("{VERSION}"), String(mMain->config.version)); - if(mMain->config.apActive) + html.replace(F("{DEVICE}"), String(mMain->sysConfig.deviceName)); + html.replace(F("{VERSION}"), String(mMain->version)); + if(mMain->sysConfig.apActive) html.replace("{IP}", String(F("http://192.168.1.1"))); else html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); @@ -148,15 +148,15 @@ class web { // general if(mWeb->arg("ssid") != "") { - mWeb->arg("ssid").toCharArray(mMain->config.stationSsid, SSID_LEN); + mWeb->arg("ssid").toCharArray(mMain->sysConfig.stationSsid, SSID_LEN); saveMask |= SAVE_SSID; } if(mWeb->arg("pwd") != "{PWD}") { - mWeb->arg("pwd").toCharArray(mMain->config.stationPwd, PWD_LEN); + mWeb->arg("pwd").toCharArray(mMain->sysConfig.stationPwd, PWD_LEN); saveMask |= SAVE_PWD; } if(mWeb->arg("device") != "") { - mWeb->arg("device").toCharArray(mMain->config.deviceName, DEVNAME_LEN); + mWeb->arg("device").toCharArray(mMain->sysConfig.deviceName, DEVNAME_LEN); saveMask |= SAVE_DEVICE_NAME; } From 15402dbd99d9a0513e3c2fbdc903e283fdd463d4 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 13 Aug 2022 23:59:19 +0200 Subject: [PATCH 07/10] * merged showSetup (app + main) --- tools/esp8266/app.cpp | 385 +++++++++------------------------------ tools/esp8266/app.h | 25 +-- tools/esp8266/defines.h | 6 +- tools/esp8266/hmRadio.h | 24 +-- tools/esp8266/hmSystem.h | 4 +- tools/esp8266/web.h | 132 ++++++++++---- 6 files changed, 209 insertions(+), 367 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 48651e45..de054091 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -12,63 +12,66 @@ //----------------------------------------------------------------------------- app::app() { DPRINTLN(DBG_VERBOSE, F("app::app")); - mDns = new DNSServer(); - mWeb = new ESP8266WebServer(80); - mUdp = new WiFiUDP(); + mDns = new DNSServer(); + mWeb = new ESP8266WebServer(80); + mUdp = new WiFiUDP(); mEep = new eep(); - - loadDefaultConfig(); - - mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); - mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); - - mWifiStationTimeout = 10; - mNextTryTs = 0; - mApLastTick = 0; - - Serial.begin(115200); - DPRINTLN(DBG_VERBOSE, F("Main::Main")); - mUptimeSecs = 0; - mUptimeTicker = 0xffffffff; - mUptimeInterval = 1000; + resetSystem(); + loadDefaultConfig(); -#ifdef AP_ONLY - mTimestamp = 1; -#else - mTimestamp = 0; -#endif + mSys = new HmSystemType(); +} - mHeapStatCnt = 0; - mSendTicker = 0xffff; - mMqttTicker = 0xffff; - mMqttInterval = MQTT_INTERVAL; - mSerialTicker = 0xffff; - mMqttActive = false; +//----------------------------------------------------------------------------- +app::~app(void) { - mTicker = 0; - mRxTicker = 0; +} - mSendLastIvId = 0; - mShowRebootRequest = false; +//----------------------------------------------------------------------------- +void app::setup(uint32_t timeout) { + DPRINTLN(DBG_VERBOSE, F("app::setup")); + mWifiStationTimeout = timeout; + mWifiSettingsValid = checkEEpCrc(ADDR_START, ADDR_WIFI_CRC, ADDR_WIFI_CRC); + mSettingsValid = checkEEpCrc(ADDR_START_SETTINGS, ((ADDR_NEXT)-(ADDR_START_SETTINGS)), ADDR_SETTINGS_CRC); + loadEEpconfig(); - memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t))); - mRxFailed = 0; - mRxSuccess = 0; - mFrameCnt = 0; - mLastPacketId = 0x00; +#ifndef AP_ONLY + if(false == sysConfig.apActive) + sysConfig.apActive = setupStation(mWifiStationTimeout); +#endif - mSys = new HmSystemType(); -} + //mWeb->on("/setup", std::bind(&app::showSetup, this)); + //mWeb->on("/save", std::bind(&app::showSave, this)); + mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); + mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this)); + mWeb->on("/livedata", std::bind(&app::showLiveData, this)); + mWeb->on("/json", std::bind(&app::showJSON, this)); + mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this)); +#ifndef AP_ONLY + setupMqtt(); +#endif -//----------------------------------------------------------------------------- -app::~app(void) { + mSys->setup(&config); + if(!mWifiSettingsValid) + DPRINTLN(DBG_WARN, F("your settings are not valid! check [IP]/setup")); + else { + DPRINTLN(DBG_INFO, F("\n\n----------------------------------------")); + DPRINTLN(DBG_INFO, F("Welcome to AHOY!")); + DPRINT(DBG_INFO, F("\npoint your browser to http://")); + if(sysConfig.apActive) + DBGPRINTLN(F("192.168.1.1")); + else + DBGPRINTLN(WiFi.localIP()); + DPRINTLN(DBG_INFO, F("to configure your device")); + DPRINTLN(DBG_INFO, F("----------------------------------------\n")); + } } @@ -125,47 +128,6 @@ void app::MainLoop(void) { } } - -//----------------------------------------------------------------------------- -void app::setup(uint32_t timeout) { - DPRINTLN(DBG_VERBOSE, F("app::setup")); - mWifiStationTimeout = timeout; - - -#ifndef AP_ONLY - if(false == sysConfig.apActive) - sysConfig.apActive = setupStation(mWifiStationTimeout); -#endif - - //mWeb->on("/setup", std::bind(&app::showSetup, this)); - //mWeb->on("/save", std::bind(&app::showSave, this)); - mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); - mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this)); - mWeb->on("/livedata", std::bind(&app::showLiveData, this)); - mWeb->on("/json", std::bind(&app::showJSON, this)); - mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this)); - - loadEEpconfig(); - setupMqtt(); - - mSys->setup(); - - if(!mWifiSettingsValid) - DPRINTLN(DBG_WARN, F("your settings are not valid! check [IP]/setup")); - else { - DPRINTLN(DBG_INFO, F("\n\n----------------------------------------")); - DPRINTLN(DBG_INFO, F("Welcome to AHOY!")); - DPRINT(DBG_INFO, F("\npoint your browser to http://")); - if(sysConfig.apActive) - DBGPRINTLN(F("192.168.1.1")); - else - DBGPRINTLN(WiFi.localIP()); - DPRINTLN(DBG_INFO, F("to configure your device")); - DPRINTLN(DBG_INFO, F("----------------------------------------\n")); - } -} - - //----------------------------------------------------------------------------- void app::loop(void) { DPRINTLN(DBG_VERBOSE, F("app::loop")); @@ -532,148 +494,6 @@ void app::processPayload(bool retransmit) { } -//----------------------------------------------------------------------------- -/*void app::showSetup(void) { - DPRINTLN(DBG_VERBOSE, F("app::showSetup")); - // overrides same method in main.cpp - - String html = FPSTR(setup_html); - html.replace(F("{SSID}"), mStationSsid); - // PWD will be left at the default value (for protection) - // -> the PWD will only be changed if it does not match the placeholder "{PWD}" - - html.replace(F("{DEVICE}"), String(mDeviceName)); - html.replace(F("{VERSION}"), String(mVersion)); - if(mApActive) - html.replace(F("{IP}"), String(F("http://192.168.1.1"))); - else - html.replace(F("{IP}"), ("http://" + String(WiFi.localIP().toString()))); - - String inv; - uint64_t invSerial; - char name[MAX_NAME_LENGTH + 1] = {0}; - uint16_t modPwr[4]; - uint16_t invActivePowerLimit = -1; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - mEep->read(ADDR_INV_ADDR + (i * 8), &invSerial); - mEep->read(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), name, MAX_NAME_LENGTH); - mEep->read(ADDR_INV_CH_PWR + (i * 2 * 4), modPwr, 4); - mEep->read(ADDR_INV_PWR_LIM + (i * 2),(uint16_t *) &invActivePowerLimit); - inv += F("

Inverter ") + String(i) + "

"; - - inv += F(""); - inv += F(""); - - inv += F(""); - inv += F(""; - - inv += F(""); - inv += F(""; - - - inv += F(""); - for(uint8_t j = 0; j < 4; j++) { - inv += F(""); - } - inv += F("
"); - for(uint8_t j = 0; j < 4; j++) { - mEep->read(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, name, MAX_NAME_LENGTH); - inv += F(""; - } - } - html.replace(F("{INVERTERS}"), String(inv)); - - - // pinout - String pinout; - for(uint8_t i = 0; i < 3; i++) { - pinout += F(""); - pinout += F(""); - } - html.replace(F("{PINOUT}"), String(pinout)); - - - // nrf24l01+ - String rf24; - for(uint8_t i = 0; i <= 3; i++) { - rf24 += F(""); - } - html.replace(F("{RF24}"), String(rf24)); - - - if(mSettingsValid) { - html.replace(F("{INV_INTVL}"), String(mSendInterval)); - html.replace(F("{INV_RETRIES}"), String(maxRetransPerPyld)); - - uint8_t tmp; - mEep->read(ADDR_SER_ENABLE, &tmp); - html.replace(F("{SER_INTVL}"), String(mSerialInterval)); - html.replace(F("{SER_VAL_CB}"), (tmp == 0x01) ? "checked" : ""); - mEep->read(ADDR_SER_DEBUG, &tmp); - html.replace(F("{SER_DBG_CB}"), (tmp == 0x01) ? "checked" : ""); - - char ntpAddr[NTP_ADDR_LEN] = {0}; - uint16_t ntpPort; - mEep->read(ADDR_NTP_ADDR, ntpAddr, NTP_ADDR_LEN); - mEep->read(ADDR_NTP_PORT, &ntpPort); - html.replace(F("{NTP_ADDR}"), String(ntpAddr)); - html.replace(F("{NTP_PORT}"), String(ntpPort)); - - char mqttAddr[MQTT_ADDR_LEN] = {0}; - uint16_t mqttPort; - mEep->read(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN); - mEep->read(ADDR_MQTT_PORT, &mqttPort); - - html.replace(F("{MQTT_ADDR}"), String(mqttAddr)); - html.replace(F("{MQTT_PORT}"), String(mMqtt.getPort())); - html.replace(F("{MQTT_USER}"), String(mMqtt.getUser())); - html.replace(F("{MQTT_PWD}"), String(mMqtt.getPwd())); - html.replace(F("{MQTT_TOPIC}"), String(mMqtt.getTopic())); - html.replace(F("{MQTT_INTVL}"), String(mMqttInterval)); - } - - mWeb->send(200, F("text/html"), html); -} - - -//----------------------------------------------------------------------------- -void app::showSave(void) { - DPRINTLN(DBG_VERBOSE, F("app::showSave")); - //saveValues(true); -}*/ - - //----------------------------------------------------------------------------- void app::cbMqtt(char* topic, byte* payload, unsigned int length) { // callback handling on subscribed devcontrol topic @@ -1080,6 +900,46 @@ bool app::setupStation(uint32_t timeout) { } +//----------------------------------------------------------------------------- +void app::resetSystem(void) { + mWifiStationTimeout = 10; + mNextTryTs = 0; + mApLastTick = 0; + + mUptimeSecs = 0; + mUptimeTicker = 0xffffffff; + mUptimeInterval = 1000; + +#ifdef AP_ONLY + mTimestamp = 1; +#else + mTimestamp = 0; +#endif + + mHeapStatCnt = 0; + + mSendTicker = 0xffff; + mMqttTicker = 0xffff; + mMqttInterval = MQTT_INTERVAL; + mSerialTicker = 0xffff; + mMqttActive = false; + + mTicker = 0; + mRxTicker = 0; + + mSendLastIvId = 0; + + mShowRebootRequest = false; + + + memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t))); + mRxFailed = 0; + mRxSuccess = 0; + mFrameCnt = 0; + mLastPacketId = 0x00; +} + + //----------------------------------------------------------------------------- void app::loadDefaultConfig(void) { memset(&sysConfig, 0, sizeof(sysConfig_t)); @@ -1151,7 +1011,7 @@ void app::loadEEpconfig(void) { } } - + // TODO: the original mqttinterval value is not needed any more mMqttInterval += config.sendInterval; } } @@ -1199,7 +1059,7 @@ void app::setupMqtt(void) { //----------------------------------------------------------------------------- -void app::saveValues(uint32_t saveMask = 0) { +void app::saveValues(void) { DPRINTLN(DBG_VERBOSE, F("app::saveValues")); mEep->write(ADDR_CFG_SYS, (uint8_t*)&sysConfig, CFG_SYS_LEN); @@ -1221,77 +1081,6 @@ void app::saveValues(uint32_t saveMask = 0) { updateCrc(); mEep->commit(); - - /*if(CHK_MSK(saveMask, SAVE_SSID)) - mEep->write(ADDR_SSID, sysConfig.stationSsid, SSID_LEN); - if(CHK_MSK(saveMask, SAVE_PWD)) - mEep->write(ADDR_PWD, sysConfig.stationPwd, SSID_LEN); - if(CHK_MSK(saveMask, SAVE_DEVICE_NAME)) - mEep->write(ADDR_DEVNAME, sysConfig.deviceName, DEVNAME_LEN); - - if(CHK_MSK(saveMask, SAVE_INVERTERS)) { - Inverter<> *iv; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - iv = mSys->getInverterByPos(i); - if(NULL != iv) { - mEep->write(ADDR_INV_ADDR + (i * 8), iv->serial.u64); - mEep->write(ADDR_INV_PWR_LIM + i * 2, iv->powerLimit[0]); - mEep->write(ADDR_INV_NAME + (i * MAX_NAME_LENGTH), iv->name, MAX_NAME_LENGTH); - // max channel power / name - for(uint8_t j = 0; j < 4; j++) { - mEep->write(ADDR_INV_CH_PWR + (i * 2 * 4) + (j*2), iv->chMaxPwr[j]); - mEep->write(ADDR_INV_CH_NAME + (i * 4 * MAX_NAME_LENGTH) + j * MAX_NAME_LENGTH, iv->chName[j], MAX_NAME_LENGTH); - } - } - } - } - if(CHK_MSK(saveMask, SAVE_INV_SEND_INTERVAL)) - mEep->write(ADDR_INV_INTERVAL, config.sendInterval); - if(CHK_MSK(saveMask, SAVE_INV_RETRY)) - mEep->write(ADDR_INV_MAX_RTRY, config.maxRetransPerPyld); - - - if(CHK_MSK(saveMask, SAVE_PINOUT)) { - uint8_t pin; - for(uint8_t i = 0; i < 3; i ++) { - switch(i) { - default: pin = mSys->Radio.pinCs; break; - case 1: pin = mSys->Radio.pinCe; break; - case 2: pin = mSys->Radio.pinIrq; break; - } - mEep->write(ADDR_PINOUT + i, pin); - } - } - - if(CHK_MSK(saveMask, SAVE_RF24)) - mEep->write(ADDR_RF24_AMP_PWR, mSys->Radio.AmplifierPower); - - if(CHK_MSK(saveMask, SAVE_NTP)) { - mEep->write(ADDR_NTP_ADDR, config.ntpAddr, NTP_ADDR_LEN); - mEep->write(ADDR_NTP_PORT, config.ntpPort); - } - - if(CHK_MSK(saveMask, SAVE_MQTT)) { - mEep->write(ADDR_MQTT_ADDR, config.mqtt.broker, MQTT_ADDR_LEN); - mEep->write(ADDR_MQTT_PORT, config.mqtt.port); - mEep->write(ADDR_MQTT_USER, config.mqtt.user, MQTT_USER_LEN); - mEep->write(ADDR_MQTT_PWD, config.mqtt.pwd, MQTT_PWD_LEN); - mEep->write(ADDR_MQTT_TOPIC, config.mqtt.topic, MQTT_TOPIC_LEN); - } - - if(CHK_MSK(saveMask, SAVE_SERIAL)) { - DPRINT(DBG_INFO, "Serial debug is "); - if(config.serialDebug) DPRINTLN(DBG_INFO, "on"); else DPRINTLN(DBG_INFO, "off"); - mSys->Radio.mSerialDebug = config.serialDebug; - mEep->write(ADDR_SER_INTERVAL, config.serialInterval); - mEep->write(ADDR_SER_ENABLE, (uint8_t)((config.serialShowIv) ? 0x01 : 0x00)); - mEep->write(ADDR_SER_DEBUG, (uint8_t)((config.serialDebug) ? 0x01 : 0x00)); - } - - if(0 < saveMask) { - updateCrc(); - mEep->commit(); - }*/ } diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index e794239a..a5c5ac21 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -37,7 +37,7 @@ // #define __MQTT_NO_DISCOVERCONFIG__ // das versenden der MQTTDiscoveryConfig abschalten ( gehört eigentlich ins Setup ) typedef CircularBuffer BufferType; -typedef HmRadio RadioType; +typedef HmRadio RadioType; typedef Inverter InverterType; typedef HmSystem HmSystemType; @@ -67,20 +67,6 @@ const byte mDnsPort = 53; #define TIMEZONE 1 // Central European time +1 -#define SAVE_SSID 0x00000001 -#define SAVE_PWD 0x00000002 -#define SAVE_DEVICE_NAME 0x00000004 -#define SAVE_INVERTERS 0x00000008 -#define SAVE_INV_SEND_INTERVAL 0x00000010 -#define SAVE_INV_RETRY 0x00000020 -#define SAVE_PINOUT 0x00000040 -#define SAVE_RF24 0x00000080 -#define SAVE_NTP 0x00000100 -#define SAVE_MQTT 0x00000200 -#define SAVE_SERIAL 0x00000400 - -#define CHK_MSK(v, m) ((m & v) == m) - class app { public: app(); @@ -90,12 +76,11 @@ class app { void loop(void); void handleIntr(void); void cbMqtt(char* topic, byte* payload, unsigned int length); + void saveValues(void); - uint8_t app_loops; uint8_t getIrqPin(void) { - return mSys->Radio.pinIrq; + return config.pinIrq; } - HmSystemType *mSys; uint64_t Serial2u64(const char *val) { char tmp[3] = {0}; @@ -111,7 +96,6 @@ class app { } return ret; } - void saveValues(uint32_t saveMask); String getDateTimeStr(time_t t) { char str[20] = {0}; @@ -146,6 +130,8 @@ class app { mEep->commit(); } + uint8_t app_loops; + HmSystemType *mSys; ESP8266WebServer *mWeb; sysConfig_t sysConfig; config_t config; @@ -156,6 +142,7 @@ class app { void setupAp(const char *ssid, const char *pwd); bool setupStation(uint32_t timeout); + void resetSystem(void); void loadDefaultConfig(void); void loadEEpconfig(void); void setupMqtt(void); diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 6379fda8..585da08b 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -170,6 +170,10 @@ typedef struct { // nrf24 uint16_t sendInterval; uint8_t maxRetransPerPyld; + uint8_t pinCs; + uint8_t pinCe; + uint8_t pinIrq; + uint8_t amplifierPower; // ntp char ntpAddr[NTP_ADDR_LEN]; @@ -187,7 +191,7 @@ typedef struct { // eeprom new #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 -#define CFG_LEN 2 + 1 + NTP_ADDR_LEN + 2 + CFG_MQTT_LEN + 2 + 1 + 1 +#define CFG_LEN 7 + NTP_ADDR_LEN + 2 + CFG_MQTT_LEN + 4 #define ADDR_START 0 #define ADDR_CFG_SYS ADDR_START diff --git a/tools/esp8266/hmRadio.h b/tools/esp8266/hmRadio.h index a5c6f863..957ace68 100644 --- a/tools/esp8266/hmRadio.h +++ b/tools/esp8266/hmRadio.h @@ -27,7 +27,7 @@ #define ALL_FRAMES 0x80 #define SINGLE_FRAME 0x81 -const char* const rf24AmpPower[] = {"MIN", "LOW", "HIGH", "MAX"}; +const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"}; //----------------------------------------------------------------------------- @@ -55,7 +55,7 @@ const char* const rf24AmpPower[] = {"MIN", "LOW", "HIGH", "MAX"}; //----------------------------------------------------------------------------- // HM Radio class //----------------------------------------------------------------------------- -template +template class HmRadio { public: HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) { @@ -73,11 +73,6 @@ class HmRadio { mRxChIdx = 0; // Start RX with 03 mRxLoopCnt = RF_LOOP_CNT; - pinCs = CS_PIN; - pinCe = CE_PIN; - pinIrq = IRQ_PIN; - - AmplifierPower = 1; mSendCnt = 0; mSerialDebug = false; @@ -85,13 +80,13 @@ class HmRadio { } ~HmRadio() {} - void setup(BUFFER *ctrl) { + void setup(config_t *config, BUFFER *ctrl) { DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup")); - pinMode(pinIrq, INPUT_PULLUP); + pinMode(config->pinIrq, INPUT_PULLUP); mBufCtrl = ctrl; - mNrf24.begin(pinCe, pinCs); + mNrf24.begin(config->pinCe, config->pinCs); mNrf24.setRetries(0, 0); mNrf24.setChannel(DEFAULT_RECV_CHANNEL); @@ -106,8 +101,8 @@ class HmRadio { // enable only receiving interrupts mNrf24.maskIRQ(true, true, false); - DPRINTLN(DBG_INFO, F("RF24 Amp Pwr: RF24_PA_") + String(rf24AmpPower[AmplifierPower])); - mNrf24.setPALevel(AmplifierPower & 0x03); + DPRINTLN(DBG_INFO, F("RF24 Amp Pwr: RF24_PA_") + String(rf24AmpPowerNames[config->amplifierPower])); + mNrf24.setPALevel(config->amplifierPower & 0x03); mNrf24.startListening(); DPRINTLN(DBG_INFO, F("Radio Config:")); @@ -277,11 +272,8 @@ class HmRadio { return mNrf24.isChipConnected(); } - uint8_t pinCs; - uint8_t pinCe; - uint8_t pinIrq; - uint8_t AmplifierPower; + uint32_t mSendCnt; bool mSerialDebug; diff --git a/tools/esp8266/hmSystem.h b/tools/esp8266/hmSystem.h index 06307696..386484fa 100644 --- a/tools/esp8266/hmSystem.h +++ b/tools/esp8266/hmSystem.h @@ -30,9 +30,9 @@ class HmSystem { // TODO: cleanup } - void setup() { + void setup(config_t *config) { DPRINTLN(DBG_VERBOSE, F("hmSystem.h:setup")); - Radio.setup(&BufCtrl); + Radio.setup(config, &BufCtrl); } INVERTERTYPE *addInverter(const char *name, uint64_t serial, uint16_t chMaxPwr[]) { diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h index 7ce5d74c..11ea54b2 100644 --- a/tools/esp8266/web.h +++ b/tools/esp8266/web.h @@ -136,6 +136,97 @@ class web { else html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); + String inv = ""; + Inverter<> *iv; + for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { + iv = mMain->mSys->getInverterByPos(i); + + inv += F("

Inverter ") + String(i) + "

"; + inv += F(""); + inv += F("serial.u64, HEX); + inv += F("\"/ maxlength=\"12\" onkeyup=\"checkSerial()\">"); + + inv += F(""); + inv += F("name); + inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">"; + + inv += F(""); + inv += F("powerLimit[0]); + inv += F("\"/ maxlength=\"") + String(6) + "\">"; + + inv += F(""); + for(uint8_t j = 0; j < 4; j++) { + inv += F("chMaxPwr[j]); + inv += F("\"/ maxlength=\"4\">"); + } + inv += F("
"); + for(uint8_t j = 0; j < 4; j++) { + inv += F("chName[j]); + inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">"; + } + } + html.replace(F("{INVERTERS}"), String(inv)); + + + // pinout + String pinout; + for(uint8_t i = 0; i < 3; i++) { + pinout += F(""); + pinout += F(""); + } + html.replace(F("{PINOUT}"), String(pinout)); + + + // nrf24l01+ + String rf24; + for(uint8_t i = 0; i <= 3; i++) { + rf24 += F(""); + } + html.replace(F("{RF24}"), String(rf24)); + + + html.replace(F("{INV_INTVL}"), String(mMain->config.sendInterval)); + html.replace(F("{INV_RETRIES}"), String(mMain->config.maxRetransPerPyld)); + + html.replace(F("{SER_INTVL}"), String(mMain->config.serialInterval)); + html.replace(F("{SER_VAL_CB}"), (mMain->config.serialShowIv) ? "checked" : ""); + html.replace(F("{SER_DBG_CB}"), (mMain->config.serialDebug) ? "checked" : ""); + + html.replace(F("{NTP_ADDR}"), String(mMain->config.ntpAddr)); + html.replace(F("{NTP_PORT}"), String(mMain->config.ntpPort)); + + html.replace(F("{MQTT_ADDR}"), String(mMain->config.mqtt.broker)); + html.replace(F("{MQTT_PORT}"), String(mMain->config.mqtt.port)); + html.replace(F("{MQTT_USER}"), String(mMain->config.mqtt.user)); + html.replace(F("{MQTT_PWD}"), String(mMain->config.mqtt.pwd)); + html.replace(F("{MQTT_TOPIC}"), String(mMain->config.mqtt.topic)); + html.replace(F("{MQTT_INTVL}"), String("0")); + mWeb->send(200, F("text/html"), html); } @@ -143,22 +234,15 @@ class web { DPRINTLN(DBG_VERBOSE, F("showSave")); if(mWeb->args() > 0) { - uint32_t saveMask = 0; char buf[20] = {0}; // general - if(mWeb->arg("ssid") != "") { + if(mWeb->arg("ssid") != "") mWeb->arg("ssid").toCharArray(mMain->sysConfig.stationSsid, SSID_LEN); - saveMask |= SAVE_SSID; - } - if(mWeb->arg("pwd") != "{PWD}") { + if(mWeb->arg("pwd") != "{PWD}") mWeb->arg("pwd").toCharArray(mMain->sysConfig.stationPwd, PWD_LEN); - saveMask |= SAVE_PWD; - } - if(mWeb->arg("device") != "") { + if(mWeb->arg("device") != "") mWeb->arg("device").toCharArray(mMain->sysConfig.deviceName, DEVNAME_LEN); - saveMask |= SAVE_DEVICE_NAME; - } // inverter Inverter<> *iv; @@ -168,8 +252,6 @@ class web { mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20); if(strlen(buf) == 0) memset(buf, 0, 20); - else - saveMask |= SAVE_INVERTERS; iv->serial.u64 = mMain->Serial2u64(buf); // active power limit @@ -186,36 +268,29 @@ class web { mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH); } } - if(mWeb->arg("invInterval") != "") { + if(mWeb->arg("invInterval") != "") mMain->config.sendInterval = mWeb->arg("invInterval").toInt(); - saveMask |= SAVE_INV_SEND_INTERVAL; - } - if(mWeb->arg("invRetry") != "") { + if(mWeb->arg("invRetry") != "") mMain->config.sendInterval = mWeb->arg("invRetry").toInt(); - saveMask |= SAVE_INV_RETRY; - } // pinout uint8_t pin; for(uint8_t i = 0; i < 3; i ++) { pin = mWeb->arg(String(pinArgNames[i])).toInt(); switch(i) { - default: mMain->mSys->Radio.pinCs = pin; break; - case 1: mMain->mSys->Radio.pinCe = pin; break; - case 2: mMain->mSys->Radio.pinIrq = pin; break; + default: mMain->config.pinCs = pin; break; + case 1: mMain->config.pinCe = pin; break; + case 2: mMain->config.pinIrq = pin; break; } } - saveMask |= SAVE_PINOUT; // nrf24 amplifier power - mMain->mSys->Radio.AmplifierPower = mWeb->arg("rf24Power").toInt() & 0x03; - saveMask |= SAVE_RF24; + mMain->config.amplifierPower = mWeb->arg("rf24Power").toInt() & 0x03; // ntp if(mWeb->arg("ntpAddr") != "") { mWeb->arg("ntpAddr").toCharArray(mMain->config.ntpAddr, NTP_ADDR_LEN); mMain->config.ntpPort = mWeb->arg("ntpPort").toInt() & 0xffff; - saveMask |= SAVE_NTP; } // mqtt @@ -225,7 +300,6 @@ class web { mWeb->arg("mqttPwd").toCharArray(mMain->config.mqtt.pwd, MQTT_PWD_LEN); mWeb->arg("mqttTopic").toCharArray(mMain->config.mqtt.topic, MQTT_TOPIC_LEN); mMain->config.mqtt.port = mWeb->arg("mqttPort").toInt(); - saveMask |= SAVE_MQTT; } // serial console @@ -234,11 +308,9 @@ class web { mMain->config.serialDebug = (mWeb->arg("serEn") == "on"); mMain->config.serialShowIv = (mWeb->arg("serDbg") == "on"); - saveMask |= SAVE_SERIAL; } - - mMain->saveValues(saveMask); + mMain->saveValues(); if(mWeb->arg("reboot") == "on") showReboot(); @@ -249,8 +321,6 @@ class web { } - - private: ESP8266WebServer *mWeb; ESP8266HTTPUpdateServer *mUpdater; From 3c8a4c49a12973c98005d43709a212bf7e9c8ef9 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 14 Aug 2022 01:40:55 +0200 Subject: [PATCH 08/10] * first refactored version which is accessible through web interface --- tools/esp8266/app.cpp | 192 ++++++++++++----------- tools/esp8266/app.h | 13 +- tools/esp8266/defines.h | 1 - tools/esp8266/main.cpp | 3 - tools/esp8266/web.h | 327 +++------------------------------------- 5 files changed, 125 insertions(+), 411 deletions(-) diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index de054091..14fe2bd4 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -13,11 +13,14 @@ app::app() { DPRINTLN(DBG_VERBOSE, F("app::app")); mDns = new DNSServer(); - mWeb = new ESP8266WebServer(80); + //mWeb = new ESP8266WebServer(80); mUdp = new WiFiUDP(); mEep = new eep(); Serial.begin(115200); + mWebInst = new web(this, &mSysConfig, &mConfig, mVersion); + mWebInst->setup(); + resetSystem(); loadDefaultConfig(); @@ -41,31 +44,34 @@ void app::setup(uint32_t timeout) { loadEEpconfig(); #ifndef AP_ONLY - if(false == sysConfig.apActive) - sysConfig.apActive = setupStation(mWifiStationTimeout); + if(false == apActive) + apActive = setupStation(mWifiStationTimeout); #endif - //mWeb->on("/setup", std::bind(&app::showSetup, this)); - //mWeb->on("/save", std::bind(&app::showSave, this)); - mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); + /*mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this)); mWeb->on("/livedata", std::bind(&app::showLiveData, this)); mWeb->on("/json", std::bind(&app::showJSON, this)); - mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this)); + mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this));*/ #ifndef AP_ONLY setupMqtt(); #endif - mSys->setup(&config); + mSys->setup(&mConfig); - if(!mWifiSettingsValid) + if(!mWifiSettingsValid) { DPRINTLN(DBG_WARN, F("your settings are not valid! check [IP]/setup")); + apActive = true; + mApLastTick = millis(); + mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); + setupAp(WIFI_AP_SSID, WIFI_AP_PWD); + } else { DPRINTLN(DBG_INFO, F("\n\n----------------------------------------")); DPRINTLN(DBG_INFO, F("Welcome to AHOY!")); DPRINT(DBG_INFO, F("\npoint your browser to http://")); - if(sysConfig.apActive) + if(apActive) DBGPRINTLN(F("192.168.1.1")); else DBGPRINTLN(WiFi.localIP()); @@ -78,12 +84,12 @@ void app::setup(uint32_t timeout) { //----------------------------------------------------------------------------- void app::MainLoop(void) { //DPRINTLN(DBG_VERBOSE, F("M")); - if(sysConfig.apActive) { + if(apActive) { mDns->processNextRequest(); #ifndef AP_ONLY if(checkTicker(&mNextTryTs, (WIFI_AP_ACTIVE_TIME * 1000))) { - sysConfig.apActive = setupStation(mWifiStationTimeout); - if(sysConfig.apActive) { + apActive = setupStation(mWifiStationTimeout); + if(apActive) { if(strlen(WIFI_AP_PWD) < 8) DPRINTLN(DBG_ERROR, F("password must be at least 8 characters long")); mApLastTick = millis(); @@ -95,7 +101,7 @@ void app::MainLoop(void) { if(millis() - mApLastTick > 10000) { uint8_t cnt = WiFi.softAPgetStationNum(); if(cnt > 0) { - DPRINTLN(DBG_INFO, String(cnt) + F(" clients connected, resetting AP timeout")); + DPRINTLN(DBG_INFO, String(cnt) + F(" client connected, resetting AP timeout")); mNextTryTs = (millis() + (WIFI_AP_ACTIVE_TIME * 1000)); } mApLastTick = millis(); @@ -104,27 +110,25 @@ void app::MainLoop(void) { } #endif } - mWeb->handleClient(); + + mWebInst->loop(); if(checkTicker(&mUptimeTicker, mUptimeInterval)) { mUptimeSecs++; if(0 != mTimestamp) mTimestamp++; else { - if(!sysConfig.apActive) { + if(!apActive) { mTimestamp = getNtpTime(); DPRINTLN(DBG_INFO, "[NTP]: " + getDateTimeStr(mTimestamp)); } } - - /*if(++mHeapStatCnt >= 10) { - mHeapStatCnt = 0; - stats(); - }*/ } - if (WiFi.status() != WL_CONNECTED) { - DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); - setupStation(mWifiStationTimeout); + if((WiFi.status() != WL_CONNECTED) && wifiWasEstablished) { + if(!apActive) { + DPRINTLN(DBG_INFO, "[WiFi]: Connection Lost"); + setupStation(mWifiStationTimeout); + } } } @@ -140,7 +144,6 @@ void app::loop(void) { if(checkTicker(&mRxTicker, 5)) { //DPRINTLN(DBG_VERBOSE, F("app_loops =") + String(app_loops)); app_loops=0; - DPRINT(DBG_VERBOSE, F("a")); bool rxRdy = mSys->Radio.switchRxCh(); @@ -150,7 +153,7 @@ void app::loop(void) { if(mSys->Radio.checkPaketCrc(p->packet, &len, p->rxCh)) { // process buffer only on first occurrence - if(config.serialDebug) { + if(mConfig.serialDebug) { DPRINT(DBG_INFO, "RX " + String(len) + "B Ch" + String(p->rxCh) + " | "); mSys->Radio.dumpBuf(NULL, p->packet, len); } @@ -257,7 +260,7 @@ void app::loop(void) { mMqtt.loop(); if(checkTicker(&mTicker, 1000)) { - if((++mMqttTicker >= mMqttInterval) && (mMqttInterval != 0xffff)) { + if((++mMqttTicker >= mMqttInterval) && (mMqttInterval != 0xffff) && mMqttActive) { mMqttTicker = 0; mMqtt.isConnected(true); char topic[30], val[10]; @@ -275,11 +278,11 @@ void app::loop(void) { } } snprintf(val, 10, "%ld", millis()/1000); - + #ifndef __MQTT_NO_DISCOVERCONFIG__ // MQTTDiscoveryConfig nur wenn nicht abgeschaltet. sendMqttDiscoveryConfig(); -#endif +#endif mMqtt.sendMsg("uptime", val); #ifdef __MQTT_TEST__ @@ -288,8 +291,8 @@ void app::loop(void) { #endif } - if(config.serialShowIv) { - if(++mSerialTicker >= config.serialInterval) { + if(mConfig.serialShowIv) { + if(++mSerialTicker >= mConfig.serialInterval) { mSerialTicker = 0; char topic[30], val[10]; for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { @@ -312,15 +315,15 @@ void app::loop(void) { } } - if(++mSendTicker >= config.sendInterval) { + if(++mSendTicker >= mConfig.sendInterval) { mSendTicker = 0; if(0 != mTimestamp) { - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_DEBUG, F("Free heap: 0x") + String(ESP.getFreeHeap(), HEX)); if(!mSys->BufCtrl.empty()) { - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_DEBUG, F("recbuf not empty! #") + String(mSys->BufCtrl.getFill())); } @@ -339,7 +342,7 @@ void app::loop(void) { if(!mPayload[iv->id].complete) { mRxFailed++; - if(config.serialDebug) { + if(mConfig.serialDebug) { DPRINT(DBG_INFO, F("Inverter #") + String(iv->id) + " "); DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload[iv->id].retransmits) + ")"); } @@ -354,11 +357,11 @@ void app::loop(void) { mPayload[iv->id].ts = mTimestamp; yield(); - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()) ); DPRINTLN(DBG_INFO, F("Requesting Inverter SN ") + String(iv->serial.u64, HEX)); if(iv->devControlRequest && iv->powerLimit[0] > 0){ // prevent to "switch off" - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_INFO, F("Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0])); mSys->Radio.sendControlPacket(iv->radioId.u64,iv->devControlCmd ,iv->powerLimit); } else { @@ -367,7 +370,7 @@ void app::loop(void) { } } } - else if(config.serialDebug) + else if(mConfig.serialDebug) DPRINTLN(DBG_WARN, F("time not set, can't request inverter!")); yield(); } @@ -422,12 +425,12 @@ void app::processPayload(bool retransmit) { if(!buildPayload(iv->id)) { if(mPayload[iv->id].requested) { if(retransmit) { - if(mPayload[iv->id].retransmits < config.maxRetransPerPyld) { + if(mPayload[iv->id].retransmits < mConfig.maxRetransPerPyld) { mPayload[iv->id].retransmits++; if(mPayload[iv->id].maxPackId != 0) { for(uint8_t i = 0; i < (mPayload[iv->id].maxPackId-1); i ++) { if(mPayload[iv->id].len[i] == 0) { - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_ERROR, F("while retrieving data: Frame ") + String(i+1) + F(" missing: Request Retransmit")); mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME+i), true); break; // only retransmit one frame per loop @@ -436,7 +439,7 @@ void app::processPayload(bool retransmit) { } } else { - if(config.serialDebug) + if(mConfig.serialDebug) DPRINTLN(DBG_ERROR, F("while retrieving data: last frame missing: Request Retransmit")); if(0x00 != mLastPacketId) mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, mLastPacketId, true); @@ -459,7 +462,7 @@ void app::processPayload(bool retransmit) { yield(); } offs-=2; - if(config.serialDebug) { + if(mConfig.serialDebug) { DPRINT(DBG_INFO, F("Payload (") + String(offs) + "): "); mSys->Radio.dumpBuf(NULL, payload, offs); } @@ -568,7 +571,7 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { //----------------------------------------------------------------------------- -void app::showStatistics(void) { +/*void app::showStatistics(void) { DPRINTLN(DBG_VERBOSE, F("app::showStatistics")); String content = F("Receive success: ") + String(mRxSuccess) + "\n"; content += F("Receive fail: ") + String(mRxFailed) + "\n"; @@ -615,10 +618,11 @@ void app::showStatistics(void) { content += F("connected\n"); mWeb->send(200, F("text/plain"), content); -} +}*/ + //----------------------------------------------------------------------------- -void app::webapi(void) { // ToDo +/*void app::webapi(void) { // ToDo DPRINTLN(DBG_VERBOSE, F("app::api")); DPRINTLN(DBG_DEBUG, mWeb->arg("plain")); const size_t capacity = 200; // Use arduinojson.org/assistant to compute the capacity. @@ -632,23 +636,23 @@ void app::webapi(void) { // ToDo DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(mSys->InfoCmd)); } mWeb->send ( 200, "text/json", "{success:true}" ); -} +}*/ //----------------------------------------------------------------------------- -void app::showHoymiles(void) { +/*void app::showHoymiles(void) { DPRINTLN(DBG_VERBOSE, F("app::showHoymiles")); String html = FPSTR(hoymiles_html); - html.replace(F("{DEVICE}"), sysConfig.deviceName); + html.replace(F("{DEVICE}"), mSysConfig.deviceName); html.replace(F("{VERSION}"), version); html.replace(F("{TS}"), String(config.sendInterval) + " "); html.replace(F("{JS_TS}"), String(config.sendInterval * 1000)); mWeb->send(200, F("text/html"), html); -} +}*/ //----------------------------------------------------------------------------- -void app::showLiveData(void) { +/*void app::showLiveData(void) { DPRINTLN(DBG_VERBOSE, F("app::showLiveData")); String modHtml; for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { @@ -720,11 +724,11 @@ void app::showLiveData(void) { } } mWeb->send(200, F("text/html"), modHtml); -} +}*/ //----------------------------------------------------------------------------- -void app::showJSON(void) { +/*void app::showJSON(void) { DPRINTLN(DBG_VERBOSE, F("app::showJSON")); String modJson; @@ -747,7 +751,7 @@ void app::showJSON(void) { // mWeb->send(200, F("text/json"), modJson); mWeb->send(200, F("application/json"), modJson); // the preferred content-type (https://stackoverflow.com/questions/22406077/what-is-the-exact-difference-between-content-type-text-json-and-application-jso) -} +}*/ @@ -772,7 +776,7 @@ void app::sendMqttDiscoveryConfig(void) { } else { snprintf(name, 32, "%s CH%d %s", iv->name, iv->assign[i].ch, iv->getFieldName(i)); } - snprintf(stateTopic, 64, "%s/%s/ch%d/%s", config.mqtt.topic, iv->name, iv->assign[i].ch, iv->getFieldName(i)); + snprintf(stateTopic, 64, "%s/%s/ch%d/%s", mConfig.mqtt.topic, iv->name, iv->assign[i].ch, iv->getFieldName(i)); snprintf(discoveryTopic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->name, iv->assign[i].ch, iv->getFieldName(i)); snprintf(uniq_id, 32, "ch%d_%s", iv->assign[i].ch, iv->getFieldName(i)); const char* devCls = getFieldDeviceClass(iv->assign[i].fieldId); @@ -839,14 +843,7 @@ void app::setupAp(const char *ssid, const char *pwd) { WiFi.softAPConfig(apIp, apIp, IPAddress(255, 255, 255, 0)); WiFi.softAP(ssid, pwd); - mDns->start(mDnsPort, "*", apIp); - - /*mWeb->onNotFound([&]() { - showSetup(); - }); - mWeb->on("/", std::bind(&app::showSetup, this)); - - mWeb->begin();*/ + mDns->start(53, "*", apIp); } @@ -864,15 +861,15 @@ bool app::setupStation(uint32_t timeout) { } WiFi.mode(WIFI_STA); - WiFi.begin(sysConfig.stationSsid, sysConfig.stationPwd); - if(String(sysConfig.deviceName) != "") - WiFi.hostname(sysConfig.deviceName); + WiFi.begin(mSysConfig.stationSsid, mSysConfig.stationPwd); + if(String(mSysConfig.deviceName) != "") + WiFi.hostname(mSysConfig.deviceName); delay(2000); - DPRINTLN(DBG_INFO, F("connect to network '") + String(sysConfig.stationSsid) + F("' ...")); + DPRINTLN(DBG_INFO, F("connect to network '") + String(mSysConfig.stationSsid) + F("' ...")); while (WiFi.status() != WL_CONNECTED) { delay(100); - if(cnt % 100 == 0) + if(cnt % 40 == 0) Serial.println("."); else Serial.print("."); @@ -891,7 +888,7 @@ bool app::setupStation(uint32_t timeout) { Serial.println("."); if(false == startAp) { - mWeb->begin(); + wifiWasEstablished = true; } delay(1000); @@ -903,6 +900,7 @@ bool app::setupStation(uint32_t timeout) { //----------------------------------------------------------------------------- void app::resetSystem(void) { mWifiStationTimeout = 10; + wifiWasEstablished = false; mNextTryTs = 0; mApLastTick = 0; @@ -942,36 +940,36 @@ void app::resetSystem(void) { //----------------------------------------------------------------------------- void app::loadDefaultConfig(void) { - memset(&sysConfig, 0, sizeof(sysConfig_t)); - memset(&config, 0, sizeof(config_t)); - snprintf(version, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); + memset(&mSysConfig, 0, sizeof(sysConfig_t)); + memset(&mConfig, 0, sizeof(config_t)); + snprintf(mVersion, 12, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); - snprintf(sysConfig.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); + snprintf(mSysConfig.deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME); // wifi - snprintf(sysConfig.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); - snprintf(sysConfig.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); - sysConfig.apActive = false; + snprintf(mSysConfig.stationSsid, SSID_LEN, "%s", FB_WIFI_SSID); + snprintf(mSysConfig.stationPwd, PWD_LEN, "%s", FB_WIFI_PWD); + apActive = false; // nrf24 - config.sendInterval = SEND_INTERVAL; - config.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; + mConfig.sendInterval = SEND_INTERVAL; + mConfig.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; // ntp - snprintf(config.ntpAddr, NTP_ADDR_LEN, "%s", NTP_SERVER_NAME); - config.ntpPort = NTP_LOCAL_PORT; + snprintf(mConfig.ntpAddr, NTP_ADDR_LEN, "%s", NTP_SERVER_NAME); + mConfig.ntpPort = NTP_LOCAL_PORT; // mqtt - snprintf(config.mqtt.broker, MQTT_ADDR_LEN, "%s", DEF_MQTT_BROKER); - config.mqtt.port = DEF_MQTT_PORT; - snprintf(config.mqtt.user, MQTT_USER_LEN, "%s", DEF_MQTT_USER); - snprintf(config.mqtt.pwd, MQTT_PWD_LEN, "%s", DEF_MQTT_PWD); - snprintf(config.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); + snprintf(mConfig.mqtt.broker, MQTT_ADDR_LEN, "%s", DEF_MQTT_BROKER); + mConfig.mqtt.port = DEF_MQTT_PORT; + snprintf(mConfig.mqtt.user, MQTT_USER_LEN, "%s", DEF_MQTT_USER); + snprintf(mConfig.mqtt.pwd, MQTT_PWD_LEN, "%s", DEF_MQTT_PWD); + snprintf(mConfig.mqtt.topic, MQTT_TOPIC_LEN, "%s", DEF_MQTT_TOPIC); // serial - config.serialInterval = SERIAL_INTERVAL; - config.serialShowIv = true; - config.serialDebug = false; + mConfig.serialInterval = SERIAL_INTERVAL; + mConfig.serialShowIv = true; + mConfig.serialDebug = false; } @@ -980,11 +978,11 @@ void app::loadEEpconfig(void) { DPRINTLN(DBG_VERBOSE, F("app::loadEEpconfig")); if(mWifiSettingsValid) - mEep->read(ADDR_CFG_SYS, (uint8_t*) &sysConfig, CFG_SYS_LEN); + mEep->read(ADDR_CFG_SYS, (uint8_t*) &mSysConfig, CFG_SYS_LEN); if(mSettingsValid) { - mEep->read(ADDR_CFG, (uint8_t*) &config, CFG_LEN); + mEep->read(ADDR_CFG, (uint8_t*) &mConfig, CFG_LEN); - mSendTicker = config.sendInterval; + mSendTicker = mConfig.sendInterval; mSerialTicker = 0; // inverter @@ -1012,7 +1010,7 @@ void app::loadEEpconfig(void) { } // TODO: the original mqttinterval value is not needed any more - mMqttInterval += config.sendInterval; + mMqttInterval += mConfig.sendInterval; } } } @@ -1022,7 +1020,7 @@ void app::loadEEpconfig(void) { //----------------------------------------------------------------------------- void app::setupMqtt(void) { if(mSettingsValid) { - if(config.mqtt.broker[0] > 0) { + if(mConfig.mqtt.broker[0] > 0) { mMqttActive = true; if(mMqttInterval < MIN_MQTT_INTERVAL) mMqttInterval = MIN_MQTT_INTERVAL; @@ -1031,14 +1029,14 @@ void app::setupMqtt(void) { mMqttInterval = 0xffff; mMqttTicker = 0; - mMqtt.setup(&config.mqtt, sysConfig.deviceName); + mMqtt.setup(&mConfig.mqtt, mSysConfig.deviceName); mMqtt.setCallback(std::bind(&app::cbMqtt, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); if(mMqttActive) { - mMqtt.sendMsg("version", version); + mMqtt.sendMsg("version", mVersion); if(mMqtt.isConnected()) - mMqtt.sendMsg("device", sysConfig.deviceName); + mMqtt.sendMsg("device", mSysConfig.deviceName); /*char topic[30]; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { @@ -1062,8 +1060,8 @@ void app::setupMqtt(void) { void app::saveValues(void) { DPRINTLN(DBG_VERBOSE, F("app::saveValues")); - mEep->write(ADDR_CFG_SYS, (uint8_t*)&sysConfig, CFG_SYS_LEN); - mEep->write(ADDR_CFG, (uint8_t*)&config, CFG_LEN); + mEep->write(ADDR_CFG_SYS, (uint8_t*)&mSysConfig, CFG_SYS_LEN); + mEep->write(ADDR_CFG, (uint8_t*)&mConfig, CFG_LEN); Inverter<> *iv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { iv = mSys->getInverterByPos(i); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index a5c5ac21..de8f5751 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -28,6 +28,7 @@ #include "CircularBuffer.h" #include "hmSystem.h" #include "mqtt.h" +#include "web.h" // hier läst sich das Verhalten der app in Bezug auf MQTT // durch PER-Conpiler defines anpassen @@ -66,6 +67,7 @@ const byte mDnsPort = 53; #define NTP_PACKET_SIZE 48 #define TIMEZONE 1 // Central European time +1 +class web; class app { public: @@ -79,7 +81,7 @@ class app { void saveValues(void); uint8_t getIrqPin(void) { - return config.pinIrq; + return mConfig.pinIrq; } uint64_t Serial2u64(const char *val) { @@ -133,9 +135,8 @@ class app { uint8_t app_loops; HmSystemType *mSys; ESP8266WebServer *mWeb; - sysConfig_t sysConfig; - config_t config; - char version[12]; + bool apActive; + bool wifiWasEstablished; private: void MainLoop(void); @@ -254,6 +255,10 @@ class app { bool mShowRebootRequest; + web *mWebInst; + sysConfig_t mSysConfig; + config_t mConfig; + char mVersion[12]; uint16_t mSendTicker; uint8_t mSendLastIvId; diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index 585da08b..ed35731a 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -163,7 +163,6 @@ typedef struct { // wifi char stationSsid[SSID_LEN]; char stationPwd[PWD_LEN]; - bool apActive; } sysConfig_t; typedef struct { diff --git a/tools/esp8266/main.cpp b/tools/esp8266/main.cpp index fe44abc7..eb7a388b 100644 --- a/tools/esp8266/main.cpp +++ b/tools/esp8266/main.cpp @@ -7,10 +7,8 @@ #include "app.h" #include "config.h" -#include "web.h" app myApp; -web *mWebInst; //----------------------------------------------------------------------------- IRAM_ATTR void handleIntr(void) { @@ -21,7 +19,6 @@ IRAM_ATTR void handleIntr(void) { //----------------------------------------------------------------------------- void setup() { myApp.setup(WIFI_TRY_CONNECT_TIME); - mWebInst = new web(&myApp); // TODO: move to HmRadio attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING); diff --git a/tools/esp8266/web.h b/tools/esp8266/web.h index 11ea54b2..3e3e8299 100644 --- a/tools/esp8266/web.h +++ b/tools/esp8266/web.h @@ -12,320 +12,35 @@ #include "app.h" -#include "html/h/index_html.h" -#include "html/h/style_css.h" -#include "favicon.h" -#include "html/h/setup_html.h" - +class app; class web { public: - web(app *main) { - mMain = main; - mWeb = main->mWeb; - //mWeb = new ESP8266WebServer(80); - mUpdater = new ESP8266HTTPUpdateServer(); - mUpdater->setup(mWeb); - } - - void setup(void) { - mWeb->on("/", std::bind(&web::showIndex, this)); - mWeb->on("/style.css", std::bind(&web::showCss, this)); - mWeb->on("/favicon.ico", std::bind(&web::showFavicon, this)); - mWeb->onNotFound ( std::bind(&web::showNotFound, this)); - mWeb->on("/uptime", std::bind(&web::showUptime, this)); - mWeb->on("/reboot", std::bind(&web::showReboot, this)); - mWeb->on("/erase", std::bind(&web::showErase, this)); - mWeb->on("/factory", std::bind(&web::showFactoryRst, this)); - - mWeb->on("/setup", std::bind(&web::showSetup, this)); - mWeb->on("/save", std::bind(&web::showSave, this)); - } - - void showIndex(void) { - DPRINTLN(DBG_VERBOSE, F("showIndex")); - String html = FPSTR(index_html); - html.replace(F("{DEVICE}"), mMain->sysConfig.deviceName); - html.replace(F("{VERSION}"), mMain->version); - html.replace(F("{TS}"), String(mMain->config.sendInterval) + " "); - html.replace(F("{JS_TS}"), String(mMain->config.sendInterval * 1000)); - html.replace(F("{BUILD}"), String(AUTO_GIT_HASH)); - mWeb->send(200, "text/html", html); - } - - void showCss(void) { - mWeb->send(200, "text/css", FPSTR(style_css)); - } - - void showFavicon(void) { - static const char favicon_type[] PROGMEM = "image/x-icon"; - static const char favicon_content[] PROGMEM = FAVICON_PANEL_16; - mWeb->send_P(200, favicon_type, favicon_content, sizeof(favicon_content)); - } - - void showNotFound(void) { - DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + mWeb->uri()); - String msg = F("File Not Found\n\nURI: "); - msg += mWeb->uri(); - mWeb->send(404, F("text/plain"), msg); - } - - void showUptime(void) { - 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); - - mWeb->send(200, "text/plain", String(time) + mMain->getDateTimeStr(mMain->getTimestamp())); - } - - void showReboot(void) { - mWeb->send(200, F("text/html"), F("Rebooting ...rebooting ... auto reload after 10s")); - delay(1000); - ESP.restart(); - } - - void showErase() { - DPRINTLN(DBG_VERBOSE, F("showErase")); - mMain->eraseSettings(); - showReboot(); - } - - void showFactoryRst(void) { - DPRINTLN(DBG_VERBOSE, F("showFactoryRst")); - String content = ""; - int refresh = 3; - if(mWeb->args() > 0) { - if(mWeb->arg("reset").toInt() == 1) { - mMain->eraseSettings(true); - content = F("factory reset: success\n\nrebooting ... "); - refresh = 10; - } - else { - content = F("factory reset: aborted"); - refresh = 3; - } - } - else { - content = F("

Factory Reset

" - "

RESET

CANCEL

"); - refresh = 120; - } - mWeb->send(200, F("text/html"), F("Factory Reset") + content + F("")); - if(refresh == 10) { - delay(1000); - ESP.restart(); - } - } - - void showSetup(void) { - DPRINTLN(DBG_VERBOSE, F("showSetup")); - String html = FPSTR(setup_html); - html.replace(F("{SSID}"), mMain->sysConfig.stationSsid); - // PWD will be left at the default value (for protection) - // -> the PWD will only be changed if it does not match the default "{PWD}" - html.replace(F("{DEVICE}"), String(mMain->sysConfig.deviceName)); - html.replace(F("{VERSION}"), String(mMain->version)); - if(mMain->sysConfig.apActive) - html.replace("{IP}", String(F("http://192.168.1.1"))); - else - html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString()))); - - String inv = ""; - Inverter<> *iv; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - iv = mMain->mSys->getInverterByPos(i); - - inv += F("

Inverter ") + String(i) + "

"; - inv += F(""); - inv += F("serial.u64, HEX); - inv += F("\"/ maxlength=\"12\" onkeyup=\"checkSerial()\">"); - - inv += F(""); - inv += F("name); - inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">"; - - inv += F(""); - inv += F("powerLimit[0]); - inv += F("\"/ maxlength=\"") + String(6) + "\">"; - - inv += F(""); - for(uint8_t j = 0; j < 4; j++) { - inv += F("chMaxPwr[j]); - inv += F("\"/ maxlength=\"4\">"); - } - inv += F("
"); - for(uint8_t j = 0; j < 4; j++) { - inv += F("chName[j]); - inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">"; - } - } - html.replace(F("{INVERTERS}"), String(inv)); - - - // pinout - String pinout; - for(uint8_t i = 0; i < 3; i++) { - pinout += F(""); - pinout += F(""); - } - html.replace(F("{PINOUT}"), String(pinout)); - - - // nrf24l01+ - String rf24; - for(uint8_t i = 0; i <= 3; i++) { - rf24 += F(""); - } - html.replace(F("{RF24}"), String(rf24)); - - - html.replace(F("{INV_INTVL}"), String(mMain->config.sendInterval)); - html.replace(F("{INV_RETRIES}"), String(mMain->config.maxRetransPerPyld)); - - html.replace(F("{SER_INTVL}"), String(mMain->config.serialInterval)); - html.replace(F("{SER_VAL_CB}"), (mMain->config.serialShowIv) ? "checked" : ""); - html.replace(F("{SER_DBG_CB}"), (mMain->config.serialDebug) ? "checked" : ""); - - html.replace(F("{NTP_ADDR}"), String(mMain->config.ntpAddr)); - html.replace(F("{NTP_PORT}"), String(mMain->config.ntpPort)); - - html.replace(F("{MQTT_ADDR}"), String(mMain->config.mqtt.broker)); - html.replace(F("{MQTT_PORT}"), String(mMain->config.mqtt.port)); - html.replace(F("{MQTT_USER}"), String(mMain->config.mqtt.user)); - html.replace(F("{MQTT_PWD}"), String(mMain->config.mqtt.pwd)); - html.replace(F("{MQTT_TOPIC}"), String(mMain->config.mqtt.topic)); - html.replace(F("{MQTT_INTVL}"), String("0")); - - mWeb->send(200, F("text/html"), html); - } - - void showSave(void) { - DPRINTLN(DBG_VERBOSE, F("showSave")); - - if(mWeb->args() > 0) { - char buf[20] = {0}; - - // general - if(mWeb->arg("ssid") != "") - mWeb->arg("ssid").toCharArray(mMain->sysConfig.stationSsid, SSID_LEN); - if(mWeb->arg("pwd") != "{PWD}") - mWeb->arg("pwd").toCharArray(mMain->sysConfig.stationPwd, PWD_LEN); - if(mWeb->arg("device") != "") - mWeb->arg("device").toCharArray(mMain->sysConfig.deviceName, DEVNAME_LEN); - - // inverter - Inverter<> *iv; - for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) { - iv = mMain->mSys->getInverterByPos(i, false); - // address - mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20); - if(strlen(buf) == 0) - memset(buf, 0, 20); - iv->serial.u64 = mMain->Serial2u64(buf); - - // active power limit - uint16_t actPwrLimit = mWeb->arg("inv" + String(i) + "ActivePowerLimit").toInt(); - if (actPwrLimit != 0xffff && actPwrLimit > 0) - iv->powerLimit[0] = actPwrLimit; - - // name - mWeb->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH); - - // max channel power / name - for(uint8_t j = 0; j < 4; j++) { - iv->chMaxPwr[j] = mWeb->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff; - mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH); - } - } - if(mWeb->arg("invInterval") != "") - mMain->config.sendInterval = mWeb->arg("invInterval").toInt(); - if(mWeb->arg("invRetry") != "") - mMain->config.sendInterval = mWeb->arg("invRetry").toInt(); - - // pinout - uint8_t pin; - for(uint8_t i = 0; i < 3; i ++) { - pin = mWeb->arg(String(pinArgNames[i])).toInt(); - switch(i) { - default: mMain->config.pinCs = pin; break; - case 1: mMain->config.pinCe = pin; break; - case 2: mMain->config.pinIrq = pin; break; - } - } - - // nrf24 amplifier power - mMain->config.amplifierPower = mWeb->arg("rf24Power").toInt() & 0x03; - - // ntp - if(mWeb->arg("ntpAddr") != "") { - mWeb->arg("ntpAddr").toCharArray(mMain->config.ntpAddr, NTP_ADDR_LEN); - mMain->config.ntpPort = mWeb->arg("ntpPort").toInt() & 0xffff; - } - - // mqtt - if(mWeb->arg("mqttAddr") != "") { - mWeb->arg("mqttAddr").toCharArray(mMain->config.mqtt.broker, MQTT_ADDR_LEN); - mWeb->arg("mqttUser").toCharArray(mMain->config.mqtt.user, MQTT_USER_LEN); - mWeb->arg("mqttPwd").toCharArray(mMain->config.mqtt.pwd, MQTT_PWD_LEN); - mWeb->arg("mqttTopic").toCharArray(mMain->config.mqtt.topic, MQTT_TOPIC_LEN); - mMain->config.mqtt.port = mWeb->arg("mqttPort").toInt(); - } - - // serial console - if(mWeb->arg("serIntvl") != "") { - mMain->config.serialInterval = mWeb->arg("serIntvl").toInt() & 0xffff; - - mMain->config.serialDebug = (mWeb->arg("serEn") == "on"); - mMain->config.serialShowIv = (mWeb->arg("serDbg") == "on"); - } - - mMain->saveValues(); - - if(mWeb->arg("reboot") == "on") - showReboot(); - else - mWeb->send(200, F("text/html"), F("Setup saved" - "

saved

")); - } - } - + web(app *main, sysConfig_t *sysCfg, config_t *config, char version[]); + ~web() {} + + void setup(void); + void loop(void); + + void showIndex(void); + void showCss(void); + void showFavicon(void); + void showNotFound(void); + void showUptime(void); + void showReboot(void); + void showErase(); + void showFactoryRst(void); + void showSetup(void); + void showSave(void); private: ESP8266WebServer *mWeb; ESP8266HTTPUpdateServer *mUpdater; - app *mMain; + config_t *mConfig; + sysConfig_t *mSysCfg; + char *mVersion; + app *mMain; }; #endif /*__WEB_H__*/ From 74f053a5aead282747160ac6c3dbb88398529dcd Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 14 Aug 2022 02:18:53 +0200 Subject: [PATCH 09/10] * webinterface refactored completely --- tools/esp8266/app.cpp | 99 ++--- tools/esp8266/app.h | 7 +- tools/esp8266/config.h | 30 +- tools/esp8266/defines.h | 56 +-- tools/esp8266/html/convert.py | 2 +- tools/esp8266/html/h/hoymiles_html.h | 4 - tools/esp8266/html/h/index_html.h | 2 +- tools/esp8266/html/h/visualization_html.h | 4 + tools/esp8266/html/index.html | 5 +- .../{hoymiles.html => visualization.html} | 0 tools/esp8266/web.cpp | 401 ++++++++++++++++++ tools/esp8266/web.h | 6 + 12 files changed, 480 insertions(+), 136 deletions(-) delete mode 100644 tools/esp8266/html/h/hoymiles_html.h create mode 100644 tools/esp8266/html/h/visualization_html.h rename tools/esp8266/html/{hoymiles.html => visualization.html} (100%) create mode 100644 tools/esp8266/web.cpp diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index 14fe2bd4..a612e757 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -5,7 +5,6 @@ #include "app.h" -#include "html/h/hoymiles_html.h" #include @@ -13,7 +12,6 @@ app::app() { DPRINTLN(DBG_VERBOSE, F("app::app")); mDns = new DNSServer(); - //mWeb = new ESP8266WebServer(80); mUdp = new WiFiUDP(); mEep = new eep(); Serial.begin(115200); @@ -28,12 +26,6 @@ app::app() { } -//----------------------------------------------------------------------------- -app::~app(void) { - -} - - //----------------------------------------------------------------------------- void app::setup(uint32_t timeout) { DPRINTLN(DBG_VERBOSE, F("app::setup")); @@ -46,15 +38,6 @@ void app::setup(uint32_t timeout) { #ifndef AP_ONLY if(false == apActive) apActive = setupStation(mWifiStationTimeout); -#endif - - /*mWeb->on("/cmdstat", std::bind(&app::showStatistics, this)); - mWeb->on("/hoymiles", std::bind(&app::showHoymiles, this)); - mWeb->on("/livedata", std::bind(&app::showLiveData, this)); - mWeb->on("/json", std::bind(&app::showJSON, this)); - mWeb->on("/api",HTTP_POST, std::bind(&app::webapi, this));*/ - -#ifndef AP_ONLY setupMqtt(); #endif @@ -569,10 +552,26 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { } +//----------------------------------------------------------------------------- +/*void app::webapi(void) { // ToDo + DPRINTLN(DBG_VERBOSE, F("app::api")); + const size_t capacity = 200; // Use arduinojson.org/assistant to compute the capacity. + DynamicJsonDocument payload(capacity); + + // Parse JSON object + deserializeJson(payload, mWeb->arg("plain")); + // ToDo: error handling for payload + if (payload["tx_request"] == TX_REQ_INFO){ + mSys->InfoCmd = payload["cmd"]; + DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(mSys->InfoCmd)); + } + mWeb->send ( 200, "text/json", "{success:true}" ); +}*/ + + //----------------------------------------------------------------------------- -/*void app::showStatistics(void) { - DPRINTLN(DBG_VERBOSE, F("app::showStatistics")); +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"; @@ -617,43 +616,13 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { content += F("not "); content += F("connected\n"); - mWeb->send(200, F("text/plain"), content); -}*/ - - -//----------------------------------------------------------------------------- -/*void app::webapi(void) { // ToDo - DPRINTLN(DBG_VERBOSE, F("app::api")); - DPRINTLN(DBG_DEBUG, mWeb->arg("plain")); - const size_t capacity = 200; // Use arduinojson.org/assistant to compute the capacity. - DynamicJsonDocument payload(capacity); - - // Parse JSON object - deserializeJson(payload, mWeb->arg("plain")); - // ToDo: error handling for payload - if (payload["tx_request"] == TX_REQ_INFO){ - mSys->InfoCmd = payload["cmd"]; - DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(mSys->InfoCmd)); - } - mWeb->send ( 200, "text/json", "{success:true}" ); -}*/ - + return content; +} -//----------------------------------------------------------------------------- -/*void app::showHoymiles(void) { - DPRINTLN(DBG_VERBOSE, F("app::showHoymiles")); - String html = FPSTR(hoymiles_html); - html.replace(F("{DEVICE}"), mSysConfig.deviceName); - html.replace(F("{VERSION}"), version); - html.replace(F("{TS}"), String(config.sendInterval) + " "); - html.replace(F("{JS_TS}"), String(config.sendInterval * 1000)); - mWeb->send(200, F("text/html"), html); -}*/ //----------------------------------------------------------------------------- -/*void app::showLiveData(void) { - DPRINTLN(DBG_VERBOSE, F("app::showLiveData")); +String app::getLiveData(void) { String modHtml; for(uint8_t id = 0; id < mSys->getNumInverters(); id++) { Inverter<> *iv = mSys->getInverterByPos(id); @@ -723,13 +692,13 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { #endif } } - mWeb->send(200, F("text/html"), modHtml); -}*/ + return modHtml; +} //----------------------------------------------------------------------------- -/*void app::showJSON(void) { - DPRINTLN(DBG_VERBOSE, F("app::showJSON")); +String app::getJson(void) { + DPRINTLN(DBG_VERBOSE, F("app::showJson")); String modJson; modJson = F("{\n"); @@ -749,12 +718,11 @@ void app::cbMqtt(char* topic, byte* payload, unsigned int length) { } modJson += F("\"json_ts\": \"") + String(getDateTimeStr(mTimestamp)) + F("\"\n}\n"); - // mWeb->send(200, F("text/json"), modJson); - mWeb->send(200, F("application/json"), modJson); // the preferred content-type (https://stackoverflow.com/questions/22406077/what-is-the-exact-difference-between-content-type-text-json-and-application-jso) -}*/ - + return modJson; +} +//----------------------------------------------------------------------------- void app::sendMqttDiscoveryConfig(void) { DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); @@ -808,6 +776,8 @@ void app::sendMqttDiscoveryConfig(void) { } } + +//----------------------------------------------------------------------------- const char* app::getFieldDeviceClass(uint8_t fieldId) { uint8_t pos = 0; for(; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { @@ -817,6 +787,8 @@ const char* app::getFieldDeviceClass(uint8_t fieldId) { return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : deviceClasses[deviceFieldAssignment[pos].deviceClsId]; } + +//----------------------------------------------------------------------------- const char* app::getFieldStateClass(uint8_t fieldId) { uint8_t pos = 0; for(; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { @@ -954,6 +926,10 @@ void app::loadDefaultConfig(void) { // nrf24 mConfig.sendInterval = SEND_INTERVAL; mConfig.maxRetransPerPyld = DEF_MAX_RETRANS_PER_PYLD; + mConfig.pinCs = DEF_RF24_CS_PIN; + mConfig.pinCe = DEF_RF24_CE_PIN; + mConfig.pinIrq = DEF_RF24_IRQ_PIN; + mConfig.amplifierPower = DEF_AMPLIFIERPOWER & 0x03; // ntp snprintf(mConfig.ntpAddr, NTP_ADDR_LEN, "%s", NTP_SERVER_NAME); @@ -968,7 +944,7 @@ void app::loadDefaultConfig(void) { // serial mConfig.serialInterval = SERIAL_INTERVAL; - mConfig.serialShowIv = true; + mConfig.serialShowIv = false; mConfig.serialDebug = false; } @@ -1082,7 +1058,6 @@ void app::saveValues(void) { } - //----------------------------------------------------------------------------- time_t app::getNtpTime(void) { //DPRINTLN(DBG_VERBOSE, F("app::getNtpTime")); diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index de8f5751..e003adec 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -38,7 +38,7 @@ // #define __MQTT_NO_DISCOVERCONFIG__ // das versenden der MQTTDiscoveryConfig abschalten ( gehört eigentlich ins Setup ) typedef CircularBuffer BufferType; -typedef HmRadio RadioType; +typedef HmRadio RadioType; typedef Inverter InverterType; typedef HmSystem HmSystemType; @@ -72,13 +72,16 @@ class web; class app { public: app(); - ~app(); + ~app() {} void setup(uint32_t timeout); void loop(void); void handleIntr(void); void cbMqtt(char* topic, byte* payload, unsigned int length); void saveValues(void); + String getStatistics(void); + String getLiveData(void); + String getJson(void); uint8_t getIrqPin(void) { return mConfig.pinIrq; diff --git a/tools/esp8266/config.h b/tools/esp8266/config.h index 0a28423e..b9af7f8e 100644 --- a/tools/esp8266/config.h +++ b/tools/esp8266/config.h @@ -31,6 +31,14 @@ // default device name #define DEF_DEVICE_NAME "AHOY-DTU" +// default pinout +#define DEF_RF24_CS_PIN 15 +#define DEF_RF24_CE_PIN 2 +#define DEF_RF24_IRQ_PIN 0 + +// default NRF24 power, possible values (0 - 3) +#define DEF_AMPLIFIERPOWER 2 + // number of packets hold in buffer #define PACKET_BUFFER_SIZE 30 @@ -38,13 +46,10 @@ #define MAX_NUM_INVERTERS 3 // default serial interval -#define SERIAL_INTERVAL 5 +#define SERIAL_INTERVAL 5 // default send interval -#define SEND_INTERVAL 30 - -// default mqtt interval -#define MQTT_INTERVAL 60 +#define SEND_INTERVAL 30 // maximum human readable inverter name length #define MAX_NAME_LENGTH 16 @@ -64,14 +69,14 @@ // threshold of minimum power on which the inverter is marked as inactive #define INACT_PWR_THRESH 3 -// changes the style of "/setup" page, visualized = nicer -#define LIVEDATA_VISUALIZED - // default ntp server uri -#define NTP_SERVER_NAME "pool.ntp.org" +#define NTP_SERVER_NAME "pool.ntp.org" // default ntp server port -#define NTP_LOCAL_PORT 8888 +#define NTP_LOCAL_PORT 8888 + +// default mqtt interval +#define MQTT_INTERVAL 60 // default MQTT broker uri #define DEF_MQTT_BROKER "\0" @@ -86,6 +91,9 @@ #define DEF_MQTT_PWD "\0" // default MQTT topic -#define DEF_MQTT_TOPIC "inverter" +#define DEF_MQTT_TOPIC "inverter" + +// changes the style of "/setup" page, visualized = nicer +#define LIVEDATA_VISUALIZED #endif /*__CONFIG_H__*/ diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index ed35731a..ce21e996 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -8,21 +8,12 @@ #include "config.h" -//------------------------------------- -// PINOUT (Default, can be changed in setup) -//------------------------------------- -#define RF24_CS_PIN 15 -#define RF24_CE_PIN 2 -#define RF24_IRQ_PIN 0 - - //------------------------------------- // VERSION //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 10 - +#define VERSION_PATCH 11 //------------------------------------- @@ -111,44 +102,7 @@ typedef enum { #define SER_DEBUG_LEN 1 // uint8_t #define SER_INTERVAL_LEN 2 // uint16_t -/* -#define ADDR_START 0 -#define ADDR_SSID ADDR_START -#define ADDR_PWD ADDR_SSID + SSID_LEN -#define ADDR_DEVNAME ADDR_PWD + PWD_LEN -#define ADDR_WIFI_CRC ADDR_DEVNAME + DEVNAME_LEN -#define ADDR_START_SETTINGS ADDR_WIFI_CRC + CRC_LEN -#define ADDR_PINOUT ADDR_START_SETTINGS - -#define ADDR_RF24_AMP_PWR ADDR_PINOUT + PINOUT_LEN - -#define ADDR_INV_ADDR ADDR_RF24_AMP_PWR + RF24_AMP_PWR_LEN -#define ADDR_INV_NAME ADDR_INV_ADDR + INV_ADDR_LEN -#define ADDR_INV_CH_PWR ADDR_INV_NAME + INV_NAME_LEN -#define ADDR_INV_CH_NAME ADDR_INV_CH_PWR + INV_CH_CH_PWR_LEN -#define ADDR_INV_INTERVAL ADDR_INV_CH_NAME + INV_CH_CH_NAME_LEN -#define ADDR_INV_MAX_RTRY ADDR_INV_INTERVAL + INV_INTERVAL_LEN -#define ADDR_INV_PWR_LIM ADDR_INV_MAX_RTRY + INV_MAX_RTRY_LEN - -#define ADDR_NTP_ADDR ADDR_INV_PWR_LIM + INV_PWR_LIM_LEN //Bugfix #125 -#define ADDR_NTP_PORT ADDR_NTP_ADDR + NTP_ADDR_LEN - -#define ADDR_MQTT_ADDR ADDR_NTP_PORT + NTP_PORT_LEN -#define ADDR_MQTT_USER ADDR_MQTT_ADDR + MQTT_ADDR_LEN -#define ADDR_MQTT_PWD ADDR_MQTT_USER + MQTT_USER_LEN -#define ADDR_MQTT_TOPIC ADDR_MQTT_PWD + MQTT_PWD_LEN -#define ADDR_MQTT_INTERVAL ADDR_MQTT_TOPIC + MQTT_TOPIC_LEN -#define ADDR_MQTT_PORT ADDR_MQTT_INTERVAL + MQTT_INTERVAL_LEN - -#define ADDR_SER_ENABLE ADDR_MQTT_PORT + MQTT_PORT_LEN -#define ADDR_SER_DEBUG ADDR_SER_ENABLE + SER_ENABLE_LEN -#define ADDR_SER_INTERVAL ADDR_SER_DEBUG + SER_DEBUG_LEN -#define ADDR_NEXT ADDR_SER_INTERVAL + SER_INTERVAL_LEN -*/ - - -//------------------------------------- typedef struct { char broker[MQTT_ADDR_LEN]; uint16_t port; @@ -187,10 +141,10 @@ typedef struct { bool serialDebug; } config_t; -// eeprom new -#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 -#define CFG_LEN 7 + NTP_ADDR_LEN + 2 + CFG_MQTT_LEN + 4 + +#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 +#define CFG_LEN 7 + NTP_ADDR_LEN + 2 + CFG_MQTT_LEN + 4 #define ADDR_START 0 #define ADDR_CFG_SYS ADDR_START diff --git a/tools/esp8266/html/convert.py b/tools/esp8266/html/convert.py index 4cbecb20..98027b2f 100755 --- a/tools/esp8266/html/convert.py +++ b/tools/esp8266/html/convert.py @@ -34,5 +34,5 @@ def convert2Header(inFile): convert2Header("index.html") convert2Header("setup.html") -convert2Header("hoymiles.html") +convert2Header("visualization.html") convert2Header("style.css") diff --git a/tools/esp8266/html/h/hoymiles_html.h b/tools/esp8266/html/h/hoymiles_html.h deleted file mode 100644 index 93beff78..00000000 --- a/tools/esp8266/html/h/hoymiles_html.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __HOYMILES_HTML_H__ -#define __HOYMILES_HTML_H__ -const char hoymiles_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Every {TS}seconds the values are updated

© 2022

Home

AHOY :: {VERSION}

"; -#endif /*__HOYMILES_HTML_H__*/ diff --git a/tools/esp8266/html/h/index_html.h b/tools/esp8266/html/h/index_html.h index 6c4255bf..61dd0cce 100644 --- a/tools/esp8266/html/h/index_html.h +++ b/tools/esp8266/html/h/index_html.h @@ -1,4 +1,4 @@ #ifndef __INDEX_HTML_H__ #define __INDEX_HTML_H__ -const char index_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Visualization

Setup

Uptime:

Time:

Statistics:

Every {TS}seconds the values are updated

This project was started from this discussion. (Mikrocontroller.net)
New updates can be found on Github: https://github.com/grindylow/ahoy

Please report issues using the feature provided by Github

Discuss with us on Discord

Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/
Check the licenses which are published on https://github.com/grindylow/ahoyas well

© 2022

Update Firmware

AHOY :: {VERSION}

Reboot

Git SHA: {BUILD}

"; +const char index_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Visualization

Setup

Uptime:

Statistics:

Every {TS}seconds the values are updated

This project was started from this discussion. (Mikrocontroller.net)
New updates can be found on Github: https://github.com/grindylow/ahoy

Please report issues using the feature provided by Github

Discuss with us on Discord

Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/
Check the licenses which are published on https://github.com/grindylow/ahoyas well

© 2022

Update Firmware

AHOY :: {VERSION}

Reboot

Git SHA: {BUILD}

"; #endif /*__INDEX_HTML_H__*/ diff --git a/tools/esp8266/html/h/visualization_html.h b/tools/esp8266/html/h/visualization_html.h new file mode 100644 index 00000000..b70bc5b2 --- /dev/null +++ b/tools/esp8266/html/h/visualization_html.h @@ -0,0 +1,4 @@ +#ifndef __VISUALIZATION_HTML_H__ +#define __VISUALIZATION_HTML_H__ +const char visualization_html[] PROGMEM = "Index - {DEVICE}

AHOY - {DEVICE}

Every {TS}seconds the values are updated

© 2022

Home

AHOY :: {VERSION}

"; +#endif /*__VISUALIZATION_HTML_H__*/ diff --git a/tools/esp8266/html/index.html b/tools/esp8266/html/index.html index f0d2ffa8..d72ae6f3 100644 --- a/tools/esp8266/html/index.html +++ b/tools/esp8266/html/index.html @@ -6,10 +6,8 @@