update Code

This commit is contained in:
Siwat Sirichai 2019-08-09 09:17:05 +07:00
parent 3c47103b39
commit a641fad56c
119 changed files with 10997 additions and 5 deletions

View 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);
}

View 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

View 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);
}
}
}

View 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

View 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)

View file

@ -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);
}

View file

@ -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);
}

View file

@ -0,0 +1,21 @@
#######################################
# Syntax Coloring
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
PubSubClientTools KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
publish KEYWORD2
subscribe KEYWORD2
resubscribe KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View 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=*