Skip to content

Commit

Permalink
Merge branch 'release/v0.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jptrsn committed Oct 13, 2018
2 parents 1c7425f + 01181e5 commit 83716b0
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 73 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Settings_local.h
.pioenvs
.piolibdeps
lib
.clang_complete
.gcc-flags.json
.idea
160 changes: 98 additions & 62 deletions ESP32-mqtt-room.ino
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
/*
Major thank you to the following contributors for their efforts:
pcbreflux for the original version of this code, as well as the eddystone handlers.
Andreis Speiss for his work on YouTube and his invaluable github at sensorsiot
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncTCP.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <AsyncMqttClient.h>
#include <ArduinoJSON.h>
#include "BLEBeacon.h"
#include "BLEEddystoneTLM.h"
#include "BLEEddystoneURL.h"
#include "Settings_local.h"

BLEScan* pBLEScan;
int scanTime = 5; //In seconds
int scanTime = 10; //In seconds
int waitTime = scanInterval; //In seconds

uint16_t beconUUID = 0xFEAA;
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))

WiFiClient espClient;
PubSubClient client(espClient);
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

TaskHandle_t CoreZeroTask;

Expand Down Expand Up @@ -83,27 +89,71 @@ float calculateDistance(int rssi, int txPower) {

}

void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");

if (client.connect(uint64_to_string(ESP.getEfuseMac()), mqttUser, mqttPassword )) {
Serial.print("connected with client id ");
Serial.println(uint64_to_string(ESP.getEfuseMac()));
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
void connectToWifi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
WiFi.setHostname(hostname);
}

void connectToMqtt() {
Serial.println("Connecting to MQTT");
mqttClient.setCredentials(mqttUser, mqttPassword);
mqttClient.connect();
}

void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}

void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);

String publishTopic = String(channel) + "/" + room;
if (mqttClient.publish((char *)publishTopic.c_str(), 0, 0, "Hello from ESP32") == true) {
Serial.println("Success sending message to topic");
} else {
Serial.println("Error sending message");
}

}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");

if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}

void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

void onResult(BLEAdvertisedDevice advertisedDevice) {

unsigned long started = millis();
Serial.printf("\n\n");
Serial.println("onResult started");

StaticJsonBuffer<500> JSONbuffer;
JsonObject& JSONencoder = JSONbuffer.createObject();

Expand All @@ -116,14 +166,18 @@ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
JSONencoder["uuid"] = mac_address;
JSONencoder["rssi"] = rssi;

Serial.println("Parsed id");

if (advertisedDevice.haveName()){
String nameBLE = String(advertisedDevice.getName().c_str());
Serial.print("Name: ");
Serial.println(nameBLE);
JSONencoder["name"] = nameBLE;
} else {
JSONencoder["name"] = "unknown";
}

Serial.printf("\n\n");
// Serial.printf("\n\n");
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
std::string strServiceData = advertisedDevice.getServiceData();
uint8_t cServiceData[100];
Expand Down Expand Up @@ -153,7 +207,7 @@ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
} else {
if (advertisedDevice.haveManufacturerData()==true) {
std::string strManufacturerData = advertisedDevice.getManufacturerData();

Serial.println("Got manufacturer data");
uint8_t cManufacturerData[100];
strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);

Expand Down Expand Up @@ -198,10 +252,7 @@ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

Serial.printf("strManufacturerData: %d \n",strManufacturerData.length());
// TODO: parse manufacturer data
// for (int i=0;i<strManufacturerData.length();i++) {
// Serial.printf("[%X]",cManufacturerData[i]);
// }
// Serial.printf("\n");

}
} else {

Expand All @@ -218,28 +269,24 @@ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
}
}

Serial.println("wdt");
vTaskDelay(500); // watchdog timer

unsigned long started = millis();

char JSONmessageBuffer[500];
char JSONmessageBuffer[512];
JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));

String publishTopic = String(channel) + "/" + room;

if (client.publish((char *)publishTopic.c_str(), JSONmessageBuffer) == true) {
if (mqttClient.publish((char *)publishTopic.c_str(), 0, 0, JSONmessageBuffer) == true) {

Serial.print("Success sending message to topic: "); Serial.println(publishTopic);
unsigned long duration = millis() - started;
Serial.print("duration ");
Serial.println(duration);
// Serial.print("Message: "); Serial.println(JSONmessageBuffer);

} else {
Serial.print("Error sending message: "); Serial.println(publishTopic);
Serial.print("Message: "); Serial.println(JSONmessageBuffer);
}

unsigned long duration = millis() - started;
Serial.print("duration ");
Serial.println(duration);
}
};

Expand All @@ -256,55 +303,44 @@ void createTaskOnCoreZero() {


void setup() {

Serial.begin(115200);
createTaskOnCoreZero();
WiFi.begin(ssid, password);
WiFi.setHostname(hostname);

Serial.print("Connecting to WiFi..");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

Serial.println();
Serial.print("Connected to the WiFi network as ");
Serial.println(hostname);
WiFi.onEvent(WiFiEvent);

client.setServer(mqttServer, mqttPort);
reconnect();
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);

String publishTopic = String(channel) + "/" + room;
if (client.publish((char *)publishTopic.c_str(), "Hello from ESP32") == true) {
Serial.println("Success sending message to topic");
} else {
Serial.println("Error sending message");
}
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(mqttHost, mqttPort);

connectToWifi();

createTaskOnCoreZero();

BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster

}

unsigned long last = 0;

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

if (millis() - last > (waitTime * 1000)) {
vTaskDelay(10); // watchdog timer

if (millis() - last > (waitTime * 1000) || last == 0) {
Serial.println("Scanning...");
BLEScanResults foundDevices = pBLEScan->start(scanTime);
Serial.printf("\nScan done! Devices found: %d\n",foundDevices.getCount());
last = millis();
}

vTaskDelay(10); // watchdog timer

}

char *uint64_to_string(uint64_t input) {
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ An ESP32 based presence detection node for use with the Home Assistant mqtt_room
This depends heavily on the hard work done by [pcbreflux](https://github.com/pcbreflux) and [nkolban](https://github.com/nkolban) both on GitHub and on their YouTube Channels. Specifically, it is a modified version of pcbreflux's [ESP32_BLE_beaconscan](https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_BLE_beaconscan).

## Getting Started
1. You can get started by cloning this repository to your local machine using git. Alternatively, you can [download the zip](https://github.com/jptrsn/ESP32-mqtt-room/archive/master.zip).

You can get started by cloning this repository to your local machine using git. Alternatively, you can [download the zip](https://github.com/jptrsn/ESP32-mqtt-room/archive/master.zip). To get the code onto your device, you can load it via the Arduino IDE or, thanks to some great work by [kylegordon](https://github.com/kylegordon), you can now build and upload using PlatformIO.


2. Make a copy of the `Settings.h` file, and rename it `Settings_local.h`. Fill in the required information in your local settings file (the local file is ignored by GitHub, so you won't upload your sensitive information).

### Configuration
Expand Down
4 changes: 2 additions & 2 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
//Replace with a human-friendly host name.
#define hostname "esp32_room_presence"

//Replace with your MQTT Broker address; example: #define mqttServer "192.168.0.112"
#define mqttServer "$MQTT_BROKER_ADDRESS$"
//Replace with your MQTT Broker address; example: #define mqttHost IPAddress(192, 168, 1, 195)
#define mqttHost IPAddress(192, 168, 1, 195)

//Replace with your MQTT Broker port; example: #define mqttPort 1883
#define mqttPort $MQTT_PORT$
Expand Down
2 changes: 1 addition & 1 deletion Settings_CI.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#define ssid "Travis"
#define password "123456789"
#define hostname "esp32_room_presence"
#define mqttServer "192.168.1.1"
#define mqttHost IPAddress(192, 168, 1, 195)
#define mqttPort 1883
#define mqttUser "homeassistant"
#define mqttPassword "123456789"
Expand Down
11 changes: 6 additions & 5 deletions BLEEddystoneTLM.cpp → lib/BLEEddystoneTLM/BLEEddystoneTLM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Created on: Mar 12, 2018
* Author: pcbreflux
* See original repository at https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_BLE_beaconscan
*/
#include "Arduino.h"
#include "sdkconfig.h"
Expand Down Expand Up @@ -57,27 +58,27 @@ std::string BLEEddystoneTLM::toString() {
std::string out = "";
String buff;
uint32_t rawsec;

out += "Version ";
buff = String(m_eddystoneData.version, DEC);
out += buff.c_str();
out += "\n";

out += "Battery Voltage ";
buff = String(ENDIAN_CHANGE_U16(m_eddystoneData.volt), DEC);
out += buff.c_str();
out += " mV\n";

out += "Temperature ";
buff = String((float)m_eddystoneData.temp, 1);
out += buff.c_str();
out += " °C\n";

out += "Adv. Count ";
buff = String(ENDIAN_CHANGE_U32(m_eddystoneData.advCount), DEC);
out += buff.c_str();
out += "\n";

out += "Time ";
rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
buff = "0000"+String(rawsec/864000, DEC);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Created on: Mar 12, 2018
* Author: pcbreflux
* See original repository at https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_BLE_beaconscan
*/

#ifndef _BLEEddystoneTLM_H_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Created on: Mar 12, 2018
* Author: pcbreflux
* See original repository at https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_BLE_beaconscan
*/
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Created on: Mar 12, 2018
* Author: pcbreflux
* See original repository at https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_BLE_beaconscan
*/

#ifndef _BLEEddystoneURL_H_
Expand Down
Loading

0 comments on commit 83716b0

Please sign in to comment.