Browse Source

0.8.39

* fix MqTT dis_night_comm in the morning #1309
* seperated offset for sunrise and sunset #1308
pull/1315/head
lumapu 9 months ago
parent
commit
2cda39c9f9
  1. 4
      src/CHANGES.md
  2. 21
      src/app.cpp
  3. 19
      src/config/settings.h
  4. 4
      src/defines.h
  5. 10
      src/publisher/pubMqtt.h
  6. 8
      src/web/RestApi.h
  7. 38
      src/web/html/index.html
  8. 14
      src/web/html/setup.html
  9. 8
      src/web/web.h

4
src/CHANGES.md

@ -1,5 +1,9 @@
# Development Changes # 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 ## 0.8.38 - 2023-12-31
* fix Grid-Profile JSON #1304 * fix Grid-Profile JSON #1304

21
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 // 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 if (mSunrise == 0) // on boot/reboot calc sun values for current time
ah::calculateSunriseSunset(mTimestamp, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset); 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); ah::calculateSunriseSunset(mTimestamp + 86400, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset);
tickIVCommunication(); 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"); onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig, "Sunri");
if (mMqttEnabled) if (mMqttEnabled) {
tickSun(); 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 iv->commEnabled = !iv->config->disNightCom; // if sun.disNightCom is false, communication is always on
if (!iv->commEnabled) { // inverter communication only during the day 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 if (mTimestamp < (mSunrise - mConfig->sun.offsetSecMorning)) { // current time is before communication start, set next trigger to communication start
nxtTrig = mSunrise - mConfig->sun.offsetSec; nxtTrig = mSunrise - mConfig->sun.offsetSecMorning;
} else { } 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; nxtTrig = 0;
} else { // current time lies within communication start/stop time, set next trigger to communication stop } else { // current time lies within communication start/stop time, set next trigger to communication stop
iv->commEnabled = true; iv->commEnabled = true;
nxtTrig = mSunset + mConfig->sun.offsetSec; nxtTrig = mSunset + mConfig->sun.offsetSecEvening;
} }
} }
if (nxtTrig != 0) if (nxtTrig != 0)
@ -279,7 +282,7 @@ void app::tickIVCommunication(void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void app::tickSun(void) { void app::tickSun(void) {
// only used and enabled by MQTT (see setup()) // 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 once(std::bind(&app::tickSun, this), 1, "mqSun"); // MQTT not connected, retry
} }

19
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 // 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 * https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#flash-layout
* */ * */
#define CONFIG_VERSION 7 #define CONFIG_VERSION 8
#define PROT_MASK_INDEX 0x0001 #define PROT_MASK_INDEX 0x0001
@ -106,7 +106,8 @@ typedef struct {
typedef struct { typedef struct {
float lat; float lat;
float lon; float lon;
uint16_t offsetSec; uint16_t offsetSecMorning;
uint16_t offsetSecEvening;
} cfgSun_t; } cfgSun_t;
typedef struct { typedef struct {
@ -420,7 +421,8 @@ class settings {
mCfg.sun.lat = 0.0; mCfg.sun.lat = 0.0;
mCfg.sun.lon = 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.showIv = false;
mCfg.serial.debug = false; mCfg.serial.debug = false;
@ -496,6 +498,9 @@ class settings {
if(mCfg.configVersion < 7) { if(mCfg.configVersion < 7) {
mCfg.led.luminance = 255; mCfg.led.luminance = 255;
} }
if(mCfg.configVersion < 8) {
mCfg.sun.offsetSecEvening = mCfg.sun.offsetSecMorning;
}
} }
} }
@ -625,11 +630,13 @@ class settings {
if(set) { if(set) {
obj[F("lat")] = mCfg.sun.lat; obj[F("lat")] = mCfg.sun.lat;
obj[F("lon")] = mCfg.sun.lon; 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 { } else {
getVal<float>(obj, F("lat"), &mCfg.sun.lat); getVal<float>(obj, F("lat"), &mCfg.sun.lat);
getVal<float>(obj, F("lon"), &mCfg.sun.lon); getVal<float>(obj, F("lon"), &mCfg.sun.lon);
getVal<uint16_t>(obj, F("offs"), &mCfg.sun.offsetSec); getVal<uint16_t>(obj, F("offs"), &mCfg.sun.offsetSecMorning);
getVal<uint16_t>(obj, F("offsEve"), &mCfg.sun.offsetSecEvening);
} }
} }

4
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 // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -13,7 +13,7 @@
//------------------------------------- //-------------------------------------
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 8 #define VERSION_MINOR 8
#define VERSION_PATCH 38 #define VERSION_PATCH 39
//------------------------------------- //-------------------------------------
typedef struct { typedef struct {

10
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 // Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -134,14 +134,14 @@ class PubMqtt {
#endif #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()) if (!mClient.connected())
return false; return false;
publish(subtopics[MQTT_SUNRISE], String(sunrise).c_str(), true); publish(subtopics[MQTT_SUNRISE], String(sunrise).c_str(), true);
publish(subtopics[MQTT_SUNSET], String(sunset).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_START], String(sunrise - offsM).c_str(), true);
publish(subtopics[MQTT_COMM_STOP], String(sunset + offs).c_str(), true); publish(subtopics[MQTT_COMM_STOP], String(sunset + offsE).c_str(), true);
Inverter<> *iv; Inverter<> *iv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
@ -155,7 +155,7 @@ class PubMqtt {
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "comm_disabled"); 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; return true;
} }

8
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/ // Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -600,7 +600,8 @@ class RestApi {
void getSun(JsonObject obj) { void getSun(JsonObject obj) {
obj[F("lat")] = mConfig->sun.lat ? String(mConfig->sun.lat, 5) : ""; obj[F("lat")] = mConfig->sun.lat ? String(mConfig->sun.lat, 5) : "";
obj[F("lon")] = mConfig->sun.lat ? String(mConfig->sun.lon, 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) { void getPinout(JsonObject obj) {
@ -688,7 +689,8 @@ class RestApi {
obj[F("ts_now")] = mApp->getTimestamp(); obj[F("ts_now")] = mApp->getTimestamp();
obj[F("ts_sunrise")] = mApp->getSunrise(); obj[F("ts_sunrise")] = mApp->getSunrise();
obj[F("ts_sunset")] = mApp->getSunset(); obj[F("ts_sunset")] = mApp->getSunset();
obj[F("ts_offset")] = mConfig->sun.offsetSec; obj[F("ts_offsSr")] = mConfig->sun.offsetSecMorning;
obj[F("ts_offsSs")] = mConfig->sun.offsetSecEvening;
JsonArray inv = obj.createNestedArray(F("inverter")); JsonArray inv = obj.createNestedArray(F("inverter"));
Inverter<> *iv; Inverter<> *iv;

38
src/web/html/index.html

@ -45,12 +45,12 @@
function apiCb(obj) { function apiCb(obj) {
var e = document.getElementById("apiResult"); var e = document.getElementById("apiResult");
if(obj["success"]) { if(obj.success) {
e.innerHTML = " command executed"; e.innerHTML = " command executed";
getAjax("/api/index", parse); getAjax("/api/index", parse);
} }
else else
e.innerHTML = " Error: " + obj["error"]; e.innerHTML = " Error: " + obj.error;
} }
function setTime() { function setTime() {
@ -68,9 +68,9 @@
} }
function parseSys(obj) { function parseSys(obj) {
ts = obj["ts_now"]; ts = obj.ts_now;
var date = new Date(obj["ts_now"] * 1000); var date = new Date(obj.ts_now * 1000);
var up = obj["generic"]["ts_uptime"]; var up = obj.generic["ts_uptime"];
var days = parseInt(up / 86400) % 365; var days = parseInt(up / 86400) % 365;
var hrs = parseInt(up / 3600) % 24; var hrs = parseInt(up / 3600) % 24;
var min = parseInt(up / 60) % 60; var min = parseInt(up / 60) % 60;
@ -83,8 +83,8 @@
+ ("0"+min).substr(-2) + ":" + ("0"+min).substr(-2) + ":"
+ ("0"+sec).substr(-2); + ("0"+sec).substr(-2);
var dSpan = document.getElementById("date"); var dSpan = document.getElementById("date");
if(0 != obj["ts_now"]) { if(0 != obj.ts_now) {
if(obj["ts_now"] < 1680000000) if(obj.ts_now < 1680000000)
setTime(); setTime();
else else
dSpan.innerHTML = toIsoDateStr(date); dSpan.innerHTML = toIsoDateStr(date);
@ -98,18 +98,18 @@
e.addEventListener("click", setTime); e.addEventListener("click", setTime);
} }
if(obj["disNightComm"]) { if(obj.disNightComm) {
if(((obj["ts_sunrise"] - obj["ts_offset"]) < obj["ts_now"]) if(((obj.ts_sunrise - obj.ts_offsSr) < obj.ts_now)
&& ((obj["ts_sunset"] + obj["ts_offset"]) > 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_offset"]) * 1000).toLocaleString('de-DE')); commInfo = "Polling inverter(s), will pause at sunset " + (new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE'));
} }
else { else {
commInfo = "Night time, inverter polling disabled, "; commInfo = "Night time, inverter polling disabled, ";
if(obj["ts_now"] > (obj["ts_sunrise"] - obj["ts_offset"])) { if(obj.ts_now > (obj.ts_sunrise - obj.ts_offsSr)) {
commInfo += "paused at " + (new Date((obj["ts_sunset"] + obj["ts_offset"]) * 1000).toLocaleString('de-DE')); commInfo += "paused at " + (new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE'));
} }
else { 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) { function parse(obj) {
if(null != obj) { if(null != obj) {
if(exeOnce) if(exeOnce)
parseNav(obj["generic"]); parseNav(obj.generic);
parseGeneric(obj["generic"]); parseGeneric(obj.generic);
parseSys(obj); parseSys(obj);
parseIv(obj["inverter"], obj.ts_now); parseIv(obj.inverter, obj.ts_now);
parseWarn(obj["warnings"]); parseWarn(obj.warnings);
if(exeOnce) { if(exeOnce) {
window.setInterval("tick()", 1000); window.setInterval("tick()", 1000);
exeOnce = false; exeOnce = false;
@ -210,7 +210,7 @@
} }
function parseRelease(obj) { function parseRelease(obj) {
release = obj["name"].substring(6); release = obj.name.substring(6);
getAjax("/api/index", parse); getAjax("/api/index", parse);
} }

14
src/web/html/setup.html

@ -227,8 +227,12 @@
<div class="col-12 col-sm-9"><input type="number" name="sunLon" step="any"/></div> <div class="col-12 col-sm-9"><input type="number" name="sunLon" step="any"/></div>
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-12 col-sm-3 my-2">Offset (pre sunrise, post sunset)</div> <div class="col-12 col-sm-3 my-2">Offset (sunrise)</div>
<div class="col-12 col-sm-9"><select name="sunOffs"></select></div> <div class="col-12 col-sm-9"><select name="sunOffsSr"></select></div>
</div>
<div class="row mb-3">
<div class="col-12 col-sm-3 my-2">Offset (sunset)</div>
<div class="col-12 col-sm-9"><select name="sunOffsSs"></select></div>
</div> </div>
</fieldset> </fieldset>
</div> </div>
@ -889,9 +893,11 @@
function parseSun(obj) { function parseSun(obj) {
document.getElementsByName("sunLat")[0].value = obj["lat"]; document.getElementsByName("sunLat")[0].value = obj["lat"];
document.getElementsByName("sunLon")[0].value = obj["lon"]; document.getElementsByName("sunLon")[0].value = obj["lon"];
const sel = document.getElementsByName("sunOffs")[0]; for(p of [["sunOffsSr", "offsSr"], ["sunOffsSs", "offsSs"]]) {
const sel = document.getElementsByName(p[0])[0];
for(var i = 0; i <= 60; i++) { for(var i = 0; i <= 60; i++) {
sel.appendChild(opt(i, i + " minutes", (i == (obj["offs"] / 60)))); sel.appendChild(opt(i, i + " minutes", (i == (obj[p[1]] / 60))));
}
} }
} }

8
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 // 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") == "")) { if (request->arg("sunLat") == "" || (request->arg("sunLon") == "")) {
mConfig->sun.lat = 0.0; mConfig->sun.lat = 0.0;
mConfig->sun.lon = 0.0; mConfig->sun.lon = 0.0;
mConfig->sun.offsetSec = 0; mConfig->sun.offsetSecMorning = 0;
mConfig->sun.offsetSecEvening = 0;
} else { } else {
mConfig->sun.lat = request->arg("sunLat").toFloat(); mConfig->sun.lat = request->arg("sunLat").toFloat();
mConfig->sun.lon = request->arg("sunLon").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 // mqtt

Loading…
Cancel
Save