Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

22-featurerequest-mqtt-auto-discovery-for-home-assitant #32

Merged
1 change: 1 addition & 0 deletions .github/workflows/feature_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dtuGateway_snapshot_${{ env.CURRENT_VERSIONNUMBER }}
path: .pio/build/esp12e/dtuGateway_snapshot_${{ env.CURRENT_VERSIONNUMBER }}.bin
11 changes: 3 additions & 8 deletions include/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ struct UserConfig

char mqttBrokerIpDomain[128] = "192.168.1.100";
int mqttBrokerPort = 1883;
boolean mqttUseTLS = false;
char mqttBrokerUser[64] = "dtuuser";
char mqttBrokerPassword[64] = "dtupass";
char mqttBrokerMainTopic[32] = "dtu1";
char mqttBrokerMainTopic[32] = "dtu_12345678";
boolean mqttHAautoDiscoveryON = false;
boolean mqttActive = false;

uint8_t displayConnected = 0; // OLED default
Expand All @@ -41,13 +43,6 @@ struct UserConfig

extern UserConfig userConfig;

// struct for web update
typedef struct keyAndValue_
{
char key[30];
String value;
} keyAndValue_t;

// Define the UserConfigManager class
class UserConfigManager {
public:
Expand Down
47 changes: 40 additions & 7 deletions include/index_html.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,21 @@ const char INDEX_HTML[] PROGMEM = R"=====(
</div>
<hr>
<div id="mqttSection">
<h3><input type="checkbox" id="mqttActive"> mqtt publishing</h3>
<h3><input type="checkbox" id="mqttActive"> MQTT connection</h3>
<div>
<p>publish all data to a specific mqtt broker and subscribing to the requested powersetting</p>
<p>publish all data to a specific MQTT broker and subscribing to the requested powersetting</p>
</div>
<div>
IP/port to mqtt broker (e.g. 192.168.178.100:1883):
IP/port to MQTT broker (e.g. 192.168.178.100:1883):
</div>
<div>
<input type="text" id="mqttIP" class="ipv4Input" name="ipv4" placeholder="xxx.xxx.xxx.xxx">
</div>
<!-- <div> -->
<!-- <input type="checkbox" id="mqttUseTLS"> TLS connection (e.g. 123456789.s1.eu.hivemq.cloud:8883) -->
<!-- </div> -->
<div>
specific user on your mqtt broker instance:
<br>specify user on your mqtt broker instance:
</div>
<div>
<input type="text" id="mqttUser" value="please type in" required maxlength="64">
Expand All @@ -96,12 +99,16 @@ const char INDEX_HTML[] PROGMEM = R"=====(
<input type="password" id="mqttPassword" value="admin12345" required maxlength="64">
</div>
<div>
mqtt main topic for this dtu (e.g. dtu1 will appear as 'dtu1/grid/U' in the broker):
MQTT main topic for this dtu (e.g. dtu_12345678 will appear as 'dtu_12345678/grid/U' in the broker - has to be unique in your setup):
</div>
<div>
<input type="text" id="mqttMainTopic" maxlength="32">
</div>
<div>
<input type="checkbox" id="mqttHAautoDiscoveryON"> HomeAssistant Auto Discovery <br><small>(On = config is send once after every restart, Off = delete the sensor from HA instantly - using the same main topic as set above)</small><br>
</div>
</div>
<hr>
<div style="text-align: center;">
<b onclick="changeBindingsData()" id="btnSaveWifiSettings" class="form-button btn">save</b>
<b onclick="hide('#changeSettings')" id="btnSettingsClose" class="form-button btn">close</b>
Expand Down Expand Up @@ -667,10 +674,21 @@ const char INDEX_HTML[] PROGMEM = R"=====(
$('#mqttActive').prop("checked", false);
$('#mqttSection').css('color', 'grey');
}
if(mqttData.mqttUseTLS) {
$('#mqttUseTLS').prop("checked", true);
} else {
$('#mqttUseTLS').prop("checked", false);
}
$('#mqttIP').val(mqttData.mqttIp+":"+mqttData.mqttPort);
$('#mqttUser').val(mqttData.mqttUser);
$('#mqttPassword').val(mqttData.mqttPass);
$('#mqttMainTopic').val(mqttData.mqttMainTopic);

