mirror of
https://github.com/lumapu/ahoy.git
synced 2025-08-06 01:48:19 +02:00
fix #521 no reconnect at beginning of day
added immediate (each minute) report of inverter status MQTT #522 added protection mask to select which pages should be protected
This commit is contained in:
parent
6bb8a4e448
commit
c3fc01b956
12 changed files with 222 additions and 96 deletions
|
@ -36,6 +36,7 @@ class PubMqtt {
|
|||
mSubscriptionCb = NULL;
|
||||
mIsDay = false;
|
||||
mIvAvail = true;
|
||||
memset(mLastIvState, 0xff, MAX_NUM_INVERTERS);
|
||||
}
|
||||
|
||||
~PubMqtt() { }
|
||||
|
@ -77,6 +78,7 @@ class PubMqtt {
|
|||
}
|
||||
|
||||
void tickerMinute() {
|
||||
processIvStatus();
|
||||
char val[12];
|
||||
snprintf(val, 12, "%ld", millis() / 1000);
|
||||
publish("uptime", val);
|
||||
|
@ -368,6 +370,72 @@ class PubMqtt {
|
|||
return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId];
|
||||
}
|
||||
|
||||
bool processIvStatus() {
|
||||
// returns true if all inverters are available
|
||||
bool allAvail = true;
|
||||
bool first = true;
|
||||
bool changed = false;
|
||||
char topic[7 + MQTT_TOPIC_LEN], val[40];
|
||||
Inverter<> *iv;
|
||||
record_t<> *rec;
|
||||
bool totalComplete = true;
|
||||
|
||||
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
|
||||
iv = mSys->getInverterByPos(id);
|
||||
if (NULL == iv)
|
||||
continue; // skip to next inverter
|
||||
|
||||
rec = iv->getRecordStruct(RealTimeRunData_Debug);
|
||||
if(first)
|
||||
mIvAvail = false;
|
||||
first = false;
|
||||
|
||||
// inverter status
|
||||
uint8_t status = MQTT_STATUS_AVAIL_PROD;
|
||||
if ((!iv->isAvailable(*mUtcTimestamp, rec)) || (!iv->config->enabled)) {
|
||||
status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
|
||||
if(iv->config->enabled) { // only change all-avail if inverter is enabled!
|
||||
totalComplete = false;
|
||||
allAvail = false;
|
||||
}
|
||||
}
|
||||
else if (!iv->isProducing(*mUtcTimestamp, rec)) {
|
||||
mIvAvail = true;
|
||||
if (MQTT_STATUS_AVAIL_PROD == status)
|
||||
status = MQTT_STATUS_AVAIL_NOT_PROD;
|
||||
}
|
||||
else
|
||||
mIvAvail = true;
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->config->name);
|
||||
snprintf(val, 40, "%s%s%s%s",
|
||||
(status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not " : "",
|
||||
"available and ",
|
||||
(status == MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
|
||||
"producing"
|
||||
);
|
||||
publish(topic, val, true);
|
||||
|
||||
if(mLastIvState[id] != status) {
|
||||
mLastIvState[id] = status;
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
|
||||
snprintf(val, 40, "%d", status);
|
||||
publish(topic, val, true);
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
|
||||
snprintf(val, 40, "%d", iv->getLastTs(rec));
|
||||
publish(topic, val, true);
|
||||
}
|
||||
}
|
||||
|
||||
if(changed) {
|
||||
snprintf(val, 32, "%s", ((allAvail) ? "online" : ((mIvAvail) ? "partial" : "offline")));
|
||||
publish("status", val, true);
|
||||
}
|
||||
|
||||
return totalComplete;
|
||||
}
|
||||
|
||||
void sendIvData(void) {
|
||||
if(mSendList.empty())
|
||||
return;
|
||||
|
@ -375,9 +443,6 @@ class PubMqtt {
|
|||
char topic[7 + MQTT_TOPIC_LEN], val[40];
|
||||
float total[4];
|
||||
bool sendTotal = false;
|
||||
bool totalIncomplete = false;
|
||||
bool allAvail = true;
|
||||
bool first = true;
|
||||
|
||||
while(!mSendList.empty()) {
|
||||
memset(total, 0, sizeof(float) * 4);
|
||||
|
@ -388,45 +453,6 @@ class PubMqtt {
|
|||
|
||||
record_t<> *rec = iv->getRecordStruct(mSendList.front());
|
||||
|
||||
if(mSendList.front() == RealTimeRunData_Debug) {
|
||||
if(first)
|
||||
mIvAvail = false;
|
||||
first = false;
|
||||
|
||||
// inverter status
|
||||
uint8_t status = MQTT_STATUS_AVAIL_PROD;
|
||||
if ((!iv->isAvailable(*mUtcTimestamp, rec)) || (!iv->config->enabled)) {
|
||||
status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
|
||||
if(iv->config->enabled) { // only change all-avail if inverter is enabled!
|
||||
totalIncomplete = true;
|
||||
allAvail = false;
|
||||
}
|
||||
}
|
||||
else if (!iv->isProducing(*mUtcTimestamp, rec)) {
|
||||
mIvAvail = true;
|
||||
if (MQTT_STATUS_AVAIL_PROD == status)
|
||||
status = MQTT_STATUS_AVAIL_NOT_PROD;
|
||||
}
|
||||
else
|
||||
mIvAvail = true;
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->config->name);
|
||||
snprintf(val, 40, "%s%s%s%s",
|
||||
(status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not " : "",
|
||||
"available and ",
|
||||
(status == MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
|
||||
"producing"
|
||||
);
|
||||
publish(topic, val, true);
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name);
|
||||
snprintf(val, 40, "%d", status);
|
||||
publish(topic, val, true);
|
||||
|
||||
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name);
|
||||
snprintf(val, 40, "%d", iv->getLastTs(rec));
|
||||
publish(topic, val, true);
|
||||
}
|
||||
|
||||
// data
|
||||
if(iv->isAvailable(*mUtcTimestamp, rec)) {
|
||||
for (uint8_t i = 0; i < rec->length; i++) {
|
||||
|
@ -471,10 +497,7 @@ class PubMqtt {
|
|||
|
||||
mSendList.pop(); // remove from list once all inverters were processed
|
||||
|
||||
snprintf(val, 32, "%s", ((allAvail) ? "online" : ((mIvAvail) ? "partial" : "offline")));
|
||||
publish("status", val, true);
|
||||
|
||||
if ((true == sendTotal) && (false == totalIncomplete)) {
|
||||
if ((true == sendTotal) && processIvStatus()) {
|
||||
uint8_t fieldId;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
switch (i) {
|
||||
|
@ -514,6 +537,7 @@ class PubMqtt {
|
|||
subscriptionCb mSubscriptionCb;
|
||||
bool mIsDay;
|
||||
bool mIvAvail; // shows if at least one inverter is available
|
||||
uint8_t mLastIvState[MAX_NUM_INVERTERS];
|
||||
|
||||
// last will topic and payload must be available trough lifetime of 'espMqttClient'
|
||||
char mLwtTopic[MQTT_TOPIC_LEN+5];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue