LittleBits is a set of components that allow kids to build their own electrical circuits. The Cloudbit will send and receive values from the Internet.
For this project we wanted to build some Python programs that could interact with the littleBits Cloud API.
littleBits Hardware Setup
The Cloudbit enables an input to be sent to the Internet, and it will receive a value (output) from the Internet. For a test setup we used a dimmer bit to adjust the input value with a number bit to show the value. On the output side we used a bargraph bit. Other combinations of bits are possible. The key is to be able to test and see your input and output values.
Cloudbits Setup
For the Cloudbit setup you will need to create a sign-in on the littleBits web site. For details on how to setup your Cloudbit use the following link.
Python Basic Setup
The Cloud API is a RESTful interface, that uses http requests with some header definitions. Before you get started you’ll need your specific littleBits device ID and authorization token. In your specific Cloudbit definition go to the Settings icon, and get your Device ID and AccessToken.
The Cloud API presently does not support a single point read (this might change), instead the input data point value is streamed about once a second.
The basic syntax in Python to get values from the Cloud API will be:
import requests requests.packages.urllib3.disable_warnings() # Change with your Authorization code and deviceID authToken = "4f3830b44e15fa0d" deviceId = "00e04c" headers = {"Authorization": "Bearer " + authToken,"Content-type": "application/json"} # For a read littleBitsUrl = "https://api-http.littlebitscloud.cc/devices/" + deviceId + "/input" r = requests.get(littleBitsUrl, headers=headers, stream=True) # For a write, note: a data body needs to be defined # littleBitsUrl = "https://api-http.littlebitscloud.cc/devices/" + deviceId + "/output" # body = {"percent": thevalue , "duration_ms": thetime} # thebody = json.dumps(body) # r = requests.post(littleBitsUrl, data=thebody, headers=headers)
To do a read of the Cloud API an get request is done, to do a write a post request is used.
Python Read Value Example
The cloud API will stream the input value about every second in a format something like:
data: {"type":"input","timestamp":1521587206463,"percent":61,"absolute":629,"name":"amplitude","payload":{"percent":61,"absolute":629},"from":{"device":{"id":"00e04c0379bb","mac":"00e04c0379bb"}}} {"type":"input","timestamp":1521587206463,"percent":61,"absolute":629,"name":"amplitude","payload":{"percent":61,"absolute":629},"from":{"device":{"id":"00e04c0379bb","mac":"00e04c0379bb"}}}
This data stream will need to be massaged with the following steps:
- decode the stream (UTF-8)
- remove the leading data: , (the remain message will be JSON formatted).
- load the remain string into a JSON object
Below is some example code, for an app with a slider.
# # lb_input.py - read input from a Cloudbit device # import json import requests requests.packages.urllib3.disable_warnings() # Change with your Authorization code and deviceID authToken = "4f3830b44e1d4b27xxxxxx" deviceId = "00e04c03xxxx" littleBitsUrl = "https://api-http.littlebitscloud.cc/devices/" + deviceId + "/input" headers = {"Authorization": "Bearer " + authToken,"Content-type": "application/json"} r = requests.get(littleBitsUrl, headers=headers, stream=True) for line in r.iter_lines(): strmsg = line.decode("utf-8").strip() print("Str: ",strmsg) if len(strmsg) > 0: lb_data = strmsg.split('data:')[1] print(lb_data) result = json.loads(lb_data) thevalue = result['percent'] lb_bar.set(thevalue) thetime = str(datetime.datetime.fromtimestamp(result['timestamp']/1000)) lb_time['text'] = "Time : " + thetime[:-7] root.update()
The Cloud API passed the time stamp as a numeric value with microseconds. The time can be cleaned with:
thetime = str(datetime.datetime.fromtimestamp(result['timestamp']/1000)) time_no_micro_seconds = thetime[:-7]
Python Output Value Example
The Cloud API output uses a post method and unlike the input example there is no streaming.
The new output value and a pulse time is sent in the post data parameter. The value is from 0-100, and a pulse time is -1 for sustained, otherwise a millisecond pulse time is used.
Below is some sample code for a Tkinter app:
from Tkinter import * import json import requests # update your auth Token and device ID authToken = "4f3830b44e1d4b27xxxx" deviceId = "00e04c03xxxxx" littleBitsUrl = "https://api-http.littlebitscloud.cc/devices/" + deviceId + "/output" headers = {"Authorization": "Bearer " + authToken, "Content-type": "application/json"} def setvalue(): thevalue = lb_value.get() thetime = lb_duration.get() body = {"percent": thevalue , "duration_ms": thetime} thebody = json.dumps(body) print body, thebody r = requests.post(littleBitsUrl, data=thebody, headers=headers) print r root = Tk() root.title('littleBits Output') Label(text = "Value (0-100) :",width=30).grid(row=0,column=0) lb_value = Entry(root, width= 10) lb_value.grid(row=0,column=1) Label(text = "Duration (ms) (constant=-1) :",width=30).grid(row=1,column=0) lb_duration = Entry(root, width= 10) lb_duration.grid(row=1,column=1) Button(root, text=' Set Output ', bg='silver', command=setvalue).grid(row=2,column=1) root.mainloop()
Final Comments
There are a lot of simple applications and projects that can be created with Python and some littleBits. One of the limitations on the Cloudbit is that it only sends 1 value and receives 1 value. If you are dealing with digital signals it would be possible to do some multiplexing.
Hi, thanks for the guide. It works nicely!
How can I make the json get method to only read once and not be a stream?
How can I pass a slower stream then?
I basically want to ask every 5 minutes if the temperature is above a certain value and if so, turn on/keep on the AC climate.
Cheers.
LikeLike
I just passed the command break after one pass of the iteration and it worked.
LikeLike
Hi, Littlebits presently doesn’t have a single time read value call, they only offer the streaming option. I’ve seen requests for them to include this, so hopefully it will come out with a future release. As a workaround you can do a break and close the HTTP request after you have the first streamed value, Then start a Tkinter 5 minute timer to call a routine to restart the request. If you get stuck let me know I might have some example code I could send you.
Regards Pete
LikeLike