MQTT(Message Queue Telemetry Transport) is a Publish/Subscribe based messaging protocol on top of the TCP/IP protocol. Amazon AWS IoT is a great platform that enables you to connect devices to AWS Services using MQTT protocol. Here, we are going to show Raspberry Pi communicating with another Raspberry Pi through Amazon AWS IoT.
We are using Amazon AWS IoT Python SDK and MQTT protocol to Publish/Subscribe event. The Publish/Subscribe messaging pattern requires a MQTT broker. The MQTT broker is responsible for distributing messages to interested clients based on the topic of a message. Here, Raspberry pi used as a MQTT Client and Amazon AWS IoT used as a MQTT Broker.
In this program, first Raspberry Pi device is Subscribing to Button Event of second Raspberry Pi device and vice versa. Raspberry pi will toggle the light when Button Event received from another Raspberry Pi. So when we press button on first device, it will send Publish request of button event. This event will be received by second device which will toggle light. We will need to generate end point on Amazon AWS IoT which will also provide us private key and certificate required for a particular device secure authentication.
Thunderboard Sense is tiny but Swiss Knife of Sensors. Trust me it is! It has Relative Humidity and Temperature Sensor, UV and Ambient Light Sensor, Pressure Sensor, Indoor Air Quality and Gas Sensor, 6-axis Inertial Sensor and MEMS Microphone including BLE capability.
Here I am going to show you how to get Temperature, Humidity and Battery Level data from Thunderboard Sense to Thingspeak through Raspberry Pi’s BLE and Internet connectivity. Check out this video.
Thunderboard Sense transmits all the Sensor values with its original shipped firmware. You can try to connect with it using following Thunderboard Android or iPhone App. It will shows all the Sensor values periodically.
Thingspeak is very easy to use platform. I have created my channel there with three fields. It gives you unique API key using which you can push data to cloud and on Thingspeak you can view the graph of your logged data. There is limit on it so you can push data once at every 15 seconds only.
As I want to read Battery Level, Temperature and Humidity, I have found out those three BLE characteristics first and then read it. It will read parameters at every 1 second from device and collect it and then after push to cloud at 15 second interval.
Here is the python code for Raspberry Pi 3 to connect with Thunderboard Sense Kit using BLE, Read data and push to Cloud.
from __future__ import division import sys from bluepy.btle import * import struct import thread from time import sleep import urllib2 PRIVATE_KEY = 'Your unique API Key Goes Here' #Base URL of Thingspeak baseURL = 'https://api.thingspeak.com/update?api_key=' def vReadSENSE(): scanner = Scanner(0) devices = scanner.scan(3) for dev in devices: print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi) for (adtype, desc, value) in dev.getScanData(): print " %s = %s" % (desc, value) num_ble = len(devices) print num_ble if num_ble==0: return None ble_service =  char_sensor = 0 non_sensor = 0 bat_char = Characteristic temperature_char = Characteristic humidity_char = Characteristic count = 15 for i in range(num_ble): try: devices[i].getScanData() ble_service.append(Peripheral()) ble_service[char_sensor].connect(devices[i].addr,devices[i].addrType) char_sensor = char_sensor + 1 print "Connected %s device with addr %s " % (char_sensor, devices[i].addr) except: non_sensor = non_sensor + 1 try: for i in range(char_sensor): services = ble_service[i].getServices() characteristics = ble_service[i].getCharacteristics() for k in characteristics: print k if k.uuid=="2a19": print "Battery Level" bat_char = k if k.uuid == "2a6e": print "Temperature" temperature_char = k if k.uuid == "2a6f": print "Humidity" humidity_char = k except: return None while True: bat_data = bat_char.read() bat_data_value = ord(bat_data) temperature_data = temperature_char.read() temperature_data_value =(ord(temperature_data)<<8)+ord(temperature_data) float_temperature_data_value = (temperature_data_value / 100) humidity_data = humidity_char.read() humidity_data_value =(ord(humidity_data)< 14: f = urllib2.urlopen(baseURL + PRIVATE_KEY +"&field1=%s&field2=%s&field3=%s" % (bat_data_value, float_temperature_data_value, humidity_data_value)) print f.read() f.close() count = 0 count = count + 1 sleep(1) while True: vReadSENSE()