Add Library
This commit is contained in:
parent
e365b9dbd9
commit
3c47103b39
318 changed files with 56465 additions and 0 deletions
851
libraries/Adafruit_MQTT_Library/Adafruit_MQTT.cpp
Normal file
851
libraries/Adafruit_MQTT_Library/Adafruit_MQTT.cpp
Normal file
|
@ -0,0 +1,851 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Adafruit Industries
|
||||
//
|
||||
// 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.
|
||||
#include "Adafruit_MQTT.h"
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_ARCH_SAMD)
|
||||
static char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
|
||||
char fmt[20];
|
||||
sprintf(fmt, "%%%d.%df", width, prec);
|
||||
sprintf(sout, fmt, val);
|
||||
return sout;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
int strncasecmp(const char * str1, const char * str2, int len) {
|
||||
int d = 0;
|
||||
while(len--) {
|
||||
int c1 = tolower(*str1++);
|
||||
int c2 = tolower(*str2++);
|
||||
if(((d = c1 - c2) != 0) || (c2 == '\0')) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void printBuffer(uint8_t *buffer, uint16_t len) {
|
||||
DEBUG_PRINTER.print('\t');
|
||||
for (uint16_t i=0; i<len; i++) {
|
||||
if (isprint(buffer[i]))
|
||||
DEBUG_PRINTER.write(buffer[i]);
|
||||
else
|
||||
DEBUG_PRINTER.print(" ");
|
||||
DEBUG_PRINTER.print(F(" [0x"));
|
||||
if (buffer[i] < 0x10)
|
||||
DEBUG_PRINTER.print("0");
|
||||
DEBUG_PRINTER.print(buffer[i],HEX);
|
||||
DEBUG_PRINTER.print("], ");
|
||||
if (i % 8 == 7) {
|
||||
DEBUG_PRINTER.print("\n\t");
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTER.println();
|
||||
}
|
||||
|
||||
/* Not used now, but might be useful in the future
|
||||
static uint8_t *stringprint(uint8_t *p, char *s) {
|
||||
uint16_t len = strlen(s);
|
||||
p[0] = len >> 8; p++;
|
||||
p[0] = len & 0xFF; p++;
|
||||
memmove(p, s, len);
|
||||
return p+len;
|
||||
}
|
||||
*/
|
||||
|
||||
static uint8_t *stringprint(uint8_t *p, const char *s, uint16_t maxlen=0) {
|
||||
// If maxlen is specified (has a non-zero value) then use it as the maximum
|
||||
// length of the source string to write to the buffer. Otherwise write
|
||||
// the entire source string.
|
||||
uint16_t len = strlen(s);
|
||||
if (maxlen > 0 && len > maxlen) {
|
||||
len = maxlen;
|
||||
}
|
||||
/*
|
||||
for (uint8_t i=0; i<len; i++) {
|
||||
Serial.write(pgm_read_byte(s+i));
|
||||
}
|
||||
*/
|
||||
p[0] = len >> 8; p++;
|
||||
p[0] = len & 0xFF; p++;
|
||||
strncpy((char *)p, s, len);
|
||||
return p+len;
|
||||
}
|
||||
|
||||
|
||||
// Adafruit_MQTT Definition ////////////////////////////////////////////////////
|
||||
|
||||
Adafruit_MQTT::Adafruit_MQTT(const char *server,
|
||||
uint16_t port,
|
||||
const char *cid,
|
||||
const char *user,
|
||||
const char *pass) {
|
||||
servername = server;
|
||||
portnum = port;
|
||||
clientid = cid;
|
||||
username = user;
|
||||
password = pass;
|
||||
|
||||
// reset subscriptions
|
||||
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
subscriptions[i] = 0;
|
||||
}
|
||||
|
||||
will_topic = 0;
|
||||
will_payload = 0;
|
||||
will_qos = 0;
|
||||
will_retain = 0;
|
||||
|
||||
packet_id_counter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Adafruit_MQTT::Adafruit_MQTT(const char *server,
|
||||
uint16_t port,
|
||||
const char *user,
|
||||
const char *pass) {
|
||||
servername = server;
|
||||
portnum = port;
|
||||
clientid = "";
|
||||
username = user;
|
||||
password = pass;
|
||||
|
||||
// reset subscriptions
|
||||
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
subscriptions[i] = 0;
|
||||
}
|
||||
|
||||
will_topic = 0;
|
||||
will_payload = 0;
|
||||
will_qos = 0;
|
||||
will_retain = 0;
|
||||
|
||||
packet_id_counter = 0;
|
||||
|
||||
}
|
||||
|
||||
int8_t Adafruit_MQTT::connect() {
|
||||
// Connect to the server.
|
||||
if (!connectServer())
|
||||
return -1;
|
||||
|
||||
// Construct and send connect packet.
|
||||
uint8_t len = connectPacket(buffer);
|
||||
if (!sendPacket(buffer, len))
|
||||
return -1;
|
||||
|
||||
// Read connect response packet and verify it
|
||||
len = readFullPacket(buffer, MAXBUFFERSIZE, CONNECT_TIMEOUT_MS);
|
||||
if (len != 4)
|
||||
return -1;
|
||||
if ((buffer[0] != (MQTT_CTRL_CONNECTACK << 4)) || (buffer[1] != 2))
|
||||
return -1;
|
||||
if (buffer[3] != 0)
|
||||
return buffer[3];
|
||||
|
||||
// Setup subscriptions once connected.
|
||||
for (uint8_t i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
// Ignore subscriptions that aren't defined.
|
||||
if (subscriptions[i] == 0) continue;
|
||||
|
||||
boolean success = false;
|
||||
for (uint8_t retry=0; (retry<3) && !success; retry++) { // retry until we get a suback
|
||||
// Construct and send subscription packet.
|
||||
uint8_t len = subscribePacket(buffer, subscriptions[i]->topic, subscriptions[i]->qos);
|
||||
if (!sendPacket(buffer, len))
|
||||
return -1;
|
||||
|
||||
if(MQTT_PROTOCOL_LEVEL < 3) // older versions didn't suback
|
||||
break;
|
||||
|
||||
// Check for SUBACK if using MQTT 3.1.1 or higher
|
||||
// TODO: The Server is permitted to start sending PUBLISH packets matching the
|
||||
// Subscription before the Server sends the SUBACK Packet. (will really need to use callbacks - ada)
|
||||
|
||||
//Serial.println("\t**looking for suback");
|
||||
if (processPacketsUntil(buffer, MQTT_CTRL_SUBACK, SUBACK_TIMEOUT_MS)) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! success) return -2; // failed to sub for some reason
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t Adafruit_MQTT::connect(const char *user, const char *pass)
|
||||
{
|
||||
username = user;
|
||||
password = pass;
|
||||
return connect();
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MQTT::processPacketsUntil(uint8_t *buffer, uint8_t waitforpackettype, uint16_t timeout) {
|
||||
uint16_t len;
|
||||
|
||||
while(true) {
|
||||
len = readFullPacket(buffer, MAXBUFFERSIZE, timeout);
|
||||
|
||||
if(len == 0){
|
||||
break;
|
||||
}
|
||||
|
||||
if ((buffer[0] >> 4) == waitforpackettype)
|
||||
{
|
||||
return len;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_PRINTLN(F("Dropped a packet"));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize, uint16_t timeout) {
|
||||
// will read a packet and Do The Right Thing with length
|
||||
uint8_t *pbuff = buffer;
|
||||
|
||||
uint8_t rlen;
|
||||
|
||||
// read the packet type:
|
||||
rlen = readPacket(pbuff, 1, timeout);
|
||||
if (rlen != 1) return 0;
|
||||
|
||||
DEBUG_PRINT(F("Packet Type:\t")); DEBUG_PRINTBUFFER(pbuff, rlen);
|
||||
pbuff++;
|
||||
|
||||
uint32_t value = 0;
|
||||
uint32_t multiplier = 1;
|
||||
uint8_t encodedByte;
|
||||
|
||||
do {
|
||||
rlen = readPacket(pbuff, 1, timeout);
|
||||
if (rlen != 1) return 0;
|
||||
encodedByte = pbuff[0]; // save the last read val
|
||||
pbuff++; // get ready for reading the next byte
|
||||
uint32_t intermediate = encodedByte & 0x7F;
|
||||
intermediate *= multiplier;
|
||||
value += intermediate;
|
||||
multiplier *= 128;
|
||||
if (multiplier > (128UL*128UL*128UL)) {
|
||||
DEBUG_PRINT(F("Malformed packet len\n"));
|
||||
return 0;
|
||||
}
|
||||
} while (encodedByte & 0x80);
|
||||
|
||||
DEBUG_PRINT(F("Packet Length:\t")); DEBUG_PRINTLN(value);
|
||||
|
||||
if (value > (maxsize - (pbuff-buffer) - 1)) {
|
||||
DEBUG_PRINTLN(F("Packet too big for buffer"));
|
||||
rlen = readPacket(pbuff, (maxsize - (pbuff-buffer) - 1), timeout);
|
||||
} else {
|
||||
rlen = readPacket(pbuff, value, timeout);
|
||||
}
|
||||
//DEBUG_PRINT(F("Remaining packet:\t")); DEBUG_PRINTBUFFER(pbuff, rlen);
|
||||
|
||||
return ((pbuff - buffer)+rlen);
|
||||
}
|
||||
|
||||
const __FlashStringHelper* Adafruit_MQTT::connectErrorString(int8_t code) {
|
||||
switch (code) {
|
||||
case 1: return F("The Server does not support the level of the MQTT protocol requested");
|
||||
case 2: return F("The Client identifier is correct UTF-8 but not allowed by the Server");
|
||||
case 3: return F("The MQTT service is unavailable");
|
||||
case 4: return F("The data in the user name or password is malformed");
|
||||
case 5: return F("Not authorized to connect");
|
||||
case 6: return F("Exceeded reconnect rate limit. Please try again later.");
|
||||
case 7: return F("You have been banned from connecting. Please contact the MQTT server administrator for more details.");
|
||||
case -1: return F("Connection failed");
|
||||
case -2: return F("Failed to subscribe");
|
||||
default: return F("Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::disconnect() {
|
||||
|
||||
// Construct and send disconnect packet.
|
||||
uint8_t len = disconnectPacket(buffer);
|
||||
if (! sendPacket(buffer, len))
|
||||
DEBUG_PRINTLN(F("Unable to send disconnect packet"));
|
||||
|
||||
return disconnectServer();
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Adafruit_MQTT::publish(const char *topic, const char *data, uint8_t qos) {
|
||||
return publish(topic, (uint8_t*)(data), strlen(data), qos);
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::publish(const char *topic, uint8_t *data, uint16_t bLen, uint8_t qos) {
|
||||
// Construct and send publish packet.
|
||||
uint16_t len = publishPacket(buffer, topic, data, bLen, qos);
|
||||
if (!sendPacket(buffer, len))
|
||||
return false;
|
||||
|
||||
// If QOS level is high enough verify the response packet.
|
||||
if (qos > 0) {
|
||||
len = readFullPacket(buffer, MAXBUFFERSIZE, PUBLISH_TIMEOUT_MS);
|
||||
DEBUG_PRINT(F("Publish QOS1+ reply:\t"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
if (len != 4)
|
||||
return false;
|
||||
if ((buffer[0] >> 4) != MQTT_CTRL_PUBACK)
|
||||
return false;
|
||||
uint16_t packnum = buffer[2];
|
||||
packnum <<= 8;
|
||||
packnum |= buffer[3];
|
||||
|
||||
// we increment the packet_id_counter right after publishing so inc here too to match
|
||||
packnum++;
|
||||
if (packnum != packet_id_counter)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::will(const char *topic, const char *payload, uint8_t qos, uint8_t retain) {
|
||||
|
||||
if (connected()) {
|
||||
DEBUG_PRINT(F("Will defined after connect"));
|
||||
return false;
|
||||
}
|
||||
|
||||
will_topic = topic;
|
||||
will_payload = payload;
|
||||
will_qos = qos;
|
||||
will_retain = retain;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::subscribe(Adafruit_MQTT_Subscribe *sub) {
|
||||
uint8_t i;
|
||||
// see if we are already subscribed
|
||||
for (i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
if (subscriptions[i] == sub) {
|
||||
DEBUG_PRINTLN(F("Already subscribed"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (i==MAXSUBSCRIPTIONS) { // add to subscriptionlist
|
||||
for (i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
if (subscriptions[i] == 0) {
|
||||
DEBUG_PRINT(F("Added sub ")); DEBUG_PRINTLN(i);
|
||||
subscriptions[i] = sub;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_PRINTLN(F("no more subscription space :("));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::unsubscribe(Adafruit_MQTT_Subscribe *sub) {
|
||||
uint8_t i;
|
||||
|
||||
// see if we are already subscribed
|
||||
for (i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
|
||||
if (subscriptions[i] == sub) {
|
||||
|
||||
DEBUG_PRINTLN(F("Found matching subscription and attempting to unsubscribe."));
|
||||
|
||||
// Construct and send unsubscribe packet.
|
||||
uint8_t len = unsubscribePacket(buffer, subscriptions[i]->topic);
|
||||
|
||||
// sending unsubscribe failed
|
||||
if (! sendPacket(buffer, len))
|
||||
return false;
|
||||
|
||||
// if QoS for this subscription is 1 or 2, we need
|
||||
// to wait for the unsuback to confirm unsubscription
|
||||
if(subscriptions[i]->qos > 0 && MQTT_PROTOCOL_LEVEL > 3) {
|
||||
|
||||
// wait for UNSUBACK
|
||||
len = readFullPacket(buffer, MAXBUFFERSIZE, CONNECT_TIMEOUT_MS);
|
||||
DEBUG_PRINT(F("UNSUBACK:\t"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
|
||||
if ((len != 5) || (buffer[0] != (MQTT_CTRL_UNSUBACK << 4))) {
|
||||
return false; // failure to unsubscribe
|
||||
}
|
||||
}
|
||||
|
||||
subscriptions[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// subscription not found, so we are unsubscribed
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void Adafruit_MQTT::processPackets(int16_t timeout) {
|
||||
|
||||
uint32_t elapsed = 0, endtime, starttime = millis();
|
||||
|
||||
while (elapsed < (uint32_t)timeout) {
|
||||
Adafruit_MQTT_Subscribe *sub = readSubscription(timeout - elapsed);
|
||||
if (sub) {
|
||||
//Serial.println("**** sub packet received");
|
||||
if (sub->callback_uint32t != NULL) {
|
||||
// huh lets do the callback in integer mode
|
||||
uint32_t data = 0;
|
||||
data = atoi((char *)sub->lastread);
|
||||
//Serial.print("*** calling int callback with : "); Serial.println(data);
|
||||
sub->callback_uint32t(data);
|
||||
}
|
||||
else if (sub->callback_double != NULL) {
|
||||
// huh lets do the callback in doublefloat mode
|
||||
double data = 0;
|
||||
data = atof((char *)sub->lastread);
|
||||
//Serial.print("*** calling double callback with : "); Serial.println(data);
|
||||
sub->callback_double(data);
|
||||
}
|
||||
else if (sub->callback_buffer != NULL) {
|
||||
// huh lets do the callback in buffer mode
|
||||
//Serial.print("*** calling buffer callback with : "); Serial.println((char *)sub->lastread);
|
||||
sub->callback_buffer((char *)sub->lastread, sub->datalen);
|
||||
}
|
||||
else if (sub->callback_io != NULL) {
|
||||
// huh lets do the callback in io mode
|
||||
//Serial.print("*** calling io instance callback with : "); Serial.println((char *)sub->lastread);
|
||||
((sub->io_mqtt)->*(sub->callback_io))((char *)sub->lastread, sub->datalen);
|
||||
}
|
||||
}
|
||||
|
||||
// keep track over elapsed time
|
||||
endtime = millis();
|
||||
if (endtime < starttime) {
|
||||
starttime = endtime; // looped around!")
|
||||
}
|
||||
elapsed += (endtime - starttime);
|
||||
}
|
||||
}
|
||||
|
||||
Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) {
|
||||
uint16_t i, topiclen, datalen;
|
||||
|
||||
// Check if data is available to read.
|
||||
uint16_t len = readFullPacket(buffer, MAXBUFFERSIZE, timeout); // return one full packet
|
||||
if (!len)
|
||||
return NULL; // No data available, just quit.
|
||||
DEBUG_PRINT("Packet len: "); DEBUG_PRINTLN(len);
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
|
||||
if (len<3) return NULL;
|
||||
if ((buffer[0] & 0xF0) != (MQTT_CTRL_PUBLISH) << 4) return NULL;
|
||||
|
||||
// Parse out length of packet.
|
||||
topiclen = buffer[3];
|
||||
DEBUG_PRINT(F("Looking for subscription len ")); DEBUG_PRINTLN(topiclen);
|
||||
|
||||
// Find subscription associated with this packet.
|
||||
for (i=0; i<MAXSUBSCRIPTIONS; i++) {
|
||||
if (subscriptions[i]) {
|
||||
// Skip this subscription if its name length isn't the same as the
|
||||
// received topic name.
|
||||
if (strlen(subscriptions[i]->topic) != topiclen)
|
||||
continue;
|
||||
// Stop if the subscription topic matches the received topic. Be careful
|
||||
// to make comparison case insensitive.
|
||||
if (strncasecmp((char*)buffer+4, subscriptions[i]->topic, topiclen) == 0) {
|
||||
DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i==MAXSUBSCRIPTIONS) return NULL; // matching sub not found ???
|
||||
|
||||
uint8_t packet_id_len = 0;
|
||||
uint16_t packetid = 0;
|
||||
// Check if it is QoS 1, TODO: we dont support QoS 2
|
||||
if ((buffer[0] & 0x6) == 0x2) {
|
||||
packet_id_len = 2;
|
||||
packetid = buffer[topiclen+4];
|
||||
packetid <<= 8;
|
||||
packetid |= buffer[topiclen+5];
|
||||
}
|
||||
|
||||
// zero out the old data
|
||||
memset(subscriptions[i]->lastread, 0, SUBSCRIPTIONDATALEN);
|
||||
|
||||
datalen = len - topiclen - packet_id_len - 4;
|
||||
if (datalen > SUBSCRIPTIONDATALEN) {
|
||||
datalen = SUBSCRIPTIONDATALEN-1; // cut it off
|
||||
}
|
||||
// extract out just the data, into the subscription object itself
|
||||
memmove(subscriptions[i]->lastread, buffer+4+topiclen+packet_id_len, datalen);
|
||||
subscriptions[i]->datalen = datalen;
|
||||
DEBUG_PRINT(F("Data len: ")); DEBUG_PRINTLN(datalen);
|
||||
DEBUG_PRINT(F("Data: ")); DEBUG_PRINTLN((char *)subscriptions[i]->lastread);
|
||||
|
||||
if ((MQTT_PROTOCOL_LEVEL > 3) &&(buffer[0] & 0x6) == 0x2) {
|
||||
uint8_t ackpacket[4];
|
||||
|
||||
// Construct and send puback packet.
|
||||
uint8_t len = pubackPacket(ackpacket, packetid);
|
||||
if (!sendPacket(ackpacket, len))
|
||||
DEBUG_PRINT(F("Failed"));
|
||||
}
|
||||
|
||||
// return the valid matching subscription
|
||||
return subscriptions[i];
|
||||
}
|
||||
|
||||
void Adafruit_MQTT::flushIncoming(uint16_t timeout) {
|
||||
// flush input!
|
||||
DEBUG_PRINTLN(F("Flushing input buffer"));
|
||||
while (readPacket(buffer, MAXBUFFERSIZE, timeout));
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT::ping(uint8_t num) {
|
||||
//flushIncoming(100);
|
||||
|
||||
while (num--) {
|
||||
// Construct and send ping packet.
|
||||
uint8_t len = pingPacket(buffer);
|
||||
if (!sendPacket(buffer, len))
|
||||
continue;
|
||||
|
||||
// Process ping reply.
|
||||
len = processPacketsUntil(buffer, MQTT_CTRL_PINGRESP, PING_TIMEOUT_MS);
|
||||
if (buffer[0] == (MQTT_CTRL_PINGRESP << 4))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packet Generation Functions /////////////////////////////////////////////////
|
||||
|
||||
// The current MQTT spec is 3.1.1 and available here:
|
||||
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028
|
||||
// However this connect packet and code follows the MQTT 3.1 spec here (some
|
||||
// small differences in the protocol):
|
||||
// http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#connect
|
||||
uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
|
||||
uint8_t *p = packet;
|
||||
uint16_t len;
|
||||
|
||||
// fixed header, connection messsage no flags
|
||||
p[0] = (MQTT_CTRL_CONNECT << 4) | 0x0;
|
||||
p+=2;
|
||||
// fill in packet[1] last
|
||||
|
||||
#if MQTT_PROTOCOL_LEVEL == 3
|
||||
p = stringprint(p, "MQIsdp");
|
||||
#elif MQTT_PROTOCOL_LEVEL == 4
|
||||
p = stringprint(p, "MQTT");
|
||||
#else
|
||||
#error "MQTT level not supported"
|
||||
#endif
|
||||
|
||||
p[0] = MQTT_PROTOCOL_LEVEL;
|
||||
p++;
|
||||
|
||||
// always clean the session
|
||||
p[0] = MQTT_CONN_CLEANSESSION;
|
||||
|
||||
// set the will flags if needed
|
||||
if (will_topic && pgm_read_byte(will_topic) != 0) {
|
||||
|
||||
p[0] |= MQTT_CONN_WILLFLAG;
|
||||
|
||||
if(will_qos == 1)
|
||||
p[0] |= MQTT_CONN_WILLQOS_1;
|
||||
else if(will_qos == 2)
|
||||
p[0] |= MQTT_CONN_WILLQOS_2;
|
||||
|
||||
if(will_retain == 1)
|
||||
p[0] |= MQTT_CONN_WILLRETAIN;
|
||||
|
||||
}
|
||||
|
||||
if (pgm_read_byte(username) != 0)
|
||||
p[0] |= MQTT_CONN_USERNAMEFLAG;
|
||||
if (pgm_read_byte(password) != 0)
|
||||
p[0] |= MQTT_CONN_PASSWORDFLAG;
|
||||
p++;
|
||||
|
||||
p[0] = MQTT_CONN_KEEPALIVE >> 8;
|
||||
p++;
|
||||
p[0] = MQTT_CONN_KEEPALIVE & 0xFF;
|
||||
p++;
|
||||
|
||||
if(MQTT_PROTOCOL_LEVEL == 3) {
|
||||
p = stringprint(p, clientid, 23); // Limit client ID to first 23 characters.
|
||||
} else {
|
||||
if (pgm_read_byte(clientid) != 0) {
|
||||
p = stringprint(p, clientid);
|
||||
} else {
|
||||
p[0] = 0x0;
|
||||
p++;
|
||||
p[0] = 0x0;
|
||||
p++;
|
||||
DEBUG_PRINTLN(F("SERVER GENERATING CLIENT ID"));
|
||||
}
|
||||
}
|
||||
|
||||
if (will_topic && pgm_read_byte(will_topic) != 0) {
|
||||
p = stringprint(p, will_topic);
|
||||
p = stringprint(p, will_payload);
|
||||
}
|
||||
|
||||
if (pgm_read_byte(username) != 0) {
|
||||
p = stringprint(p, username);
|
||||
}
|
||||
if (pgm_read_byte(password) != 0) {
|
||||
p = stringprint(p, password);
|
||||
}
|
||||
|
||||
len = p - packet;
|
||||
|
||||
packet[1] = len-2; // don't include the 2 bytes of fixed header data
|
||||
DEBUG_PRINTLN(F("MQTT connect packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
// as per http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
|
||||
uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
|
||||
uint8_t *data, uint16_t bLen, uint8_t qos) {
|
||||
uint8_t *p = packet;
|
||||
uint16_t len=0;
|
||||
|
||||
// calc length of non-header data
|
||||
len += 2; // two bytes to set the topic size
|
||||
len += strlen(topic); // topic length
|
||||
if(qos > 0) {
|
||||
len += 2; // qos packet id
|
||||
}
|
||||
len += bLen; // payload length
|
||||
|
||||
// Now you can start generating the packet!
|
||||
p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1;
|
||||
p++;
|
||||
|
||||
// fill in packet[1] last
|
||||
do {
|
||||
uint8_t encodedByte = len % 128;
|
||||
len /= 128;
|
||||
// if there are more data to encode, set the top bit of this byte
|
||||
if ( len > 0 ) {
|
||||
encodedByte |= 0x80;
|
||||
}
|
||||
p[0] = encodedByte;
|
||||
p++;
|
||||
} while ( len > 0 );
|
||||
|
||||
// topic comes before packet identifier
|
||||
p = stringprint(p, topic);
|
||||
|
||||
// add packet identifier. used for checking PUBACK in QOS > 0
|
||||
if(qos > 0) {
|
||||
p[0] = (packet_id_counter >> 8) & 0xFF;
|
||||
p[1] = packet_id_counter & 0xFF;
|
||||
p+=2;
|
||||
|
||||
// increment the packet id
|
||||
packet_id_counter++;
|
||||
}
|
||||
|
||||
memmove(p, data, bLen);
|
||||
p+= bLen;
|
||||
len = p - packet;
|
||||
DEBUG_PRINTLN(F("MQTT publish packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t Adafruit_MQTT::subscribePacket(uint8_t *packet, const char *topic,
|
||||
uint8_t qos) {
|
||||
uint8_t *p = packet;
|
||||
uint16_t len;
|
||||
|
||||
p[0] = MQTT_CTRL_SUBSCRIBE << 4 | MQTT_QOS_1 << 1;
|
||||
// fill in packet[1] last
|
||||
p+=2;
|
||||
|
||||
// packet identifier. used for checking SUBACK
|
||||
p[0] = (packet_id_counter >> 8) & 0xFF;
|
||||
p[1] = packet_id_counter & 0xFF;
|
||||
p+=2;
|
||||
|
||||
// increment the packet id
|
||||
packet_id_counter++;
|
||||
|
||||
p = stringprint(p, topic);
|
||||
|
||||
p[0] = qos;
|
||||
p++;
|
||||
|
||||
len = p - packet;
|
||||
packet[1] = len-2; // don't include the 2 bytes of fixed header data
|
||||
DEBUG_PRINTLN(F("MQTT subscription packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t Adafruit_MQTT::unsubscribePacket(uint8_t *packet, const char *topic) {
|
||||
|
||||
uint8_t *p = packet;
|
||||
uint16_t len;
|
||||
|
||||
p[0] = MQTT_CTRL_UNSUBSCRIBE << 4 | 0x1;
|
||||
// fill in packet[1] last
|
||||
p+=2;
|
||||
|
||||
// packet identifier. used for checking UNSUBACK
|
||||
p[0] = (packet_id_counter >> 8) & 0xFF;
|
||||
p[1] = packet_id_counter & 0xFF;
|
||||
p+=2;
|
||||
|
||||
// increment the packet id
|
||||
packet_id_counter++;
|
||||
|
||||
p = stringprint(p, topic);
|
||||
|
||||
len = p - packet;
|
||||
packet[1] = len-2; // don't include the 2 bytes of fixed header data
|
||||
DEBUG_PRINTLN(F("MQTT unsubscription packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
uint8_t Adafruit_MQTT::pingPacket(uint8_t *packet) {
|
||||
packet[0] = MQTT_CTRL_PINGREQ << 4;
|
||||
packet[1] = 0;
|
||||
DEBUG_PRINTLN(F("MQTT ping packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, 2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint8_t Adafruit_MQTT::pubackPacket(uint8_t *packet, uint16_t packetid) {
|
||||
packet[0] = MQTT_CTRL_PUBACK << 4;
|
||||
packet[1] = 2;
|
||||
packet[2] = packetid >> 8;
|
||||
packet[3] = packetid;
|
||||
DEBUG_PRINTLN(F("MQTT puback packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, 4);
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint8_t Adafruit_MQTT::disconnectPacket(uint8_t *packet) {
|
||||
packet[0] = MQTT_CTRL_DISCONNECT << 4;
|
||||
packet[1] = 0;
|
||||
DEBUG_PRINTLN(F("MQTT disconnect packet:"));
|
||||
DEBUG_PRINTBUFFER(buffer, 2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Adafruit_MQTT_Publish Definition ////////////////////////////////////////////
|
||||
|
||||
Adafruit_MQTT_Publish::Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver,
|
||||
const char *feed, uint8_t q) {
|
||||
mqtt = mqttserver;
|
||||
topic = feed;
|
||||
qos = q;
|
||||
}
|
||||
bool Adafruit_MQTT_Publish::publish(int32_t i) {
|
||||
char payload[12];
|
||||
ltoa(i, payload, 10);
|
||||
return mqtt->publish(topic, payload, qos);
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Publish::publish(uint32_t i) {
|
||||
char payload[11];
|
||||
ultoa(i, payload, 10);
|
||||
return mqtt->publish(topic, payload, qos);
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Publish::publish(double f, uint8_t precision) {
|
||||
char payload[41]; // Need to technically hold float max, 39 digits and minus sign.
|
||||
dtostrf(f, 0, precision, payload);
|
||||
return mqtt->publish(topic, payload, qos);
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Publish::publish(const char *payload) {
|
||||
return mqtt->publish(topic, payload, qos);
|
||||
}
|
||||
|
||||
//publish buffer of arbitrary length
|
||||
bool Adafruit_MQTT_Publish::publish(uint8_t *payload, uint16_t bLen) {
|
||||
|
||||
return mqtt->publish(topic, payload, bLen, qos);
|
||||
}
|
||||
|
||||
|
||||
// Adafruit_MQTT_Subscribe Definition //////////////////////////////////////////
|
||||
|
||||
Adafruit_MQTT_Subscribe::Adafruit_MQTT_Subscribe(Adafruit_MQTT *mqttserver,
|
||||
const char *feed, uint8_t q) {
|
||||
mqtt = mqttserver;
|
||||
topic = feed;
|
||||
qos = q;
|
||||
datalen = 0;
|
||||
callback_uint32t = 0;
|
||||
callback_buffer = 0;
|
||||
callback_double = 0;
|
||||
callback_io = 0;
|
||||
io_mqtt = 0;
|
||||
}
|
||||
|
||||
void Adafruit_MQTT_Subscribe::setCallback(SubscribeCallbackUInt32Type cb) {
|
||||
callback_uint32t = cb;
|
||||
}
|
||||
|
||||
void Adafruit_MQTT_Subscribe::setCallback(SubscribeCallbackDoubleType cb) {
|
||||
callback_double = cb;
|
||||
}
|
||||
|
||||
void Adafruit_MQTT_Subscribe::setCallback(SubscribeCallbackBufferType cb) {
|
||||
callback_buffer = cb;
|
||||
}
|
||||
|
||||
void Adafruit_MQTT_Subscribe::setCallback(AdafruitIO_MQTT *io, SubscribeCallbackIOType cb) {
|
||||
callback_io = cb;
|
||||
io_mqtt= io;
|
||||
}
|
||||
|
||||
void Adafruit_MQTT_Subscribe::removeCallback(void) {
|
||||
callback_uint32t = 0;
|
||||
callback_buffer = 0;
|
||||
callback_double = 0;
|
||||
callback_io = 0;
|
||||
io_mqtt = 0;
|
||||
}
|
302
libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h
Normal file
302
libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h
Normal file
|
@ -0,0 +1,302 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Adafruit Industries
|
||||
//
|
||||
// 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.
|
||||
#ifndef _ADAFRUIT_MQTT_H_
|
||||
#define _ADAFRUIT_MQTT_H_
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_STM32_FEATHER)
|
||||
#define strncpy_P(dest, src, len) strncpy((dest), (src), (len))
|
||||
#define strncasecmp_P(f1, f2, len) strncasecmp((f1), (f2), (len))
|
||||
#endif
|
||||
|
||||
#define ADAFRUIT_MQTT_VERSION_MAJOR 0
|
||||
#define ADAFRUIT_MQTT_VERSION_MINOR 17
|
||||
#define ADAFRUIT_MQTT_VERSION_PATCH 0
|
||||
|
||||
// Uncomment/comment to turn on/off debug output messages.
|
||||
//#define MQTT_DEBUG
|
||||
// Uncomment/comment to turn on/off error output messages.
|
||||
#define MQTT_ERROR
|
||||
|
||||
// Set where debug messages will be printed.
|
||||
#define DEBUG_PRINTER Serial
|
||||
// If using something like Zero or Due, change the above to SerialUSB
|
||||
|
||||
// Define actual debug output functions when necessary.
|
||||
#ifdef MQTT_DEBUG
|
||||
#define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
|
||||
#define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
|
||||
#define DEBUG_PRINTBUFFER(buffer, len) { printBuffer(buffer, len); }
|
||||
#else
|
||||
#define DEBUG_PRINT(...) {}
|
||||
#define DEBUG_PRINTLN(...) {}
|
||||
#define DEBUG_PRINTBUFFER(buffer, len) {}
|
||||
#endif
|
||||
|
||||
#ifdef MQTT_ERROR
|
||||
#define ERROR_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
|
||||
#define ERROR_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
|
||||
#define ERROR_PRINTBUFFER(buffer, len) { printBuffer(buffer, len); }
|
||||
#else
|
||||
#define ERROR_PRINT(...) {}
|
||||
#define ERROR_PRINTLN(...) {}
|
||||
#define ERROR_PRINTBUFFER(buffer, len) {}
|
||||
#endif
|
||||
|
||||
// Use 3 (MQTT 3.0) or 4 (MQTT 3.1.1)
|
||||
#define MQTT_PROTOCOL_LEVEL 4
|
||||
|
||||
#define MQTT_CTRL_CONNECT 0x1
|
||||
#define MQTT_CTRL_CONNECTACK 0x2
|
||||
#define MQTT_CTRL_PUBLISH 0x3
|
||||
#define MQTT_CTRL_PUBACK 0x4
|
||||
#define MQTT_CTRL_PUBREC 0x5
|
||||
#define MQTT_CTRL_PUBREL 0x6
|
||||
#define MQTT_CTRL_PUBCOMP 0x7
|
||||
#define MQTT_CTRL_SUBSCRIBE 0x8
|
||||
#define MQTT_CTRL_SUBACK 0x9
|
||||
#define MQTT_CTRL_UNSUBSCRIBE 0xA
|
||||
#define MQTT_CTRL_UNSUBACK 0xB
|
||||
#define MQTT_CTRL_PINGREQ 0xC
|
||||
#define MQTT_CTRL_PINGRESP 0xD
|
||||
#define MQTT_CTRL_DISCONNECT 0xE
|
||||
|
||||
#define MQTT_QOS_1 0x1
|
||||
#define MQTT_QOS_0 0x0
|
||||
|
||||
#define CONNECT_TIMEOUT_MS 6000
|
||||
#define PUBLISH_TIMEOUT_MS 500
|
||||
#define PING_TIMEOUT_MS 500
|
||||
#define SUBACK_TIMEOUT_MS 500
|
||||
|
||||
// Adjust as necessary, in seconds. Default to 5 minutes.
|
||||
#define MQTT_CONN_KEEPALIVE 300
|
||||
|
||||
// Largest full packet we're able to send.
|
||||
// Need to be able to store at least ~90 chars for a connect packet with full
|
||||
// 23 char client ID.
|
||||
#define MAXBUFFERSIZE (150)
|
||||
|
||||
#define MQTT_CONN_USERNAMEFLAG 0x80
|
||||
#define MQTT_CONN_PASSWORDFLAG 0x40
|
||||
#define MQTT_CONN_WILLRETAIN 0x20
|
||||
#define MQTT_CONN_WILLQOS_1 0x08
|
||||
#define MQTT_CONN_WILLQOS_2 0x18
|
||||
#define MQTT_CONN_WILLFLAG 0x04
|
||||
#define MQTT_CONN_CLEANSESSION 0x02
|
||||
|
||||
// how much data we save in a subscription object
|
||||
// and how many subscriptions we want to be able to track.
|
||||
#if defined (__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__)
|
||||
#define MAXSUBSCRIPTIONS 5
|
||||
#define SUBSCRIPTIONDATALEN 20
|
||||
#else
|
||||
#define MAXSUBSCRIPTIONS 15
|
||||
#define SUBSCRIPTIONDATALEN 100
|
||||
#endif
|
||||
|
||||
class AdafruitIO_MQTT; // forward decl
|
||||
|
||||
//Function pointer that returns an int
|
||||
typedef void (*SubscribeCallbackUInt32Type)(uint32_t);
|
||||
// returns a double
|
||||
typedef void (*SubscribeCallbackDoubleType)(double);
|
||||
// returns a chunk of raw data
|
||||
typedef void (*SubscribeCallbackBufferType)(char *str, uint16_t len);
|
||||
// returns an io data wrapper instance
|
||||
typedef void (AdafruitIO_MQTT::*SubscribeCallbackIOType)(char *str, uint16_t len);
|
||||
|
||||
extern void printBuffer(uint8_t *buffer, uint16_t len);
|
||||
|
||||
class Adafruit_MQTT_Subscribe; // forward decl
|
||||
|
||||
class Adafruit_MQTT {
|
||||
public:
|
||||
Adafruit_MQTT(const char *server,
|
||||
uint16_t port,
|
||||
const char *cid,
|
||||
const char *user,
|
||||
const char *pass);
|
||||
|
||||
Adafruit_MQTT(const char *server,
|
||||
uint16_t port,
|
||||
const char *user = "",
|
||||
const char *pass = "");
|
||||
virtual ~Adafruit_MQTT() {}
|
||||
|
||||
// Connect to the MQTT server. Returns 0 on success, otherwise an error code
|
||||
// that indicates something went wrong:
|
||||
// -1 = Error connecting to server
|
||||
// 1 = Wrong protocol
|
||||
// 2 = ID rejected
|
||||
// 3 = Server unavailable
|
||||
// 4 = Bad username or password
|
||||
// 5 = Not authenticated
|
||||
// 6 = Failed to subscribe
|
||||
// Use connectErrorString() to get a printable string version of the
|
||||
// error.
|
||||
int8_t connect();
|
||||
int8_t connect(const char *user, const char *pass);
|
||||
|
||||
// Return a printable string version of the error code returned by
|
||||
// connect(). This returns a __FlashStringHelper*, which points to a
|
||||
// string stored in flash, but can be directly passed to e.g.
|
||||
// Serial.println without any further processing.
|
||||
const __FlashStringHelper* connectErrorString(int8_t code);
|
||||
|
||||
// Sends MQTT disconnect packet and calls disconnectServer()
|
||||
bool disconnect();
|
||||
|
||||
// Return true if connected to the MQTT server, otherwise false.
|
||||
virtual bool connected() = 0; // Subclasses need to fill this in!
|
||||
|
||||
// Set MQTT last will topic, payload, QOS, and retain. This needs
|
||||
// to be called before connect() because it is sent as part of the
|
||||
// connect control packet.
|
||||
bool will(const char *topic, const char *payload, uint8_t qos = 0, uint8_t retain = 0);
|
||||
|
||||
// Publish a message to a topic using the specified QoS level. Returns true
|
||||
// if the message was published, false otherwise.
|
||||
bool publish(const char *topic, const char *payload, uint8_t qos = 0);
|
||||
bool publish(const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos = 0);
|
||||
|
||||
// Add a subscription to receive messages for a topic. Returns true if the
|
||||
// subscription could be added or was already present, false otherwise.
|
||||
// Must be called before connect(), subscribing after the connection
|
||||
// is made is not currently supported.
|
||||
bool subscribe(Adafruit_MQTT_Subscribe *sub);
|
||||
|
||||
// Unsubscribe from a previously subscribed MQTT topic.
|
||||
bool unsubscribe(Adafruit_MQTT_Subscribe *sub);
|
||||
|
||||
// Check if any subscriptions have new messages. Will return a reference to
|
||||
// an Adafruit_MQTT_Subscribe object which has a new message. Should be called
|
||||
// in the sketch's loop function to ensure new messages are recevied. Note
|
||||
// that subscribe should be called first for each topic that receives messages!
|
||||
Adafruit_MQTT_Subscribe *readSubscription(int16_t timeout=0);
|
||||
|
||||
void processPackets(int16_t timeout);
|
||||
|
||||
// Ping the server to ensure the connection is still alive.
|
||||
bool ping(uint8_t n = 1);
|
||||
|
||||
protected:
|
||||
// Interface that subclasses need to implement:
|
||||
|
||||
// Connect to the server and return true if successful, false otherwise.
|
||||
virtual bool connectServer() = 0;
|
||||
|
||||
// Disconnect from the MQTT server. Returns true if disconnected, false otherwise.
|
||||
virtual bool disconnectServer() = 0; // Subclasses need to fill this in!
|
||||
|
||||
// Send data to the server specified by the buffer and length of data.
|
||||
virtual bool sendPacket(uint8_t *buffer, uint16_t len) = 0;
|
||||
|
||||
// Read MQTT packet from the server. Will read up to maxlen bytes and store
|
||||
// the data in the provided buffer. Waits up to the specified timeout (in
|
||||
// milliseconds) for data to be available.
|
||||
virtual uint16_t readPacket(uint8_t *buffer, uint16_t maxlen, int16_t timeout) = 0;
|
||||
|
||||
// Read a full packet, keeping note of the correct length
|
||||
uint16_t readFullPacket(uint8_t *buffer, uint16_t maxsize, uint16_t timeout);
|
||||
// Properly process packets until you get to one you want
|
||||
uint16_t processPacketsUntil(uint8_t *buffer, uint8_t waitforpackettype, uint16_t timeout);
|
||||
|
||||
// Shared state that subclasses can use:
|
||||
const char *servername;
|
||||
int16_t portnum;
|
||||
const char *clientid;
|
||||
const char *username;
|
||||
const char *password;
|
||||
const char *will_topic;
|
||||
const char *will_payload;
|
||||
uint8_t will_qos;
|
||||
uint8_t will_retain;
|
||||
uint8_t buffer[MAXBUFFERSIZE]; // one buffer, used for all incoming/outgoing
|
||||
uint16_t packet_id_counter;
|
||||
|
||||
private:
|
||||
Adafruit_MQTT_Subscribe *subscriptions[MAXSUBSCRIPTIONS];
|
||||
|
||||
void flushIncoming(uint16_t timeout);
|
||||
|
||||
// Functions to generate MQTT packets.
|
||||
uint8_t connectPacket(uint8_t *packet);
|
||||
uint8_t disconnectPacket(uint8_t *packet);
|
||||
uint16_t publishPacket(uint8_t *packet, const char *topic, uint8_t *payload, uint16_t bLen, uint8_t qos);
|
||||
uint8_t subscribePacket(uint8_t *packet, const char *topic, uint8_t qos);
|
||||
uint8_t unsubscribePacket(uint8_t *packet, const char *topic);
|
||||
uint8_t pingPacket(uint8_t *packet);
|
||||
uint8_t pubackPacket(uint8_t *packet, uint16_t packetid);
|
||||
};
|
||||
|
||||
|
||||
class Adafruit_MQTT_Publish {
|
||||
public:
|
||||
Adafruit_MQTT_Publish(Adafruit_MQTT *mqttserver, const char *feed, uint8_t qos = 0);
|
||||
|
||||
bool publish(const char *s);
|
||||
bool publish(double f, uint8_t precision=2); // Precision controls the minimum number of digits after decimal.
|
||||
// This might be ignored and a higher precision value sent.
|
||||
bool publish(int32_t i);
|
||||
bool publish(uint32_t i);
|
||||
bool publish(uint8_t *b, uint16_t bLen);
|
||||
|
||||
|
||||
private:
|
||||
Adafruit_MQTT *mqtt;
|
||||
const char *topic;
|
||||
uint8_t qos;
|
||||
};
|
||||
|
||||
class Adafruit_MQTT_Subscribe {
|
||||
public:
|
||||
Adafruit_MQTT_Subscribe(Adafruit_MQTT *mqttserver, const char *feedname, uint8_t q=0);
|
||||
|
||||
void setCallback(SubscribeCallbackUInt32Type callb);
|
||||
void setCallback(SubscribeCallbackDoubleType callb);
|
||||
void setCallback(SubscribeCallbackBufferType callb);
|
||||
void setCallback(AdafruitIO_MQTT *io, SubscribeCallbackIOType callb);
|
||||
void removeCallback(void);
|
||||
|
||||
const char *topic;
|
||||
uint8_t qos;
|
||||
|
||||
uint8_t lastread[SUBSCRIPTIONDATALEN];
|
||||
// Number valid bytes in lastread. Limited to SUBSCRIPTIONDATALEN-1 to
|
||||
// ensure nul terminating lastread.
|
||||
uint16_t datalen;
|
||||
|
||||
SubscribeCallbackUInt32Type callback_uint32t;
|
||||
SubscribeCallbackDoubleType callback_double;
|
||||
SubscribeCallbackBufferType callback_buffer;
|
||||
SubscribeCallbackIOType callback_io;
|
||||
|
||||
AdafruitIO_MQTT *io_mqtt;
|
||||
|
||||
private:
|
||||
Adafruit_MQTT *mqtt;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
106
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp
Normal file
106
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Adafruit Industries
|
||||
//
|
||||
// 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.
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
|
||||
bool Adafruit_MQTT_Client::connectServer() {
|
||||
// Grab server name from flash and copy to buffer for name resolution.
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
strcpy((char *)buffer, servername);
|
||||
DEBUG_PRINT(F("Connecting to: ")); DEBUG_PRINTLN((char *)buffer);
|
||||
// Connect and check for success (0 result).
|
||||
int r = client->connect((char *)buffer, portnum);
|
||||
DEBUG_PRINT(F("Connect result: ")); DEBUG_PRINTLN(r);
|
||||
return r != 0;
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Client::disconnectServer() {
|
||||
// Stop connection if connected and return success (stop has no indication of
|
||||
// failure).
|
||||
if (client->connected()) {
|
||||
client->stop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Client::connected() {
|
||||
// Return true if connected, false if not connected.
|
||||
return client->connected();
|
||||
}
|
||||
|
||||
uint16_t Adafruit_MQTT_Client::readPacket(uint8_t *buffer, uint16_t maxlen,
|
||||
int16_t timeout) {
|
||||
/* Read data until either the connection is closed, or the idle timeout is reached. */
|
||||
uint16_t len = 0;
|
||||
int16_t t = timeout;
|
||||
|
||||
|
||||
while (client->connected() && (timeout >= 0)) {
|
||||
//DEBUG_PRINT('.');
|
||||
while (client->available()) {
|
||||
//DEBUG_PRINT('!');
|
||||
char c = client->read();
|
||||
timeout = t; // reset the timeout
|
||||
buffer[len] = c;
|
||||
//DEBUG_PRINTLN((uint8_t)c, HEX);
|
||||
len++;
|
||||
|
||||
if (maxlen == 0) { // handle zero-length packets
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len == maxlen) { // we read all we want, bail
|
||||
DEBUG_PRINT(F("Read data:\t"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
timeout -= MQTT_CLIENT_READINTERVAL_MS;
|
||||
delay(MQTT_CLIENT_READINTERVAL_MS);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool Adafruit_MQTT_Client::sendPacket(uint8_t *buffer, uint16_t len) {
|
||||
uint16_t ret = 0;
|
||||
|
||||
while (len > 0) {
|
||||
if (client->connected()) {
|
||||
// send 250 bytes at most at a time, can adjust this later based on Client
|
||||
|
||||
uint16_t sendlen = len > 250 ? 250 : len;
|
||||
//Serial.print("Sending: "); Serial.println(sendlen);
|
||||
ret = client->write(buffer, sendlen);
|
||||
DEBUG_PRINT(F("Client sendPacket returned: ")); DEBUG_PRINTLN(ret);
|
||||
len -= ret;
|
||||
|
||||
if (ret != sendlen) {
|
||||
DEBUG_PRINTLN("Failed to send packet.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Connection failed!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
61
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h
Normal file
61
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Adafruit Industries
|
||||
//
|
||||
// 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.
|
||||
#ifndef _ADAFRUIT_MQTT_CLIENT_H_
|
||||
#define _ADAFRUIT_MQTT_CLIENT_H_
|
||||
|
||||
#include "Client.h"
|
||||
#include "Adafruit_MQTT.h"
|
||||
|
||||
|
||||
// How long to delay waiting for new data to be available in readPacket.
|
||||
#define MQTT_CLIENT_READINTERVAL_MS 10
|
||||
|
||||
|
||||
// MQTT client implementation for a generic Arduino Client interface. Can work
|
||||
// with almost all Arduino network hardware like ethernet shield, wifi shield,
|
||||
// and even other platforms like ESP8266.
|
||||
class Adafruit_MQTT_Client : public Adafruit_MQTT {
|
||||
public:
|
||||
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
|
||||
const char *cid, const char *user, const char *pass):
|
||||
Adafruit_MQTT(server, port, cid, user, pass),
|
||||
client(client)
|
||||
{}
|
||||
|
||||
Adafruit_MQTT_Client(Client *client, const char *server, uint16_t port,
|
||||
const char *user="", const char *pass=""):
|
||||
Adafruit_MQTT(server, port, user, pass),
|
||||
client(client)
|
||||
{}
|
||||
|
||||
bool connectServer();
|
||||
bool disconnectServer();
|
||||
bool connected();
|
||||
uint16_t readPacket(uint8_t *buffer, uint16_t maxlen, int16_t timeout);
|
||||
bool sendPacket(uint8_t *buffer, uint16_t len);
|
||||
|
||||
private:
|
||||
Client* client;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
142
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_FONA.h
Normal file
142
libraries/Adafruit_MQTT_Library/Adafruit_MQTT_FONA.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 Adafruit Industries
|
||||
//
|
||||
// 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.
|
||||
#ifndef _ADAFRUIT_MQTT_FONA_H_
|
||||
#define _ADAFRUIT_MQTT_FONA_H_
|
||||
|
||||
#include <Adafruit_FONA.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
|
||||
#define MQTT_FONA_INTERAVAILDELAY 100
|
||||
#define MQTT_FONA_QUERYDELAY 500
|
||||
|
||||
|
||||
// FONA-specific version of the Adafruit_MQTT class.
|
||||
// Note that this is defined as a header-only class to prevent issues with using
|
||||
// the library on non-FONA platforms (since Arduino will include all .cpp files
|
||||
// in the compilation of the library).
|
||||
class Adafruit_MQTT_FONA : public Adafruit_MQTT {
|
||||
public:
|
||||
Adafruit_MQTT_FONA(Adafruit_FONA *f, const char *server, uint16_t port,
|
||||
const char *cid, const char *user, const char *pass):
|
||||
Adafruit_MQTT(server, port, cid, user, pass),
|
||||
fona(f)
|
||||
{}
|
||||
|
||||
Adafruit_MQTT_FONA(Adafruit_FONA *f, const char *server, uint16_t port,
|
||||
const char *user="", const char *pass=""):
|
||||
Adafruit_MQTT(server, port, user, pass),
|
||||
fona(f)
|
||||
{}
|
||||
|
||||
bool connectServer() {
|
||||
char server[40];
|
||||
strncpy(server, servername, 40);
|
||||
#ifdef ADAFRUIT_SLEEPYDOG_H
|
||||
Watchdog.reset();
|
||||
#endif
|
||||
|
||||
// connect to server
|
||||
DEBUG_PRINTLN(F("Connecting to TCP"));
|
||||
return fona->TCPconnect(server, portnum);
|
||||
}
|
||||
|
||||
bool disconnectServer() {
|
||||
return fona->TCPclose();
|
||||
}
|
||||
|
||||
bool connected() {
|
||||
// Return true if connected, false if not connected.
|
||||
return fona->TCPconnected();
|
||||
}
|
||||
|
||||
uint16_t readPacket(uint8_t *buffer, uint16_t maxlen, int16_t timeout) {
|
||||
uint8_t *buffp = buffer;
|
||||
DEBUG_PRINTLN(F("Reading data.."));
|
||||
|
||||
if (!fona->TCPconnected()) return 0;
|
||||
|
||||
|
||||
/* Read data until either the connection is closed, or the idle timeout is reached. */
|
||||
uint16_t len = 0;
|
||||
int16_t t = timeout;
|
||||
uint16_t avail;
|
||||
|
||||
while (fona->TCPconnected() && (timeout >= 0)) {
|
||||
//DEBUG_PRINT('.');
|
||||
while (avail = fona->TCPavailable()) {
|
||||
//DEBUG_PRINT('!');
|
||||
|
||||
if (len + avail > maxlen) {
|
||||
avail = maxlen - len;
|
||||
if (avail == 0) return len;
|
||||
}
|
||||
|
||||
// try to read the data into the end of the pointer
|
||||
if (! fona->TCPread(buffp, avail)) return len;
|
||||
|
||||
// read it! advance pointer
|
||||
buffp += avail;
|
||||
len += avail;
|
||||
timeout = t; // reset the timeout
|
||||
|
||||
//DEBUG_PRINTLN((uint8_t)c, HEX);
|
||||
|
||||
if (len == maxlen) { // we read all we want, bail
|
||||
DEBUG_PRINT(F("Read:\t"));
|
||||
DEBUG_PRINTBUFFER(buffer, len);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
#ifdef ADAFRUIT_SLEEPYDOG_H
|
||||
Watchdog.reset();
|
||||
#endif
|
||||
timeout -= MQTT_FONA_INTERAVAILDELAY;
|
||||
timeout -= MQTT_FONA_QUERYDELAY; // this is how long it takes to query the FONA for avail()
|
||||
delay(MQTT_FONA_INTERAVAILDELAY);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool sendPacket(uint8_t *buffer, uint16_t len) {
|
||||
DEBUG_PRINTLN(F("Writing packet"));
|
||||
if (fona->TCPconnected()) {
|
||||
boolean ret = fona->TCPsend((char *)buffer, len);
|
||||
//DEBUG_PRINT(F("sendPacket returned: ")); DEBUG_PRINTLN(ret);
|
||||
if (!ret) {
|
||||
DEBUG_PRINTLN("Failed to send packet.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Connection failed!"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t serverip;
|
||||
Adafruit_FONA *fona;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
22
libraries/Adafruit_MQTT_Library/LICENSE
Normal file
22
libraries/Adafruit_MQTT_Library/LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Adafruit Industries
|
||||
|
||||
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.
|
||||
|
57
libraries/Adafruit_MQTT_Library/README.md
Normal file
57
libraries/Adafruit_MQTT_Library/README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Adafruit MQTT Library [](https://travis-ci.com/adafruit/Adafruit_MQTT_Library)
|
||||
|
||||
Arduino library for MQTT support, including access to Adafruit IO. Works with
|
||||
the Adafruit FONA, Arduino Yun, ESP8266 Arduino platforms, and anything that supports
|
||||
Arduino's Client interface (like Ethernet shield).
|
||||
|
||||
See included examples for how to use the library to access an MQTT service to
|
||||
publish and subscribe to feeds. Note that this does not support the full MQTT
|
||||
spec but is intended to support enough for QoS 0 and 1 publishing.
|
||||
|
||||
Depends on the following other libraries depending on the target platform:
|
||||
|
||||
- [Adafruit SleepyDog](https://github.com/adafruit/Adafruit_SleepyDog), watchdog
|
||||
library used by FONA code for reliability.
|
||||
|
||||
- [Adafruit FONA](https://github.com/adafruit/Adafruit_FONA_Library), required for
|
||||
the FONA hardware.
|
||||
|
||||
Future todos:
|
||||
|
||||
- Subscription callbacks
|
||||
|
||||
- remove watchdog
|
||||
|
||||
<!-- START COMPATIBILITY TABLE -->
|
||||
|
||||
## Compatibility
|
||||
|
||||
MCU | Tested Works | Doesn't Work | Not Tested | Notes
|
||||
------------------ | :----------: | :----------: | :---------: | -----
|
||||
Atmega328 @ 16MHz | | | X |
|
||||
Atmega328 @ 12MHz | | | X |
|
||||
Atmega32u4 @ 16MHz | | | X |
|
||||
Atmega32u4 @ 8MHz | | | X |
|
||||
ESP8266 | | | X |
|
||||
Atmega2560 @ 16MHz | | | X |
|
||||
ATSAM3X8E | | | X |
|
||||
ATSAM21D | | | X |
|
||||
ATSAMD51J20 | | | X |
|
||||
ATtiny85 @ 16MHz | | | X |
|
||||
ATtiny85 @ 8MHz | | | X |
|
||||
Intel Curie @ 32MHz | | | X |
|
||||
STM32F2 | | | X |
|
||||
|
||||
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
|
||||
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
|
||||
* ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
|
||||
* ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
|
||||
* ESP8266 : Adafruit Huzzah
|
||||
* ATmega2560 @ 16MHz : Arduino Mega
|
||||
* ATSAM3X8E : Arduino Due
|
||||
* ATSAM21D : Arduino Zero, M0 Pro
|
||||
* ATSAMD51J20: Adafruit PyPortal
|
||||
* ATtiny85 @ 16MHz : Adafruit Trinket 5V
|
||||
* ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
|
||||
|
||||
<!-- END COMPATIBILITY TABLE -->
|
|
@ -0,0 +1,122 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Adafruit IO Anonymous Time Query
|
||||
|
||||
Must use the latest version of ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
#define WLAN_SSID "network"
|
||||
#define WLAN_PASS "password"
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 8883
|
||||
|
||||
WiFiClientSecure client;
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT);
|
||||
|
||||
Adafruit_MQTT_Subscribe timefeed = Adafruit_MQTT_Subscribe(&mqtt, "time/seconds");
|
||||
|
||||
// set timezone offset from UTC
|
||||
int timeZone = -4; // UTC - 4 eastern daylight time (nyc)
|
||||
int interval = 4; // trigger every X hours
|
||||
|
||||
int last_min = -1;
|
||||
|
||||
void timecallback(uint32_t current) {
|
||||
// adjust to local time zone
|
||||
current += (timeZone * 60 * 60);
|
||||
int curr_hour = (current / 60 / 60) % 24;
|
||||
int curr_min = (current / 60 ) % 60;
|
||||
int curr_sec = (current) % 60;
|
||||
|
||||
Serial.print("Time: ");
|
||||
Serial.print(curr_hour); Serial.print(':');
|
||||
Serial.print(curr_min); Serial.print(':');
|
||||
Serial.println(curr_sec);
|
||||
|
||||
// only trigger on minute change
|
||||
if(curr_min != last_min) {
|
||||
last_min = curr_min;
|
||||
|
||||
Serial.println("This will print out every minute!");
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.print(F("\nAdafruit IO anonymous Time Demo"));
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(F("."));
|
||||
}
|
||||
Serial.println(F(" WiFi connected."));
|
||||
|
||||
timefeed.setCallback(timecallback);
|
||||
mqtt.subscribe(&timefeed);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// wait 10 seconds for subscription messages
|
||||
// since we have no other tasks in this example.
|
||||
mqtt.processPackets(10000);
|
||||
|
||||
// keep the connection alive
|
||||
mqtt.ping();
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Example
|
||||
|
||||
Must use ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
Error examples by Todd Treece for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "...your SSID..."
|
||||
#define WLAN_PASS "...your password..."
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883 // 8883 for MQTTS
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||||
WiFiClient client;
|
||||
// or... use WiFiFlientSecure for SSL
|
||||
//WiFiClientSecure client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Error Reporting *********************************/
|
||||
|
||||
Adafruit_MQTT_Subscribe errors = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/errors");
|
||||
Adafruit_MQTT_Subscribe throttle = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/throttle");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
|
||||
// for some reason (only affects ESP8266, likely an arduino-builder bug).
|
||||
void MQTT_connect();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||||
|
||||
// Setup MQTT subscription for onoff feed
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
|
||||
// Setup MQTT subscriptions for throttle & error messages
|
||||
mqtt.subscribe(&throttle);
|
||||
mqtt.subscribe(&errors);
|
||||
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
// try to spend your time here
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(5000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("Got onoff: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
} else if(subscription == &errors) {
|
||||
Serial.print(F("ERROR: "));
|
||||
Serial.println((char *)errors.lastread);
|
||||
} else if(subscription == &throttle) {
|
||||
Serial.println((char *)throttle.lastread);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending photocell val "));
|
||||
Serial.print(x);
|
||||
Serial.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/****************************************************************
|
||||
Adafruit MQTT Library, Adafruit IO SSL/TLS Example for AirLift
|
||||
|
||||
Must use the latest version of nina-fw from:
|
||||
https://github.com/adafruit/nina-fw
|
||||
|
||||
Works great with Adafruit AirLift ESP32 Co-Processors!
|
||||
--> https://www.adafruit.com/product/4201
|
||||
--> https://www.adafruit.com/product/4116
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Brent Rubell for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
*******************************************************************/
|
||||
|
||||
#include <WiFiNINA.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// For AirLift Breakout/Wing/Shield: Configure the following to match the ESP32 Pins!
|
||||
#if !defined(SPIWIFI_SS)
|
||||
// Don't change the names of these #define's! they match the variant ones
|
||||
#define SPIWIFI SPI
|
||||
#define SPIWIFI_SS 11 // Chip select pin
|
||||
#define SPIWIFI_ACK 10 // a.k.a BUSY or READY pin
|
||||
#define ESP32_RESETN 9 // Reset pin
|
||||
#define ESP32_GPIO0 -1 // Not connected
|
||||
#define SET_PINS 1 // Pins were set using this IFNDEF
|
||||
#endif
|
||||
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "WLAN_SSID"
|
||||
#define WLAN_PASS "WIFI_PASSWORD"
|
||||
int keyIndex = 0; // your network key Index number (needed only for WEP)
|
||||
|
||||
int status = WL_IDLE_STATUS;
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
// Using port 8883 for MQTTS
|
||||
#define AIO_SERVERPORT 8883
|
||||
// Adafruit IO Account Configuration
|
||||
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)
|
||||
#define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME"
|
||||
#define AIO_KEY "YOUR_ADAFRUIT_IO_KEY"
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// WiFiSSLClient for SSL/TLS support
|
||||
WiFiSSLClient client;
|
||||
|
||||
// Setup the MQTT client class by WLAN_PASSing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'test' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish test = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/test");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Initialize serial and wait for port to open:
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
{
|
||||
; // wait for serial port to connect. Needed for native USB port only
|
||||
}
|
||||
|
||||
// if the AirLift's pins were defined above...
|
||||
#ifdef SET_PINS
|
||||
WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);
|
||||
#endif
|
||||
|
||||
// check for the wifi module
|
||||
while (WiFi.status() == WL_NO_MODULE)
|
||||
{
|
||||
Serial.println("Communication with WiFi module failed!");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
String fv = WiFi.firmwareVersion();
|
||||
if (fv < "1.0.0")
|
||||
{
|
||||
Serial.println("Please upgrade the firmware");
|
||||
}
|
||||
|
||||
// attempt to connect to Wifi network:
|
||||
Serial.print("Attempting to connect to SSID: ");
|
||||
Serial.println(WLAN_SSID);
|
||||
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
|
||||
do
|
||||
{
|
||||
status = WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
delay(100); // wait until connected
|
||||
} while (status != WL_CONNECTED);
|
||||
Serial.println("Connected to wifi");
|
||||
printWiFiStatus();
|
||||
}
|
||||
|
||||
uint32_t x = 0;
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending val "));
|
||||
Serial.print(x);
|
||||
Serial.print(F(" to test feed..."));
|
||||
if (!test.publish(x++))
|
||||
{
|
||||
Serial.println(F("Failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
// wait a couple seconds to avoid rate limit
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect()
|
||||
{
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0)
|
||||
{ // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0)
|
||||
{
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
||||
|
||||
void printWiFiStatus()
|
||||
{
|
||||
// print the SSID of the network you're attached to:
|
||||
Serial.print("SSID: ");
|
||||
Serial.println(WiFi.SSID());
|
||||
|
||||
// print your board's IP address:
|
||||
IPAddress ip = WiFi.localIP();
|
||||
Serial.print("IP Address: ");
|
||||
Serial.println(ip);
|
||||
|
||||
// print the received signal strength:
|
||||
long rssi = WiFi.RSSI();
|
||||
Serial.print("signal strength (RSSI):");
|
||||
Serial.print(rssi);
|
||||
Serial.println(" dBm");
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Adafruit IO SSL/TLS example
|
||||
|
||||
Must use the latest version of ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
SSL/TLS additions by Todd Treece for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "WLAN_SSID"
|
||||
#define WLAN_PASS "WIFI_PASSWORD"
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
// Using port 8883 for MQTTS
|
||||
#define AIO_SERVERPORT 8883
|
||||
// Adafruit IO Account Configuration
|
||||
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)
|
||||
#define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME"
|
||||
#define AIO_KEY "YOUR_ADAFRUIT_IO_KEY"
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// WiFiFlientSecure for SSL/TLS support
|
||||
WiFiClientSecure client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
// io.adafruit.com SHA1 fingerprint
|
||||
static const char *fingerprint PROGMEM = "77 00 54 2D DA E7 D8 03 27 31 23 99 EB 27 DB CB A5 4C 57 18";
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'test' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish test = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/test");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
delay(1000);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
delay(2000);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||||
|
||||
// check the fingerprint of io.adafruit.com's SSL cert
|
||||
client.setFingerprint(fingerprint);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending val "));
|
||||
Serial.print(x);
|
||||
Serial.print(F(" to test feed..."));
|
||||
if (! test.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
// wait a couple seconds to avoid rate limit
|
||||
delay(2000);
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Adafruit IO SSL/TLS example
|
||||
|
||||
Must use the latest version of ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
Time additions by Todd Treece for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
#define WLAN_SSID "network"
|
||||
#define WLAN_PASS "password"
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 8883
|
||||
#define AIO_USERNAME "user"
|
||||
#define AIO_KEY "key"
|
||||
|
||||
WiFiClientSecure client;
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
Adafruit_MQTT_Subscribe timefeed = Adafruit_MQTT_Subscribe(&mqtt, "time/seconds");
|
||||
|
||||
// set timezone offset from UTC
|
||||
int timeZone = -4; // UTC - 4 eastern daylight time (nyc)
|
||||
int interval = 4; // trigger every X hours
|
||||
int hour = 0; // current hour
|
||||
|
||||
void timecallback(uint32_t current) {
|
||||
|
||||
// stash previous hour
|
||||
int previous = hour;
|
||||
|
||||
// adjust to local time zone
|
||||
current += (timeZone * 60 * 60);
|
||||
|
||||
// calculate current hour
|
||||
hour = (current / 60 / 60) % 24;
|
||||
|
||||
// only trigger on interval
|
||||
if((hour != previous) && (hour % interval) == 0) {
|
||||
Serial.println("Run your code here");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.print(F("Adafruit IO Time Demo"));
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(F("."));
|
||||
}
|
||||
Serial.println(F(" WiFi connected."));
|
||||
|
||||
timefeed.setCallback(timecallback);
|
||||
mqtt.subscribe(&timefeed);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// wait 10 seconds for subscription messages
|
||||
// since we have no other tasks in this example.
|
||||
mqtt.processPackets(10000);
|
||||
|
||||
// keep the connection alive
|
||||
mqtt.ping();
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Example
|
||||
|
||||
Must use ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
// the on off button feed turns this LED on/off
|
||||
#define LED 2
|
||||
// the slider feed sets the PWM output of this pin
|
||||
#define PWMOUT 12
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "...your SSID..."
|
||||
#define WLAN_PASS "...your password..."
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883 // use 8883 for SSL
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||||
WiFiClient client;
|
||||
// or... use WiFiFlientSecure for SSL
|
||||
//WiFiClientSecure client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
Adafruit_MQTT_Subscribe slider = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/slider");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
|
||||
// for some reason (only affects ESP8266, likely an arduino-builder bug).
|
||||
void MQTT_connect();
|
||||
|
||||
void setup() {
|
||||
pinMode(LED, OUTPUT);
|
||||
pinMode(PWMOUT, OUTPUT);
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||||
|
||||
// Setup MQTT subscription for onoff & slider feed.
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
mqtt.subscribe(&slider);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
// try to spend your time here
|
||||
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(5000))) {
|
||||
// Check if its the onoff button feed
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("On-Off button: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
|
||||
if (strcmp((char *)onoffbutton.lastread, "ON") == 0) {
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
if (strcmp((char *)onoffbutton.lastread, "OFF") == 0) {
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
// check if its the slider feed
|
||||
if (subscription == &slider) {
|
||||
Serial.print(F("Slider: "));
|
||||
Serial.println((char *)slider.lastread);
|
||||
uint16_t sliderval = atoi((char *)slider.lastread); // convert to a number
|
||||
analogWrite(PWMOUT, sliderval);
|
||||
}
|
||||
}
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
if(! mqtt.ping()) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
# Adafruit MQTT Library Arbitrary Data Publish Example
|
||||
|
||||
This example illustrates publishing an arbitrary data packet using the Adafruit MQTT library to an MQTT feed which can then be parsed by the included python subscriber client. Possible usage cases include adding metadata (collection time, sensor info etc) to a datapoint.
|
||||
|
||||

|
||||
|
||||
My motivation for this was wanting to be able to include metadata to a post.
|
||||
Specifically, I was playing around with a [Teviso RD3024 radiation sensor](http://www.teviso.com/en/products/radiation-sensor-rd3024.htm), and a salvaged Americium radiation source from a smoke detector, at varying distances from the sensor. I wanted a way to associate the collection time, and distance between the source and sensor with the actual radiation reading itself.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Installing and configuring Mosquitto broker (minimal working setup):
|
||||
|
||||
####_Installing on Raspberry Pi/Linux:_
|
||||
|
||||
```bash
|
||||
sudo apt-get install mosquitto
|
||||
cd /etc/mosquitto/
|
||||
#See "Configuring Mosquitto Broker below"
|
||||
```
|
||||
|
||||
####_Installing On a Mac:_
|
||||
```bash
|
||||
brew install mosquitto
|
||||
cd /usr/local/etc/mosquitto
|
||||
#See "Configuring Mosquitto Broker below"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
####Configuring Mosquitto broker
|
||||
```bash
|
||||
sudo nano mosquitto.conf
|
||||
```
|
||||
Now we have to enable a password file to correctly interface with the Adafruit MQTT library. Scroll about two thirds of the way down until you see:
|
||||
|
||||
```bash
|
||||
# -----------------------------------------------------------------
|
||||
# Default authentication and topic access control
|
||||
# -----------------------------------------------------------------
|
||||
```
|
||||
|
||||
You should see `#password_file` about a paragraph after that.
|
||||
Change
|
||||
|
||||
```bash
|
||||
#password_file
|
||||
```
|
||||
|
||||
To
|
||||
|
||||
```bash
|
||||
password_file pwfile
|
||||
```
|
||||
|
||||
Now `ctrl-x` to save and exit.
|
||||
|
||||
You're almost done! We just have to create and populate the password file we just configured. The default user info is:
|
||||
* **Arduino Subscriber:**
|
||||
* Username: TestUser
|
||||
* Password: TestUser
|
||||
|
||||
* **Python Subscriber:**
|
||||
* Username: TestPy
|
||||
* Password: TestPy
|
||||
|
||||
```bash
|
||||
touch pwfile #create the password file
|
||||
mosquitto_passwd pwfile TestUser #Enter and confirm password when prompted
|
||||
mosquitto_passwd pwfile TestPy #Enter and confirm password when prompted
|
||||
```
|
||||
|
||||
####Running Mosquitto broker
|
||||
Now run Mosquitto broker to allow Arduino publisher and Python subscriber to communicate
|
||||
|
||||
```bash
|
||||
mosquitto
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using Example Python Subscriber:
|
||||
|
||||
####Installing Python subscriber
|
||||
Install dependencies if you haven't already
|
||||
```bash
|
||||
cd ../Adafruit_MQTT_Library/examples/mqtt_arbitrary_buffer/python_subscriber
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
|
||||
####Installing Python subscriber
|
||||
Run python script with default values and watch your parsed data print out.
|
||||
```bash
|
||||
python subscriber.py #Add -h flag to see modifiable options
|
||||
```
|
||||
|
||||
Assuming that the Mosquitto broker is running in the background and the Adafruit_MQTT client (Arduino) is publishing, you should see the example data print out every 10 seconds.
|
||||
|
||||
```bash
|
||||
MQTT: Connection successful
|
||||
Connection successful
|
||||
Subscribed to /feeds/arb_packet
|
||||
Received char Array: "Hello!", val1: -4533, val2: 73102, val3: 3354...
|
||||
Received char Array: "Hello!", val1: -4533, val2: 83611, val3: 3354...
|
||||
Received char Array: "Hello!", val1: -4533, val2: 94115, val3: 3354...
|
||||
```
|
|
@ -0,0 +1,184 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library Arbitrary Data Example
|
||||
|
||||
Must use ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Stuart Feichtinger
|
||||
Modifed from the mqtt_esp8266 example written by Tony DiCola for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "...your SSID..."
|
||||
#define WLAN_PASS "...your password..."
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define ARB_SERVER "...host computer ip address..."
|
||||
#define ARB_SERVERPORT 1883 // use 8883 for SSL
|
||||
#define ARB_USERNAME "TestUser"
|
||||
#define ARB_PW "TestUser"
|
||||
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||||
WiFiClient client;
|
||||
// or... use WiFiFlientSecure for SSL
|
||||
//WiFiClientSecure client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, ARB_SERVER, ARB_SERVERPORT, ARB_USERNAME, ARB_PW);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'arb_packet' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
#define ARB_FEED "/feeds/arb_packet"
|
||||
Adafruit_MQTT_Publish ap = Adafruit_MQTT_Publish(&mqtt, ARB_FEED);
|
||||
|
||||
|
||||
// Arbitrary Payload
|
||||
// Union allows for easier interaction of members in struct form with easy publishing
|
||||
// of "raw" bytes
|
||||
typedef union{
|
||||
//Customize struct with whatever variables/types you like.
|
||||
|
||||
struct __attribute__((__packed__)){ // packed to eliminate padding for easier parsing.
|
||||
char charAry[10];
|
||||
int16_t val1;
|
||||
unsigned long val2;
|
||||
uint16_t val3;
|
||||
}s;
|
||||
|
||||
uint8_t raw[sizeof(s)]; // For publishing
|
||||
|
||||
/*
|
||||
// Alternate Option with anonymous struct, but manual byte count:
|
||||
|
||||
struct __attribute__((__packed__)){ // packed to eliminate padding for easier parsing.
|
||||
char charAry[10]; // 10 x 1 byte = 10 bytes
|
||||
int16_t val1; // 1 x 2 bytes = 2 bytes
|
||||
unsigned long val2; // 1 x 4 bytes = 4 bytes
|
||||
uint16_t val3; // 1 x 2 bytes = 2 bytes
|
||||
-------------------
|
||||
TOTAL = 18 bytes
|
||||
};
|
||||
uint8_t raw[18]; // For publishing
|
||||
*/
|
||||
|
||||
} packet_t;
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
|
||||
// for some reason (only affects ESP8266, likely an arduino-builder bug).
|
||||
void MQTT_connect();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print(F("Connecting to "));
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(F("."));
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("WiFi connected"));
|
||||
Serial.println(F("IP address: ")); Serial.println(WiFi.localIP());
|
||||
|
||||
}
|
||||
|
||||
packet_t arbPac;
|
||||
|
||||
const char strVal[] PROGMEM = "Hello!";
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
//Update arbitrary packet values
|
||||
strcpy_P(arbPac.s.charAry, strVal);
|
||||
arbPac.s.val1 = -4533;
|
||||
arbPac.s.val2 = millis();
|
||||
arbPac.s.val3 = 3354;
|
||||
|
||||
/*
|
||||
// Alternate Union with anonymous struct
|
||||
// (see union declaration above)
|
||||
|
||||
strcpy_P(arbPac.charAry, strVal);
|
||||
arbPac.val1 = -4533;
|
||||
arbPac.val2 = millis();
|
||||
arbPac.val3 = 3354;
|
||||
*/
|
||||
|
||||
if (! ap.publish(arbPac.raw, sizeof(packet_t)))
|
||||
Serial.println(F("Publish Failed."));
|
||||
else {
|
||||
Serial.println(F("Publish Success!"));
|
||||
delay(500);
|
||||
}
|
||||
|
||||
delay(10000);
|
||||
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
// NOT required if you are publishing once every KEEPALIVE seconds
|
||||
/*
|
||||
if(! mqtt.ping()) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print(F("Connecting to MQTT... "));
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println(F("Retrying MQTT connection in 5 seconds..."));
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
Serial.println(F("MQTT Connected!"));
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 865 KiB |
|
@ -0,0 +1 @@
|
|||
paho-mqtt>=1.1
|
|
@ -0,0 +1,114 @@
|
|||
'''MQTT subscriber for Adafruit MQTT library mqtt_arbitrary_buffer example'''
|
||||
import paho.mqtt.client as mqtt
|
||||
import argparse
|
||||
import struct
|
||||
import array
|
||||
import sys
|
||||
|
||||
return_str =[
|
||||
"Connection successful",
|
||||
"incorrect protocol version",
|
||||
"invalid client identifier",
|
||||
"server unavailable",
|
||||
"bad username or password",
|
||||
"not authorised"
|
||||
]
|
||||
|
||||
args = None
|
||||
|
||||
# The callback for when the client receives a CONNACK response from the server.
|
||||
def on_connect(client, userdata, rc):
|
||||
"""callback function on connect. Subscribes or exits depending on outcome"""
|
||||
print("MQTT: "),
|
||||
print(return_str[rc])
|
||||
if(rc > 1):
|
||||
print("Connection refused - " + return_str[rc])
|
||||
sys.exit(rc)
|
||||
# Subscribing in on_connect() means that if we lose the connection and
|
||||
# reconnect then subscriptions will be renewed.
|
||||
else:
|
||||
print(return_str[rc])
|
||||
client.subscribe(args.topic)
|
||||
print("Subscribed to {}".format(args.topic))
|
||||
|
||||
def on_disconnect(client, userdata, rc):
|
||||
"""Callback for disconnect"""
|
||||
if rc != 0:
|
||||
print("Unexpected disconnection.")
|
||||
client.reconnect()
|
||||
|
||||
# The callback for when a PUBLISH message is received from the server.
|
||||
def on_message(client, userdata, msg):
|
||||
try:
|
||||
pMsg = parseMsg(msg.payload)
|
||||
print("Received char Array: \"{}\", val1: {}, val2: {}, val3: {}...".format(pMsg[0], pMsg[1], pMsg[2], pMsg[3]))
|
||||
|
||||
except Exception as err:
|
||||
print err
|
||||
|
||||
|
||||
|
||||
def argBegin():
|
||||
parser = argparse.ArgumentParser(description='MQTT subscriber for Adafruit MQTT library mqtt_arbitrary_buffer example')
|
||||
parser.add_argument("--host", default="localhost", help='mqtt host to connect to. Defaults to localhost.')
|
||||
parser.add_argument("-p", "--port", default=1883, help='network port to connect to. Defaults to 1883.')
|
||||
parser.add_argument("-t", "--topic", nargs='*', default="/feeds/arb_packet", help="mqtt topic to subscribe to. May be repeated multiple times.")
|
||||
parser.add_argument("-u", "--username", default="testPy", help="provide a username (requires MQTT 3.1 broker)")
|
||||
parser.add_argument("-P", "--password", default="testPy", help="provide a password (requires MQTT 3.1 broker)")
|
||||
parser.add_argument("-k", "--keepalive", default=60, help="keep alive in seconds for this client. Defaults to 60.")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def parseMsg(payload):
|
||||
"""Parses C struct from MQTT publisher Adafruit MQTT client to Python list"""
|
||||
|
||||
arr = array.array('B', payload) #convert python list to C-like array of unsigned char (B)
|
||||
|
||||
parsedStruct = struct.Struct('< 10s h L H') #define struct template (see below)
|
||||
'''
|
||||
Format of Struct from Adafruit MQTT client, Arduino, etc:
|
||||
|
||||
Adafruit MQTT client == Little endian (<)
|
||||
|
||||
Var NAME | C TYPE (python symbol) | size of member x bytes
|
||||
-------------------------------------------------------------------
|
||||
"charAry" | uchar (s) | 10s x 1 = 10 bytes
|
||||
"val1" | int16 / short (h) | 1h x 2 = 2 bytes
|
||||
"val2" | unsigned long (L) | 1L x 4 = 4 bytes
|
||||
"val3" | uint16/unsigned short(H)| 1H x 2 = 2 bytes
|
||||
------------------------------------------------------------------
|
||||
Total packet size = | 18 bytes |
|
||||
|
||||
See Section 7.3.2 of Python struct module documentation for complete format list
|
||||
https://docs.python.org/2/library/struct.html
|
||||
'''
|
||||
|
||||
charAry, val1, val2, val3 = parsedStruct.unpack_from(arr) #convert byte array to formatted struct
|
||||
charAry = charAry.rstrip(' \t\r\n\0') #remove trailing white space from buffer
|
||||
return charAry, val1, val2, val3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
"""Wait for incoming message published by Adafruit MQTT client"""
|
||||
global args
|
||||
args = argBegin()
|
||||
client = mqtt.Client()
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
client.username_pw_set(args.username, args.password)
|
||||
client.connect(args.host, args.port, args.keepalive)
|
||||
|
||||
# Blocking call that processes network traffic, dispatches callbacks and
|
||||
# handles reconnecting.
|
||||
# Other loop*() functions are available that give a threaded interface and a
|
||||
# manual interface.
|
||||
client.loop_forever()
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -0,0 +1,147 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Example
|
||||
|
||||
Must use ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board & Feather
|
||||
----> https://www.adafruit.com/product/2471
|
||||
----> https://www.adafruit.com/products/2821
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "...your SSID..."
|
||||
#define WLAN_PASS "...your password..."
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883 // use 8883 for SSL
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||||
WiFiClient client;
|
||||
// or... use WiFiFlientSecure for SSL
|
||||
//WiFiClientSecure client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
|
||||
// for some reason (only affects ESP8266, likely an arduino-builder bug).
|
||||
void MQTT_connect();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||||
|
||||
// Setup MQTT subscription for onoff feed.
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
// try to spend your time here
|
||||
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(5000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("Got: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending photocell val "));
|
||||
Serial.print(x);
|
||||
Serial.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
// NOT required if you are publishing once every KEEPALIVE seconds
|
||||
/*
|
||||
if(! mqtt.ping()) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library ESP8266 Example
|
||||
|
||||
Must use ESP8266 Arduino from:
|
||||
https://github.com/esp8266/Arduino
|
||||
|
||||
Works great with Adafruit's Huzzah ESP board:
|
||||
----> https://www.adafruit.com/product/2471
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
#define WLAN_SSID "network"
|
||||
#define WLAN_PASS "password"
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883
|
||||
#define AIO_USERNAME "user"
|
||||
#define AIO_KEY "key"
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
|
||||
WiFiClient client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'time' for subscribing to current time
|
||||
Adafruit_MQTT_Subscribe timefeed = Adafruit_MQTT_Subscribe(&mqtt, "time/seconds");
|
||||
|
||||
// Setup a feed called 'slider' for subscribing to changes on the slider
|
||||
Adafruit_MQTT_Subscribe slider = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/slider", MQTT_QOS_1);
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes to the button
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff", MQTT_QOS_1);
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
int sec;
|
||||
int min;
|
||||
int hour;
|
||||
|
||||
int timeZone = -4; // utc-4 eastern daylight time (nyc)
|
||||
|
||||
void timecallback(uint32_t current) {
|
||||
|
||||
// adjust to local time zone
|
||||
current += (timeZone * 60 * 60);
|
||||
|
||||
// calculate current time
|
||||
sec = current % 60;
|
||||
current /= 60;
|
||||
min = current % 60;
|
||||
current /= 60;
|
||||
hour = current % 24;
|
||||
|
||||
// print hour
|
||||
if(hour == 0 || hour == 12)
|
||||
Serial.print("12");
|
||||
if(hour < 12)
|
||||
Serial.print(hour);
|
||||
else
|
||||
Serial.print(hour - 12);
|
||||
|
||||
// print mins
|
||||
Serial.print(":");
|
||||
if(min < 10) Serial.print("0");
|
||||
Serial.print(min);
|
||||
|
||||
// print seconds
|
||||
Serial.print(":");
|
||||
if(sec < 10) Serial.print("0");
|
||||
Serial.print(sec);
|
||||
|
||||
if(hour < 12)
|
||||
Serial.println(" am");
|
||||
else
|
||||
Serial.println(" pm");
|
||||
|
||||
}
|
||||
|
||||
void slidercallback(double x) {
|
||||
Serial.print("Hey we're in a slider callback, the slider value is: ");
|
||||
Serial.println(x);
|
||||
}
|
||||
|
||||
void onoffcallback(char *data, uint16_t len) {
|
||||
Serial.print("Hey we're in a onoff callback, the button value is: ");
|
||||
Serial.println(data);
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Connect to WiFi access point.
|
||||
Serial.println(); Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(WLAN_SSID);
|
||||
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: "); Serial.println(WiFi.localIP());
|
||||
|
||||
timefeed.setCallback(timecallback);
|
||||
slider.setCallback(slidercallback);
|
||||
onoffbutton.setCallback(onoffcallback);
|
||||
|
||||
// Setup MQTT subscription for time feed.
|
||||
mqtt.subscribe(&timefeed);
|
||||
mqtt.subscribe(&slider);
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets and callback em' busy subloop
|
||||
// try to spend your time here:
|
||||
mqtt.processPackets(10000);
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
// NOT required if you are publishing once every KEEPALIVE seconds
|
||||
|
||||
if(! mqtt.ping()) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
uint8_t retries = 3;
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 10 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(10000); // wait 10 seconds
|
||||
retries--;
|
||||
if (retries == 0) {
|
||||
// basically die and wait for WDT to reset me
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library Ethernet Example
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Alec Moore
|
||||
Derived from the code written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <SPI.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
#include <Ethernet.h>
|
||||
#include <EthernetClient.h>
|
||||
#include <Dns.h>
|
||||
#include <Dhcp.h>
|
||||
|
||||
/************************* Ethernet Client Setup *****************************/
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
|
||||
//Uncomment the following, and set to a valid ip if you don't have dhcp available.
|
||||
//IPAddress iotIP (192, 168, 0, 42);
|
||||
//Uncomment the following, and set to your preference if you don't have automatic dns.
|
||||
//IPAddress dnsIP (8, 8, 8, 8);
|
||||
//If you uncommented either of the above lines, make sure to change "Ethernet.begin(mac)" to "Ethernet.begin(mac, iotIP)" or "Ethernet.begin(mac, iotIP, dnsIP)"
|
||||
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
//Set up the ethernet client
|
||||
EthernetClient client;
|
||||
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
// You don't need to change anything below this line!
|
||||
#define halt(s) { Serial.println(F( s )); while(1); }
|
||||
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Initialise the Client
|
||||
Serial.print(F("\nInit the Client..."));
|
||||
Ethernet.begin(mac);
|
||||
delay(1000); //give the ethernet a second to initialize
|
||||
|
||||
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(1000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("Got: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending photocell val "));
|
||||
Serial.print(x);
|
||||
Serial.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
if(! mqtt.ping()) {
|
||||
mqtt.disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#include <Adafruit_SleepyDog.h>
|
||||
#include <SoftwareSerial.h>
|
||||
#include "Adafruit_FONA.h"
|
||||
|
||||
#define halt(s) { Serial.println(F( s )); while(1); }
|
||||
|
||||
extern Adafruit_FONA fona;
|
||||
extern SoftwareSerial fonaSS;
|
||||
|
||||
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password) {
|
||||
Watchdog.reset();
|
||||
|
||||
Serial.println(F("Initializing FONA....(May take 3 seconds)"));
|
||||
|
||||
fonaSS.begin(4800); // if you're using software serial
|
||||
|
||||
if (! fona.begin(fonaSS)) { // can also try fona.begin(Serial1)
|
||||
Serial.println(F("Couldn't find FONA"));
|
||||
return false;
|
||||
}
|
||||
fonaSS.println("AT+CMEE=2");
|
||||
Serial.println(F("FONA is OK"));
|
||||
Watchdog.reset();
|
||||
Serial.println(F("Checking for network..."));
|
||||
while (fona.getNetworkStatus() != 1) {
|
||||
delay(500);
|
||||
}
|
||||
|
||||
Watchdog.reset();
|
||||
delay(5000); // wait a few seconds to stabilize connection
|
||||
Watchdog.reset();
|
||||
|
||||
fona.setGPRSNetworkSettings(apn, username, password);
|
||||
|
||||
Serial.println(F("Disabling GPRS"));
|
||||
fona.enableGPRS(false);
|
||||
|
||||
Watchdog.reset();
|
||||
delay(5000); // wait a few seconds to stabilize connection
|
||||
Watchdog.reset();
|
||||
|
||||
Serial.println(F("Enabling GPRS"));
|
||||
if (!fona.enableGPRS(true)) {
|
||||
Serial.println(F("Failed to turn GPRS on"));
|
||||
return false;
|
||||
}
|
||||
Watchdog.reset();
|
||||
|
||||
return true;
|
||||
}
|
169
libraries/Adafruit_MQTT_Library/examples/mqtt_fona/mqtt_fona.ino
Normal file
169
libraries/Adafruit_MQTT_Library/examples/mqtt_fona/mqtt_fona.ino
Normal file
|
@ -0,0 +1,169 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library FONA Example
|
||||
|
||||
Designed specifically to work with the Adafruit FONA
|
||||
----> http://www.adafruit.com/products/1946
|
||||
----> http://www.adafruit.com/products/1963
|
||||
----> http://www.adafruit.com/products/2468
|
||||
----> http://www.adafruit.com/products/2542
|
||||
|
||||
These cellular modules use TTL Serial to communicate, 2 pins are
|
||||
required to interface.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <Adafruit_SleepyDog.h>
|
||||
#include <SoftwareSerial.h>
|
||||
#include "Adafruit_FONA.h"
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_FONA.h"
|
||||
|
||||
/*************************** FONA Pins ***********************************/
|
||||
|
||||
// Default pins for Feather 32u4 FONA
|
||||
#define FONA_RX 9
|
||||
#define FONA_TX 8
|
||||
#define FONA_RST 4
|
||||
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
|
||||
|
||||
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
|
||||
// Optionally configure a GPRS APN, username, and password.
|
||||
// You might need to do this to access your network's GPRS/data
|
||||
// network. Contact your provider for the exact APN, username,
|
||||
// and password values. Username and password are optional and
|
||||
// can be removed, but APN is required.
|
||||
#define FONA_APN ""
|
||||
#define FONA_USERNAME ""
|
||||
#define FONA_PASSWORD ""
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
|
||||
Adafruit_MQTT_FONA mqtt(&fona, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
// You don't need to change anything below this line!
|
||||
#define halt(s) { Serial.println(F( s )); while(1); }
|
||||
|
||||
// FONAconnect is a helper function that sets up the FONA and connects to
|
||||
// the GPRS network. See the fonahelper.cpp tab above for the source!
|
||||
boolean FONAconnect(const __FlashStringHelper *apn, const __FlashStringHelper *username, const __FlashStringHelper *password);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
// How many transmission failures in a row we're willing to be ok with before reset
|
||||
uint8_t txfailures = 0;
|
||||
#define MAXTXFAILURES 3
|
||||
|
||||
void setup() {
|
||||
while (!Serial);
|
||||
|
||||
// Watchdog is optional!
|
||||
//Watchdog.enable(8000);
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println(F("Adafruit FONA MQTT demo"));
|
||||
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
|
||||
Watchdog.reset();
|
||||
delay(5000); // wait a few seconds to stabilize connection
|
||||
Watchdog.reset();
|
||||
|
||||
// Initialise the FONA module
|
||||
while (! FONAconnect(F(FONA_APN), F(FONA_USERNAME), F(FONA_PASSWORD))) {
|
||||
Serial.println("Retrying FONA");
|
||||
}
|
||||
|
||||
Serial.println(F("Connected to Cellular!"));
|
||||
|
||||
Watchdog.reset();
|
||||
delay(5000); // wait a few seconds to stabilize connection
|
||||
Watchdog.reset();
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Make sure to reset watchdog every loop iteration!
|
||||
Watchdog.reset();
|
||||
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
Watchdog.reset();
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending photocell val "));
|
||||
Serial.print(x);
|
||||
Serial.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
txfailures++;
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
txfailures = 0;
|
||||
}
|
||||
|
||||
Watchdog.reset();
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(5000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("Got: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
}
|
||||
}
|
||||
|
||||
// ping the server to keep the mqtt connection alive, only needed if we're not publishing
|
||||
//if(! mqtt.ping()) {
|
||||
// Serial.println(F("MQTT Ping failed."));
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library WINC1500 Example
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <SPI.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
#include <WiFi101.h>
|
||||
|
||||
/************************* WiFI Setup *****************************/
|
||||
#define WINC_CS 8
|
||||
#define WINC_IRQ 7
|
||||
#define WINC_RST 4
|
||||
#define WINC_EN 2 // or, tie EN to VCC
|
||||
|
||||
char ssid[] = "yournetwork"; // your network SSID (name)
|
||||
char pass[] = "yourpassword"; // your network password (use for WPA, or use as key for WEP)
|
||||
int keyIndex = 0; // your network key Index number (needed only for WEP)
|
||||
|
||||
int status = WL_IDLE_STATUS;
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883
|
||||
#define AIO_USERNAME "adafruitiousername"
|
||||
#define AIO_KEY "adafruitiokey"
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
//Set up the wifi client
|
||||
WiFiClient client;
|
||||
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
// You don't need to change anything below this line!
|
||||
#define halt(s) { Serial.println(F( s )); while(1); }
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
#define LEDPIN 13
|
||||
|
||||
|
||||
void setup() {
|
||||
WiFi.setPins(WINC_CS, WINC_IRQ, WINC_RST, WINC_EN);
|
||||
|
||||
while (!Serial);
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println(F("Adafruit MQTT demo for WINC1500"));
|
||||
|
||||
// Initialise the Client
|
||||
Serial.print(F("\nInit the WiFi module..."));
|
||||
// check for the presence of the breakout
|
||||
if (WiFi.status() == WL_NO_SHIELD) {
|
||||
Serial.println("WINC1500 not present");
|
||||
// don't continue:
|
||||
while (true);
|
||||
}
|
||||
Serial.println("ATWINC OK!");
|
||||
|
||||
pinMode(LEDPIN, OUTPUT);
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(5000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Serial.print(F("Got: "));
|
||||
Serial.println((char *)onoffbutton.lastread);
|
||||
|
||||
if (0 == strcmp((char *)onoffbutton.lastread, "OFF")) {
|
||||
digitalWrite(LEDPIN, LOW);
|
||||
}
|
||||
if (0 == strcmp((char *)onoffbutton.lastread, "ON")) {
|
||||
digitalWrite(LEDPIN, HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can publish stuff!
|
||||
Serial.print(F("\nSending photocell val "));
|
||||
Serial.print(x);
|
||||
Serial.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Serial.println(F("Failed"));
|
||||
} else {
|
||||
Serial.println(F("OK!"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// attempt to connect to Wifi network:
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print("Attempting to connect to SSID: ");
|
||||
Serial.println(ssid);
|
||||
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
|
||||
status = WiFi.begin(ssid, pass);
|
||||
|
||||
// wait 10 seconds for connection:
|
||||
uint8_t timeout = 10;
|
||||
while (timeout && (WiFi.status() != WL_CONNECTED)) {
|
||||
timeout--;
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Connecting to MQTT... ");
|
||||
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Serial.println(mqtt.connectErrorString(ret));
|
||||
Serial.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
}
|
||||
Serial.println("MQTT Connected!");
|
||||
}
|
116
libraries/Adafruit_MQTT_Library/examples/mqtt_yun/mqtt_yun.ino
Normal file
116
libraries/Adafruit_MQTT_Library/examples/mqtt_yun/mqtt_yun.ino
Normal file
|
@ -0,0 +1,116 @@
|
|||
/***************************************************
|
||||
Adafruit MQTT Library Arduino Yun Example
|
||||
|
||||
Make sure your Arduino Yun is connected to a WiFi access point which
|
||||
has internet access. Also note this sketch uses the Console class
|
||||
for debug output so make sure to connect to the Yun over WiFi and
|
||||
open the serial monitor to see the console output.
|
||||
|
||||
Works great with the Arduino Yun:
|
||||
----> https://www.adafruit.com/products/1498
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Tony DiCola for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
#include <Bridge.h>
|
||||
#include <Console.h>
|
||||
#include <BridgeClient.h>
|
||||
#include "Adafruit_MQTT.h"
|
||||
#include "Adafruit_MQTT_Client.h"
|
||||
|
||||
/************************* Adafruit.io Setup *********************************/
|
||||
|
||||
#define AIO_SERVER "io.adafruit.com"
|
||||
#define AIO_SERVERPORT 1883
|
||||
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
|
||||
#define AIO_KEY "...your AIO key..."
|
||||
|
||||
|
||||
/************ Global State (you don't need to change this!) ******************/
|
||||
|
||||
// Create a BridgeClient instance to communicate using the Yun's bridge & Linux OS.
|
||||
BridgeClient client;
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
|
||||
|
||||
/****************************** Feeds ***************************************/
|
||||
|
||||
// Setup a feed called 'photocell' for publishing.
|
||||
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
|
||||
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");
|
||||
|
||||
// Setup a feed called 'onoff' for subscribing to changes.
|
||||
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
|
||||
void setup() {
|
||||
Bridge.begin();
|
||||
Console.begin();
|
||||
Console.println(F("Adafruit MQTT demo"));
|
||||
|
||||
// Setup MQTT subscription for onoff feed.
|
||||
mqtt.subscribe(&onoffbutton);
|
||||
}
|
||||
|
||||
uint32_t x=0;
|
||||
|
||||
void loop() {
|
||||
// Ensure the connection to the MQTT server is alive (this will make the first
|
||||
// connection and automatically reconnect when disconnected). See the MQTT_connect
|
||||
// function definition further below.
|
||||
MQTT_connect();
|
||||
|
||||
// this is our 'wait for incoming subscription packets' busy subloop
|
||||
Adafruit_MQTT_Subscribe *subscription;
|
||||
while ((subscription = mqtt.readSubscription(1000))) {
|
||||
if (subscription == &onoffbutton) {
|
||||
Console.print(F("Got: "));
|
||||
Console.println((char *)onoffbutton.lastread);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can publish stuff!
|
||||
Console.print(F("\nSending photocell val "));
|
||||
Console.print(x);
|
||||
Console.print("...");
|
||||
if (! photocell.publish(x++)) {
|
||||
Console.println(F("Failed"));
|
||||
} else {
|
||||
Console.println(F("OK!"));
|
||||
}
|
||||
|
||||
// ping the server to keep the mqtt connection alive
|
||||
if(! mqtt.ping()) {
|
||||
Console.println(F("MQTT Ping failed."));
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
|
||||
// Function to connect and reconnect as necessary to the MQTT server.
|
||||
// Should be called in the loop function and it will take care if connecting.
|
||||
void MQTT_connect() {
|
||||
int8_t ret;
|
||||
|
||||
// Stop if already connected.
|
||||
if (mqtt.connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Console.print("Connecting to MQTT... ");
|
||||
|
||||
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
|
||||
Console.println(mqtt.connectErrorString(ret));
|
||||
Console.println("Retrying MQTT connection in 5 seconds...");
|
||||
mqtt.disconnect();
|
||||
delay(5000); // wait 5 seconds
|
||||
}
|
||||
Console.println("MQTT Connected!");
|
||||
}
|
20
libraries/Adafruit_MQTT_Library/keywords.txt
Normal file
20
libraries/Adafruit_MQTT_Library/keywords.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
Adafruit_MQTT KEYWORD1
|
||||
Adafruit_MQTT_FONA KEYWORD1
|
||||
Adafruit_MQTT_Client KEYWORD1
|
||||
Adafruit_MQTT_Publish KEYWORD1
|
||||
Adafruit_MQTT_Subscribe KEYWORD1
|
||||
connect KEYWORD2
|
||||
connectErrorString KEYWORD2
|
||||
disconnect KEYWORD2
|
||||
connected KEYWORD2
|
||||
will KEYWORD2
|
||||
publish KEYWORD2
|
||||
subscribe KEYWORD2
|
||||
unsubscribe KEYWORD2
|
||||
readSubscription KEYWORD2
|
||||
ping KEYWORD2
|
||||
setCallback KEYWORD2
|
||||
connectServer KEYWORD2
|
||||
disconnectServer KEYWORD2
|
||||
readPacket KEYWORD2
|
||||
sendPacket KEYWORD2
|
9
libraries/Adafruit_MQTT_Library/library.properties
Normal file
9
libraries/Adafruit_MQTT_Library/library.properties
Normal file
|
@ -0,0 +1,9 @@
|
|||
name=Adafruit MQTT Library
|
||||
version=1.0.3
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=MQTT library that supports the FONA, ESP8266, Yun, and generic Arduino Client hardware.
|
||||
paragraph=Simple MQTT library that supports the bare minimum to publish and subscribe to topics.
|
||||
category=Communication
|
||||
url=https://github.com/adafruit/Adafruit_MQTT_Library
|
||||
architectures=*
|
Loading…
Add table
Add a link
Reference in a new issue