Browse Source

Merge branch 'development03' into hms

pull/935/head
lumapu 2 years ago
parent
commit
f2ce528a56
  1. 2
      .github/workflows/compile_development.yml
  2. 2
      .github/workflows/compile_release.yml
  3. 1
      .gitignore
  4. 5
      scripts/getVersion.py
  5. 5
      src/.vscode/settings.json
  6. 10
      src/CHANGES.md
  7. 3
      src/app.cpp
  8. 12
      src/config/config.h
  9. 21
      src/config/config_override_example.h
  10. 16
      src/config/settings.h
  11. 2
      src/defines.h
  12. 2
      src/hm/hmInverter.h
  13. 4
      src/hm/hmPayload.h
  14. 20
      src/hm/hmRadio.h
  15. 10
      src/platformio.ini
  16. 10
      src/plugins/Display/Display_ePaper.cpp
  17. 90
      src/publisher/pubMqtt.h
  18. 3
      src/web/RestApi.h
  19. 68
      src/web/html/setup.html
  20. 17
      src/web/web.h

2
.github/workflows/compile_development.yml

@ -47,7 +47,7 @@ jobs:
run: python convert.py
- name: Run PlatformIO
run: pio run -d src --environment esp8266-release --environment esp8266-release-prometheus --environment esp8285-release --environment esp32-wroom32-release --environment esp32-wroom32-release-prometheus
run: pio run -d src --environment esp8266-release --environment esp8266-release-prometheus --environment esp8285-release --environment esp32-wroom32-release --environment esp32-wroom32-release-prometheus --environment opendtufusionv1-release
- name: Rename Binary files
id: rename-binary-files

2
.github/workflows/compile_release.yml

@ -51,7 +51,7 @@ jobs:
run: python convert.py
- name: Run PlatformIO
run: pio run -d src --environment esp8266-release --environment esp8266-release-prometheus --environment esp8285-release --environment esp32-wroom32-release --environment esp32-wroom32-release-prometheus
run: pio run -d src --environment esp8266-release --environment esp8266-release-prometheus --environment esp8285-release --environment esp32-wroom32-release --environment esp32-wroom32-release-prometheus --environment opendtufusionv1-release
- name: Rename Binary files
id: rename-binary-files

1
.gitignore

