Skip to content

Commit

Permalink
Handler
Browse files Browse the repository at this point in the history
Exposing methods connect() and disconnect() from PubSubclient library
  • Loading branch information
jotathebest committed Apr 9, 2021
1 parent 278ed32 commit 487dbba
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 116 deletions.
106 changes: 56 additions & 50 deletions README.md
Expand Up @@ -19,68 +19,74 @@ MQTT library for connecting to Ubidots using MQTT protocol and an ESP8266 chip.

### Ubidots

```
Ubidots(char* token)
Ubidots(char* token, char* clientName)
```
> Creates an Ubidots instance, you must setup as input your Ubidots TOKEN, the MQTT client name is optional and must be unique so we recommend you to insert random ASCII characters if you decide to use it, if you don't pass the clientName as parameter to the constructor the library will try to get the MAC of the device as default client name.
`Ubidots(char* token)`
`Ubidots(char* token, char* clientName)`
Creates an Ubidots instance, you must setup as input your Ubidots TOKEN, the MQTT client name is optional and must be unique so we recommend you to insert random ASCII characters if you decide to use it, if you don't pass the clientName as parameter to the constructor the library will try to get the MAC of the device as default client name.

- @token, [Required]. Your Ubidots unique account [TOKEN](http://help.ubidots.com/user-guides/find-your-token-from-your-ubidots-account).
- @clientName, [Optional] [default] = device unique MAC address. The MQTT unique client id to be identified by the broker.
## Methods

### Ubidots

```
add(char* variableLabel, float value, char *context, char *timestamp);
```
> Add a variable with a value, context and timestamp to be sent to a certain data source, once you use add() you can publish your variable using the ubidotsPublish() method. You can add 5 variables maximum before of publish them.
`add(char* variableLabel, float value, char *context, char *timestamp)`
Add a variable with a value, context and timestamp to be sent to a certain data source, once you use add() you can publish your variable using the ubidotsPublish() method. You can add 5 variables maximum before of publish them.
**Important:** As this library depends on a Pubsubclient client, the max length of the JSON dictionary to send by default is 128 bytes, if you want to publish more than 3 variables and they have context or long names you should set at PubSubclient.h the MQTT_MAX_PACKET_SIZE to 512, you can see on your serial console the dictionary to POST if you call the ```setDebug(bool debug)``` method and pass a true value to it. For more information, refer to the PubSubclient official library: https://github.com/knolleary/pubsubclient
```
begin(void (*callback)(char*,uint8_t*,unsigned int));
```

> Sets the callback function for subscribed topics
```
connected();
```
> Returns True if the device is connected to the MQTT broker
```
loop();
```
> Infinite loop for MQTT connection, insert it at the end of your routine
```
reconnect();
```
> For trying to make a reconnection every 5 seconds if the connection is lost.
```
ubidotsSetBroker(char* broker);
```
> Sets the broker properly for publish and subscribe to Ubidots accounts. If your account if a business one, set "business.api.ubidots.com" or the endpoint provided by Ubidots as your broker, see examples for more information.

- @variable_label, [Required]. The label of the variable where the dot will be stored.
- @value, [Required]. The value of the dot.
- @context, [Optional]. The dot's context.
- @timestamp, [Optional]. The dot's timestamp in milliseconds.

`begin(void (*callback)(char*,uint8_t*,unsigned int))`
Sets the callback function for subscribed topics

- @callback [Mandatory] Pointer to the callback function that will process the incoming data

`connected()`
Returns True if the device is connected to the MQTT broker

`loop()`
Infinite loop for MQTT connection, insert it at the end of your routine

`reconnect()`
For trying to make a reconnection every 5 seconds if the connection is lost.

`ubidotsSetBroker(char* broker)`
Sets the broker properly for publish and subscribe to Ubidots accounts. If your account if a business one, set "business.api.ubidots.com" or the endpoint provided by Ubidots as your broker, see examples for more information.
By default, broker will be set to publish and subscribe to free educational version accounts with broker "things.ubidots.com".
```
setDebug(bool debug);;
```

> Make available debug messages through the serial port.
- @broker, [Optional] [default] = `industrial.api.ubidots.com`. The server to send data url.

`setDebug(bool debug)`
Make available debug messages through the serial port.

`ubidotsPublish(char *deviceLabel)`
Publishes the variables added to the specified device label.
- @deviceLabel [Mandatory] Device label that stores the the values to be ingested

`ubidotsSubscribe(char* deviceLabel, char* variableLabel)`
Subscribe to the specified device label and variable label of your Ubidots account.

- @deviceLabel [Mandatory] Device label that stores the variable to retrieve values from
- @variableLabel [Mandatory] Variable label to retrieve values from

`bool connect(const char* clientName, const char* username, const char* password)`
Connects to the broker using a custom client name, username and password

- @clientName, [Optional] [default] = device unique MAC address. The MQTT unique client id to be identified by the broker.
- @username, [optional] [default] = Ubidots account token used in the constructor. The username to be identified by the broker
- @password, [optional] [default] = Ubidots account token used in the constructor. The password to be identified by the broker

`void wifiConnection(char* ssid, char* pass)`
Connects to an available WiFi network using WAP2.

```
ubidotsPublish(char *deviceLabel);
```
> Publishes the variables added to the specified device label.
- @ssid [Mandatory] SSID of the network to connect to
- @pass [Mandatory] WiFi network password

```
ubidotsSubscribe(char* deviceLabel, char* variableLabel);
```
> Subscribe to the specified device label and variable label of your Ubidots account.
`void disconnect()`
Disconnects gracefully from the broker, closing the socket

```
wifiConnection(char* ssid, char* pass);
```
> Connect via Wifi to the specified SSID.

# Examples

Expand Down
2 changes: 2 additions & 0 deletions keywords.txt
Expand Up @@ -20,6 +20,8 @@ ubidotsSetBroker KEYWORD2
reconnect KEYWORD2
setDebug KEYWORD2
wifiConnection KEYWORD2
connect KEYWORD2
disconnect KEYWORD2

#######################################
# Instances (KEYWORD2)
Expand Down
181 changes: 115 additions & 66 deletions src/UbidotsESPMQTT.cpp
@@ -1,30 +1,28 @@
/*
Copyright (c) 2016 Ubidots.
Copyright (c) 2021 Ubidots.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Original Maker: Mateo Velez - Metavix for Ubidots Inc
Modified and Maintened by: Jose Garcia - Ubidots Inc
Created by: Jose Garcia
*/

/**************************************************************************
* Overloaded constructors
***************************************************************************/

#include "UbidotsESPMQTT.h"

Ubidots::Ubidots(char* token) {
Expand All @@ -36,12 +34,112 @@ Ubidots::Ubidots(char* token) {

Ubidots::Ubidots(char* token, char* clientName) { initialize(token, clientName); }

void Ubidots::begin(void (*callback)(char*, uint8_t*, unsigned int)) {
this->callback = callback;
_client.setServer(_server, MQTT_PORT);
_client.setCallback(callback);
/***************************************************************************
FUNCTIONS TO SEND/RETRIEVE DATA
***************************************************************************/

bool Ubidots::ubidotsSubscribe(char* deviceLabel, char* variableLabel) {
char topic[150];
sprintf(topic, "%s%s/%s/lv", FIRST_PART_TOPIC, deviceLabel, variableLabel);
if (!_client.connected()) {
reconnect();
}
if (_debug) {
Serial.println("Subscribed to: ");
Serial.println(topic);
}
return _client.subscribe(topic);
}

bool Ubidots::ubidotsPublish(char* deviceLabel) {
char topic[150];
char payload[500];
String str;
sprintf(topic, "%s%s", FIRST_PART_TOPIC, deviceLabel);
sprintf(payload, "{");
for (int i = 0; i <= currentValue;) {
str = String((val + i)->_value, 2);
sprintf(payload, "%s\"%s\": [{\"value\": %s", payload, (val + i)->_variableLabel, str.c_str());
if ((val + i)->_timestamp != "NULL") {
sprintf(payload, "%s, \"timestamp\": %s", payload, (val + i)->_timestamp);
}
if ((val + i)->_context != "NULL") {
sprintf(payload, "%s, \"context\": {%s}", payload, (val + i)->_context);
}
i++;
if (i >= currentValue) {
sprintf(payload, "%s}]}", payload);
break;
} else {
sprintf(payload, "%s}], ", payload);
}
}
if (_debug) {
Serial.println("publishing to TOPIC: ");
Serial.println(topic);
Serial.print("JSON dict: ");
Serial.println(payload);
}
currentValue = 0;
return _client.publish(topic, payload, 512);
}

/***************************************************************************
FUNCTIONS TO MANAGE SOCKET CONNECTION
***************************************************************************/

/**
* Overloaded connect() methods.
* Connects to the broker using a custom username and password
* @arg clientName [Optional] Unique MQTT client id
* @arg username [Mandatory] MQTT username to be identified by the broker
* @arg password [Mandatory] MQTT password to be identified by the broker
*/
bool Ubidots::connect() { return connect(_clientName, _token, _token); }
bool Ubidots::connect(const char* username, const char* password) { return connect(_clientName, username, password); }
bool Ubidots::connect(const char* clientName, const char* username, const char* password) {
bool result = _client.connect(clientName, username, password);
if (_debug) {
Serial.println("attempting to connect");
if (!result) {
Serial.print("failed, rc=");
Serial.print(_client.state());
}
}
return result;
}

bool Ubidots::connected() { return _client.connected(); }

/**
* Maintains the socket connection and sends periodically the keep alive command
*/

bool Ubidots::loop() {
if (!_client.connected()) {
reconnect();
}
return _client.loop();
}

/**
* Disconnects gracefully from the broker, closing the socket
*/
void Ubidots::disconnect() { _client.disconnect(); };

/***************************************************************************
AUXILIAR FUNCTIONS
***************************************************************************/

/**
* Add a value of variable to save
* @arg variable_label [Mandatory] variable label where the dot will be stored
* @arg value [Mandatory] Dot value
* @arg context [optional] Dot context to store. Default NULL
* @arg dot_timestamp_seconds [optional] Dot timestamp in seconds, usefull for
* datalogger. Default NULL
*/

bool Ubidots::add(char* variableLabel, float value) { return add(variableLabel, value, "NULL", "NULL"); }

bool Ubidots::add(char* variableLabel, float value, char* context) {
Expand All @@ -61,7 +159,11 @@ bool Ubidots::add(char* variableLabel, float value, char* context, char* timesta
return true;
}

bool Ubidots::connected() { return _client.connected(); }
void Ubidots::begin(void (*callback)(char*, uint8_t*, unsigned int)) {
this->callback = callback;
_client.setServer(_server, MQTT_PORT);
_client.setCallback(callback);
}

void Ubidots::initialize(char* token, char* clientName) {
_server = SERVER;
Expand All @@ -71,13 +173,6 @@ void Ubidots::initialize(char* token, char* clientName) {
_clientName = clientName;
}

bool Ubidots::loop() {
if (!_client.connected()) {
reconnect();
}
return _client.loop();
}

void Ubidots::reconnect() {
while (!_client.connected()) {
Serial.print("Attempting MQTT connection...");
Expand All @@ -102,52 +197,6 @@ void Ubidots::ubidotsSetBroker(char* broker) {
_server = broker;
}

bool Ubidots::ubidotsSubscribe(char* deviceLabel, char* variableLabel) {
char topic[150];
sprintf(topic, "%s%s/%s/lv", FIRST_PART_TOPIC, deviceLabel, variableLabel);
if (!_client.connected()) {
reconnect();
}
if (_debug) {
Serial.println("Subscribed to: ");
Serial.println(topic);
}
return _client.subscribe(topic);
}

bool Ubidots::ubidotsPublish(char* deviceLabel) {
char topic[150];
char payload[500];
String str;
sprintf(topic, "%s%s", FIRST_PART_TOPIC, deviceLabel);
sprintf(payload, "{");
for (int i = 0; i <= currentValue;) {
str = String((val + i)->_value, 2);
sprintf(payload, "%s\"%s\": [{\"value\": %s", payload, (val + i)->_variableLabel, str.c_str());
if ((val + i)->_timestamp != "NULL") {
sprintf(payload, "%s, \"timestamp\": %s", payload, (val + i)->_timestamp);
}
if ((val + i)->_context != "NULL") {
sprintf(payload, "%s, \"context\": {%s}", payload, (val + i)->_context);
}
i++;
if (i >= currentValue) {
sprintf(payload, "%s}]}", payload);
break;
} else {
sprintf(payload, "%s}], ", payload);
}
}
if (_debug) {
Serial.println("publishing to TOPIC: ");
Serial.println(topic);
Serial.print("JSON dict: ");
Serial.println(payload);
}
currentValue = 0;
return _client.publish(topic, payload, 512);
}

bool Ubidots::wifiConnection(char* ssid, char* pass) {
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
Expand Down
4 changes: 4 additions & 0 deletions src/UbidotsESPMQTT.h
Expand Up @@ -70,6 +70,10 @@ class Ubidots {
bool add(char* variableLabel, float value, char* context, char* timestamp);
void begin(void (*callback)(char*, uint8_t*, unsigned int));
bool connected();
bool connect();
bool connect(const char* username, const char* password);
bool connect(const char* clientName, const char* username, const char* password);
void disconnect();
bool loop();
bool ubidotsSubscribe(char* deviceLabel, char* variableLabel);
bool ubidotsPublish(char* deviceLabel);
Expand Down

0 comments on commit 487dbba

Please sign in to comment.