Skip to content

Commit 22e1cad

Browse files
Added MQTT Support and enabled 2xBME/P280 Sensors at same time (using different adresses)
1 parent 9909248 commit 22e1cad

30 files changed

+744
-286
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Find out more at https://www.sensate.io
1717
- Adafruit BME680 (https://github.com/adafruit/Adafruit_BME680 v1.0.7)
1818
- Max44009 (https://github.com/dantudose/MAX44009 v1.2.3)
1919
- BH1750 (https://github.com/claws/BH1750)
20+
- MQTT Client Library (https://github.com/knolleary/pubsubclient v2.8.0)
2021

2122
Windows Users:
2223
Use https://github.com/nodemcu/nodemcu-flasher for flashing the firmware.

firmware-esp8266.ino

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
1212
1313
@section HISTORY
14+
v32 - Added MQTT Support!
1415
v31 - Fixed an issue with DHT11 Sensors
1516
v30 - Added support for SSD1306 I2C Displays
1617
v29 - First Public Release
@@ -25,7 +26,7 @@
2526

2627
Display* display = NULL;
2728

28-
int currentVersion = 31;
29+
int currentVersion = 32;
2930
boolean printMemory = false;
3031

3132
String board = "Generic";
@@ -70,6 +71,7 @@ extern int displayMode;
7071

7172
extern uint8_t i2cSDAPort;
7273
extern uint8_t i2cSCLPort;
74+
extern MQTT* mqtt;
7375

7476
#define tickerInterval 250
7577
#define delayInterval 10000
@@ -153,6 +155,8 @@ void runLoop() {
153155
case Init_Configuration:
154156
case Operating:
155157
loopRestserver();
158+
if(mqtt!=NULL)
159+
mqtt->loop();
156160
break;
157161
}
158162
}

src/communication/Data.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,37 @@
1212
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
1313
1414
@section HISTORY
15+
v32 - Added MQTT Support!
1516
v29 - First Public Release
1617
*/
1718
/**************************************************************************/
1819

1920
#include "Data.h"
2021

21-
Data::Data(long id, float value, String unit) {
22+
Data::Data(Sensor *sensor, float value, String unit) {
2223
_type = 1;
2324
_valueFloat = value;
24-
_id = id;
25+
_sensor = sensor;
2526
_unit = unit;
2627
}
2728

28-
Data::Data(long id, int value, String unit) {
29+
Data::Data(Sensor *sensor, int value, String unit) {
2930
_type = 2;
3031
_valueInt = value;
31-
_id = id;
32+
_sensor = sensor;
3233
_unit = unit;
3334
}
3435

35-
Data::Data(long id, boolean value, String unit) {
36+
Data::Data(Sensor *sensor, boolean value, String unit) {
3637
_type = 3;
3738
_valueBoolean = value;
38-
_id = id;
39+
_sensor = sensor;
3940
_unit = unit;
4041
}
4142

4243
String Data::getRequestString() {
4344

44-
String returnString = String(_id) +",";
45+
String returnString = String(_sensor->getId()) +",";
4546

4647
if(_type==1)
4748
returnString = returnString + String(_valueFloat);
@@ -52,4 +53,20 @@ String Data::getRequestString() {
5253

5354
return returnString+","+_unit;
5455

55-
}
56+
}
57+
58+
String Data::getValueString() {
59+
60+
if(_type==1)
61+
return String(_valueFloat);
62+
else if(_type==2)
63+
return String(_valueInt);
64+
else if(_type==3)
65+
return String(_valueBoolean);
66+
67+
return "";
68+
}
69+
70+
Sensor* Data::getSensor() {
71+
return _sensor;
72+
}

src/communication/Data.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
1212
1313
@section HISTORY
14+
v32 - Added MQTT Support!
1415
v29 - First Public Release
1516
*/
1617
/**************************************************************************/
@@ -20,19 +21,25 @@
2021
#ifndef _Data_h_
2122
#define _Data_h_
2223

24+
#include "../input/Sensor.h"
25+
26+
class Sensor;
27+
2328
class Data {
2429
private:
25-
long _id;
30+
Sensor *_sensor;
2631
float _valueFloat;
2732
int _valueInt;
2833
boolean _valueBoolean;
2934
String _unit;
3035
int _type;
3136
public:
32-
Data(long, float, String);
33-
Data(long, int, String);
34-
Data(long, boolean, String);
35-
String getRequestString();
37+
Data(Sensor*, float, String);
38+
Data(Sensor*, int, String);
39+
Data(Sensor*, boolean, String);
40+
String getValueString(void);
41+
String getRequestString(void);
42+
Sensor* getSensor(void);
3643
};
3744

3845
#endif

src/communication/MQTT.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/**************************************************************************/
2+
/*!
3+
@file MQTT.cpp
4+
@author M. Fegerl (Sensate Digital Solutions GmbH)
5+
@license GPL (see LICENSE file)
6+
The Sensate ESP8266 firmware is used to connect ESP8266 based hardware
7+
with the Sensate Cloud and the Sensate apps.
8+
9+
----> https://www.sensate.io
10+
11+
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
12+
13+
@section HISTORY
14+
v32 - Added MQTT Support!
15+
*/
16+
/**************************************************************************/
17+
18+
#include "MQTT.h"
19+
20+
extern unsigned long currentMillis;
21+
boolean enableMQTT;
22+
MQTT *mqtt;
23+
24+
MQTT::MQTT (char* brokerUrl, long brokerPort, String username, String password)
25+
{
26+
_username = username;
27+
_password = password;
28+
_brokerPort = brokerPort;
29+
_brokerUrl = String(brokerUrl);
30+
31+
espClient = WiFiClient();
32+
pubSubClient = new PubSubClient(espClient);
33+
34+
clientId = "Sensate-"+getUUID().substring(0,7);
35+
36+
pubSubClient->setServer(_brokerUrl.c_str(), _brokerPort);
37+
38+
lastMillis = 0;
39+
}
40+
41+
MQTT::MQTT (char* brokerUrl, long brokerPort)
42+
{
43+
_username = "NULL";
44+
_password = "NULL";
45+
46+
clientId = "Sensate-"+getUUID().substring(0,7);
47+
48+
pubSubClient = new PubSubClient(espClient);
49+
pubSubClient->setServer(brokerUrl, brokerPort);
50+
51+
}
52+
53+
bool MQTT::connect()
54+
{
55+
Serial.println("Connecting to broker with clientId: "+clientId);
56+
57+
if(_username=="NULL" && _password=="NULL")
58+
{
59+
Serial.println("Connecting to MQTT broker...");
60+
61+
if (pubSubClient->connect(clientId.c_str()))
62+
{
63+
Serial.println("Connected to MQTT broker");
64+
return true;
65+
}
66+
else
67+
{
68+
Serial.print("Connection to MQTT Broker failed with state ");
69+
Serial.print(pubSubClient->state());
70+
return false;
71+
}
72+
}
73+
else
74+
{
75+
Serial.println("Connecting to MQTT broker with credentials...");
76+
77+
if (pubSubClient->connect(clientId.c_str(), _username.c_str(), _password.c_str()))
78+
{
79+
Serial.println("Connected to MQTT broker");
80+
return true;
81+
}
82+
else
83+
{
84+
Serial.print("Connection to MQTT Broker failed with state ");
85+
Serial.print(pubSubClient->state());
86+
return false;
87+
}
88+
}
89+
}
90+
91+
void MQTT::publishForAutoDiscovery(Sensor* sensor)
92+
{
93+
String pTopic = "homeassistant/sensor/"+clientId+"/"+String(sensor->getId())+"/config";
94+
String category = sensor->getCategory();
95+
String pPayload;
96+
97+
if(category==NULL)
98+
category = "Unnamed";
99+
100+
if(sensor->getMqttClass()=="resistance" || sensor->getMqttClass()=="altitude" || sensor->getMqttClass()=="flux" || sensor->getMqttClass()=="")
101+
pPayload = "{\"name\": \""+sensor->getName()+"\", \"state_topic\": \"Sensate/"+category+"/"+sensor->getName()+"/value\", \"unit_of_measurement\": \""+sensor->getMqttUnit()+"\"}";
102+
else
103+
pPayload = "{\"name\": \""+sensor->getName()+"\", \"device_class\": \""+sensor->getMqttClass()+"\", \"state_topic\": \"Sensate/"+category+"/"+sensor->getName()+"/value\", \"unit_of_measurement\": \""+sensor->getMqttUnit()+"\"}";
104+
105+
pubSubClient->publish(pTopic.c_str(), pPayload.c_str());
106+
}
107+
108+
void MQTT::loop()
109+
{
110+
pubSubClient->loop();
111+
}
112+
113+
void MQTT::publishSensorData(Data* data[], int dataCount)
114+
{
115+
boolean republish = false;
116+
117+
if (!pubSubClient->connected()) {
118+
Serial.println("Trying reconnecting to MQTT broker...");
119+
republish=connect();
120+
}
121+
122+
if((lastMillis == 0) || (currentMillis>lastMillis+300000))
123+
{
124+
Serial.println("Republish MQTT Sensors (once every 5min)");
125+
republish=true;
126+
lastMillis = currentMillis;
127+
}
128+
129+
for (int i = 0; i < dataCount; i++)
130+
{
131+
if(republish)
132+
{
133+
publishForAutoDiscovery(data[i]->getSensor());
134+
delay(250);
135+
}
136+
137+
String cat = data[i]->getSensor()->getCategory();
138+
if(cat.equals(""))
139+
cat="Unnamed";
140+
String name = data[i]->getSensor()->getName();
141+
String vTopic = "Sensate/"+cat+"/"+name+"/value";
142+
pubSubClient->publish(vTopic.c_str(), data[i]->getValueString().c_str());
143+
}
144+
}

src/communication/MQTT.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**************************************************************************/
2+
/*!
3+
@file MQTT.h
4+
@author M. Fegerl (Sensate Digital Solutions GmbH)
5+
@license GPL (see LICENSE file)
6+
The Sensate ESP8266 firmware is used to connect ESP8266 based hardware
7+
with the Sensate Cloud and the Sensate apps.
8+
9+
----> https://www.sensate.io
10+
11+
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
12+
13+
@section HISTORY
14+
v32 - Added MQTT Support!
15+
*/
16+
/**************************************************************************/
17+
18+
#include <Arduino.h>
19+
#include <PubSubClient.h>
20+
#include <ESP8266WiFi.h>
21+
22+
#ifndef _MQTT_h_
23+
#define _MQTT_h_
24+
25+
#include "../controller/UUID.h"
26+
#include "Data.h"
27+
28+
class MQTT {
29+
private:
30+
unsigned long lastMillis;
31+
String _brokerUrl;
32+
long _brokerPort;
33+
String _username;
34+
String _password;
35+
WiFiClient espClient;
36+
PubSubClient* pubSubClient;
37+
String clientId;
38+
39+
public:
40+
MQTT (char*, long);
41+
MQTT (char*, long, String, String);
42+
bool connect(void);
43+
void loop(void);
44+
void publishSensorData(Data* data[], int);
45+
void publishForAutoDiscovery(Sensor*);
46+
};
47+
48+
#endif

0 commit comments

Comments
 (0)