@ -12,3 +12,4 @@ src/web/html/tmp/*
*.db
*.suo
*.ipch
src/output.map

5
scripts/getVersion.py

@ -78,6 +78,11 @@ def readVersion(path, infile):
dst = path + "firmware/" + versionout
os.rename(src, dst)
versionout = version[:-1] + "_" + sha + "_esp32s3.bin"
src = path + ".pio/build/opendtufusionv1-release/firmware.bin"
dst = path + "firmware/" + versionout
os.rename(src, dst)
# other ESP32 bin files
src = path + ".pio/build/esp32-wroom32-release/"
dst = path + "firmware/"

5
src/.vscode/settings.json

@ -4,20 +4,16 @@
"workbench.colorCustomizations": {
"editorLineNumber.foreground": "#00ff00"
},
"editor.wordWrap": "off",
"files.eol": "\n",
"files.trimTrailingWhitespace": true,
"diffEditor.ignoreTrimWhitespace": true,
"files.autoSave": "afterDelay",
"editor.tabSize": 4,
"editor.insertSpaces": true,
// `editor.tabSize` and `editor.insertSpaces` will be detected based on the file contents.
// Set to false to keep the values you've explicitly set, above.
"editor.detectIndentation": false,
// https://clang.llvm.org/docs/ClangFormatStyleOptions.html
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 0}",
"files.associations": {
@ -86,4 +82,5 @@
"thread": "cpp"
},
"cmake.configureOnOpen": false,
"editor.formatOnSave": false,
}

10
src/CHANGES.md

@ -2,6 +2,16 @@
(starting from release version `0.5.66`)
## 0.5.109
* reduced heap fragmentation by optimizing MqTT #768
* ePaper: centered text thx @knickohr
## 0.5.108
* merge: PR SPI pins configureable (ESP32) #807, #806
* merge: PR MI serial outputs #809
* fix: no MQTT `total` sensor for autodiscover if only one inverter was found #805
* fix: MQTT `total` renamed to `device_name` + `_TOTOL` for better visibility #805
## 0.5.107
* fix: show save message
* fix: removed serial newline for `enqueueCmd`

3
src/app.cpp

@ -29,9 +29,8 @@ void app::setup() {
else
DBGPRINTLN(F("false"));
mSys.setup();
if(mConfig->nrf.enabled) {
mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs);
mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso);
mNrfRadio.enableDebug();
}
#if defined(ESP32)

12
src/config/config.h

@ -44,13 +44,25 @@
// default pinout (GPIO Number)
#if defined(ESP32)
// this is the default ESP32 (son-S) pinout on the WROOM modules for VSPI,
// for the ESP32-S3 there is no sane 'default', as it has full flexibility
// to map its two HW SPIs anywhere and PCBs differ materially,
// so it has to be selected in the Web UI
#define DEF_CS_PIN 5
#define DEF_CE_PIN 4
#define DEF_IRQ_PIN 16
#define DEF_MISO_PIN 19
#define DEF_MOSI_PIN 23
#define DEF_SCLK_PIN 18
#else
#define DEF_CS_PIN 15
#define DEF_CE_PIN 2
#define DEF_IRQ_PIN 0
// these are given to relay the correct values via API
// they cannot actually be moved for ESP82xx models
#define DEF_MISO_PIN 12
#define DEF_MOSI_PIN 13
#define DEF_SCLK_PIN 14
#endif
// default NRF24 power, possible values (0 - 3)

21
src/config/config_override_example.h

@ -17,14 +17,19 @@
#undef FB_WIFI_PWD
#define FB_WIFI_PWD "MY_WIFI_KEY"
// ESP32 default pinout
#undef DEF_RF24_CS_PIN
#define DEF_RF24_CS_PIN 5
#undef DEF_RF24_CE_PIN
#define DEF_RF24_CE_PIN 4
#undef DEF_RF24_IRQ_PIN
#define DEF_RF24_IRQ_PIN 16
// ESP32-S3 example pinout
#undef DEF_CS_PIN
#define DEF_CS_PIN 37
#undef DEF_CE_PIN
#define DEF_CE_PIN 38
#undef DEF_IRQ_PIN
#define DEF_IRQ_PIN 47
#undef DEF_MISO_PIN
#define DEF_MISO_PIN 48
#undef DEF_MOSI_PIN
#define DEF_MOSI_PIN 35
#undef DEF_SCLK_PIN
#define DEF_SCLK_PIN 36
// Offset for midnight Ticker Example: 1 second before midnight (local time)
#undef MIDNIGHTTICKER_OFFSET

16
src/config/settings.h

@ -74,6 +74,9 @@ typedef struct {
uint8_t pinCs;
uint8_t pinCe;
uint8_t pinIrq;
uint8_t pinMiso;
uint8_t pinMosi;
uint8_t pinSclk;
uint8_t amplifierPower;
} cfgNrf24_t;
@ -359,6 +362,10 @@ class settings {
mCfg.nrf.pinCs = DEF_CS_PIN;
mCfg.nrf.pinCe = DEF_CE_PIN;
mCfg.nrf.pinIrq = DEF_IRQ_PIN;
mCfg.nrf.pinMiso = DEF_MISO_PIN;
mCfg.nrf.pinMosi = DEF_MOSI_PIN;
mCfg.nrf.pinSclk = DEF_SCLK_PIN;
mCfg.nrf.amplifierPower = DEF_AMPLIFIERPOWER & 0x03;
mCfg.nrf.enabled = true;
@ -447,6 +454,9 @@ class settings {
obj[F("cs")] = mCfg.nrf.pinCs;
obj[F("ce")] = mCfg.nrf.pinCe;
obj[F("irq")] = mCfg.nrf.pinIrq;
obj[F("sclk")] = mCfg.nrf.pinSclk;
obj[F("mosi")] = mCfg.nrf.pinMosi;
obj[F("miso")] = mCfg.nrf.pinMiso;
obj[F("pwr")] = mCfg.nrf.amplifierPower;
obj[F("en")] = (bool) mCfg.nrf.enabled;
} else {
@ -455,12 +465,18 @@ class settings {
mCfg.nrf.pinCs = obj[F("cs")];
mCfg.nrf.pinCe = obj[F("ce")];
mCfg.nrf.pinIrq = obj[F("irq")];
mCfg.nrf.pinSclk = obj[F("sclk")];
mCfg.nrf.pinMosi = obj[F("mosi")];
mCfg.nrf.pinMiso = obj[F("miso")];
mCfg.nrf.amplifierPower = obj[F("pwr")];
mCfg.nrf.enabled = (bool) obj[F("en")];
if((obj[F("cs")] == obj[F("ce")])) {
mCfg.nrf.pinCs = DEF_CS_PIN;
mCfg.nrf.pinCe = DEF_CE_PIN;
mCfg.nrf.pinIrq = DEF_IRQ_PIN;
mCfg.nrf.pinSclk = DEF_SCLK_PIN;
mCfg.nrf.pinMosi = DEF_MOSI_PIN;
mCfg.nrf.pinMiso = DEF_MISO_PIN;
}
}
}

2
src/defines.h

@ -13,7 +13,7 @@
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 5
#define VERSION_PATCH 107
#define VERSION_PATCH 109
//-------------------------------------
typedef struct {

2
src/hm/hmInverter.h

@ -305,7 +305,7 @@ class Inverter {
if (getPosByChFld(0, FLD_ACT_ACTIVE_PWR_LIMIT, rec) == pos){
actPowerLimit = rec->record[pos];
DPRINT(DBG_DEBUG, F("Inverter actual power limit: "));
DBGPRINTLN(String(actPowerLimit, 1));
DPRINTLN(DBG_DEBUG, String(actPowerLimit, 1));
}
}
else if (rec->assign == AlarmDataAssignment) {

4
src/hm/hmPayload.h

@ -170,7 +170,7 @@ class HmPayload {
DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored"));
} else {
DPRINT(DBG_DEBUG, F("PID: 0x"));
DBGHEXLN(*pid);
DPRINTLN(DBG_DEBUG, String(*pid, HEX));
if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) {
memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11);
mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11;
@ -287,7 +287,7 @@ class HmPayload {
DPRINT(DBG_INFO, F("procPyld: txid: 0x"));
DBGHEXLN(mPayload[iv->id].txId);
DPRINT(DBG_DEBUG, F("procPyld: max: "));
DBGPRINTLN(String(mPayload[iv->id].maxPackId));
DPRINTLN(DBG_DEBUG, String(mPayload[iv->id].maxPackId));
record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
mPayload[iv->id].complete = true;

20
src/hm/hmRadio.h

@ -10,6 +10,7 @@
#include <RF24.h>
#include "../utils/crc.h"
#include "../config/config.h"
#include "SPI.h"
#define SPI_SPEED 1000000
@ -26,7 +27,7 @@ const char* const rf24AmpPowerNames[] = {"MIN", "LOW", "HIGH", "MAX"};
//-----------------------------------------------------------------------------
// HM Radio class
//-----------------------------------------------------------------------------
template <uint8_t IRQ_PIN = DEF_IRQ_PIN, uint8_t CE_PIN = DEF_CE_PIN, uint8_t CS_PIN = DEF_CS_PIN, uint8_t AMP_PWR = RF24_PA_LOW>
template <uint8_t IRQ_PIN = DEF_IRQ_PIN, uint8_t CE_PIN = DEF_CE_PIN, uint8_t CS_PIN = DEF_CS_PIN, uint8_t AMP_PWR = RF24_PA_LOW, uint8_t SCLK_PIN = DEF_SCLK_PIN, uint8_t MOSI_PIN = DEF_MOSI_PIN, uint8_t MISO_PIN = DEF_MISO_PIN>
class HmRadio {
public:
HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) {
@ -57,7 +58,7 @@ class HmRadio {
}
~HmRadio() {}
void setup(uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN) {
void setup(uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) {
DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup"));
pinMode(irq, INPUT_PULLUP);
@ -79,7 +80,19 @@ class HmRadio {
// change the byte order of the DTU serial number and append the required 0x01 at the end
DTU_RADIO_ID = ((uint64_t)(((dtuSn >> 24) & 0xFF) | ((dtuSn >> 8) & 0xFF00) | ((dtuSn << 8) & 0xFF0000) | ((dtuSn << 24) & 0xFF000000)) << 8) | 0x01;
mNrf24.begin(ce, cs);
#ifdef ESP32
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
mSpi = new SPIClass(FSPI);
#else
mSpi = new SPIClass(VSPI);
#endif
mSpi->begin(sclk, miso, mosi, cs);
#else
//the old ESP82xx cannot freely place their SPI pins
mSpi = new SPIClass();
mSpi->begin();
#endif
mNrf24.begin(mSpi, ce, cs);
mNrf24.setRetries(3, 15); // 3*250us + 250us and 15 loops -> 15ms
mNrf24.setChannel(mRfChLst[mRxChIdx]);
@ -320,6 +333,7 @@ class HmRadio {
uint8_t mTxChIdx;
uint8_t mRxChIdx;
SPIClass* mSpi;
RF24 mNrf24;
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
};

10
src/platformio.ini

@ -133,3 +133,13 @@ monitor_filters =
;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line
log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory
[env:opendtufusionv1-release]
platform = espressif32
board = esp32-s3-devkitc-1
build_flags = -D RELEASE -std=gnu++14
build_unflags = -std=gnu++11
monitor_filters =
;default ; Remove typical terminal control codes from input
time ; Add timestamp with milliseconds for each new line
;log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory

10
src/plugins/Display/Display_ePaper.cpp

@ -146,28 +146,28 @@ void DisplayEPaper::actualPowerPaged(float _totalPower, float _totalYieldDay, fl
_display->setFont(&FreeSans12pt7b);
y = _display->height() / 2;
_display->setCursor(0, y);
_display->setCursor(5, y);
_display->print("today:");
snprintf(_fmtText, _display->width(), "%.0f", _totalYieldDay);
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
x = ((_display->width() - tbw) / 2) - tbx;
_display->setCursor(x, y);
_display->print(_fmtText);
_display->setCursor(_display->width() - 33, y);
_display->setCursor(_display->width() - 38, y);
_display->println("Wh");
y = y + tbh + 7;
_display->setCursor(0, y);
_display->setCursor(5, y);
_display->print("total:");
snprintf(_fmtText, _display->width(), "%.1f", _totalYieldTotal);
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
x = ((_display->width() - tbw) / 2) - tbx;
_display->setCursor(x, y);
_display->print(_fmtText);
_display->setCursor(_display->width() - 45, y);
_display->setCursor(_display->width() - 50, y);
_display->println("kWh");
_display->setCursor(0, _display->height() - (mHeadFootPadding + 10));
_display->setCursor(10, _display->height() - (mHeadFootPadding + 10));
snprintf(_fmtText, sizeof(_fmtText), "%d Inverter online", _isprod);
_display->println(_fmtText);

90
src/publisher/pubMqtt.h

@ -38,6 +38,7 @@ typedef struct {
bool running;
uint8_t lastIvId;
uint8_t sub;
uint8_t foundIvCnt;
} discovery_t;
template<class HMSYSTEM>
@ -117,9 +118,8 @@ class PubMqtt {
}
void tickerMinute() {
char val[12];
snprintf(val, 12, "%ld", millis() / 1000);
publish(subtopics[MQTT_UPTIME], val);
snprintf(mVal, 40, "%ld", millis() / 1000);
publish(subtopics[MQTT_UPTIME], mVal);
publish(subtopics[MQTT_RSSI], String(WiFi.RSSI()).c_str());
publish(subtopics[MQTT_FREE_HEAP], String(ESP.getFreeHeap()).c_str());
#ifndef ESP32
@ -151,12 +151,10 @@ class PubMqtt {
}
void tickerMidnight() {
char topic[7 + MQTT_TOPIC_LEN], val[4];
// set Total YieldDay to zero
snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[FLD_YD]);
snprintf(val, 2, "0");
publish(topic, val, true);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "total/%s", fields[FLD_YD]);
snprintf(mVal, 2, "0");
publish(mSubTopic, mVal, true);
}
void payloadEventListener(uint8_t cmd) {
@ -176,7 +174,6 @@ class PubMqtt {
if(!mClient.connected())
return;
memset(mTopic, 0, MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1);
if(addTopic){
snprintf(mTopic, MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1, "%s/%s", mCfgMqtt->topic, subTopic);
} else {
@ -224,14 +221,13 @@ class PubMqtt {
mDiscovery.running = true;
mDiscovery.lastIvId = 0;
mDiscovery.sub = 0;
mDiscovery.foundIvCnt = 0;
}
void setPowerLimitAck(Inverter<> *iv) {
if (NULL != iv) {
char topic[7 + MQTT_TOPIC_LEN];
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
publish(topic, "true", true);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, subtopics[MQTT_ACK_PWR_LMT]);
publish(mSubTopic, "true", true);
}
}
@ -245,12 +241,11 @@ class PubMqtt {
tickerMinute();
publish(mLwtTopic, mqttStr[MQTT_STR_LWT_CONN], true, false);
char sub[20];
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
snprintf(sub, 20, "ctrl/limit/%d", i);
subscribe(sub);
snprintf(sub, 20, "ctrl/restart/%d", i);
subscribe(sub);
snprintf(mVal, 20, "ctrl/limit/%d", i);
subscribe(mVal);
snprintf(mVal, 20, "ctrl/restart/%d", i);
subscribe(mVal);
}
subscribe(subscr[MQTT_SUBS_SET_TIME]);
}
@ -350,14 +345,16 @@ class PubMqtt {
uint8_t fldTotal[4] = {FLD_PAC, FLD_YT, FLD_YD, FLD_PDC};
const char* unitTotal[4] = {"W", "kWh", "Wh", "W"};
String node_mac = WiFi.macAddress().substring(12,14)+ WiFi.macAddress().substring(15,17);
String node_id = "AHOY_DTU_" + node_mac;
String node_id = String(mDevName) + "_TOTAL";
bool total = (mDiscovery.lastIvId == MAX_NUM_INVERTERS);
Inverter<> *iv = mSys->getInverterByPos(mDiscovery.lastIvId);
record_t<> *rec;
if (NULL != iv)
record_t<> *rec = NULL;
if (NULL != iv) {
rec = iv->getRecordStruct(RealTimeRunData_Debug);
if(0 == mDiscovery.sub)
mDiscovery.foundIvCnt++;
}
if ((NULL != iv) || total) {
if (!total) {
@ -420,18 +417,25 @@ class PubMqtt {
if(++mDiscovery.sub == ((!total) ? (rec->length) : 4)) {
mDiscovery.sub = 0;
if(++mDiscovery.lastIvId == (MAX_NUM_INVERTERS + 1))
mDiscovery.running = false;
checkDiscoveryEnd();
}
} else {
mDiscovery.sub = 0;
if(++mDiscovery.lastIvId == (MAX_NUM_INVERTERS + 1))
mDiscovery.running = false;
checkDiscoveryEnd();
}
yield();
}
void checkDiscoveryEnd(void) {
if(++mDiscovery.lastIvId == MAX_NUM_INVERTERS) {
// check if only one inverter was found, then don't create 'total' sensor
if(mDiscovery.foundIvCnt == 1)
mDiscovery.running = false;
} else if(mDiscovery.lastIvId == (MAX_NUM_INVERTERS + 1))
mDiscovery.running = false;
}
const char *getFieldDeviceClass(uint8_t fieldId) {
uint8_t pos = 0;
for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) {
@ -455,7 +459,6 @@ class PubMqtt {
bool allAvail = true; // shows if all enabled inverters are available
bool anyAvail = false; // shows if at least one enabled inverter is available
bool changed = false;
char topic[7 + MQTT_TOPIC_LEN], val[40];
Inverter<> *iv;
record_t<> *rec;
@ -485,19 +488,19 @@ class PubMqtt {
mLastIvState[id] = status;
changed = true;
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
snprintf(val, 40, "%d", status);
publish(topic, val, true);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
snprintf(mVal, 40, "%d", status);
publish(mSubTopic, mVal, true);
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
snprintf(val, 40, "%d", iv->getLastTs(rec));
publish(topic, val, true);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
snprintf(mVal, 40, "%d", iv->getLastTs(rec));
publish(mSubTopic, mVal, true);
}
}
if(changed) {
snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE)));
publish("status", val, true);
snprintf(mVal, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE)));
publish("status", mVal, true);
}
return anyAvail;
@ -517,7 +520,6 @@ class PubMqtt {
}
void sendData(Inverter<> *iv, uint8_t curInfoCmd) {
char topic[7 + MQTT_TOPIC_LEN], val[40];
record_t<> *rec = iv->getRecordStruct(curInfoCmd);
if (iv->getLastTs(rec) > 0) {
@ -534,9 +536,9 @@ class PubMqtt {
}
}
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
snprintf(val, 40, "%g", ah::round3(iv->getValue(i, rec)));
publish(topic, val, retained);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
snprintf(mVal, 40, "%g", ah::round3(iv->getValue(i, rec)));
publish(mSubTopic, mVal, retained);
yield();
}
@ -551,7 +553,6 @@ class PubMqtt {
if(mSendList.empty())
return;
char topic[7 + MQTT_TOPIC_LEN], val[40];
float total[4];
bool RTRDataHasBeenSent = false;
@ -623,9 +624,9 @@ class PubMqtt {
retained = false;
break;
}
snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
snprintf(val, 40, "%g", ah::round3(total[i]));
publish(topic, val, retained);
snprintf(mSubTopic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
snprintf(mVal, 40, "%g", ah::round3(total[i]));
publish(mSubTopic, mVal, retained);
}
RTRDataHasBeenSent = true;
yield();
@ -660,7 +661,8 @@ class PubMqtt {
char mClientId[24]; // number of chars is limited to 23 up to v3.1 of MQTT
// global buffer for mqtt topic. Used when publishing mqtt messages.
char mTopic[MQTT_TOPIC_LEN + 32 + MAX_NAME_LENGTH + 1];
char mSubTopic[32 + MAX_NAME_LENGTH + 1];
char mVal[40];
discovery_t mDiscovery;
};

3
src/web/RestApi.h

@ -387,6 +387,9 @@ class RestApi {
obj[F("cs")] = mConfig->nrf.pinCs;
obj[F("ce")] = mConfig->nrf.pinCe;
obj[F("irq")] = mConfig->nrf.pinIrq;
obj[F("sclk")] = mConfig->nrf.pinSclk;
obj[F("mosi")] = mConfig->nrf.pinMosi;
obj[F("miso")] = mConfig->nrf.pinMiso;
obj[F("led0")] = mConfig->led.led0;
obj[F("led1")] = mConfig->led.led1;
}

68
src/web/html/setup.html

@ -367,6 +367,54 @@
[36, "VP (GPIO36)"],
[39, "VN (GPIO39)"]
];
var esp32s3pins = [
[255, "off / default"],
[0, "GPIO0 (DONT USE - BOOT)"],
[1, "GPIO1"],
[2, "GPIO2"],
[3, "GPIO3"],
[4, "GPIO4"],
[5, "GPIO5"],
[6, "GPIO6"],
[7, "GPIO7"],
[8, "GPIO8"],
[9, "GPIO9"],
[10, "GPIO10"],
[11, "GPIO11"],
[12, "GPIO12"],
[13, "GPIO13"],
[14, "GPIO14"],
[15, "GPIO15"],
[16, "GPIO16"],
[17, "GPIO17"],
[18, "GPIO18"],
[19, "GPIO19 (DONT USE - USB-)"],
[20, "GPIO20 (DONT USE - USB+)"],
[21, "GPIO21"],
[26, "GPIO26 (PSRAM - not available)"],
[27, "GPIO27 (FLASH - not available)"],
[28, "GPIO28 (FLASH - not available)"],
[29, "GPIO29 (FLASH - not available)"],
[30, "GPIO30 (FLASH - not available)"],
[31, "GPIO31 (FLASH - not available)"],
[32, "GPIO32 (FLASH - not available)"],
[33, "GPIO33 (not exposed on WROOM modules)"],
[34, "GPIO34 (not exposed on WROOM modules)"],
[35, "GPIO35"],
[36, "GPIO36"],
[37, "GPIO37"],
[38, "GPIO38"],
[39, "GPIO39"],
[40, "GPIO40"],
[41, "GPIO41"],
[42, "GPIO42"],
[43, "GPIO43"],
[44, "GPIO44"],
[45, "GPIO45 (DONT USE - STRAPPING PIN)"],
[46, "GPIO46 (DONT USE - STRAPPING PIN)"],
[47, "GPIO47"],
[48, "GPIO48"],
];
const re = /11[2,4,6][1,2,4].*/;
@ -613,7 +661,7 @@
}
}
function parsePinout(obj, type) {
function parsePinout(obj, type, system) {
var e = document.getElementById("pinout");
pins = [['led0', 'pinLed0'], ['led1', 'pinLed1']];
for(p of pins) {
@ -621,7 +669,7 @@
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()),
ml("div", {class: "col-12 col-sm-9"},
sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]])
sel(p[1], ("ESP8266" == type) ? esp8266pins : ("ESP32-S3" == system["chip_model"]) ? esp32s3pins : esp32pins, obj[p[0]])
)
])
);
@ -630,13 +678,17 @@
function parseNrfRadio(obj, type) {
var e = document.getElementById("rf24");
if ("ESP8266" == type) {
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']];
} else {
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['sclk', 'pinSclk'], ['mosi', 'pinMosi'], ['miso', 'pinMiso']];
}
for(p of pins) {
e.append(
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()),
ml("div", {class: "col-12 col-sm-9"},
sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]])
sel(p[1], ("ESP8266" == type) ? esp8266pins : ("ESP32-S3" == system["chip_model"]) ? esp32s3pins : esp32pins, obj[p[0]])
)
])
);
@ -673,7 +725,7 @@
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()),
ml("div", {class: "col-12 col-sm-9"},
sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]])
sel(p[1], ("ESP8266" == type) ? esp8266pins : ("ESP32-S3" == system["chip_model"]) ? esp32s3pins : esp32pins, obj[p[0]])
)
])
);
@ -686,7 +738,7 @@
document.getElementsByName("serIntvl")[0].value = obj["interval"];
}
function parseDisplay(obj, type) {
function parseDisplay(obj, type, system) {
for(var i of ["disp_pwr", "disp_pxshift"])
document.getElementsByName(i)[0].checked = obj[i];
@ -699,7 +751,7 @@
ml("div", {class: "row mb-3", id: "row_" + p[1]}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()),
ml("div", {class: "col-12 col-sm-9"},
sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[1]])
sel(p[1], ("ESP8266" == type) ? esp8266pins : ("ESP32-S3" == system["chip_model"]) ? esp32s3pins : esp32pins, obj[p[1]])
)
])
);
@ -764,12 +816,12 @@
parseMqtt(root["mqtt"]);
parseNtp(root["ntp"]);
parseSun(root["sun"]);
parsePinout(root["pinout"], root["system"]["esp_type"]);
parsePinout(root["pinout"], root["system"]["esp_type"], root["system"]);
parseNrfRadio(root["radioNrf"], root["system"]["esp_type"]);
if(root["generic"]["esp_type"] == "ESP32")
parseCmtRadio(root["radioCmt"], root["system"]["esp_type"]);
parseSerial(root["serial"]);
parseDisplay(root["display"], root["system"]["esp_type"]);
parseDisplay(root["display"], root["system"]["esp_type"], root["system"]);
getAjax("/api/inverter/list", parseIv);
}
}

