diff --git a/src/CHANGES.md b/src/CHANGES.md index f6e7445e..66056890 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.8.39 - 2024-01-01 +* fix MqTT dis_night_comm in the morning #1309 +* seperated offset for sunrise and sunset #1308 + ## 0.8.38 - 2023-12-31 * fix Grid-Profile JSON #1304 diff --git a/src/app.cpp b/src/app.cpp index 0bba14da..8e70778a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de +// 2024 Ahoy, https://ahoydtu.de // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -226,15 +226,18 @@ void app::tickCalcSunrise(void) { if (mSunrise == 0) // on boot/reboot calc sun values for current time ah::calculateSunriseSunset(mTimestamp, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset); - if (mTimestamp > (mSunset + mConfig->sun.offsetSec)) // current time is past communication stop, calc sun values for next day + if (mTimestamp > (mSunset + mConfig->sun.offsetSecEvening)) // current time is past communication stop, calc sun values for next day ah::calculateSunriseSunset(mTimestamp + 86400, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset); tickIVCommunication(); - uint32_t nxtTrig = mSunset + mConfig->sun.offsetSec + 60; // set next trigger to communication stop, +60 for safety that it is certain past communication stop + uint32_t nxtTrig = mSunset + mConfig->sun.offsetSecEvening + 60; // set next trigger to communication stop, +60 for safety that it is certain past communication stop onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig, "Sunri"); - if (mMqttEnabled) + if (mMqttEnabled) { tickSun(); + nxtTrig = mSunrise - mConfig->sun.offsetSecMorning + 1; // one second safety to trigger correctly + onceAt(std::bind(&app::tickSun, this), nxtTrig, "mqSr"); // trigger on sunrise to update 'dis_night_comm' + } } //----------------------------------------------------------------------------- @@ -251,14 +254,14 @@ void app::tickIVCommunication(void) { iv->commEnabled = !iv->config->disNightCom; // if sun.disNightCom is false, communication is always on if (!iv->commEnabled) { // inverter communication only during the day - if (mTimestamp < (mSunrise - mConfig->sun.offsetSec)) { // current time is before communication start, set next trigger to communication start - nxtTrig = mSunrise - mConfig->sun.offsetSec; + if (mTimestamp < (mSunrise - mConfig->sun.offsetSecMorning)) { // current time is before communication start, set next trigger to communication start + nxtTrig = mSunrise - mConfig->sun.offsetSecMorning; } else { - if (mTimestamp >= (mSunset + mConfig->sun.offsetSec)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise + if (mTimestamp >= (mSunset + mConfig->sun.offsetSecEvening)) { // current time is past communication stop, nothing to do. Next update will be done at midnight by tickCalcSunrise nxtTrig = 0; } else { // current time lies within communication start/stop time, set next trigger to communication stop iv->commEnabled = true; - nxtTrig = mSunset + mConfig->sun.offsetSec; + nxtTrig = mSunset + mConfig->sun.offsetSecEvening; } } if (nxtTrig != 0) @@ -279,7 +282,7 @@ void app::tickIVCommunication(void) { //----------------------------------------------------------------------------- void app::tickSun(void) { // only used and enabled by MQTT (see setup()) - if (!mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec)) + if (!mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSecMorning, mConfig->sun.offsetSecEvening)) once(std::bind(&app::tickSun, this), 1, "mqSun"); // MQTT not connected, retry } diff --git a/src/config/settings.h b/src/config/settings.h index fe2ad1b0..c493eb1a 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de +// 2024 Ahoy, https://ahoydtu.de // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -30,7 +30,7 @@ * https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout * */ -#define CONFIG_VERSION 7 +#define CONFIG_VERSION 8 #define PROT_MASK_INDEX 0x0001 @@ -106,7 +106,8 @@ typedef struct { typedef struct { float lat; float lon; - uint16_t offsetSec; + uint16_t offsetSecMorning; + uint16_t offsetSecEvening; } cfgSun_t; typedef struct { @@ -420,7 +421,8 @@ class settings { mCfg.sun.lat = 0.0; mCfg.sun.lon = 0.0; - mCfg.sun.offsetSec = 0; + mCfg.sun.offsetSecMorning = 0; + mCfg.sun.offsetSecEvening = 0; mCfg.serial.showIv = false; mCfg.serial.debug = false; @@ -496,6 +498,9 @@ class settings { if(mCfg.configVersion < 7) { mCfg.led.luminance = 255; } + if(mCfg.configVersion < 8) { + mCfg.sun.offsetSecEvening = mCfg.sun.offsetSecMorning; + } } } @@ -625,11 +630,13 @@ class settings { if(set) { obj[F("lat")] = mCfg.sun.lat; obj[F("lon")] = mCfg.sun.lon; - obj[F("offs")] = mCfg.sun.offsetSec; + obj[F("offs")] = mCfg.sun.offsetSecMorning; + obj[F("offsEve")] = mCfg.sun.offsetSecEvening; } else { getVal(obj, F("lat"), &mCfg.sun.lat); getVal(obj, F("lon"), &mCfg.sun.lon); - getVal(obj, F("offs"), &mCfg.sun.offsetSec); + getVal(obj, F("offs"), &mCfg.sun.offsetSecMorning); + getVal(obj, F("offsEve"), &mCfg.sun.offsetSecEvening); } } diff --git a/src/defines.h b/src/defines.h index 05cdc5e0..ad321921 100644 --- a/src/defines.h +++ b/src/defines.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de +// 2024 Ahoy, https://ahoydtu.de // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 38 +#define VERSION_PATCH 39 //------------------------------------- typedef struct { diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index e062439c..9834f29a 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de +// 2024 Ahoy, https://ahoydtu.de // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -134,14 +134,14 @@ class PubMqtt { #endif } - bool tickerSun(uint32_t sunrise, uint32_t sunset, uint32_t offs) { + bool tickerSun(uint32_t sunrise, uint32_t sunset, uint16_t offsM, uint16_t offsE) { if (!mClient.connected()) return false; publish(subtopics[MQTT_SUNRISE], String(sunrise).c_str(), true); publish(subtopics[MQTT_SUNSET], String(sunset).c_str(), true); - publish(subtopics[MQTT_COMM_START], String(sunrise - offs).c_str(), true); - publish(subtopics[MQTT_COMM_STOP], String(sunset + offs).c_str(), true); + publish(subtopics[MQTT_COMM_START], String(sunrise - offsM).c_str(), true); + publish(subtopics[MQTT_COMM_STOP], String(sunset + offsE).c_str(), true); Inverter<> *iv; for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { @@ -155,7 +155,7 @@ class PubMqtt { snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "comm_disabled"); - publish(mSubTopic, (((*mUtcTimestamp > (sunset + offs)) || (*mUtcTimestamp < (sunrise - offs))) ? dict[STR_TRUE] : dict[STR_FALSE]), true); + publish(mSubTopic, (((*mUtcTimestamp > (sunset + offsE)) || (*mUtcTimestamp < (sunrise - offsM))) ? dict[STR_TRUE] : dict[STR_FALSE]), true); return true; } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index a74f4f14..c920a8e3 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2023 Ahoy, https://ahoydtu.de +// 2024 Ahoy, https://ahoydtu.de // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ //----------------------------------------------------------------------------- @@ -600,7 +600,8 @@ class RestApi { void getSun(JsonObject obj) { obj[F("lat")] = mConfig->sun.lat ? String(mConfig->sun.lat, 5) : ""; obj[F("lon")] = mConfig->sun.lat ? String(mConfig->sun.lon, 5) : ""; - obj[F("offs")] = mConfig->sun.offsetSec; + obj[F("offsSr")] = mConfig->sun.offsetSecMorning; + obj[F("offsSs")] = mConfig->sun.offsetSecEvening; } void getPinout(JsonObject obj) { @@ -685,10 +686,11 @@ class RestApi { void getIndex(AsyncWebServerRequest *request, JsonObject obj) { getGeneric(request, obj.createNestedObject(F("generic"))); - obj[F("ts_now")] = mApp->getTimestamp(); - obj[F("ts_sunrise")] = mApp->getSunrise(); - obj[F("ts_sunset")] = mApp->getSunset(); - obj[F("ts_offset")] = mConfig->sun.offsetSec; + obj[F("ts_now")] = mApp->getTimestamp(); + obj[F("ts_sunrise")] = mApp->getSunrise(); + obj[F("ts_sunset")] = mApp->getSunset(); + obj[F("ts_offsSr")] = mConfig->sun.offsetSecMorning; + obj[F("ts_offsSs")] = mConfig->sun.offsetSecEvening; JsonArray inv = obj.createNestedArray(F("inverter")); Inverter<> *iv; diff --git a/src/web/html/index.html b/src/web/html/index.html index baa70742..3ac72e89 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -45,12 +45,12 @@ function apiCb(obj) { var e = document.getElementById("apiResult"); - if(obj["success"]) { + if(obj.success) { e.innerHTML = " command executed"; getAjax("/api/index", parse); } else - e.innerHTML = " Error: " + obj["error"]; + e.innerHTML = " Error: " + obj.error; } function setTime() { @@ -68,9 +68,9 @@ } function parseSys(obj) { - ts = obj["ts_now"]; - var date = new Date(obj["ts_now"] * 1000); - var up = obj["generic"]["ts_uptime"]; + ts = obj.ts_now; + var date = new Date(obj.ts_now * 1000); + var up = obj.generic["ts_uptime"]; var days = parseInt(up / 86400) % 365; var hrs = parseInt(up / 3600) % 24; var min = parseInt(up / 60) % 60; @@ -83,8 +83,8 @@ + ("0"+min).substr(-2) + ":" + ("0"+sec).substr(-2); var dSpan = document.getElementById("date"); - if(0 != obj["ts_now"]) { - if(obj["ts_now"] < 1680000000) + if(0 != obj.ts_now) { + if(obj.ts_now < 1680000000) setTime(); else dSpan.innerHTML = toIsoDateStr(date); @@ -98,18 +98,18 @@ e.addEventListener("click", setTime); } - if(obj["disNightComm"]) { - if(((obj["ts_sunrise"] - obj["ts_offset"]) < obj["ts_now"]) - && ((obj["ts_sunset"] + obj["ts_offset"]) > obj["ts_now"])) { - commInfo = "Polling inverter(s), will pause at sunset " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); + if(obj.disNightComm) { + if(((obj.ts_sunrise - obj.ts_offsSr) < obj.ts_now) + && ((obj.ts_sunset + obj.ts_offsSs) > obj.ts_now)) { + commInfo = "Polling inverter(s), will pause at sunset " + (new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')); } else { commInfo = "Night time, inverter polling disabled, "; - if(obj["ts_now"] > (obj["ts_sunrise"] - obj["ts_offset"])) { - commInfo += "paused at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); + if(obj.ts_now > (obj.ts_sunrise - obj.ts_offsSr)) { + commInfo += "paused at " + (new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')); } else { - commInfo += "will start polling at " + (new Date((obj["ts_sunrise"] - obj["ts_offset"]) * 1000).toLocaleString('de-DE')); + commInfo += "will start polling at " + (new Date((obj.ts_sunrise - obj.ts_offsSr) * 1000).toLocaleString('de-DE')); } } } @@ -190,11 +190,11 @@ function parse(obj) { if(null != obj) { if(exeOnce) - parseNav(obj["generic"]); - parseGeneric(obj["generic"]); + parseNav(obj.generic); + parseGeneric(obj.generic); parseSys(obj); - parseIv(obj["inverter"], obj.ts_now); - parseWarn(obj["warnings"]); + parseIv(obj.inverter, obj.ts_now); + parseWarn(obj.warnings); if(exeOnce) { window.setInterval("tick()", 1000); exeOnce = false; @@ -210,7 +210,7 @@ } function parseRelease(obj) { - release = obj["name"].substring(6); + release = obj.name.substring(6); getAjax("/api/index", parse); } diff --git a/src/web/html/setup.html b/src/web/html/setup.html index f172f925..aef43dcf 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -227,8 +227,12 @@
-
Offset (pre sunrise, post sunset)
-
+
Offset (sunrise)
+
+
+
+
Offset (sunset)
+
@@ -889,9 +893,11 @@ function parseSun(obj) { document.getElementsByName("sunLat")[0].value = obj["lat"]; document.getElementsByName("sunLon")[0].value = obj["lon"]; - const sel = document.getElementsByName("sunOffs")[0]; - for(var i = 0; i <= 60; i++) { - sel.appendChild(opt(i, i + " minutes", (i == (obj["offs"] / 60)))); + for(p of [["sunOffsSr", "offsSr"], ["sunOffsSs", "offsSs"]]) { + const sel = document.getElementsByName(p[0])[0]; + for(var i = 0; i <= 60; i++) { + sel.appendChild(opt(i, i + " minutes", (i == (obj[p[1]] / 60)))); + } } } diff --git a/src/web/web.h b/src/web/web.h index 1e87547b..d10fa62d 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778 +// 2024 Ahoy, https://www.mikrocontroller.net/topic/525778 // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- @@ -541,11 +541,13 @@ class Web { if (request->arg("sunLat") == "" || (request->arg("sunLon") == "")) { mConfig->sun.lat = 0.0; mConfig->sun.lon = 0.0; - mConfig->sun.offsetSec = 0; + mConfig->sun.offsetSecMorning = 0; + mConfig->sun.offsetSecEvening = 0; } else { mConfig->sun.lat = request->arg("sunLat").toFloat(); mConfig->sun.lon = request->arg("sunLon").toFloat(); - mConfig->sun.offsetSec = request->arg("sunOffs").toInt() * 60; + mConfig->sun.offsetSecMorning = request->arg("sunOffsSr").toInt() * 60; + mConfig->sun.offsetSecEvening = request->arg("sunOffsSs").toInt() * 60; } // mqtt