From c1479068341492c9297032043e640e1af5241410 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sun, 18 Jun 2023 00:20:27 +0200 Subject: [PATCH] 0.7.6 * fix display of hidden SSID checkbox * changed yield correction data type to `double`, now decimal places are supported * corrected name of 0.91" display in settings * attempt to fix MqTT zero values only if setting is there #980, #957 * made AP password configurable #951 * added option to start without time-sync, eg. for AP-only-mode #951 --- src/CHANGES.md | 8 ++++++++ src/app.cpp | 15 ++------------- src/config/settings.h | 10 +++++++++- src/defines.h | 2 +- src/publisher/pubMqtt.h | 7 +++++-- src/publisher/pubMqttIvData.h | 35 ++++++++++++++++------------------- src/utils/scheduler.h | 4 ++-- src/web/RestApi.h | 2 ++ src/web/html/index.html | 8 ++++++-- src/web/html/setup.html | 21 ++++++++++++++++----- src/web/html/style.css | 5 +++++ src/web/web.h | 3 +++ src/wifi/ahoywifi.cpp | 4 ++-- 13 files changed, 77 insertions(+), 47 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 4815879a..ed280f46 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,13 @@ # Development Changes +## 0.7.6 - 2023-06-17 +* fix display of hidden SSID checkbox +* changed yield correction data type to `double`, now decimal places are supported +* corrected name of 0.91" display in settings +* attempt to fix MqTT zero values only if setting is there #980, #957 +* made AP password configurable #951 +* added option to start without time-sync, eg. for AP-only-mode #951 + ## 0.7.5 - 2023-06-16 * fix yield day reset on midnight #957 * improved tickers in `app.cpp` diff --git a/src/app.cpp b/src/app.cpp index bd060425..fc5f6b0f 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -17,12 +17,12 @@ void app::setup() { while (!Serial) yield(); - ah::Scheduler::setup(); resetSystem(); mSettings.setup(); mSettings.getPtr(mConfig); + ah::Scheduler::setup(mConfig->inst.startWithoutTime); DPRINT(DBG_INFO, F("Settings valid: ")); if (mSettings.getValid()) DBGPRINTLN(F("true")); @@ -67,10 +67,6 @@ void app::setup() { mHmsPayload.enableSerialDebug(mConfig->serial.debug); mHmsPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); #endif - /*DBGPRINTLN("--- after payload"); - DBGPRINTLN(String(ESP.getFreeHeap())); - DBGPRINTLN(String(ESP.getHeapFragmentation())); - DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/ if(mConfig->nrf.enabled) { if (!mNrfRadio.isChipConnected()) @@ -101,12 +97,6 @@ void app::setup() { mPubSerial.setup(mConfig, &mSys, &mTimestamp); regularTickers(); - - - // DBGPRINTLN("--- end setup"); - // DBGPRINTLN(String(ESP.getFreeHeap())); - // DBGPRINTLN(String(ESP.getHeapFragmentation())); - // DBGPRINTLN(String(ESP.getMaxFreeBlockSize())); } //----------------------------------------------------------------------------- @@ -253,7 +243,6 @@ void app::tickNtpUpdate(void) { } // immediately start communicating - // @TODO: leads to reboot loops? not sure #674 if (isOK && mSendFirst) { mSendFirst = false; once(std::bind(&app::tickSend, this), 2, "senOn"); @@ -439,7 +428,7 @@ void app:: zeroIvValues(bool checkAvail, bool skipYieldDay) { } if(changed) { - if(mMqttEnabled) + if(mMqttEnabled && !skipYieldDay) mMqtt.setZeroValuesEnable(); payloadEventListener(RealTimeRunData_Debug, NULL); } diff --git a/src/config/settings.h b/src/config/settings.h index 610b2fef..2fdcab0e 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -68,6 +68,7 @@ typedef struct { // wifi char stationSsid[SSID_LEN]; char stationPwd[PWD_LEN]; + char apPwd[PWD_LEN]; bool isHidden; cfgIp_t ip; @@ -131,7 +132,7 @@ typedef struct { char name[MAX_NAME_LENGTH]; serial_u serial; uint16_t chMaxPwr[6]; - int32_t yieldCor[6]; // signed YieldTotal correction value + double yieldCor[6]; // signed YieldTotal correction value char chName[6][MAX_NAME_LENGTH]; } cfgIv_t; @@ -142,6 +143,7 @@ typedef struct { bool rstYieldMidNight; bool rstValsNotAvail; bool rstValsCommStop; + bool startWithoutTime; } cfgInst_t; typedef struct { @@ -360,6 +362,7 @@ class settings { else { snprintf(mCfg.sys.stationSsid, SSID_LEN, FB_WIFI_SSID); snprintf(mCfg.sys.stationPwd, PWD_LEN, FB_WIFI_PWD); + snprintf(mCfg.sys.apPwd, PWD_LEN, WIFI_AP_PWD); mCfg.sys.isHidden = false; } @@ -404,6 +407,7 @@ class settings { mCfg.inst.rstYieldMidNight = false; mCfg.inst.rstValsNotAvail = false; mCfg.inst.rstValsCommStop = false; + mCfg.inst.startWithoutTime = false; mCfg.led.led0 = DEF_PIN_OFF; mCfg.led.led1 = DEF_PIN_OFF; @@ -428,6 +432,7 @@ class settings { char buf[16]; obj[F("ssid")] = mCfg.sys.stationSsid; obj[F("pwd")] = mCfg.sys.stationPwd; + obj[F("ap_pwd")] = mCfg.sys.apPwd; obj[F("hidd")] = (bool) mCfg.sys.isHidden; obj[F("dev")] = mCfg.sys.deviceName; obj[F("adm")] = mCfg.sys.adminPwd; @@ -441,6 +446,7 @@ class settings { } else { getChar(obj, F("ssid"), mCfg.sys.stationSsid, SSID_LEN); getChar(obj, F("pwd"), mCfg.sys.stationPwd, PWD_LEN); + getChar(obj, F("ap_pwd"), mCfg.sys.apPwd, PWD_LEN); getVal(obj, F("hidd"), &mCfg.sys.isHidden); getChar(obj, F("dev"), mCfg.sys.deviceName, DEVNAME_LEN); getChar(obj, F("adm"), mCfg.sys.adminPwd, PWD_LEN); @@ -617,12 +623,14 @@ class settings { obj[F("rstMidNight")] = (bool)mCfg.inst.rstYieldMidNight; obj[F("rstNotAvail")] = (bool)mCfg.inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mCfg.inst.rstValsCommStop; + obj[F("strtWthtTime")] = (bool)mCfg.inst.startWithoutTime; } else { getVal(obj, F("en"), &mCfg.inst.enabled); getVal(obj, F("rstMidNight"), &mCfg.inst.rstYieldMidNight); getVal(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail); getVal(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop); + getVal(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime); } JsonArray ivArr; diff --git a/src/defines.h b/src/defines.h index da7fffc2..caa556eb 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 5 +#define VERSION_PATCH 6 //------------------------------------- typedef struct { diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index d04416d2..c6723396 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -52,6 +52,7 @@ class PubMqtt { memset(mLastIvState, MQTT_STATUS_NOT_AVAIL_NOT_PROD, MAX_NUM_INVERTERS); memset(mIvLastRTRpub, 0, MAX_NUM_INVERTERS * 4); mLastAnyAvail = false; + mZeroValues = false; } ~PubMqtt() { } @@ -241,7 +242,7 @@ class PubMqtt { } void setZeroValuesEnable(void) { - mSendIvData.setZeroValuesEnable(); + mZeroValues = true; } private: @@ -574,7 +575,8 @@ class PubMqtt { if(mSendList.empty()) return; - mSendIvData.start(); + mSendIvData.start(mZeroValues); + mZeroValues = false; mLastAnyAvail = anyAvail; } @@ -593,6 +595,7 @@ class PubMqtt { std::queue mAlarmList; subscriptionCb mSubscriptionCb; bool mLastAnyAvail; + bool mZeroValues; uint8_t mLastIvState[MAX_NUM_INVERTERS]; uint32_t mIvLastRTRpub[MAX_NUM_INVERTERS]; uint16_t mIntervalTimeout; diff --git a/src/publisher/pubMqttIvData.h b/src/publisher/pubMqttIvData.h index 9f8ff318..eb1bdb1c 100644 --- a/src/publisher/pubMqttIvData.h +++ b/src/publisher/pubMqttIvData.h @@ -43,10 +43,11 @@ class PubMqttIvData { yield(); } - bool start(void) { + bool start(bool zeroValues = false) { if(IDLE != mState) return false; + mZeroValues = zeroValues; mRTRDataHasBeenSent = false; mState = START; return true; @@ -56,10 +57,6 @@ class PubMqttIvData { mPublish = cb; } - void setZeroValuesEnable(void) { - mZeroValues = true; - } - private: enum State {IDLE, START, FIND_NXT_IV, SEND_DATA, SEND_TOTALS, NUM_STATES}; typedef void (PubMqttIvData::*StateFunction)(); @@ -100,8 +97,11 @@ class PubMqttIvData { mLastIvId++; mPos = 0; - if(found) + if(found) { mState = SEND_DATA; + if(!mIv->isAvailable(*mUtcTimestamp)) + mSendTotals = false; // avoid send total values on not producing, because the sum of values is not built + } else if(mSendTotals) mState = SEND_TOTALS; else { @@ -122,19 +122,16 @@ class PubMqttIvData { if(mPos < rec->length) { bool retained = false; if (mCmd == RealTimeRunData_Debug) { - switch (rec->assign[mPos].fieldId) { - case FLD_YT: - case FLD_YD: - if(!mZeroValues) { - if ((rec->assign[mPos].ch == CH0) && (!mIv->isProducing(*mUtcTimestamp))) { // avoids returns to 0 on restart - mPos++; - if(!mIv->isAvailable(*mUtcTimestamp)) - mSendTotals = false; // avoid send total values on not producing, because the sum of values is no built - return; - } + if(FLD_YT == rec->assign[mPos].fieldId) + retained = true; + else if(FLD_YD == rec->assign[mPos].fieldId) { + if(!mZeroValues) { + if ((rec->assign[mPos].ch == CH0) && (!mIv->isProducing(*mUtcTimestamp))) { // avoids returns to 0 on restart + mPos++; + return; } - retained = true; - break; + } + retained = true; } // calculate total values for RealTimeRunData_Debug @@ -221,7 +218,7 @@ class PubMqttIvData { char mSubTopic[32 + MAX_NAME_LENGTH + 1]; char mVal[40]; - bool mZeroValues; + bool mZeroValues; // makes sure that yield day is sent even if no inverter is online std::queue *mSendList; }; diff --git a/src/utils/scheduler.h b/src/utils/scheduler.h index 50a46826..954ae18a 100644 --- a/src/utils/scheduler.h +++ b/src/utils/scheduler.h @@ -31,9 +31,9 @@ namespace ah { public: Scheduler() {} - void setup() { + void setup(bool directStart) { mUptime = 0; - mTimestamp = 0; + mTimestamp = (directStart) ? 1 : 0; mMax = 0; mPrevMillis = millis(); resetTicker(); diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 35c22e44..e2fefd86 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -206,6 +206,7 @@ class RestApi { void getSysInfo(AsyncWebServerRequest *request, JsonObject obj) { obj[F("ssid")] = mConfig->sys.stationSsid; + obj[F("ap_pwd")] = mConfig->sys.apPwd; obj[F("hidd")] = mConfig->sys.isHidden; obj[F("device_name")] = mConfig->sys.deviceName; obj[F("dark_mode")] = (bool)mConfig->sys.darkMode; @@ -326,6 +327,7 @@ class RestApi { obj[F("rstMid")] = (bool)mConfig->inst.rstYieldMidNight; obj[F("rstNAvail")] = (bool)mConfig->inst.rstValsNotAvail; obj[F("rstComStop")] = (bool)mConfig->inst.rstValsCommStop; + obj[F("strtWthtTm")] = (bool)mConfig->inst.startWithoutTime; } void getInverter(JsonObject obj, uint8_t id) { diff --git a/src/web/html/index.html b/src/web/html/index.html index 72537e5e..2799598f 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -88,8 +88,12 @@ + ("0"+min).substr(-2) + ":" + ("0"+sec).substr(-2); var dSpan = document.getElementById("date"); - if(0 != obj["ts_now"]) - dSpan.innerHTML = date.toLocaleString('de-DE'); + if(0 != obj["ts_now"]) { + if(obj["ts_now"] < 1680000000) + setTime(); + else + dSpan.innerHTML = date.toLocaleString('de-DE'); + } else { dSpan.innerHTML = ""; var e = inp("set", "sync from browser", 0, ["btn"], "set", "button"); diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 01d481c2..c968e390 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -55,6 +55,12 @@
WiFi + +
+
AP Password (min. length: 8)
+
+
+

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

@@ -72,11 +78,11 @@
SSID
-
+
-
hidden SSID
-
+
SSID is hidden
+
Password
@@ -162,6 +168,10 @@
Reset values when inverter status is 'not available'
+
+
Start without time sync (useful in AP-Only-Mode)
+
+
@@ -616,10 +626,11 @@ document.getElementsByName(i[0])[0].value = obj[i[1]]; for(var i of [["Mid", "rstMid"], ["ComStop", "rstComStop"], ["NotAvail", "rstNAvail"]]) document.getElementsByName("invRst"+i[0])[0].checked = obj[i[1]]; + document.getElementsByName("strtWthtTm")[0].checked = obj["strtWthtTm"]; } function parseSys(obj) { - for(var i of [["device", "device_name"], ["ssid", "ssid"]]) + for(var i of [["device", "device_name"], ["ssid", "ssid"], ["ap_pwd", "ap_pwd"]]) document.getElementsByName(i[0])[0].value = obj[i[1]]; document.getElementsByName("hidd")[0].checked = obj["hidd"]; document.getElementsByName("darkMode")[0].checked = obj["dark_mode"]; @@ -789,7 +800,7 @@ ); } - var opts = [[0, "None"], [1, "SSD1306 0.96\" 128X64"], [2, "SH1106 1.3\""], [3, "Nokia5110"], [4, "SSD1306 0.96\" 128X32"]]; + var opts = [[0, "None"], [1, "SSD1306 0.96\" 128X64"], [2, "SH1106 1.3\""], [3, "Nokia5110"], [4, "SSD1306 0.91\" 128X32"]]; if("ESP32" == type) opts.push([10, "ePaper"]); var dispType = sel("disp_typ", opts, obj["disp_typ"]); diff --git a/src/web/html/style.css b/src/web/html/style.css index bb231881..fdbf5aa7 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -475,6 +475,11 @@ input[type=text], input[type=password], select, input[type=number] { color: var(--fg); } +input:invalid { + border: 2px solid #f00 !important; + background-color: #400 !important; +} + input.sh { max-width: 150px !important; margin-right: 10px; diff --git a/src/web/web.h b/src/web/web.h index 0b7ca7de..92b024ac 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -448,6 +448,8 @@ class Web { request->arg("ssid").toCharArray(mConfig->sys.stationSsid, SSID_LEN); if (request->arg("pwd") != "{PWD}") request->arg("pwd").toCharArray(mConfig->sys.stationPwd, PWD_LEN); + if (request->arg("ap_pwd") != "") + request->arg("ap_pwd").toCharArray(mConfig->sys.apPwd, PWD_LEN); mConfig->sys.isHidden = (request->arg("hidd") == "on"); if (request->arg("device") != "") request->arg("device").toCharArray(mConfig->sys.deviceName, DEVNAME_LEN); @@ -521,6 +523,7 @@ class Web { mConfig->inst.rstYieldMidNight = (request->arg("invRstMid") == "on"); mConfig->inst.rstValsCommStop = (request->arg("invRstComStop") == "on"); mConfig->inst.rstValsNotAvail = (request->arg("invRstNotAvail") == "on"); + mConfig->inst.startWithoutTime = (request->arg("strtWthtTm") == "on"); // pinout uint8_t pin; diff --git a/src/wifi/ahoywifi.cpp b/src/wifi/ahoywifi.cpp index 6def5282..933ffff7 100644 --- a/src/wifi/ahoywifi.cpp +++ b/src/wifi/ahoywifi.cpp @@ -170,7 +170,7 @@ void ahoywifi::setupAp(void) { DBGPRINT(F("\n---------\nAP MODE\nSSID: ")); DBGPRINTLN(WIFI_AP_SSID); DBGPRINT(F("PWD: ")); - DBGPRINTLN(WIFI_AP_PWD); + DBGPRINTLN(mConfig->sys.apPwd); DBGPRINT(F("IP Address: http://")); DBGPRINTLN(mApIp.toString()); DBGPRINTLN(F("---------\n")); @@ -180,7 +180,7 @@ void ahoywifi::setupAp(void) { WiFi.mode(WIFI_AP_STA); WiFi.softAPConfig(mApIp, mApIp, IPAddress(255, 255, 255, 0)); - WiFi.softAP(WIFI_AP_SSID, WIFI_AP_PWD); + WiFi.softAP(WIFI_AP_SSID, mConfig->sys.apPwd); }