Browse Source

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`
pull/1155/head^2
lumapu 9 months ago
parent
commit
0d10d19b30
  1. 3
      src/CHANGES.md
  2. 8
      src/defines.h
  3. 2
      src/hm/Communication.h
  4. 29
      src/hm/hmInverter.h
  5. 2
      src/hm/hmRadio.h
  6. 6
      src/hm/radio.h
  7. 2
      src/hms/hmsRadio.h
  8. 10
      src/publisher/pubMqttIvData.h
  9. 6
      src/web/RestApi.h
  10. 10
      src/web/html/system.html
  11. 4
      src/web/html/visualization.html
  12. 8
      src/web/web.h

3
src/CHANGES.md

@ -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
* merge PR: beautifiying typography, added spaces between value and unit for `/visualization` #1314
* 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
* fix display timeout (OLED) to 60s

8
src/defines.h

@ -103,10 +103,10 @@ typedef struct {
uint32_t frmCnt;
uint32_t txCnt;
uint32_t retransmits;
uint16_t ivRxCnt; // last iv rx frames (from GetLossRate)
uint16_t ivTxCnt; // last iv tx frames (from GetLossRate)
uint16_t dtuRxCnt; // current DTU rx frames (since last GetLossRate)
uint16_t dtuTxCnt; // current DTU tx frames (since last GetLossRate)
uint16_t ivLoss; // lost frames (from GetLossRate)
uint16_t ivSent; // sent frames (from GetLossRate)
uint16_t dtuLoss; // current DTU lost frames (since last GetLossRate)
uint16_t dtuSent; // current DTU sent frames (since last GetLossRate)
} statistics_t;
#endif /*__DEFINES_H__*/

2
src/hm/Communication.h

@ -151,7 +151,7 @@ class Communication : public CommQueue<> {
if(validateIvSerial(&p->packet[1], q->iv)) {
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(parseFrame(p))

29
src/hm/hmInverter.h

@ -595,22 +595,27 @@ class Inverter {
uint16_t rxCnt = (pyld[0] << 8) + pyld[1];
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);
DBGPRINT(F("Inv loss: "));
DBGPRINT(String (radioStatistics.dtuTxCnt - (rxCnt - radioStatistics.ivRxCnt)));
DBGPRINT(String(radioStatistics.ivLoss));
DBGPRINT(F(" of "));
DBGPRINT(String (radioStatistics.dtuTxCnt));
DBGPRINT(String(radioStatistics.ivSent));
DBGPRINT(F(", DTU loss: "));
DBGPRINT(String (txCnt - radioStatistics.ivTxCnt - radioStatistics.dtuRxCnt));
DBGPRINT(String(radioStatistics.dtuLoss));
DBGPRINT(F(" of "));
DBGPRINTLN(String (txCnt - radioStatistics.ivTxCnt));
DBGPRINTLN(String(radioStatistics.dtuSent));
}
radioStatistics.ivRxCnt = rxCnt;
radioStatistics.ivTxCnt = txCnt;
radioStatistics.dtuRxCnt = 0; // start new interval
radioStatistics.dtuTxCnt = 0; // start new interval
mIvRxCnt = rxCnt;
mIvTxCnt = txCnt;
mDtuRxCnt = 0; // start new interval
mDtuTxCnt = 0; // start new interval
return true;
}
@ -806,6 +811,12 @@ class Inverter {
uint8_t mGridLen = 0;
uint8_t mGridProfile[MAX_GRID_LENGTH];
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>

2
src/hm/hmRadio.h

@ -339,7 +339,7 @@ class HmRadio : public Radio {
mMillis = millis();
mLastIv = iv;
iv->radioStatistics.dtuTxCnt++;
iv->mDtuTxCnt++;
}
uint64_t getIvId(Inverter<> *iv) {

6
src/hm/radio.h

@ -14,6 +14,8 @@
#include "../utils/dbg.h"
#include "../utils/crc.h"
enum { IRQ_UNKNOWN = 0, IRQ_OK, IRQ_ERROR };
// forward declaration of class
template <class REC_TYP=float>
class Inverter;
@ -30,6 +32,7 @@ class Radio {
void handleIntr(void) {
mIrqRcvd = true;
mIrqOk = IRQ_OK;
}
void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
@ -65,6 +68,7 @@ class Radio {
public:
std::queue<packet_t> mBufCtrl;
uint8_t mIrqOk = IRQ_UNKNOWN;
protected:
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);
mTxBuf[9] = pid;
memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10));
if(IRQ_UNKNOWN == mIrqOk)
mIrqOk = IRQ_ERROR;
}
void updateCrcs(uint8_t *len, bool appendCrc16=true) {

2
src/hms/hmsRadio.h

@ -112,7 +112,7 @@ class CmtRadio : public Radio {
if(CMT_ERR_RX_IN_FIFO == status)
mIrqRcvd = true;
}
iv->radioStatistics.dtuTxCnt++;
iv->mDtuTxCnt++;
}
uint64_t getIvId(Inverter<> *iv) {

10
src/publisher/pubMqttIvData.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
//-----------------------------------------------------------------------------
@ -201,10 +201,10 @@ class PubMqttIvData {
mIv->radioStatistics.rxFail,
mIv->radioStatistics.rxFailNoAnser,
mIv->radioStatistics.retransmits,
mIv->radioStatistics.ivRxCnt,
mIv->radioStatistics.ivTxCnt,
mIv->radioStatistics.dtuRxCnt,
mIv->radioStatistics.dtuTxCnt);
mIv->radioStatistics.ivLoss,
mIv->radioStatistics.ivSent,
mIv->radioStatistics.dtuLoss,
mIv->radioStatistics.dtuSent);
mPublish(mSubTopic, mVal, false, QOS_0);
}

6
src/web/RestApi.h

@ -405,6 +405,10 @@ class RestApi {
obj[F("frame_cnt")] = iv->radioStatistics.frmCnt;
obj[F("tx_cnt")] = iv->radioStatistics.txCnt;
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) {
@ -633,6 +637,7 @@ class RestApi {
if(mConfig->cmt.enabled) {
obj[F("isconnected")] = mRadioCmt->isChipConnected();
obj[F("sn")] = String(mRadioCmt->getDTUSn(), HEX);
obj[F("irqOk")] = mRadioCmt->mIrqOk;
}
}
#endif
@ -643,6 +648,7 @@ class RestApi {
obj[F("isconnected")] = mRadioNrf->isChipConnected();
obj[F("dataRate")] = mRadioNrf->getDataRate();
obj[F("sn")] = String(mRadioNrf->getDTUSn(), HEX);
obj[F("irqOk")] = mRadioNrf->mIrqOk;
}
}

10
src/web/html/system.html

@ -44,12 +44,21 @@
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) {
const dr = ["1 M", "2 M", "250 k"]
if(obj.radioNrf.en) {
lines = [
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("DTU Radio ID", obj.radioNrf.sn)
];
@ -67,6 +76,7 @@
if(obj.radioCmt.en) {
cmt = [
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)
];
} else

4
src/web/html/visualization.html

@ -388,7 +388,9 @@
tr2(["RX fail", obj.rx_fail, String(Math.round(obj.rx_fail / obj.tx_cnt * 10000) / 100) + "&nbsp;%"]),
tr2(["RX no answer", obj.rx_fail_answer, String(Math.round(obj.rx_fail_answer / obj.tx_cnt * 10000) / 100) + "&nbsp;%"]),
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) + "&nbsp;%"]),
tr2(["DTU loss rate", "lost " + obj.dtuLoss + " of " + obj.dtuSent, String(Math.round(obj.dtuLoss / obj.dtuSent * 10000) / 100) + "&nbsp;%"])
])
])
modal("Radio statistics for inverter " + obj.name, ml("div", {}, html))

8
src/web/web.h

@ -665,10 +665,10 @@ class Web {
{ "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_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_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivTxCnt;} },
{ "radio_dtu_rx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuRxCnt;} },
{ "radio_dtu_tx_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuTxCnt;} }
{ "radio_iv_loss_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivLoss;} },
{ "radio_iv_sent_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.ivSent;} },
{ "radio_dtu_loss_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuLoss;} },
{ "radio_dtu_sent_cnt", "counter" ,metricConstInverterFormat, [](Inverter<> *iv)-> uint64_t {return iv->radioStatistics.dtuSent;} }
};
int metricsInverterId;
uint8_t metricsFieldId;

Loading…
Cancel
Save