17
src/web/web.h

@ -33,7 +33,7 @@
#define WEB_SERIAL_BUF_SIZE 2048
const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq", "pinLed0", "pinLed1", "pinCsb", "pinFcsb", "pinGpio3"};
const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq", "pinSclk", "pinMosi", "pinMiso", "pinLed0", "pinLed1", "pinCsb", "pinFcsb", "pinGpio3"};
template <class HMSYSTEM>
class Web {
@ -521,17 +521,20 @@ class Web {
// pinout
uint8_t pin;
for(uint8_t i = 0; i < 8; i ++) {
for (uint8_t i = 0; i < 11; i++) {
pin = request->arg(String(pinArgNames[i])).toInt();
switch(i) {
case 0: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_CS_PIN); break;
case 1: mConfig->nrf.pinCe = ((pin != 0xff) ? pin : DEF_CE_PIN); break;
case 2: mConfig->nrf.pinIrq = ((pin != 0xff) ? pin : DEF_IRQ_PIN); break;
case 3: mConfig->led.led0 = pin; break;
case 4: mConfig->led.led1 = pin; break;
case 5: mConfig->cmt.pinCsb = pin; break;
case 6: mConfig->cmt.pinFcsb = pin; break;
case 7: mConfig->cmt.pinIrq = pin; break;
case 3: mConfig->nrf.pinSclk = ((pin != 0xff) ? pin : DEF_SCLK_PIN); break;
case 4: mConfig->nrf.pinMosi = ((pin != 0xff) ? pin : DEF_MOSI_PIN); break;
case 5: mConfig->nrf.pinMiso = ((pin != 0xff) ? pin : DEF_MISO_PIN); break;
case 6: mConfig->led.led0 = pin; break;
case 7: mConfig->led.led1 = pin; break;
case 8: mConfig->cmt.pinCsb = pin; break;
case 9: mConfig->cmt.pinFcsb = pin; break;
case 10: mConfig->cmt.pinIrq = pin; break;
}
}

Loading…
Cancel
Save