mirror of
https://gitlab.com/wirelos/sprocket-lib.git
synced 2025-12-15 21:18:21 +01:00
mesh mqtt gateway example
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
; http://docs.platformio.org/page/projectconf.html
|
; http://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
env_default = mesh
|
env_default = meshMqttBridge
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
@@ -34,7 +34,7 @@ lib_deps = ${common.lib_deps}
|
|||||||
;upload_port = 192.168.1.168
|
;upload_port = 192.168.1.168
|
||||||
|
|
||||||
[env:basic]
|
[env:basic]
|
||||||
src_filter = +<*> +<examples/basic/> -<examples/mesh/>
|
src_filter = +<*> +<examples/basic/> -<examples/mesh/> -<examples/mqttBridge/>
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp12e
|
board = esp12e
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
@@ -45,11 +45,22 @@ lib_deps = ${common.lib_deps}
|
|||||||
|
|
||||||
|
|
||||||
[env:mesh]
|
[env:mesh]
|
||||||
src_filter = +<*> +<examples/mesh/> -<examples/basic/>
|
src_filter = +<*> +<examples/mesh/> -<examples/basic/> -<examples/mqttBridge/>
|
||||||
platform = espressif8266
|
platform = espressif8266
|
||||||
board = esp12e
|
board = esp12e
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
monitor_baud = 115200
|
monitor_baud = 115200
|
||||||
framework = ${common.framework}
|
framework = ${common.framework}
|
||||||
lib_deps = ${common.lib_deps}
|
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
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define __MESHNET_H__
|
#define __MESHNET_H__
|
||||||
|
|
||||||
#include <painlessMesh.h>
|
#include <painlessMesh.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
#include "Network.h"
|
#include "Network.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -13,15 +13,13 @@ using namespace std::placeholders;
|
|||||||
#define MESH_PASSWORD "somethingSneaky"
|
#define MESH_PASSWORD "somethingSneaky"
|
||||||
#define MESH_PORT 5555
|
#define MESH_PORT 5555
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MeshNet : public Network {
|
class MeshNet : public Network {
|
||||||
public:
|
public:
|
||||||
painlessMesh mesh;
|
painlessMesh mesh;
|
||||||
Network* init(){
|
Network* init(){
|
||||||
Serial.println("init mesh");
|
Serial.println("init mesh");
|
||||||
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
|
//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.init( MESH_PREFIX, MESH_PASSWORD, scheduler, MESH_PORT, WIFI_AP_STA, 11 );
|
||||||
//mesh.onReceive(bind(&MeshNet::receivedCallback,this, _1, _2));
|
//mesh.onReceive(bind(&MeshNet::receivedCallback,this, _1, _2));
|
||||||
mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1));
|
mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1));
|
||||||
@@ -31,6 +29,9 @@ class MeshNet : public Network {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
Network* connect(){
|
Network* connect(){
|
||||||
|
Serial.println("connect station");
|
||||||
|
mesh.stationManual("tErAx1d", "ramalamadingdong");
|
||||||
|
mesh.setHostname("MeshNode");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
void broadcast(String msg){
|
void broadcast(String msg){
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <TaskSchedulerDeclarations.h>
|
#include <TaskSchedulerDeclarations.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
|
||||||
class Network {
|
class Network {
|
||||||
public:
|
public:
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
Network(){}
|
Network(){}
|
||||||
Scheduler* scheduler;
|
Scheduler* scheduler;
|
||||||
|
//WiFiClient wifiClient;
|
||||||
virtual Network* init() { return this; };
|
virtual Network* init() { return this; };
|
||||||
virtual Network* connect() { return this; };
|
virtual Network* connect() { return this; };
|
||||||
virtual void update() {};
|
virtual void update() {};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <painlessMesh.h>
|
#include <painlessMesh.h>
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
|
#include "MeshNet.h"
|
||||||
|
|
||||||
#define MESH_PREFIX "whateverYouLike"
|
#define MESH_PREFIX "whateverYouLike"
|
||||||
#define MESH_PASSWORD "somethingSneaky"
|
#define MESH_PASSWORD "somethingSneaky"
|
||||||
@@ -17,18 +18,21 @@ class MeshApp : public App {
|
|||||||
MeshNet* net;
|
MeshNet* net;
|
||||||
MeshApp() /* : App(sprkt) */ {
|
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){
|
void advertise(MeshNet* network){
|
||||||
String msg = "Hi, my name is " + String(network->id);
|
String msg = "Hi, my name is " + String(network->id);
|
||||||
network->broadcast(msg);
|
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 ) {
|
void receivedCallback( uint32_t from, String &msg ) {
|
||||||
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
|
Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
101
src/examples/mqttBridge/MqttMeshBridge.h
Normal file
101
src/examples/mqttBridge/MqttMeshBridge.h
Normal 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
|
||||||
29
src/examples/mqttBridge/bridge.cpp
Normal file
29
src/examples/mqttBridge/bridge.cpp
Normal 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();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user