mesh mqtt gateway example

This commit is contained in:
2018-06-10 21:42:57 +02:00
parent 0e6d7f7f3d
commit 73e9f4af8f
7 changed files with 164 additions and 82 deletions

View File

@@ -9,7 +9,7 @@
; http://docs.platformio.org/page/projectconf.html
[platformio]
env_default = mesh
env_default = meshMqttBridge
[common]
framework = arduino
@@ -34,7 +34,7 @@ lib_deps = ${common.lib_deps}
;upload_port = 192.168.1.168
[env:basic]
src_filter = +<*> +<examples/basic/> -<examples/mesh/>
src_filter = +<*> +<examples/basic/> -<examples/mesh/> -<examples/mqttBridge/>
platform = espressif8266
board = esp12e
upload_speed = 921600
@@ -45,11 +45,22 @@ lib_deps = ${common.lib_deps}
[env:mesh]
src_filter = +<*> +<examples/mesh/> -<examples/basic/>
src_filter = +<*> +<examples/mesh/> -<examples/basic/> -<examples/mqttBridge/>
platform = espressif8266
board = esp12e
upload_speed = 921600
monitor_baud = 115200
framework = ${common.framework}
lib_deps = ${common.lib_deps}
painlessMesh
painlessMesh
[env:meshMqttBridge]
src_filter = +<*> +<examples/mesh/> -<examples/basic/> -<examples/mesh/>
platform = espressif8266
board = esp12e
upload_speed = 921600
monitor_baud = 115200
framework = ${common.framework}
lib_deps = ${common.lib_deps}
painlessMesh
PubSubClient

View File

@@ -2,7 +2,7 @@
#define __MESHNET_H__
#include <painlessMesh.h>
#include <WiFiClient.h>
#include "Network.h"
using namespace std;
@@ -13,15 +13,13 @@ using namespace std::placeholders;
#define MESH_PASSWORD "somethingSneaky"
#define MESH_PORT 5555
class MeshNet : public Network {
public:
painlessMesh mesh;
Network* init(){
Serial.println("init mesh");
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP);
mesh.setDebugMsgTypes( ERROR | STARTUP | CONNECTION);
mesh.init( MESH_PREFIX, MESH_PASSWORD, scheduler, MESH_PORT, WIFI_AP_STA, 11 );
//mesh.onReceive(bind(&MeshNet::receivedCallback,this, _1, _2));
mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1));
@@ -31,6 +29,9 @@ class MeshNet : public Network {
return this;
}
Network* connect(){
Serial.println("connect station");
mesh.stationManual("tErAx1d", "ramalamadingdong");
mesh.setHostname("MeshNode");
return this;
}
void broadcast(String msg){

View File

@@ -3,12 +3,14 @@
#include <Arduino.h>
#include <TaskSchedulerDeclarations.h>
#include <WiFiClient.h>
class Network {
public:
uint32_t id = 0;
Network(){}
Scheduler* scheduler;
//WiFiClient wifiClient;
virtual Network* init() { return this; };
virtual Network* connect() { return this; };
virtual void update() {};

View File

@@ -3,6 +3,7 @@
#include <painlessMesh.h>
#include "App.h"
#include "MeshNet.h"
#define MESH_PREFIX "whateverYouLike"
#define MESH_PASSWORD "somethingSneaky"
@@ -17,18 +18,21 @@ class MeshApp : public App {
MeshNet* net;
MeshApp() /* : App(sprkt) */ {
}
void activate(Scheduler* scheduler, Network* network) {
net = static_cast<MeshNet*>(network);
net->mesh.onReceive(bind(&MeshApp::receivedCallback,this, _1, _2));
// add a task that sends stuff to the mesh
someTask.set(TASK_SECOND * 5, TASK_FOREVER,
bind(&MeshApp::advertise, this, net));
scheduler->addTask(someTask);
someTask.enable();
}
void advertise(MeshNet* network){
String msg = "Hi, my name is " + String(network->id);
network->broadcast(msg);
}
void activate(Scheduler* scheduler, Network* network) {
net = static_cast<MeshNet*>(network);
someTask.set(TASK_SECOND * 5, TASK_FOREVER,
bind(&MeshApp::advertise, this, net));
net->mesh.onReceive(bind(&MeshApp::receivedCallback,this, _1, _2));
scheduler->addTask(someTask);
someTask.enable();
}
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());

View File

@@ -1,66 +0,0 @@
//************************************************************
// this is a simple example that uses the painlessMesh library
//
// 1. sends a silly message to every node on the mesh at a random time between 1 and 5 seconds
// 2. prints anything it receives to Serial.print
//
//
//************************************************************
#include "painlessMesh.h"
#define MESH_PREFIX "whateverYouLike"
#define MESH_PASSWORD "somethingSneaky"
#define MESH_PORT 5555
Scheduler userScheduler; // to control your personal task
painlessMesh mesh;
// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain
Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );
void sendMessage() {
String msg = "Hello from node ";
msg += mesh.getNodeId();
mesh.sendBroadcast( msg );
taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}
// Needed for painless library
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}
void newConnectionCallback(uint32_t nodeId) {
Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}
void changedConnectionCallback() {
Serial.printf("Changed connections %s\n",mesh.subConnectionJson().c_str());
}
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}
void setup() {
Serial.begin(115200);
mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
//mesh.setDebugMsgTypes( ERROR | STARTUP ); // set before init() so that you can see startup messages
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 6 );
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
userScheduler.addTask( taskSendMessage );
taskSendMessage.enable();
}
void loop() {
userScheduler.execute(); // it will run mesh scheduler as well
mesh.update();
}

View File

@@ -0,0 +1,101 @@
#ifndef __MESH_MQTT_BRIDGE_APP__
#define __MESH_MQTT_BRIDGE_APP__
#include <WiFiClient.h>
#include <painlessMesh.h>
#include <PubSubClient.h>
#include "App.h"
#include "MeshNet.h"
#define MQTT_CLIENT_NAME "meshBridge"
#define MQTT_BROKER_HOST "citadel.lan"
#define MQTT_BROKER_PORT 1883
#define MQTT_TOPIC_ROOT "mesh"
using namespace std;
using namespace std::placeholders;
WiFiClient wifiClient;
class MqttMeshBridge : public App {
public:
Task connectTask;
Task processTask;
MeshNet* net;
PubSubClient* client;
MqttMeshBridge() /* : App(sprkt) */ {
}
void activate(Scheduler* scheduler, Network* network) {
net = static_cast<MeshNet*>(network);
net->mesh.onReceive(bind(&MqttMeshBridge::receivedCallback,this, _1, _2));
client = new PubSubClient(MQTT_BROKER_HOST, MQTT_BROKER_PORT, bind(&MqttMeshBridge::mqttCallback, this, _1, _2, _3), wifiClient);
// add a task that sends stuff to the mesh
enableConnectTask(scheduler);
enableProcessTask(scheduler);
}
void enableConnectTask(Scheduler* scheduler){
connectTask.set(TASK_SECOND * 5, TASK_FOREVER,
bind(&MqttMeshBridge::connect, this));
scheduler->addTask(connectTask);
connectTask.enable();
}
void enableProcessTask(Scheduler* scheduler){
processTask.set(TASK_MILLISECOND * 5, TASK_FOREVER,
bind(&MqttMeshBridge::process, this));
scheduler->addTask(processTask);
processTask.enable();
}
void process(){
client->loop();
}
void connect() {
if (!client->connected()) {
if (client->connect(MQTT_CLIENT_NAME)) {
Serial.println("MQTT connected");
client->publish("mesh/from/gateway","Ready!");
client->subscribe("mesh/to/#");
}
}
}
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("bridge: Received from %u msg=%s\n", from, msg.c_str());
String topic = "mesh/from/" + String(from);
client->publish(topic.c_str(), msg.c_str());
}
void mqttCallback(char* topic, uint8_t* payload, unsigned int length) {
char* cleanPayload = (char*)malloc(length+1);
payload[length] = '\0';
memcpy(cleanPayload, payload, length+1);
String msg = String(cleanPayload);
free(cleanPayload);
int topicRootLength = String(MQTT_TOPIC_ROOT).length();
String targetStr = String(topic).substring(topicRootLength + 4);
if(targetStr == "gateway"){
if(msg == "getNodes") {
client->publish("mesh/from/gateway", net->mesh.subConnectionJson().c_str());
}
} else if(targetStr == "broadcast") {
net->mesh.sendBroadcast(msg);
} else {
uint32_t target = strtoul(targetStr.c_str(), NULL, 10);
if(net->mesh.isConnected(target)){
net->mesh.sendSingle(target, msg);
} else {
client->publish("mesh/from/gateway", "Client not connected!");
}
}
}
};
#endif

View File

@@ -0,0 +1,29 @@
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STD_FUNCTION
#include "Network.h"
#include "MeshNet.h"
#include "Sprocket.h"
#include "AppStack.h"
#include "MqttMeshBridge.h"
#define SERIAL_BAUD_RATE 115200
#define STARTUP_DELAY 3000
SprocketConfig config = { SERIAL_BAUD_RATE };
Sprocket sprocket;
MeshNet net;
MqttMeshBridge app;
void setup() {
delay(STARTUP_DELAY);
sprocket.init(config);
sprocket.join(net, app);
}
void loop() {
net.update();
sprocket.loop();
yield();
}