Compare commits

...

4 Commits

Author SHA1 Message Date
lumapu e601bfe443 0.8.151 2 days ago
lumapu d1fbb7d259 0.8.151 2 days ago
lumapu f06e56c14f 0.8.151 2 days ago
lumapu 28b303cac2 0.8.151 2 days ago
  1. 5
      src/CHANGES.md
  2. 23
      src/app.h
  3. 2
      src/appInterface.h
  4. 2
      src/defines.h
  5. 12
      src/hm/CommQueue.h
  6. 11
      src/hm/Communication.h
  7. 1
      src/hm/Radio.h
  8. 37
      src/hms/CmtRadio.h
  9. 4
      src/hms/cmt2300a.h
  10. 7
      src/publisher/pubMqtt.h
  11. 5
      src/web/RestApi.h
  12. 13
      src/web/html/setup.html
  13. 10
      src/web/lang.json

5
src/CHANGES.md

@ -1,5 +1,10 @@
# Development Changes
## 0.8.151 - 2024-10-03
* don't interrupt current command by setting a new limit #1757
* add button for CMT inverters to catch them independend on which frequency they were before #1749
* increased communication queue length from 100 to 200 for ESP32-S3
## 0.8.150 - 2024-10-02
* fix nullptr exception
* modified MqTT to not publish while not connected

23
src/app.h

@ -291,6 +291,29 @@ class app : public IApp, public ah::Scheduler {
return mConfig->cmt.enabled;
}
bool cmtSearch(uint8_t id, uint8_t toCh) override {
#if defined(ESP32)
Inverter<> *iv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
iv = mSys.getInverterByPos(i, true);
if(nullptr != iv) {
if(i == id)
break;
else
iv = nullptr;
}
}
if(nullptr != iv) {
mCmtRadio.catchInverter(iv, toCh);
return true;
}
#endif
return false;
}
uint8_t getNrfIrqPin(void) {
return mConfig->nrf.pinIrq;
}

2
src/appInterface.h

@ -56,6 +56,8 @@ class IApp {
virtual bool getNrfEnabled() = 0;
virtual bool getCmtEnabled() = 0;
virtual bool cmtSearch(uint8_t id, uint8_t toCh) = 0;
virtual uint32_t getMqttRxCnt() = 0;
virtual uint32_t getMqttTxCnt() = 0;

2
src/defines.h

@ -13,7 +13,7 @@
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 8
#define VERSION_PATCH 150
#define VERSION_PATCH 151
//-------------------------------------
typedef struct {
uint8_t ch;

12
src/hm/CommQueue.h

@ -12,12 +12,18 @@
#include "../utils/dbg.h"
#if !defined(ESP32)
#define vSemaphoreDelete(a)
#define xSemaphoreTake(a, b)
#define xSemaphoreGive(a)
#if !defined(vSemaphoreDelete)
#define vSemaphoreDelete(a)
#define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; }
#define xSemaphoreGive(a) { a = false; }
#endif
#endif
#if defined(CONFIG_IDF_TARGET_ESP32S3)
template <uint8_t N=200>
#else
template <uint8_t N=100>
#endif
class CommQueue {
protected: /* types */
static constexpr uint8_t DefaultAttempts = 5;

11
src/hm/Communication.h

@ -34,13 +34,6 @@ class Communication : public CommQueue<> {
mPrintWholeTrace = printWholeTrace;
}
void addImportant(Inverter<> *iv, uint8_t cmd) {
if(!mIsDevControl) // only reset communication once there is no other devcontrol command
mState = States::IDLE; // cancel current operation
mIsDevControl = true;
CommQueue::addImportant(iv, cmd);
}
void addPayloadListener(payloadListenerType cb) {
mCbPayload = cb;
}
@ -95,9 +88,6 @@ class Communication : public CommQueue<> {
mLocalBuf[i].len = 0;
}
if(!q->isDevControl)
mIsDevControl = false; // reset devcontrol flag
if(*mSerialDebug)
mHeu.printStatus(q->iv);
mHeu.getTxCh(q->iv);
@ -1066,7 +1056,6 @@ class Communication : public CommQueue<> {
Heuristic mHeu;
uint32_t mLastEmptyQueueMillis = 0;
bool mPrintSequenceDuration = false;
bool mIsDevControl = false; // holds if current command is devcontrol
};
#endif /*__COMMUNICATION_H__*/

1
src/hm/Radio.h

@ -29,6 +29,7 @@ class Radio {
virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0;
virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; }
virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; }
virtual void catchInverter(Inverter<> *iv, uint8_t toCh) {}
virtual bool isChipConnected(void) const { return false; }
virtual uint16_t getBaseFreqMhz() { return 0; }
virtual uint16_t getBootFreqMhz() { return 0; }

37
src/hms/CmtRadio.h

@ -35,6 +35,11 @@ class CmtRadio : public Radio {
return;
mCmt.loop();
if(nullptr != mCatchIv) {
if(mCmt.isTxReady())
catchInverterLoop();
}
if((!mIrqRcvd) && (!mRqstGetRx))
return;
getRx();
@ -93,6 +98,28 @@ class CmtRadio : public Radio {
return true;
}
void catchInverter(Inverter<> *iv, uint8_t toCh) override {
if(!isChipConnected())
return;
mCatchIv = iv;
mCatchIvCh = 1;
mCatchIvToCh = toCh;
mCmt.switchChannel(0);
sendSwitchChCmd(iv, toCh);
}
void catchInverterLoop() {
mCmt.switchChannel(mCatchIvCh);
sendSwitchChCmd(mCatchIv, mCatchIvToCh);
if(++mCatchIvCh == 0x29) {
mCmt.switchChannel(mCatchIvToCh);
mCatchIv = nullptr;
}
}
uint16_t getBaseFreqMhz(void) override {
return mCmt.getBaseFreqMhz();
}
@ -168,10 +195,6 @@ class CmtRadio : public Radio {
}
inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) {
//if(CMT_SWITCH_CHANNEL_CYCLE > ++mSwitchCycle)
// return;
//mSwitchCycle = 0;
/** ch:
* 0x00: 860.00 MHz
* 0x01: 860.25 MHz
@ -194,7 +217,6 @@ class CmtRadio : public Radio {
packet_t p;
p.millis = millis() - mMillis;
if(CmtStatus::SUCCESS == mCmt.getRx(p.packet, &p.len, 28, &p.rssi)) {
//mSwitchCycle = 0;
p.ch = 0; // not used for CMT inverters
mBufCtrl.push(p);
}
@ -210,7 +232,10 @@ class CmtRadio : public Radio {
bool mCmtAvail = false;
bool mRqstGetRx = false;
uint32_t mMillis = 0;
//uint8_t mSwitchCycle = 0;
Inverter<> *mCatchIv = nullptr;
uint8_t mCatchIvCh = 0;
uint8_t mCatchIvToCh = 0;
};
#endif /*__HMS_RADIO_H__*/

4
src/hms/cmt2300a.h

@ -188,6 +188,10 @@ class Cmt2300a {
}
}
bool isTxReady() {
return !mTxPending;
}
CmtStatus goRx(void) {
if(mTxPending)
return CmtStatus::ERR_TX_PENDING;

7
src/publisher/pubMqtt.h

@ -11,8 +11,11 @@
#if defined(ENABLE_MQTT)
#ifdef ESP8266
#include <ESP8266WiFi.h>
#define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; }
#define xSemaphoreGive(a) { a = false; }
#if !defined(vSemaphoreDelete)
#define vSemaphoreDelete(a)
#define xSemaphoreTake(a, b) { while(a) { yield(); } a = true; }
#define xSemaphoreGive(a) { a = false; }
#endif
#elif defined(ESP32)
#include <WiFi.h>
#endif

5
src/web/RestApi.h

@ -1131,6 +1131,11 @@ class RestApi {
iv->setDevCommand(jsonIn[F("val")].as<int>());
} else if(F("restart_ahoy") == jsonIn[F("cmd")]) {
mApp->setRebootFlag();
} else if(F("cmt_search") == jsonIn[F("cmd")]) {
if(!mApp->cmtSearch(jsonIn[F("id")], jsonIn[F("to_ch")])) {
jsonOut[F("error")] = F("ERR_INVERTER_NOT_FOUND");
return false;
}
} else {
jsonOut[F("error")] = F("ERR_UNKNOWN_CMD");
return false;

13
src/web/html/setup.html

@ -817,7 +817,8 @@
ml("input", {type: "hidden", name: "isnrf"}, null),
ml("div", {id: "setcmt"}, [
divRow("{#INV_FREQUENCY}", sel("freq", esp32cmtFreq, obj.freq)),
divRow("{#INV_POWER_LEVEL}", sel("cmtpa", esp32cmtPa, obj.pa))
divRow("{#INV_POWER_LEVEL}", sel("cmtpa", esp32cmtPa, obj.pa)),
divRow("{#INV_SEARCH}", ml("input", {type: "button", value: "{#BTN_SEARCH}", class: "btn", onclick: function() { cmtSearch(); }}, null))
]),
ml("div", {id: "setnrf"},
divRow("{#INV_POWER_LEVEL}", sel("nrfpa", nrfPa, obj.pa))
@ -902,6 +903,16 @@
getAjax("/api/setup", cb, "POST", JSON.stringify(o));
}
function cmtSearch() {
var o = {}
o.cmd = "cmt_search"
o.token = "*"
o.id = obj.id
o.to_ch = document.getElementsByName("freq")[0].value;
getAjax("/api/ctrl", cb, "POST", JSON.stringify(o));
}
function convHerf(sn) {
let sn_int = 0n;
const CHARS = "0123456789ABCDEFGHJKLMNPRSTUVWXY";

10
src/web/lang.json

@ -698,6 +698,16 @@
"en": "Pause communication during night (lat. and lon. need to be set)",
"de": "Kommunikation w&auml;hrend der Nacht pausieren (Breiten- und L&auml;ngengrad m&uuml;ssen gesetzt sein"
},
{
"token": "INV_SEARCH",
"en": "Catch Inverter",
"de": "Wechselrichter suchen"
},
{
"token": "BTN_SEARCH",
"en": "start",
"de": "starten"
},
{
"token": "BTN_SAVE",
"en": "save",

Loading…
Cancel
Save