-
Extending the MQTT Protocol
Last month we deployed a change to Adafruit IO’s MQTT broker that allowed us to rate limit connection attempts. Although we don’t like to throttle or ban users, the change was necessary to protect Adafruit IO from abuse, and ensure the overall health of the service.
This presented a problem: How do we inform users when they have been throttled or banned? Ideally the MQTT protocol would allow for us to inform the user using a standard response, but currently the connection acknowledgement packet (
CONNACK
) has a limited set of response codes.The MQTT v3.1.1 protocol has the following values defined for the
CONNACK
packet response code:Value
Return Code Response
Description
0
0x00 Connection Accepted
Connection accepted
1
0x01 Connection Refused, unacceptable protocol version
The Server does not support the level of the MQTT protocol requested by the Client
2
0x02 Connection Refused, identifier rejected
The Client identifier is correct UTF-8 but not allowed by the Server
3
0x03 Connection Refused, Server unavailable
The Network Connection has been made but the MQTT service is unavailable
4
0x04 Connection Refused, bad user name or password
The data in the user name or password is malformed
5
0x05 Connection Refused, not authorized
The Client is not authorized to connect
6-255
Reserved for future use
The current set of codes didn’t allow us to clearly communicate the reason for disconnects to our users. We have extended the list of codes in the
CONNACK
packet to include connection throttle (0x06) and ban (0x07).Value
Return Code Response
Description
6
0x06 Connection Refused, throttled
Client has exceeded connection rate limit. Please try again later.
7
0x07 Connection Refused, banned
The client has been banned by the server administrator.
We have submitted these two new codes to the OASIS MQTT Technical Committee for comment, and we are adding support to our MQTT client libraries. If you would like to comment on these changes, please visit our IO forum and share your thoughts.
-
Using MQTT Last Will with Adafruit IO
MQTT’s last will feature allows you to ask the Adafruit IO servers to publish a message to a feed or group on your behalf. This is helpful if you would like to track when your device unexpectedly disconnects due to issues like network or power outages.
Here are some helpful tips from the IO forum that might help you if you are looking to use MQTT’s last will feature with Adafruit IO:
- The last will topic must match the normal IO MQTT topic format for feeds or group publishes.
- Last will is only published by the MQTT broker if the client fails to disconnect cleanly by sending the MQTT disconnect packet.
- Last will is only published by the MQTT broker if the the keep alive timeout expires, and the last will is not sent if your device reconnects within the timeout window. The Adafruit MQTT Library for Arduino has a default keep alive timeout of 5 minutes.
Here’s an example of setting a last will message using the Adafruit MQTT Library for Arduino:
// always set the last will message before calling connect. // if the device unexpectedly disconnects, the 'disconnect' // feed will receive the 'water monitor disconnected' message. mqtt.will("your_username_here/feeds/disconnect", "water monitor disconnected"); mqtt.connect();
-
State of IO 6.14.16
We’re continuing forward with refactoring our UI so that we can get to a point where it’s easier and quicker to build out new features. The front-end is also going to use the same API V2 that will be the future default API. As another reminder, it would be a good idea to explicitly set ‘/api/v1’ in your paths until you’re ready to upgrade to the ‘/api/v2’.
Stability of the entire system has been an ongoing project for us. We’re getting there, and continue to add more monitoring and fixes to reduce any future downtime.
Also, we’re updating our client libraries with new features and bug fixes. If you haven’t tried out the Go client library, now is a good time! If you have any suggestions for our libraries, please let us know in the forums.
Here are the stats for the past week:
* 35.6 million inserts of logged data in the last 7 days * 12578 users * 8,900 online feeds (29554 feeds total)
-
Postmortem 06.07.16
Issue
We had a brief outage this morning due to a disk space issue on our Sidekiq EC2 instance. One set of log files grew to almost 20GB, which is strange because they are setup to be rotated using
logrotate
. The files should have been limited to 700MB max. According tologrotate
status, it last ran on 6-1-16, when it should run daily viacron
.Fix
logrotate
is now setup to run hourly, and we are going have monit monitor disk space on all of our EC2 instances so we can catch this issue in the future. -
New Client Library in Go
We are pleased to announce the release of a new officially supported client library for the Adafruit IO API! We now have an client library for Go. This client meets a few goals for us, and hopefully provides a useful hook into Adafruit IO for curious and interested web developers.
It’s my (Adam) first project with the IO team, and so is a good starting place for exploring both the external API and the internal systems that drive it. It’s also a good chance for me to introduce my teammates to Go which is a very pleasant language to write web-connected code in. I’m a Rubyist by trade but exploring Go for lower level and Machine-to-Machine web services. I like it.
More client libraries means broader coverage of the Adafruit IO API. As web developers, we aren’t often forced to think of the systems we build from the outside in. By making a public API and building the client libraries for it, we have a chance to see what works and doesn’t work. That’s both from a design perspective–is this API “friendly”?–and from a very practical perspective. For example, I committed two bug fixes to Adafruit IO’s core codebase while building
io-client-go
, huge success! Today, this library covers version 1 of the Adafruit IO API, but we’re hard at work on version 2.More client libraries means more open doors for new developers. Adafruit IO’s primary goal is to be the easiest way to get your Internet of Things project online. That involves a big team of people at Adafruit working at every part of the stack: engineers building new hardware and writing new firmware, makers coming up with new projects and spending a lot of time on clearly communicating what they’re doing, web developers inventing new ways of building an accessible Internet of Things platform, and, MOST IMPORTANTLY, an awesome crowd of people who can think of things to do with the tools we build that we cannot think of ourselves.
This library isn’t the ending place for anyone’s project, but it could be the starting place for all kinds of interesting work. We don’t know! That’s the point! Here, take this, we made it for you, enjoy! :D
This isn’t the first client library we’ve built and it won’t be the last. If Go isn’t your style yet, make sure to check out similar tools in Python, Javascript, and Ruby. And when you’re using the things we’ve built in the Things you’re building, feel free to talk to us and tell us what’s good, what’s bad, or what you’d like to see. Leave a note in the bug tracker, on the forum, or in the respective client library’s GitHub repository.
And please, show us what you’re making! We would LOVE to see it almost as much as (I hope) you loved to build it. Also, speaking as a new member of the Adafruit team, I have never met a group of people more genuinely committed to supporting people at every level of experience than here at Adafruit.
As always, Adafruit’s open source work is supported by the clever, creative folks who shop at Adafruit and by the community that contributes in code to any of our open source projects.