mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-03 04:05:55 +02:00
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
This commit is contained in:
parent
a843ab6881
commit
ca25f16548
13 changed files with 37 additions and 32 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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*>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Add table
Reference in a new issue