====== Lighting interfaces ====== ===== Preliminaries ===== All communications should be done over HTTP/1.1 so as to allow for keepalive. ==== Timestamp format ==== According to ISO 8601, plus microseconds, see examples: * "2014-03-25T14:03:33.547222" - assumes zulu time (UTC) * "2014-03-25T14:03:33.547222Z" - zulu time (UTC) * "2014-03-25T14:03:33.547222+01" - UTC+1 * "2014-03-25T14:03:33.547222+0100" - UTC+1 * "2014-03-25T14:03:33.547222+01:00" - UTC+1 ==== Lamp (device) addressing ==== Lamps (devices) are addressed using (cabinet id, device id) pairs: GET /CID/DID/... PUT / Where: * CID (Cabinet IDentifier) is: * an atomic value (e.g. 35), referring to an ID of a single cabinet, * a set of comma-separated values (e.g. 33,35,40), referring to a set of cabinets, * a range (e.g. 33-35), referring to a range of cabinet IDs, * "all", referring to all cabinets. * DID (Device IDentifier) is: * if DID is an atomic value: * an atomic value (e.g. 2), referring to an ID of a single lamp within that cabinet, * a set of comma-separated values (e.g. 1,2,5), referring to a set of lamps, * a range (e.g. 1-4), referring to a range of lamp IDs, * "all", referring to all lamps within that cabinet, * otherwise, only "all" is allowed, which refers to all lamps in specified cabinets. All keywords (apart from "all") can be added in the future. Everything that is not one of the reserved keywords is treated as a cabinet ID or lamp ID, respectively. === Examples === For a single device: GET /34/44/... For a range of device IDs: GET /34/10-13/... For a set of device IDs: GET /34/4,6,13/... ===== Interfaces ===== ==== Control interface ==== Change lamp parameters: PUT / with the following request data: { "data": [ { "cid": 34, "did": 1, "params": [ { "k" : "dimming", "v": 50 }, {"k": "state", "v": "on",} ] }, { "cid": 34, "did": 5, "params": [ {"k": "state", "v": "off"} ]} ] } That will set: * lamp 1 in cabinet 34 to on with 50% dimming * lamp 5 in cabinet 35 to off with unspecified dimming Returns confirmation that particular parameters are set with additional timestamp: { "timestamp": "2014-03-25T14:03:22.547342Z", "data": [ { "cid": 34, "did": 10, "params": [ {"k": "state", "v": "on" } ] }, ... ] } If the parameter cannot be changed, or if it is nonexistant a null value is returned: Request: {"data":[{"cid":1, "did": 25, "params":[ { "k":"detecdted", "v":"false"}, { "k":"detected", "v":"false"}]}]} Reply: { "timestamp":"2014-05-30T21:37:39.088752+0200", "data": [ { "cid":1, "did":25, "params": [ {"k":"detecdted", "v":null}, {"k":"detected", "v":"false"} ] } ] } ==== State interface ==== === Get device state === GET /CID/DID/state Returns: { "timestamp": "2014-03-25T14:03.547Z", "data": [ { "cid": 34, "did": 10, "params": [ {"k": "state", "v": "on" } ] }, ... ] } === Get lamp dimming === GET /CID/DID/dimming Returns: { "timestamp": "2014-03-25T14:03.547Z", "data": [ { "cid": 34, "did": 10, "params": [ {"k": "dimming", "v": 50 } ] }, ... ] } === Get multiple parameters === GET /CID/DID/state,dimming Returns: { "timestamp": "2014-03-25T14:03.547Z", "data": [ { "cid": 34, "did": 10, "params": [ {"k": "state", "v": "on" }, {"k": "dimming", "v": 50 } ] }, ... ] } === Get all parameters === GET /CID/DID/all Returns: { timestamp: "2014-03-25T14:03.547Z", data: [ { "cid": 34, "did": 10, "params": [ { "k": "state", "v": "on" }, ... ] }, ... ] } === Subscribe to parameter changes === This is done by specifying the ''lasttimestamp'' GET parameter, which contains the last known timestamp of an update: GET /34/all/state?lasttimestamp=2014-03-25T14:03:18.547989+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. === Nonexistant CID, DID or parameters === In case of nonexistant CID, DID or parameters a null is returned as parameter value Assuming that ''foo'' does not exist the following request: 1/9/status,foo results in: { "timestamp":"2014-09-17T11:31:29.804738+0200", "data": [ { "cid":1, "did":9, "params": [ {"k":"status", "v":0.0}, {"k":"foo", "v":null} ] } ] } ==== Log interface ==== === Subscribe to newly generated logs === GET /log/CID/DID No response is given initially; connection is kept alive and every time any log entries appear, an object containing a single array object called ''log data'', which in turn contains log entries, is supplied { "logdata": [ { json obj } ] } === Get logs from a certain date and subscribe to new entries === GET /log/CID/DID?fromtimestamp=XXXXXXX Response: { "lastknowntimestamp": XXXXXXX "logdata": [ { json obj }, { json obj }, ... { json obj } ] } connection is then kept alive and every time any new log entries appear, an object containing a single array object called ''log data'', which in turn contains log entries, is supplied { "logdata": [ { json obj } ] } === Get logs from a certain period === GET /log/CID/DID?fromtimestamp=XXXXXXX&totimestamp=YYYYYYY Response: { "lastknowntimestamp": XXXXXXX "logdata": [ { json obj }, { json obj }, ... { json obj } ] } connection is then closed. === Logged data === Assumming that there is a GET request: ''http://192.168.20.1/2/3/state'', ''json obj'' in the above statements is structured as: { "timestamp": TTTTT, "who": "192.168.20.1", "type": "request", "method": "GET", "origin": "192.168.20.2", "target": "192.168.20.1", "cid": 2, "did": 3, "resource": "state", "payload": null } where * ''payload'' contains complete data sent as the payload (content of the request or reply), * ''type=request | response'', * ''method=PUT | GET''. ==== LIMS interface ==== === LIMS Info interface === Main goal: * device geo location, * mapping between logical model (type, idx, class, attributes) and physical deployment (cabinet,device). GET /info Response: [ { "type": "d", "class": "dark", "idx": 1, "attributes": [ {"key": "detected", "communication": "ro", "type": "atom", "values": [ "true", "false", "unknown" ]}, {"key": "control", "communication": "rw", "type": "numeric", "ranges": [ {"from": 0, to: 10, "precision": 0.1 } ] } ] "cid": 1, "did": 22, "coordinates": { "lat": 45.7811111, "lon": -108.5038888, "alt": 12.223112 } }, ... ] where ''attributes'' object consists of: * ''key'' - attribute name, * ''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''. A complete example: [ { "type":"d", "class":"done", "idx":1, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":1, "coordinates": {"lon":19.972399, "lat":50.066368, "alt":0.0} }, { "type":"d", "class":"done", "idx":2, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":2, "coordinates": {"lon":19.972399, "lat":50.066353, "alt":0.0} }, { "type":"d", "class":"done", "idx":3, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":3, "coordinates": {"lon":19.972534, "lat":50.066368, "alt":0.0} }, { "type":"d", "class":"done", "idx":4, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":4, "coordinates": {"lon":19.972534, "lat":50.066357, "alt":0.0} }, { "type":"d", "class":"done", "idx":5, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":5, "coordinates": {"lon":19.972408, "lat":50.06628, "alt":0.0} }, { "type":"d", "class":"done", "idx":6, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":6, "coordinates": {"lon":19.972408, "lat":50.066265, "alt":0.0} }, { "type":"d", "class":"done", "idx":7, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":7, "coordinates": {"lon":19.972542, "lat":50.066284, "alt":0.0} }, { "type":"d", "class":"done", "idx":8, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":8, "coordinates": {"lon":19.972542, "lat":50.066269, "alt":0.0} }, { "type":"l", "class":"light", "idx":1, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":9, "coordinates": {"lon":19.972359, "lat":50.066387, "alt":0.0} }, { "type":"l", "class":"light", "idx":2, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":10, "coordinates": {"lon":19.972464, "lat":50.066395, "alt":0.0} }, { "type":"l", "class":"light", "idx":3, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":11, "coordinates": {"lon":19.972553, "lat":50.066399, "alt":0.0} }, { "type":"l", "class":"light", "idx":4, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":12, "coordinates": {"lon":19.972368, "lat":50.066322, "alt":0.0} }, { "type":"l", "class":"light", "idx":5, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":13, "coordinates": {"lon":19.972433, "lat":50.066322, "alt":0.0} }, { "type":"l", "class":"light", "idx":6, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":14, "coordinates": {"lon":19.972496, "lat":50.066322, "alt":0.0} }, { "type":"l", "class":"light", "idx":7, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":15, "coordinates": {"lon":19.972559, "lat":50.066326, "alt":0.0} }, { "type":"l", "class":"light", "idx":8, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":16, "coordinates": {"lon":19.972376, "lat":50.066235, "alt":0.0} }, { "type":"l", "class":"light", "idx":9, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":17, "coordinates": {"lon":19.972569, "lat":50.066238, "alt":0.0} }, { "type":"l", "class":"light", "idx":10, "attributes": [ { "key":"status", "communication":"rw", "type":"numeric", "values": [], "ranges": [ {"from":0.0, "to":100.0, "precision":10.0} ] } ], "cid":1, "did":18, "coordinates": {"lon":19.972492, "lat":50.066177, "alt":0.0} }, { "type":"d", "class":"present", "idx":11, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":19, "coordinates": {"lon":19.972399, "lat":50.066391, "alt":0.0} }, { "type":"d", "class":"present", "idx":12, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":20, "coordinates": {"lon":19.972528, "lat":50.066395, "alt":0.0} }, { "type":"d", "class":"present", "idx":13, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":21, "coordinates": {"lon":19.972401, "lat":50.066322, "alt":0.0} }, { "type":"d", "class":"present", "idx":14, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":22, "coordinates": {"lon":19.972536, "lat":50.066326, "alt":0.0} }, { "type":"d", "class":"present", "idx":15, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":23, "coordinates": {"lon":19.972406, "lat":50.066235, "alt":0.0} }, { "type":"d", "class":"present", "idx":16, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":24, "coordinates": {"lon":19.972544, "lat":50.066238, "alt":0.0} }, { "type":"d", "class":"dark", "idx":21, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["true", "false" ], "ranges": [] } ], "cid":1, "did":25, "coordinates": {"lon":19.972429, "lat":50.066425, "alt":0.0} }, { "type":"d", "class":"hour", "idx":22, "attributes": [ { "key":"detected", "communication":"ro", "type":"atom", "values": ["night", "day" ], "ranges": [] } ], "cid":1, "did":26, "coordinates": {"lon":19.972481, "lat":50.066425, "alt":0.0} } ]