diff --git a/src/CHANGES.md b/src/CHANGES.md index c9551461..ce80ed95 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -7,6 +7,7 @@ * fix calcSunrise was not called every day * added MQTT RX counter to index.html * all values are displayed on /live even if they are 0 +* added MQTT /status to show status over all inverters ## 0.5.51 * improved scheduler, @beegee3 #483 diff --git a/src/app.cpp b/src/app.cpp index 66acf863..24b5fceb 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -165,6 +165,7 @@ void app::tickCalcSunrise(void) { onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig); if (mConfig->mqtt.broker[0] > 0) { once(std::bind(&PubMqttType::tickerSun, &mMqtt), 1); + onceAt(std::bind(&PubMqttType::tickSunrise, &mMqtt), mSunrise); onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), mSunset); } } diff --git a/src/app.h b/src/app.h index 0b256270..ec708310 100644 --- a/src/app.h +++ b/src/app.h @@ -146,6 +146,10 @@ class app : public IApp, public ah::Scheduler { return String(str); } + uint32_t getTimezoneOffset() { + return mApi.getTimezoneOffset(); + } + void setTimestamp(uint32_t newTime) { DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime)); if(0 == newTime) diff --git a/src/appInterface.h b/src/appInterface.h index 6a611345..c3760de5 100644 --- a/src/appInterface.h +++ b/src/appInterface.h @@ -26,6 +26,8 @@ class IApp { virtual uint32_t getSunrise() = 0; virtual uint32_t getSunset() = 0; virtual void setTimestamp(uint32_t newTime) = 0; + virtual String getTimeStr(uint32_t offset) = 0; + virtual uint32_t getTimezoneOffset() = 0; virtual bool getRebootRequestState() = 0; virtual bool getSettingsValid() = 0; diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index c52847b0..f94d2206 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -34,6 +34,8 @@ class PubMqtt { mTxCnt = 0; mEnReconnect = false; mSubscriptionCb = NULL; + mIsDay = false; + mIvAvail = true; } ~PubMqtt() { } @@ -87,6 +89,8 @@ class PubMqtt { if(mEnReconnect) mClient.connect(); } + else if(mIvAvail && !mIsDay) + tickSunset(); } void tickerSun() { @@ -94,22 +98,37 @@ class PubMqtt { publish("sunset", String(*mSunset).c_str(), true); } + void tickSunrise() { + mIsDay = true; + } + void tickSunset() { - printf("tickSunset\n"); - char topic[MAX_NAME_LENGTH + 15], val[32]; + mIsDay = false; + char topic[MQTT_TOPIC_LEN + 15], val[32]; + Inverter<> *iv; + record_t<> *rec; + mIvAvail = false; for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { - Inverter<> *iv = mSys->getInverterByPos(id); + iv = mSys->getInverterByPos(id); if (NULL == iv) continue; // skip to next inverter + rec = iv->getRecordStruct(RealTimeRunData_Debug); - snprintf(topic, MAX_NAME_LENGTH + 15, "%s/available_text", iv->config->name); - snprintf(val, 32, "not available and not producing"); - publish(topic, val, true); + 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"); + publish(topic, val, true); - snprintf(topic, MAX_NAME_LENGTH + 15, "%s/available", iv->config->name); - snprintf(val, 32, "%d", MQTT_STATUS_NOT_AVAIL_NOT_PROD); - publish(topic, val, true); + snprintf(topic, MQTT_TOPIC_LEN + 15, "%s/available", iv->config->name); + snprintf(val, 32, "%d", MQTT_STATUS_NOT_AVAIL_NOT_PROD); + publish(topic, val, true); + } + else + mIvAvail = true; } + + if(!mIvAvail) + publish("status", "offline", true); } 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) { + if(!mClient.connected()) + return; + char topic[MQTT_TOPIC_LEN + 2]; snprintf(topic, (MQTT_TOPIC_LEN + 2), "%s/%s", mCfgMqtt->topic, subTopic); if(addTopic) @@ -349,10 +371,12 @@ class PubMqtt { if(mSendList.empty()) return; - char topic[32 + MAX_NAME_LENGTH], val[40]; + 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); @@ -364,16 +388,24 @@ 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)) { status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; 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 " : "", @@ -436,6 +468,9 @@ 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)) { uint8_t fieldId; for (uint8_t i = 0; i < 4; i++) { @@ -475,6 +510,8 @@ class PubMqtt { std::queue mSendList; bool mEnReconnect; 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' char mLwtTopic[MQTT_TOPIC_LEN+5]; diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 94248302..e2a7714c 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -366,7 +366,7 @@ class RestApi { if(!mSys->Radio.isChipConnected()) warn.add(F("your NRF24 module can't be reached, check the wiring and pinout")); else if(!mSys->Radio.isPVariant()) - warn.add(F("your NRF24 module have not a plus(+), please check!")); + warn.add(F("your NRF24 module isn't a plus version(+), maybe incompatible!")); if((!mApp->getMqttIsConnected()) && (String(mConfig->mqtt.broker).length() > 0)) warn.add(F("MQTT is not connected")); diff --git a/src/web/web.h b/src/web/web.h index 5d8fe5fd..d5b10014 100644 --- a/src/web/web.h +++ b/src/web/web.h @@ -152,9 +152,9 @@ class Web { void serialCb(String msg) { msg.replace("\r\n", ""); - /*if(mSerialAddTime) { + if(mSerialAddTime) { if((9 + mSerialBufFill) <= WEB_SERIAL_BUF_SIZE) { - strncpy(&mSerialBuf[mSerialBufFill], mMain->getTimeStr(mApi.getTimezoneOffset()).c_str(), 9); + strncpy(&mSerialBuf[mSerialBufFill], mApp->getTimeStr(mApp->getTimezoneOffset()).c_str(), 9); mSerialBufFill += 9; } else { @@ -162,9 +162,7 @@ class Web { mEvts->send("webSerial, buffer overflow!", "serial", millis()); } mSerialAddTime = false; - }*/ - - // TODO: comment in + } if(msg.endsWith("")) mSerialAddTime = true;