if(mqttData.mqttHAautoDiscoveryON) {
$('#mqttHAautoDiscoveryON').prop("checked", true);
} else {
$('#mqttHAautoDiscoveryON').prop("checked", false);
}
}

$('.passcheck').click(function () {
Expand Down Expand Up @@ -806,20 +824,32 @@ const char INDEX_HTML[] PROGMEM = R"=====(

var mqttIpPortString = $('#mqttIP').val().split(":");


var mqttIpSend = mqttIpPortString[0];
var mqttPortSend = "1883";
if(mqttIpPortString[1] != undefined && !isNaN(mqttIpPortString[1])) {
mqttPortSend = mqttIpPortString[1];
}
}
var mqttUseTLSSend = 0;
var mqttUserSend = $('#mqttUser').val();
var mqttPassSend = $('#mqttPassword').val();
var mqttMainTopicSend = $('#mqttMainTopic').val();
var mqttHAautoDiscoveryONSend = 0;

if ($("#mqttActive").is(':checked')) {
mqttActiveSend = 1;
} else {
mqttActiveSend = 0;
}
if ($("#mqttUseTLS").is(':checked')) {
mqttUseTLSSend = 1;
} else {
mqttUseTLSSend = 0;
}
if ($("#mqttHAautoDiscoveryON").is(':checked')) {
mqttHAautoDiscoveryONSend = 1;
} else {
mqttHAautoDiscoveryONSend = 0;
}

var data = {};
data["openhabHostIpDomainSend"] = openhabHostIpDomainSend;
Expand All @@ -828,10 +858,13 @@ const char INDEX_HTML[] PROGMEM = R"=====(

data["mqttIpSend"] = mqttIpSend;
data["mqttPortSend"] = mqttPortSend;
data["mqttUseTLS"] = mqttUseTLSSend;
data["mqttUserSend"] = mqttUserSend;
data["mqttPassSend"] = mqttPassSend;
data["mqttMainTopicSend"] = mqttMainTopicSend;
data["mqttActiveSend"] = mqttActiveSend;
data["mqttHAautoDiscoveryONSend"] = mqttHAautoDiscoveryONSend;


console.log("send to server: openhabHostIpDomainSend: " + openhabHostIpDomainSend);

Expand Down
57 changes: 57 additions & 0 deletions include/mqttHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef MQTTHANDLER_H
#define MQTTHANDLER_H

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

struct PowerLimitSet {
uint16_t timestamp = 0;
int8_t setValue = 0;
};

class MQTTHandler {
public:
MQTTHandler(const char *broker, int port, const char *user, const char *password, bool useTLS, const char *sensorUniqueName);
void setup(bool autoDiscovery);
void loop(bool autoDiscovery, String mainTopicPath, String ipAdress);
void publishDiscoveryMessage(const char *entity, const char *entityName, const char *unit, bool deleteMessage, const char *icon=NULL, const char *deviceClass=NULL);
void publishStandardData(String topicPath, String value);

// Setters for runtime configuration
void setBroker(const char* broker);
void setPort(int port);
void setUser(const char* user);
void setPassword(const char* password);
void setUseTLS(bool useTLS);

PowerLimitSet getPowerLimitSet();

void reconnect(bool autoDiscovery, String mainTopicPath, bool autoDiscoveryRemove, String ipAdress);
static void callback(char *topic, byte *payload, unsigned int length);

private:
const char* mqtt_broker;
int mqtt_port;
const char* mqtt_user;
const char* mqtt_password;
bool useTLS;
const char* sensor_uniqueName;
const char* espURL;


WiFiClient wifiClient;
WiFiClientSecure wifiClientSecure;
PubSubClient client;

static MQTTHandler* instance;

String mqttMainTopicPath;
int8_t mqtt_IncomingPowerLmitSet;
PowerLimitSet lastPowerLimitSet;
String gw_ipAdress;

void stopConnection();
};

#endif // MQTTHANDLER_H
4 changes: 2 additions & 2 deletions include/version.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define VERSION "1.6.0_localDev"
#define BUILDTIME "05.06.2024 - 19:12:17"
#define BUILDTIMESTAMP "1717607537"
#define BUILDTIME "14.06.2024 - 17:53:36"
#define BUILDTIMESTAMP "1718380416"
2 changes: 1 addition & 1 deletion include/version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": "1.6.0_localDev",
"versiondate": "05.06.2024 - 19:12:17",
"versiondate": "14.06.2024 - 17:53:36",
"linksnapshot": "https://github.com/ohAnd/dtuGateway/releases/download/snapshot/dtuGateway_snapshot_1.6.0_localDev.bin",
"link": "https://github.com/ohAnd/dtuGateway//releases/latest/download/dtuGateway_release_1.6.0_localDev.bin"
}
3 changes: 1 addition & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
platform = espressif8266
board = esp07s
framework = arduino
monitor_port = COM4
monitor_port = COM3
monitor_speed = 115200
lib_deps =
arduino-libraries/NTPClient @ ^3.2.1
Expand All @@ -37,7 +37,6 @@ monitor_filters =
default
time
build_flags =
; Define the TFT driver, pins etc. here:
-DGC9A01_DRIVER=1
-DTFT_WIDTH=240
-DTFT_HEIGHT=240
Expand Down
77 changes: 51 additions & 26 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
- [data - http://\<ip\_to\_your\_device\>/api/data](#data---httpip_to_your_deviceapidata)
- [info - http://\<ip\_to\_your\_device\>/api/info](#info---httpip_to_your_deviceapiinfo)
- [openhab integration/ configuration](#openhab-integration-configuration)
- [mqqt integration/ configuration](#mqqt-integration-configuration)
- [MQTT integration/ configuration](#mqtt-integration-configuration)
- [known bugs](#known-bugs)
- [releases](#releases)
- [installation / update](#installation--update)
Expand Down Expand Up @@ -72,9 +72,11 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract

#### connections to the environment
- serving the readed data per /api/data
- binding configuration with seperate activation and login data setting
- configuration of bindings with seperate activation and login data setting
- binding: updating openHab instance with readed data and pulling set data from the instance
- binding: updating to a MQTT broker with readed data [OPEN: pulling set power data from the mqtt instance]
- binding: updating to a MQTT broker with readed data incl. set PowerLimit over MQTT
- 2 ways to configure - simple mqtt publishing with base topic or together with HA MQTT AutoDiscovery based
- for all publishing retain flag is set (keeping last seen data in broker)

#### display support
- selectable (and storable) over advanced web config[^2] or per serial com and at directly at start up coming from factory mode ( [see first-setup-with-access-point](#first-setup-with-access-point) )
Expand Down Expand Up @@ -118,6 +120,7 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract
- select found local wifi and enter/ save the needed wifi password
- change dtu connection data (e.g. host IP in local network, wireless user/ pass for dtu access point)
- configurable data for openhab item settings
- configurable data for MQTT settings incl. HomeAssistant AutoDiscovery
- advanced web config[^2] for all config parameter (http://IP_domain/config) - expert mode
- display selection (0 - OLED, 1 - round TFT)
- timeZone Offset -xxxx sec <-> xxxx sec e.g. 3600 for CET(+1h) /7200 for CEST(+2)/-21600 for CST
Expand All @@ -129,6 +132,9 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract

### data - http://<ip_to_your_device>/api/data

<details>
<summary>expand to see json example</summary>

```json
{
"localtime": 1704110892,
Expand Down Expand Up @@ -166,9 +172,13 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract
}
}
```
</details>

### info - http://<ip_to_your_device>/api/info

<details>
<summary>expand to see json example</summary>

```json
{

Expand Down Expand Up @@ -221,6 +231,7 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract
}
}
```
</details>

## openhab integration/ configuration

Expand All @@ -229,6 +240,9 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract
- list of items that should be available in your openhab config
- read your given power set value from openhab with "<yourOpenItemPrefix>_PowerLimit_Set"
- set openhab items with data from dtu:
<details>
<summary>expand to see to details</summary>

- grid data:
- "<openItemPrefix>Grid_U"
- "<openItemPrefix>Grid_I"
Expand All @@ -252,38 +266,49 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract
- "<openItemPrefix>_PowerLimit" //current read power limit from dtu
- "<openItemPrefix>_WifiRSSI"

## mqqt integration/ configuration
</details>

## MQTT integration/ configuration

- set the IP to your MQTT broker
- set the MQTT user and MQTT password
- set the main topic e.g. 'dtu1' for the pubished data
- data will be published as following ('dtu1' is configurable in the settings):
- set the main topic e.g. 'dtu_12345678' for the pubished data (default: is `dtu_<ESP chip id>` and has to be unique in your environment)
- to set the Power Limit from your environment
- you have to publish to `dtu_<ESP chip id>/inverter/PowerLimit_Set` a value between 2...100 (possible range at DTU)
- the incoming value will be checked for this interval and locally corrected to 2 or 100 if exceeds
- (optional: with retain flag, to get the last set value after restart / reconnect of the dtuGateway)
- data will be published as following ('dtu_12345678' is configurable in the settings):

```
dtu1/timestamp
dtu_12345678/timestamp

dtu1/grid/U
dtu1/grid/I
dtu1/grid/P
dtu1/grid/dailyEnergy
dtu1/grid/totalEnergy
dtu_12345678/grid/U
dtu_12345678/grid/I
dtu_12345678/grid/P
dtu_12345678/grid/dailyEnergy
dtu_12345678/grid/totalEnergy

dtu1/pv0/U
dtu1/pv0/I
dtu1/pv0/P
dtu1/pv0/dailyEnergy
dtu1/pv0/totalEnergy
dtu_12345678/pv0/U
dtu_12345678/pv0/I
dtu_12345678/pv0/P
dtu_12345678/pv0/dailyEnergy
dtu_12345678/pv0/totalEnergy

dtu1/pv1/U
dtu1/pv1/I
dtu1/pv1/P
dtu1/pv1/dailyEnergy
dtu1/pv1/totalEnergy

dtu1/inverter/Temp
dtu1/inverter/PowerLimit
dtu1/inverter/WifiRSSI
dtu_12345678/pv1/U
dtu_12345678/pv1/I
dtu_12345678/pv1/P
dtu_12345678/pv1/dailyEnergy
dtu_12345678/pv1/totalEnergy

dtu_12345678/inverter/Temp
dtu_12345678/inverter/PowerLimit
dtu_12345678/inverter/PowerLimit_Set // <-- this topic will be subscribed to get the power limit to set from your broker
dtu_12345678/inverter/WifiRSSI
```
- Home Assistant Auto Discovery
- you can set HomeAssistant Auto Discovery, if you want to auto configure the dtuGateway for your HA installation
- switch to ON means - with every restart/ reconnection of the dtuGateway the so called config messages will be published for HA and HA will configure all the given entities of dtuGateway incl. the set value for PowerLimit
- switch to OFF means - all the config messages will be deleted and therefore the dtuGateway will be removed from HA (base publishing of data will be remain the same, if MQTT is activated)

## known bugs
- sometimes out-of-memory resets with instant reboots (rare after some hours or more often after some days)
Expand Down
Loading