** Application is in beta mode (API build: 1.0.8, core system build: 2.0.0) **
POST
/api/providers/create
¶
Creates a new data provider.
Parameters: |
|
---|---|
Request: JSON Object | |
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST /api/providers/create HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
{
"name": "Data Provider",
"acronym": "DP",
"description": "Provider description",
"username": "my.username",
"password": "my100th.Secret.password",
"email": "my.mail.address@any.domain.com"
}
Example response:
HTTPS/1.1 201 OK
Content-Type: application/json
{
"providerid": 10,
"message": "Created",
"token": "c85c8ed3da7944ee9ff82ef34f863d49",
"http-status-code": 201,
"atom": "https://sensors.nilu.no/api/providers/10"
}
Note: New data providers are by default shipped with one authentication token. More tokens can be created if required. Also see this section.
POST
/api/providers/tokens/new
¶
Creates a new token (with indefinite expiration date) for data provider.
Response: JSON Object: | |
---|---|
|
|
Status Codes: |
|
Example request:
POST /api/providers/tokens/new HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Basic MDZmODQ2MmE0ZTAzNDNiOjIzYmFjYjIwYTU=
Example response:
HTTPS/1.1 201 OK
Content-Type: application/json
{
"providerid": 10,
"message": "Created",
"token": "ec0de379f8304fa396a032698c9050fa",
"http-status-code": 201
}
Note: Basic authentication is used. Username and password must therefore be Base64 encoded. Please refer to this section.
POST
/api/providers/tokens/new/{string: format}
¶
Creates a new provider token with custom expiration date.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST /api/providers/tokens/new/10d HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Basic ZWU1MDI5ZTBkNjNlNDVkOjlhMjE3NjViYTI=
Example response:
Please refer to this section.
POST
/api/providers/tokens/revoke
¶
Revokes the data provider token.
Response: JSON Object: | |
---|---|
|
|
Status Codes: |
|
Example request:
POST /api/providers/tokens/revoke HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
Authorization: Basic ZjUxM2NmMzQ2MDM3NDk4OjRiMjY4NjExNmI=
{
"token": "37bc37b7cf9644758b69af1860d28c83"
}
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"providerid": 10,
"message": "OK",
"http-status-code": 200
}
GET
/api/providers/{int: id}
¶
Get data provider identified by id.
Parameters: |
|
---|---|
Response: JSON object: | |
Status Codes: |
|
Example request:
GET /api/providers/1 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"name": "Norwegian Institute for Air Research",
"acronym": "NILU",
"atom": "https://sensors.nilu.no/api/providers/1",
"description": "Norwegian Institute for Air Research is an independent, nonprofit institution established in 1969.",
"created": "2020-04-15T08:14:14.3191140Z"
}
GET
/api/providers
¶
Get a list of data providers.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
Status Codes: |
|
Example request:
GET /api/providers HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 1,
"name": "Norwegian Institute for Air Research",
"acronym": "NILU",
"atom": "https://sensors.nilu.no/api/providers/1",
"description": "Norwegian Institute for Air Research is an independent, nonprofit institution established in 1969.",
"created": "2020-04-15T08:14:14.3191140Z"
},
{
"id": 2,
"name": "Data Provider",
"acronym": "DP",
"atom": "https://sensors.nilu.no/api/providers/2",
"description": "Description of data provider.",
"created": "2024-11-18T19:33:46.9983075Z"
}]
GET
/api/sensors/providers/{int: id}
¶
Get a list of sensors using the provider id.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/providers/1 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
Please refer to this section.
GET
/api/data/id/{int: id}/minutc
¶
Gets the oldest sensor data identified by id.
Under re-implementation (temporary unavailable).
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/122/minutc HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer ef522ce87c6e490d87b402e2af7d8820
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
X-disclaimer: NILU makes no warranty of any kind, express or implied, concerning the provided data and information (..)
[{
"id": 122,
"component": "Humidity",
"value": 15.98,
"unit": "%RH",
"longitude": -90,
"latitude": 90,
"altitude": 1,
"level": 0,
"epsg": 4326,
"timestamp_from_epoch": 1588067073,
"timestamp_to_epoch": 1588067133,
"qc_flags": {
"flags": 1,
"bitflags": "00000001"
},
"qcs_flags": {
"flags": 6,
"bitflags": "0000000000000110"
}
},
{
"id": 122,
"component": "PM2.5",
"value": 2.45,
"unit": "µg/m³",
"longitude": -90,
"latitude": 90,
"altitude": 1,
"level": 0,
"epsg": 4326,
"timestamp_from_epoch": 1588067073,
"timestamp_to_epoch": 1588067133,
"qc_flags": {
"flags": 9,
"bitflags": "00001001"
},
"qcs_flags": {
"flags": 62,
"bitflags": "0000000000111110"
}
}]
GET
/api/data/id/{int: id}/maxutc
¶
Gets last sensor data identified by id.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/122/maxutc HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer 114268930ee14f8bb52da1b840a338f5
Example response:
Please refer to this section.
GET
/api/data/id/{int: id}/fromutc/{string: fromUtc}
¶
Get sensor data using a UTC timestamp. The end UTC date will be 2 months ahead the start UTC date.
Parameters: | |
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/122/fromutc/2020-01-20T09:20:05.13Z HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer 752b66c65fd846a794f2753b5e778153
Example response:
Please refer to this section.
GET
/api/data/id/{int: id}/fromutc/{string: fromUtc}/toutc/{string: toUtc}
¶
Get sensor data using a UTC timestamp range. Date range cannot exceed 2 months.
Parameters: | |
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/122/fromutc/2020-01-20T09:20:05.13Z/toutc/2021-01-20T09:20:05.13Z HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer aaa47440582344ca8156fc5b7b51ecb6
Example response:
Please refer to this section.
GET
/api/data/id/{int: id}/{string: period}/stats(?exclude=position|none)
¶
Get last periodic statistics for sensor identified by id.
Outliers are ignored in the calculation.
When ?exclude=position is used in HTTP GET, the aggregation is not performed on distinct sensor positions. Instead the averaged sensor positions are used within the aggregation groups. The aggregation is much slower when not using this filter, especially for moving sensors with a lot of distinct positions.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/117/hourly/stats HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer aed28136f46947ba92ff27fdc27d1ebf
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 117,
"timestamp_from_epoch": 1605164400,
"timestamp_to_epoch": 1605168000,
"component": "Humidity",
"level": 1,
"unit": "%RH",
"qc": 0,
"n": 35,
"of": -1,
"res": 60,
"avg": 67.27,
"median": 67.36,
"min": 65.84,
"max": 68.44,
"std_dev": 0.71,
"var": 0.509,
"sem": 0.121,
"mse": 0.014542857142857144,
"cv": 0.010554481938456964,
"q1": 66.8,
"q3": 67.88,
"iqr": 1.0799999999999983,
"epsg": 4326,
"longitude": 5.312691,
"latitude": 60.395897,
"altitude": 3
},
{
"id": 117,
"timestamp_from_epoch": 1605164400,
"timestamp_to_epoch": 1605168000,
"component": "PM10.0",
"level": 1,
"unit": "µg/m³",
"qc": 1,
"n": 5,
"of": 0.01,
"res": 60,
"avg": 1.01,
"median": 0.97,
"min": 0.69,
"max": 1.33,
"std_dev": 0.3,
"var": 0.1,
"sem": 0.13,
"mse": 0.02,
"cv": 0.297029702970297,
"q1": 0.73,
"q3": 1.31,
"iqr": 0.5800000000000001,
"epsg": 4326,
"longitude": 5.312691,
"latitude": 60.395897,
"altitude": 3
},
..
..
..
]
GET
/api/data/id/{int: id}/{string: period}/stats/fromutc/{string: fromUtc}/toutc/{string: toUtc}(?exclude=position|none)
¶
Get periodic statistics for sensor using a UTC timestamp range. Date range cannot exceed 2 months.
Outliers are ignored in the calculation.
When ?exclude=position is used in HTTP GET, the aggregation is not performed on distinct sensor positions. Instead the averaged sensor positions are used within the aggregation groups. The aggregation is much slower when not using this filter, especially for moving sensors with a lot of distinct positions.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
Example request:
GET /api/data/id/117/hourly/stats/fromutc/2020-10-01T09:00:00.00Z/toutc/2020-10-01T10:00:00.00Z HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer 2e643661e9aa4396a9626a6f5ecae0be
Example response:
Please refer to this section.
GET
/api/sensors/??
¶
Get raw sensor data using a UTC timestamp.
Not yet implemented.
The QC flags are set at raw value level.
Table below displays the possible QC flags:
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|
X | X | X | Value is an outlier (ML model) | Value repeating | Value > max | Value < min | QC operation executed |
X = bit not in use
Example: The string representation of the following QC flags "00001011" indicates that a value is repeating (a specified number of times), and also that it is lower than a (specified) minumum value. The numeric value will be 11.
Example: The string representation of the following QC flags "00000000" indicates that QC operations has not been performed for value. The numeric value will be 0.
Example: The string representation of the following QC flags "00000001" indicates that a QC operation has been performed, but no other flags are set. The numeric value will be 1.
Hint: To test whether a specific QC flag is set, the bitwise logical AND operator can be used upon the numeric QC flags value.
The QCS flags are set at raw value level.
Table below displays the possible QCS flags:
32768 | 16384 | 8192 | 4096 | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
X | X | X | X | Value corr. failed (outlier(s)) | Value corr. failed (NaN) | Value corr. failed (expression) | Value corr. failed (eval) | Value corr. failed (unknown) | Outlier detection failed | Value corr. enabled | Outlier detection enabled | Persistence check enabled | Range check (max) enabled | Range check (min) enabled | X |
X = bit not in use
Table below displays the possible QA flags:
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|
X | X | X | X | Value accepted | Metadata complete | X | X |
X = bit not in use
Hint: To test whether a specific QA flag is set, the bitwise logical AND operator can be used upon the numeric QA flags value.
Table below displays the possible QAS flags:
32768 | 16384 | 8192 | 4096 | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
X | X | X | X | X | X | Window varying positions | Mad zero value | Window too small | X | X | X | Value outlier | Value persistent | Value out of range | X |
X = bit not in use
NILU makes no warranty of any kind, express or implied, concerning the provided data and information, including but not limited to any warranties of merchantability or fitness for any particular purpose.
NILU assumes no responsibility or legal liability concerning the data’s accuracy, reliability, completeness, timeliness, or usefulness.
GET
/api/sensors/{int : id}
¶
Get sensor identified by sensor id.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/393 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"id": 393,
"name": "Innosense",
"provider": {
"id": 1,
"name": "Norwegian Institute for Air Research",
"atom": "https://sensors.nilu.no/api/providers/1"
},
"resolution": 60,
"srs": {
"epsg": 2000,
"srtext": "PROJCS["Anguilla 1957 / British West Indies Grid",GEOGCS["Anguilla 1957",DATUM["Anguilla_1957",SPHEROID["Clarke 1880 (RGS)",6378249.145,293.465,AUTHORITY["EPSG","7012"]],AUTHORITY["EPSG","6600"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4600"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-62],PARAMETER["scale_factor",0.9995],PARAMETER["false_easting",400000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2000"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]",
"srtext": "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/2000"
},
"enabled": true,
"parameters": [{
"name": "no2",
"type": "double",
"doc": "Predicted NO2 in microgram"
},
{
"name": "date",
"type": "long",
"doc": "Date of measurement"
}],
"location":
{
"longitude": 67,
"latitude": 50,
"altitude": 1.5
},
"components": [
{
"id": 8,
"name": "NO2",
"binding-path": "/no2",
"conv_factor": 1.0,
"atom": "https://sensors.nilu.no/api/components/8",
"unit": {
"id": 3,
"name": "µg/m³",
"atom": "https://sensors.nilu.no/api/units/3"
},
"level": {
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
}}
],
"converters": [
{
"input-type": "string",
"output-type": "StringEpochTime",
"target-path": "/date",
"input-args": {
"input-format": "yyyy/MM/dd HH:mm:ss",
"timezone": "Europe/Stockholm" },
"atom": "https://sensors.nilu.no/api/doc/converters#StringEpochTime"
},
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/no2",
"atom": "https://sensors.nilu.no/api/doc/converters#StringDouble"
}],
"mapping": [
{
"name": "Timestamp",
"target-path": "/date",
"atom": "https://sensors.nilu.no/api/doc/fieldmapping#Timestamp"
}],
"pipeline":
{
"flags": 0,
"bitflags": "00000000",
"status": "Never processed",
"atom": "https://sensors.nilu.no/api/sensors/393/pipeline",
"processed": null
},
"created": "2018-12-17T12:56:23.405806Z",
"atom": "https://sensors.nilu.no/api/sensors/393",
"endpoint": "https://sensors.nilu.no/api/sensors/393/inbound"
}
GET
/api/sensors
¶
Get a list of sensors.
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/sensors HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 393,
"name": "Innosense",
"provider": {
"id": 1,
"name": "Norwegian Institute for Air Research",
"atom": "https://sensors.nilu.no/api/providers/1"
},
"resolution": 60,
"srs": {
"epsg": 2000,
"srtext": "PROJCS["Anguilla 1957 / British West Indies Grid",GEOGCS["Anguilla 1957",DATUM["Anguilla_1957",SPHEROID["Clarke 1880 (RGS)",6378249.145,293.465,AUTHORITY["EPSG","7012"]],AUTHORITY["EPSG","6600"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4600"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-62],PARAMETER["scale_factor",0.9995],PARAMETER["false_easting",400000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2000"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]",
"srtext": "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/2000"
},
"enabled": true,
"parameters": [{
"name": "no2",
"type": "double",
"doc": "Predicted NO2 in microgram"
},
{
"name": "date",
"type": "long",
"doc": "Date of measurement"
}],
"location":
{
"longitude": 67,
"latitude": 50,
"altitude": 1.5
},
"components": [
{
"id": 8,
"name": "NO2",
"binding-path": "/no2",
"conv_factor": 1.0,
"atom": "https://sensors.nilu.no/api/components/8",
"unit": {
"id": 3,
"name": "µg/m³",
"atom": "https://sensors.nilu.no/api/units/3"
},
"level": {
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
}}
],
"converters": [
{
"input-type": "string",
"output-type": "StringEpochTime",
"target-path": "/date",
"input-args": {
"input-format": "yyyy/MM/dd HH:mm:ss",
"timezone": "Europe/Stockholm" },
"atom": "https://sensors.nilu.no/api/doc/converters#StringEpochTime"
},
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/no2",
"atom": "https://sensors.nilu.no/api/doc/converters#StringDouble"
}],
"mapping": [
{
"name": "Timestamp",
"target-path": "/date",
"atom": "https://sensors.nilu.no/api/doc/fieldmapping#Timestamp"
}],
"pipeline":
{
"flags": 0,
"bitflags": "00000000",
"status": "Never processed",
"atom": "https://sensors.nilu.no/api/sensors/393/pipeline",
"processed": null
},
"created": "2018-12-17T12:56:23.405806Z",
"atom": "https://sensors.nilu.no/api/sensors/393",
"endpoint": "https://sensors.nilu.no/api/sensors/393/inbound"
},
{
"id": 394,
"name": "HackAir",
"provider": {
"id": 1,
"name": "Norwegian Institute for Air Research",
"atom": "https://sensors.nilu.no/api/providers/1"
},
"resolution": 3600,
"srs": {
"epsg": 4326,
"srtext": "GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]",
"srtext": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/4326"
} ,
"enabled": true,
"parameters": [
{
"name": "temperature",
"type": "double",
"doc": "Ground temperature"
},
{
"name": "PM10",
"type": "double",
"doc": "Particulate matter. 10 micrometers or less in diameter."
}],
"location": null,
"components": [
{
"id": 15,
"name": "Temperature",
"binding-path": "/temperature",
"conv_factor": 0.0,
"atom": "https://sensors.nilu.no/api/components/15",
"unit": {
"id": 8,
"name": "K",
"atom": "https://sensors.nilu.no/api/units/8"
},
"level": {
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
}},
{
"id": 12,
"name": "PM10",
"binding-path": "/pm10",
"conv_factor": 1.0,
"atom": "https://sensors.nilu.no/api/components/12",
"unit": {
"id": 3,
"name": "µg/m³",
"atom": "https://sensors.nilu.no/api/units/3"
},
"level": {
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
}}
],
"converters": [
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/temperature",
"atom": "https://sensors.nilu.no/api/doc/converters#StringDouble"
},
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/pm10",
"atom": "https://sensors.nilu.no/api/doc/converters#StringDouble"
}],
"mapping": null,
"pipeline":
{
"flags": 10,
"bitflags": "00001010",
"status": "Raw data processed and stored. QA/QC executed.",
"atom": "https://sensors.nilu.no/api/sensors/394/pipeline",
"processed": "2020-09-08T18:05:32.0000000Z"
},
"created": "2018-12-18T12:50:23.405806Z",
"atom": "https://sensors.nilu.no/api/sensors/394",
"endpoint": "https://sensors.nilu.no/api/sensors/394/{longitude}/{latitude}/{altitude}/inbound"
}]
GET
/api/sensors/{int : id}/components
¶
Get a list of components configured for sensor given id of sensor.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/234/components HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 84,
"name": "PM10",
"type": "Standard",
"atom": "https://sensors.nilu.no/api/components/84"
},
{
"id": 64,
"name": "NO2",
"type": "Standard",
"atom": "https://sensors.nilu.no/api/components/64"
}]
GET
/api/sensors/{int : id}/converters
¶
Get a list of converters configured for sensor given id of sensor.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/234/converters HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[
{
"input-type": "string",
"output-type": "StringEpochTime",
"target-path": "/date",
"input-args": {
"input-format": "yyyy/MM/dd HH:mm:ss",
"timezone": "Europe/Stockholm" },
"atom": "https://sensors.nilu.no/api/doc/converters#StringEpochTime"
},
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/no2",
"atom": "https://sensors.nilu.no/api/doc/converters#StringDouble"
}
]
GET
/api/sensors/{int : id}/mapping
¶
Get a list of field mappers configured for sensor given id of sensor.
Parameters: |
|
---|---|
Response: JSON Array of Objects: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/224/mapping HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[
{
"name": "Timestamp",
"target-path": "/date",
"atom": "https://sensors.nilu.no/api/doc/fieldmapping#Timestamp"
}
]
GET
/api/sensors/{int : id}/location
¶
Get the sensor location given id of sensor.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/224/location HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"longitude": 67.0,
"latitude": 50.0,
"altitude": 1.5
}
Note: If location is not configured for sensor, an empty JSON object ({ }) will be the response from server.
GET
/api/sensors/{int : id}/parameters
¶
Get the parameters configured for sensor given id of sensor.
Parameters: |
|
---|---|
Response: JSON Array of Objects (partial Avro Schema): | |
|
|
Status Codes: |
|
Example request:
GET /api/sensors/234/parameters HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[
{
"name": "temperature",
"type": "double",
"doc": "Ground temperature"
},
{
"name": "PM10",
"type": "double",
"doc": "Particulate matter. 10 micrometers or less in diameter."
}
]
POST
/api/sensors/configure
¶
New sensor schema configuration.
Parameters: |
|
---|---|
Request: JSON Object | |
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST /api/sensors/configure HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
Authorization: Bearer 56e6648fecbf4125991ad49f8e17aaa8
{
"name": "Innosense",
"description": "Innosense sensor",
"resolution": 60,
"srs": {
"epsg": 4326
},
"enabled": true,
"location":
{
"longitude": 67,
"latitude": 50,
"altitude": 1.5
},
"parameters": [
{
"name": "no2",
"type": "double",
"doc": "Predicted NO2 in microgram"
},
{
"name": "date",
"type": "long",
"doc": "Date of measurement"
}]
,
"components": [
{
"componentid": 64,
"unitid": 35,
"binding-path": "/no2"
"level": 1
}]
,
"converters": [
{
"input-type": "string",
"output-type": "StringEpochTime",
"target-path": "/date",
"input-args": {
"input-format": "yyyy/MM/dd HH:mm:ss",
"timezone": "Europe/Stockholm" }
},
{
"input-type": "string",
"output-type": "StringDouble",
"target-path": "/no2"
}]
,
"mapping": [
{
"name": "Timestamp",
"target-path": "/date"
}]
}
Example response:
HTTPS/1.1 201 OK
Content-Type: application/json
{
"sensorid": 421,
"message": "Created",
"http-status-code": 201
"atom": "https://sensors.nilu.no/api/sensors/421"
}
PUT
/api/sensors/{int : id}/reconfigure
¶
Reconfigures existing sensor schema identified by id.
Sensor must be disabled before re-configuration is possible. Please refer to this section.
Parameters: |
|
---|---|
Request: JSON Object | |
|
|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
PUT /api/sensors/123/reconfigure HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
Authorization: Bearer 81b0fe0e7f6f4d558fb6f04797c461e4
{
"name": "Innosense_new",
"description": "Innosense sensor",
"resolution": 20,
"srs": {
"epsg": 4326
},
"enabled": true,
"location":
{
"longitude": 32,
"latitude": 76,
"altitude": 1
}}
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"sensorid": 123,
"message": "OK",
"http-status-code": 200
"atom": "https://sensors.nilu.no/api/sensors/123"
}
The "binding-path" and "target-path" JSON attributes are used when a converter or a field mapper is used when defining the sensor schema.
When defining a new sensor schema and specifying the components, the binding-path is the absolute JSON path to an attribute (in sensor data packet) that will be "bound" to a component (eg. PM10, NO2, CO).
Similar, when using a converter (if required) for one of the components defined using the binding-path, the converter takes the target-path as an argument. The converter requires this path in order to be able to convert an attribute (k) with value (v) located at the given JSON path.
Same principle applies when using a field mapper. The field mapper m is an alias for attribute k with value v located at target path p.
These attributes supports JPath syntax.
Below is a table with some examples:
JSON | Binding / Target (JSON) Path | Remarks |
---|---|---|
{ "no2" : 15.232 } |
"no2" | |
{ "no2" : { "value" : 15.232 }} |
"no2.value" | |
{ "gas" : { "components" : [ { "no2" : { "value" : 15.232 } }, .. , { "no2" : { "value" : 15.232 } } ] }} |
"gas.components[0].no2.value" | |
{ "level1" : { "lev.el2" : { "no2" : { "value" : 15.232 } } } } |
"level1.['lev.el2'].no2.value" | The "." character at path level 2 has been escaped |
POST
/api/sensors/{int : id}/disable
¶
Puts the sensor in disabled mode using the sensor id.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST /api/sensors/393/disable HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Bearer a5d87e77026e4ad9b63619d90416ff7e
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"sensorid": 393,
"message": "OK",
"http-status-code": 200
}
DELETE
/api/sensors/{int : id}/delete
¶
Deletes sensor identified by id.
Sensor must be in disabled state prior to delete operation. Please refer to this section.
Existing data in storage system will not be deleted.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
DELETE /api/sensors/393/delete HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Authorization: Basic M2QwYzAxZDczNjI2NGEwOmMzNGY0YmE3MTA=
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"sensorid": 393,
"message": "OK",
"http-status-code": 200
}
GET
/api/datalevels
¶
Get a list of available datalevels.
The datalevel is set on sensor component during configuration.
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/datalevels HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
},
{
"value": 2,
"description": "Estimate of a geophysical quantity using any available data within the sensor system itself. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/2"
}]
GET
/api/datalevels/{int : level}
¶
Get datalevel identified by value.
Parameters: |
|
---|---|
Response: JSON object: | |
|
|
Status Codes: |
|
Example request:
GET /api/datalevels/1 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"value": 1,
"description": "Estimate of a geophysical quantity derived from corresponding Level-0 data, using basic physical assumptions and no compensation schemes. Often temporally averaged.",
"atom": "https://sensors.nilu.no/api/datalevels/1"
}
POST
/api/sensors/{int : id}/inbound
¶
Data transfer using fixed sensor position.
Parameters: |
|
---|---|
Request: JSON Object | |
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST /api/sensors/393/inbound HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
Authorization: Bearer c4754d140d774a0892607afbfeb82eae
{
"sensorid": "innosense-6",
"date": "2010/10/20 15:00:00",
"position": [
"0.000000",
"0.000000"
],
"rawvalues": [
"fff98ea8",
"000296f6"
..
..
..
],
"samplecount": "40",
"viewer_wanip": "37.253.165.85",
"scanner_wanip": "37.253.165.85",
"regulator": [
"16.54",
"22.93"
..
..
..
],
"no2": "132.5657676765"
}
Note: Only date and NO2 parameters are configured in example above. The date parameter is mapped as timestamp, and the NO2 parameter is mapped as component with a corresponding unit in the backend system. The other parameters are ignored, but stored as raw data, when sensor data is processed (see section above). The parameter sensorid should not be confused with the sensorid in API documentation because sensorid is an internal id used by the sensor vendor in example above.
Also note: When data is in the XML format, the Content-Type request header must be set to application/xml.
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"atom": "https://sensors.nilu.no/api/sensors/393/pipeline",
"message": "OK",
"http-status-code": 200
}
POST
/api/sensors/{int : id}/{double : longitude}/{double : latitude}/{double : altitude}/inbound
¶
Data transfer using GPS enabled sensors.
Parameters: |
|
---|---|
Request: JSON Object | |
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
POST https://sensors.nilu.no/api/sensors/394/60/50/1/inbound HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Content-Type: application/json
Authorization: Bearer 4d858a5ec540468f8a3a37d551c8f1a4
{
"name": "HackAir",
"temperature": "24.61",
"humidity": "50.12",
"pm25": "412.77",
"pm10": "804.34",
"freemembytes": "1024"
}
Note: Only temperature and PM10 parameters are configured in example above and these are the only parameters that will be mapped as components. The other parameters are ignored, but stored as raw data, when data is processed (see section above). Also note that this sample sensor does not contain any timestamp parameter, therefore no timestamp mapping is possible here. In this example the system time will be used as timestamp for data.
Also note: When data is in the XML format, the Content-Type request header must be set to application/xml.
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"atom": "https://sensors.nilu.no/api/sensors/394/pipeline",
"message": "OK",
"http-status-code": 200
}
POST
/api/sensors/{int : id}/inbound/?pushtest=true
¶
Test data transfer using fixed sensor position.
No data will be stored during push-test.
Example request:
Please refer to this section.
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"atom": "https://sensors.nilu.no/api/sensors/393/pipeline/test",
"message": "OK",
"http-status-code": 200
}
POST
/api/sensors/{int : id}/{double : longitude}/{double : latitude}/{double : altitude}/inbound/?pushtest=true
¶
Test data transfer using GPS enabled sensors.
No data will be stored during push-test.
Example request:
Please refer to this section.
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"atom": "https://sensors.nilu.no/api/sensors/394/pipeline/test",
"message": "OK",
"http-status-code": 200
}
GET
/api/components
¶
Get a list of available components.
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/components HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 84,
"name": "PM10",
"type": "Standard",
"atom": "https://sensors.nilu.no/api/components/84"
},
{
"id": 64,
"name": "NO2",
"type": "Standard",
"atom": "https://sensors.nilu.no/api/components/64"
}]
GET
/api/components/{int : id}
¶
Get component identified by component id.
Parameters: |
|
---|---|
Response: JSON object: | |
|
|
Status Codes: |
|
Example request:
GET /api/components/84 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"id": 84,
"name": "PM10",
"type": "Standard",
"atom": "https://sensors.nilu.no/api/components/84"
}
GET
/api/units
¶
Get a list of available units.
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/units HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"id": 3,
"name": "µg/m³",
"atom": "https://sensors.nilu.no/api/units/3"
},
{
"id": 8,
"name": "K",
"atom": "https://sensors.nilu.no/api/units/8"
}]
GET
/api/units/{int : id}
¶
Get unit identified by unit id.
Parameters: |
|
---|---|
Response: JSON object: | |
|
|
Status Codes: |
|
Example request:
GET /api/units/3 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"id": 3,
"name": "µg/m³",
"atom": "https://sensors.nilu.no/api/units/3"
}
It is possible to map a JSON attribute representing a moment in time as a timestamp when storing data.
If this JSON attribute is given as number of seconds since 00:00:00 UTC on 1 January 1970 (Unix Epoch) , then no timestamp converter is required.
On the other hand, if the attribute is represented as a string of any given format (e.g. 'yyyy/MM/dd HH:mm:ss'), then the StringEpochTime converter must be used. This converter converts the string value into Unix Epoch.
In both cases the Timestamp Mapper must be used in order to tell the system that you want to use the JSON attribute as a timestamp. If this attribute mapping is omitted, the system time will instead be used.
GET
/api/timezones
¶
Get a list of available timezones.
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/timezones HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"timezone": "Europe/Stockholm",
"supportsDaylightSavingTime": true
},
..
..
..
{
"timezone": "America/Chicago",
"supportsDaylightSavingTime": true
}]
GET
/api/srs
¶
Get a list of available Spatial Reference Systems (SRS).
Response: JSON Array of Objects: | |
---|---|
|
|
Status Codes: |
|
Example request:
GET /api/srs HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
[{
"epsg": 2000,
"srtext": "PROJCS["Anguilla 1957 / British West Indies Grid",GEOGCS["Anguilla 1957",DATUM["Anguilla_1957",SPHEROID["Clarke 1880 (RGS)",6378249.145,293.465,AUTHORITY["EPSG","7012"]],AUTHORITY["EPSG","6600"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4600"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-62],PARAMETER["scale_factor",0.9995],PARAMETER["false_easting",400000],PARAMETER["false_northing",0],AUTHORITY["EPSG","2000"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]",
"srtext": "+proj=tmerc +lat_0=0 +lon_0=-62 +k=0.9995000000000001 +x_0=400000 +y_0=0 +ellps=clrk80 +units=m +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/2000"
},
..
..
..
..
..
{
"epsg": 4326,
"srtext": "GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]",
"srtext": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/4326"
}]
GET
/api/srs/{int : srid}
¶
Get a Spatial Reference System (SRS) identified by srid.
Parameters: |
|
---|---|
Response: JSON Object: | |
|
|
Status Codes: |
|
Example request:
GET /api/srs/4326 HTTPS/1.1
Host: https://sensors.nilu.no
Accept: application/json
Example response:
HTTPS/1.1 200 OK
Content-Type: application/json
{
"epsg": 4326,
"srtext": "GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]",
"srtext": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ",
"atom": "https://sensors.nilu.no/api/srs/4326"
}
Apache Avro is used to define the data schema to the value of a record. A record value in this context is the sensor data ("packet") itself. The schema describes the fields allowed in the value, along with their expected data types.
The parameter schema for sensor (described in other sections in this document) is defined as a partial Avro schema. It is defined as partial because it is not complete until created in backend system during sensor schema configuration or reconfiguration.
Avro schema combined with the sensor data defines the "Avro record". This record is transmitted to backend system for further processing and storage.
The usage of Avro schemas allows serialized values to be stored in a very space-efficient binary format (Avro encoded format).
More information about the Avro API can be found here (external page).
The pipeline status flags are set at the sensor level.
Table below displays the possible pipeline flag values:
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|
X | X | X | QA/QC of raw data failed | QA/QC of raw data executed | Raw data processed with errors | Raw data processed and stored | Raw data processed [NO DATA] |
X = bit not in use
Example: The string representation of the following pipeline flags "00001010" indicates that inbound data has been processed, and that data has been going through the quality control pipeline. The numeric value will be 10.
Example: The string representation of the following pipeline flags "00000000" indicates that sensor data has never been processed, neither in the inbound nor in the QC pipeline. The numeric value will be 0.
Example: The string representation of the following pipeline flags "00000010" indicates that inbound data has been processed, but with no quality control. The numeric value will be 2.
Example: The string representation of the following pipeline flags "00010010" indicates that inbound data has been processed, but that the processing of data has failed in the QC pipeline. The numeric value will be 18.
Example: The string representation of the following pipeline flags "00000001" indicates that inbound data has been processed, but with no data (*). The numeric value will be 1.
(*) The "no data" pipeline flag is set if all sensor components in data packet are containing NaN values.
Hint: In order to test whether a specific pipeline flag is set, the bitwise logical AND operator can be used upon the numeric pipeline "flags" value.
All API endpoints use a standard error message format for any requests that return an HTTP status indicating an error (any 400 or 500 statuses). For example, a request entity that omits a required field may generate the following response:
HTTPS/1.1 422 Unprocessable Entity Content-Type: application/json { "error-code": 1000, "error-message": "Sensor name must be defined.", "http-status-code": 422 }
Although it is good practice to check the status code, you may safely parse the
response of the API calls and check for the presence of an
error-code
field to detect errors.
Some error codes are used frequently across the entire API and you will probably want to have general purpose code to handle these, whereas most other error codes will need to be handled on a per-request basis.