sample_pir-lights_rgb

Dependencies:   ChainableLED

Committer:
iv123
Date:
Sun Jun 18 10:14:56 2017 +0000
Revision:
0:7a352727249b
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iv123 0:7a352727249b 1 # Using the mbed Device Connector API
iv123 0:7a352727249b 2
iv123 0:7a352727249b 3 The mbed Device Connector web interface that we used in the previous section is a wrapper around the mbed Device Connector API. Through this API we can connect any app to any device. We can use this API to build an app that allows us to control any of the lighting systems that we deploy in our house or office.
iv123 0:7a352727249b 4
iv123 0:7a352727249b 5 ## Obtaining an access key
iv123 0:7a352727249b 6
iv123 0:7a352727249b 7 To talk to the API we need to obtain an access key. This key is used to authenticate with the API. To create a new access key, go to the [Access Keys](https://connector.mbed.com/#accesskeys) page in the mbed Device Connector web interface.
iv123 0:7a352727249b 8
iv123 0:7a352727249b 9 Click *CREATE NEW ACCESS KEY* to create a new access key, and give it a descriptive name.
iv123 0:7a352727249b 10
iv123 0:7a352727249b 11
iv123 0:7a352727249b 12 ![Creating a new access key in mbed Device Connector](assets/lights14.png)
iv123 0:7a352727249b 13
iv123 0:7a352727249b 14 ## Testing the API
iv123 0:7a352727249b 15
iv123 0:7a352727249b 16 We can quickly test out if the access key works by doing a call to the API to query for all our devices. To retrieve a list of all devices, make a GET request to https://api.connector.mbed.com/endpoints/. You'll need to send an authorization header with this request:
iv123 0:7a352727249b 17
iv123 0:7a352727249b 18 ```
iv123 0:7a352727249b 19 Authorization: Bearer <your_access_key>
iv123 0:7a352727249b 20 ```
iv123 0:7a352727249b 21
iv123 0:7a352727249b 22 You can make this request with any request library, but if you're using curl, use the following command:
iv123 0:7a352727249b 23
iv123 0:7a352727249b 24
iv123 0:7a352727249b 25
iv123 0:7a352727249b 26 ```
iv123 0:7a352727249b 27 curl -v -H "Authorization: Bearer <your_access_key>" https://api.connector.mbed.com/endpoints/
iv123 0:7a352727249b 28 ```
iv123 0:7a352727249b 29
iv123 0:7a352727249b 30 This will return something like this:
iv123 0:7a352727249b 31
iv123 0:7a352727249b 32 ```
iv123 0:7a352727249b 33 < HTTP/1.1 200 OK
iv123 0:7a352727249b 34 < Date: Tue, 14 Jun 2016 10:37:01 GMT
iv123 0:7a352727249b 35 < Server: mbed Device Server
iv123 0:7a352727249b 36 < Content-Type: application/json
iv123 0:7a352727249b 37 < Content-Length: 169
iv123 0:7a352727249b 38 <
iv123 0:7a352727249b 39 * Connection #0 to host api.connector.mbed.com left intact
iv123 0:7a352727249b 40
iv123 0:7a352727249b 41 [
iv123 0:7a352727249b 42 {
iv123 0:7a352727249b 43 "name": "9e3a37ae-e74f-465f-b04c-f105c8f69f1c",
iv123 0:7a352727249b 44 "type": "test",
iv123 0:7a352727249b 45 "status": "ACTIVE"
iv123 0:7a352727249b 46 },
iv123 0:7a352727249b 47 {
iv123 0:7a352727249b 48 "name": "8874e0eb-96ef-4799-b948-e91d05147bfe",
iv123 0:7a352727249b 49 "type": "light-system",
iv123 0:7a352727249b 50 "status": "ACTIVE"
iv123 0:7a352727249b 51 }
iv123 0:7a352727249b 52 ]
iv123 0:7a352727249b 53 ```
iv123 0:7a352727249b 54
iv123 0:7a352727249b 55 <span class="notes">**Note:** The official API documentation for the mbed Device Connector REST interface is [located here](https://docs.mbed.com/docs/mbed-device-connector-web-interfaces/en/latest/).</span>
iv123 0:7a352727249b 56
iv123 0:7a352727249b 57 ## Using the official libraries
iv123 0:7a352727249b 58
iv123 0:7a352727249b 59 You don't need to write raw HTTP requests to deal with the mbed Device Connector REST interface, as there are official libraries available for node.js, Python and Java. This is especially nice because the APIs to interact with resources are [asynchronous](https://docs.mbed.com/docs/mbed-device-connector-web-interfaces/en/latest/#asynchronous-requests), because for many functions it's not guaranteed that an action (such as writing to a device) will happen straight away, as the device might be in deep sleep or otherwise slow to respond. Therefore, you need to listen to callbacks on a [notification channel](https://docs.mbed.com/docs/mbed-device-connector-web-interfaces/en/latest/api-reference/#notifications). If you're using any of the official libraries, notification channels are abstracted away, making it easier to write applications on top of mbed Device Connector.
iv123 0:7a352727249b 60
iv123 0:7a352727249b 61 An additional feature in the libraries is that they support subscriptions. We can subscribe to resources and get a notification whenever they change. This is useful for our `/pir/0/count` resource, as we can get notified whenever someone moves in front of the sensor.
iv123 0:7a352727249b 62
iv123 0:7a352727249b 63 The following sections show an example of changing the color of the light, and receiving a notification whenever someone waves in front of the PIR sensor, in both node.js and Python.
iv123 0:7a352727249b 64
iv123 0:7a352727249b 65 ### node.js
iv123 0:7a352727249b 66
iv123 0:7a352727249b 67 First, make sure you have installed [node.js](http://nodejs.org). Then create a new folder, and install the mbed Device Connector node.js library via npm:
iv123 0:7a352727249b 68
iv123 0:7a352727249b 69 ```bash
iv123 0:7a352727249b 70 $ npm install mbed-connector-api
iv123 0:7a352727249b 71 ```
iv123 0:7a352727249b 72
iv123 0:7a352727249b 73 Next create a new file ``main.js`` in the same folder where you installed the library, and fill it with the following content (replace `YOUR_ACCESS_KEY` with your access key):
iv123 0:7a352727249b 74
iv123 0:7a352727249b 75 ```js
iv123 0:7a352727249b 76 var CloudApi = require('mbed-connector-api');
iv123 0:7a352727249b 77 var api = new CloudApi({
iv123 0:7a352727249b 78 accessKey: 'YOUR_ACCESS_KEY'
iv123 0:7a352727249b 79 });
iv123 0:7a352727249b 80
iv123 0:7a352727249b 81 // Start notification channel
iv123 0:7a352727249b 82 api.startLongPolling(function(err) {
iv123 0:7a352727249b 83 if (err) throw err;
iv123 0:7a352727249b 84
iv123 0:7a352727249b 85 // Find all lights
iv123 0:7a352727249b 86 api.getEndpoints(function(err, devices) {
iv123 0:7a352727249b 87 if (err) throw err;
iv123 0:7a352727249b 88
iv123 0:7a352727249b 89 console.log('Found', devices.length, 'lights', devices);
iv123 0:7a352727249b 90
iv123 0:7a352727249b 91 devices.forEach(function(d) {
iv123 0:7a352727249b 92 // For every light, we will request notifications on the PIR resource
iv123 0:7a352727249b 93 api.putResourceSubscription(d.name, '/pir/0/count');
iv123 0:7a352727249b 94
iv123 0:7a352727249b 95 // and set the color to orange, as your's truly is Dutch
iv123 0:7a352727249b 96 var orange = 0xff6400;
iv123 0:7a352727249b 97 api.putResourceValue(d.name, '/led/0/color', orange, function(err) {
iv123 0:7a352727249b 98 if (err) console.error('Setting led/0/color for', d.name, 'failed', err);
iv123 0:7a352727249b 99 console.log('Set color of', d.name, 'to orange!');
iv123 0:7a352727249b 100 });
iv123 0:7a352727249b 101
iv123 0:7a352727249b 102 });
iv123 0:7a352727249b 103
iv123 0:7a352727249b 104 }, { parameters: { type: 'light-system' } });
iv123 0:7a352727249b 105 });
iv123 0:7a352727249b 106
iv123 0:7a352727249b 107 // Notifications
iv123 0:7a352727249b 108 api.on('notification', function(notification) {
iv123 0:7a352727249b 109 console.log('Got a notification', notification);
iv123 0:7a352727249b 110 });
iv123 0:7a352727249b 111 ```
iv123 0:7a352727249b 112
iv123 0:7a352727249b 113 When you run this program, and you wave your hand in front of the PIR sensor, you'll see something like this:
iv123 0:7a352727249b 114
iv123 0:7a352727249b 115 ```
iv123 0:7a352727249b 116 $ node main.js
iv123 0:7a352727249b 117 Found 1 lights [ { name: '8874e0eb-96ef-4799-b948-e91d05147bfe',
iv123 0:7a352727249b 118 type: 'light-system',
iv123 0:7a352727249b 119 status: 'ACTIVE' } ]
iv123 0:7a352727249b 120 Set color of 8874e0eb-96ef-4799-b948-e91d05147bfe to orange!
iv123 0:7a352727249b 121 Got a notification { ep: '8874e0eb-96ef-4799-b948-e91d05147bfe',
iv123 0:7a352727249b 122 path: '/pir/0/count',
iv123 0:7a352727249b 123 ct: 'text/plain',
iv123 0:7a352727249b 124 payload: '7',
iv123 0:7a352727249b 125 'max-age': 0 }
iv123 0:7a352727249b 126 ```
iv123 0:7a352727249b 127
iv123 0:7a352727249b 128 See here for the [full docs](https://github.com/ARMmbed/mbed-connector-api-node) on how to use the node.js library.
iv123 0:7a352727249b 129
iv123 0:7a352727249b 130 ### Python
iv123 0:7a352727249b 131
iv123 0:7a352727249b 132 First make sure that you have installed [Python 2.7 or Python 3](https://www.python.org/downloads/) and [pip](https://pip.pypa.io/en/stable/installing/). Then create a new folder, and install the mbed Device Connector library through pip:
iv123 0:7a352727249b 133
iv123 0:7a352727249b 134 ```bash
iv123 0:7a352727249b 135 $ pip install -U mbed-connector-api
iv123 0:7a352727249b 136 ```
iv123 0:7a352727249b 137
iv123 0:7a352727249b 138 Next create a new file - ``lights.py`` - in the same folder where you installed the library, and fill it with the following content (replace `YOUR_ACCESS_KEY` with your access key):
iv123 0:7a352727249b 139
iv123 0:7a352727249b 140 ```python
iv123 0:7a352727249b 141 import mbed_connector_api
iv123 0:7a352727249b 142 import time
iv123 0:7a352727249b 143 import base64
iv123 0:7a352727249b 144
iv123 0:7a352727249b 145 connector = mbed_connector_api.connector("YOUR_ACCESS_KEY")
iv123 0:7a352727249b 146
iv123 0:7a352727249b 147 def notificationHandler(data):
iv123 0:7a352727249b 148 for n in data['notifications']:
iv123 0:7a352727249b 149 print "Got a notification for %s: %s -> new value %s" % (n['ep'], n['path'], base64.b64decode(n['payload']))
iv123 0:7a352727249b 150
iv123 0:7a352727249b 151 connector.startLongPolling()
iv123 0:7a352727249b 152 connector.setHandler('notifications', notificationHandler)
iv123 0:7a352727249b 153
iv123 0:7a352727249b 154 e = connector.getEndpoints("light-system")
iv123 0:7a352727249b 155 while not e.isDone():
iv123 0:7a352727249b 156 None
iv123 0:7a352727249b 157 if e.error:
iv123 0:7a352727249b 158 raise(e.error.error)
iv123 0:7a352727249b 159 print("Found %d lights: %s" % (len(e.result), str(e.result)))
iv123 0:7a352727249b 160
iv123 0:7a352727249b 161 for endpoint in e.result:
iv123 0:7a352727249b 162 # Get a notification whenever the PIR count changes
iv123 0:7a352727249b 163 connector.putResourceSubscription(endpoint['name'], "/pir/0/count")
iv123 0:7a352727249b 164
iv123 0:7a352727249b 165 # And change the color to pink, because that's nice
iv123 0:7a352727249b 166 pink = 0xff69b4
iv123 0:7a352727249b 167 x = connector.putResourceValue(endpoint['name'], "/led/0/color", pink)
iv123 0:7a352727249b 168 while not x.isDone():
iv123 0:7a352727249b 169 None
iv123 0:7a352727249b 170 if (x.error):
iv123 0:7a352727249b 171 print("Setting pink color for %s failed: %s" % (endpoint['name'], x.error.error))
iv123 0:7a352727249b 172 else:
iv123 0:7a352727249b 173 print("Set color of %s to pink!" % endpoint['name'])
iv123 0:7a352727249b 174
iv123 0:7a352727249b 175 while 1:
iv123 0:7a352727249b 176 time.sleep(1.0)
iv123 0:7a352727249b 177 ```
iv123 0:7a352727249b 178
iv123 0:7a352727249b 179 When we run this program, and you wave your hand in front of the PIR sensor, we'll see something like this:
iv123 0:7a352727249b 180
iv123 0:7a352727249b 181 ```
iv123 0:7a352727249b 182 $ python lights.py
iv123 0:7a352727249b 183 Found 1 lights: [{u'status': u'ACTIVE', u'type': u'light-system', u'name': u'8874e0eb-96ef-4799-b948-e91d05147bfe'}]
iv123 0:7a352727249b 184 Set color of 8874e0eb-96ef-4799-b948-e91d05147bfe to pink!
iv123 0:7a352727249b 185 Got a notification for 8874e0eb-96ef-4799-b948-e91d05147bfe: /pir/0/count -> new value 49
iv123 0:7a352727249b 186 ```
iv123 0:7a352727249b 187
iv123 0:7a352727249b 188 See here for the [full docs](https://github.com/ARMmbed/mbed-connector-api-python) on how to use the Python library.