This repository has been archived by the owner on Jun 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathapiary.apib
574 lines (427 loc) · 20.4 KB
/
apiary.apib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
FORMAT: 1A
HOST: http://example.com/api/v1
# OpenT2T API Server
This documents a simple REST API hosting the [OpenT2T library](https://github.com/opent2t/opent2t). It can be called by other non-node services
that cannot host OpenT2T directly, or simply deployed as part of a [Microservices Architecture](http://microservices.io/).
The purpose of this document is to facilitate anyone who wants to create a service using OpenT2T. Everything you need to know about OpenT2T is
at http://opent2t.io.
# Group Anonymous Actions
The APIs in this section are anonymous, i.e. the caller does not need to present any credentials or
`Authorization` header.
## Hubs Collection [/hubs]
### List All Hubs Supported by OpenT2T [GET]
May be used by the caller to render UX allowing the user to initiate setup for any hubs that they own.
The *onboarding* property of each hub in the response references the specific onboarding type required to set up the hub. Currently,
only [OAuth2](https://tools.ietf.org/html/rfc6749) is supported. For this onboarding type, the caller should take the user to the `auth_uri`
(e.g. in a hosted browser in the case of an app caller) and then start monitoring all redirects. When the caller
detects a redirect to the `redirect_uri` it should note the entire URI (including any fragment attached to it)
and POST it to the `/hubs/{hub_id}/connect` Action (where `{hub_id}` is the ID of the Hub the user selected).
Some hubs supported by OpenT2T, e.g. Wink, only support the OAuth 2 Resource Owner Password Credentials flow. In these
cases, we assume that this service also proxies the auth to such hubs and hosts the Sign-In forms
where the user enters the username and password. The auth_uri for such hubs points that these hosted Sign-In forms, and
in this way clients (e.g. phone apps) can deal with all hubs exactly the same way regardless of what OAuth flavor is supported.
The hosted Sign-in forms are documented under the `/hubs/{hub_id}/signInForm` Action (where `{hub_id}` is the ID of the Hub the user selected).
+ Response 200 (application/json)
[
{
"id": 1,
"name": "Nest",
"icon": "https://example.com/images/nest.png",
"onboarding": {
"type" : "OAuth2",
{
"auth_uri": "https://home.nest.com/login/oauth2?client_id=ABCDXYZ&state=1234567",
"redirect_uri": "https://www.example.com/auth_redirect"
}
}
},
{
"id": 2,
"name": "Wink",
"icon": "https://example.com/images/wink.png",
"onboarding": {
"type" : "OAuth2",
{
"auth_uri": "/hubs/2/signInForm",
"redirect_uri": "https://www.example.com/auth_redirect"
}
}
},
]
# Group User Authorized Actions
The APIs in this section require authorization, i.e. the caller needs to provide a valid
`Authorization` header. This document does not specify any particular authorization format, and that
is up to the implementation. The only requirement is that this API recognizes the Authorization header
as valid, and it is associated with a particular user (e.g. a user Bearer token).
It is expected that internally this service is configured with any secrets to communicate with other services, e.g. client secrets
to talk to services like Wink, Nest, etc. These secrets are never exposed out of the REST API, but are internally used to securely
communicate with other services as needed.
It is also expected that internally this service has a data store where it stashes user data, e.g. service
specific credentials for each user as well as other data like device IDs etc.
## Hubs [/hubs/{hub_id}]
### Display a Hosted Sign-In Form [GET /hubs/{hub_id}/signInForm]
Displays a hosted sign-in form for hubs that support the OAuth 2 Resource Owner Password Credentials Flow. These forms
are used to make such hubs equivalent to others that support the full OAuth 2 flow, as far as callers of this API
are concerned.
This form is sent as the `auth_uri` for hubs that support the OAuth 2 Resource Owner Password Credentials Flow.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Request (text/html)
+ Headers
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Response 200 (text/html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Sign in to Wink</title>
</head>
<body>
<form method="post" action="">
<fieldset>
<legend>Sign in to Wink</legend>
<p>
<label for="user[email]">
Email:
<input type="email" name="user[email]">
<div class="tip">
Enter the email address you use to sign in to WINK, e.g. <em>[email protected]</em>.
</div>
</label>
</p>
<p>
<label for="user[name]">
Password:
<input type="password" name="user[password]">
</label>
</p>
</fieldset>
<p class="buttons"><input type="submit" value="Sign in"></p>
</form>
<p>
Don't have a Wink account? You can create one using the Wink app.
</p>
</body>
</html>
### Process a Hosted Sign-In Form [POST /hubs/{hub_id}/signInForm]
The hosted Sign-In forms for hubs that support the OAuth 2 Resource Owner Password Credentials Flow post the
contents of the sign-in form to this action.
Internally, this API gets an access token for this user using the provided credentials. This service is
internally configured with any secrets required to talk to complete the OAuth flow.
Upon success, there is a redirect to the `redirect_uri ` for this hub, so that any client monitoring for that
URI is notified that sign-in is complete.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Request (application/x-www-form-urlencoded)
+ Headers
Content-Length: 45
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Body
user[email]:[email protected]
user[password]:chocolate
+ Response 303
+ Headers
Location: https://www.example.com/auth_redirect
### Connect to a Hub [POST /hubs/{hub_id}/connect]
After the client completes onboarding, per the `onboard` parameter of the user-selected entry in the `/hubs`
response, the next step is to connect to the hub with the result of onboarding.
What is sent to this action is different per onboarding type. For now, with only OAuth 2 supported, it is expected
that the client will post the entire `redirect_uri` (including any fragment) received after onboarding to this endpoint.
Internally, this API will use the information in the `redirect_uri` to get the access token for this hub, and save it in
its internal database. There are two possible ways this is done.
1. **Full Oauth 2 Flow:** The `redirect_uri` sent to this action contains a code fragment that can be exchanged for the
access token for this hub, and then saved in its internal database. This service is internally configured with any secrets
required to talk to complete the OAuth flow.
2. **OAuth 2 Resource Owner Password Credentials Flow:** The `redirect_uri` sent to this action does not contain any code
fragment and this action is bascially a no-op, e.g. in the case of Wink. In this case, the redirect_uri was generated
by the Hosted Sign-In form which has already stored and saved the access token for this user for this service and the client
is simply following the same flow it follows for other OAuth 2 onboarding types.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Request (application/json)
+ Headers
Content-Length: 45
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Body
{
"type" : "OAuth2",
{
"redirect_uri": "https://www.example.com/auth_redirect#code=abcdef1234567890"
}
}
+ Response 200 (application/json)
+ Response 401
### List All Devices Connected To Hub [GET /hubs/{hub_id}/devices]
Returns the different devices connected to the hub, by directly querying the hub. May be used by the caller to
render UX or to cache the device list locally.
Internally, this service also caches this list of devices and assigns a user-unique ID for this device (across hubs).
These user-unique device IDs can be used in other API calls to interact with any device in this list without the need to
scope the call with the hub ID.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Request (application/json)
+ Headers
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Response 200 (application/json)
[
{
"id": "2_1",
"name": "Hallway Thermostat",
"openT2T": {
"schema": "org.opent2t.sample.thermostat.superpopular",
"translator": "com.wink.thermostat"
},
"icon": "https://example.com/images/thermostat.png",
},
{
"id": "2_2",
"name": "Patio Light",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
"translator": "com.wink.lightbulb"
},
"icon": "https://example.com/images/light.png"
}
]
### Get Details for Device Connected To Hub [GET /hubs/{hub_id}/devices/{device_id}]
Returns details for a device, by directly querying the hub. May be used by the caller to
render UX or to cache the device state locally. This includes current state for the device
which is not returned when listing devices.
Internally, this service also caches this device state.
Note that these user-unique device IDs can be used in other API calls to interact with any device
without the need to scope the call with the hub ID.
By definition, this API call is identical to `GET /devices/{device_id}` so please refer to
documentation for that API for more information.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Response 200
### Update Details for Device Connected To Hub [POST /hubs/{hub_id}/devices/{device_id}]
Updates details for a device, by directly updating via the hub. May be used by the caller to
respond to user requests to interact with the device.
Note that these user-unique device IDs can be used in other API calls to interact with any device
without the need to scope the call with the hub ID.
By definition, this API call is identical to `POST /devices/{device_id}` so please refer to
documentation for that API for more information.
+ Parameters
+ hub_id (number) - ID of the Hub
+ Response 200
## Devices [/devices]
### List All Devices [GET]
Returns all devices for a user. May be used by the caller to
render UX or to cache the device list locally.
Internally, this service also caches this list of devices and assigns a user-unique ID for this device (across hubs).
These user-unique device IDs can be used in other API calls to interact with any device in this list without the need to
scope the call with the hub ID.
+ Request (application/json)
+ Headers
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Response 200 (application/json)
[
{
"id": "2_1",
"name": "Hallway Thermostat",
"openT2T": {
"schema": "org.opent2t.sample.thermostat.superpopular",
"translator": "com.wink.thermostat"
},
"icon": "https://example.com/images/thermostat.png",
},
{
"id": "2_2",
"name": "Patio Light",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
"translator": "com.wink.lightbulb"
},
"icon": "https://example.com/images/light.png"
}
]
### Get Details for Device [GET /devices/{device_id}]
Returns details for a device by directly querying it (via a hub in the case this is a
hub-connected device). May be used by the caller to render UX or to cache the device state locally.
This includes current state for the device which is not returned when listing devices.
Internally, this service also caches this device state.
Note that these are user-unique device IDs and can therefore be used in API calls like
this one to interact with any device (including hub connected devices) without the need to scope
the call with the hub ID.
+ Parameters
+ device_id (string) - ID of the device
+ Request (application/json)
+ Headers
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Response 200 (application/json)
{
"id": "2_1",
"name": "Hallway Thermostat",
"openT2T": {
"schema": "org.opent2t.sample.thermostat.superpopular",
"translator": "com.wink.thermostat"
},
"icon": "https://example.com/images/thermostat.png",
"state": {
"ambientTemperature": "27",
"targetTemperature": "26.5",
"targetTemperatureHigh": "27.5",
"targetTemperatureLow": "26"
}
}
### Update Details for Device [POST /devices/{device_id}]
Updates details for a device, by directly directly updating it (via a hub in the
case this is a hub-connected device). May be used by the caller to
respond to user requests to interact with the device.
Note that these are user-unique device IDs and can therefore be used in API calls like
this one to interact with any device (including hub connected devices) without the need to scope
the call with the hub ID.
This API responds with the updated device details.
+ Parameters
+ device_id (string) - ID of the device
+ Request (application/json)
+ Headers
Content-Length: 45
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Body
{
"ambientTemperature": "27",
"targetTemperature": "26.5",
"targetTemperatureHigh": "27.5",
"targetTemperatureLow": "26"
}
+ Response 200 (application/json)
{
"id": "2_1",
"name": "Hallway Thermostat",
"openT2T": {
"schema": "org.opent2t.sample.thermostat.superpopular",
"translator": "com.wink.thermostat"
},
"icon": "https://example.com/images/thermostat.png",
"state": {
"ambientTemperature": "27",
"targetTemperature": "26.5",
"targetTemperatureHigh": "27.5",
"targetTemperatureLow": "26"
}
}
## Device Groups [/groups]
Devices can be grouped together, and a group can be treated like a composite device in some
cases (e.g. turning off a group of lights all together).
### List All Device Groups for User [GET]
May be used by the caller to render UX or to cache the group list locally.
Does not include details about the devices in each group (since this could be a large
response). If caller is interested, they can call `GET /groups/{group_id}` to get
complete group details, including devices in the group.
+ Request (application/json)
+ Headers
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Response 200 (application/json)
[
{
"id": "123",
"name": "Downstairs Lights",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
},
"icon": "https://example.com/images/lights.png",
},
{
"id": "456"
"name": "Upstairs Lights",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
},
"icon": "https://example.com/images/lights.png",
}
]
### Create a New Device Group for User [POST]
Devices can be added or removed from this group after creation via:
1. Add a device: `PUT /groups/{group_id}/{device_id}`
2. Remove a device: `DELETE /groups/{group_id}/{device_id}`
This action takes a JSON payload as part of the request body.
Response then return specific header and body.
+ Request (application/json)
+ Headers
Content-Length: 45
Authorization: Bearer USER_OPENT2T_API_BEARER_TOKEN
+ Body
{
"name": "Downstairs Lights",
"openT2T": {
"schema": "org.opent2t.sample.superpopular.lamp",
},
"icon": "https://example.com/images/lights.png"
}
+ Response 201 (application/json)
+ Headers
Location: /groups/123
+ Body
{
"id": "123",
"created_at": "2016-08-02T09:30:32.120Z",
"name": "Downstairs Lights",
"openT2T": {
"schema": "org.opent2t.sample.superpopular.lamp",
},
"icon": "https://example.com/images/lights.png"
}
### Device Group Details [GET /groups/{group_id}]
Queries the contents of a group, including devices in the group.
+ Parameters
+ group_id (number) - ID of the Device Group
+ Response 200 (application/json)
{
"id": "123",
"created_at": "2016-08-02T09:30:32.120Z",
"name": "Downstairs Lights",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
},
"icon": "https://example.com/images/lights.png",
"members": [
{
"id": "2_2"
"name": "Living Room Light",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
"translator": "com.wink.lightbulb"
},
"icon": "https://example.com/images/light.png"
},
{
"id": "2_3"
"name": "Living Room Light",
"openT2T": {
"schema": "org.opent2t.sample.lamp.superpopular",
"translator": "com.philips.hub.bulb"
},
"icon": "https://example.com/images/light.png"
}
]
}
### Add Device to a Group [PUT /groups/{group_id}/{device_id}]
> **Note:** At this time, we only support homogenous groups, e.g. you can only have
a group of lights or a group of window blinds -- you cannot mix and match.
+ Parameters
+ group_id (number) - ID of the Device Group
+ device_id (number) - ID of the Device to add to the group
+ Response 200
+ Response 404 (application/json)
{
"message" : "The group or device ID specified was not found"
}
+ Response 400 (application/json)
{
"message" : "The specified device could not be associated with the specified group"
}
### Remove Device from a Group [DELETE /groups/{group_id}/{device_id}]
Note that the device is simply disassociated from the group. It is not
removed from the devices collection for this user, nor from the hub (if any)
that the device is associated with.
+ Parameters
+ group_id (number) - ID of the Device Group
+ device_id (number) - ID of the Device to add to the group
+ Response 200
+ Response 404 (application/json)
{
"message" : "The group or device ID specified was not found"
}