mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-10 22:51:36 +02:00
changed calculation of start / stop communication to 1 min after last comm. stop #515
moved payload send to `payload.h`, function `ivSend` #515
This commit is contained in:
parent
f8fe044e1b
commit
19e86ebdb2
4 changed files with 77 additions and 118 deletions
|
@ -1,36 +1,7 @@
|
|||
# Changelog v0.5.66
|
||||
# Changelog
|
||||
|
||||
**Note:** Version `0.5.42` to `0.5.65` were development versions. Last release version was `0.5.41`
|
||||
Detailed change log (development changes): https://github.com/lumapu/ahoy/blob/945a671d27d10d0f7c175ebbf2fbb2806f9cd79a/src/CHANGES.md
|
||||
(starting from release version `0.5.66`)
|
||||
|
||||
|
||||
* updated REST API and MQTT (both of them use the same functionality)
|
||||
* improved stability
|
||||
* Regular expressions for input fields which are used for MQTT to be compliant to MQTT
|
||||
* WiFi optimization (AP Mode and STA in parallel, reconnect if local STA is unavailable)
|
||||
* improved display of `/system`
|
||||
* fix Update button protection (prevent double click #527)
|
||||
* optimized scheduler #515
|
||||
* fix of duplicates in API `/api/record/live` (#526)
|
||||
* added update information to `index.html` (check for update with github.com)
|
||||
* fix web logout (auto logout)
|
||||
* switched MQTT library
|
||||
* removed MQTT `available_text` (can be deducted from `available`)
|
||||
* enhanced MQTT documentation in `User_Manual.md`
|
||||
* changed MQTT topic `status` to nummeric value, check documentation in `User_Manual.md`
|
||||
* added immediate (each minute) report of inverter status MQTT #522
|
||||
* increased MQTT user, pwd and topic length to 64 characters + `\0`. (The string end `\0` reduces the available size by one) #516
|
||||
* added disable night communication flag to MQTT #505
|
||||
* added MQTT <TOPIC>/status to show status over all inverters
|
||||
* added MQTT RX counter to index.html
|
||||
* added protection mask to select which pages should be protected
|
||||
* added monochrome display that show values also if nothing changed and in offline mode #498
|
||||
* added icons to index.html, added WiFi-strength symbol on each page
|
||||
* refactored communication offset (adjustable in minutes now)
|
||||
* factory reset formats entire little fs
|
||||
* renamed sunrise / sunset on index.html to start / stop communication
|
||||
* fixed static IP save
|
||||
* fix NTP with static IP
|
||||
* all values are displayed on /live even if they are 0
|
||||
* added NRF24 info to Systeminfo
|
||||
* reordered enqueue commands after boot up to prevent same payload length for successive commands
|
||||
## 0.5.67
|
||||
* changed calculation of start / stop communication to 1 min after last comm. stop #515
|
||||
* moved payload send to `payload.h`, function `ivSend` #515
|
||||
|
|
63
src/app.cpp
63
src/app.cpp
|
@ -51,7 +51,7 @@ void app::setup() {
|
|||
#endif
|
||||
|
||||
mSys->addInverters(&mConfig->inst);
|
||||
mPayload.setup(mSys);
|
||||
mPayload.setup(mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
||||
mPayload.enableSerialDebug(mConfig->serial.debug);
|
||||
|
||||
if(!mSys->Radio.isChipConnected())
|
||||
|
@ -115,7 +115,9 @@ void app::loop(void) {
|
|||
yield();
|
||||
|
||||
if (rxRdy)
|
||||
mPayload.process(true, mConfig->nrf.maxRetransPerPyld, &mStat);
|
||||
mPayload.process(true);
|
||||
|
||||
mRxTicker = 0;
|
||||
}
|
||||
|
||||
#if !defined(AP_ONLY)
|
||||
|
@ -138,14 +140,18 @@ void app::tickNtpUpdate(void) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
void app::tickCalcSunrise(void) {
|
||||
ah::calculateSunriseSunset(mTimestamp, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset);
|
||||
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
|
||||
ah::calculateSunriseSunset(mTimestamp + 86400, mCalculatedTimezoneOffset, mConfig->sun.lat, mConfig->sun.lon, &mSunrise, &mSunset);
|
||||
|
||||
tickIVCommunication();
|
||||
|
||||
uint32_t nxtTrig = mTimestamp - ((mTimestamp + mCalculatedTimezoneOffset - 10) % 86400) + 86400;; // next midnight, -10 for safety that it is certain next day, local timezone
|
||||
uint32_t nxtTrig = mSunset + mConfig->sun.offsetSec + 60; // set next trigger to communication stop, +60 for safety that it is certain past communication stop
|
||||
onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig);
|
||||
if (mConfig->mqtt.broker[0] > 0) {
|
||||
if (mConfig->mqtt.broker[0] > 0)
|
||||
mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec, mConfig->sun.disNightCom);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -187,49 +193,8 @@ void app::tickSend(void) {
|
|||
} while ((NULL == iv) && ((maxLoop--) > 0));
|
||||
|
||||
if (NULL != iv) {
|
||||
if(iv->config->enabled) {
|
||||
if (!mPayload.isComplete(iv))
|
||||
mPayload.process(false, mConfig->nrf.maxRetransPerPyld, &mStat);
|
||||
|
||||
if (!mPayload.isComplete(iv)) {
|
||||
if (0 == mPayload.getMaxPacketId(iv))
|
||||
mStat.rxFailNoAnser++;
|
||||
else
|
||||
mStat.rxFail++;
|
||||
|
||||
iv->setQueuedCmdFinished(); // command failed
|
||||
if (mConfig->serial.debug)
|
||||
DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout"));
|
||||
if (mConfig->serial.debug) {
|
||||
DPRINT(DBG_INFO, F("(#") + String(iv->id) + ") ");
|
||||
DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload.getRetransmits(iv)) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
mPayload.reset(iv, mTimestamp);
|
||||
mPayload.request(iv);
|
||||
|
||||
yield();
|
||||
if (mConfig->serial.debug) {
|
||||
DPRINTLN(DBG_DEBUG, F("app:loop WiFi WiFi.status ") + String(WiFi.status()));
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX));
|
||||
}
|
||||
|
||||
if (iv->devControlRequest) {
|
||||
if (mConfig->serial.debug)
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
|
||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);
|
||||
mPayload.setTxCmd(iv, iv->devControlCmd);
|
||||
iv->clearCmdQueue();
|
||||
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
||||
} else {
|
||||
uint8_t cmd = iv->getQueuedCmd();
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket"));
|
||||
mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload.getTs(iv), iv->alarmMesIndex);
|
||||
mPayload.setTxCmd(iv, cmd);
|
||||
mRxTicker = 0;
|
||||
}
|
||||
}
|
||||
if(iv->config->enabled)
|
||||
mPayload.ivSend(iv);
|
||||
}
|
||||
} else {
|
||||
if (mConfig->serial.debug)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 66
|
||||
#define VERSION_PATCH 67
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -34,47 +34,67 @@ class Payload : public Handler<payloadListenerType> {
|
|||
public:
|
||||
Payload() : Handler() {}
|
||||
|
||||
void setup(HMSYSTEM *sys) {
|
||||
mSys = sys;
|
||||
void setup(HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
|
||||
mSys = sys;
|
||||
mStat = stat;
|
||||
mMaxRetrans = maxRetransmits;
|
||||
mTimestamp = timestamp;
|
||||
memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t)));
|
||||
mLastPacketId = 0x00;
|
||||
mSerialDebug = false;
|
||||
mSerialDebug = false;
|
||||
}
|
||||
|
||||
void enableSerialDebug(bool enable) {
|
||||
mSerialDebug = enable;
|
||||
}
|
||||
|
||||
bool isComplete(Inverter<> *iv) {
|
||||
return mPayload[iv->id].complete;
|
||||
}
|
||||
|
||||
uint8_t getMaxPacketId(Inverter<> *iv) {
|
||||
return mPayload[iv->id].maxPackId;
|
||||
}
|
||||
|
||||
uint8_t getRetransmits(Inverter<> *iv) {
|
||||
return mPayload[iv->id].retransmits;
|
||||
}
|
||||
|
||||
uint32_t getTs(Inverter<> *iv) {
|
||||
return mPayload[iv->id].ts;
|
||||
}
|
||||
|
||||
void request(Inverter<> *iv) {
|
||||
mPayload[iv->id].requested = true;
|
||||
}
|
||||
|
||||
void setTxCmd(Inverter<> *iv, uint8_t cmd) {
|
||||
mPayload[iv->id].txCmd = cmd;
|
||||
}
|
||||
|
||||
void notify(uint8_t val) {
|
||||
for(typename std::list<payloadListenerType>::iterator it = mList.begin(); it != mList.end(); ++it) {
|
||||
(*it)(val);
|
||||
}
|
||||
}
|
||||
|
||||
void ivSend(Inverter<> *iv) {
|
||||
if (!mPayload[iv->id].complete)
|
||||
process(false);
|
||||
|
||||
if (!mPayload[iv->id].complete) {
|
||||
if (0 == mPayload[iv->id].maxPackId)
|
||||
mStat->rxFailNoAnser++;
|
||||
else
|
||||
mStat->rxFail++;
|
||||
|
||||
iv->setQueuedCmdFinished(); // command failed
|
||||
if (mSerialDebug)
|
||||
DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout"));
|
||||
if (mSerialDebug) {
|
||||
DPRINT(DBG_INFO, F("(#") + String(iv->id) + ") ");
|
||||
DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload[iv->id].retransmits) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
reset(iv);
|
||||
mPayload[iv->id].requested = true;
|
||||
|
||||
yield();
|
||||
if (mSerialDebug)
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX));
|
||||
|
||||
if (iv->devControlRequest) {
|
||||
if (mSerialDebug)
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
|
||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);
|
||||
mPayload[iv->id].txCmd = iv->devControlCmd;
|
||||
iv->clearCmdQueue();
|
||||
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
||||
} else {
|
||||
uint8_t cmd = iv->getQueuedCmd();
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket"));
|
||||
mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex);
|
||||
mPayload[iv->id].txCmd = cmd;
|
||||
}
|
||||
}
|
||||
|
||||
void add(packet_t *p, uint8_t len) {
|
||||
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
||||
if ((NULL != iv) && (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES))) { // response from get information command
|
||||
|
@ -134,7 +154,7 @@ class Payload : public Handler<payloadListenerType> {
|
|||
return (crc == crcRcv) ? true : false;
|
||||
}
|
||||
|
||||
void process(bool retransmit, uint8_t maxRetransmits, statistics_t *stat) {
|
||||
void process(bool retransmit) {
|
||||
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
||||
if (NULL == iv)
|
||||
|
@ -152,9 +172,9 @@ class Payload : public Handler<payloadListenerType> {
|
|||
if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) {
|
||||
// This is required to prevent retransmissions without answer.
|
||||
DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm..."));
|
||||
mPayload[iv->id].retransmits = maxRetransmits;
|
||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||
} else {
|
||||
if (mPayload[iv->id].retransmits < maxRetransmits) {
|
||||
if (mPayload[iv->id].retransmits < mMaxRetrans) {
|
||||
mPayload[iv->id].retransmits++;
|
||||
if (mPayload[iv->id].maxPackId != 0) {
|
||||
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
|
||||
|
@ -207,7 +227,7 @@ class Payload : public Handler<payloadListenerType> {
|
|||
DPRINTLN(DBG_ERROR, F("record is NULL!"));
|
||||
} else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
|
||||
if (mPayload[iv->id].txId == (TX_REQ_INFO + 0x80))
|
||||
stat->rxSuccess++;
|
||||
mStat->rxSuccess++;
|
||||
|
||||
rec->ts = mPayload[iv->id].ts;
|
||||
for (uint8_t i = 0; i < rec->length; i++) {
|
||||
|
@ -218,7 +238,7 @@ class Payload : public Handler<payloadListenerType> {
|
|||
notify(mPayload[iv->id].txCmd);
|
||||
} else {
|
||||
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
|
||||
stat->rxFail++;
|
||||
mStat->rxFail++;
|
||||
}
|
||||
|
||||
iv->setQueuedCmdFinished();
|
||||
|
@ -230,7 +250,7 @@ class Payload : public Handler<payloadListenerType> {
|
|||
}
|
||||
}
|
||||
|
||||
void reset(Inverter<> *iv, uint32_t utcTs) {
|
||||
void reset(Inverter<> *iv) {
|
||||
DPRINTLN(DBG_INFO, "resetPayload: id: " + String(iv->id));
|
||||
memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||
mPayload[iv->id].txCmd = 0;
|
||||
|
@ -238,11 +258,14 @@ class Payload : public Handler<payloadListenerType> {
|
|||
mPayload[iv->id].maxPackId = 0;
|
||||
mPayload[iv->id].complete = false;
|
||||
mPayload[iv->id].requested = false;
|
||||
mPayload[iv->id].ts = utcTs;
|
||||
mPayload[iv->id].ts = *mTimestamp;
|
||||
}
|
||||
|
||||
private:
|
||||
HMSYSTEM *mSys;
|
||||
statistics_t *mStat;
|
||||
uint8_t mMaxRetrans;
|
||||
uint32_t *mTimestamp;
|
||||
invPayload_t mPayload[MAX_NUM_INVERTERS];
|
||||
uint8_t mLastPacketId;
|
||||
bool mSerialDebug;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue