diff --git a/User_Manual.md b/User_Manual.md index 5f34676f..bcc8bef2 100644 --- a/User_Manual.md +++ b/User_Manual.md @@ -9,7 +9,42 @@ In the initial case or after click "erase settings" the fields for the inverter Set at least the serial number and a name for each inverter, check "reboot after save" and click the "Save" button. -## MQTT Output +## MQTT Publish + +### Topic `` + +| Topic | Example Value | Remarks | +| `comm_start` | 1672123767 | inverter communication start, based on sunrise, UTC timestamp | +| `comm_stop` | 1672155709 | inverter communication stop, based on sunset, UTC timestamp | +| `device` | AHOY-DTU | configured device name | +| `dis_night_comm` | true | setting if night communication is disabled | +| `free_heap` | 17784 | free heap of ESP in bytes | +| `mqtt` | connected | shows MQTT status | +| `status` | offline | see table below | +| `sunrise` | 1672124667 | sunrise, UTC timestamp | +| `sunset` | 1672154809 | sunset, UTC timestamp | +| `uptime` | 73630 | uptime in seconds | +| `version` | 0.5.61 | current installed verison of AhoyDTU | +| `wifi_rssi` | -75 | WiFi signal strength | + +| status code | Remarks | +| 0 | offline | +| 1 | partial | +| 2 | online | + + +### Topic `//` + +| Topic | Example Value | Remarks | +| `available` | 2 | see table below | +| `last_success` | 1672155690 | UTC Timestamp | + +| status code | Remarks | +| 0 | not available and not producing | +| 1 | available but not producing | +| 2 | available and producing | + + The AhoyDTU will publish on the following topics `//ch0/#` diff --git a/src/CHANGES.md b/src/CHANGES.md index 26e1b94d..a6c29c7e 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.62 +* fix MQTT `status` update +* removed MQTT `available_text` (can be deducted from `available`) +* enhanced MQTT documentation in `User_Manual.md` +* remvoed `tickSunset` and `tickSunrise` from MQTT. It's not needed any more because of minute wise check of status (`processIvStatus`) +* changed MQTT topic `status` to nummeric value, check documentation in `User_Manual.md` +* fix regular expression of `setup.html` for inverter name and channel name + ## 0.5.61 * fix #521 no reconnect at beginning of day * added immediate (each minute) report of inverter status MQTT #522 diff --git a/src/app.cpp b/src/app.cpp index c350f109..2d3d1769 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -145,8 +145,6 @@ void app::tickCalcSunrise(void) { onceAt(std::bind(&app::tickCalcSunrise, this), nxtTrig); if (mConfig->mqtt.broker[0] > 0) { mMqtt.tickerSun(mSunrise, mSunset, mConfig->sun.offsetSec, mConfig->sun.disNightCom); - onceAt(std::bind(&PubMqttType::tickSunrise, &mMqtt), (mSunrise - mConfig->sun.offsetSec)); - onceAt(std::bind(&PubMqttType::tickSunset, &mMqtt), mSunset); } } diff --git a/src/defines.h b/src/defines.h index 35dc142b..2778da46 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 61 +#define VERSION_PATCH 62 //------------------------------------- typedef struct { @@ -77,6 +77,8 @@ union serial_u { #define MQTT_STATUS_AVAIL_NOT_PROD 1 #define MQTT_STATUS_AVAIL_PROD 2 +enum {MQTT_STATUS_OFFLINE = 0, MQTT_STATUS_PARTIAL, MQTT_STATUS_ONLINE}; + //------------------------------------- // EEPROM //------------------------------------- diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index ebe1a822..bd7a709f 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -34,7 +34,6 @@ class PubMqtt { mTxCnt = 0; mEnReconnect = false; mSubscriptionCb = NULL; - mIsDay = false; mIvAvail = true; memset(mLastIvState, 0xff, MAX_NUM_INVERTERS); } @@ -89,8 +88,6 @@ class PubMqtt { if(mEnReconnect) mClient.connect(); } - else if(mIvAvail && !mIsDay) - tickSunset(); } void tickerSun(uint32_t sunrise, uint32_t sunset, uint32_t offs, bool disNightCom) { @@ -101,39 +98,6 @@ class PubMqtt { publish("dis_night_comm", ((disNightCom) ? "true" : "false"), true); } - void tickSunrise() { - mIsDay = true; - } - - void tickSunset() { - 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++) { - iv = mSys->getInverterByPos(id); - if (NULL == iv) - continue; // skip to next inverter - rec = iv->getRecordStruct(RealTimeRunData_Debug); - - if ((!iv->isAvailable(*mUtcTimestamp, rec)) || (!iv->config->enabled)) { - 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, 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) { if(mClient.connected()) // prevent overflow if MQTT broker is not reachable but set mSendList.push(cmd); @@ -406,17 +370,10 @@ class PubMqtt { } 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; + changed = true; snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name); snprintf(val, 40, "%d", status); @@ -429,7 +386,7 @@ class PubMqtt { } if(changed) { - snprintf(val, 32, "%s", ((allAvail) ? "online" : ((mIvAvail) ? "partial" : "offline"))); + snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((mIvAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); publish("status", val, true); } @@ -535,7 +492,6 @@ class PubMqtt { std::queue mSendList; bool mEnReconnect; subscriptionCb mSubscriptionCb; - bool mIsDay; bool mIvAvail; // shows if at least one inverter is available uint8_t mLastIvState[MAX_NUM_INVERTERS]; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 79184089..3574a8f6 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -147,7 +147,7 @@ - + @@ -320,10 +320,10 @@ iv.append( lbl(id + "Name", "Name*"), - inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9.-_]+", "Invalid input") + inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9.\\-_\\+]+", "Invalid input") ); - for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"], ["ModName", "ch_name", "Module Name", 16, "[A-Za-z0-9.-_]+"]]) { + for(var j of [["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"], ["ModName", "ch_name", "Module Name", 16, "[A-Za-z0-9.\\-_\\+]+"]]) { var cl = (re.test(obj["serial"])) ? null : ["hide"]; iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0])); d = div([j[0]]);