mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-06 20:51:38 +02:00
improved payload handling (request / retransmit) #464
included alarm ID parse to serial console (in development)
This commit is contained in:
parent
43c07be148
commit
3d3e3dc8c6
13 changed files with 202 additions and 115 deletions
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
(starting from release version `0.5.66`)
|
(starting from release version `0.5.66`)
|
||||||
|
|
||||||
|
## 0.5.73
|
||||||
|
* improved payload handling (request / retransmit) #464
|
||||||
|
* included alarm ID parse to serial console (in development)
|
||||||
|
|
||||||
|
## 0.5.72
|
||||||
|
* repaired system, scheduler was not called any more #596
|
||||||
|
|
||||||
## 0.5.71
|
## 0.5.71
|
||||||
* improved wifi handling and tickers, many thanks to @beegee3 #571
|
* improved wifi handling and tickers, many thanks to @beegee3 #571
|
||||||
* fixed YieldTotal correction calculation #589
|
* fixed YieldTotal correction calculation #589
|
||||||
|
|
|
@ -92,7 +92,7 @@ void app::loopStandard(void) {
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
if (ah::checkTicker(&mRxTicker, 5)) {
|
if (ah::checkTicker(&mRxTicker, 4)) {
|
||||||
bool rxRdy = mSys->Radio.switchRxCh();
|
bool rxRdy = mSys->Radio.switchRxCh();
|
||||||
|
|
||||||
if (!mSys->BufCtrl.empty()) {
|
if (!mSys->BufCtrl.empty()) {
|
||||||
|
|
|
@ -66,7 +66,6 @@ class app : public IApp, public ah::Scheduler {
|
||||||
void handleIntr(void);
|
void handleIntr(void);
|
||||||
void cbMqtt(char* topic, byte* payload, unsigned int length);
|
void cbMqtt(char* topic, byte* payload, unsigned int length);
|
||||||
void saveValues(void);
|
void saveValues(void);
|
||||||
void resetPayload(Inverter<>* iv);
|
|
||||||
bool getWifiApActive(void);
|
bool getWifiApActive(void);
|
||||||
|
|
||||||
uint32_t getUptime() {
|
uint32_t getUptime() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 5
|
#define VERSION_MINOR 5
|
||||||
#define VERSION_PATCH 72
|
#define VERSION_PATCH 73
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -106,7 +106,7 @@ const byteAssign_t AlarmDataAssignment[] = {
|
||||||
};
|
};
|
||||||
#define HMALARMDATA_LIST_LEN (sizeof(AlarmDataAssignment) / sizeof(byteAssign_t))
|
#define HMALARMDATA_LIST_LEN (sizeof(AlarmDataAssignment) / sizeof(byteAssign_t))
|
||||||
#define HMALARMDATA_PAYLOAD_LEN 0 // 0: means check is off
|
#define HMALARMDATA_PAYLOAD_LEN 0 // 0: means check is off
|
||||||
|
#define ALARM_LOG_ENTRY_SIZE 12
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
|
@ -105,32 +105,33 @@ const calcFunc_t<T> calcFunctions[] = {
|
||||||
template <class REC_TYP>
|
template <class REC_TYP>
|
||||||
class Inverter {
|
class Inverter {
|
||||||
public:
|
public:
|
||||||
cfgIv_t *config; // stored settings
|
cfgIv_t *config; // stored settings
|
||||||
uint8_t id; // unique id
|
uint8_t id; // unique id
|
||||||
uint8_t type; // integer which refers to inverter type
|
uint8_t type; // integer which refers to inverter type
|
||||||
uint16_t alarmMesIndex; // Last recorded Alarm Message Index
|
uint16_t alarmMesIndex; // Last recorded Alarm Message Index
|
||||||
uint16_t powerLimit[2]; // limit power output
|
uint16_t powerLimit[2]; // limit power output
|
||||||
float actPowerLimit; // actual power limit
|
float actPowerLimit; // actual power limit
|
||||||
uint8_t devControlCmd; // carries the requested cmd
|
uint8_t devControlCmd; // carries the requested cmd
|
||||||
bool devControlRequest; // true if change needed
|
serial_u radioId; // id converted to modbus
|
||||||
serial_u radioId; // id converted to modbus
|
uint8_t channels; // number of PV channels (1-4)
|
||||||
uint8_t channels; // number of PV channels (1-4)
|
record_t<REC_TYP> recordMeas; // structure for measured values
|
||||||
record_t<REC_TYP> recordMeas; // structure for measured values
|
record_t<REC_TYP> recordInfo; // structure for info values
|
||||||
record_t<REC_TYP> recordInfo; // structure for info values
|
record_t<REC_TYP> recordConfig; // structure for system config values
|
||||||
record_t<REC_TYP> recordConfig; // structure for system config values
|
record_t<REC_TYP> recordAlarm; // structure for alarm 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 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)
|
||||||
|
|
||||||
Inverter() {
|
Inverter() {
|
||||||
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
powerLimit[0] = 0xffff; // 65535 W Limit -> unlimited
|
||||||
powerLimit[1] = AbsolutNonPersistent; // default power limit setting
|
powerLimit[1] = AbsolutNonPersistent; // default power limit setting
|
||||||
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
actPowerLimit = 0xffff; // init feedback from inverter to -1
|
||||||
devControlRequest = false;
|
mDevControlRequest = false;
|
||||||
devControlCmd = InitDataState;
|
devControlCmd = InitDataState;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
lastAlarmMsg = "nothing";
|
lastAlarmMsg = "nothing";
|
||||||
alarmMesIndex = 0;
|
alarmMesIndex = 0;
|
||||||
|
isConnected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Inverter() {
|
~Inverter() {
|
||||||
|
@ -140,7 +141,7 @@ class Inverter {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void enqueCommand(uint8_t cmd) {
|
void enqueCommand(uint8_t cmd) {
|
||||||
_commandQueue.push(std::make_shared<T>(cmd));
|
_commandQueue.push(std::make_shared<T>(cmd));
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(id) + F(") enqueuedCmd: ") + String(cmd));
|
DPRINTLN(DBG_INFO, F("(#") + String(id) + F(") enqueuedCmd: 0x") + String(cmd, HEX));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setQueuedCmdFinished() {
|
void setQueuedCmdFinished() {
|
||||||
|
@ -161,10 +162,10 @@ class Inverter {
|
||||||
uint8_t getQueuedCmd() {
|
uint8_t getQueuedCmd() {
|
||||||
if (_commandQueue.empty()) {
|
if (_commandQueue.empty()) {
|
||||||
if (getFwVersion() == 0)
|
if (getFwVersion() == 0)
|
||||||
enqueCommand<InfoCommand>(InverterDevInform_All);
|
enqueCommand<InfoCommand>(InverterDevInform_All); // firmware version
|
||||||
enqueCommand<InfoCommand>(RealTimeRunData_Debug);
|
enqueCommand<InfoCommand>(RealTimeRunData_Debug); // live data
|
||||||
if (actPowerLimit == 0xffff)
|
if (actPowerLimit == 0xffff)
|
||||||
enqueCommand<InfoCommand>(SystemConfigPara);
|
enqueCommand<InfoCommand>(SystemConfigPara); // power limit info
|
||||||
}
|
}
|
||||||
return _commandQueue.front().get()->getCmd();
|
return _commandQueue.front().get()->getCmd();
|
||||||
}
|
}
|
||||||
|
@ -219,6 +220,20 @@ class Inverter {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool setDevControlRequest() {
|
||||||
|
if(isConnected)
|
||||||
|
mDevControlRequest = true;
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearDevControlRequest() {
|
||||||
|
mDevControlRequest = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool getDevControlRequest() {
|
||||||
|
return mDevControlRequest;
|
||||||
|
}
|
||||||
|
|
||||||
void addValue(uint8_t pos, uint8_t buf[], record_t<> *rec) {
|
void addValue(uint8_t pos, uint8_t buf[], record_t<> *rec) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue"));
|
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:addValue"));
|
||||||
if(NULL != rec) {
|
if(NULL != rec) {
|
||||||
|
@ -256,11 +271,10 @@ class Inverter {
|
||||||
if (alarmMesIndex < rec->record[pos]){
|
if (alarmMesIndex < rec->record[pos]){
|
||||||
alarmMesIndex = rec->record[pos];
|
alarmMesIndex = rec->record[pos];
|
||||||
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
|
//enqueCommand<InfoCommand>(AlarmUpdate); // What is the function of AlarmUpdate?
|
||||||
|
|
||||||
|
DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(alarmMesIndex));
|
||||||
enqueCommand<InfoCommand>(AlarmData);
|
enqueCommand<InfoCommand>(AlarmData);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
alarmMesIndex = rec->record[pos]; // no change
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rec->assign == InfoAssignment) {
|
else if (rec->assign == InfoAssignment) {
|
||||||
|
@ -273,6 +287,7 @@ class Inverter {
|
||||||
if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){
|
if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){
|
||||||
actPowerLimit = rec->record[pos];
|
actPowerLimit = rec->record[pos];
|
||||||
DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1));
|
DPRINT(DBG_DEBUG, F("Inverter actual power limit: ") + String(actPowerLimit, 1));
|
||||||
|
isConnected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rec->assign == AlarmDataAssignment) {
|
else if (rec->assign == AlarmDataAssignment) {
|
||||||
|
@ -345,10 +360,10 @@ class Inverter {
|
||||||
|
|
||||||
record_t<> *getRecordStruct(uint8_t cmd) {
|
record_t<> *getRecordStruct(uint8_t cmd) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case RealTimeRunData_Debug: return &recordMeas;
|
case RealTimeRunData_Debug: return &recordMeas; // 11 = 0x0b
|
||||||
case InverterDevInform_All: return &recordInfo;
|
case InverterDevInform_All: return &recordInfo; // 1 = 0x01
|
||||||
case SystemConfigPara: return &recordConfig;
|
case SystemConfigPara: return &recordConfig; // 5 = 0x05
|
||||||
case AlarmData: return &recordAlarm;
|
case AlarmData: return &recordAlarm; // 17 = 0x11
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -411,7 +426,27 @@ class Inverter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAlarmStr(u_int16_t alarmCode) {
|
bool parseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len) {
|
||||||
|
uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE;
|
||||||
|
if((startOff + ALARM_LOG_ENTRY_SIZE) > len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint16_t wCode = ((uint16_t)pyld[startOff]) << 8 | pyld[startOff+1];
|
||||||
|
uint32_t startTimeOffset = 0, endTimeOffset = 0;
|
||||||
|
|
||||||
|
if (((wCode >> 13) & 0x01) == 1) // check if is AM or PM
|
||||||
|
startTimeOffset = 12 * 60 * 60;
|
||||||
|
if (((wCode >> 12) & 0x01) == 1) // check if is AM or PM
|
||||||
|
endTimeOffset = 12 * 60 * 60;
|
||||||
|
|
||||||
|
uint32_t start = (((uint16_t)pyld[startOff + 4] << 8) | ((uint16_t)pyld[startOff + 5])) + startTimeOffset;
|
||||||
|
uint32_t end = (((uint16_t)pyld[startOff + 6] << 8) | ((uint16_t)pyld[startOff + 7])) + endTimeOffset;
|
||||||
|
|
||||||
|
DPRINTLN(DBG_INFO, "Alarm #" + String(pyld[startOff+1]) + " '" + String(getAlarmStr(pyld[startOff+1])) + "' start: " + ah::getTimeStr(start) + ", end: " + ah::getTimeStr(end));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getAlarmStr(uint16_t alarmCode) {
|
||||||
switch (alarmCode) { // breaks are intentionally missing!
|
switch (alarmCode) { // breaks are intentionally missing!
|
||||||
case 1: return String(F("Inverter start"));
|
case 1: return String(F("Inverter start"));
|
||||||
case 2: return String(F("DTU command failed"));
|
case 2: return String(F("DTU command failed"));
|
||||||
|
@ -486,7 +521,6 @@ class Inverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<std::shared_ptr<CommandAbstract>> _commandQueue;
|
|
||||||
void toRadioId(void) {
|
void toRadioId(void) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:toRadioId"));
|
DPRINTLN(DBG_VERBOSE, F("hmInverter.h:toRadioId"));
|
||||||
radioId.u64 = 0ULL;
|
radioId.u64 = 0ULL;
|
||||||
|
@ -496,6 +530,9 @@ class Inverter {
|
||||||
radioId.b[1] = config->serial.b[3];
|
radioId.b[1] = config->serial.b[3];
|
||||||
radioId.b[0] = 0x01;
|
radioId.b[0] = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::queue<std::shared_ptr<CommandAbstract>> _commandQueue;
|
||||||
|
bool mDevControlRequest; // true if change needed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ class HmRadio {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data) {
|
void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data) {
|
||||||
DPRINTLN(DBG_INFO, F("sendControlPacket cmd: ") + String(cmd));
|
DPRINTLN(DBG_INFO, F("sendControlPacket cmd: 0x") + String(cmd, HEX));
|
||||||
sendCmdPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME, false);
|
sendCmdPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME, false);
|
||||||
uint8_t cnt = 0;
|
uint8_t cnt = 0;
|
||||||
mTxBuf[10 + cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
|
mTxBuf[10 + cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
|
||||||
|
@ -219,7 +219,7 @@ class HmRadio {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) {
|
void sendTimePacket(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId) {
|
||||||
DPRINTLN(DBG_INFO, F("sendTimePacket ") + String(cmd, HEX));
|
DPRINTLN(DBG_DEBUG, F("sendTimePacket 0x") + String(cmd, HEX));
|
||||||
sendCmdPacket(invId, TX_REQ_INFO, ALL_FRAMES, false);
|
sendCmdPacket(invId, TX_REQ_INFO, ALL_FRAMES, false);
|
||||||
mTxBuf[10] = cmd; // cid
|
mTxBuf[10] = cmd; // cid
|
||||||
mTxBuf[11] = 0x00;
|
mTxBuf[11] = 0x00;
|
||||||
|
|
149
src/hm/payload.h
149
src/hm/payload.h
|
@ -24,6 +24,7 @@ typedef struct {
|
||||||
bool lastFound;
|
bool lastFound;
|
||||||
uint8_t retransmits;
|
uint8_t retransmits;
|
||||||
bool requested;
|
bool requested;
|
||||||
|
bool gotFragment;
|
||||||
} invPayload_t;
|
} invPayload_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +42,9 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
mStat = stat;
|
mStat = stat;
|
||||||
mMaxRetrans = maxRetransmits;
|
mMaxRetrans = maxRetransmits;
|
||||||
mTimestamp = timestamp;
|
mTimestamp = timestamp;
|
||||||
memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t)));
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
|
||||||
|
reset(i);
|
||||||
|
}
|
||||||
mSerialDebug = false;
|
mSerialDebug = false;
|
||||||
mHighPrioIv = NULL;
|
mHighPrioIv = NULL;
|
||||||
}
|
}
|
||||||
|
@ -69,42 +72,44 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
|
|
||||||
void ivSend(Inverter<> *iv, bool highPrio = false) {
|
void ivSend(Inverter<> *iv, bool highPrio = false) {
|
||||||
if(!highPrio) {
|
if(!highPrio) {
|
||||||
if (!mPayload[iv->id].complete)
|
if (mPayload[iv->id].requested) {
|
||||||
process(false);
|
if (!mPayload[iv->id].complete)
|
||||||
|
process(false); // no retransmit
|
||||||
|
|
||||||
if (!mPayload[iv->id].complete) {
|
if (!mPayload[iv->id].complete) {
|
||||||
if (0 == mPayload[iv->id].maxPackId)
|
if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId)
|
||||||
mStat->rxFailNoAnser++;
|
mStat->rxFailNoAnser++; // got nothing
|
||||||
else
|
else
|
||||||
mStat->rxFail++;
|
mStat->rxFail++; // got fragments but not complete response
|
||||||
|
|
||||||
iv->setQueuedCmdFinished(); // command failed
|
iv->setQueuedCmdFinished(); // command failed
|
||||||
if (mSerialDebug)
|
if (mSerialDebug)
|
||||||
DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout"));
|
DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout"));
|
||||||
if (mSerialDebug) {
|
if (mSerialDebug) {
|
||||||
DPRINT(DBG_INFO, F("(#") + String(iv->id) + ") ");
|
DPRINT(DBG_INFO, F("(#") + String(iv->id) + ") ");
|
||||||
DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload[iv->id].retransmits) + ")");
|
DPRINTLN(DBG_INFO, F("no Payload received! (retransmits: ") + String(mPayload[iv->id].retransmits) + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(iv);
|
reset(iv->id);
|
||||||
mPayload[iv->id].requested = true;
|
mPayload[iv->id].requested = true;
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
if (mSerialDebug)
|
if (mSerialDebug)
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX));
|
||||||
|
|
||||||
if (iv->devControlRequest) {
|
if (iv->getDevControlRequest()) {
|
||||||
if (mSerialDebug)
|
if (mSerialDebug)
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Devcontrol request ") + String(iv->devControlCmd) + F(" power limit ") + String(iv->powerLimit[0]));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Devcontrol request 0x") + String(iv->devControlCmd, HEX) + F(" power limit ") + String(iv->powerLimit[0]));
|
||||||
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);
|
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);
|
||||||
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
|
||||||
} else {
|
} else {
|
||||||
uint8_t cmd = iv->getQueuedCmd();
|
uint8_t cmd = iv->getQueuedCmd();
|
||||||
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket"));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket")); // + String(cmd, HEX));
|
||||||
mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex);
|
mSys->Radio.sendTimePacket(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex);
|
||||||
mPayload[iv->id].txCmd = cmd;
|
mPayload[iv->id].txCmd = cmd;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +117,11 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
|
|
||||||
void add(packet_t *p, uint8_t len) {
|
void add(packet_t *p, uint8_t len) {
|
||||||
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
Inverter<> *iv = mSys->findInverter(&p->packet[1]);
|
||||||
if ((NULL != iv) && (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES))) { // response from get information command
|
|
||||||
|
if(NULL == iv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
||||||
mPayload[iv->id].txId = p->packet[0];
|
mPayload[iv->id].txId = p->packet[0];
|
||||||
DPRINTLN(DBG_DEBUG, F("Response from info request received"));
|
DPRINTLN(DBG_DEBUG, F("Response from info request received"));
|
||||||
uint8_t *pid = &p->packet[9];
|
uint8_t *pid = &p->packet[9];
|
||||||
|
@ -120,26 +129,26 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
DPRINT(DBG_DEBUG, F("fragment number zero received and ignored"));
|
DPRINT(DBG_DEBUG, F("fragment number zero received and ignored"));
|
||||||
} else {
|
} else {
|
||||||
DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX));
|
DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX));
|
||||||
if ((*pid & 0x7F) < 5) {
|
if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) {
|
||||||
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], len - 11);
|
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], len - 11);
|
||||||
mPayload[iv->id].len[(*pid & 0x7F) - 1] = len - 11;
|
mPayload[iv->id].len[(*pid & 0x7F) - 1] = len - 11;
|
||||||
|
mPayload[iv->id].gotFragment = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*pid & ALL_FRAMES) == ALL_FRAMES) {
|
if ((*pid & ALL_FRAMES) == ALL_FRAMES) {
|
||||||
// Last packet
|
// Last packet
|
||||||
if ((*pid & 0x7f) > mPayload[iv->id].maxPackId) {
|
if (((*pid & 0x7f) > mPayload[iv->id].maxPackId) || (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId)) {
|
||||||
mPayload[iv->id].maxPackId = (*pid & 0x7f);
|
mPayload[iv->id].maxPackId = (*pid & 0x7f);
|
||||||
if (*pid > 0x81)
|
if (*pid > 0x81)
|
||||||
mPayload[iv->id].lastFound = true;
|
mPayload[iv->id].lastFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
||||||
if ((NULL != iv) && (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES))) { // response from dev control command
|
|
||||||
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
|
DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received"));
|
||||||
|
|
||||||
mPayload[iv->id].txId = p->packet[0];
|
mPayload[iv->id].txId = p->packet[0];
|
||||||
iv->devControlRequest = false;
|
iv->clearDevControlRequest();
|
||||||
|
|
||||||
if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) {
|
if ((p->packet[12] == ActivePowerContr) && (p->packet[13] == 0x00)) {
|
||||||
String msg = "";
|
String msg = "";
|
||||||
|
@ -148,31 +157,13 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
else
|
else
|
||||||
msg = "NOT ";
|
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]));
|
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]));
|
||||||
|
iv->clearCmdQueue();
|
||||||
|
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
|
||||||
}
|
}
|
||||||
iv->devControlCmd = Init;
|
iv->devControlCmd = Init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool build(uint8_t id) {
|
|
||||||
DPRINTLN(DBG_VERBOSE, F("build"));
|
|
||||||
uint16_t crc = 0xffff, crcRcv = 0x0000;
|
|
||||||
if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES)
|
|
||||||
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) {
|
|
||||||
if (mPayload[id].len[i] > 0) {
|
|
||||||
if (i == (mPayload[id].maxPackId - 1)) {
|
|
||||||
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc);
|
|
||||||
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]);
|
|
||||||
} else
|
|
||||||
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc);
|
|
||||||
}
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (crc == crcRcv) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void process(bool retransmit) {
|
void process(bool retransmit) {
|
||||||
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
||||||
Inverter<> *iv = mSys->getInverterByPos(id);
|
Inverter<> *iv = mSys->getInverterByPos(id);
|
||||||
|
@ -182,6 +173,7 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) {
|
if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) {
|
||||||
// no processing needed if txId is not 0x95
|
// no processing needed if txId is not 0x95
|
||||||
mPayload[iv->id].complete = true;
|
mPayload[iv->id].complete = true;
|
||||||
|
continue; // skip to next inverter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mPayload[iv->id].complete) {
|
if (!mPayload[iv->id].complete) {
|
||||||
|
@ -191,18 +183,21 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
// This is required to prevent retransmissions without answer.
|
// This is required to prevent retransmissions without answer.
|
||||||
DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm..."));
|
DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm..."));
|
||||||
mPayload[iv->id].retransmits = mMaxRetrans;
|
mPayload[iv->id].retransmits = mMaxRetrans;
|
||||||
|
} else if(iv->devControlCmd == ActivePowerContr) {
|
||||||
|
DPRINTLN(DBG_INFO, F("retransmit power limit"));
|
||||||
|
mSys->Radio.sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit);
|
||||||
} else {
|
} else {
|
||||||
if (mPayload[iv->id].retransmits < mMaxRetrans) {
|
if (mPayload[iv->id].retransmits < mMaxRetrans) {
|
||||||
mPayload[iv->id].retransmits++;
|
mPayload[iv->id].retransmits++;
|
||||||
if(false == mPayload[iv->id].lastFound) {
|
if(false == mPayload[iv->id].gotFragment) {
|
||||||
DPRINTLN(DBG_WARN, F("while retrieving data: last frame missing: 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(") sendTimePacket"));
|
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") sendTimePacket 0x") + String(mPayload[iv->id].txCmd, HEX));
|
||||||
mSys->Radio.sendTimePacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex);
|
mSys->Radio.sendTimePacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex);
|
||||||
} else {
|
} else {
|
||||||
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("while retrieving data: 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);
|
mSys->Radio.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
|
||||||
}
|
}
|
||||||
|
@ -214,7 +209,7 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // payload complete
|
} else { // payload complete
|
||||||
DPRINTLN(DBG_INFO, F("procPyld: cmd: ") + String(mPayload[iv->id].txCmd));
|
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));
|
DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX));
|
||||||
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId));
|
||||||
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
|
||||||
|
@ -250,6 +245,15 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
}
|
}
|
||||||
iv->doCalculations();
|
iv->doCalculations();
|
||||||
notify(mPayload[iv->id].txCmd);
|
notify(mPayload[iv->id].txCmd);
|
||||||
|
|
||||||
|
if(AlarmData == mPayload[iv->id].txCmd) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
while(1) {
|
||||||
|
if(!iv->parseAlarmLog(i++, payload, payloadLen))
|
||||||
|
break;
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
|
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
|
||||||
mStat->rxFail++;
|
mStat->rxFail++;
|
||||||
|
@ -264,19 +268,40 @@ class Payload : public Handler<payloadListenerType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(Inverter<> *iv) {
|
private:
|
||||||
DPRINTLN(DBG_INFO, "resetPayload: id: " + String(iv->id));
|
bool build(uint8_t id) {
|
||||||
memset(mPayload[iv->id].len, 0, MAX_PAYLOAD_ENTRIES);
|
DPRINTLN(DBG_VERBOSE, F("build"));
|
||||||
mPayload[iv->id].txCmd = 0;
|
uint16_t crc = 0xffff, crcRcv = 0x0000;
|
||||||
mPayload[iv->id].retransmits = 0;
|
if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES)
|
||||||
mPayload[iv->id].maxPackId = 0;
|
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
|
||||||
mPayload[iv->id].lastFound = false;
|
|
||||||
mPayload[iv->id].complete = false;
|
for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) {
|
||||||
mPayload[iv->id].requested = false;
|
if (mPayload[id].len[i] > 0) {
|
||||||
mPayload[iv->id].ts = *mTimestamp;
|
if (i == (mPayload[id].maxPackId - 1)) {
|
||||||
|
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc);
|
||||||
|
crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]);
|
||||||
|
} else
|
||||||
|
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc);
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (crc == crcRcv) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(uint8_t id) {
|
||||||
|
DPRINTLN(DBG_INFO, "resetPayload: id: " + String(id));
|
||||||
|
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||||
|
mPayload[id].txCmd = 0;
|
||||||
|
mPayload[id].gotFragment = false;
|
||||||
|
mPayload[id].retransmits = 0;
|
||||||
|
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
|
||||||
|
mPayload[id].lastFound = false;
|
||||||
|
mPayload[id].complete = false;
|
||||||
|
mPayload[id].requested = false;
|
||||||
|
mPayload[id].ts = *mTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
IApp *mApp;
|
IApp *mApp;
|
||||||
HMSYSTEM *mSys;
|
HMSYSTEM *mSys;
|
||||||
statistics_t *mStat;
|
statistics_t *mStat;
|
||||||
|
|
|
@ -148,10 +148,10 @@ class PubMqtt {
|
||||||
if(!mClient.connected())
|
if(!mClient.connected())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char topic[(MQTT_TOPIC_LEN << 1) + 2];
|
if(addTopic) {
|
||||||
snprintf(topic, ((MQTT_TOPIC_LEN << 1) + 2), "%s/%s", mCfgMqtt->topic, subTopic);
|
String topic = String(mCfgMqtt->topic) + "/" + String(subTopic);
|
||||||
if(addTopic)
|
mClient.publish(topic.c_str(), QOS_0, retained, payload);
|
||||||
mClient.publish(topic, QOS_0, retained, payload);
|
}
|
||||||
else
|
else
|
||||||
mClient.publish(subTopic, QOS_0, retained, payload);
|
mClient.publish(subTopic, QOS_0, retained, payload);
|
||||||
mTxCnt++;
|
mTxCnt++;
|
||||||
|
|
|
@ -40,6 +40,15 @@ namespace ah {
|
||||||
return String(str);
|
return String(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getTimeStr(time_t t) {
|
||||||
|
char str[9];
|
||||||
|
if(0 == t)
|
||||||
|
sprintf(str, "n/a");
|
||||||
|
else
|
||||||
|
sprintf(str, "%02d:%02d:%02d", hour(t), minute(t), second(t));
|
||||||
|
return String(str);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t Serial2u64(const char *val) {
|
uint64_t Serial2u64(const char *val) {
|
||||||
char tmp[3];
|
char tmp[3];
|
||||||
uint64_t ret = 0ULL;
|
uint64_t ret = 0ULL;
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace ah {
|
||||||
void ip2Char(uint8_t ip[], char *str);
|
void ip2Char(uint8_t ip[], char *str);
|
||||||
double round3(double value);
|
double round3(double value);
|
||||||
String getDateTimeStr(time_t t);
|
String getDateTimeStr(time_t t);
|
||||||
|
String getTimeStr(time_t t);
|
||||||
uint64_t Serial2u64(const char *val);
|
uint64_t Serial2u64(const char *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class RestApi {
|
||||||
RestApi() {
|
RestApi() {
|
||||||
mTimezoneOffset = 0;
|
mTimezoneOffset = 0;
|
||||||
mFreeHeap = 0;
|
mFreeHeap = 0;
|
||||||
|
nr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(IApp *app, HMSYSTEM *sys, AsyncWebServer *srv, settings_t *config) {
|
void setup(IApp *app, HMSYSTEM *sys, AsyncWebServer *srv, settings_t *config) {
|
||||||
|
@ -539,6 +540,7 @@ class RestApi {
|
||||||
|
|
||||||
bool setCtrl(JsonObject jsonIn, JsonObject jsonOut) {
|
bool setCtrl(JsonObject jsonIn, JsonObject jsonOut) {
|
||||||
Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")]);
|
Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")]);
|
||||||
|
bool accepted = true;
|
||||||
if(NULL == iv) {
|
if(NULL == iv) {
|
||||||
jsonOut[F("error")] = F("inverter index invalid: ") + jsonIn[F("id")].as<String>();
|
jsonOut[F("error")] = F("inverter index invalid: ") + jsonIn[F("id")].as<String>();
|
||||||
return false;
|
return false;
|
||||||
|
@ -546,10 +548,10 @@ class RestApi {
|
||||||
|
|
||||||
if(F("power") == jsonIn[F("cmd")]) {
|
if(F("power") == jsonIn[F("cmd")]) {
|
||||||
iv->devControlCmd = (jsonIn[F("val")] == 1) ? TurnOn : TurnOff;
|
iv->devControlCmd = (jsonIn[F("val")] == 1) ? TurnOn : TurnOff;
|
||||||
iv->devControlRequest = true;
|
accepted = iv->setDevControlRequest();
|
||||||
} else if(F("restart") == jsonIn[F("restart")]) {
|
} else if(F("restart") == jsonIn[F("restart")]) {
|
||||||
iv->devControlCmd = Restart;
|
iv->devControlCmd = Restart;
|
||||||
iv->devControlRequest = true;
|
accepted = iv->setDevControlRequest();
|
||||||
}
|
}
|
||||||
else if(0 == strncmp("limit_", jsonIn[F("cmd")].as<const char*>(), 6)) {
|
else if(0 == strncmp("limit_", jsonIn[F("cmd")].as<const char*>(), 6)) {
|
||||||
iv->powerLimit[0] = jsonIn["val"];
|
iv->powerLimit[0] = jsonIn["val"];
|
||||||
|
@ -562,8 +564,9 @@ class RestApi {
|
||||||
else if(F("limit_nonpersistent_absolute") == jsonIn[F("cmd")])
|
else if(F("limit_nonpersistent_absolute") == jsonIn[F("cmd")])
|
||||||
iv->powerLimit[1] = AbsolutNonPersistent;
|
iv->powerLimit[1] = AbsolutNonPersistent;
|
||||||
iv->devControlCmd = ActivePowerContr;
|
iv->devControlCmd = ActivePowerContr;
|
||||||
iv->devControlRequest = true;
|
accepted = iv->setDevControlRequest();
|
||||||
mApp->ivSendHighPrio(iv);
|
if(accepted)
|
||||||
|
mApp->ivSendHighPrio(iv);
|
||||||
}
|
}
|
||||||
else if(F("dev") == jsonIn[F("cmd")]) {
|
else if(F("dev") == jsonIn[F("cmd")]) {
|
||||||
DPRINTLN(DBG_INFO, F("dev cmd"));
|
DPRINTLN(DBG_INFO, F("dev cmd"));
|
||||||
|
@ -574,6 +577,11 @@ class RestApi {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!accepted) {
|
||||||
|
jsonOut[F("error")] = F("inverter does not accept dev control request at this moment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +613,7 @@ class RestApi {
|
||||||
|
|
||||||
uint32_t mTimezoneOffset;
|
uint32_t mTimezoneOffset;
|
||||||
uint32_t mFreeHeap;
|
uint32_t mFreeHeap;
|
||||||
|
uint16_t nr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__WEB_API_H__*/
|
#endif /*__WEB_API_H__*/
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Web {
|
||||||
mWeb.on("/save", HTTP_ANY, std::bind(&Web::showSave, this, std::placeholders::_1));
|
mWeb.on("/save", HTTP_ANY, std::bind(&Web::showSave, this, std::placeholders::_1));
|
||||||
|
|
||||||
mWeb.on("/live", HTTP_ANY, std::bind(&Web::onLive, this, std::placeholders::_1));
|
mWeb.on("/live", HTTP_ANY, std::bind(&Web::onLive, this, std::placeholders::_1));
|
||||||
mWeb.on("/api1", HTTP_POST, std::bind(&Web::showWebApi, this, std::placeholders::_1));
|
//mWeb.on("/api1", HTTP_POST, std::bind(&Web::showWebApi, this, std::placeholders::_1));
|
||||||
|
|
||||||
#ifdef ENABLE_JSON_EP
|
#ifdef ENABLE_JSON_EP
|
||||||
mWeb.on("/json", HTTP_ANY, std::bind(&Web::showJson, this, std::placeholders::_1));
|
mWeb.on("/json", HTTP_ANY, std::bind(&Web::showJson, this, std::placeholders::_1));
|
||||||
|
@ -584,7 +584,7 @@ class Web {
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showWebApi(AsyncWebServerRequest *request) {
|
/*void showWebApi(AsyncWebServerRequest *request) {
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
DPRINTLN(DBG_VERBOSE, F("web::showWebApi"));
|
DPRINTLN(DBG_VERBOSE, F("web::showWebApi"));
|
||||||
DPRINTLN(DBG_DEBUG, request->arg("plain"));
|
DPRINTLN(DBG_DEBUG, request->arg("plain"));
|
||||||
|
@ -647,7 +647,7 @@ class Web {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request->send(200, "text/json", "{success:true}");
|
request->send(200, "text/json", "{success:true}");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void onSerial(AsyncWebServerRequest *request) {
|
void onSerial(AsyncWebServerRequest *request) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("onSerial"));
|
DPRINTLN(DBG_VERBOSE, F("onSerial"));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue