|
@ -15,7 +15,6 @@ |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#include "../utils/dbg.h" |
|
|
#include "../utils/dbg.h" |
|
|
#include "../utils/ahoyTimer.h" |
|
|
|
|
|
#include "../config/config.h" |
|
|
#include "../config/config.h" |
|
|
#include <espMqttClient.h> |
|
|
#include <espMqttClient.h> |
|
|
#include <ArduinoJson.h> |
|
|
#include <ArduinoJson.h> |
|
@ -40,8 +39,7 @@ class PubMqtt { |
|
|
mRxCnt = 0; |
|
|
mRxCnt = 0; |
|
|
mTxCnt = 0; |
|
|
mTxCnt = 0; |
|
|
mSubscriptionCb = NULL; |
|
|
mSubscriptionCb = NULL; |
|
|
mIvAvail = true; |
|
|
memset(mLastIvState, MQTT_STATUS_NOT_AVAIL_NOT_PROD, MAX_NUM_INVERTERS); |
|
|
memset(mLastIvState, 0xff, MAX_NUM_INVERTERS); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
~PubMqtt() { } |
|
|
~PubMqtt() { } |
|
@ -70,6 +68,7 @@ class PubMqtt { |
|
|
void loop() { |
|
|
void loop() { |
|
|
#if defined(ESP8266) |
|
|
#if defined(ESP8266) |
|
|
mClient.loop(); |
|
|
mClient.loop(); |
|
|
|
|
|
yield(); |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -408,13 +407,12 @@ class PubMqtt { |
|
|
|
|
|
|
|
|
bool processIvStatus() { |
|
|
bool processIvStatus() { |
|
|
// returns true if all inverters are available
|
|
|
// returns true if all inverters are available
|
|
|
bool allAvail = true; |
|
|
bool allAvail = true; // shows if all enabled inverters are available
|
|
|
bool first = true; |
|
|
bool anyAvail = false; // shows if at least one enabled inverter is available
|
|
|
bool changed = false; |
|
|
bool changed = false; |
|
|
char topic[7 + MQTT_TOPIC_LEN], val[40]; |
|
|
char topic[7 + MQTT_TOPIC_LEN], val[40]; |
|
|
Inverter<> *iv; |
|
|
Inverter<> *iv; |
|
|
record_t<> *rec; |
|
|
record_t<> *rec; |
|
|
bool totalComplete = true; |
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { |
|
|
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { |
|
|
iv = mSys->getInverterByPos(id); |
|
|
iv = mSys->getInverterByPos(id); |
|
@ -422,32 +420,21 @@ class PubMqtt { |
|
|
continue; // skip to next inverter
|
|
|
continue; // skip to next inverter
|
|
|
|
|
|
|
|
|
rec = iv->getRecordStruct(RealTimeRunData_Debug); |
|
|
rec = iv->getRecordStruct(RealTimeRunData_Debug); |
|
|
if(first) |
|
|
|
|
|
mIvAvail = false; |
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
|
|
// inverter status
|
|
|
// inverter status
|
|
|
uint8_t status = MQTT_STATUS_AVAIL_PROD; |
|
|
uint8_t status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; |
|
|
if ((!iv->isAvailable(*mUtcTimestamp)) || (!iv->config->enabled)) { |
|
|
if (iv->config->enabled) { |
|
|
status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; |
|
|
if (iv->isAvailable(*mUtcTimestamp)) |
|
|
if(iv->config->enabled) { // only change all-avail if inverter is enabled!
|
|
|
status = (iv->isProducing(*mUtcTimestamp)) ? MQTT_STATUS_AVAIL_PROD : MQTT_STATUS_AVAIL_NOT_PROD; |
|
|
totalComplete = false; |
|
|
else // inverter is enabled but not available
|
|
|
allAvail = false; |
|
|
allAvail = false; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
mIvAvail = true; |
|
|
|
|
|
if (!iv->isProducing(*mUtcTimestamp)) { |
|
|
|
|
|
if (MQTT_STATUS_AVAIL_PROD == status) |
|
|
|
|
|
status = MQTT_STATUS_AVAIL_NOT_PROD; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(mLastIvState[id] != status) { |
|
|
if(mLastIvState[id] != status) { |
|
|
mLastIvState[id] = status; |
|
|
mLastIvState[id] = status; |
|
|
changed = true; |
|
|
changed = true; |
|
|
|
|
|
|
|
|
if(mCfgMqtt->rstValsNotAvail) |
|
|
if((MQTT_STATUS_NOT_AVAIL_NOT_PROD == status) && (mCfgMqtt->rstValsNotAvail)) |
|
|
zeroValues(iv); |
|
|
zeroValues(iv); |
|
|
|
|
|
|
|
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name); |
|
|
snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name); |
|
@ -461,12 +448,12 @@ class PubMqtt { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if(changed) { |
|
|
if(changed) { |
|
|
snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((mIvAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); |
|
|
snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); |
|
|
publish("status", val, true); |
|
|
publish("status", val, true); |
|
|
sendIvData(false); // false prevents loop of same function
|
|
|
sendIvData(false); // false prevents loop of same function
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return totalComplete; |
|
|
return allAvail; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void sendAlarmData() { |
|
|
void sendAlarmData() { |
|
@ -494,7 +481,7 @@ class PubMqtt { |
|
|
memset(total, 0, sizeof(float) * 4); |
|
|
memset(total, 0, sizeof(float) * 4); |
|
|
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { |
|
|
for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { |
|
|
Inverter<> *iv = mSys->getInverterByPos(id); |
|
|
Inverter<> *iv = mSys->getInverterByPos(id); |
|
|
if (NULL == iv) |
|
|
if ((NULL == iv) || (MQTT_STATUS_NOT_AVAIL_NOT_PROD == mLastIvState[id])) |
|
|
continue; // skip to next inverter
|
|
|
continue; // skip to next inverter
|
|
|
|
|
|
|
|
|
record_t<> *rec = iv->getRecordStruct(mSendList.front()); |
|
|
record_t<> *rec = iv->getRecordStruct(mSendList.front()); |
|
@ -626,7 +613,6 @@ class PubMqtt { |
|
|
std::queue<uint8_t> mSendList; |
|
|
std::queue<uint8_t> mSendList; |
|
|
std::queue<alarm_t> mAlarmList; |
|
|
std::queue<alarm_t> mAlarmList; |
|
|
subscriptionCb mSubscriptionCb; |
|
|
subscriptionCb mSubscriptionCb; |
|
|
bool mIvAvail; // shows if at least one inverter is available
|
|
|
|
|
|
bool mReconnectRequest; |
|
|
bool mReconnectRequest; |
|
|
uint8_t mLastIvState[MAX_NUM_INVERTERS]; |
|
|
uint8_t mLastIvState[MAX_NUM_INVERTERS]; |
|
|
uint16_t mIntervalTimeout; |
|
|
uint16_t mIntervalTimeout; |
|
|