mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-30 09:16:11 +02:00
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
This commit is contained in:
parent
76f01bbe95
commit
c147906834
13 changed files with 77 additions and 47 deletions
|
@ -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`
|
||||
|
|
15
src/app.cpp
15
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);
|
||||
}
|
||||
|
|
|
@ -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<bool>(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<bool>(obj, F("en"), &mCfg.inst.enabled);
|
||||
getVal<bool>(obj, F("rstMidNight"), &mCfg.inst.rstYieldMidNight);
|
||||
getVal<bool>(obj, F("rstNotAvail"), &mCfg.inst.rstValsNotAvail);
|
||||
getVal<bool>(obj, F("rstComStop"), &mCfg.inst.rstValsCommStop);
|
||||
getVal<bool>(obj, F("strtWthtTime"), &mCfg.inst.startWithoutTime);
|
||||
}
|
||||
|
||||
JsonArray ivArr;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 7
|
||||
#define VERSION_PATCH 5
|
||||
#define VERSION_PATCH 6
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -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<alarm_t> mAlarmList;
|
||||
subscriptionCb mSubscriptionCb;
|
||||
bool mLastAnyAvail;
|
||||
bool mZeroValues;
|
||||
uint8_t mLastIvState[MAX_NUM_INVERTERS];
|
||||
uint32_t mIvLastRTRpub[MAX_NUM_INVERTERS];
|
||||
uint16_t mIntervalTimeout;
|
||||
|
|
|
@ -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(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++;
|
||||
if(!mIv->isAvailable(*mUtcTimestamp))
|
||||
mSendTotals = false; // avoid send total values on not producing, because the sum of values is no built
|
||||
return;
|
||||
}
|
||||
}
|
||||
retained = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 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<sendListCmdIv> *mSendList;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -88,8 +88,12 @@
|
|||
+ ("0"+min).substr(-2) + ":"
|
||||
+ ("0"+sec).substr(-2);
|
||||
var dSpan = document.getElementById("date");
|
||||
if(0 != obj["ts_now"])
|
||||
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");
|
||||
|
|
|
@ -55,6 +55,12 @@
|
|||
<div class="s_content">
|
||||
<fieldset class="mb-2">
|
||||
<legend class="des">WiFi</legend>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 col-sm-3 my-2">AP Password (min. length: 8)</div>
|
||||
<div class="col-12 col-sm-9"><input type="text" name="ap_pwd" minlength="8" /></div>
|
||||
</div>
|
||||
|
||||
<p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.</p>
|
||||
|
||||
<div class="row mb-3">
|
||||
|
@ -72,11 +78,11 @@
|
|||
</div>
|
||||
<div class="row mb-2 mb-sm-3">
|
||||
<div class="col-12 col-sm-3 my-2">SSID</div>
|
||||
<div class="col-12 col-sm-9"><input type="text" name="ssid"/><div>
|
||||
<div class="col-12 col-sm-9"><input type="text" name="ssid"/></div>
|
||||
</div>
|
||||
<div class="row mb-2 mb-sm-3">
|
||||
<div class="col-12 col-sm-3 my-2">hidden SSID</div>
|
||||
<div class="col-12 col-sm-9"><input type="checkbox" name="hidd"/><div>
|
||||
<div class="col-12 col-sm-3">SSID is hidden</div>
|
||||
<div class="col-12 col-sm-9"><input type="checkbox" name="hidd"/></div>
|
||||
</div>
|
||||
<div class="row mb-2 mb-sm-3">
|
||||
<div class="col-12 col-sm-3 my-2">Password</div>
|
||||
|
@ -162,6 +168,10 @@
|
|||
<div class="col-8 col-sm-3">Reset values when inverter status is 'not available'</div>
|
||||
<div class="col-4 col-sm-9"><input type="checkbox" name="invRstNotAvail"/></div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-8 col-sm-3">Start without time sync (useful in AP-Only-Mode)</div>
|
||||
<div class="col-4 col-sm-9"><input type="checkbox" name="strtWthtTm"/></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
@ -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"]);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue