Skip to content

Commit

Permalink
Added MQTT Support and enabled 2xBME/P280 Sensors at same time (using…
Browse files Browse the repository at this point in the history
… different adresses)
  • Loading branch information
Manuel-Sensate committed Jul 7, 2020
1 parent 9909248 commit 22e1cad
Show file tree
Hide file tree
Showing 30 changed files with 744 additions and 286 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Find out more at https://www.sensate.io
- Adafruit BME680 (https://github.com/adafruit/Adafruit_BME680 v1.0.7)
- Max44009 (https://github.com/dantudose/MAX44009 v1.2.3)
- BH1750 (https://github.com/claws/BH1750)
- MQTT Client Library (https://github.com/knolleary/pubsubclient v2.8.0)

Windows Users:
Use https://github.com/nodemcu/nodemcu-flasher for flashing the firmware.
Expand Down
6 changes: 5 additions & 1 deletion firmware-esp8266.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
@section HISTORY
v32 - Added MQTT Support!
v31 - Fixed an issue with DHT11 Sensors
v30 - Added support for SSD1306 I2C Displays
v29 - First Public Release
Expand All @@ -25,7 +26,7 @@

Display* display = NULL;

int currentVersion = 31;
int currentVersion = 32;
boolean printMemory = false;

String board = "Generic";
Expand Down Expand Up @@ -70,6 +71,7 @@ extern int displayMode;

extern uint8_t i2cSDAPort;
extern uint8_t i2cSCLPort;
extern MQTT* mqtt;

#define tickerInterval 250
#define delayInterval 10000
Expand Down Expand Up @@ -153,6 +155,8 @@ void runLoop() {
case Init_Configuration:
case Operating:
loopRestserver();
if(mqtt!=NULL)
mqtt->loop();
break;
}
}
Expand Down
33 changes: 25 additions & 8 deletions src/communication/Data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,37 @@
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
@section HISTORY
v32 - Added MQTT Support!
v29 - First Public Release
*/
/**************************************************************************/

#include "Data.h"

Data::Data(long id, float value, String unit) {
Data::Data(Sensor *sensor, float value, String unit) {
_type = 1;
_valueFloat = value;
_id = id;
_sensor = sensor;
_unit = unit;
}

Data::Data(long id, int value, String unit) {
Data::Data(Sensor *sensor, int value, String unit) {
_type = 2;
_valueInt = value;
_id = id;
_sensor = sensor;
_unit = unit;
}

Data::Data(long id, boolean value, String unit) {
Data::Data(Sensor *sensor, boolean value, String unit) {
_type = 3;
_valueBoolean = value;
_id = id;
_sensor = sensor;
_unit = unit;
}

String Data::getRequestString() {

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

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

return returnString+","+_unit;

}
}

String Data::getValueString() {

if(_type==1)
return String(_valueFloat);
else if(_type==2)
return String(_valueInt);
else if(_type==3)
return String(_valueBoolean);

return "";
}

Sensor* Data::getSensor() {
return _sensor;
}
17 changes: 12 additions & 5 deletions src/communication/Data.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
@section HISTORY
v32 - Added MQTT Support!
v29 - First Public Release
*/
/**************************************************************************/
Expand All @@ -20,19 +21,25 @@
#ifndef _Data_h_
#define _Data_h_

#include "../input/Sensor.h"

class Sensor;

class Data {
private:
long _id;
Sensor *_sensor;
float _valueFloat;
int _valueInt;
boolean _valueBoolean;
String _unit;
int _type;
public:
Data(long, float, String);
Data(long, int, String);
Data(long, boolean, String);
String getRequestString();
Data(Sensor*, float, String);
Data(Sensor*, int, String);
Data(Sensor*, boolean, String);
String getValueString(void);
String getRequestString(void);
Sensor* getSensor(void);
};

#endif
144 changes: 144 additions & 0 deletions src/communication/MQTT.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**************************************************************************/
/*!
@file MQTT.cpp
@author M. Fegerl (Sensate Digital Solutions GmbH)
@license GPL (see LICENSE file)
The Sensate ESP8266 firmware is used to connect ESP8266 based hardware
with the Sensate Cloud and the Sensate apps.
----> https://www.sensate.io
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
@section HISTORY
v32 - Added MQTT Support!
*/
/**************************************************************************/

#include "MQTT.h"

extern unsigned long currentMillis;
boolean enableMQTT;
MQTT *mqtt;

MQTT::MQTT (char* brokerUrl, long brokerPort, String username, String password)
{
_username = username;
_password = password;
_brokerPort = brokerPort;
_brokerUrl = String(brokerUrl);

espClient = WiFiClient();
pubSubClient = new PubSubClient(espClient);

clientId = "Sensate-"+getUUID().substring(0,7);

pubSubClient->setServer(_brokerUrl.c_str(), _brokerPort);

lastMillis = 0;
}

MQTT::MQTT (char* brokerUrl, long brokerPort)
{
_username = "NULL";
_password = "NULL";

clientId = "Sensate-"+getUUID().substring(0,7);

pubSubClient = new PubSubClient(espClient);
pubSubClient->setServer(brokerUrl, brokerPort);

}

bool MQTT::connect()
{
Serial.println("Connecting to broker with clientId: "+clientId);

if(_username=="NULL" && _password=="NULL")
{
Serial.println("Connecting to MQTT broker...");

if (pubSubClient->connect(clientId.c_str()))
{
Serial.println("Connected to MQTT broker");
return true;
}
else
{
Serial.print("Connection to MQTT Broker failed with state ");
Serial.print(pubSubClient->state());
return false;
}
}
else
{
Serial.println("Connecting to MQTT broker with credentials...");

if (pubSubClient->connect(clientId.c_str(), _username.c_str(), _password.c_str()))
{
Serial.println("Connected to MQTT broker");
return true;
}
else
{
Serial.print("Connection to MQTT Broker failed with state ");
Serial.print(pubSubClient->state());
return false;
}
}
}

void MQTT::publishForAutoDiscovery(Sensor* sensor)
{
String pTopic = "homeassistant/sensor/"+clientId+"/"+String(sensor->getId())+"/config";
String category = sensor->getCategory();
String pPayload;

if(category==NULL)
category = "Unnamed";

if(sensor->getMqttClass()=="resistance" || sensor->getMqttClass()=="altitude" || sensor->getMqttClass()=="flux" || sensor->getMqttClass()=="")
pPayload = "{\"name\": \""+sensor->getName()+"\", \"state_topic\": \"Sensate/"+category+"/"+sensor->getName()+"/value\", \"unit_of_measurement\": \""+sensor->getMqttUnit()+"\"}";
else
pPayload = "{\"name\": \""+sensor->getName()+"\", \"device_class\": \""+sensor->getMqttClass()+"\", \"state_topic\": \"Sensate/"+category+"/"+sensor->getName()+"/value\", \"unit_of_measurement\": \""+sensor->getMqttUnit()+"\"}";

pubSubClient->publish(pTopic.c_str(), pPayload.c_str());
}

void MQTT::loop()
{
pubSubClient->loop();
}

void MQTT::publishSensorData(Data* data[], int dataCount)
{
boolean republish = false;

if (!pubSubClient->connected()) {
Serial.println("Trying reconnecting to MQTT broker...");
republish=connect();
}

if((lastMillis == 0) || (currentMillis>lastMillis+300000))
{
Serial.println("Republish MQTT Sensors (once every 5min)");
republish=true;
lastMillis = currentMillis;
}

for (int i = 0; i < dataCount; i++)
{
if(republish)
{
publishForAutoDiscovery(data[i]->getSensor());
delay(250);
}

String cat = data[i]->getSensor()->getCategory();
if(cat.equals(""))
cat="Unnamed";
String name = data[i]->getSensor()->getName();
String vTopic = "Sensate/"+cat+"/"+name+"/value";
pubSubClient->publish(vTopic.c_str(), data[i]->getValueString().c_str());
}
}
48 changes: 48 additions & 0 deletions src/communication/MQTT.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**************************************************************************/
/*!
@file MQTT.h
@author M. Fegerl (Sensate Digital Solutions GmbH)
@license GPL (see LICENSE file)
The Sensate ESP8266 firmware is used to connect ESP8266 based hardware
with the Sensate Cloud and the Sensate apps.
----> https://www.sensate.io
SOURCE: https://github.com/sensate-io/firmware-esp8266.git
@section HISTORY
v32 - Added MQTT Support!
*/
/**************************************************************************/

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

#ifndef _MQTT_h_
#define _MQTT_h_

#include "../controller/UUID.h"
#include "Data.h"

class MQTT {
private:
unsigned long lastMillis;
String _brokerUrl;
long _brokerPort;
String _username;
String _password;
WiFiClient espClient;
PubSubClient* pubSubClient;
String clientId;

public:
MQTT (char*, long);
MQTT (char*, long, String, String);
bool connect(void);
void loop(void);
void publishSensorData(Data* data[], int);
void publishForAutoDiscovery(Sensor*);
};

#endif
Loading

0 comments on commit 22e1cad

Please sign in to comment.