All communications should be done over HTTP/1.1 so as to allow for keepalive.
Timestamp format is ISO 8601, e.g.:
Devices (lamps, sensors) are addressed using a text-based unique identifier e.g:
PL_KRK_0070034_45_6_01
A device addres, refered to as ADDR later on, has the following properties:
For a single device URI:
/PL_KRK_0070034_45_6_01/...
For a range of devices' URI:
/PL_KRK_0070034_*/...
For a set of devices' URI:
/{PL_KRK_0070034_45_6_01,PL_KRK_0070034_45_6_02,PL_KRK_0070034_45_6_03}/...
Device properties are represented as parameters. A parameter is identified by its name. Parameters, referred to as PARAMS later on, are subject to the same wildcards as ADDR.
A single parameter URI:
/.../status
Multiple parameters URI:
/.../{status,time}
All parameters URI:
/.../*
GET /ADDR/PARAMS
e.g. getting 'state' parameter:
GET /PL_KRK_0070034_45_6_01/state
Returns:
{ "timestamp": "2014-03-25T14:03Z", "data": [ {"id": "PL_KRK_0070034_45_6_01", "state": "on" }, ... ] }
e.g.
GET /PL_KRK_0070034_45_6_01/{state,dimming}
Returns:
{ "timestamp": "2014-03-25T14:03Z", "data": [ {"id": "PL_KRK_0070034_45_6_01", "state": "on", "dimming": 50 } ] }
GET /PL_KRK_0070034_45_6_01/*
Returns:
{ timestamp: "2014-03-25T14:03Z", data: [ {"id": "PL_KRK_0070034_45_6_01", "state": "on", "dimming": 50 } ] }
This is done by specifying the lasttimestamp
GET parameter, which contains the last known timestamp of an update:
GET /*/state?lasttimestamp=2014-03-25T14:03:18+0100
If something has changed from that timestamp, the response will be issued immediately with the current data.
If nothing has changed, the connection will hang until an update of any queried parameters occurs.
In case of nonexistant ADDR or PARAMS a null is returned as parameter value
Assuming that foo
does not exist the following request:
GET /PL_KRK_0070034_45_6_01/{status,foo}
results in (mind foo
is not there):
{ "timestamp":"2014-09-17T11:31:29+0200", "data": [ { "id": "PL_KRK_0070034_45_6_01", "status" :0.0 } ] }
Assuming that ADDR does not exists:
GET /non_existing_addr/something
results in (mind there is no object for the requested address):
{ "timestamp":"2014-09-17T11:31:29+0200", "data": [ ] }
Change lamp parameters:
PUT /
with the following request data:
{ "data" : [ {"id": "PL_KRK_0070034_45_6_01", "dimming" : 50, "state": "on" }, {"id": "PL_KRK_0070034_45_6_02", "state": "off" } ] }
That will set:
Returns confirmation that particular parameters are set with additional timestamp:
{ "timestamp": "2014-03-25T14:03:22+0200", "data": [ {"id": "PL_KRK_0070034_45_6_01", "dimming" : 50, "state": "on" }, ... ] }
If the parameter cannot be changed, or if it is nonexistant it is not returned/confirmed:
Request:
{ "data" : [ {"id": "PL_KRK_0070034_45_6_01", "detecdted" :"false", "detected":"false"} ] }
Reply:
{ "timestamp":"2014-05-30T21:37:39+0200", "data" : [ {"id": "PL_KRK_0070034_45_6_01", "detected":"false"} ] }
If an ADDR does not exist: Request:
{ "data" : [ { "id": "non_existing", "detected":"false" } ] }
Reply:
{ "timestamp":"2014-05-30T21:37:39+0200", "data" : [ ] }
TBD
Main goal:
It is provided as GEOJSON, where location is array-encoded [longitude, latitude, elevation]
GET /info
Response:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": {"type": "Point", "coordinates": [19.0, 50.0, 118.0]}, "properties": { "id": "PL_KRK_0070034_45_6_01", "type": "d", "class": "traffic", "attributes": [ { "name": "detected", "communication": "ro", "type": "atom", "values": [ "true", "false", "unknown" ]}, { "name": "control", "communication": "rw", "type": "numeric", "ranges": [ {"from": 0.0, "to": 10.0, "precision": 0.1 } ] } ] } }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [19.0, 50.0, 118.0]}, "properties": { "id": "PL_KRK_0070034_45_6_01", "type": "l", "class": "light", "attributes": [ { "name": "status", "communication": "rw", "type": "numeric", "ranges": [ {"from": 0.0, "to": 100.0, "precision": 1.0 } ] } ] } }, ... ] }
where attributes
object consists of:
communication
- defines if the attribute can be read or written, available values: ro
(read only), rw
(read/write), wo
(write only),type
- data type, available values: atom
(arbitrary symbol), numeric
, values
- an array of acceptable values,range
- an array of acceptable ranges indicated with from
, to
and precision
.In the example above a single address acts as a two types of device: d and l, by definition they must use disjoint set of properties.
A complete LIMS response example:
{ "features": [ { "geometry": {"coordinates": [19.972399, 50.066368, 0.0 ], "type":"Point"}, "properties": { "id":1, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972399, 50.066353, 0.0 ], "type":"Point"}, "properties": { "id":2, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972534, 50.066368, 0.0 ], "type":"Point"}, "properties": { "id":3, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972534, 50.066357, 0.0 ], "type":"Point"}, "properties": { "id":4, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972408, 50.06628, 0.0 ], "type":"Point"}, "properties": { "id":5, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972408, 50.066265, 0.0 ], "type":"Point"}, "properties": { "id":6, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972542, 50.066284, 0.0 ], "type":"Point"}, "properties": { "id":7, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972542, 50.066269, 0.0 ], "type":"Point"}, "properties": { "id":8, "type":"d", "class":"done", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972359, 50.066387, 0.0 ], "type":"Point"}, "properties": { "id":1, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972464, 50.066395, 0.0 ], "type":"Point"}, "properties": { "id":2, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972553, 50.066399, 0.0 ], "type":"Point"}, "properties": { "id":3, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972368, 50.066322, 0.0 ], "type":"Point"}, "properties": { "id":4, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972433, 50.066322, 0.0 ], "type":"Point"}, "properties": { "id":5, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972496, 50.066322, 0.0 ], "type":"Point"}, "properties": { "id":6, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972559, 50.066326, 0.0 ], "type":"Point"}, "properties": { "id":7, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972376, 50.066235, 0.0 ], "type":"Point"}, "properties": { "id":8, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972569, 50.066238, 0.0 ], "type":"Point"}, "properties": { "id":9, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972492, 50.066177, 0.0 ], "type":"Point"}, "properties": { "id":10, "type":"l", "class":"light", "attributes": [ { "name":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972399, 50.066391, 0.0 ], "type":"Point"}, "properties": { "id":11, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972528, 50.066395, 0.0 ], "type":"Point"}, "properties": { "id":12, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972401, 50.066322, 0.0 ], "type":"Point"}, "properties": { "id":13, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972536, 50.066326, 0.0 ], "type":"Point"}, "properties": { "id":14, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972406, 50.066235, 0.0 ], "type":"Point"}, "properties": { "id":15, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972544, 50.066238, 0.0 ], "type":"Point"}, "properties": { "id":16, "type":"d", "class":"present", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972429, 50.066425, 0.0 ], "type":"Point"}, "properties": { "id":21, "type":"d", "class":"dark", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ] }, "type":"Feature" }, { "geometry": {"coordinates": [19.972481, 50.066425, 0.0 ], "type":"Point"}, "properties": { "id":22, "type":"d", "class":"hour", "attributes": [ { "name":"detected", "communication":"ro", "type":"atom", "values": ["night", "day" ], "ranges": [] } ] }, "type":"Feature" } ], "type":"FeatureCollection" }