mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-13 00:46:38 +02:00
0.8.42
* add loss rate to `/visualization` in the statistics window * corrected `getLossRate` infos for MqTT and prometheus * added information about working IRQ for NRF24 and CMT2300A to `/system`
This commit is contained in:
parent
dd0bec6fc0
commit
0d10d19b30
12 changed files with 64 additions and 26 deletions
|
@ -4,6 +4,9 @@
|
||||||
* add LED to display whether it's night time or not. Can be reused as output to control battery system #1308
|
* add LED to display whether it's night time or not. Can be reused as output to control battery system #1308
|
||||||
* merge PR: beautifiying typography, added spaces between value and unit for `/visualization` #1314
|
* merge PR: beautifiying typography, added spaces between value and unit for `/visualization` #1314
|
||||||
* merge PR: Prometheus add `getLossRate` and bugfixing #1315
|
* merge PR: Prometheus add `getLossRate` and bugfixing #1315
|
||||||
|
* add loss rate to `/visualization` in the statistics window
|
||||||
|
* corrected `getLossRate` infos for MqTT and prometheus
|
||||||
|
* added information about working IRQ for NRF24 and CMT2300A to `/system`
|
||||||
|
|
||||||
## 0.8.41 - 2024-01-02
|
## 0.8.41 - 2024-01-02
|
||||||
* fix display timeout (OLED) to 60s
|
* fix display timeout (OLED) to 60s
|
||||||
|
|
|
@ -103,10 +103,10 @@ typedef struct {
|
||||||
uint32_t frmCnt;
|
uint32_t frmCnt;
|
||||||
uint32_t txCnt;
|
uint32_t txCnt;
|
||||||
uint32_t retransmits;
|
uint32_t retransmits;
|
||||||
uint16_t ivRxCnt; // last iv rx frames (from GetLossRate)
|
uint16_t ivLoss; // lost frames (from GetLossRate)
|
||||||
uint16_t ivTxCnt; // last iv tx frames (from GetLossRate)
|
uint16_t ivSent; // sent frames (from GetLossRate)
|
||||||
uint16_t dtuRxCnt; // current DTU rx frames (since last GetLossRate)
|
uint16_t dtuLoss; // current DTU lost frames (since last GetLossRate)
|
||||||
uint16_t dtuTxCnt; // current DTU tx frames (since last GetLossRate)
|
uint16_t dtuSent; // current DTU sent frames (since last GetLossRate)
|
||||||
} statistics_t;
|
} statistics_t;
|
||||||
|
|
||||||
#endif /*__DEFINES_H__*/
|
#endif /*__DEFINES_H__*/
|
||||||
|
|
|
@ -151,7 +151,7 @@ class Communication : public CommQueue<> {
|
||||||
|
|
||||||
if(validateIvSerial(&p->packet[1], q->iv)) {
|
if(validateIvSerial(&p->packet[1], q->iv)) {
|
||||||
q->iv->radioStatistics.frmCnt++;
|
q->iv->radioStatistics.frmCnt++;
|
||||||
q->iv->radioStatistics.dtuRxCnt++;
|
q->iv->mDtuRxCnt++;
|
||||||
|
|
||||||
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
||||||
if(parseFrame(p))
|
if(parseFrame(p))
|
||||||
|
|
|
@ -595,22 +595,27 @@ class Inverter {
|
||||||
uint16_t rxCnt = (pyld[0] << 8) + pyld[1];
|
uint16_t rxCnt = (pyld[0] << 8) + pyld[1];
|
||||||
uint16_t txCnt = (pyld[2] << 8) + pyld[3];
|
uint16_t txCnt = (pyld[2] << 8) + pyld[3];
|
||||||
|
|
||||||
if (radioStatistics.ivRxCnt || radioStatistics.ivTxCnt) { // there was successful GetLossRate in the past
|
if (mIvRxCnt || mIvTxCnt) { // there was successful GetLossRate in the past
|
||||||
|
radioStatistics.ivLoss = mDtuTxCnt - (rxCnt - mIvRxCnt);
|
||||||
|
radioStatistics.ivSent = mDtuTxCnt;
|
||||||
|
radioStatistics.dtuLoss = txCnt - mIvTxCnt - mDtuRxCnt;
|
||||||
|
radioStatistics.dtuSent = txCnt - mIvTxCnt;
|
||||||
|
|
||||||
DPRINT_IVID(DBG_INFO, id);
|
DPRINT_IVID(DBG_INFO, id);
|
||||||
DBGPRINT(F("Inv loss: "));
|
DBGPRINT(F("Inv loss: "));
|
||||||
DBGPRINT(String (radioStatistics.dtuTxCnt - (rxCnt - radioStatistics.ivRxCnt)));
|
DBGPRINT(String(radioStatistics.ivLoss));
|
||||||
DBGPRINT(F(" of "));
|
DBGPRINT(F(" of "));
|
||||||
DBGPRINT(String (radioStatistics.dtuTxCnt));
|
DBGPRINT(String(radioStatistics.ivSent));
|
||||||
DBGPRINT(F(", DTU loss: "));
|
DBGPRINT(F(", DTU loss: "));
|
||||||
DBGPRINT(String (txCnt - radioStatistics.ivTxCnt - radioStatistics.dtuRxCnt));
|
DBGPRINT(String(radioStatistics.dtuLoss));
|
||||||
DBGPRINT(F(" of "));
|
DBGPRINT(F(" of "));
|
||||||
DBGPRINTLN(String (txCnt - radioStatistics.ivTxCnt));
|
DBGPRINTLN(String(radioStatistics.dtuSent));
|
||||||
}
|
}
|
||||||
|
|
||||||
radioStatistics.ivRxCnt = rxCnt;
|
mIvRxCnt = rxCnt;
|
||||||
radioStatistics.ivTxCnt = txCnt;
|
mIvTxCnt = txCnt;
|
||||||
radioStatistics.dtuRxCnt = 0; // start new interval
|
mDtuRxCnt = 0; // start new interval
|
||||||
radioStatistics.dtuTxCnt = 0; // start new interval
|
mDtuTxCnt = 0; // start new interval
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,6 +811,12 @@ class Inverter {
|
||||||
uint8_t mGridLen = 0;
|
uint8_t mGridLen = 0;
|
||||||
uint8_t mGridProfile[MAX_GRID_LENGTH];
|
uint8_t mGridProfile[MAX_GRID_LENGTH];
|
||||||
uint8_t mGetLossInterval; // request iv every AHOY_GET_LOSS_INTERVAL RealTimeRunData_Debug
|
uint8_t mGetLossInterval; // request iv every AHOY_GET_LOSS_INTERVAL RealTimeRunData_Debug
|
||||||
|
uint16_t mIvRxCnt = 0;
|
||||||
|
uint16_t mIvTxCnt = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint16_t mDtuRxCnt = 0;
|
||||||
|
uint16_t mDtuTxCnt = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class REC_TYP>
|
template <class REC_TYP>
|
||||||
|
|
|
@ -339,7 +339,7 @@ class HmRadio : public Radio {
|
||||||
mMillis = millis();
|
mMillis = millis();
|
||||||
|
|
||||||
mLastIv = iv;
|
mLastIv = iv;
|
||||||
iv->radioStatistics.dtuTxCnt++;
|
iv->mDtuTxCnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getIvId(Inverter<> *iv) {
|
uint64_t getIvId(Inverter<> *iv) {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "../utils/dbg.h"
|
#include "../utils/dbg.h"
|
||||||
#include "../utils/crc.h"
|
#include "../utils/crc.h"
|
||||||
|
|
||||||
|
enum { IRQ_UNKNOWN = 0, IRQ_OK, IRQ_ERROR };
|
||||||
|
|
||||||
// forward declaration of class
|
// forward declaration of class
|
||||||
template <class REC_TYP=float>
|
template <class REC_TYP=float>
|
||||||
class Inverter;
|
class Inverter;
|
||||||
|
@ -30,6 +32,7 @@ class Radio {
|
||||||
|
|
||||||
void handleIntr(void) {
|
void handleIntr(void) {
|
||||||
mIrqRcvd = true;
|
mIrqRcvd = true;
|
||||||
|
mIrqOk = IRQ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
|
void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
|
||||||
|
@ -65,6 +68,7 @@ class Radio {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::queue<packet_t> mBufCtrl;
|
std::queue<packet_t> mBufCtrl;
|
||||||
|
uint8_t mIrqOk = IRQ_UNKNOWN;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;
|
virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;
|
||||||
|
@ -77,6 +81,8 @@ class Radio {
|
||||||
CP_U32_LittleEndian(&mTxBuf[5], mDtuSn);
|
CP_U32_LittleEndian(&mTxBuf[5], mDtuSn);
|
||||||
mTxBuf[9] = pid;
|
mTxBuf[9] = pid;
|
||||||
memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10));
|
memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10));
|
||||||
|
if(IRQ_UNKNOWN == mIrqOk)
|
||||||
|
mIrqOk = IRQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCrcs(uint8_t *len, bool appendCrc16=true) {
|
void updateCrcs(uint8_t *len, bool appendCrc16=true) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ class CmtRadio : public Radio {
|
||||||
if(CMT_ERR_RX_IN_FIFO == status)
|
if(CMT_ERR_RX_IN_FIFO == status)
|
||||||
mIrqRcvd = true;
|
mIrqRcvd = true;
|
||||||
}
|
}
|
||||||
iv->radioStatistics.dtuTxCnt++;
|
iv->mDtuTxCnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getIvId(Inverter<> *iv) {
|
uint64_t getIvId(Inverter<> *iv) {
|
||||||
|
|
|
@ -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
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -201,10 +201,10 @@ class PubMqttIvData {
|
||||||
mIv->radioStatistics.rxFail,
|
mIv->radioStatistics.rxFail,
|
||||||
mIv->radioStatistics.rxFailNoAnser,
|
mIv->radioStatistics.rxFailNoAnser,
|
||||||
mIv->radioStatistics.retransmits,
|
mIv->radioStatistics.retransmits,
|
||||||
mIv->radioStatistics.ivRxCnt,
|
mIv->radioStatistics.ivLoss,
|
||||||
mIv->radioStatistics.ivTxCnt,
|
mIv->radioStatistics.ivSent,
|
||||||
mIv->radioStatistics.dtuRxCnt,
|
mIv->radioStatistics.dtuLoss,
|
||||||
mIv->radioStatistics.dtuTxCnt);
|
mIv->radioStatistics.dtuSent);
|
||||||
mPublish(mSubTopic, mVal, false, QOS_0);
|
mPublish(mSubTopic, mVal, false, QOS_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -405,6 +405,10 @@ class RestApi {
|
||||||
obj[F("frame_cnt")] = iv->radioStatistics.frmCnt;
|
obj[F("frame_cnt")] = iv->radioStatistics.frmCnt;
|
||||||
obj[F("tx_cnt")] = iv->radioStatistics.txCnt;
|
obj[F("tx_cnt")] = iv->radioStatistics.txCnt;
|
||||||
obj[F("retransmits")] = iv->radioStatistics.retransmits;
|
obj[F("retransmits")] = iv->radioStatistics.retransmits;
|
||||||
|
obj[F("ivLoss")] = iv->radioStatistics.ivLoss;
|
||||||
|
obj[F("ivSent")] = iv->radioStatistics.ivSent;
|
||||||
|
obj[F("dtuLoss")] = iv->radioStatistics.dtuLoss;
|
||||||
|
obj[F("dtuSent")] = iv->radioStatistics.dtuSent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getIvPowerLimitAck(JsonObject obj, uint8_t id) {
|
void getIvPowerLimitAck(JsonObject obj, uint8_t id) {
|
||||||
|
@ -633,6 +637,7 @@ class RestApi {
|
||||||
if(mConfig->cmt.enabled) {
|
if(mConfig->cmt.enabled) {
|
||||||
obj[F("isconnected")] = mRadioCmt->isChipConnected();
|
obj[F("isconnected")] = mRadioCmt->isChipConnected();
|
||||||
obj[F("sn")] = String(mRadioCmt->getDTUSn(), HEX);
|
obj[F("sn")] = String(mRadioCmt->getDTUSn(), HEX);
|
||||||
|
obj[F("irqOk")] = mRadioCmt->mIrqOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -643,6 +648,7 @@ class RestApi {
|
||||||
obj[F("isconnected")] = mRadioNrf->isChipConnected();
|
obj[F("isconnected")] = mRadioNrf->isChipConnected();
|
||||||
obj[F("dataRate")] = mRadioNrf->getDataRate();
|
obj[F("dataRate")] = mRadioNrf->getDataRate();
|
||||||
obj[F("sn")] = String(mRadioNrf->getDTUSn(), HEX);
|
obj[F("sn")] = String(mRadioNrf->getDTUSn(), HEX);
|
||||||
|
obj[F("irqOk")] = mRadioNrf->mIrqOk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,21 @@
|
||||||
return ml("div", {class: "head p-2 mt-3"}, ml("div", {class: "row"}, ml("div", {class: "col a-c"}, text)))
|
return ml("div", {class: "head p-2 mt-3"}, ml("div", {class: "row"}, ml("div", {class: "col a-c"}, text)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function irqBadge(state) {
|
||||||
|
switch(state) {
|
||||||
|
case 0: return badge(false, "unknown", "warning"); break;
|
||||||
|
case 1: return badge(true, "true"); break;
|
||||||
|
default: return badge(false, "false"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseRadio(obj) {
|
function parseRadio(obj) {
|
||||||
const dr = ["1 M", "2 M", "250 k"]
|
const dr = ["1 M", "2 M", "250 k"]
|
||||||
|
|
||||||
if(obj.radioNrf.en) {
|
if(obj.radioNrf.en) {
|
||||||
lines = [
|
lines = [
|
||||||
tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "not ") + "connected")),
|
tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "not ") + "connected")),
|
||||||
|
tr("Interrupt Pin working", irqBadge(obj.radioNrf.irqOk)),
|
||||||
tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps"),
|
tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps"),
|
||||||
tr("DTU Radio ID", obj.radioNrf.sn)
|
tr("DTU Radio ID", obj.radioNrf.sn)
|
||||||
];
|
];
|
||||||
|
@ -67,6 +76,7 @@
|
||||||
if(obj.radioCmt.en) {
|
if(obj.radioCmt.en) {
|
||||||
cmt = [
|
cmt = [
|
||||||
tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "not ") + "connected")),
|
tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "not ") + "connected")),
|
||||||
|
tr("Interrupt Pin working", irqBadge(obj.radioCmt.irqOk)),
|
||||||
tr("DTU Radio ID", obj.radioCmt.sn)
|
tr("DTU Radio ID", obj.radioCmt.sn)
|
||||||
];
|
];
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -388,7 +388,9 @@
|
||||||
tr2(["RX fail", obj.rx_fail, String(Math.round(obj.rx_fail / obj.tx_cnt * 10000) / 100) + " %"]),
|
tr2(["RX fail", obj.rx_fail, String(Math.round(obj.rx_fail / obj.tx_cnt * 10000) / 100) + " %"]),
|
||||||
tr2(["RX no answer", obj.rx_fail_answer, String(Math.round(obj.rx_fail_answer / obj.tx_cnt * 10000) / 100) + " %"]),
|
tr2(["RX no answer", obj.rx_fail_answer, String(Math.round(obj.rx_fail_answer / obj.tx_cnt * 10000) / 100) + " %"]),
|
||||||
tr2(["RX fragments", obj.frame_cnt, ""]),
|
tr2(["RX fragments", obj.frame_cnt, ""]),
|
||||||
tr2(["TX retransmits", obj.retransmits, ""])
|
tr2(["TX retransmits", obj.retransmits, ""]),
|
||||||
|
tr2(["Inverter loss rate", "lost " + obj.ivLoss + " of " + obj.ivSent, String(Math.round(obj.ivLoss / obj.ivSent * 10000) / 100) + " %"]),
|
||||||
|
tr2(["DTU loss rate", "lost " + obj.dtuLoss + " of " + obj.dtuSent, String(Math.round(obj.dtuLoss / obj.dtuSent * 10000) / 100) + " %"])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
modal("Radio statistics for inverter " + obj.name, ml("div", {}, html))
|
modal("Radio statistics for inverter " + obj.name, ml("div", {}, html))
|
||||||
|
|
|
@ -665,10 +665,10 @@ class Web {
|
||||||
{ "radio_frame_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.frmCnt;} },
|
{ "radio_frame_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.frmCnt;} },
|
||||||
{ "radio_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.txCnt;} },
|
{ "radio_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.txCnt;} },
|
||||||
{ "radio_retransmits", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.retransmits;} },
|
{ "radio_retransmits", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.retransmits;} },
|
||||||
{ "radio_iv_rx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivRxCnt;} },
|
{ "radio_iv_loss_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivLoss;} },
|
||||||
{ "radio_iv_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivTxCnt;} },
|
{ "radio_iv_sent_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivSent;} },
|
||||||
{ "radio_dtu_rx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuRxCnt;} },
|
{ "radio_dtu_loss_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuLoss;} },
|
||||||
{ "radio_dtu_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuTxCnt;} }
|
{ "radio_dtu_sent_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuSent;} }
|
||||||
};
|
};
|
||||||
int metricsInverterId;
|
int metricsInverterId;
|
||||||
uint8_t metricsFieldId;
|
uint8_t metricsFieldId;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue