mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-10 14:41:37 +02:00
improved MQTT #468 set status to "offline" / "online" / "partial"
fix web-serial-console
This commit is contained in:
parent
e5a40673fd
commit
67b9170fcf
7 changed files with 59 additions and 16 deletions
|
@ -7,6 +7,7 @@
|
||||||
* fix calcSunrise was not called every day
|
* fix calcSunrise was not called every day
|
||||||
* added MQTT RX counter to index.html
|
* added MQTT RX counter to index.html
|
||||||
* all values are displayed on /live even if they are 0
|
* all values are displayed on /live even if they are 0
|
||||||
|
* added MQTT <TOPIC>/status to show status over all inverters
|
||||||
|
|
||||||
## 0.5.51
|
## 0.5.51
|
||||||
* improved scheduler, @beegee3 #483
|
* improved scheduler, @beegee3 #483
|
||||||
|
|
|
@ -165,6 +165,7 @@ void app::tickCalcSunrise(void) {
|
||||||
onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig);
|
onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig);
|
||||||
if (mConfig->mqtt.broker[0] > 0) {
|
if (mConfig->mqtt.broker[0] > 0) {
|
||||||
once(std::bind(&PubMqttType::tickerSun, &mMqtt), 1);
|
once(std::bind(&PubMqttType::tickerSun, &mMqtt), 1);
|
||||||
|
onceAt(std::bind(&PubMqttType::tickSunrise, &mMqtt), mSunrise);
|
||||||
onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), mSunset);
|
onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), mSunset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,10 @@ class app : public IApp, public ah::Scheduler {
|
||||||
return String(str);
|
return String(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t getTimezoneOffset() {
|
||||||
|
return mApi.getTimezoneOffset();
|
||||||
|
}
|
||||||
|
|
||||||
void setTimestamp(uint32_t newTime) {
|
void setTimestamp(uint32_t newTime) {
|
||||||
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
|
DPRINTLN(DBG_DEBUG, F("setTimestamp: ") + String(newTime));
|
||||||
if(0 == newTime)
|
if(0 == newTime)
|
||||||
|
|
|
@ -26,6 +26,8 @@ class IApp {
|
||||||
virtual uint32_t getSunrise() = 0;
|
virtual uint32_t getSunrise() = 0;
|
||||||
virtual uint32_t getSunset() = 0;
|
virtual uint32_t getSunset() = 0;
|
||||||
virtual void setTimestamp(uint32_t newTime) = 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 getRebootRequestState() = 0;
|
||||||
virtual bool getSettingsValid() = 0;
|
virtual bool getSettingsValid() = 0;
|
||||||
|
|
|
@ -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(val, 32, "not available and not producing");
|
snprintf(topic, MQTT_TOPIC_LEN + 15, "%s/available_text", iv->config->name);
|
||||||
publish(topic, val, true);
|
snprintf(val, 32, "not available and not producing");
|
||||||
|
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];
|
||||||
|
|
|
@ -366,7 +366,7 @@ class RestApi {
|
||||||
if(!mSys->Radio.isChipConnected())
|
if(!mSys->Radio.isChipConnected())
|
||||||
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
warn.add(F("your NRF24 module can't be reached, check the wiring and pinout"));
|
||||||
else if(!mSys->Radio.isPVariant())
|
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))
|
if((!mApp->getMqttIsConnected()) && (String(mConfig->mqtt.broker).length() > 0))
|
||||||
warn.add(F("MQTT is not connected"));
|
warn.add(F("MQTT is not connected"));
|
||||||
|
|
|
@ -152,9 +152,9 @@ class Web {
|
||||||
|
|
||||||
void serialCb(String msg) {
|
void serialCb(String msg) {
|
||||||
msg.replace("\r\n", "<rn>");
|
msg.replace("\r\n", "<rn>");
|
||||||
/*if(mSerialAddTime) {
|
if(mSerialAddTime) {
|
||||||
if((9 + mSerialBufFill) <= WEB_SERIAL_BUF_SIZE) {
|
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;
|
mSerialBufFill += 9;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -162,9 +162,7 @@ class Web {
|
||||||
mEvts->send("webSerial, buffer overflow!", "serial", millis());
|
mEvts->send("webSerial, buffer overflow!", "serial", millis());
|
||||||
}
|
}
|
||||||
mSerialAddTime = false;
|
mSerialAddTime = false;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// TODO: comment in
|
|
||||||
|
|
||||||
if(msg.endsWith("<rn>"))
|
if(msg.endsWith("<rn>"))
|
||||||
mSerialAddTime = true;
|
mSerialAddTime = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue