API v2.0¶
Warning
Not all sensors/project may provide all measurands that are documented here. That depends on hardware capabilities and project configuration.
The base url is: https://josene.intemo.com/
API methods¶
List devices¶
- GET /sensors/v2.0/devices¶
Get a list of devices that are available
Example request:
GET /sensors/v2.0/devices HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "devices": [ "/sensors/v2.0/devices/14561", "/sensors/v2.0/devices/14564", "/sensors/v2.0/devices/15300" ] }
Example request:
GET /sensors/v2.0/devices?user_field__contains=Amsterdam&type=main HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "devices": [ "/sensors/v2.0/devices/14561" ] }
- Status Codes:
200 OK – OK
403 Forbidden – Authorization error
- Query Parameters:
user_field – Show only sensors that have this user_field (case insensitive)
user_field__contains – Show only sensors which user_field contain this value (case insensitive)
hardware_id – Show only sensors that have this hardware_id (case insensitive)
type – [main, sub, all] Show only sensors which are a main or sub board. defaults to all
Get metadata¶
- GET /sensors/v2.0/devices/(uint32: sensor_id)¶
Get meta data list for a specific sensor sensor_id
Example request:
GET /sensors/v2.0/devices/14561 HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "id": "14561", "hardware": { "id": "0004A30B00012AD0", "sensors" : [{"measurand": "NH3 Concentration", "type": "Gas, Calyx, N100 Ammonia , NH3" }], }, "last": "/sensors/v2.0/devices/14561/last", "subs": [14562, 14563], "main": 14660, "location": "gps", "outputs": [ { "name": "battery_current.mA" }, { "name": "battery_gauge.mCoulomb" }, { " snipped..."}, ], "user_field": "My fancy name", "serial_number": "22090019", "timeseries": "/sensors/v2.0/devices/14561/timeseries" }
- Parameters:
sensor_id – id of device
- Status Codes:
200 OK – OK
404 Not Found – sensor_id not found
403 Forbidden – Authorization error
- Response JSON Object:
id – sensor_id of the sensor
hardware (object) – Hardware details of the sensor
hardware_id – Hardware id (hex format)
hardware_sensors – List of sensor info (Informative only, format may change)
main – sensor_id of the corresponding main sensor (if any)
subs – sensor_ids of the corresponding sub sensors (if any)
location – “gps” location is read from gps in sensor, “fixed” location is fixed. (only available on the main sensor)
user_field – Custom field writable by api user. Useful for naming, cross-referencing or grouping (string, max length = 50)
serial_number – Intemo serial number
Multiple sensor devices can be placed in the same physical sensor. In that case you have one main sensor, and one or more sub-sensors. Every sensor is visible in the api with its own sensor_id and the topology can be derived from the main and subs fields in the response.
Update metadata¶
- POST /sensors/v2.0/devices/(uint32: sensor_id)¶
Update meta data fields list for a specific sensor sensor_id
Example request:
POST /sensors/v2.0/devices/14561 HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X { "user_field": "My fancy name" }
Example response:
HTTP/1.1 201 CREATED Content-Type: application/json; charset=utf-8
- param sensor_id:
id of device
- status 201:
OK
- status 404:
sensor_id not found
- status 400:
Invalid parameter or invalid value
- status 403:
Authorization error
- jsonparam string user_field:
Update user_field
- jsonparam string serial_number:
Update serial_number
- jsonparam int hardware_type:
Hardware type (EG: 22000)
- jsonparam string hardware_revision:
Hardware rev (Eg: “A03”)
- jsonparam string firmware_version:
Firmware version (Eg: “1.0.4”)
Pass an empty value (“”) to erase a field.
Note
You can only update the fields documented here. the other fields are not writable via the API.
Note
Not all api keys have write access enabled. If you POST metadata with an apikey that has write access not enabled you get a 403 with an informative body eg: “token has no write access”
Note
serial_number, hardware_type, hardware_revision, firmware_version are Intemo internal apis. These require special permission. If you try to update these fields with an ApiKey without those permissions you get a 403.
Create Sensor¶
- POST /sensors/v2.0/devices¶
Create a new sensor in the database.
Example request:
POST /sensors/v2.0/devices/ HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X { "hardware": {"id": "0004A30B00012AD0"}, "user_field": "My fancy name" "project_id": 2, "serial_number": "22090019", }
Example response:
HTTP/1.1 201 CREATED Content-Type: application/json; charset=utf-8 { "id": "14561" }
- param sensor_id:
id of device
- status 201:
OK
- status 400:
Invalid parameter or invalid value
- status 403:
Authorization error
- status 409:
Object already existed (hardware id is already known)
- jsonparam string hardware.id:
unique hardware identifier
- jsonparam string user_field:
user_field
- jsonparam string serial_number:
serial_number
- jsonparam int hardware_type:
Hardware type (EG: 22000)
- jsonparam string hardware_revision:
Hardware rev (Eg: “A03”)
- jsonparam string firmware_version:
Firmware version (Eg: “1.0.4”)
- jsonparam string project_id:
Project id (sensor gets initially assigned to this project)
- >json string id:
Resulting sensor_id of created object
Note
This is an Intemo internal API. Not all api keys have access to this method. If your api key does not have the correct permissions, you get a 403 with an informative body.
Days¶
- GET /sensors/v2.0/devices/(uint32: sensor_id)/timeseries¶
Get the available days of timeseries for a specific sensor sensor_id.
Example request:
GET /sensors/v2.0/devices/14561/timeseries HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "days": [ "/sensors/v2.0/devices/14561/timeseries/20171207", "/sensors/v2.0/devices/14561/timeseries/20171208", "/sensors/v2.0/devices/14561/timeseries/20171215", "/sensors/v2.0/devices/14561/timeseries/20171216", "/sensors/v2.0/devices/14561/timeseries/20171217" ], "id": "14561" }
- Parameters:
sensor_id – id of device
- Status Codes:
200 OK – OK
404 Not Found – sensor_id not found
403 Forbidden – Authorization error
Hours¶
- GET /sensors/v2.0/devices/(uint32: sensor_id)/timeseries/(int: date)¶
Get the available days of timeseries for a specific sensor sensor_id.
Example request:
GET /sensors/v2.0/devices/14561/timeseries/20171208 HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "date": "2017/12/08", "hours": [ 9, 10, 11, 12, 13, 14 ], "id": "14561" }
- Parameters:
sensor_id – id of device
date – YYYYMMDD encoded date
- Status Codes:
200 OK – OK
404 Not Found – sensor_id not found
403 Forbidden – Authorization error
Note
Date/Time is in UTC
The hour number ranges from 1 to 24; 1 means from 0:00:00 until 0:59:59
The date should include zero padding, so 1 january 2018 should be encoded as 2018010
Get data¶
- GET /sensors/v2.0/devices/(uint32: sensor_id)/timeseries/(int: date)/(int: hour)¶
Get all sensor data in time window date and hour for sensor sensor_id.
Example request:
GET /sensors/v2.0/devices/14561/timeseries/20171208/9 HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "date": "2017/12/08", "hour": 9, "id": "14561", "timeseries": [ { "accelero_z.g": 1.07421875, "max_audio_125Hz.dbA": 30, "max_audio_630Hz.dbA": 26, "mom_audio_2_5kHz.dbA": 25, "max_audio_total.dbA": 48, "time": "2017-12-08T08:22:53.972Z" }, { " snipped ..." }, { " snipped ..." } ] }
- Parameters:
sensor_id – id of device
date – YYYYMMDD encoded date
hour – hour
- Query Parameters:
measurands – (Optional) comma separated list of measurands you want to see. (defaults to show all)
- Status Codes:
200 OK – OK
404 Not Found – sensor_id not found
403 Forbidden – Authorization error
In timeseries a number of measurands is given.
In timeseries you find a list of measurements. Each measurements contains a set of measurands on a single time. The unit of the measurand is encoded in the measurand name. See Data format for details on the unit abbreviations
Note
Date/Time is in UTC
The hour number ranges from 1 to 24; 1 means from 0:00:00 until 0:59:59
The date should include zero padding, so 1 Januari 2018 should be encoded as 2018010
Get last data¶
- GET /sensors/v2.0/devices/(uint32: sensor_id)/last¶
Get the last sensor data of sensor sensor_id
Example request:
GET /sensors/v2.0/devices/14561/last HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "id": "14561", "accelero_z.g": 1.07421875, "max_audio_125Hz.dbA": 30, "max_audio_630Hz.dbA": 26, "mom_audio_2_5kHz.dbA": 25, "max_audio_total.dbA": 48, " snipped ...", " snipped ..." "time": "2018-01-11T08:40:51.521Z" }
- Parameters:
sensor_id – id of device
- Query Parameters:
measurands – (Optional) comma separated list of measurands you want to see. (leaving out defaults to show all)
- Status Codes:
200 OK – OK
404 Not Found – sensor_id not found
403 Forbidden – Authorization error
The reply contains a number of measurands. See Data format for details how to interpret that unit.
Get last data (multiple)¶
- GET /sensors/v2.0/devices/last/(comma_separated: sensor_ids)¶
Get the last sensor data of a series of sensors. This api is similar to Get last data but queries multiple sensors in a single request. This api should be used when querying every sensor individually takes much overhead/latency.
Example request:
GET /sensors/v2.0/devices/last/14561,14562 HTTP/1.1 Host: josene.intemo.com Authorization: Bearer yEUqAXfH06WPr81IKU1X
Example response:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 [ { "id": "14561", "max_audio_100Hz.dbA": 30, " snipped ...", " snipped ..." "time": "2018-01-11T08:40:51.521Z" }, { "id": "14562", "max_audio_100Hz.dbA": 32, " snipped ...", " snipped ..." "time": "2018-01-11T08:41:50.123Z" } ]
- Parameters:
sensor_ids – comma separated list of sensor ids
- Query Parameters:
measurands – (Optional) comma separated list of measurands you want to see. (leaving out defaults to show all)
- Status Codes:
200 OK – OK. If not all sensors in sensor_ids could be found, we return a 200 with the sensors that do exist.
404 Not Found – None of the sensors in sensor_ids could be found.
403 Forbidden – Authorization error
The reply contains a number of measurands. See Get metadata what the unit is, and see Data format for details how to interpret that unit.
Data format¶
This chapter describes how to interpret the units of the measurands.
Warning
This chapter is not complete.
Some of the units are self explanatory: eg “milliKelvin”, “milliAmpere”, “milliCoulomb”. The ones that are not self explanatory are described in in the table below.
unit |
description |
conversion |
example |
---|---|---|---|
|
degrees latitude |
longitude |
|
|
milli degrees (angle) |
||
|
milli Volt |
||
|
milli Ampere |
||
|
nano Volt |
||
|
milli Coulomb |
||
|
milli Kelvin |
||
|
dB(A) sound pressure |
||
|
parts per billion |
498000 is 498 ppm |
|
|
seconds |
||
|
lux |
||
|
Pascal |
||
|
g-force 9.81 m/s^2 |
||
|
meter |
||
|
micro gram per cubic meter |
||
|
nano gram per cubic meter |
||
|
# html color code eg: 0x808000 = #808000 = olive |
||
|
Ohm |
||
|
m/s meter per second (speed) |
||
|
mm/s milli-meter per second (speed) |
||
|
micro liter per second |
||
|
milli |
||
|
relative humidity in % |
||
|
Kelvin |
||
|
<undocumented> |
for internal use only |
wind direction¶
Wind direction is reported by the direction from which is originates where 0 degrees is north, 180 is south.
degrees |
origin |
meaning |
---|---|---|
0 |
north |
wind blowing from north to south |
90 |
east |
wind blowing from east to west |
180 |
south |
wind blowing from south to north |
270 |
west |
wind blowing from west to east. |
audio format¶
Audio measurements return four types measurements:
average in sample interval
minimum values in sample interval
maximum values in sample interval
momentary level (single measurement)
A sample interval is typically 10s.
Audio levels are send in dB(A), where 0 dB(A) is the lowest, and 127 dB(A) is the highest possible value.
The four types of measurements are distinguished by the prefix in the measurands in the api.
type |
prefix |
example |
---|---|---|
average data |
avg_audio_ |
avg_audio_25Hz.dbA |
minumum data |
min_audio_ |
min_audio_31_5Hz.dbA |
maximum data |
max_audio_ |
max_audio_31_5Hz.dbA |
momentary data |
mom_audio_ |
mom_audio_125Hz.dbA |
The following table lists all the frequency sub-bands the sensors measure. Each of the audio types above, have the bands below.
measurand |
Freq |
---|---|
|
25 Hz |
|
31.5 Hz |
|
40 Hz |
|
50 Hz |
|
63 Hz |
|
80 Hz |
|
100 Hz |
|
125 Hz |
|
160 Hz |
|
200 Hz |
|
250 Hz |
|
315 Hz |
|
400 Hz |
|
500 Hz |
|
630 Hz |
|
800 Hz |
|
1 kHz |
|
1.25 kHz |
|
1.6 kHz |
|
2 kHz |
|
2.5 kHz |
|
3.15 kHz |
|
4 kHz |
|
5 kHz |
|
6.3 kHz |
|
8 kHz |
|
10 kHz |
|
12.5 kHz |
|
16 kHz |
|
20 kHz |
|
sum of bands |
Total audio¶
The sensors measure the audio in 1/3 octave bands. Besides these sub-bands measurands the api exports the ‘total’ audio pressure. This total value is not directly measued but calculated by adding the sub-band data.
type |
measurand |
---|---|
average data |
total_avg_audio.dbA |
minumum data |
total_min_audio.dbA |
maximum data |
total_max_audio.dbA |
momentary data |
total_mom_audio.dbA |
NB: The total audio values are not plain additions, but rather additions taking into account the logarithmic scales of the dB(A) values. The following code example shows how the total audio fields are calculated.
import numpy as np
def db_sum(levels):
"""Add audio levels
This is what smartemission does too: https://github.com/smartemission/
further references:
http://www.sengpielaudio.com/calculator-spl.htm
:param levels: list of levels (dB).
:type levels: list
:return: sum of audio levels
:rtype: float
>>> '%.1f' % db_sum([80])
'80.0'
>>> '%.2f' % db_sum([80, 80, 80])
'84.77'
>>> '%.2f' % db_sum([80] * 30)
'94.77'
>>> '%.2f' % db_sum([0] * 30)
'0.00'
"""
levels = np.asanyarray(levels)
total = 10.0 * np.log10((10.0 ** (levels / 10.0)).sum())
# Adding 30 zeroes, end up with a dB(A) of 15
# if that is the case just round down to zero again, that is much clearer
if total <= 15:
total = 0
return total
Color temperature¶
The api may provide a measurand color_temperature.K
.
This is not a directly measured value but rather a calculated value based
on a measured RGB value (rgb_color.html
).
We use the algorithm as proposed by Javier Hernandez-Andre to calculate the temperature, using the library colour.
Warning
This algorithm may have unexpected results for some RGB values. Even negative values for color_temperature.K may be reported.