update Code
This commit is contained in:
parent
3c47103b39
commit
a641fad56c
119 changed files with 10997 additions and 5 deletions
53
libraries/PubSubClientTools/MqttWildcard.cpp
Normal file
53
libraries/PubSubClientTools/MqttWildcard.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include "MqttWildcard.h"
|
||||
|
||||
int MqttWildcard::explode(String *results, String source, char delimiter) {
|
||||
int count = 0;
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < source.length(); i++) {
|
||||
if (source.charAt(i) == delimiter) {
|
||||
results[count++] = source.substring(index, i);
|
||||
index = i+1;
|
||||
}
|
||||
}
|
||||
results[count++] = source.substring(index);
|
||||
|
||||
return count;
|
||||
}
|
||||
bool MqttWildcard::wildcardMatch(String topic, String wildcard) {
|
||||
// Catch trivial matches
|
||||
if (topic == wildcard) return true;
|
||||
if (wildcard == "#") return true;
|
||||
|
||||
String exploded_topic[TOPIC_BUFFER_SIZE];
|
||||
int exploded_topic_count = MqttWildcard::explode(exploded_topic, topic, '/');
|
||||
|
||||
String exploded_wildcard[TOPIC_BUFFER_SIZE];
|
||||
int exploded_wildcard_count = MqttWildcard::explode(exploded_wildcard, wildcard, '/');
|
||||
|
||||
// Impossible to match since wildcard "+/+/#" is not matched by topic foo/bar
|
||||
if (exploded_wildcard_count > exploded_topic_count) return false;
|
||||
|
||||
int match_count = 0;
|
||||
for (int i = 0; i < exploded_wildcard_count; i++) {
|
||||
if (exploded_wildcard[i] == "+") {
|
||||
continue;
|
||||
}
|
||||
if (exploded_wildcard[i] == "#") {
|
||||
return true;
|
||||
}
|
||||
if (exploded_wildcard[i] != exploded_topic[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If this point is reached and we did not return yet,
|
||||
topic- and wildcard-depth must be equal, otherwise it cant't be a valid match:
|
||||
topic: foo/bar/example
|
||||
wildcard_1: foo/bar/+
|
||||
wildcard_2: foo/+
|
||||
Both wildcards would make it to this point, bot only wildcard_1 would be a valid match.
|
||||
*/
|
||||
return (exploded_wildcard_count == exploded_topic_count);
|
||||
}
|
17
libraries/PubSubClientTools/MqttWildcard.h
Normal file
17
libraries/PubSubClientTools/MqttWildcard.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef MqttWildcard_h
|
||||
#define MqttWildcard_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <PubSubClientTools.h>
|
||||
|
||||
#ifndef TOPIC_BUFFER_SIZE
|
||||
#define TOPIC_BUFFER_SIZE 100
|
||||
#endif
|
||||
|
||||
class MqttWildcard {
|
||||
public:
|
||||
static int explode(String *results, String source, char delimiter);
|
||||
static bool wildcardMatch(String topic, String wildcard);
|
||||
};
|
||||
|
||||
#endif
|
83
libraries/PubSubClientTools/PubSubClientTools.cpp
Normal file
83
libraries/PubSubClientTools/PubSubClientTools.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "PubSubClientTools.h"
|
||||
|
||||
// Public
|
||||
PubSubClientTools::PubSubClientTools(PubSubClient& _pubSub) : pubSub(_pubSub) {
|
||||
pubSub.setCallback(mqtt_callback);
|
||||
};
|
||||
|
||||
bool PubSubClientTools::connected() {
|
||||
return pubSub.connected();
|
||||
}
|
||||
bool PubSubClientTools::connect(String clientId) {
|
||||
char client_char[CLIENTID_BUFFER_SIZE];
|
||||
clientId.toCharArray(client_char, CLIENTID_BUFFER_SIZE);
|
||||
return pubSub.connect(client_char);
|
||||
}
|
||||
bool PubSubClientTools::connect(String clientId, String willTopic, int willQoS, bool willRetain, String willMessage) {
|
||||
char client_char[CLIENTID_BUFFER_SIZE];
|
||||
char topic_char[TOPIC_BUFFER_SIZE];
|
||||
char msg_char[MESSAGE_BUFFER_SIZE];
|
||||
|
||||
clientId.toCharArray(client_char, CLIENTID_BUFFER_SIZE);
|
||||
willTopic.toCharArray(topic_char, TOPIC_BUFFER_SIZE);
|
||||
willMessage.toCharArray(msg_char, MESSAGE_BUFFER_SIZE);
|
||||
|
||||
return pubSub.connect(client_char, topic_char, willQoS, willRetain, msg_char);
|
||||
}
|
||||
|
||||
bool PubSubClientTools::publish(String topic, String message) {
|
||||
return this->publish(topic, message, false);
|
||||
}
|
||||
bool PubSubClientTools::publish(String topic, String message, bool retained) {
|
||||
char topic_char[TOPIC_BUFFER_SIZE];
|
||||
char msg_char[MESSAGE_BUFFER_SIZE];
|
||||
|
||||
topic.toCharArray(topic_char, TOPIC_BUFFER_SIZE);
|
||||
message.toCharArray(msg_char, MESSAGE_BUFFER_SIZE);
|
||||
|
||||
return pubSub.publish(topic_char, msg_char, retained);
|
||||
}
|
||||
|
||||
bool PubSubClientTools::subscribe(String topic, CALLBACK_SIGNATURE) {
|
||||
if (callbackCount >= CALLBACK_LIST_SIZE) return false;
|
||||
|
||||
char topic_char[TOPIC_BUFFER_SIZE];
|
||||
topic.toCharArray(topic_char, TOPIC_BUFFER_SIZE);
|
||||
|
||||
callbackList[callbackCount].topic = topic;
|
||||
callbackList[callbackCount].callback = callback;
|
||||
callbackCount++;
|
||||
|
||||
return pubSub.subscribe(topic_char);
|
||||
}
|
||||
|
||||
int PubSubClientTools::resubscribe() {
|
||||
int count = 0;
|
||||
|
||||
pubSub.setCallback(mqtt_callback);
|
||||
|
||||
for (int i = 0; i < callbackCount; i++) {
|
||||
char topic_char[TOPIC_BUFFER_SIZE];
|
||||
callbackList[i].topic.toCharArray(topic_char, TOPIC_BUFFER_SIZE);
|
||||
|
||||
if ( pubSub.subscribe(topic_char) ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Private
|
||||
void PubSubClientTools::callback(PUBSUBCLIENT_CALLBACK_PARAMETERS) {
|
||||
String topic = String(topicChar);
|
||||
String message = "";
|
||||
for (int i = 0; i < length; i++) {
|
||||
message += (char)payload[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < callbackCount; i++) {
|
||||
if (MqttWildcard::wildcardMatch(topic, callbackList[i].topic)) {
|
||||
(*callbackList[i].callback)(topic,message);
|
||||
}
|
||||
}
|
||||
}
|
59
libraries/PubSubClientTools/PubSubClientTools.h
Normal file
59
libraries/PubSubClientTools/PubSubClientTools.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifndef PubSubClientTools_h
|
||||
#define PubSubClientTools_h
|
||||
|
||||
#if !defined(ESP8266) && !defined(ESP32)
|
||||
#warning This library was developed for ESP8266 and ESP32 microcontrollers
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "PubSubClient.h"
|
||||
#include "MqttWildcard.h"
|
||||
|
||||
#define CALLBACK_SIGNATURE void (*callback)(String topic, String message)
|
||||
#define PUBSUBCLIENT_CALLBACK_PARAMETERS char* topicChar, uint8_t* payload, unsigned int length
|
||||
|
||||
#ifndef CLIENTID_BUFFER_SIZE
|
||||
#define CLIENTID_BUFFER_SIZE 50
|
||||
#endif
|
||||
#ifndef TOPIC_BUFFER_SIZE
|
||||
#define TOPIC_BUFFER_SIZE 100
|
||||
#endif
|
||||
#ifndef MESSAGE_BUFFER_SIZE
|
||||
#define MESSAGE_BUFFER_SIZE MQTT_MAX_PACKET_SIZE
|
||||
#endif
|
||||
#ifndef CALLBACK_LIST_SIZE
|
||||
#define CALLBACK_LIST_SIZE 50
|
||||
#endif
|
||||
|
||||
struct callbackTopic {
|
||||
String topic;
|
||||
void (*callback)(String topic, String message);
|
||||
};
|
||||
|
||||
class PubSubClientTools {
|
||||
private:
|
||||
PubSubClient& pubSub;
|
||||
struct callbackTopic callbackList[CALLBACK_LIST_SIZE];
|
||||
int callbackCount = 0;
|
||||
|
||||
std::function<void(PUBSUBCLIENT_CALLBACK_PARAMETERS)> mqtt_callback = std::bind(&PubSubClientTools::callback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
void callback(PUBSUBCLIENT_CALLBACK_PARAMETERS);
|
||||
|
||||
public:
|
||||
PubSubClientTools(PubSubClient& pubSub);
|
||||
|
||||
bool connected();
|
||||
bool connect(String clientId);
|
||||
bool connect(String clientId, String willTopic, int willQoS, bool willRetain, String willMessage);
|
||||
|
||||
bool publish(String topic, String message);
|
||||
bool publish(String topic, String message, bool retained);
|
||||
|
||||
bool subscribe(String topic, CALLBACK_SIGNATURE);
|
||||
|
||||
int resubscribe();
|
||||
};
|
||||
|
||||
#endif
|
10
libraries/PubSubClientTools/README.md
Normal file
10
libraries/PubSubClientTools/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
This library provides some functions to make life easier when using PubSubClient for Arduino
|
||||
|
||||
## Examples
|
||||
|
||||
The library comes with a number of example sketches. See File > Examples > PubSubClientTools
|
||||
within the Arduino application.
|
||||
|
||||
## Credits
|
||||
|
||||
[PubSubClient](https://github.com/knolleary/pubsubclient)
|
|
@ -0,0 +1,70 @@
|
|||
#include <WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <PubSubClientTools.h>
|
||||
|
||||
#include <Thread.h> // https://github.com/ivanseidel/ArduinoThread
|
||||
#include <ThreadController.h>
|
||||
|
||||
#define WIFI_SSID "........"
|
||||
#define WIFI_PASS "........"
|
||||
#define MQTT_SERVER "broker.mqtt-dashboard.com"
|
||||
|
||||
WiFiClient espClient;
|
||||
PubSubClient client(MQTT_SERVER, 1883, espClient);
|
||||
PubSubClientTools mqtt(client);
|
||||
|
||||
ThreadController threadControl = ThreadController();
|
||||
Thread thread = Thread();
|
||||
|
||||
int value = 0;
|
||||
const String s = "";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
|
||||
// Connect to WiFi
|
||||
Serial.print(s+"Connecting to WiFi: "+WIFI_SSID+" ");
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("connected");
|
||||
|
||||
// Connect to MQTT
|
||||
Serial.print(s+"Connecting to MQTT: "+MQTT_SERVER+" ... ");
|
||||
if (client.connect("ESP32Client")) {
|
||||
Serial.println("connected");
|
||||
|
||||
mqtt.subscribe("test_in/foo/bar", topic1_subscriber);
|
||||
mqtt.subscribe("test_in/+/bar", topic2_subscriber);
|
||||
mqtt.subscribe("test_in/#", topic3_subscriber);
|
||||
} else {
|
||||
Serial.println(s+"failed, rc="+client.state());
|
||||
}
|
||||
|
||||
// Enable Thread
|
||||
thread.onRun(publisher);
|
||||
thread.setInterval(2000);
|
||||
threadControl.add(&thread);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
threadControl.run();
|
||||
}
|
||||
|
||||
void publisher() {
|
||||
++value;
|
||||
mqtt.publish("test_out/hello_world", s+"Hello World! - No. "+value);
|
||||
}
|
||||
void topic1_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 1 ["+topic+"] "+message);
|
||||
}
|
||||
void topic2_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 2 ["+topic+"] "+message);
|
||||
}
|
||||
void topic3_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 3 ["+topic+"] "+message);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <PubSubClientTools.h>
|
||||
|
||||
#include <Thread.h> // https://github.com/ivanseidel/ArduinoThread
|
||||
#include <ThreadController.h>
|
||||
|
||||
#define WIFI_SSID "........"
|
||||
#define WIFI_PASS "........"
|
||||
#define MQTT_SERVER "broker.mqtt-dashboard.com"
|
||||
|
||||
WiFiClient espClient;
|
||||
PubSubClient client(MQTT_SERVER, 1883, espClient);
|
||||
PubSubClientTools mqtt(client);
|
||||
|
||||
ThreadController threadControl = ThreadController();
|
||||
Thread thread = Thread();
|
||||
|
||||
int value = 0;
|
||||
const String s = "";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
|
||||
// Connect to WiFi
|
||||
Serial.print(s+"Connecting to WiFi: "+WIFI_SSID+" ");
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("connected");
|
||||
|
||||
// Connect to MQTT
|
||||
Serial.print(s+"Connecting to MQTT: "+MQTT_SERVER+" ... ");
|
||||
if (client.connect("ESP8266Client")) {
|
||||
Serial.println("connected");
|
||||
|
||||
mqtt.subscribe("test_in/foo/bar", topic1_subscriber);
|
||||
mqtt.subscribe("test_in/+/bar", topic2_subscriber);
|
||||
mqtt.subscribe("test_in/#", topic3_subscriber);
|
||||
} else {
|
||||
Serial.println(s+"failed, rc="+client.state());
|
||||
}
|
||||
|
||||
// Enable Thread
|
||||
thread.onRun(publisher);
|
||||
thread.setInterval(2000);
|
||||
threadControl.add(&thread);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
threadControl.run();
|
||||
}
|
||||
|
||||
void publisher() {
|
||||
++value;
|
||||
mqtt.publish("test_out/hello_world", s+"Hello World! - No. "+value);
|
||||
}
|
||||
void topic1_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 1 ["+topic+"] "+message);
|
||||
}
|
||||
void topic2_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 2 ["+topic+"] "+message);
|
||||
}
|
||||
void topic3_subscriber(String topic, String message) {
|
||||
Serial.println(s+"Message arrived in function 3 ["+topic+"] "+message);
|
||||
}
|
21
libraries/PubSubClientTools/keywords.txt
Normal file
21
libraries/PubSubClientTools/keywords.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
#######################################
|
||||
# Syntax Coloring
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
PubSubClientTools KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
publish KEYWORD2
|
||||
subscribe KEYWORD2
|
||||
resubscribe KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
9
libraries/PubSubClientTools/library.properties
Normal file
9
libraries/PubSubClientTools/library.properties
Normal file
|
@ -0,0 +1,9 @@
|
|||
name=PubSubClientTools
|
||||
version=0.6
|
||||
author=Simon Christmann <simon@christmann.email>
|
||||
maintainer=Simon Christmann <simon@christmann.email>
|
||||
sentence=Tools for easier usage of PubSubClient
|
||||
paragraph=Provides useful tools for PubSubClient, however they may consume more power and storage. Therefore it's recommended for powerful microcontrollers like ESP8266.
|
||||
category=Communication
|
||||
url=https://github.com/dersimn/ArduinoPubSubClientTools
|
||||
architectures=*
|
Loading…
Add table
Add a link
Reference in a new issue