NAV Navbar
CURL Arduino Python Circuitpython Ruby

Adafruit IO API Cookbook

This page contains a number of recipes related to Adafruit IO which have been found useful in the past. You can add and contribute to this file by filing an issue on the GitHub repository, or by editing this file and submitting a pull request.

Sending and Sending image data with Adafruit IO

Using an Image Block, you can automatically display a Base64 image data string on your dashboard by sending a Base64 image data string to an Adafruit IO feed.

Design Considerations: There are some important things to keep in mind when using this feature. Normal feeds are limited to 1KB of data, or about 1024 bytes, for publishing. Turning off feed history from the feed settings page allows publishing up to 100KB, or 102400 bytes, of data. Image conversion from binary to Base64 happens inside the browser, with no image pre-compression, and more importantly, conversion from binary to Base64 expands the size of the image data.

You’ll have to do your own testing to figure out what an appropriate image size and format (png, gif, or bmp) for you are. For example, the .png image used for testing below has an on disk size of 68089 bytes, but a Base64 value of 90788 bytes, an expansion factor of about 150%, which is really close to the limit.

base64imagepreview

Feed Identifiers

Names are for humans.

Keys are for computers.

You tell the computer the name, and it will tell you the key.

When using Adafruit IO, you'll want to tell the client (the computer) the feed's key instead of the feed's name.

For more information about this topic:, visit the learn guide for feeds or the IO Development blog post about naming feeds.

Webhook Receivers

Webhook receiver URLs give you a limited use, unique API address that you can send data to and have it appear in your Adafruit IO feed. Webhook URLs can be shared with anyone and used from anywhere on the web.

You can access a webhook by navigating to your feed and clicking the Webhooks button on the right-hand sidebar.

Raw Webhooks

If you want to receive the whole contents of webhook events--for example, when receiving webhook notifications from a service like Slack or GitHub where you don't have control over the payload the service is sending--add /raw to the end of the Adafruit IO webhook URL that you share with the service.

Notify Webhooks

If you only want to be notified that an event has happened, rather than have to handle all the data from an event--for example, if a service like GitHub is trying to send 7KB of JSON to your ESP8266--add /notify to the end of your Adafruit IO webhook URL. When data arrives, your feed will receive the message "ping".

Floating Point Data

If you're sending 3.1415 and only want to send 3.14 - reduce the value to the desired amount of precision in your code. You can round (up or down) or truncate this value to get it in the format you want Adafruit IO to display.

Sending and Storing JSON

// A basic data record
{
  "value": 22.587,
  "lat": 38.1123,
  "lon": -91.2325,
  "ele": 112
}

Because Adafruit IO supports additional features beyond a basic MQTT brokering service, such as location tagging for data points, the service supports data in the JSON format described in the HTTP create data API description.

This lets us store the individual value, 22.587, and data about the value: its latitude, longitude, and elevation. Data about the data is "metadata"!

But what happens when the value you want to send is itself JSON? Good news! There are a few solutions available to you in that situation.

Double encoded JSON strings

The safest way to can send JSON data as a value is to "double encode" it before sending, in which case IO will treat it as a raw string. If you're using something like javascript's JSON.stringify function or Ruby's JSON.generate, double encoding means passing the result of JSON.stringify through JSON.stringify a second time.

JSON.stringify({
  "value": JSON.stringify({"sensor-1":22.587,"sensor-2":13.182})
})

The double encoded JSON string can be sent directly through Adafruit IO without interference from our processing system, because the processing system will not interpret it as JSON. In your receiving code, because the value passed through includes surrounding double quotes, you have to call your parse function twice to restore the JSON object.

var data = JSON.parse(message)
var value = JSON.parse(data.value)

IO formatted JSON

{
  "value": {"sensor-1":22.587,"sensor-2":13.182},
  "lat": 38.1123,
  "lon": -91.2325,
  "ele": 112
}

The simplest way to send JSON data to Adafruit IO is include it directly in the datum formatted record you send to IO. For example, if instead of 22.587, I wanted to send something like, {"sensor-1":22.587,"sensor-2":13.182}, the "wrapped" version would look like the value on the right.

It's worth noting that because Adafruit IO parses the entire JSON object that you send it, any valid JSON will be parsed and when it is stored in our system and forwarded to any subscribers, it will be regenerated. The significance of that is that if you publish JSON data with whitespace, it will be stored and republished without whitespace, because our generator produces the most compact JSON format possible.

Non-IO formatted JSON

curl -H "Content-Type: application/json" \
    -H "X-AIO-Key: toomanysecrets" \
    --data '{"sensor-1":22.587,"sensor-2":13.182}' \
    https://io.adafruit.com/api/v2/username/feeds/feed-key/data

Another way you can send raw JSON data is to just send it. If Adafruit IO doesn't find a "value" key in the JSON object you send, it will treat the whole blob as plain text and store and forward the data. That means with our example JSON object, sending the string {"sensor-1":22.587,"sensor-2":13.182} will result in {"sensor-1":22.587,"sensor-2":13.182} being stored in IO and sent to MQTT subscribers.

NOTE: This solution is the riskiest, because if your JSON blob includes the key named value, then IO will interpret that as the value you want to store and ignore all the other keys.

That's not JSON at all!

If you want to be absolutely sure that Adafruit IO will not interfere with the data you're sending, encode it as a Base64 string first.

btoa(JSON.stringify({ "something": "here" }))
// "eyJzb21ldGhpbmciOiJoZXJlIn0="
atob("eyJzb21ldGhpbmciOiJoZXJlIn0=")
// {"something":"here"}

This solution is also ideal if you want to store or send binary data with Adafruit IO. You won't get to see any pretty charts, but your data will remain exactly the way you left it.