mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-29 00:36:11 +02:00
improved general structures to support HMS in future
This commit is contained in:
parent
c56c785a1f
commit
c4dd372554
14 changed files with 96 additions and 77 deletions
37
src/app.cpp
37
src/app.cpp
|
@ -35,8 +35,11 @@ void app::setup() {
|
||||||
else
|
else
|
||||||
DBGPRINTLN(F("false"));
|
DBGPRINTLN(F("false"));
|
||||||
|
|
||||||
mSys.enableDebug();
|
mSys.setup();
|
||||||
mSys.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs);
|
if(mConfig->nrf.enabled) {
|
||||||
|
mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs);
|
||||||
|
mNrfRadio.enableDebug();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(AP_ONLY)
|
#if defined(AP_ONLY)
|
||||||
mInnerLoopCb = std::bind(&app::loopStandard, this);
|
mInnerLoopCb = std::bind(&app::loopStandard, this);
|
||||||
|
@ -50,19 +53,21 @@ void app::setup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mSys.addInverters(&mConfig->inst);
|
mSys.addInverters(&mConfig->inst);
|
||||||
mPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
if(mConfig->nrf.enabled) {
|
||||||
mPayload.enableSerialDebug(mConfig->serial.debug);
|
mPayload.setup(this, &mSys, &mNrfRadio, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
||||||
mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1));
|
mPayload.enableSerialDebug(mConfig->serial.debug);
|
||||||
|
mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1));
|
||||||
|
|
||||||
mMiPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
mMiPayload.setup(this, &mSys, &mNrfRadio, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
||||||
mMiPayload.enableSerialDebug(mConfig->serial.debug);
|
mMiPayload.enableSerialDebug(mConfig->serial.debug);
|
||||||
|
}
|
||||||
|
|
||||||
/*DBGPRINTLN("--- after payload");
|
/*DBGPRINTLN("--- after payload");
|
||||||
DBGPRINTLN(String(ESP.getFreeHeap()));
|
DBGPRINTLN(String(ESP.getFreeHeap()));
|
||||||
DBGPRINTLN(String(ESP.getHeapFragmentation()));
|
DBGPRINTLN(String(ESP.getHeapFragmentation()));
|
||||||
DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/
|
DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/
|
||||||
|
|
||||||
if(!mSys.Radio.isChipConnected())
|
if(!mNrfRadio.isChipConnected())
|
||||||
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
||||||
|
|
||||||
// when WiFi is in client mode, then enable mqtt broker
|
// when WiFi is in client mode, then enable mqtt broker
|
||||||
|
@ -79,7 +84,7 @@ void app::setup() {
|
||||||
mWeb.setup(this, &mSys, mConfig);
|
mWeb.setup(this, &mSys, mConfig);
|
||||||
mWeb.setProtection(strlen(mConfig->sys.adminPwd) != 0);
|
mWeb.setProtection(strlen(mConfig->sys.adminPwd) != 0);
|
||||||
|
|
||||||
mApi.setup(this, &mSys, mWeb.getWebSrvPtr(), mConfig);
|
mApi.setup(this, &mSys, &mNrfRadio, mWeb.getWebSrvPtr(), mConfig);
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
if(mConfig->plugin.display.type != 0)
|
if(mConfig->plugin.display.type != 0)
|
||||||
|
@ -105,9 +110,9 @@ void app::loop(void) {
|
||||||
void app::loopStandard(void) {
|
void app::loopStandard(void) {
|
||||||
ah::Scheduler::loop();
|
ah::Scheduler::loop();
|
||||||
|
|
||||||
if (mSys.Radio.loop()) {
|
if (mNrfRadio.loop()) {
|
||||||
while (!mSys.Radio.mBufCtrl.empty()) {
|
while (!mNrfRadio.mBufCtrl.empty()) {
|
||||||
packet_t *p = &mSys.Radio.mBufCtrl.front();
|
packet_t *p = &mNrfRadio.mBufCtrl.front();
|
||||||
|
|
||||||
if (mConfig->serial.debug) {
|
if (mConfig->serial.debug) {
|
||||||
DPRINT(DBG_INFO, F("RX "));
|
DPRINT(DBG_INFO, F("RX "));
|
||||||
|
@ -126,7 +131,7 @@ void app::loopStandard(void) {
|
||||||
else
|
else
|
||||||
mMiPayload.add(iv, p);
|
mMiPayload.add(iv, p);
|
||||||
}
|
}
|
||||||
mSys.Radio.mBufCtrl.pop();
|
mNrfRadio.mBufCtrl.pop();
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
mPayload.process(true);
|
mPayload.process(true);
|
||||||
|
@ -324,15 +329,15 @@ void app::tickMidnight(void) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void app::tickSend(void) {
|
void app::tickSend(void) {
|
||||||
if(!mSys.Radio.isChipConnected()) {
|
if(!mNrfRadio.isChipConnected()) {
|
||||||
DPRINTLN(DBG_WARN, F("NRF24 not connected!"));
|
DPRINTLN(DBG_WARN, F("NRF24 not connected!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mIVCommunicationOn) {
|
if (mIVCommunicationOn) {
|
||||||
if (!mSys.Radio.mBufCtrl.empty()) {
|
if (!mNrfRadio.mBufCtrl.empty()) {
|
||||||
if (mConfig->serial.debug) {
|
if (mConfig->serial.debug) {
|
||||||
DPRINT(DBG_DEBUG, F("recbuf not empty! #"));
|
DPRINT(DBG_DEBUG, F("recbuf not empty! #"));
|
||||||
DBGPRINTLN(String(mSys.Radio.mBufCtrl.size()));
|
DBGPRINTLN(String(mNrfRadio.mBufCtrl.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
src/app.h
30
src/app.h
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "utils/dbg.h"
|
#include "utils/dbg.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <RF24.h>
|
|
||||||
#include <RF24_config.h>
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
#include "appInterface.h"
|
#include "appInterface.h"
|
||||||
|
@ -21,6 +19,8 @@
|
||||||
#include "utils/scheduler.h"
|
#include "utils/scheduler.h"
|
||||||
|
|
||||||
#include "hm/hmSystem.h"
|
#include "hm/hmSystem.h"
|
||||||
|
#include "hm/hmRadio.h"
|
||||||
|
//#include "hms/hmsRadio.h"
|
||||||
#include "hm/hmPayload.h"
|
#include "hm/hmPayload.h"
|
||||||
#include "hm/miPayload.h"
|
#include "hm/miPayload.h"
|
||||||
#include "wifi/ahoywifi.h"
|
#include "wifi/ahoywifi.h"
|
||||||
|
@ -38,10 +38,10 @@
|
||||||
#define ACOS(x) (degrees(acos(x)))
|
#define ACOS(x) (degrees(acos(x)))
|
||||||
|
|
||||||
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
|
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
|
||||||
typedef HmPayload<HmSystemType> PayloadType;
|
typedef HmPayload<HmSystemType, HmRadio<>> PayloadType;
|
||||||
typedef MiPayload<HmSystemType> MiPayloadType;
|
typedef MiPayload<HmSystemType, HmRadio<>> MiPayloadType;
|
||||||
typedef Web<HmSystemType> WebType;
|
typedef Web<HmSystemType> WebType;
|
||||||
typedef RestApi<HmSystemType> RestApiType;
|
typedef RestApi<HmSystemType, HmRadio<>> RestApiType;
|
||||||
typedef PubMqtt<HmSystemType> PubMqttType;
|
typedef PubMqtt<HmSystemType> PubMqttType;
|
||||||
typedef PubSerial<HmSystemType> PubSerialType;
|
typedef PubSerial<HmSystemType> PubSerialType;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
void regularTickers(void);
|
void regularTickers(void);
|
||||||
|
|
||||||
void handleIntr(void) {
|
void handleIntr(void) {
|
||||||
mSys.Radio.handleIntr();
|
mNrfRadio.handleIntr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleHmsIntr(void) {
|
void handleHmsIntr(void) {
|
||||||
|
@ -160,11 +160,24 @@ class app : public IApp, public ah::Scheduler {
|
||||||
return mWeb.getProtection();
|
return mWeb.getProtection();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getIrqPin(void) {
|
void getNrfRadioCounters(uint32_t *sendCnt, uint32_t *retransmits) {
|
||||||
|
*sendCnt = mNrfRadio.mSendCnt;
|
||||||
|
*retransmits = mNrfRadio.mRetransmits;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getNrfEnabled(void) {
|
||||||
|
return mConfig->nrf.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getCmtEnabled(void) {
|
||||||
|
return mConfig->cmt.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getNrfIrqPin(void) {
|
||||||
return mConfig->nrf.pinIrq;
|
return mConfig->nrf.pinIrq;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getHmsIrqPin(void) {
|
uint8_t getCmtIrqPin(void) {
|
||||||
return mConfig->cmt.pinIrq;
|
return mConfig->cmt.pinIrq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +212,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
}
|
}
|
||||||
|
|
||||||
HmSystemType mSys;
|
HmSystemType mSys;
|
||||||
|
HmRadio<> mNrfRadio;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::function<void()> innerLoopCb;
|
typedef std::function<void()> innerLoopCb;
|
||||||
|
|
|
@ -46,6 +46,9 @@ class IApp {
|
||||||
virtual uint32_t getMqttTxCnt() = 0;
|
virtual uint32_t getMqttTxCnt() = 0;
|
||||||
|
|
||||||
virtual bool getProtection() = 0;
|
virtual bool getProtection() = 0;
|
||||||
|
|
||||||
|
virtual void getNrfRadioCounters(uint32_t *sendCnt, uint32_t *retransmits) = 0;
|
||||||
|
//virtual void getCmtRadioCounters(uint32_t *sendCnt, uint32_t *retransmits) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__IAPP_H__*/
|
#endif /*__IAPP_H__*/
|
||||||
|
|
|
@ -60,6 +60,7 @@ typedef struct {
|
||||||
} cfgSys_t;
|
} cfgSys_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
bool enabled;
|
||||||
uint16_t sendInterval;
|
uint16_t sendInterval;
|
||||||
uint8_t maxRetransPerPyld;
|
uint8_t maxRetransPerPyld;
|
||||||
uint8_t pinCs;
|
uint8_t pinCs;
|
||||||
|
@ -69,6 +70,7 @@ typedef struct {
|
||||||
} cfgNrf24_t;
|
} cfgNrf24_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
bool enabled;
|
||||||
uint8_t pinCsb;
|
uint8_t pinCsb;
|
||||||
uint8_t pinFcsb;
|
uint8_t pinFcsb;
|
||||||
uint8_t pinIrq;
|
uint8_t pinIrq;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,15 @@ typedef std::function<void(uint8_t)> payloadListenerType;
|
||||||
typedef std::function<void(uint16_t alarmCode, uint32_t start, uint32_t end)> alarmListenerType;
|
typedef std::function<void(uint16_t alarmCode, uint32_t start, uint32_t end)> alarmListenerType;
|
||||||
|
|
||||||
|
|
||||||
template<class HMSYSTEM>
|
template<class HMSYSTEM, class HMRADIO>
|
||||||
class HmPayload {
|
class HmPayload {
|
||||||
public:
|
public:
|
||||||
HmPayload() {}
|
HmPayload() {}
|
||||||
|
|
||||||
void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
|
void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
|
||||||
mApp = app;
|
mApp = app;
|
||||||
mSys = sys;
|
mSys = sys;
|
||||||
|
mRadio = radio;
|
||||||
mStat = stat;
|
mStat = stat;
|
||||||
mMaxRetrans = maxRetransmits;
|
mMaxRetrans = maxRetransmits;
|
||||||
mTimestamp = timestamp;
|
mTimestamp = timestamp;
|
||||||
|
@ -149,7 +150,7 @@ class HmPayload {
|
||||||
DBGPRINT(F(" power limit "));
|
DBGPRINT(F(" power limit "));
|
||||||
DBGPRINTLN(String(iv->powerLimit[0]));
|
DBGPRINTLN(String(iv->powerLimit[0]));
|
||||||
}
|
}
|
||||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false);
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false);
|
||||||
mPayload[iv->id].txCmd = iv->devControlCmd;
|
mPayload[iv->id].txCmd = iv->devControlCmd;
|
||||||
//iv->clearCmdQueue();
|
//iv->clearCmdQueue();
|
||||||
//iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
//iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
||||||
|
@ -158,7 +159,7 @@ class HmPayload {
|
||||||
DPRINT(DBG_INFO, F("(#"));
|
DPRINT(DBG_INFO, F("(#"));
|
||||||
DBGPRINT(String(iv->id));
|
DBGPRINT(String(iv->id));
|
||||||
DBGPRINT(F(") prepareDevInformCmd")); // + String(cmd, HEX));
|
DBGPRINT(F(") prepareDevInformCmd")); // + String(cmd, HEX));
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
|
||||||
mPayload[iv->id].txCmd = cmd;
|
mPayload[iv->id].txCmd = cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,14 +244,14 @@ class HmPayload {
|
||||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||||
} else if(iv->devControlCmd == ActivePowerContr) {
|
} else if(iv->devControlCmd == ActivePowerContr) {
|
||||||
DPRINTLN(DBG_INFO, F("retransmit power limit"));
|
DPRINTLN(DBG_INFO, F("retransmit power limit"));
|
||||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true);
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true);
|
||||||
} else {
|
} else {
|
||||||
if(false == mPayload[iv->id].gotFragment) {
|
if(false == mPayload[iv->id].gotFragment) {
|
||||||
/*
|
/*
|
||||||
DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit"));
|
DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit"));
|
||||||
mPayload[iv->id].txCmd = iv->getQueuedCmd();
|
mPayload[iv->id].txCmd = iv->getQueuedCmd();
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
||||||
*/
|
*/
|
||||||
DPRINT(DBG_INFO, F("(#"));
|
DPRINT(DBG_INFO, F("(#"));
|
||||||
DBGPRINT(String(iv->id));
|
DBGPRINT(String(iv->id));
|
||||||
|
@ -262,7 +263,7 @@ class HmPayload {
|
||||||
DPRINT(DBG_WARN, F("Frame "));
|
DPRINT(DBG_WARN, F("Frame "));
|
||||||
DBGPRINT(String(i + 1));
|
DBGPRINT(String(i + 1));
|
||||||
DBGPRINTLN(F(" missing: Request Retransmit"));
|
DBGPRINTLN(F(" missing: Request Retransmit"));
|
||||||
mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
||||||
break; // only request retransmit one frame per loop
|
break; // only request retransmit one frame per loop
|
||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
|
@ -280,7 +281,7 @@ class HmPayload {
|
||||||
DBGPRINT(String(iv->id));
|
DBGPRINT(String(iv->id));
|
||||||
DBGPRINT(F(") prepareDevInformCmd 0x"));
|
DBGPRINT(F(") prepareDevInformCmd 0x"));
|
||||||
DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX));
|
DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX));
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
||||||
}
|
}
|
||||||
} else { // payload complete
|
} else { // payload complete
|
||||||
DPRINT(DBG_INFO, F("procPyld: cmd: 0x"));
|
DPRINT(DBG_INFO, F("procPyld: cmd: 0x"));
|
||||||
|
@ -407,6 +408,7 @@ class HmPayload {
|
||||||
|
|
||||||
IApp *mApp;
|
IApp *mApp;
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys;
|
||||||
|
HMRADIO *mRadio;
|
||||||
statistics_t *mStat;
|
statistics_t *mStat;
|
||||||
uint8_t mMaxRetrans;
|
uint8_t mMaxRetrans;
|
||||||
uint32_t *mTimestamp;
|
uint32_t *mTimestamp;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://github.com/lumpapu/ahoy
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -7,23 +7,14 @@
|
||||||
#define __HM_SYSTEM_H__
|
#define __HM_SYSTEM_H__
|
||||||
|
|
||||||
#include "hmInverter.h"
|
#include "hmInverter.h"
|
||||||
#include "hmRadio.h"
|
|
||||||
|
|
||||||
template <uint8_t MAX_INVERTER=3, class INVERTERTYPE=Inverter<float>>
|
template <uint8_t MAX_INVERTER=3, class INVERTERTYPE=Inverter<float>>
|
||||||
class HmSystem {
|
class HmSystem {
|
||||||
public:
|
public:
|
||||||
HmRadio<> Radio;
|
|
||||||
|
|
||||||
HmSystem() {}
|
HmSystem() {}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
mNumInv = 0;
|
mNumInv = 0;
|
||||||
Radio.setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup(uint8_t ampPwr, uint8_t irqPin, uint8_t cePin, uint8_t csPin) {
|
|
||||||
mNumInv = 0;
|
|
||||||
Radio.setup(ampPwr, irqPin, cePin, csPin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addInverters(cfgInst_t *config) {
|
void addInverters(cfgInst_t *config) {
|
||||||
|
@ -124,10 +115,6 @@ class HmSystem {
|
||||||
return MAX_NUM_INVERTERS;
|
return MAX_NUM_INVERTERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableDebug() {
|
|
||||||
Radio.enableDebug();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INVERTERTYPE mInverter[MAX_INVERTER];
|
INVERTERTYPE mInverter[MAX_INVERTER];
|
||||||
uint8_t mNumInv;
|
uint8_t mNumInv;
|
||||||
|
|
|
@ -35,14 +35,15 @@ typedef struct {
|
||||||
typedef std::function<void(uint8_t)> miPayloadListenerType;
|
typedef std::function<void(uint8_t)> miPayloadListenerType;
|
||||||
|
|
||||||
|
|
||||||
template<class HMSYSTEM>
|
template<class HMSYSTEM, class HMRADIO>
|
||||||
class MiPayload {
|
class MiPayload {
|
||||||
public:
|
public:
|
||||||
MiPayload() {}
|
MiPayload() {}
|
||||||
|
|
||||||
void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
|
void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) {
|
||||||
mApp = app;
|
mApp = app;
|
||||||
mSys = sys;
|
mSys = sys;
|
||||||
|
mRadio = radio;
|
||||||
mStat = stat;
|
mStat = stat;
|
||||||
mMaxRetrans = maxRetransmits;
|
mMaxRetrans = maxRetransmits;
|
||||||
mTimestamp = timestamp;
|
mTimestamp = timestamp;
|
||||||
|
@ -86,7 +87,7 @@ class MiPayload {
|
||||||
|
|
||||||
uint8_t cmd = iv->type == INV_TYPE_4CH ? 0x36 : 0x09; //iv->getQueuedCmd();
|
uint8_t cmd = iv->type == INV_TYPE_4CH ? 0x36 : 0x09; //iv->getQueuedCmd();
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd"));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd"));
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd);
|
||||||
mPayload[iv->id].txCmd = cmd;
|
mPayload[iv->id].txCmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +105,8 @@ class MiPayload {
|
||||||
miDataDecode(iv,p);
|
miDataDecode(iv,p);
|
||||||
iv->setQueuedCmdFinished();
|
iv->setQueuedCmdFinished();
|
||||||
if (INV_TYPE_2CH == iv->type) {
|
if (INV_TYPE_2CH == iv->type) {
|
||||||
//mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
//mRadio->prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, 0x11, mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, 0x11, mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
||||||
} else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?)
|
} else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?)
|
||||||
mPayload[iv->id].complete = true;
|
mPayload[iv->id].complete = true;
|
||||||
//iv->setQueuedCmdFinished();
|
//iv->setQueuedCmdFinished();
|
||||||
|
@ -122,8 +123,8 @@ class MiPayload {
|
||||||
miDataDecode(iv,p);
|
miDataDecode(iv,p);
|
||||||
iv->setQueuedCmdFinished();
|
iv->setQueuedCmdFinished();
|
||||||
if (p->packet[0] < (0x39 + ALL_FRAMES)) {
|
if (p->packet[0] < (0x39 + ALL_FRAMES)) {
|
||||||
//mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES);
|
//mRadio->prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES);
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, p->packet[0] + 1 - ALL_FRAMES, mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, p->packet[0] + 1 - ALL_FRAMES, mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES);
|
||||||
} else {
|
} else {
|
||||||
mPayload[iv->id].complete = true;
|
mPayload[iv->id].complete = true;
|
||||||
//iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0);
|
//iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0);
|
||||||
|
@ -259,12 +260,12 @@ class MiPayload {
|
||||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||||
} else if(iv->devControlCmd == ActivePowerContr) {
|
} else if(iv->devControlCmd == ActivePowerContr) {
|
||||||
DPRINTLN(DBG_INFO, F("retransmit power limit"));
|
DPRINTLN(DBG_INFO, F("retransmit power limit"));
|
||||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true);
|
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true);
|
||||||
} else {
|
} else {
|
||||||
if (mPayload[iv->id].retransmits < mMaxRetrans) {
|
if (mPayload[iv->id].retransmits < mMaxRetrans) {
|
||||||
mPayload[iv->id].retransmits++;
|
mPayload[iv->id].retransmits++;
|
||||||
//mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
//mRadio->prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
|
||||||
mSys->Radio.sendCmdPacket(iv->radioId.u64, iv->getQueuedCmd(), 24, true);
|
mRadio->sendCmdPacket(iv->radioId.u64, iv->getQueuedCmd(), 24, true);
|
||||||
/*if(false == mPayload[iv->id].gotFragment) {
|
/*if(false == mPayload[iv->id].gotFragment) {
|
||||||
DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received"));
|
DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received"));
|
||||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||||
|
@ -272,7 +273,7 @@ class MiPayload {
|
||||||
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
|
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
|
||||||
if (mPayload[iv->id].len[i] == 0) {
|
if (mPayload[iv->id].len[i] == 0) {
|
||||||
DPRINTLN(DBG_WARN, F("Frame ") + String(i + 1) + F(" missing: Request Retransmit"));
|
DPRINTLN(DBG_WARN, F("Frame ") + String(i + 1) + F(" missing: Request Retransmit"));
|
||||||
mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
||||||
break; // only request retransmit one frame per loop
|
break; // only request retransmit one frame per loop
|
||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
|
@ -287,7 +288,7 @@ class MiPayload {
|
||||||
DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit"));
|
DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit"));
|
||||||
mPayload[iv->id].txCmd = iv->getQueuedCmd();
|
mPayload[iv->id].txCmd = iv->getQueuedCmd();
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
||||||
}
|
}
|
||||||
} /*else { // payload complete
|
} /*else { // payload complete
|
||||||
DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX));
|
DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||||
|
@ -310,7 +311,7 @@ class MiPayload {
|
||||||
|
|
||||||
if (mSerialDebug) {
|
if (mSerialDebug) {
|
||||||
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
||||||
mSys->Radio.dumpBuf(payload, payloadLen);
|
ah::dumpBuf(payload, payloadLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == rec) {
|
if (NULL == rec) {
|
||||||
|
@ -552,6 +553,7 @@ class MiPayload {
|
||||||
|
|
||||||
IApp *mApp;
|
IApp *mApp;
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys;
|
||||||
|
HMRADIO *mRadio;
|
||||||
statistics_t *mStat;
|
statistics_t *mStat;
|
||||||
uint8_t mMaxRetrans;
|
uint8_t mMaxRetrans;
|
||||||
uint32_t *mTimestamp;
|
uint32_t *mTimestamp;
|
||||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -1,12 +1,10 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
|
// 2023 Ahoy, https://www.mikrocontroller.net/topic/525778
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "utils/dbg.h"
|
#include "utils/dbg.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "config/config.h"
|
|
||||||
|
|
||||||
|
|
||||||
app myApp;
|
app myApp;
|
||||||
|
|
||||||
|
@ -20,13 +18,14 @@ IRAM_ATTR void handleHmsIntr(void) {
|
||||||
myApp.handleHmsIntr();
|
myApp.handleHmsIntr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void setup() {
|
void setup() {
|
||||||
myApp.setup();
|
myApp.setup();
|
||||||
|
|
||||||
attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING);
|
if(myApp.getNrfEnabled())
|
||||||
attachInterrupt(digitalPinToInterrupt(myApp.getHmsIrqPin()), handleHmsIntr, RISING);
|
attachInterrupt(digitalPinToInterrupt(myApp.getNrfIrqPin()), handleIntr, FALLING);
|
||||||
|
if(myApp.getCmtEnabled())
|
||||||
|
attachInterrupt(digitalPinToInterrupt(myApp.getCmtIrqPin()), handleHmsIntr, RISING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define F(sl) (sl)
|
#define F(sl) (sl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class HMSYSTEM>
|
template<class HMSYSTEM, class HMRADIO>
|
||||||
class RestApi {
|
class RestApi {
|
||||||
public:
|
public:
|
||||||
RestApi() {
|
RestApi() {
|
||||||
|
@ -35,10 +35,11 @@ class RestApi {
|
||||||
nr = 0;
|
nr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(IApp *app, HMSYSTEM *sys, AsyncWebServer *srv, settings_t *config) {
|
void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, AsyncWebServer *srv, settings_t *config) {
|
||||||
mApp = app;
|
mApp = app;
|
||||||
mSrv = srv;
|
mSrv = srv;
|
||||||
mSys = sys;
|
mSys = sys;
|
||||||
|
mRadio = radio;
|
||||||
mConfig = config;
|
mConfig = config;
|
||||||
mSrv->on("/api", HTTP_GET, std::bind(&RestApi::onApi, this, std::placeholders::_1));
|
mSrv->on("/api", HTTP_GET, std::bind(&RestApi::onApi, this, std::placeholders::_1));
|
||||||
mSrv->on("/api", HTTP_POST, std::bind(&RestApi::onApiPost, this, std::placeholders::_1)).onBody(
|
mSrv->on("/api", HTTP_POST, std::bind(&RestApi::onApiPost, this, std::placeholders::_1)).onBody(
|
||||||
|
@ -281,8 +282,8 @@ class RestApi {
|
||||||
obj[F("rx_fail")] = stat->rxFail;
|
obj[F("rx_fail")] = stat->rxFail;
|
||||||
obj[F("rx_fail_answer")] = stat->rxFailNoAnser;
|
obj[F("rx_fail_answer")] = stat->rxFailNoAnser;
|
||||||
obj[F("frame_cnt")] = stat->frmCnt;
|
obj[F("frame_cnt")] = stat->frmCnt;
|
||||||
obj[F("tx_cnt")] = mSys->Radio.mSendCnt;
|
obj[F("tx_cnt")] = mRadio->mSendCnt;
|
||||||
obj[F("retransmits")] = mSys->Radio.mRetransmits;
|
obj[F("retransmits")] = mRadio->mRetransmits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getInverterList(JsonObject obj) {
|
void getInverterList(JsonObject obj) {
|
||||||
|
@ -346,9 +347,9 @@ class RestApi {
|
||||||
|
|
||||||
void getRadio(JsonObject obj) {
|
void getRadio(JsonObject obj) {
|
||||||
obj[F("power_level")] = mConfig->nrf.amplifierPower;
|
obj[F("power_level")] = mConfig->nrf.amplifierPower;
|
||||||
obj[F("isconnected")] = mSys->Radio.isChipConnected();
|
obj[F("isconnected")] = mRadio->isChipConnected();
|
||||||
obj[F("DataRate")] = mSys->Radio.getDataRate();
|
obj[F("DataRate")] = mRadio->getDataRate();
|
||||||
obj[F("isPVariant")] = mSys->Radio.isPVariant();
|
obj[F("isPVariant")] = mRadio->isPVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getSerial(JsonObject obj) {
|
void getSerial(JsonObject obj) {
|
||||||
|
@ -449,9 +450,9 @@ class RestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray warn = obj.createNestedArray(F("warnings"));
|
JsonArray warn = obj.createNestedArray(F("warnings"));
|
||||||
if(!mSys->Radio.isChipConnected())
|
if(!mRadio->isChipConnected())
|
||||||
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
||||||
else if(!mSys->Radio.isPVariant())
|
else if(!mRadio->isPVariant())
|
||||||
warn.add(F("your NRF24 module isn't a plus version(+), maybe incompatible"));
|
warn.add(F("your NRF24 module isn't a plus version(+), maybe incompatible"));
|
||||||
if(!mApp->getSettingsValid())
|
if(!mApp->getSettingsValid())
|
||||||
warn.add(F("your settings are invalid"));
|
warn.add(F("your settings are invalid"));
|
||||||
|
@ -633,6 +634,7 @@ class RestApi {
|
||||||
|
|
||||||
IApp *mApp;
|
IApp *mApp;
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys;
|
||||||
|
HMRADIO *mRadio;
|
||||||
AsyncWebServer *mSrv;
|
AsyncWebServer *mSrv;
|
||||||
settings_t *mConfig;
|
settings_t *mConfig;
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,7 @@ class Web {
|
||||||
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
mConfig->serial.debug = (request->arg("serDbg") == "on");
|
||||||
mConfig->serial.showIv = (request->arg("serEn") == "on");
|
mConfig->serial.showIv = (request->arg("serEn") == "on");
|
||||||
// Needed to log TX buffers to serial console
|
// Needed to log TX buffers to serial console
|
||||||
mSys->Radio.mSerialDebug = mConfig->serial.debug;
|
// mSys->Radio.mSerialDebug = mConfig->serial.debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
// display
|
// display
|
||||||
|
@ -767,11 +767,14 @@ class Web {
|
||||||
|
|
||||||
// NRF Statistics
|
// NRF Statistics
|
||||||
stat = mApp->getStatistics();
|
stat = mApp->getStatistics();
|
||||||
|
uint32_t *nrfSendCnt, *nrfRetransmits;
|
||||||
|
mApp->getNrfRadioCounters(nrfSendCnt, nrfRetransmits);
|
||||||
metrics += radioStatistic(F("rx_success"), stat->rxSuccess);
|
metrics += radioStatistic(F("rx_success"), stat->rxSuccess);
|
||||||
metrics += radioStatistic(F("rx_fail"), stat->rxFail);
|
metrics += radioStatistic(F("rx_fail"), stat->rxFail);
|
||||||
metrics += radioStatistic(F("rx_fail_answer"), stat->rxFailNoAnser);
|
metrics += radioStatistic(F("rx_fail_answer"), stat->rxFailNoAnser);
|
||||||
metrics += radioStatistic(F("frame_cnt"), stat->frmCnt);
|
metrics += radioStatistic(F("frame_cnt"), stat->frmCnt);
|
||||||
metrics += radioStatistic(F("tx_cnt"), mSys->Radio.mSendCnt);
|
metrics += radioStatistic(F("tx_cnt"), *nrfSendCnt);
|
||||||
|
metrics += radioStatistic(F("retrans_cnt"), *nrfRetransmits);
|
||||||
|
|
||||||
len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str());
|
len = snprintf((char *)buffer,maxLen,"%s",metrics.c_str());
|
||||||
// Start Inverter loop
|
// Start Inverter loop
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue