A simple API (Application Programming Interface) to send measurements from Thethingsnetwork with a post-Request to a URL, and later retrieve the measurements with a Get-Request.
Measurements made by the sensor may be one of the following types ( type S):
PH, CONDUCTIVITY, TURBIDITY, TEMPERATURE, TEMPERATURE_INSIDE, HUMIDITY, BATTERY, LID, DISSOLVED_OXYGEN
If there is a need to add support for another type of measurement, please contact me (Leik Lima-Eriksen).
To send data from TTN to the API for storage, a post-record is made to
http://vannovervakning.com:5000/api/v1/measurements/<GRUPPENR>
There <GRUPPENR> replaced with the number of your group.
For your part, this means that under Integrations , you should add an integration of the type HTTP Integration with URL as shown above to get this set up correctly.
Data sent from TTN (what is returned in Payload Formats ) must be on the format as shown below.
{
data : [
{
type : "TEMPERATURE" ,
value : 21.3
} ,
{
type : "CONDUCTIVITY" ,
value : 120
}
.
.
.
]
}An example of a very simple payload feature:
function Decoder ( bytes , port ) {
//Definerer de ulike elementene i bufferen
var temp = ( ( bytes [ 0 ] << 8 ) + bytes [ 1 ] ) ;
var turb = bytes [ 2 ] ;
//Returerer verdiene.
return {
data : [
{
type : "TEMPERATURE" ,
value : temp ,
} ,
{
type : "TURBIDITY" ,
value : turb
}
]
} ;
} Also note that the number values you send to the API are also the way they will be stored for later retrieval. That is, if you receive an analog temperature reading of eg 502 , you must convert it to an actual temperature before sending it to the API.
Tip : All the Responses API provides user JSON format (JavaScript Object Notation). Most likely, the programming language you use has support for this. Google eg <PROGRAMMERINGSSPRÅK> json parse for more info mtp your selected <PROGRAMMERINGSSPRÅK> .
To retrieve the latest sensor readings, such Get-Request is sent to the API.
https://vannovervakning.com/api/v1/measurements/<GRUPPENR>
Where <GRUPPENR> as usual is replaced with the number of your group (will not be repeated further).
The response will be the last measurement for each of the sensors for the specified sensor. Example of such a response:
{
"nodeId": 1,
"data": {
"HUMIDITY": [
{
"value": 10,
"timeCreated": "2019-02-06T09:41:55.432Z"
}
],
"BATTERY": [
{
"value": 30,
"timeCreated": "2019-02-06T09:41:55.431Z"
}
]
}
}
To retrieve measurements within a time interval, the URL is used in the following format.
https://vannovervakning.com/api/v1/measurements/<GRUPPENR>/<FROM_TIMESTAMP_MS>/<TO_TIMESTAMP_MS>
Der <FROM_TIMESTAMP_MS> and <TO_TIMESTAMP_MS> is unix hourly tamp in milliseconds.
Tip : This corresponds to the format you get from the JavaScript feature Date.now()
The response will have the same format as for the latest readings, but now the arrays for each of type S will contain more readings. Example of such a response:
{
"nodeId" : 1 ,
"data" : {
"PH" : [
{
"value" : 7.8 ,
"timeCreated" : "2019-03-01T11:55:03.390Z" ,
"position" : { }
} ,
{
"value" : 7.8 ,
"timeCreated" : "2019-03-01T11:55:03.372Z" ,
"position" : { }
}
] ,
"BATTERY" : [
{
"value" : 20 ,
"timeCreated" : "2019-02-22T09:14:20.806Z" ,
"position" : { }
} ,
{
"value" : 15 ,
"timeCreated" : "2019-02-21T22:45:33.735Z" ,
"position" : { }
} ,
]
}
} If you want to retrieve data from a specific time until now <TO_TIMESTAMP_MS> can be loosened. Thus, such a request will have the format as shown below:
https://vannovervakning.com/api/v1/measurements/<GRUPPENR>/<FROM_TIMESTAMP_MS>
It may be worth noting (considering optimization of their website) that it is guaranteed that the order of the sensor reading will come in descending order sorted by hourly tamp. That is, the latest readings come at the top of the array.
The API also supports filtration based on measurement types. Basically, you will get all kinds of measurement types that satisfy <GRUPPENR> and any time limit if it is entered. But if you only want some specific measurements you can add ?types=<TYPE>,<TYPE>,... at the end of the URL. An example of such a Query with group no, time limitation and types delimitation is the following:
https://vannovervakning.com/api/v1/measurements/1/1551434764874?types=PH,CONDUCTIVITY
or with <TO_TIMESTAMP_MS> :
https://vannovervakning.com/api/v1/measurements/1/1551434764874/1551442024867?types=CONDUCTIVITY
As many sensor types can be inserted as desirable for <TYPE> .
One last handy function of the API is the ability to aggregate the measurements that you extract. If a Query is done with ?aggregate=<AGGREGATE> time limit, you can add <AGGREGATE> can be one of the following values:
HIGHEST, LOWEST, AVERAGE
Examples of such requests:
https://vannovervakning.com/api/v1/measurements/1/1551434764874?types=PH,CONDUCTIVITY&aggregate=HIGHEST
https://vannovervakning.com/api/v1/measurements/1/1551434764874/1551442024867?aggregate=LOWEST
https://vannovervakning.com/api/v1/measurements/1/1551434764874?aggregate=AVERAGE
Example of the response such requests provide:
For AVERAGE :
{
"nodeId" : 1 ,
"data" : {
"TURBIDITY" : [
{
"value" : 348.7556962025316
}
] ,
"TEMPERATURE" : [
{
"value" : 23.533417721518983
}
] ,
"PH" : [
{
"value" : 7.778101265822785
}
] ,
"CONDUCTIVITY" : [
{
"value" : 0
}
]
}
} For HIGEST and LOWEST :
{
"nodeId" : 1 ,
"data" : {
"TURBIDITY" : [
{
"value" : 1425 ,
"timeCreated" : "2019-03-01T11:54:38.129Z" ,
"position" : null
}
] ,
"TEMPERATURE" : [
{
"value" : 30.9 ,
"timeCreated" : "2019-03-01T11:50:29.988Z" ,
"position" : null
}
] ,
"PH" : [
{
"value" : 9.4 ,
"timeCreated" : "2019-03-01T11:13:04.545Z" ,
"position" : null
}
] ,
"CONDUCTIVITY" : [
{
"value" : 0 ,
"timeCreated" : "2019-03-01T10:32:48.394Z" ,
"position" : null
}
]
}
}