mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-22 21:36:11 +02:00
added part of mac address to MQTT client ID to seperate multiple ESPs in same network added dictionary for MQTT to reduce heap-fragmentation removed `last Alarm` from Live view, because it showed always the same alarm - will change in future
This commit is contained in:
parent
fe54599502
commit
a0879cfcbe
17 changed files with 393 additions and 148 deletions
|
@ -2,6 +2,12 @@
|
|||
|
||||
(starting from release version `0.5.66`)
|
||||
|
||||
## 0.5.89
|
||||
* reduced heap fragmentation (removed `strtok` completely) #644, #645, #682
|
||||
* added part of mac address to MQTT client ID to seperate multiple ESPs in same network
|
||||
* added dictionary for MQTT to reduce heap-fragmentation
|
||||
* removed `last Alarm` from Live view, because it showed always the same alarm - will change in future
|
||||
|
||||
## 0.5.88
|
||||
* MQTT Yield Day zero, next try to fix #671, thx @beegee3
|
||||
* added Solenso inverter to supported devices
|
||||
|
|
45
src/app.cpp
45
src/app.cpp
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -21,9 +21,19 @@ void app::setup() {
|
|||
|
||||
resetSystem();
|
||||
|
||||
/*DBGPRINTLN("--- start");
|
||||
DBGPRINTLN(String(ESP.getFreeHeap()));
|
||||
DBGPRINTLN(String(ESP.getHeapFragmentation()));
|
||||
DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/
|
||||
|
||||
|
||||
mSettings.setup();
|
||||
mSettings.getPtr(mConfig);
|
||||
DPRINTLN(DBG_INFO, F("Settings valid: ") + String((mSettings.getValid()) ? F("true") : F("false")));
|
||||
DPRINT(DBG_INFO, F("Settings valid: "));
|
||||
if(mSettings.getValid())
|
||||
DBGPRINTLN(F("true"));
|
||||
else
|
||||
DBGPRINTLN(F("false"));
|
||||
|
||||
mSys.enableDebug();
|
||||
mSys.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs);
|
||||
|
@ -47,6 +57,11 @@ void app::setup() {
|
|||
mMiPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
|
||||
mMiPayload.enableSerialDebug(mConfig->serial.debug);
|
||||
|
||||
/*DBGPRINTLN("--- after payload");
|
||||
DBGPRINTLN(String(ESP.getFreeHeap()));
|
||||
DBGPRINTLN(String(ESP.getHeapFragmentation()));
|
||||
DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/
|
||||
|
||||
if(!mSys.Radio.isChipConnected())
|
||||
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
||||
|
||||
|
@ -73,6 +88,12 @@ void app::setup() {
|
|||
mPubSerial.setup(mConfig, &mSys, &mTimestamp);
|
||||
|
||||
regularTickers();
|
||||
|
||||
|
||||
/*DBGPRINTLN("--- end setup");
|
||||
DBGPRINTLN(String(ESP.getFreeHeap()));
|
||||
DBGPRINTLN(String(ESP.getHeapFragmentation()));
|
||||
DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -89,7 +110,11 @@ void app::loopStandard(void) {
|
|||
packet_t *p = &mSys.Radio.mBufCtrl.front();
|
||||
|
||||
if (mConfig->serial.debug) {
|
||||
DPRINT(DBG_INFO, "RX " + String(p->len) + "B Ch" + String(p->ch) + " | ");
|
||||
DPRINT(DBG_INFO, F("RX "));
|
||||
DBGPRINT(String(p->len));
|
||||
DBGPRINT(F("B Ch"));
|
||||
DBGPRINT(String(p->ch));
|
||||
DBGPRINT(F(" | "));
|
||||
mSys.Radio.dumpBuf(p->packet, p->len);
|
||||
}
|
||||
mStat.frmCnt++;
|
||||
|
@ -158,13 +183,13 @@ void app::tickNtpUpdate(void) {
|
|||
bool isOK = mWifi.getNtpTime();
|
||||
if (isOK || mTimestamp != 0) {
|
||||
if (mMqttReconnect && mMqttEnabled) {
|
||||
mMqtt.connect();
|
||||
mMqtt.tickerMinute();
|
||||
everySec(std::bind(&PubMqttType::tickerSecond, &mMqtt), "mqttS");
|
||||
everyMin(std::bind(&PubMqttType::tickerMinute, &mMqtt), "mqttM");
|
||||
}
|
||||
|
||||
// only install schedulers once even if NTP wasn't successful in first loop
|
||||
if(mMqttReconnect) { // @TODO: mMqttReconnect is wrong name here
|
||||
if(mMqttReconnect) { // @TODO: mMqttReconnect is variable which scope has changed
|
||||
if(mConfig->inst.rstValsNotAvail)
|
||||
everyMin(std::bind(&app::tickMinute, this), "tMin");
|
||||
if(mConfig->inst.rstYieldMidNight) {
|
||||
|
@ -282,8 +307,6 @@ void app::tickMidnight(void) {
|
|||
uint32_t nxtTrig = mTimestamp - ((mTimestamp - 1) % 86400) + 86400; // next midnight
|
||||
onceAt(std::bind(&app::tickMidnight, this), nxtTrig, "mid2");
|
||||
|
||||
DPRINTLN(DBG_INFO, "tickMidnight " + String(nxtTrig));
|
||||
|
||||
Inverter<> *iv;
|
||||
// set values to zero, except yield total
|
||||
for (uint8_t id = 0; id < mSys.getNumInverters(); id++) {
|
||||
|
@ -302,13 +325,15 @@ void app::tickMidnight(void) {
|
|||
//-----------------------------------------------------------------------------
|
||||
void app::tickSend(void) {
|
||||
if(!mSys.Radio.isChipConnected()) {
|
||||
DPRINTLN(DBG_WARN, "NRF24 not connected!");
|
||||
DPRINTLN(DBG_WARN, F("NRF24 not connected!"));
|
||||
return;
|
||||
}
|
||||
if (mIVCommunicationOn) {
|
||||
if (!mSys.Radio.mBufCtrl.empty()) {
|
||||
if (mConfig->serial.debug)
|
||||
DPRINTLN(DBG_DEBUG, F("recbuf not empty! #") + String(mSys.Radio.mBufCtrl.size()));
|
||||
if (mConfig->serial.debug) {
|
||||
DPRINT(DBG_DEBUG, F("recbuf not empty! #"));
|
||||
DBGPRINTLN(String(mSys.Radio.mBufCtrl.size()));
|
||||
}
|
||||
}
|
||||
|
||||
int8_t maxLoop = MAX_NUM_INVERTERS;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -182,7 +182,8 @@ class app : public IApp, public ah::Scheduler {
|
|||
}
|
||||
|
||||
void setTimestamp(uint32_t newTime) {
|
||||
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
|
||||
DPRINT(DBG_DEBUG, F("setTimestamp: "));
|
||||
DBGPRINTLN(String(newTime));
|
||||
if(0 == newTime)
|
||||
mWifi.getNtpTime();
|
||||
else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -212,7 +212,6 @@ class settings {
|
|||
}
|
||||
|
||||
bool readSettings(const char* path) {
|
||||
bool success = false;
|
||||
loadDefaults();
|
||||
File fp = LittleFS.open(path, "r");
|
||||
if(!fp)
|
||||
|
@ -233,7 +232,6 @@ class settings {
|
|||
jsonLed(root[F("led")]);
|
||||
jsonPlugin(root[F("plugin")]);
|
||||
jsonInst(root[F("inst")]);
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
Serial.println(F("failed to parse json, using default config"));
|
||||
|
@ -241,7 +239,7 @@ class settings {
|
|||
|
||||
fp.close();
|
||||
}
|
||||
return success;
|
||||
return mCfg.valid;
|
||||
}
|
||||
|
||||
bool saveSettings(void) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 88
|
||||
#define VERSION_PATCH 89
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -119,7 +119,7 @@ class Inverter {
|
|||
record_t<REC_TYP> recordInfo; // structure for info values
|
||||
record_t<REC_TYP> recordConfig; // structure for system config values
|
||||
record_t<REC_TYP> recordAlarm; // structure for alarm values
|
||||
String lastAlarmMsg;
|
||||
//String lastAlarmMsg;
|
||||
bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null)
|
||||
bool isConnected; // shows if inverter was successfully identified (fw version and hardware info)
|
||||
|
||||
|
@ -131,7 +131,7 @@ class Inverter {
|
|||
mDevControlRequest = false;
|
||||
devControlCmd = InitDataState;
|
||||
initialized = false;
|
||||
lastAlarmMsg = "nothing";
|
||||
//lastAlarmMsg = "nothing";
|
||||
alarmMesIndex = 0;
|
||||
isConnected = false;
|
||||
}
|
||||
|
@ -294,9 +294,9 @@ class Inverter {
|
|||
}
|
||||
else if (rec->assign == AlarmDataAssignment) {
|
||||
DPRINTLN(DBG_DEBUG, "add alarm");
|
||||
if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){
|
||||
lastAlarmMsg = getAlarmStr(rec->record[pos]);
|
||||
}
|
||||
//if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){
|
||||
// lastAlarmMsg = getAlarmStr(rec->record[pos]);
|
||||
//}
|
||||
}
|
||||
else
|
||||
DPRINTLN(DBG_WARN, F("add with unknown assginment"));
|
||||
|
@ -305,6 +305,11 @@ class Inverter {
|
|||
DPRINTLN(DBG_ERROR, F("addValue: assignment not found with cmd 0x"));
|
||||
}
|
||||
|
||||
/*inline REC_TYP getPowerLimit(void) {
|
||||
record_t<> *rec = getRecordStruct(SystemConfigPara);
|
||||
return getChannelFieldValue(CH0, FLD_ACT_ACTIVE_PWR_LIMIT, rec);
|
||||
}*/
|
||||
|
||||
bool setValue(uint8_t pos, record_t<> *rec, REC_TYP val) {
|
||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:setValue"));
|
||||
if(NULL == rec)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -71,7 +71,7 @@ class HmPayload {
|
|||
}
|
||||
|
||||
void zeroYieldDay(Inverter<> *iv) {
|
||||
DPRINTLN(DBG_INFO, "zeroYieldDay");
|
||||
DPRINTLN(DBG_DEBUG, F("zeroYieldDay"));
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
uint8_t pos;
|
||||
for(uint8_t ch = 0; ch < iv->channels; ch++) {
|
||||
|
@ -81,7 +81,7 @@ class HmPayload {
|
|||
}
|
||||
|
||||
void zeroInverterValues(Inverter<> *iv) {
|
||||
DPRINTLN(DBG_INFO, "zeroInverterValues");
|
||||
DPRINTLN(DBG_DEBUG, F("zeroInverterValues"));
|
||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
for(uint8_t ch = 0; ch <= iv->channels; ch++) {
|
||||
uint8_t pos = 0;
|
||||
|
@ -119,8 +119,11 @@ class HmPayload {
|
|||
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) + ")");
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(") no Payload received! (retransmits: "));
|
||||
DBGPRINT(String(mPayload[iv->id].retransmits));
|
||||
DBGPRINTLN(F(")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,19 +133,31 @@ class HmPayload {
|
|||
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 (mSerialDebug) {
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(") Requesting Inv SN "));
|
||||
DBGPRINTLN(String(iv->config->serial.u64, HEX));
|
||||
}
|
||||
|
||||
if (iv->getDevControlRequest()) {
|
||||
if (mSerialDebug)
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Devcontrol request 0x") + String(iv->devControlCmd, HEX) + F(" power limit ") + String(iv->powerLimit[0]));
|
||||
if (mSerialDebug) {
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(") Devcontrol request 0x"));
|
||||
DBGPRINT(String(iv->devControlCmd, HEX));
|
||||
DBGPRINT(F(" power limit "));
|
||||
DBGPRINTLN(String(iv->powerLimit[0]));
|
||||
}
|
||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false);
|
||||
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(") prepareDevInformCmd")); // + String(cmd, HEX));
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(") prepareDevInformCmd")); // + String(cmd, HEX));
|
||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
|
||||
mPayload[iv->id].txCmd = cmd;
|
||||
}
|
||||
|
@ -179,12 +194,20 @@ class HmPayload {
|
|||
iv->clearDevControlRequest();
|
||||
|
||||
if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) {
|
||||
String msg = "";
|
||||
bool ok = true;
|
||||
if((p->packet[10] == 0x00) && (p->packet[11] == 0x00))
|
||||
mApp->setMqttPowerLimitAck(iv);
|
||||
else
|
||||
msg = "NOT ";
|
||||
DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(" has ") + msg + F("accepted power limit set point ") + String(iv->powerLimit[0]) + F(" with PowerLimitControl ") + String(iv->powerLimit[1]));
|
||||
ok = false;
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(" has "));
|
||||
if(!ok) DBGPRINT(F("not "));
|
||||
DBGPRINT(F("accepted power limit set point "));
|
||||
DBGPRINT(String(iv->powerLimit[0]));
|
||||
DBGPRINT(F(" with PowerLimitControl "));
|
||||
DBGPRINT(String(iv->powerLimit[1]));
|
||||
|
||||
iv->clearCmdQueue();
|
||||
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
||||
}
|
||||
|
@ -229,12 +252,16 @@ class HmPayload {
|
|||
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);
|
||||
*/
|
||||
DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received"));
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINTLN(F(") nothing received"));
|
||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||
} else {
|
||||
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
|
||||
if (mPayload[iv->id].len[i] == 0) {
|
||||
DPRINTLN(DBG_WARN, F("Frame ") + String(i + 1) + F(" missing: Request Retransmit"));
|
||||
DPRINT(DBG_WARN, F("Frame "));
|
||||
DBGPRINT(String(i + 1));
|
||||
DBGPRINTLN(F(" missing: Request Retransmit"));
|
||||
mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
|
||||
break; // only request retransmit one frame per loop
|
||||
}
|
||||
|
@ -249,12 +276,17 @@ class HmPayload {
|
|||
mPayload[iv->id].retransmits++;
|
||||
DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit"));
|
||||
mPayload[iv->id].txCmd = iv->getQueuedCmd();
|
||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||
DPRINT(DBG_INFO, F("(#"));
|
||||
DBGPRINT(String(iv->id));
|
||||
DBGPRINT(F(") prepareDevInformCmd 0x"));
|
||||
DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX));
|
||||
mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
|
||||
}
|
||||
} else { // payload complete
|
||||
DPRINTLN(DBG_INFO, F("procPyld: cmd: 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||
DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX));
|
||||
DPRINT(DBG_INFO, F("procPyld: cmd: 0x"));
|
||||
DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX));
|
||||
DPRINT(DBG_INFO, F("procPyld: txid: 0x"));
|
||||
DBGPRINTLN(String(mPayload[iv->id].txId, HEX));
|
||||
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
||||
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
||||
mPayload[iv->id].complete = true;
|
||||
|
@ -272,7 +304,9 @@ class HmPayload {
|
|||
payloadLen -= 2;
|
||||
|
||||
if (mSerialDebug) {
|
||||
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
||||
DPRINT(DBG_INFO, F("Payload ("));
|
||||
DBGPRINT(String(payloadLen));
|
||||
DBGPRINT(F("): "));
|
||||
mSys->Radio.dumpBuf(payload, payloadLen);
|
||||
}
|
||||
|
||||
|
@ -304,7 +338,9 @@ class HmPayload {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
|
||||
DPRINT(DBG_ERROR, F("plausibility check failed, expected "));
|
||||
DBGPRINT(String(rec->pyldLen));
|
||||
DBGPRINTLN(F(" bytes"));
|
||||
mStat->rxFail++;
|
||||
}
|
||||
|
||||
|
@ -356,7 +392,8 @@ class HmPayload {
|
|||
}
|
||||
|
||||
void reset(uint8_t id) {
|
||||
DPRINTLN(DBG_INFO, "resetPayload: id: " + String(id));
|
||||
DPRINT(DBG_INFO, "resetPayload: id: ");
|
||||
DBGPRINTLN(String(id));
|
||||
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||
mPayload[id].txCmd = 0;
|
||||
mPayload[id].gotFragment = false;
|
||||
|
|
|
@ -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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -176,7 +176,8 @@ class HmRadio {
|
|||
}
|
||||
|
||||
void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit) {
|
||||
DPRINTLN(DBG_INFO, F("sendControlPacket cmd: 0x") + String(cmd, HEX));
|
||||
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
|
||||
DBGPRINTLN(String(cmd, HEX));
|
||||
initPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME);
|
||||
uint8_t cnt = 10;
|
||||
mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
|
||||
|
@ -294,7 +295,11 @@ class HmRadio {
|
|||
len++;
|
||||
|
||||
if(mSerialDebug) {
|
||||
DPRINT(DBG_INFO, "TX " + String(len) + "B Ch" + String(mRfChLst[mTxChIdx]) + " | ");
|
||||
DPRINT(DBG_INFO, F("TX "));
|
||||
DBGPRINT(String(len));
|
||||
DBGPRINT("B Ch");
|
||||
DBGPRINT(String(mRfChLst[mTxChIdx]));
|
||||
DBGPRINT(F(" | "));
|
||||
dumpBuf(mTxBuf, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
|||
#include "../defines.h"
|
||||
#include "../hm/hmSystem.h"
|
||||
|
||||
#include "pubMqttDefs.h"
|
||||
|
||||
#define QOS_0 0
|
||||
|
||||
typedef std::function<void(JsonObject)> subscriptionCb;
|
||||
|
@ -57,9 +59,11 @@ class PubMqtt {
|
|||
|
||||
if((strlen(mCfgMqtt->user) > 0) && (strlen(mCfgMqtt->pwd) > 0))
|
||||
mClient.setCredentials(mCfgMqtt->user, mCfgMqtt->pwd);
|
||||
mClient.setClientId(mDevName); // TODO: add mac?
|
||||
char clientId[64];
|
||||
snprintf(clientId, 64, "%s_%s-%s-%s", mDevName, WiFi.macAddress().substring(9,11).c_str(), WiFi.macAddress().substring(12,14).c_str(), WiFi.macAddress().substring(15,17).c_str());
|
||||
mClient.setClientId(clientId);
|
||||
mClient.setServer(mCfgMqtt->broker, mCfgMqtt->port);
|
||||
mClient.setWill(mLwtTopic, QOS_0, true, mLwtOffline);
|
||||
mClient.setWill(mLwtTopic, QOS_0, true, mqttStr[MQTT_STR_LWT_NOT_CONN]);
|
||||
mClient.onConnect(std::bind(&PubMqtt::onConnect, this, std::placeholders::_1));
|
||||
mClient.onDisconnect(std::bind(&PubMqtt::onDisconnect, this, std::placeholders::_1));
|
||||
mClient.onMessage(std::bind(&PubMqtt::onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6));
|
||||
|
@ -72,10 +76,6 @@ class PubMqtt {
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void connect() {
|
||||
if(!mClient.connected())
|
||||
mClient.connect();
|
||||
}
|
||||
|
||||
void tickerSecond() {
|
||||
if (mIntervalTimeout > 0)
|
||||
|
@ -100,20 +100,20 @@ class PubMqtt {
|
|||
void tickerMinute() {
|
||||
char val[12];
|
||||
snprintf(val, 12, "%ld", millis() / 1000);
|
||||
publish("uptime", val);
|
||||
publish("wifi_rssi", String(WiFi.RSSI()).c_str());
|
||||
publish("free_heap", String(ESP.getFreeHeap()).c_str());
|
||||
publish(subtopics[MQTT_UPTIME], val);
|
||||
publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str());
|
||||
publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str());
|
||||
}
|
||||
|
||||
bool tickerSun(uint32_t sunrise, uint32_t sunset, uint32_t offs, bool disNightCom) {
|
||||
if (!mClient.connected())
|
||||
return false;
|
||||
|
||||
publish("sunrise", String(sunrise).c_str(), true);
|
||||
publish("sunset", String(sunset).c_str(), true);
|
||||
publish("comm_start", String(sunrise - offs).c_str(), true);
|
||||
publish("comm_stop", String(sunset + offs).c_str(), true);
|
||||
publish("dis_night_comm", ((disNightCom) ? "true" : "false"), true);
|
||||
publish(subtopics[MQTT_SUNRISE], String(sunrise).c_str(), true);
|
||||
publish(subtopics[MQTT_SUNSET], String(sunset).c_str(), true);
|
||||
publish(subtopics[MQTT_COMM_START], String(sunrise - offs).c_str(), true);
|
||||
publish(subtopics[MQTT_COMM_STOP], String(sunset + offs).c_str(), true);
|
||||
publish(subtopics[MQTT_DIS_NIGHT_COMM], ((disNightCom) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ class PubMqtt {
|
|||
if (!mClient.connected())
|
||||
return false;
|
||||
|
||||
publish("comm_disabled", ((disabled) ? "true" : "false"), true);
|
||||
publish("comm_dis_ts", String(*mUtcTimestamp).c_str(), true);
|
||||
publish(subtopics[MQTT_COMM_DISABLED], ((disabled) ? dict[STR_TRUE] : dict[STR_FALSE]), true);
|
||||
publish(subtopics[MQTT_COMM_DIS_TS], String(*mUtcTimestamp).c_str(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -138,7 +138,6 @@ class PubMqtt {
|
|||
}
|
||||
|
||||
void payloadEventListener(uint8_t cmd) {
|
||||
connect();
|
||||
if(mClient.connected()) { // prevent overflow if MQTT broker is not reachable but set
|
||||
if((0 == mCfgMqtt->interval) || (RealTimeRunData_Debug != cmd)) // no interval or no live data
|
||||
mSendList.push(cmd);
|
||||
|
@ -290,7 +289,7 @@ class PubMqtt {
|
|||
if (NULL != iv) {
|
||||
char topic[7 + MQTT_TOPIC_LEN];
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ack_pwr_limit", iv->config->name);
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
|
||||
publish(topic, "true", true);
|
||||
}
|
||||
}
|
||||
|
@ -299,18 +298,18 @@ class PubMqtt {
|
|||
void onConnect(bool sessionPreset) {
|
||||
DPRINTLN(DBG_INFO, F("MQTT connected"));
|
||||
|
||||
publish("version", mVersion, true);
|
||||
publish("device", mDevName, true);
|
||||
publish("ip_addr", WiFi.localIP().toString().c_str(), true);
|
||||
publish(subtopics[MQTT_VERSION], mVersion, true);
|
||||
publish(subtopics[MQTT_DEVICE], mDevName, true);
|
||||
publish(subtopics[MQTT_IP_ADDR], WiFi.localIP().toString().c_str(), true);
|
||||
tickerMinute();
|
||||
publish(mLwtTopic, mLwtOnline, true, false);
|
||||
publish(mLwtTopic, mqttStr[MQTT_STR_LWT_CONN], true, false);
|
||||
|
||||
subscribe("ctrl/limit_persistent_relative");
|
||||
subscribe("ctrl/limit_persistent_absolute");
|
||||
subscribe("ctrl/limit_nonpersistent_relative");
|
||||
subscribe("ctrl/limit_nonpersistent_absolute");
|
||||
subscribe("setup/set_time");
|
||||
subscribe("setup/sync_ntp");
|
||||
subscribe(subscr[MQTT_SUBS_LMT_PERI_REL]);
|
||||
subscribe(subscr[MQTT_SUBS_LMT_PERI_ABS]);
|
||||
subscribe(subscr[MQTT_SUBS_LMT_NONPERI_REL]);
|
||||
subscribe(subscr[MQTT_SUBS_LMT_NONPERI_ABS]);
|
||||
subscribe(subscr[MQTT_SUBS_SET_TIME]);
|
||||
subscribe(subscr[MQTT_SUBS_SYNC_NTP]);
|
||||
//subscribe("status/#");
|
||||
}
|
||||
|
||||
|
@ -341,16 +340,14 @@ class PubMqtt {
|
|||
}
|
||||
|
||||
void onMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||
DPRINTLN(DBG_INFO, F("MQTT got topic: ") + String(topic));
|
||||
DPRINT(DBG_INFO, mqttStr[MQTT_STR_GOT_TOPIC]);
|
||||
DBGPRINTLN(String(topic));
|
||||
if(NULL == mSubscriptionCb)
|
||||
return;
|
||||
|
||||
char *tpc = new char[strlen(topic) + 1];
|
||||
uint8_t cnt = 0;
|
||||
DynamicJsonDocument json(128);
|
||||
JsonObject root = json.to<JsonObject>();
|
||||
|
||||
strncpy(tpc, topic, strlen(topic) + 1);
|
||||
if(len > 0) {
|
||||
char *pyld = new char[len + 1];
|
||||
strncpy(pyld, (const char*)payload, len);
|
||||
|
@ -359,34 +356,28 @@ class PubMqtt {
|
|||
delete[] pyld;
|
||||
}
|
||||
|
||||
char *p = strtok(tpc, "/");
|
||||
p = strtok(NULL, "/"); // remove mCfgMqtt->topic
|
||||
while(NULL != p) {
|
||||
if(0 == cnt) {
|
||||
if(0 == strncmp(p, "ctrl", 4)) {
|
||||
if(NULL != (p = strtok(NULL, "/"))) {
|
||||
root[F("path")] = F("ctrl");
|
||||
root[F("cmd")] = p;
|
||||
const char *p = topic;
|
||||
uint8_t pos = 0;
|
||||
uint8_t elm = 0;
|
||||
char tmp[30];
|
||||
|
||||
while(1) {
|
||||
if(('/' == p[pos]) || ('\0' == p[pos])) {
|
||||
strncpy(tmp, p, pos);
|
||||
tmp[pos] = '\0';
|
||||
switch(elm++) {
|
||||
case 1: root[F("path")] = String(tmp); break;
|
||||
case 2: root[F("cmd")] = String(tmp); break;
|
||||
case 3: root[F("id")] = atoi(tmp); break;
|
||||
default: break;
|
||||
}
|
||||
} else if(0 == strncmp(p, "setup", 5)) {
|
||||
if(NULL != (p = strtok(NULL, "/"))) {
|
||||
root[F("path")] = F("setup");
|
||||
root[F("cmd")] = p;
|
||||
if('\0' == p[pos])
|
||||
break;
|
||||
p = p + pos + 1;
|
||||
pos = 0;
|
||||
}
|
||||
} else if(0 == strncmp(p, "status", 6)) {
|
||||
if(NULL != (p = strtok(NULL, "/"))) {
|
||||
root[F("path")] = F("status");
|
||||
root[F("cmd")] = p;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(1 == cnt) {
|
||||
root[F("id")] = atoi(p);
|
||||
}
|
||||
p = strtok(NULL, "/");
|
||||
cnt++;
|
||||
}
|
||||
delete[] tpc;
|
||||
|
||||
/*char out[128];
|
||||
serializeJson(root, out, 128);
|
||||
|
@ -447,11 +438,11 @@ class PubMqtt {
|
|||
mLastIvState[id] = status;
|
||||
changed = true;
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, mqttStr[MQTT_STR_AVAILABLE]);
|
||||
snprintf(val, 40, "%d", status);
|
||||
publish(topic, val, true);
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, mqttStr[MQTT_STR_LAST_SUCCESS]);
|
||||
snprintf(val, 40, "%d", iv->getLastTs(rec));
|
||||
publish(topic, val, true);
|
||||
}
|
||||
|
@ -459,7 +450,7 @@ class PubMqtt {
|
|||
|
||||
if(changed) {
|
||||
snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE)));
|
||||
publish("status", val, true);
|
||||
publish(subtopics[MQTT_STATUS], val, true);
|
||||
}
|
||||
|
||||
return anyAvail;
|
||||
|
@ -471,9 +462,9 @@ class PubMqtt {
|
|||
Inverter<> *iv = mSys->getInverterByPos(0, false);
|
||||
while(!mAlarmList.empty()) {
|
||||
alarm_t alarm = mAlarmList.front();
|
||||
publish("alarm", iv->getAlarmStr(alarm.code).c_str());
|
||||
publish("alarm_start", String(alarm.start).c_str());
|
||||
publish("alarm_end", String(alarm.end).c_str());
|
||||
publish(subtopics[MQTT_ALARM], iv->getAlarmStr(alarm.code).c_str());
|
||||
publish(subtopics[MQTT_ALARM_START], String(alarm.start).c_str());
|
||||
publish(subtopics[MQTT_ALARM_END], String(alarm.end).c_str());
|
||||
mAlarmList.pop();
|
||||
}
|
||||
}
|
||||
|
@ -573,7 +564,7 @@ class PubMqtt {
|
|||
fieldId = FLD_PDC;
|
||||
break;
|
||||
}
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", mqttStr[MQTT_STR_TOTAL], fields[fieldId]);
|
||||
snprintf(val, 40, "%g", ah::round3(total[i]));
|
||||
publish(topic, val, true);
|
||||
}
|
||||
|
@ -606,8 +597,6 @@ class PubMqtt {
|
|||
|
||||
// last will topic and payload must be available trough lifetime of 'espMqttClient'
|
||||
char mLwtTopic[MQTT_TOPIC_LEN+5];
|
||||
const char* mLwtOnline = "connected";
|
||||
const char* mLwtOffline = "not connected";
|
||||
const char *mDevName, *mVersion;
|
||||
};
|
||||
|
||||
|
|
104
src/publisher/pubMqttDefs.h
Normal file
104
src/publisher/pubMqttDefs.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __PUB_MQTT_DEFS_H__
|
||||
#define __PUB_MQTT_DEFS_H__
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
enum {
|
||||
STR_TRUE,
|
||||
STR_FALSE
|
||||
};
|
||||
|
||||
const char* const dict[] PROGMEM = {
|
||||
"true",
|
||||
"false"
|
||||
};
|
||||
|
||||
enum {
|
||||
MQTT_STR_LWT_CONN,
|
||||
MQTT_STR_LWT_NOT_CONN,
|
||||
MQTT_STR_AVAILABLE,
|
||||
MQTT_STR_LAST_SUCCESS,
|
||||
MQTT_STR_TOTAL,
|
||||
MQTT_STR_GOT_TOPIC
|
||||
};
|
||||
|
||||
const char* const mqttStr[] PROGMEM = {
|
||||
"connected",
|
||||
"not connected",
|
||||
"available",
|
||||
"last_success",
|
||||
"total",
|
||||
"MQTT got topic: "
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
MQTT_UPTIME = 0,
|
||||
MQTT_RSSI,
|
||||
MQTT_FREE_HEAP,
|
||||
MQTT_SUNRISE,
|
||||
MQTT_SUNSET,
|
||||
MQTT_COMM_START,
|
||||
MQTT_COMM_STOP,
|
||||
MQTT_DIS_NIGHT_COMM,
|
||||
MQTT_COMM_DISABLED,
|
||||
MQTT_COMM_DIS_TS,
|
||||
MQTT_VERSION,
|
||||
MQTT_DEVICE,
|
||||
MQTT_IP_ADDR,
|
||||
MQTT_STATUS,
|
||||
MQTT_ALARM,
|
||||
MQTT_ALARM_START,
|
||||
MQTT_ALARM_END,
|
||||
MQTT_LWT_ONLINE,
|
||||
MQTT_LWT_OFFLINE,
|
||||
MQTT_ACK_PWR_LMT
|
||||
};
|
||||
|
||||
const char* const subtopics[] PROGMEM = {
|
||||
"uptime",
|
||||
"wifi_rssi",
|
||||
"free_heap",
|
||||
"sunrise",
|
||||
"sunset",
|
||||
"comm_start",
|
||||
"comm_stop",
|
||||
"dis_night_comm",
|
||||
"comm_disabled",
|
||||
"comm_dis_ts",
|
||||
"version",
|
||||
"device",
|
||||
"ip_addr",
|
||||
"status",
|
||||
"alarm",
|
||||
"alarm_start",
|
||||
"alarm_end",
|
||||
"connected",
|
||||
"not connected",
|
||||
"ack_pwr_limit"
|
||||
};
|
||||
|
||||
enum {
|
||||
MQTT_SUBS_LMT_PERI_REL,
|
||||
MQTT_SUBS_LMT_PERI_ABS,
|
||||
MQTT_SUBS_LMT_NONPERI_REL,
|
||||
MQTT_SUBS_LMT_NONPERI_ABS,
|
||||
MQTT_SUBS_SET_TIME,
|
||||
MQTT_SUBS_SYNC_NTP
|
||||
};
|
||||
|
||||
const char* const subscr[] PROGMEM = {
|
||||
"ctrl/limit_persistent_relative",
|
||||
"ctrl/limit_persistent_absolute",
|
||||
"ctrl/limit_nonpersistent_relative",
|
||||
"ctrl/limit_nonpersistent_absolute",
|
||||
"setup/set_time",
|
||||
"setup/sync_ntp"
|
||||
};
|
||||
|
||||
#endif /*__PUB_MQTT_DEFS_H__*/
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
|||
#define DBG_DEBUG 4
|
||||
#define DBG_VERBOSE 5
|
||||
|
||||
//#define LOG_MAX_MSG_LEN 100
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// globally used level
|
||||
|
@ -58,7 +60,7 @@
|
|||
mCb(String(b, HEX));
|
||||
}
|
||||
}
|
||||
inline void DHEX(uint16_t b) {
|
||||
/*inline void DHEX(uint16_t b) {
|
||||
if( b<0x10 ) DSERIAL.print(F("000"));
|
||||
else if( b<0x100 ) DSERIAL.print(F("00"));
|
||||
else if( b<0x1000 ) DSERIAL.print(F("0"));
|
||||
|
@ -89,7 +91,7 @@
|
|||
else if( b<0x10000000 ) mCb(F("0"));
|
||||
mCb(String(b, HEX));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -154,4 +156,52 @@
|
|||
}\
|
||||
})
|
||||
|
||||
/*class ahoyLog {
|
||||
public:
|
||||
ahoyLog() {}
|
||||
|
||||
inline void logMsg(uint8_t lvl, bool newLine, const char *fmt, va_list args) {
|
||||
snprintf(mLogBuf, LOG_MAX_MSG_LEN, fmt, args);
|
||||
DSERIAL.print(mLogBuf);
|
||||
if(NULL != mCb)
|
||||
mCb(mLogBuf);
|
||||
if(newLine) {
|
||||
DSERIAL.print(F("\r\n"));
|
||||
if(NULL != mCb)
|
||||
mCb(F("\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
inline void logError(const char *fmt, ...) {
|
||||
#if DEBUG_LEVEL >= DBG_ERROR
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
logMsg(DBG_ERROR, true, fmt, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void logWarn(const char *fmt, ...) {
|
||||
#if DEBUG_LEVEL >= DBG_WARN
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
logMsg(DBG_ERROR, true, fmt, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void logInfo(const char *fmt, ...) {
|
||||
#if DEBUG_LEVEL >= DBG_INFO
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
logMsg(DBG_ERROR, true, fmt, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
char mLogBuf[LOG_MAX_MSG_LEN];
|
||||
DBG_CB mCb = NULL;
|
||||
};*/
|
||||
|
||||
#endif /*__DBG_H__*/
|
||||
|
|
|
@ -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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -7,15 +7,15 @@
|
|||
|
||||
namespace ah {
|
||||
void ip2Arr(uint8_t ip[], const char *ipStr) {
|
||||
char tmp[16];
|
||||
uint8_t p = 1;
|
||||
memset(ip, 0, 4);
|
||||
memset(tmp, 0, 16);
|
||||
snprintf(tmp, 16, ipStr);
|
||||
char *p = strtok(tmp, ".");
|
||||
uint8_t i = 0;
|
||||
while(NULL != p) {
|
||||
ip[i++] = atoi(p);
|
||||
p = strtok(NULL, ".");
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
if(ipStr[i] == 0)
|
||||
return;
|
||||
if(0 == i)
|
||||
ip[0] = atoi(ipStr);
|
||||
else if(ipStr[i] == '.')
|
||||
ip[p++] = atoi(&ipStr[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2022 Ahoy, https://ahoydtu.de
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Lukas Pusch, lukas@lpusch.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -106,7 +106,11 @@ namespace ah {
|
|||
void printSchedulers() {
|
||||
for (uint8_t i = 0; i < MAX_NUM_TICKER; i++) {
|
||||
if (mTickerInUse[i]) {
|
||||
DPRINTLN(DBG_INFO, String(mTicker[i].name) + ", tmt: " + String(mTicker[i].timeout) + ", rel: " + String(mTicker[i].reload));
|
||||
DPRINT(DBG_INFO, String(mTicker[i].name));
|
||||
DBGPRINT(", tmt: ");
|
||||
DBGPRINT(String(mTicker[i].timeout));
|
||||
DBGPRINT(", rel: ");
|
||||
DBGPRINTLN(String(mTicker[i].reload));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://ahoydtu.de
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __WEB_API_H__
|
||||
#define __WEB_API_H__
|
||||
|
||||
|
@ -24,7 +29,9 @@ class RestApi {
|
|||
public:
|
||||
RestApi() {
|
||||
mTimezoneOffset = 0;
|
||||
mFreeHeap = 0;
|
||||
mHeapFree = 0;
|
||||
mHeapFreeBlk = 0;
|
||||
mHeapFrag = 0;
|
||||
nr = 0;
|
||||
}
|
||||
|
||||
|
@ -49,7 +56,7 @@ class RestApi {
|
|||
serializeJson(obj, out, 128);
|
||||
DPRINTLN(DBG_INFO, "RestApi: " + String(out));*/
|
||||
DynamicJsonDocument json(128);
|
||||
JsonObject dummy = json.to<JsonObject>();
|
||||
JsonObject dummy = json.as<JsonObject>();
|
||||
if(obj[F("path")] == "ctrl")
|
||||
setCtrl(obj, dummy);
|
||||
else if(obj[F("path")] == "setup")
|
||||
|
@ -58,7 +65,11 @@ class RestApi {
|
|||
|
||||
private:
|
||||
void onApi(AsyncWebServerRequest *request) {
|
||||
mFreeHeap = ESP.getFreeHeap();
|
||||
mHeapFree = ESP.getFreeHeap();
|
||||
#ifndef ESP32
|
||||
mHeapFreeBlk = ESP.getMaxFreeBlockSize();
|
||||
mHeapFrag = ESP.getHeapFragmentation();
|
||||
#endif
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192);
|
||||
JsonObject root = response->getRoot();
|
||||
|
@ -84,6 +95,7 @@ class RestApi {
|
|||
else
|
||||
getNotFound(root, F("http://") + request->host() + F("/api/"));
|
||||
|
||||
//DPRINTLN(DBG_INFO, "API mem usage: " + String(root.memoryUsage()));
|
||||
response->addHeader("Access-Control-Allow-Origin", "*");
|
||||
response->addHeader("Access-Control-Allow-Headers", "content-type");
|
||||
response->setLength();
|
||||
|
@ -194,7 +206,7 @@ class RestApi {
|
|||
|
||||
obj[F("sdk")] = ESP.getSdkVersion();
|
||||
obj[F("cpu_freq")] = ESP.getCpuFreqMHz();
|
||||
obj[F("heap_free")] = mFreeHeap;
|
||||
obj[F("heap_free")] = mHeapFree;
|
||||
obj[F("sketch_total")] = ESP.getFreeSketchSpace();
|
||||
obj[F("sketch_used")] = ESP.getSketchSize() / 1024; // in kb
|
||||
getGeneric(obj);
|
||||
|
@ -219,8 +231,8 @@ class RestApi {
|
|||
//obj[F("chip_cores")] = F("n/a");
|
||||
obj[F("core_version")] = ESP.getCoreVersion();
|
||||
obj[F("flash_size")] = ESP.getFlashChipRealSize() / 1024; // in kb
|
||||
obj[F("heap_frag")] = ESP.getHeapFragmentation();
|
||||
obj[F("max_free_blk")] = ESP.getMaxFreeBlockSize();
|
||||
obj[F("heap_frag")] = mHeapFrag;
|
||||
obj[F("max_free_blk")] = mHeapFreeBlk;
|
||||
obj[F("reboot_reason")] = ESP.getResetReason();
|
||||
#endif
|
||||
//obj[F("littlefs_total")] = LittleFS.totalBytes();
|
||||
|
@ -498,7 +510,7 @@ class RestApi {
|
|||
obj2[F("name")] = String(iv->config->name);
|
||||
obj2[F("channels")] = iv->channels;
|
||||
obj2[F("power_limit_read")] = ah::round3(iv->actPowerLimit);
|
||||
obj2[F("last_alarm")] = String(iv->lastAlarmMsg);
|
||||
//obj2[F("last_alarm")] = String(iv->lastAlarmMsg);
|
||||
obj2[F("ts_last_success")] = rec->ts;
|
||||
|
||||
JsonArray ch = obj2.createNestedArray("ch");
|
||||
|
@ -625,7 +637,8 @@ class RestApi {
|
|||
settings_t *mConfig;
|
||||
|
||||
uint32_t mTimezoneOffset;
|
||||
uint32_t mFreeHeap;
|
||||
uint32_t mHeapFree, mHeapFreeBlk;
|
||||
uint8_t mHeapFrag;
|
||||
uint16_t nr;
|
||||
};
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
var limit = iv["power_limit_read"] + "%";
|
||||
if(limit == "65535%")
|
||||
limit = "n/a";
|
||||
ch0.appendChild(span(iv["name"] + " Limit " + limit + " | last Alarm: " + iv["last_alarm"], ["head"]));
|
||||
ch0.appendChild(span(iv["name"] + " Limit " + limit, ["head"]));
|
||||
|
||||
for(var j = 0; j < root.ch0_fld_names.length; j++) {
|
||||
var val = Math.round(iv["ch"][0][j] * 100) / 100;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -72,7 +72,7 @@ void ahoywifi::tickWifiLoop() {
|
|||
mScanActive = false;
|
||||
}
|
||||
DBGPRINTLN(F("AP client connected"));
|
||||
welcome(mApIp.toString());
|
||||
welcome(mApIp.toString(), "");
|
||||
WiFi.mode(WIFI_AP);
|
||||
mDns.start(53, "*", mApIp);
|
||||
mAppWifiCb(true);
|
||||
|
@ -118,7 +118,7 @@ void ahoywifi::tickWifiLoop() {
|
|||
if(mStaConn != CONNECTED)
|
||||
mStaConn = CONNECTING;
|
||||
if(mBSSIDList.size() > 0) { // get first BSSID in list
|
||||
DBGPRINT("try to connect to AP with BSSID:");
|
||||
DBGPRINT(F("try to connect to AP with BSSID:"));
|
||||
uint8_t bssid[6];
|
||||
for (int j = 0; j < 6; j++) {
|
||||
bssid[j] = mBSSIDList.front();
|
||||
|
@ -142,7 +142,11 @@ void ahoywifi::setupAp(void) {
|
|||
|
||||
DBGPRINTLN(F("\n---------\nAhoyDTU Info:"));
|
||||
DBGPRINT(F("Version: "));
|
||||
DBGPRINTLN(String(VERSION_MAJOR) + F(".") + String(VERSION_MINOR) + F(".") + String(VERSION_PATCH));
|
||||
DBGPRINT(String(VERSION_MAJOR));
|
||||
DBGPRINT(F("."));
|
||||
DBGPRINT(String(VERSION_MINOR));
|
||||
DBGPRINT(F("."));
|
||||
DBGPRINTLN(String(VERSION_PATCH));
|
||||
DBGPRINT(F("Github Hash: "));
|
||||
DBGPRINTLN(String(AUTO_GIT_HASH));
|
||||
|
||||
|
@ -150,7 +154,8 @@ void ahoywifi::setupAp(void) {
|
|||
DBGPRINTLN(WIFI_AP_SSID);
|
||||
DBGPRINT(F("PWD: "));
|
||||
DBGPRINTLN(WIFI_AP_PWD);
|
||||
DBGPRINTLN("IP Address: http://" + mApIp.toString());
|
||||
DBGPRINT(F("IP Address: http://"));
|
||||
DBGPRINTLN(mApIp.toString());
|
||||
DBGPRINTLN(F("---------\n"));
|
||||
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
|
@ -327,9 +332,11 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) {
|
|||
WiFi.scanDelete();
|
||||
mScanActive = false;
|
||||
}
|
||||
welcome(WiFi.localIP().toString() + F(" (Station)"));
|
||||
welcome(WiFi.localIP().toString(), F(" (Station)"));
|
||||
WiFi.softAPdisconnect();
|
||||
WiFi.mode(WIFI_STA);
|
||||
DBGPRINTLN(F("[WiFi] AP disabled"));
|
||||
delay(100);
|
||||
mAppWifiCb(true);
|
||||
break;
|
||||
|
||||
|
@ -393,11 +400,12 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) {
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ahoywifi::welcome(String msg) {
|
||||
void ahoywifi::welcome(String ip, String mode) {
|
||||
DBGPRINTLN(F("\n\n--------------------------------"));
|
||||
DBGPRINTLN(F("Welcome to AHOY!"));
|
||||
DBGPRINT(F("\npoint your browser to http://"));
|
||||
DBGPRINTLN(msg);
|
||||
DBGPRINT(ip);
|
||||
DBGPRINTLN(mode);
|
||||
DBGPRINTLN(F("to configure your device"));
|
||||
DBGPRINTLN(F("--------------------------------\n"));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -52,7 +52,7 @@ class ahoywifi {
|
|||
#else
|
||||
void onWiFiEvent(WiFiEvent_t event);
|
||||
#endif
|
||||
void welcome(String msg);
|
||||
void welcome(String ip, String mode);
|
||||
|
||||
|
||||
settings_t *mConfig;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue