|  | @ -34,6 +34,8 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |             mTxCnt = 0; |  |  |             mTxCnt = 0; | 
			
		
	
		
		
			
				
					|  |  |             mEnReconnect = false; |  |  |             mEnReconnect = false; | 
			
		
	
		
		
			
				
					|  |  |             mSubscriptionCb = NULL; |  |  |             mSubscriptionCb = NULL; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mIsDay = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mIvAvail = true; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         ~PubMqtt() { } |  |  |         ~PubMqtt() { } | 
			
		
	
	
		
		
			
				
					|  | @ -87,6 +89,8 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |                 if(mEnReconnect) |  |  |                 if(mEnReconnect) | 
			
		
	
		
		
			
				
					|  |  |                     mClient.connect(); |  |  |                     mClient.connect(); | 
			
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             else if(mIvAvail && !mIsDay) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 tickSunset(); | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void tickerSun() { |  |  |         void tickerSun() { | 
			
		
	
	
		
		
			
				
					|  | @ -94,22 +98,37 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |             publish("sunset", String(*mSunset).c_str(), true); |  |  |             publish("sunset", String(*mSunset).c_str(), true); | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         void tickSunrise() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mIsDay = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void tickSunset() { |  |  |         void tickSunset() { | 
			
		
	
		
		
			
				
					
					|  |  |             printf("tickSunset\n"); |  |  |             mIsDay = false; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             char topic[MAX_NAME_LENGTH + 15], val[32]; |  |  |             char topic[MQTT_TOPIC_LEN + 15], val[32]; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             Inverter<> *iv; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             record_t<> *rec; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mIvAvail = false; | 
			
		
	
		
		
			
				
					|  |  |             for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { |  |  |             for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { | 
			
		
	
		
		
			
				
					
					|  |  |                 Inverter<> *iv = mSys->getInverterByPos(id); |  |  |                 iv = mSys->getInverterByPos(id); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 if (NULL == iv) |  |  |                 if (NULL == iv) | 
			
		
	
		
		
			
				
					|  |  |                     continue; // skip to next inverter
 |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 rec = iv->getRecordStruct(RealTimeRunData_Debug); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 snprintf(topic, MAX_NAME_LENGTH + 15, "%s/available_text", iv->config->name); |  |  |                 if (!iv->isAvailable(*mUtcTimestamp, rec)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                     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); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 snprintf(topic, MAX_NAME_LENGTH + 15, "%s/available", iv->config->name); |  |  |                     snprintf(topic, MQTT_TOPIC_LEN + 15, "%s/available", iv->config->name); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     snprintf(val, 32, "%d", MQTT_STATUS_NOT_AVAIL_NOT_PROD); |  |  |                     snprintf(val, 32, "%d", MQTT_STATUS_NOT_AVAIL_NOT_PROD); | 
			
		
	
		
		
			
				
					|  |  |                     publish(topic, val, true); |  |  |                     publish(topic, val, true); | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 else | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mIvAvail = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if(!mIvAvail) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 publish("status", "offline", true); | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void payloadEventListener(uint8_t cmd) { |  |  |         void payloadEventListener(uint8_t cmd) { | 
			
		
	
	
		
		
			
				
					|  | @ -118,6 +137,9 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true) { |  |  |         void publish(const char *subTopic, const char *payload, bool retained = false, bool addTopic = true) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if(!mClient.connected()) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 return; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             char topic[MQTT_TOPIC_LEN + 2]; |  |  |             char topic[MQTT_TOPIC_LEN + 2]; | 
			
		
	
		
		
			
				
					|  |  |             snprintf(topic, (MQTT_TOPIC_LEN + 2), "%s/%s", mCfgMqtt->topic, subTopic); |  |  |             snprintf(topic, (MQTT_TOPIC_LEN + 2), "%s/%s", mCfgMqtt->topic, subTopic); | 
			
		
	
		
		
			
				
					|  |  |             if(addTopic) |  |  |             if(addTopic) | 
			
		
	
	
		
		
			
				
					|  | @ -349,10 +371,12 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |             if(mSendList.empty()) |  |  |             if(mSendList.empty()) | 
			
		
	
		
		
			
				
					|  |  |                 return; |  |  |                 return; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             char topic[32 + MAX_NAME_LENGTH], val[40]; |  |  |             char topic[7 + MQTT_TOPIC_LEN], val[40]; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             float total[4]; |  |  |             float total[4]; | 
			
		
	
		
		
			
				
					|  |  |             bool sendTotal = false; |  |  |             bool sendTotal = false; | 
			
		
	
		
		
			
				
					|  |  |             bool totalIncomplete = false; |  |  |             bool totalIncomplete = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             bool allAvail = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             bool first = true; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             while(!mSendList.empty()) { |  |  |             while(!mSendList.empty()) { | 
			
		
	
		
		
			
				
					|  |  |                 memset(total, 0, sizeof(float) * 4); |  |  |                 memset(total, 0, sizeof(float) * 4); | 
			
		
	
	
		
		
			
				
					|  | @ -364,16 +388,24 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |                     record_t<> *rec = iv->getRecordStruct(mSendList.front()); |  |  |                     record_t<> *rec = iv->getRecordStruct(mSendList.front()); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                     if(mSendList.front() == RealTimeRunData_Debug) { |  |  |                     if(mSendList.front() == RealTimeRunData_Debug) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         if(first) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             mIvAvail = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         first = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                         // 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)) { | 
			
		
	
		
		
			
				
					|  |  |                             status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; |  |  |                             status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; | 
			
		
	
		
		
			
				
					|  |  |                             totalIncomplete = true; |  |  |                             totalIncomplete = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             allAvail = false; | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  |                         else if (!iv->isProducing(*mUtcTimestamp, rec)) { |  |  |                         else if (!iv->isProducing(*mUtcTimestamp, rec)) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             mIvAvail = true; | 
			
		
	
		
		
			
				
					|  |  |                             if (MQTT_STATUS_AVAIL_PROD == status) |  |  |                             if (MQTT_STATUS_AVAIL_PROD == status) | 
			
		
	
		
		
			
				
					|  |  |                                 status = MQTT_STATUS_AVAIL_NOT_PROD; |  |  |                                 status = MQTT_STATUS_AVAIL_NOT_PROD; | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         else | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             mIvAvail = true; | 
			
		
	
		
		
			
				
					|  |  |                         snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->config->name); |  |  |                         snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->config->name); | 
			
		
	
		
		
			
				
					|  |  |                         snprintf(val, 40, "%s%s%s%s", |  |  |                         snprintf(val, 40, "%s%s%s%s", | 
			
		
	
		
		
			
				
					|  |  |                             (status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not " : "", |  |  |                             (status == MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not " : "", | 
			
		
	
	
		
		
			
				
					|  | @ -436,6 +468,9 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 mSendList.pop(); // remove from list once all inverters were processed
 |  |  |                 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) && (false == totalIncomplete)) { | 
			
		
	
		
		
			
				
					|  |  |                     uint8_t fieldId; |  |  |                     uint8_t fieldId; | 
			
		
	
		
		
			
				
					|  |  |                     for (uint8_t i = 0; i < 4; i++) { |  |  |                     for (uint8_t i = 0; i < 4; i++) { | 
			
		
	
	
		
		
			
				
					|  | @ -475,6 +510,8 @@ class PubMqtt { | 
			
		
	
		
		
			
				
					|  |  |         std::queue<uint8_t> mSendList; |  |  |         std::queue<uint8_t> mSendList; | 
			
		
	
		
		
			
				
					|  |  |         bool mEnReconnect; |  |  |         bool mEnReconnect; | 
			
		
	
		
		
			
				
					|  |  |         subscriptionCb mSubscriptionCb; |  |  |         subscriptionCb mSubscriptionCb; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         bool mIsDay; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         bool mIvAvail; // shows if at least one inverter is available
 | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         // last will topic and payload must be available trough lifetime of 'espMqttClient'
 |  |  |         // last will topic and payload must be available trough lifetime of 'espMqttClient'
 | 
			
		
	
		
		
			
				
					|  |  |         char mLwtTopic[MQTT_TOPIC_LEN+5]; |  |  |         char mLwtTopic[MQTT_TOPIC_LEN+5]; | 
			
		
	
	
		
		
			
				
					|  | 
 |