mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-18 00:37:13 +02:00
Mono-Display: show values in offline mode #498
improved wifi class #483 added communication enable / disable (to test mutliple DTUs with the same inverter) fix factory reset #495
This commit is contained in:
parent
faf918c018
commit
c8c8b99957
12 changed files with 126 additions and 95 deletions
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.5.53
|
||||||
|
* Mono-Display: show values in offline mode #498
|
||||||
|
* improved wifi class #483
|
||||||
|
* added communication enable / disable (to test mutliple DTUs with the same inverter)
|
||||||
|
* fix factory reset #495
|
||||||
|
|
||||||
## 0.5.52
|
## 0.5.52
|
||||||
* improved ahoyWifi class
|
* improved ahoyWifi class
|
||||||
* added interface class for app
|
* added interface class for app
|
||||||
|
|
|
@ -190,6 +190,7 @@ void app::tickSend(void) {
|
||||||
} while ((NULL == iv) && ((maxLoop--) > 0));
|
} while ((NULL == iv) && ((maxLoop--) > 0));
|
||||||
|
|
||||||
if (NULL != iv) {
|
if (NULL != iv) {
|
||||||
|
if(iv->config->enabled) {
|
||||||
if (!mPayload.isComplete(iv))
|
if (!mPayload.isComplete(iv))
|
||||||
mPayload.process(false, mConfig->nrf.maxRetransPerPyld, &mStat);
|
mPayload.process(false, mConfig->nrf.maxRetransPerPyld, &mStat);
|
||||||
|
|
||||||
|
@ -232,6 +233,7 @@ void app::tickSend(void) {
|
||||||
mRxTicker = 0;
|
mRxTicker = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mConfig->serial.debug)
|
if (mConfig->serial.debug)
|
||||||
DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!"));
|
DPRINTLN(DBG_WARN, F("Time not set or it is night time, therefore no communication to the inverter!"));
|
||||||
|
|
|
@ -267,6 +267,8 @@ class settings {
|
||||||
|
|
||||||
mCfg.led.led0 = DEF_LED0_PIN;
|
mCfg.led.led0 = DEF_LED0_PIN;
|
||||||
mCfg.led.led1 = DEF_LED1_PIN;
|
mCfg.led.led1 = DEF_LED1_PIN;
|
||||||
|
|
||||||
|
memset(&mCfg.inst, 0, sizeof(cfgInst_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void jsonWifi(JsonObject obj, bool set = false) {
|
void jsonWifi(JsonObject obj, bool set = false) {
|
||||||
|
@ -374,9 +376,9 @@ class settings {
|
||||||
|
|
||||||
void jsonInst(JsonObject obj, bool set = false) {
|
void jsonInst(JsonObject obj, bool set = false) {
|
||||||
if(set)
|
if(set)
|
||||||
obj[F("en")] = mCfg.inst.enabled;
|
obj[F("en")] = (bool)mCfg.inst.enabled;
|
||||||
else
|
else
|
||||||
mCfg.inst.enabled = obj[F("en")];
|
mCfg.inst.enabled = (bool)obj[F("en")];
|
||||||
|
|
||||||
JsonArray ivArr;
|
JsonArray ivArr;
|
||||||
if(set)
|
if(set)
|
||||||
|
@ -391,7 +393,7 @@ class settings {
|
||||||
|
|
||||||
void jsonIv(JsonObject obj, cfgIv_t *cfg, bool set = false) {
|
void jsonIv(JsonObject obj, cfgIv_t *cfg, bool set = false) {
|
||||||
if(set) {
|
if(set) {
|
||||||
obj[F("en")] = 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;
|
||||||
for(uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
|
@ -399,7 +401,7 @@ class settings {
|
||||||
obj[F("chName")][i] = cfg->chName[i];
|
obj[F("chName")][i] = cfg->chName[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cfg->enabled = 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")];
|
||||||
for(uint8_t i = 0; i < 4; i++) {
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 5
|
#define VERSION_MINOR 5
|
||||||
#define VERSION_PATCH 52
|
#define VERSION_PATCH 53
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -114,7 +114,7 @@ class PubMqtt {
|
||||||
continue; // skip to next inverter
|
continue; // skip to next inverter
|
||||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
|
|
||||||
if (!iv->isAvailable(*mUtcTimestamp, rec)) {
|
if ((!iv->isAvailable(*mUtcTimestamp, rec)) || (!iv->config->enabled)) {
|
||||||
snprintf(topic, MQTT_TOPIC_LEN + 15, "%s/available_text", iv->config->name);
|
snprintf(topic, MQTT_TOPIC_LEN + 15, "%s/available_text", iv->config->name);
|
||||||
snprintf(val, 32, "not available and not producing");
|
snprintf(val, 32, "not available and not producing");
|
||||||
publish(topic, val, true);
|
publish(topic, val, true);
|
||||||
|
@ -263,7 +263,7 @@ class PubMqtt {
|
||||||
|
|
||||||
subscribe("ctrl/#");
|
subscribe("ctrl/#");
|
||||||
subscribe("setup/#");
|
subscribe("setup/#");
|
||||||
subscribe("status/#");
|
//subscribe("status/#");
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDisconnect(espMqttClientTypes::DisconnectReason reason) {
|
void onDisconnect(espMqttClientTypes::DisconnectReason reason) {
|
||||||
|
@ -293,7 +293,7 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
void onMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||||
DPRINTLN(DBG_VERBOSE, F("MQTT got topic: ") + String(topic));
|
DPRINTLN(DBG_INFO, F("MQTT got topic: ") + String(topic));
|
||||||
if(NULL == mSubscriptionCb)
|
if(NULL == mSubscriptionCb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -394,11 +394,13 @@ class PubMqtt {
|
||||||
|
|
||||||
// inverter status
|
// inverter status
|
||||||
uint8_t status = MQTT_STATUS_AVAIL_PROD;
|
uint8_t status = MQTT_STATUS_AVAIL_PROD;
|
||||||
if (!iv->isAvailable(*mUtcTimestamp, rec)) {
|
if ((!iv->isAvailable(*mUtcTimestamp, rec)) || (!iv->config->enabled)) {
|
||||||
status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
|
status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
|
||||||
|
if(iv->config->enabled) { // only change all-avail if inverter is enabled!
|
||||||
totalIncomplete = true;
|
totalIncomplete = true;
|
||||||
allAvail = false;
|
allAvail = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!iv->isProducing(*mUtcTimestamp, rec)) {
|
else if (!iv->isProducing(*mUtcTimestamp, rec)) {
|
||||||
mIvAvail = true;
|
mIvAvail = true;
|
||||||
if (MQTT_STATUS_AVAIL_PROD == status)
|
if (MQTT_STATUS_AVAIL_PROD == status)
|
||||||
|
|
|
@ -246,6 +246,7 @@ class RestApi {
|
||||||
iv = mSys->getInverterByPos(i);
|
iv = mSys->getInverterByPos(i);
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
JsonObject obj2 = invArr.createNestedObject();
|
JsonObject obj2 = invArr.createNestedObject();
|
||||||
|
obj2[F("enabled")] = (bool)iv->config->enabled;
|
||||||
obj2[F("id")] = i;
|
obj2[F("id")] = i;
|
||||||
obj2[F("name")] = String(iv->config->name);
|
obj2[F("name")] = String(iv->config->name);
|
||||||
obj2[F("serial")] = String(iv->config->serial.u64, HEX);
|
obj2[F("serial")] = String(iv->config->serial.u64, HEX);
|
||||||
|
@ -353,6 +354,7 @@ class RestApi {
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
JsonObject invObj = inv.createNestedObject();
|
JsonObject invObj = inv.createNestedObject();
|
||||||
|
invObj[F("enabled")] = (bool)iv->config->enabled;
|
||||||
invObj[F("id")] = i;
|
invObj[F("id")] = i;
|
||||||
invObj[F("name")] = String(iv->config->name);
|
invObj[F("name")] = String(iv->config->name);
|
||||||
invObj[F("version")] = String(iv->fwVersion);
|
invObj[F("version")] = String(iv->fwVersion);
|
||||||
|
@ -412,6 +414,7 @@ class RestApi {
|
||||||
if(NULL != iv) {
|
if(NULL != iv) {
|
||||||
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||||
JsonObject obj2 = invArr.createNestedObject();
|
JsonObject obj2 = invArr.createNestedObject();
|
||||||
|
obj2[F("enabled")] = (bool)iv->config->enabled;
|
||||||
obj2[F("name")] = String(iv->config->name);
|
obj2[F("name")] = String(iv->config->name);
|
||||||
obj2[F("channels")] = iv->channels;
|
obj2[F("channels")] = iv->channels;
|
||||||
obj2[F("power_limit_read")] = ah::round3(iv->actPowerLimit);
|
obj2[F("power_limit_read")] = ah::round3(iv->actPowerLimit);
|
||||||
|
|
|
@ -92,7 +92,7 @@ function inp(name, val, max=32, cl=["text"], id=null, type=null) {
|
||||||
e = document.createElement('input');
|
e = document.createElement('input');
|
||||||
e.classList.add(...cl);
|
e.classList.add(...cl);
|
||||||
e.name = name;
|
e.name = name;
|
||||||
e.value = val;
|
if(null != val) e.value = val;
|
||||||
if(null != max) e.maxLength = max;
|
if(null != max) e.maxLength = max;
|
||||||
if(null != id) e.id = id;
|
if(null != id) e.id = id;
|
||||||
if(null != type) e.type = type;
|
if(null != type) e.type = type;
|
||||||
|
|
|
@ -174,6 +174,8 @@
|
||||||
html += "-> last successful transmission: " + date.toLocaleString('de-DE') + "\n";
|
html += "-> last successful transmission: " + date.toLocaleString('de-DE') + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(false == i["enabled"])
|
||||||
|
html += "-> disabled\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
document.getElementById("iv").innerHTML = html;
|
document.getElementById("iv").innerHTML = html;
|
||||||
|
|
|
@ -194,7 +194,7 @@
|
||||||
|
|
||||||
document.getElementById("btnAdd").addEventListener("click", function() {
|
document.getElementById("btnAdd").addEventListener("click", function() {
|
||||||
if(highestId <= (maxInv-1))
|
if(highestId <= (maxInv-1))
|
||||||
ivHtml(JSON.parse('{"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
|
ivHtml(JSON.parse('{"enabled":true,"name":"","serial":"","channels":4,"ch_max_power":[0,0,0,0],"ch_name":["","","",""]}'), highestId + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
function apiCbWifi(obj) {
|
function apiCbWifi(obj) {
|
||||||
|
@ -266,12 +266,16 @@
|
||||||
iv.appendChild(des("Inverter " + id));
|
iv.appendChild(des("Inverter " + id));
|
||||||
id = "inv" + id;
|
id = "inv" + id;
|
||||||
|
|
||||||
|
iv.appendChild(lbl(id + "Enable", "Communication Enable"));
|
||||||
|
var en = inp(id + "Enable", null, null, ["cb"], id + "Enable", "checkbox");
|
||||||
|
en.checked = obj["enabled"];
|
||||||
|
iv.appendChild(en);
|
||||||
|
iv.appendChild(br());
|
||||||
|
|
||||||
iv.appendChild(lbl(id + "Addr", "Serial Number (12 digits)*"));
|
iv.appendChild(lbl(id + "Addr", "Serial Number (12 digits)*"));
|
||||||
var addr = inp(id + "Addr", obj["serial"], 12)
|
var addr = inp(id + "Addr", obj["serial"], 12);
|
||||||
iv.appendChild(addr);
|
iv.appendChild(addr);
|
||||||
['keyup', 'change'].forEach(function(evt) {
|
['keyup', 'change'].forEach(function(evt) {
|
||||||
|
|
||||||
addr.addEventListener(evt, (e) => {
|
addr.addEventListener(evt, (e) => {
|
||||||
var serial = addr.value.substring(0,4);
|
var serial = addr.value.substring(0,4);
|
||||||
var max = 0;
|
var max = 0;
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
ivHtml.push(tDiv);
|
ivHtml.push(tDiv);
|
||||||
|
|
||||||
for(var iv of obj) {
|
for(var iv of obj) {
|
||||||
|
if(iv["enabled"]) {
|
||||||
main = div(["iv"]);
|
main = div(["iv"]);
|
||||||
var ch0 = div(["ch-iv"]);
|
var ch0 = div(["ch-iv"]);
|
||||||
var limit = iv["power_limit_read"] + "%";
|
var limit = iv["power_limit_read"] + "%";
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
main.appendChild(ts);
|
main.appendChild(ts);
|
||||||
ivHtml.push(main);
|
ivHtml.push(main);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// total
|
// total
|
||||||
if(obj.length > 1) {
|
if(obj.length > 1) {
|
||||||
|
|
|
@ -406,6 +406,8 @@ class Web {
|
||||||
Inverter<> *iv;
|
Inverter<> *iv;
|
||||||
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
|
||||||
iv = mSys->getInverterByPos(i, false);
|
iv = mSys->getInverterByPos(i, false);
|
||||||
|
// enable communication
|
||||||
|
iv->config->enabled = (request->arg("inv" + String(i) + "Enable") == "on");
|
||||||
// address
|
// address
|
||||||
request->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
|
request->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
|
||||||
if(strlen(buf) == 0)
|
if(strlen(buf) == 0)
|
||||||
|
|
|
@ -31,8 +31,14 @@ void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp) {
|
||||||
setupAp();
|
setupAp();
|
||||||
#endif
|
#endif
|
||||||
#if !defined(AP_ONLY)
|
#if !defined(AP_ONLY)
|
||||||
if(mConfig->valid)
|
if(mConfig->valid) {
|
||||||
|
#if !defined(FB_WIFI_OVERRIDDEN)
|
||||||
|
if(strncmp(mConfig->sys.stationSsid, FB_WIFI_SSID, 14) != 0)
|
||||||
setupStation();
|
setupStation();
|
||||||
|
#else
|
||||||
|
setupStation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue