Browse Source

prevent send devcontrol request during disabled night communication

changed yield total correction as module (inverter input) value #570
MQTT Yield Day zero, next try to fix #671
pull/698/head
lumapu 2 years ago
parent
commit
ca25f16548
  1. 5
      src/CHANGES.md
  2. 5
      src/app.cpp
  3. 3
      src/app.h
  4. 12
      src/config/settings.h
  5. 2
      src/defines.h
  6. 5
      src/hm/hmInverter.h
  7. 2
      src/hm/hmRadio.h
  8. 7
      src/publisher/pubMqtt.h
  9. 4
      src/web/RestApi.h
  10. 18
      src/web/html/setup.html
  11. 2
      src/web/html/style.css
  12. 2
      src/web/web.h
  13. 2
      src/wifi/ahoywifi.cpp

5
src/CHANGES.md

@ -2,6 +2,11 @@
(starting from release version `0.5.66`) (starting from release version `0.5.66`)
## 0.5.86
* prevent send devcontrol request during disabled night communication
* changed yield total correction as module (inverter input) value #570
* MQTT Yield Day zero, next try to fix #671
## 0.5.85 ## 0.5.85
* fix power-limit was not checked for max retransmits #667 * fix power-limit was not checked for max retransmits #667
* fix blue LED lights up all the time #672 * fix blue LED lights up all the time #672

5
src/app.cpp

@ -181,10 +181,11 @@ void app::tickNtpUpdate(void) {
} }
// immediately start communicating // immediately start communicating
if(isOK && mSendFirst) { // @TODO: leads to reboot loops, everytime if there is no asynchronous function #674
/*if(isOK && mSendFirst) {
mSendFirst = false; mSendFirst = false;
once(std::bind(&app::tickSend, this), 2, "senOn"); once(std::bind(&app::tickSend, this), 2, "senOn");
} }*/
mMqttReconnect = false; mMqttReconnect = false;
} }

3
src/app.h

@ -136,7 +136,8 @@ class app : public IApp, public ah::Scheduler {
} }
void ivSendHighPrio(Inverter<> *iv) { void ivSendHighPrio(Inverter<> *iv) {
mPayload.ivSendHighPrio(iv); if(mIVCommunicationOn) // only send commands if communcation is enabled
mPayload.ivSendHighPrio(iv);
} }
bool getMqttIsConnected() { bool getMqttIsConnected() {

12
src/config/settings.h

@ -105,8 +105,8 @@ typedef struct {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
serial_u serial; serial_u serial;
uint16_t chMaxPwr[4]; uint16_t chMaxPwr[4];
int32_t yieldCor[4]; // signed YieldTotal correction value
char chName[4][MAX_NAME_LENGTH]; char chName[4][MAX_NAME_LENGTH];
uint32_t yieldCor; // YieldTotal correction value
} cfgIv_t; } cfgIv_t;
typedef struct { typedef struct {
@ -220,7 +220,7 @@ class settings {
else { else {
//DPRINTLN(DBG_INFO, fp.readString()); //DPRINTLN(DBG_INFO, fp.readString());
//fp.seek(0, SeekSet); //fp.seek(0, SeekSet);
DynamicJsonDocument root(4096); DynamicJsonDocument root(4500);
DeserializationError err = deserializeJson(root, fp); DeserializationError err = deserializeJson(root, fp);
if(!err && (root.size() > 0)) { if(!err && (root.size() > 0)) {
mCfg.valid = true; mCfg.valid = true;
@ -252,7 +252,7 @@ class settings {
return false; return false;
} }
DynamicJsonDocument json(4096); DynamicJsonDocument json(4500);
JsonObject root = json.to<JsonObject>(); JsonObject root = json.to<JsonObject>();
jsonWifi(root.createNestedObject(F("wifi")), true); jsonWifi(root.createNestedObject(F("wifi")), true);
jsonNrf(root.createNestedObject(F("nrf")), true); jsonNrf(root.createNestedObject(F("nrf")), true);
@ -520,17 +520,17 @@ class settings {
obj[F("en")] = (bool)cfg->enabled; obj[F("en")] = (bool)cfg->enabled;
obj[F("name")] = cfg->name; obj[F("name")] = cfg->name;
obj[F("sn")] = cfg->serial.u64; obj[F("sn")] = cfg->serial.u64;
obj[F("yield")] = cfg->yieldCor;
for(uint8_t i = 0; i < 4; i++) { for(uint8_t i = 0; i < 4; i++) {
obj[F("pwr")][i] = cfg->chMaxPwr[i]; obj[F("yield")][i] = cfg->yieldCor[i];
obj[F("pwr")][i] = cfg->chMaxPwr[i];
obj[F("chName")][i] = cfg->chName[i]; obj[F("chName")][i] = cfg->chName[i];
} }
} else { } else {
cfg->enabled = (bool)obj[F("en")]; cfg->enabled = (bool)obj[F("en")];
snprintf(cfg->name, MAX_NAME_LENGTH, "%s", obj[F("name")].as<const char*>()); snprintf(cfg->name, MAX_NAME_LENGTH, "%s", obj[F("name")].as<const char*>());
cfg->serial.u64 = obj[F("sn")]; cfg->serial.u64 = obj[F("sn")];
cfg->yieldCor = obj[F("yield")];
for(uint8_t i = 0; i < 4; i++) { for(uint8_t i = 0; i < 4; i++) {
cfg->yieldCor[i] = obj[F("yield")][i];
cfg->chMaxPwr[i] = obj[F("pwr")][i]; cfg->chMaxPwr[i] = obj[F("pwr")][i];
snprintf(cfg->chName[i], MAX_NAME_LENGTH, "%s", obj[F("chName")][i].as<const char*>()); snprintf(cfg->chName[i], MAX_NAME_LENGTH, "%s", obj[F("chName")][i].as<const char*>());
} }

2
src/defines.h

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

5
src/hm/hmInverter.h

@ -255,9 +255,8 @@ class Inverter {
if (FLD_T == rec->assign[pos].fieldId) { if (FLD_T == rec->assign[pos].fieldId) {
// temperature is a signed value! // temperature is a signed value!
rec->record[pos] = (REC_TYP)((int16_t)val) / (REC_TYP)(div); rec->record[pos] = (REC_TYP)((int16_t)val) / (REC_TYP)(div);
} else if ((FLD_YT == rec->assign[pos].fieldId) } else if (FLD_YT == rec->assign[pos].fieldId) {
&& (config->yieldCor != 0)) { rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div)) + ((REC_TYP)config->yieldCor[rec->assign[pos].ch]);
rec->record[pos] = ((REC_TYP)(val) / (REC_TYP)(div)) - ((REC_TYP)config->yieldCor);
} else { } else {
if ((REC_TYP)(div) > 1) if ((REC_TYP)(div) > 1)
rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div); rec->record[pos] = (REC_TYP)(val) / (REC_TYP)(div);

2
src/hm/hmRadio.h

@ -238,7 +238,7 @@ class HmRadio {
bool getReceived(void) { bool getReceived(void) {
bool tx_ok, tx_fail, rx_ready; bool tx_ok, tx_fail, rx_ready;
mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH mNrf24.whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
DBGPRINTLN("RX whatHappened Ch" + String(mRfChLst[mRxChIdx]) + " " + String(tx_ok) + String(tx_fail) + String(rx_ready)); //DBGPRINTLN("RX whatHappened Ch" + String(mRfChLst[mRxChIdx]) + " " + String(tx_ok) + String(tx_fail) + String(rx_ready));
bool isLastPackage = false; bool isLastPackage = false;
while(mNrf24.available()) { while(mNrf24.available()) {

7
src/publisher/pubMqtt.h

@ -474,7 +474,7 @@ class PubMqtt {
} }
} }
void sendIvData(bool sendTotals = true) { void sendIvData() {
if(mSendList.empty()) if(mSendList.empty())
return; return;
@ -527,8 +527,8 @@ class PubMqtt {
total[3] += iv->getValue(i, rec); total[3] += iv->getValue(i, rec);
break; break;
} }
sendTotal = true;
} }
sendTotal = true;
} }
yield(); yield();
} }
@ -537,9 +537,6 @@ class PubMqtt {
mSendList.pop(); // remove from list once all inverters were processed mSendList.pop(); // remove from list once all inverters were processed
if(!sendTotals) // skip total value calculation
continue;
if ((true == sendTotal) && processIvStatus()) { if ((true == sendTotal) && processIvStatus()) {
uint8_t fieldId; uint8_t fieldId;
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {

4
src/web/RestApi.h

@ -287,11 +287,11 @@ class RestApi {
obj2[F("serial")] = String(iv->config->serial.u64, HEX); obj2[F("serial")] = String(iv->config->serial.u64, HEX);
obj2[F("channels")] = iv->channels; obj2[F("channels")] = iv->channels;
obj2[F("version")] = String(iv->getFwVersion()); obj2[F("version")] = String(iv->getFwVersion());
obj2[F("yieldCor")] = iv->config->yieldCor;
for(uint8_t j = 0; j < iv->channels; j ++) { for(uint8_t j = 0; j < iv->channels; j ++) {
obj2[F("ch_yield_cor")][j] = iv->config->yieldCor[j];
obj2[F("ch_max_power")][j] = iv->config->chMaxPwr[j]; obj2[F("ch_max_power")][j] = iv->config->chMaxPwr[j];
obj2[F("ch_name")][j] = iv->config->chName[j]; obj2[F("ch_name")][j] = iv->config->chName[j];
} }
} }
} }

18
src/web/html/setup.html

@ -298,7 +298,7 @@
document.getElementById("btnAdd").addEventListener("click", function() { document.getElementById("btnAdd").addEventListener("click", function() {
if(highestId <= (maxInv-1)) { if(highestId <= (maxInv-1)) {
ivHtml(JSON.parse('{"enabled":true,"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId); ivHtml(JSON.parse('{"enabled":true,"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""],"ch_yield_cor":[0,0,0,0]}'), highestId);
} }
}); });
@ -393,9 +393,11 @@
for(var i=0;i<4;i++) { for(var i=0;i<4;i++) {
setHide(id+"ModPwr"+i, true); setHide(id+"ModPwr"+i, true);
setHide(id+"ModName"+i, true); setHide(id+"ModName"+i, true);
setHide(id+"YieldCor"+i, true);
} }
setHide("lbl"+id+"ModPwr", true); setHide("lbl"+id+"ModPwr", true);
setHide("lbl"+id+"ModName", true); setHide("lbl"+id+"ModName", true);
setHide("lbl"+id+"YieldCor", true);
if(serial.charAt(0) == 1) { if(serial.charAt(0) == 1) {
if((serial.charAt(1) == 0) || (serial.charAt(1) == 1)) { if((serial.charAt(1) == 0) || (serial.charAt(1) == 1)) {
@ -413,9 +415,11 @@
for(var i=0;i<max;i++) { for(var i=0;i<max;i++) {
setHide(id+"ModPwr"+i, false); setHide(id+"ModPwr"+i, false);
setHide(id+"ModName"+i, false); setHide(id+"ModName"+i, false);
setHide(id+"YieldCor"+i, false);
} }
setHide("lbl"+id+"ModPwr", false); setHide("lbl"+id+"ModPwr", false);
setHide("lbl"+id+"ModName", false); setHide("lbl"+id+"ModName", false);
setHide("lbl"+id+"YieldCor", false);
} }
}) })
}); });
@ -425,7 +429,10 @@
inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9./#$%&=+_-]+", "Invalid input") inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9./#$%&=+_-]+", "Invalid input")
); );
for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"], ["ModName", "ch_name", "Module Name", 16, null]]) { for(var j of [
["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"],
["ModName", "ch_name", "Module Name", 16, null],
["YieldCor", "ch_yield_cor", "Yield Total Correction [kWh]", 16, "[0-9]+"]]) {
var cl = (re.test(obj["serial"])) ? null : ["hide"]; var cl = (re.test(obj["serial"])) ? null : ["hide"];
iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0])); iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0]));
d = div([j[0]]); d = div([j[0]]);
@ -437,13 +444,6 @@
} }
iv.appendChild(d); iv.appendChild(d);
} }
iv.append(
br(),
lbl(id + "YieldCor", "Yield Total Correction (will be subtracted) [kWh]"),
inp(id + "YieldCor", obj["yieldCor"], 32, ["text"], null, "text", "[0-9]+", "Invalid input")
);
var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button"); var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button");
del.addEventListener("click", delIv); del.addEventListener("click", delIv);
iv.append( iv.append(

2
src/web/html/style.css

@ -393,7 +393,7 @@ div.ts {
padding: 7px; padding: 7px;
} }
div.ModPwr, div.ModName { div.ModPwr, div.ModName, div.YieldCor {
width:70%; width:70%;
display: inline-block; display: inline-block;
} }

2
src/web/web.h

@ -483,13 +483,13 @@ class Web {
case 0x61: iv->type = INV_TYPE_4CH; iv->channels = 4; break; case 0x61: iv->type = INV_TYPE_4CH; iv->channels = 4; break;
default: break; default: break;
} }
iv->config->yieldCor = request->arg("inv" + String(i) + "YieldCor").toInt();
// name // name
request->arg("inv" + String(i) + "Name").toCharArray(iv->config->name, MAX_NAME_LENGTH); request->arg("inv" + String(i) + "Name").toCharArray(iv->config->name, MAX_NAME_LENGTH);
// max channel power / name // max channel power / name
for(uint8_t j = 0; j < 4; j++) { for(uint8_t j = 0; j < 4; j++) {
iv->config->yieldCor[j] = request->arg("inv" + String(i) + "YieldCor" + String(j)).toInt();
iv->config->chMaxPwr[j] = request->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff; iv->config->chMaxPwr[j] = request->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff;
request->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->config->chName[j], MAX_NAME_LENGTH); request->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->config->chName[j], MAX_NAME_LENGTH);
} }

2
src/wifi/ahoywifi.cpp

@ -311,6 +311,8 @@ void ahoywifi::getBSSIDs() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ahoywifi::connectionEvent(WiFiStatus_t status) { void ahoywifi::connectionEvent(WiFiStatus_t status) {
DPRINTLN(DBG_INFO, "connectionEvent");
switch(status) { switch(status) {
case CONNECTED: case CONNECTED:
if(mStaConn != CONNECTED) { if(mStaConn != CONNECTED) {

Loading…
Cancel
Save