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. 14
      src/web/RestApi.h
  7. 38
      src/web/html/index.html
  8. 16
      src/web/html/setup.html
  9. 8
      src/web/web.h

4
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

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
//-----------------------------------------------------------------------------
@ -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
}

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
//-----------------------------------------------------------------------------
@ -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<float>(obj, F("lat"), &mCfg.sun.lat);
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
//-----------------------------------------------------------------------------
@ -13,7 +13,7 @@
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 8
#define VERSION_PATCH 38
#define VERSION_PATCH 39
//-------------------------------------
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
//-----------------------------------------------------------------------------
@ -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;
}

14
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;

38
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);
}

16
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>
<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-9"><select name="sunOffs"></select></div>
<div class="col-12 col-sm-3 my-2">Offset (sunrise)</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>
</fieldset>
</div>
@ -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))));
}
}
}

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
//-----------------------------------------------------------------------------
@ -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

Loading…
Cancel
Save