Skip to content

Ruuvi-InfluxDB Gateway implemented with TypeScript and Node.js.

License

Notifications You must be signed in to change notification settings

iiroki/ruuvi-cloud-gw

Repository files navigation

Ruuvi Cloud Gateway

Unit Tests

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:
  • Various configuration options (see Configuration)

Supported RuuviTag data formats:

Quickstart

Development

  1. Install npm dependencies:

    npm i
  2. Create a JSON configuration file and enter InfluxDB configuration.

  3. Build and start the gateway in development mode (prettier logging):

    npm run dev

Production

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.

  1. Install npm production dependencies:

    npm run build:prod
  2. Start the gateway with PM2:

    pm2 start npm --name 'ruuvi-cloud-gw' -- start
  3. (OPTIONAL) Check that the gateway is running:

    pm2 ls

Data flow

When RuuviTag data is received, it's streamed into all defined outputs.

Time Series Platform

TODO: Documentation

InfluxDB

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 name
    • btGatewayHostPlatform: Operating system platform
    • btPeripheralId: RuuviTag Bluetooth peripheral ID
    • btPeripheralName: RuuviTag Bluetooth peripheral local name
    • id: RuuviTag ID
    • mac: RuuviTag MAC
    • dataFormat: 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.

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
    }
  }
}

About

Ruuvi-InfluxDB Gateway implemented with TypeScript and Node.js.

Topics

Resources

License

Stars

Watchers

Forks

Packages