Quick Start
By following these steps you will setup ConCaVa using the built in JSON adapter. This means the authentication, metadata, and storage will be loaded from JSON files. This tutorial assumes you know how to use Bash on a Unix or Linux environment.
Setup
Install Docker and Docker Compose. Then run the following commands:
mkdir my-concava
cd my-concava
curl https://raw.githubusercontent.com/kukua/concava/master/config.js.example > config.js
chmod 600 config.js
touch output.log docker-compose.yml
mkdir data
touch data/tokens.json data/metadata.json
Copy the following text into the docker-compose.yml
file:
concava:
image: kukuadev/concava
ports:
- "3000:3000"
volumes:
- ./config.js:/data/config.js:ro
- ./output.log:/tmp/output.log
- ./data/:/data/data
With this configuration file we can easily create the container:
docker-compose up -d
That's it! We now have ConCaVa running on port 3000.
Send data
Next, we'll send device data to ConCaVa. For this we need the following:
UDID The unique device ID (16 lowercase hex characters),
for example: 0000000000000001
Auth header The authentication header,
for example: Token abcdef0123456789abcdef0123456789
Payload The measured data, normally in binary,
but for this example as a hex string
We'll use the following sensor specification:
Measurement | Value | Actual data | Converter | Calibrator | Validators |
---|---|---|---|---|---|
Temperature | 23.4 °C | 234 | int16le | return val / 10 | min=-40 max=85 |
Pressure | 1017.9 hPa | 10179 | uint16le | return val / 10 | min=300 max=1100 |
Humidity | 38.7 % | 387 | uint16le | return val / 10 | min=0 max=100 |
Latitude | 52.0842715 | 52.0842715 | floatle | ||
Longitude | 5.0124524 | 5.0124524 | floatle |
For temperature, pressure, and humidity using floats is inefficient (3 x 4 bytes = 12 bytes
). Instead we fix the value to one decimal number and multiply it by 10 and later divide it by 10 again. This allows us to use 16 bit integers (2 bytes per value) or 3 x 2 = 6 bytes
in total. This cuts our number of bytes in half!
In this tutorial we also send the device's GPS coordinates.a latitude and longitude.
It is common to use the Little Endian byte order when sending data from devices. This means the little end (byte with smallest part of value) comes first.
Translating these values to a hexadecimal payload looks like this:
Temperature 0xea00
Pressure 0xc327
Humidity 0x8301
Latitude 0x4b565042
Longitude 0x0366a040
Final payload 0xea00c32783014b5650420366a040
Send this to ConCaVa by running:
echo 'ea00c32783014b5650420366a040' | xxd -r -p | \
curl -i -XPUT 'http://localhost:3000/v1/sensorData/0000000000000001' \
-H 'Authorization: Token abcdef0123456789abcdef0123456789' \
-H 'Content-Type: application/octet-stream' --data-binary @-
The response will look like this:
HTTP/1.1 401 Unauthorized
Allow: HEAD, POST, PUT
Accept: application/octet-stream
WWW-Authenticate: Token
Date: Mon, 11 Jul 2016 13:30:16 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Unauthorized token.
Success! Sort of. We need to configure ConCaVa to be able to handle the request.
Add tokens
Now we add our token to data/tokens.json
:
{
"abcdef0123456789abcdef0123456789": {
"id": 1,
"name": "User 1"
}
}
Here you see the unique authentication token as the key and the user data object as the value. Run the curl
request again, the response will look like this:
HTTP/1.1 400 Bad Request
Allow: HEAD, POST, PUT
Accept: application/octet-stream
Date: Mon, 11 Jul 2016 13:34:40 GMT
Connection: keep-alive
Transfer-Encoding: chunked
No metadata for 0000000000000001.
Again, success! But no data yet. We need to add the metadata for this specific device.
Add metadata
Add this metadata to data/metadata.json
:
{
"0000000000000001": [
{
"name": "temperature",
"converters": ["int16le"],
"calibrators": ["return val / 10"],
"validators": [
["min", -40],
["max", 85]
]
},
{
"name": "pressure",
"converters": ["uint16le"],
"calibrators": ["return val / 10"],
"validators": [
["min", 300],
["max", 1100]
]
},
{
"name": "humidity",
"converters": ["uint16le"],
"calibrators": ["return val / 10"],
"validators": [
["min", 0],
["max", 100]
]
},
{
"name": "lat",
"converters": ["floatle"],
"calibrators": [],
"validators": []
},
{
"name": "lng",
"converters": ["floatle"],
"calibrators": [],
"validators": []
}
]
}
This is the JSON adapter format for the metadata in the table you saw earlier. Compare them to see that we used the exact same configuration.
Third time's the charm: run the curl
request again. The response should be:
HTTP/1.1 200 OK
Allow: HEAD, POST, PUT
Accept: application/octet-stream
Date: Mon, 11 Jul 2016 13:49:03 GMT
Connection: keep-alive
Content-Length: 0
Success! But how do we view the data?
Stored measurements
Open data/store.0000000000000001.json
to show the data, which looks like this:
{
"b6a84c4e-8014-4681-b78b-89a7c1c97a86": {
"_raw": "ea00c32783014b5650420366a040",
"temperature": 23.4,
"pressure": 1017.9,
"humidity": 38.7,
"lat": 52.08427047729492,
"lng": 5.012452602386475,
"timestamp": 1468244943
}
}
Tip
Use jq for displaying JSON data.