Browse Source

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
pull/558/head
lumapu 2 years ago
parent
commit
a8d9b7ad0b
  1. 37
      User_Manual.md
  2. 8
      src/CHANGES.md
  3. 2
      src/app.cpp
  4. 4
      src/defines.h
  5. 48
      src/publisher/pubMqtt.h
  6. 6
      src/web/html/setup.html

37
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>`
| 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>/<INVERTER_NAME_FROM_SETUP>/`
| 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
`<TOPIC>/<INVERTER_NAME_FROM_SETUP>/ch0/#`

8
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

2
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);
}
}

4
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
//-------------------------------------

48
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<uint8_t> mSendList;
bool mEnReconnect;
subscriptionCb mSubscriptionCb;
bool mIsDay;
bool mIvAvail; // shows if at least one inverter is available
uint8_t mLastIvState[MAX_NUM_INVERTERS];

6
src/web/html/setup.html

@ -147,7 +147,7 @@
<label for="mqttPwd">Password (optional)</label>
<input type="password" class="text" name="mqttPwd"/>
<label for="mqttTopic">Topic</label>
<input type="text" class="text" name="mqttTopic" pattern="[A-Za-z0-9.-_]+" title="Invalid input" />
<input type="text" class="text" name="mqttTopic" pattern="[A-Za-z0-9.\-_\+]+" title="Invalid input" />
<label for="mqttBtn">Discovery Config (homeassistant)</label>
<input type="button" name="mqttDiscovery" id="mqttDiscovery" class="btn" value="send" onclick="sendDiscoveryConfig()"/>
<span id="apiResultMqtt"></span>
@ -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]]);

Loading…
Cancel
Save