mirror of
https://gitlab.com/wirelos/sprocket-plugin-mqtt.git
synced 2025-12-14 13:51:27 +01:00
hardcode in/out topics, add chat example
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
[platformio]
|
[platformio]
|
||||||
env_default = basic
|
env_default = basic, chat
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
@@ -23,5 +23,15 @@ board = ${common.board}
|
|||||||
upload_speed = ${common.upload_speed}
|
upload_speed = ${common.upload_speed}
|
||||||
monitor_baud = ${common.monitor_baud}
|
monitor_baud = ${common.monitor_baud}
|
||||||
framework = ${common.framework}
|
framework = ${common.framework}
|
||||||
|
lib_deps = ${common.lib_deps}
|
||||||
|
PubSubClient
|
||||||
|
|
||||||
|
[env:chat]
|
||||||
|
src_filter = +<*> -<examples/> +<examples/chat/>
|
||||||
|
platform = ${common.platform}
|
||||||
|
board = ${common.board}
|
||||||
|
upload_speed = ${common.upload_speed}
|
||||||
|
monitor_baud = ${common.monitor_baud}
|
||||||
|
framework = ${common.framework}
|
||||||
lib_deps = ${common.lib_deps}
|
lib_deps = ${common.lib_deps}
|
||||||
PubSubClient
|
PubSubClient
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
#define JSON_MQTT_CLIENT_NAME "mqttClientName"
|
#define JSON_MQTT_CLIENT_NAME "mqttClientName"
|
||||||
#define JSON_MQTT_BROKER_HOST "mqttBrokerHost"
|
#define JSON_MQTT_BROKER_HOST "mqttBrokerHost"
|
||||||
#define JSON_MQTT_BROKER_PORT "mqttBrokerPort"
|
#define JSON_MQTT_BROKER_PORT "mqttBrokerPort"
|
||||||
#define JSON_MQTT_IN_TOPIC_ROOT "mqttInTopicRoot"
|
#define JSON_MQTT_TOPIC_ROOT "mqttTopicRoot"
|
||||||
#define JSON_MQTT_OUT_TOPIC_ROOT "mqttOutTopicRoot"
|
#define JSON_MQTT_OUT_TOPIC_ROOT "mqttOutTopicRoot"
|
||||||
|
|
||||||
struct MqttConfig
|
struct MqttConfig
|
||||||
@@ -14,8 +14,7 @@ struct MqttConfig
|
|||||||
const char *clientName;
|
const char *clientName;
|
||||||
const char *brokerHost;
|
const char *brokerHost;
|
||||||
int brokerPort;
|
int brokerPort;
|
||||||
const char *inTopicRoot;
|
const char *topicRoot;
|
||||||
const char *outTopicRoot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MqttConfigJson : public MqttConfig, public JsonStruct
|
struct MqttConfigJson : public MqttConfig, public JsonStruct
|
||||||
@@ -25,8 +24,7 @@ struct MqttConfigJson : public MqttConfig, public JsonStruct
|
|||||||
root[JSON_MQTT_CLIENT_NAME] = clientName;
|
root[JSON_MQTT_CLIENT_NAME] = clientName;
|
||||||
root[JSON_MQTT_BROKER_HOST] = brokerHost;
|
root[JSON_MQTT_BROKER_HOST] = brokerHost;
|
||||||
root[JSON_MQTT_BROKER_PORT] = brokerPort;
|
root[JSON_MQTT_BROKER_PORT] = brokerPort;
|
||||||
root[JSON_MQTT_IN_TOPIC_ROOT] = inTopicRoot;
|
root[JSON_MQTT_TOPIC_ROOT] = topicRoot;
|
||||||
root[JSON_MQTT_OUT_TOPIC_ROOT] = outTopicRoot;
|
|
||||||
}
|
}
|
||||||
void fromJsonObject(JsonObject &json)
|
void fromJsonObject(JsonObject &json)
|
||||||
{
|
{
|
||||||
@@ -39,8 +37,7 @@ struct MqttConfigJson : public MqttConfig, public JsonStruct
|
|||||||
clientName = getAttr(json, JSON_MQTT_CLIENT_NAME);
|
clientName = getAttr(json, JSON_MQTT_CLIENT_NAME);
|
||||||
brokerHost = getAttr(json, JSON_MQTT_BROKER_HOST);
|
brokerHost = getAttr(json, JSON_MQTT_BROKER_HOST);
|
||||||
brokerPort = getIntAttrFromJson(json, JSON_MQTT_BROKER_PORT);
|
brokerPort = getIntAttrFromJson(json, JSON_MQTT_BROKER_PORT);
|
||||||
inTopicRoot = getAttr(json, JSON_MQTT_IN_TOPIC_ROOT);
|
topicRoot = getAttr(json, JSON_MQTT_TOPIC_ROOT);
|
||||||
outTopicRoot = getAttr(json, JSON_MQTT_OUT_TOPIC_ROOT);
|
|
||||||
valid = 1;
|
valid = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#include "MqttPlugin.h"
|
#include "MqttPlugin.h"
|
||||||
|
|
||||||
MqttPlugin::MqttPlugin(MqttConfig cfg)
|
MqttPlugin::MqttPlugin(MqttConfig cfg, bool bindUp, bool bindDown)
|
||||||
{
|
{
|
||||||
|
bindUpstream = bindUp;
|
||||||
|
bindDownstream = bindDown;
|
||||||
applyConfig(cfg);
|
applyConfig(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,8 +11,7 @@ void MqttPlugin::applyConfig(MqttConfig cfg) {
|
|||||||
brokerHost = String(cfg.brokerHost);
|
brokerHost = String(cfg.brokerHost);
|
||||||
brokerPort = cfg.brokerPort;
|
brokerPort = cfg.brokerPort;
|
||||||
clientName = String(cfg.clientName);
|
clientName = String(cfg.clientName);
|
||||||
inTopicRoot = String(cfg.inTopicRoot);
|
topicRoot = String(cfg.topicRoot);
|
||||||
outTopicRoot = String(cfg.outTopicRoot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttPlugin::applyConfigFromFile(const char* fileName) {
|
void MqttPlugin::applyConfigFromFile(const char* fileName) {
|
||||||
@@ -57,16 +58,22 @@ void MqttPlugin::connect()
|
|||||||
{
|
{
|
||||||
for (auto const &localSub : mediator->subscriptions)
|
for (auto const &localSub : mediator->subscriptions)
|
||||||
{
|
{
|
||||||
// bind all local topics to the MQTT upstream once
|
if(bindUpstream){
|
||||||
subscribe(localSub.first.c_str(), bind(&MqttPlugin::upstreamHandler, this, localSub.first.c_str(), _1));
|
// bind all local topics to the MQTT upstream once
|
||||||
// subscribe topic on remote queue to dispatch messages to local subscriptions
|
subscribe(localSub.first.c_str(), bind(&MqttPlugin::upstreamHandler, this, localSub.first.c_str(), _1));
|
||||||
client->subscribe(
|
}
|
||||||
(inTopicRoot + String(localSub.first.c_str()))
|
if(bindDownstream){
|
||||||
.c_str());
|
// subscribe topic on remote queue to dispatch messages to local subscriptions
|
||||||
|
client->subscribe(
|
||||||
|
(topicRoot + String("/in/") + String(localSub.first.c_str())).c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
subscribed = true;
|
subscribed = true;
|
||||||
}
|
}
|
||||||
|
publish("mqtt/connect", clientName);
|
||||||
PRINT_MSG(Serial, "MQTT", "connected");
|
PRINT_MSG(Serial, "MQTT", "connected");
|
||||||
|
} else {
|
||||||
|
PRINT_MSG(Serial, "MQTT", "connect failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,10 +81,9 @@ void MqttPlugin::connect()
|
|||||||
void MqttPlugin::upstreamHandler(String topic, String msg)
|
void MqttPlugin::upstreamHandler(String topic, String msg)
|
||||||
{
|
{
|
||||||
// publish message on remote queue
|
// publish message on remote queue
|
||||||
String remoteTopic = outTopicRoot + topic;
|
String remoteTopic = topicRoot + String("/out/") + topic;
|
||||||
Serial.println(remoteTopic);
|
|
||||||
client->publish(remoteTopic.c_str(), msg.c_str());
|
client->publish(remoteTopic.c_str(), msg.c_str());
|
||||||
PRINT_MSG(Serial, "MQTT", remoteTopic.c_str());
|
PRINT_MSG(Serial, "MQTT", String("pub: "+ remoteTopic).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttPlugin::downstreamHandler(char *topic, uint8_t *payload, unsigned int length)
|
void MqttPlugin::downstreamHandler(char *topic, uint8_t *payload, unsigned int length)
|
||||||
@@ -88,10 +94,22 @@ void MqttPlugin::downstreamHandler(char *topic, uint8_t *payload, unsigned int l
|
|||||||
String msg = String(cleanPayload);
|
String msg = String(cleanPayload);
|
||||||
free(cleanPayload);
|
free(cleanPayload);
|
||||||
|
|
||||||
// substract the topic root and publish msg on local topic
|
// substract the topic root + "/in/" and publish msg on local topic
|
||||||
int topicRootLength = inTopicRoot.length();
|
String topicStr = String(topic);
|
||||||
String localTopic = String(topic).substring(topicRootLength);
|
int topicRootLength = topicRoot.length();
|
||||||
publish(localTopic, msg);
|
if(topicStr.length() > topicRootLength){
|
||||||
|
String localTopic = topicStr.substring(topicRootLength);
|
||||||
|
if(localTopic.length() > 4){
|
||||||
|
String direction = localTopic.substring(0,4);
|
||||||
|
if(direction == "/in/" ){
|
||||||
|
String localSubTopic = localTopic.substring(direction.length());
|
||||||
|
publish(localSubTopic, msg);
|
||||||
|
PRINT_MSG(Serial, "MQTT", (String("publish /in/: ") + localSubTopic).c_str());
|
||||||
|
} else {
|
||||||
|
publish(localTopic, msg);
|
||||||
|
PRINT_MSG(Serial, "MQTT", (String("publish mediator: ") + localTopic).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRINT_MSG(Serial, "MQTT", (String("publish local: ") + localTopic).c_str());
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class MqttPlugin : public Plugin
|
|||||||
public:
|
public:
|
||||||
PubSubClient *client;
|
PubSubClient *client;
|
||||||
|
|
||||||
MqttPlugin(MqttConfig cfg);
|
MqttPlugin(MqttConfig cfg, bool bindUp = true, bool bindDown = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to queue and triggers connect and process task.
|
* Connects to queue and triggers connect and process task.
|
||||||
@@ -31,11 +31,12 @@ class MqttPlugin : public Plugin
|
|||||||
Task connectTask;
|
Task connectTask;
|
||||||
Task processTask;
|
Task processTask;
|
||||||
bool subscribed = false;
|
bool subscribed = false;
|
||||||
|
bool bindUpstream = false;
|
||||||
|
bool bindDownstream = false;
|
||||||
String brokerHost;
|
String brokerHost;
|
||||||
int brokerPort;
|
int brokerPort;
|
||||||
String clientName;
|
String clientName;
|
||||||
String inTopicRoot;
|
String topicRoot;
|
||||||
String outTopicRoot;
|
|
||||||
|
|
||||||
void applyConfig(MqttConfig cfg);
|
void applyConfig(MqttConfig cfg);
|
||||||
void applyConfigFromFile(const char* fileName);
|
void applyConfigFromFile(const char* fileName);
|
||||||
@@ -46,20 +47,20 @@ class MqttPlugin : public Plugin
|
|||||||
* to the corresponding topic on the remote queue by prefixing the topic with inRootTopic.
|
* to the corresponding topic on the remote queue by prefixing the topic with inRootTopic.
|
||||||
* Creates shadow subscriptions of every local topic to propagate messages to the remote queue via upstreamHandler.
|
* Creates shadow subscriptions of every local topic to propagate messages to the remote queue via upstreamHandler.
|
||||||
*/
|
*/
|
||||||
void connect();
|
virtual void connect();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The upstream handler is bound to every local subscription.
|
* The upstream handler is bound to every local subscription.
|
||||||
* It passes the message to the remote queue by prefixing the outRootTopic.
|
* It passes the message to the remote queue by prefixing the outRootTopic.
|
||||||
*/
|
*/
|
||||||
void upstreamHandler(String topic, String msg);
|
virtual void upstreamHandler(String topic, String msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The downstream handler is bound to the remote counterpart of local subscriptions,
|
* The downstream handler is bound to the remote counterpart of local subscriptions,
|
||||||
* prefixed with inRootTopic.
|
* prefixed with inRootTopic.
|
||||||
* Everything after the prefix is used as local topic and dispatched to local subscriptions.
|
* Everything after the prefix is used as local topic and dispatched to local subscriptions.
|
||||||
*/
|
*/
|
||||||
void downstreamHandler(char *topic, uint8_t *payload, unsigned int length);
|
virtual void downstreamHandler(char *topic, uint8_t *payload, unsigned int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
38
src/examples/chat/config.h
Normal file
38
src/examples/chat/config.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef __DEVICE_CONFIG__
|
||||||
|
#define __DEVICE_CONFIG__
|
||||||
|
|
||||||
|
// Scheduler config
|
||||||
|
#define _TASK_SLEEP_ON_IDLE_RUN
|
||||||
|
#define _TASK_STD_FUNCTION
|
||||||
|
#define _TASK_PRIORITY
|
||||||
|
|
||||||
|
// Chip config
|
||||||
|
#define SPROCKET_TYPE "SPROCKET"
|
||||||
|
#define SERIAL_BAUD_RATE 115200
|
||||||
|
#define STARTUP_DELAY 1000
|
||||||
|
|
||||||
|
// network config
|
||||||
|
#define SPROCKET_MODE 1
|
||||||
|
#define WIFI_CHANNEL 11
|
||||||
|
#define MESH_PORT 5555
|
||||||
|
#define AP_SSID "sprocket"
|
||||||
|
#define AP_PASSWORD "th3r31sn0sp00n"
|
||||||
|
#define MESH_PREFIX "sprocket-mesh"
|
||||||
|
#define MESH_PASSWORD "th3r31sn0sp00n"
|
||||||
|
#define STATION_SSID "MyAP"
|
||||||
|
#define STATION_PASSWORD "th3r31sn0sp00n"
|
||||||
|
#define HOSTNAME "sprocket"
|
||||||
|
#define CONNECT_TIMEOUT 10000
|
||||||
|
#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
|
||||||
|
//#define MESH_DEBUG_TYPES ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
|
||||||
|
|
||||||
|
// WebServer
|
||||||
|
#define WEB_CONTEXT_PATH "/"
|
||||||
|
#define WEB_DOC_ROOT "/www"
|
||||||
|
#define WEB_DEFAULT_FILE "index.html"
|
||||||
|
#define WEB_PORT 80
|
||||||
|
|
||||||
|
#define MQTT_CONFIG_FILE "/mqttConfig.json"
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
62
src/examples/chat/main.cpp
Normal file
62
src/examples/chat/main.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#include "config.h"
|
||||||
|
#include "WiFiNet.h"
|
||||||
|
#include "Sprocket.h"
|
||||||
|
#include "MqttPlugin.h"
|
||||||
|
|
||||||
|
WiFiNet *network;
|
||||||
|
Sprocket *sprocket;
|
||||||
|
MqttPlugin *mqttPlugin;
|
||||||
|
|
||||||
|
Task publishHeap;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE});
|
||||||
|
mqttPlugin = new MqttPlugin({"chatSprocket",
|
||||||
|
"192.168.1.2",
|
||||||
|
1883,
|
||||||
|
"wirelos/sprocket"},
|
||||||
|
true, true);
|
||||||
|
sprocket->addPlugin(mqttPlugin);
|
||||||
|
|
||||||
|
// this subscription gets shadowed by the MqttPlugin
|
||||||
|
// to rout messages to the queue on topic wirelos/sprocket/chat/log
|
||||||
|
sprocket->subscribe("chat/log", [](String msg) {
|
||||||
|
// gets routed to MQTT broker
|
||||||
|
PRINT_MSG(Serial, "CHAT", msg.c_str());
|
||||||
|
});
|
||||||
|
publishHeap.set(TASK_SECOND * 5, TASK_FOREVER, []() {
|
||||||
|
// locally publish a message
|
||||||
|
sprocket->publish("chat/log", "hi there");
|
||||||
|
});
|
||||||
|
sprocket->addTask(publishHeap);
|
||||||
|
|
||||||
|
network = new WiFiNet(
|
||||||
|
SPROCKET_MODE,
|
||||||
|
STATION_SSID,
|
||||||
|
STATION_PASSWORD,
|
||||||
|
AP_SSID,
|
||||||
|
AP_PASSWORD,
|
||||||
|
HOSTNAME,
|
||||||
|
CONNECT_TIMEOUT);
|
||||||
|
network->connect();
|
||||||
|
|
||||||
|
sprocket->activate();
|
||||||
|
|
||||||
|
sprocket->subscribe("mqtt/connect", [](String msg) {
|
||||||
|
if (msg.length() > 0)
|
||||||
|
{
|
||||||
|
mqttPlugin->client->subscribe("wirelos/sprocket/out/chat/log");
|
||||||
|
sprocket->subscribe("/out/chat/log", [](String msg){
|
||||||
|
PRINT_MSG(Serial, "CHAT", String("incoming: " +msg).c_str());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
sprocket->loop();
|
||||||
|
yield();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user