|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
|
|
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifndef __COMM_QUEUE_H__
|
|
|
|
#define __COMM_QUEUE_H__
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <functional>
|
|
|
|
#include "hmInverter.h"
|
|
|
|
#include "../utils/dbg.h"
|
|
|
|
|
|
|
|
// needs a '+1' because the comparison does not send if attempts is equal 0
|
|
|
|
#define DEFAULT_ATTEMPS 5 + 1
|
|
|
|
#define MORE_ATTEMPS_ALARMDATA 15 + 1
|
|
|
|
#define MORE_ATTEMPS_GRIDONPROFILEPARA 15 + 1
|
|
|
|
|
|
|
|
template <uint8_t N=100>
|
|
|
|
class CommQueue {
|
|
|
|
public:
|
|
|
|
CommQueue() {}
|
|
|
|
|
|
|
|
void addImportant(Inverter<> *iv, uint8_t cmd) {
|
|
|
|
dec(&mRdPtr);
|
|
|
|
mQueue[mRdPtr] = queue_s(iv, cmd, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(Inverter<> *iv, uint8_t cmd) {
|
|
|
|
mQueue[mWrPtr] = queue_s(iv, cmd, false);
|
|
|
|
inc(&mWrPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void chgCmd(Inverter<> *iv, uint8_t cmd) {
|
|
|
|
mQueue[mWrPtr] = queue_s(iv, cmd, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t getFillState(void) {
|
|
|
|
//DPRINTLN(DBG_INFO, "wr: " + String(mWrPtr) + ", rd: " + String(mRdPtr));
|
|
|
|
return abs(mRdPtr - mWrPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t getMaxFill(void) {
|
|
|
|
return N;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
struct queue_s {
|
|
|
|
Inverter<> *iv;
|
|
|
|
uint8_t cmd;
|
|
|
|
uint8_t attempts;
|
|
|
|
uint8_t attemptsMax;
|
|
|
|
uint32_t ts;
|
|
|
|
bool isDevControl;
|
|
|
|
queue_s() {}
|
|
|
|
queue_s(Inverter<> *i, uint8_t c, bool dev) :
|
|
|
|
iv(i), cmd(c), attempts(DEFAULT_ATTEMPS), attemptsMax(DEFAULT_ATTEMPS), ts(0), isDevControl(dev) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void add(queue_s q) {
|
|
|
|
mQueue[mWrPtr] = q;
|
|
|
|
inc(&mWrPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(const queue_s *q, bool rstAttempts = false) {
|
|
|
|
mQueue[mWrPtr] = *q;
|
|
|
|
if(rstAttempts) {
|
|
|
|
mQueue[mWrPtr].attempts = DEFAULT_ATTEMPS;
|
|
|
|
mQueue[mWrPtr].attemptsMax = DEFAULT_ATTEMPS;
|
|
|
|
}
|
|
|
|
inc(&mWrPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void chgCmd(uint8_t cmd) {
|
|
|
|
mQueue[mRdPtr].cmd = cmd;
|
|
|
|
mQueue[mRdPtr].isDevControl = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void get(std::function<void(bool valid, const queue_s *q)> cb) {
|
|
|
|
if(mRdPtr == mWrPtr) {
|
|
|
|
cb(false, &mQueue[mRdPtr]); // empty
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
cb(true, &mQueue[mRdPtr]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cmdDone(bool keep = false) {
|
|
|
|
if(keep) {
|
|
|
|
mQueue[mRdPtr].attempts = DEFAULT_ATTEMPS;
|
|
|
|
mQueue[mRdPtr].attemptsMax = DEFAULT_ATTEMPS;
|
|
|
|
add(mQueue[mRdPtr]); // add to the end again
|
|
|
|
}
|
|
|
|
inc(&mRdPtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setTs(uint32_t *ts) {
|
|
|
|
mQueue[mRdPtr].ts = *ts;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAttempt(void) {
|
|
|
|
if(mQueue[mRdPtr].attempts)
|
|
|
|
mQueue[mRdPtr].attempts--;
|
|
|
|
}
|
|
|
|
|
|
|
|
void incrAttempt(uint8_t attempts = 1) {
|
|
|
|
mQueue[mRdPtr].attempts += attempts;
|
|
|
|
if (mQueue[mRdPtr].attempts > mQueue[mRdPtr].attemptsMax)
|
|
|
|
mQueue[mRdPtr].attemptsMax = mQueue[mRdPtr].attempts;
|
|
|
|
}
|
|
|
|
|
|
|
|
void inc(uint8_t *ptr) {
|
|
|
|
if(++(*ptr) >= N)
|
|
|
|
*ptr = 0;
|
|
|
|
}
|
|
|
|
void dec(uint8_t *ptr) {
|
|
|
|
if((*ptr) == 0)
|
|
|
|
*ptr = N-1;
|
|
|
|
else
|
|
|
|
--(*ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
std::array<queue_s, N> mQueue;
|
|
|
|
uint8_t mWrPtr = 0;
|
|
|
|
uint8_t mRdPtr = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif /*__COMM_QUEUE_H__*/
|