mirror of
https://gitlab.com/wirelos/sprocket-lib.git
synced 2025-12-15 05:02:21 +01:00
mesh mqtt gateway example
This commit is contained in:
@@ -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
|
||||
@@ -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){
|
||||
|
||||
@@ -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() {};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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