mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-17 10:56:10 +02:00
parent
bd88242fea
commit
71e9fbdc0f
8 changed files with 75 additions and 67 deletions
|
@ -5,6 +5,7 @@
|
|||
* fixed range of HMS / HMT frequencies to 863 to 870 MHz #1238
|
||||
* changed `yield effiency` per default to `1.0` #1243
|
||||
* small heuristics improvements #1258
|
||||
* added class to combine inverter heuristics fields #1258
|
||||
|
||||
## 0.8.14 - 2023-12-07
|
||||
* fixed decimal points for temperature (WebUI) PR #1254 #1251
|
||||
|
|
|
@ -132,8 +132,7 @@ void ahoyeth::welcome(String ip, String mode) {
|
|||
void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info)
|
||||
{
|
||||
AWS_LOG(F("[ETH]: Got event..."));
|
||||
switch (event)
|
||||
{
|
||||
switch (event) {
|
||||
#if ( ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) && ( ARDUINO_ESP32_GIT_VER != 0x46d5afb1 ) )
|
||||
// For breaking core v2.0.0
|
||||
// Why so strange to define a breaking enum arduino_event_id_t in WiFiGeneric.h
|
||||
|
@ -153,20 +152,16 @@ void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info)
|
|||
break;
|
||||
|
||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
||||
if (!ESP32_W5500_eth_connected)
|
||||
{
|
||||
if (!ESP32_W5500_eth_connected) {
|
||||
#if defined (CONFIG_IDF_TARGET_ESP32S3)
|
||||
AWS_LOG3(F("ETH MAC: "), mEthSpi.macAddress(), F(", IPv4: "), ETH.localIP());
|
||||
#else
|
||||
AWS_LOG3(F("ETH MAC: "), ETH.macAddress(), F(", IPv4: "), ETH.localIP());
|
||||
#endif
|
||||
|
||||
if (ETH.fullDuplex())
|
||||
{
|
||||
if (ETH.fullDuplex()) {
|
||||
AWS_LOG0(F("FULL_DUPLEX, "));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
AWS_LOG0(F("HALF_DUPLEX, "));
|
||||
}
|
||||
|
||||
|
@ -212,16 +207,12 @@ void ahoyeth::onEthernetEvent(WiFiEvent_t event, arduino_event_info_t info)
|
|||
break;
|
||||
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
if (!ESP32_W5500_eth_connected)
|
||||
{
|
||||
if (!ESP32_W5500_eth_connected) {
|
||||
AWS_LOG3(F("ETH MAC: "), ETH.macAddress(), F(", IPv4: "), ETH.localIP());
|
||||
|
||||
if (ETH.fullDuplex())
|
||||
{
|
||||
if (ETH.fullDuplex()) {
|
||||
AWS_LOG0(F("FULL_DUPLEX, "));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
AWS_LOG0(F("HALF_DUPLEX, "));
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ class Communication : public CommQueue<> {
|
|||
} else
|
||||
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
|
||||
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(q->iv))
|
||||
q->iv->radioStatistics.txCnt++;
|
||||
mWaitTimeout = millis() + timeout;
|
||||
mWaitTimeout_min = millis() + timeout_min;
|
||||
|
@ -115,7 +115,7 @@ class Communication : public CommQueue<> {
|
|||
}
|
||||
mFirstTry = false;
|
||||
mlastTO_min = timeout_min;
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(q->iv))
|
||||
q->iv->radioStatistics.retransmits++; // got nothing
|
||||
mState = States::START;
|
||||
break;
|
||||
|
@ -180,7 +180,7 @@ class Communication : public CommQueue<> {
|
|||
}
|
||||
|
||||
if(checkIvSerial(&p->packet[1], q->iv)) {
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(q->iv))
|
||||
q->iv->radioStatistics.frmCnt++;
|
||||
|
||||
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
||||
|
@ -193,7 +193,7 @@ class Communication : public CommQueue<> {
|
|||
parseMiFrame(p, q);
|
||||
}
|
||||
} else {
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(q->iv))
|
||||
q->iv->radioStatistics.rxFail++; // got no complete payload
|
||||
DPRINTLN(DBG_WARN, F("Inverter serial does not match"));
|
||||
mWaitTimeout = millis() + timeout;
|
||||
|
@ -464,14 +464,14 @@ class Communication : public CommQueue<> {
|
|||
// ordering of lines is relevant for statistics
|
||||
if(succeeded) {
|
||||
mHeu.setGotAll(iv);
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(iv))
|
||||
iv->radioStatistics.rxSuccess++;
|
||||
} else if(iv->mGotFragment) {
|
||||
mHeu.setGotFragment(iv);
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(iv))
|
||||
iv->radioStatistics.rxFail++; // got no complete payload
|
||||
} else {
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(iv))
|
||||
iv->radioStatistics.rxFailNoAnser++; // got nothing
|
||||
mHeu.setGotNothing(iv);
|
||||
mWaitTimeout = millis() + WAIT_GAP_TIMEOUT;
|
||||
|
@ -682,7 +682,7 @@ class Communication : public CommQueue<> {
|
|||
|
||||
if(q->iv->miMultiParts == 7) {
|
||||
mHeu.setGotAll(q->iv);
|
||||
if(!mHeu.getTestModeEnabled())
|
||||
if(!mHeu.getTestModeEnabled(q->iv))
|
||||
q->iv->radioStatistics.rxSuccess++;
|
||||
} else
|
||||
mHeu.setGotFragment(q->iv);
|
||||
|
|
|
@ -8,11 +8,7 @@
|
|||
|
||||
#include "../utils/dbg.h"
|
||||
#include "hmInverter.h"
|
||||
|
||||
#define RF_MAX_CHANNEL_ID 5
|
||||
#define RF_MAX_QUALITY 4
|
||||
#define RF_MIN_QUALTIY -6
|
||||
#define RF_NA -99
|
||||
#include "HeuristicInv.h"
|
||||
|
||||
class Heuristic {
|
||||
public:
|
||||
|
@ -23,53 +19,52 @@ class Heuristic {
|
|||
uint8_t bestId = 0;
|
||||
int8_t bestQuality = -6;
|
||||
for(uint8_t i = 0; i < RF_MAX_CHANNEL_ID; i++) {
|
||||
if(iv->txRfQuality[i] > bestQuality) {
|
||||
bestQuality = iv->txRfQuality[i];
|
||||
if(iv->heuristics.txRfQuality[i] > bestQuality) {
|
||||
bestQuality = iv->heuristics.txRfQuality[i];
|
||||
bestId = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(mTestEn) {
|
||||
if(iv->heuristics.testEn) {
|
||||
DPRINTLN(DBG_INFO, F("heuristic test mode"));
|
||||
mTestIdx = (mTestIdx + 1) % RF_MAX_CHANNEL_ID;
|
||||
iv->heuristics.testIdx = (iv->heuristics.testIdx + 1) % RF_MAX_CHANNEL_ID;
|
||||
|
||||
if (mTestIdx == bestId)
|
||||
mTestIdx = (mTestIdx + 1) % RF_MAX_CHANNEL_ID;
|
||||
if (iv->heuristics.testIdx == bestId)
|
||||
iv->heuristics.testIdx = (iv->heuristics.testIdx + 1) % RF_MAX_CHANNEL_ID;
|
||||
|
||||
// test channel get's quality of best channel (maybe temporarily, see in 'setGotNothing')
|
||||
mStoredIdx = iv->txRfQuality[mTestIdx];
|
||||
iv->txRfQuality[mTestIdx] = bestQuality;
|
||||
iv->heuristics.storedIdx = iv->heuristics.txRfQuality[iv->heuristics.testIdx];
|
||||
iv->heuristics.txRfQuality[iv->heuristics.testIdx] = bestQuality;
|
||||
|
||||
iv->txRfChId = mTestIdx;
|
||||
iv->heuristics.txRfChId = iv->heuristics.testIdx;
|
||||
} else
|
||||
iv->txRfChId = bestId;
|
||||
iv->heuristics.txRfChId = bestId;
|
||||
|
||||
return id2Ch(iv->txRfChId);
|
||||
return id2Ch(iv->heuristics.txRfChId);
|
||||
}
|
||||
|
||||
void setGotAll(Inverter<> *iv) {
|
||||
updateQuality(iv, 2); // GOOD
|
||||
mTestEn = false;
|
||||
iv->heuristics.testEn = false;
|
||||
}
|
||||
|
||||
void setGotFragment(Inverter<> *iv) {
|
||||
updateQuality(iv, 1); // OK
|
||||
mTestEn = false;
|
||||
iv->heuristics.testEn = false;
|
||||
}
|
||||
|
||||
void setGotNothing(Inverter<> *iv) {
|
||||
if(RF_NA != mStoredIdx) {
|
||||
if(RF_NA != iv->heuristics.storedIdx) {
|
||||
// if communication fails on first try with temporarily good level, revert it back to its original level
|
||||
iv->txRfQuality[iv->txRfChId] = mStoredIdx;
|
||||
mStoredIdx = RF_NA;
|
||||
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = iv->heuristics.storedIdx;
|
||||
iv->heuristics.storedIdx = RF_NA;
|
||||
}
|
||||
|
||||
if(!mTestEn) {
|
||||
if(!iv->heuristics.testEn) {
|
||||
updateQuality(iv, -2); // BAD
|
||||
mTestEn = true;
|
||||
}
|
||||
else
|
||||
mTestEn = false;
|
||||
iv->heuristics.testEn = true;
|
||||
} else
|
||||
iv->heuristics.testEn = false;
|
||||
}
|
||||
|
||||
void printStatus(Inverter<> *iv) {
|
||||
|
@ -77,7 +72,7 @@ class Heuristic {
|
|||
DBGPRINT(F("Radio infos:"));
|
||||
for(uint8_t i = 0; i < RF_MAX_CHANNEL_ID; i++) {
|
||||
DBGPRINT(F(" "));
|
||||
DBGPRINT(String(iv->txRfQuality[i]));
|
||||
DBGPRINT(String(iv->heuristics.txRfQuality[i]));
|
||||
}
|
||||
DBGPRINT(F(" | t: "));
|
||||
DBGPRINT(String(iv->radioStatistics.txCnt));
|
||||
|
@ -91,17 +86,17 @@ class Heuristic {
|
|||
DBGPRINTLN(String(iv->config->powerLevel));
|
||||
}
|
||||
|
||||
bool getTestModeEnabled(void) {
|
||||
return mTestEn;
|
||||
bool getTestModeEnabled(Inverter<> *iv) {
|
||||
return iv->heuristics.testEn;
|
||||
}
|
||||
|
||||
private:
|
||||
void updateQuality(Inverter<> *iv, uint8_t quality) {
|
||||
iv->txRfQuality[iv->txRfChId] += quality;
|
||||
if(iv->txRfQuality[iv->txRfChId] > RF_MAX_QUALITY)
|
||||
iv->txRfQuality[iv->txRfChId] = RF_MAX_QUALITY;
|
||||
else if(iv->txRfQuality[iv->txRfChId] < RF_MIN_QUALTIY)
|
||||
iv->txRfQuality[iv->txRfChId] = RF_MIN_QUALTIY;
|
||||
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] += quality;
|
||||
if(iv->heuristics.txRfQuality[iv->heuristics.txRfChId] > RF_MAX_QUALITY)
|
||||
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = RF_MAX_QUALITY;
|
||||
else if(iv->heuristics.txRfQuality[iv->heuristics.txRfChId] < RF_MIN_QUALTIY)
|
||||
iv->heuristics.txRfQuality[iv->heuristics.txRfChId] = RF_MIN_QUALTIY;
|
||||
}
|
||||
|
||||
inline uint8_t id2Ch(uint8_t id) {
|
||||
|
@ -117,9 +112,6 @@ class Heuristic {
|
|||
|
||||
private:
|
||||
uint8_t mChList[5] = {03, 23, 40, 61, 75};
|
||||
bool mTestEn = false;
|
||||
uint8_t mTestIdx = 0;
|
||||
int8_t mStoredIdx = RF_NA;
|
||||
};
|
||||
|
||||
|
||||
|
|
24
src/hm/HeuristicInv.h
Normal file
24
src/hm/HeuristicInv.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __HEURISTIC_INV_H__
|
||||
#define __HEURISTIC_INV_H__
|
||||
|
||||
#define RF_MAX_CHANNEL_ID 5
|
||||
#define RF_MAX_QUALITY 4
|
||||
#define RF_MIN_QUALTIY -6
|
||||
#define RF_NA -99
|
||||
|
||||
class HeuristicInv {
|
||||
public:
|
||||
int8_t txRfQuality[5]; // heuristics tx quality (check 'Heuristics.h')
|
||||
uint8_t txRfChId; // RF TX channel id
|
||||
|
||||
bool testEn = false;
|
||||
uint8_t testIdx = 0;
|
||||
int8_t storedIdx = RF_NA;
|
||||
};
|
||||
|
||||
#endif /*__HEURISTIC_INV_H__*/
|
|
@ -12,6 +12,7 @@
|
|||
#endif
|
||||
|
||||
#include "hmDefines.h"
|
||||
#include "HeuristicInv.h"
|
||||
#include "../hms/hmsDefines.h"
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
@ -131,8 +132,7 @@ class Inverter {
|
|||
bool mGotLastMsg; // shows if inverter has already finished transmission cycle
|
||||
Radio *radio; // pointer to associated radio class
|
||||
statistics_t radioStatistics; // information about transmitted, failed, ... packets
|
||||
int8_t txRfQuality[5]; // heuristics tx quality (check 'Heuristics.h')
|
||||
uint8_t txRfChId; // RF TX channel id
|
||||
HeuristicInv heuristics;
|
||||
uint8_t curCmtFreq; // current used CMT frequency, used to check if freq. was changed during runtime
|
||||
bool commEnabled; // 'pause night communication' sets this field to false
|
||||
|
||||
|
@ -160,7 +160,7 @@ class Inverter {
|
|||
commEnabled = true;
|
||||
|
||||
memset(&radioStatistics, 0, sizeof(statistics_t));
|
||||
memset(txRfQuality, -6, 5);
|
||||
memset(heuristics.txRfQuality, -6, 5);
|
||||
|
||||
memset(mOffYD, 0, sizeof(float) * 6);
|
||||
memset(mLastYD, 0, sizeof(float) * 6);
|
||||
|
|
|
@ -301,7 +301,7 @@ class HmRadio : public Radio {
|
|||
updateCrcs(&len, appendCrc16);
|
||||
|
||||
// set TX and RX channels
|
||||
mTxChIdx = mRfChLst[iv->txRfChId];
|
||||
mTxChIdx = mRfChLst[iv->heuristics.txRfChId];
|
||||
|
||||
if(*mSerialDebug) {
|
||||
DPRINT_IVID(DBG_INFO, iv->id);
|
||||
|
|
|
@ -120,7 +120,7 @@ class Display {
|
|||
if (iv->isAvailable()) { // consider only radio quality of inverters still communicating
|
||||
int8_t maxQInv = -6;
|
||||
for(uint8_t ch = 0; ch < RF_MAX_CHANNEL_ID; ch++) {
|
||||
int8_t q = iv->txRfQuality[ch];
|
||||
int8_t q = iv->heuristics.txRfQuality[ch];
|
||||
if (q > maxQInv)
|
||||
maxQInv = q;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue