Ruuvi Cloud Gateway is a simple gateway implemented with TypeScript and Node.js that collects data from RuuviTags and send them to various cloud outputs.
Features:
- Collect data from RuuviTags
- Transform RuuviTag data to cloud-compatible formats
- Send data to cloud:
- Time Series Platform (my personal time series storage)
- InfluxDB
- Various configuration options (see Configuration)
Supported RuuviTag data formats:
-
Install npm dependencies:
npm i
-
Create a JSON configuration file and enter InfluxDB configuration.
- See Configuration for more information.
-
Build and start the gateway in development mode (prettier logging):
npm run dev
In "production", PM2 is can be used to run the gateway as a daemon. The configuration is handled the same way as in development mode.
-
Install npm production dependencies:
npm run build:prod
-
Start the gateway with PM2:
pm2 start npm --name 'ruuvi-cloud-gw' -- start
-
(OPTIONAL) Check that the gateway is running:
pm2 ls
When RuuviTag data is received, it's streamed into all defined outputs.
TODO: Documentation
When the gateway receives data from RuuviTags, it transforms the data to InfluxDB data points using the following rules (RuuviInfluxTransform):
- Tags:
- Default tags from the configuration
btGatewayHost
: Operating system host namebtGatewayHostPlatform
: Operating system platformbtPeripheralId
: RuuviTag Bluetooth peripheral IDbtPeripheralName
: RuuviTag Bluetooth peripheral local nameid
: RuuviTag IDmac
: RuuviTag MACdataFormat
: RuuviTag data format
- Fields: All the other values included in RuuviTag advertisement broadcasts.
- Timestamp: Timestamp when
RuuviTagListener
received the data - Measurement: Measurement name from the configuration.
By default, configuration is read from config.json
in the root directory.
Env:
CONFIG_PATH
: Override default path to the configuration file.LOG_LEVEL
: Pino log level, default =info
.
Configuration:
Key | Description | Type | Required |
---|---|---|---|
ruuvi |
Ruuvi/Bluetooth configuration | RuuviConfig |
- |
outputs |
Output configuration | { "tsp": TspConfig, "influx": InfluxConfig } |
- |
RuuviConfig
:
Key | Description | Type | Required |
---|---|---|---|
scanMode |
Whether to start the bluetooth service in scan-only mode | boolean |
- |
serviceUuids |
Bluetooth service UUIDs to scan for | string[] |
- |
filters |
Filter which RuuviTags data should be collected from | RuuviTagIdentifier[] |
- |
logMissedSequences |
Generate warning logs from the missed RuuviTag sequences | boolean |
- |
RuuviTagIdentifier
:
Key | Description | Type | Required |
---|---|---|---|
type |
Type of the identifying property | id or name |
✓ |
value |
Identifier value | string |
✓ |
TspConfig
:
Key | Description | Type | Required |
---|---|---|---|
url |
URL | string |
✓ |
apiKey |
API key | string |
✓ |
apiKey |
API key header | string |
- |
intervalMs |
Interval between sending batches | number |
- |
bindings |
Ruuvi -> TSP bindings | TspRuuviBindingConfig |
✓ |
TspRuuviBindingConfig
:
Key | Description | Type | Required |
---|---|---|---|
tags |
Collected tags/measurements | TspRuuviBindingTagConfig[] |
✓ |
locations |
Locations associated with RuuviTags | TspRuuviBindingLocationConfig[] |
- |
TspRuuviBindingTagConfig
:
Key | Description | Type | Required |
---|---|---|---|
in |
RuuviTag input field name associated with the output tag | string |
✓ |
out |
TSP tag slug | string |
✓ |
TspRuuviBindingLocationConfig
:
Key | Description | Type | Required |
---|---|---|---|
in |
RuuviTag associated with the output location | RuuviTagIdentifier |
✓ |
out |
TSP location slug | string |
✓ |
InfluxConfig
:
Key | Description | Type | Required |
---|---|---|---|
url |
Database URL | string |
✓ |
token |
API token | string |
✓ |
bucket |
Bucket | string |
✓ |
org |
Organization | string |
✓ |
measurement |
Measurement | string |
✓ |
defaultTags |
Tags to be included with every data point | Record<string, string> |
✗ |
batchSize |
Max number of data points in a batch | number |
✗ |
flushIntervalMs |
Interval between forceful data flushes (ms) | number |
✗ |
gzipThreshold |
Batches larger than the value will be gzipped | number |
✗ |
Example config:
{
"ruuvi": {
"serviceUuids": ["fe9a"],
"scanMode": false,
"filters": [
{ "type": "name", "value": "Ruuvi Foo" },
{ "type": "name", "value": "Ruuvi Bar" }
]
},
"outputs": {
"tsp": {
"url": "$TSP_URL",
"apiKey": "$TSP_API_KEY",
"bindings": {
"tags": [
{ "in": "temperatureC", "out": "temperature" },
{ "in": "humidityRh", "out": "humidity" }
],
"locations": [
{
"in": { "type": "name", "value": "Ruuvi Foo" },
"out": "home-living-room"
},
{
"in": { "type": "name", "value": "Ruuvi Bar" },
"out": "home-bedroom"
}
]
}
},
"influx": {
"url": "$INFLUX_URL",
"token": "$INFLUX_TOKEN",
"bucket": "influx-bucket",
"org": "influx-org",
"measurement": "ruuvi",
"defaultTags": {
"customTag": "customValue"
},
"batchSize": 10,
"flushIntervalMs": 1000,
"gzipThreshold": 1024
}
}
}