Skip to content

Exporters

BLE Scale Sync exports body composition data to 5 targets. The setup wizard walks you through exporter selection, configuration, and connectivity testing.

Exporters are configured in global_exporters (shared by all users). For multi-user setups with separate accounts, see Per-User Exporters. All enabled exporters run in parallel — the process reports an error only if every exporter fails.

TargetDescription
Garmin ConnectAutomatic body composition upload — no phone app needed
MQTTHome Assistant auto-discovery with 10 sensors, LWT
InfluxDBTime-series database (v2 write API)
WebhookAny HTTP endpoint — n8n, Make, Zapier, custom APIs
NtfyPush notifications to phone/desktop

Garmin Connect

Automatic body composition upload to Garmin Connect — no phone app needed. Uses a Python subprocess with cached authentication tokens.

FieldRequiredDefaultDescription
emailYesGarmin account email
passwordYesGarmin account password
token_dirNo~/.garmin_tokensDirectory for cached auth tokens
yaml
global_exporters:
  - type: garmin
    email: '${GARMIN_EMAIL}'
    password: '${GARMIN_PASSWORD}'

Authentication

The setup wizard handles Garmin authentication automatically. You only need to authenticate once — tokens are cached in ~/.garmin_tokens/ and reused. To re-authenticate manually:

bash
# Docker
docker run --rm -it -v ./config.yaml:/app/config.yaml \
  ghcr.io/kristianp26/ble-scale-sync:latest setup-garmin

# Native
npm run setup-garmin

IP blocking

Garmin may block requests from cloud/VPN IPs. If authentication fails, try from a different network, then copy ~/.garmin_tokens/ to your target machine.

MQTT

Publishes body composition as JSON to an MQTT broker. Home Assistant auto-discovery is enabled by default — all 10 metrics appear as sensors grouped under a single device, with availability tracking (LWT) and display precision per metric.

FieldRequiredDefaultDescription
broker_urlYesmqtt://host:1883 or mqtts:// for TLS
topicNoscale/body-compositionPublish topic
qosNo1QoS level (0, 1, or 2)
retainNotrueRetain last message
usernameNoBroker auth username
passwordNoBroker auth password
client_idNoble-scale-syncMQTT client identifier
ha_discoveryNotrueHome Assistant auto-discovery
ha_device_nameNoBLE ScaleDevice name in Home Assistant
yaml
global_exporters:
  - type: mqtt
    broker_url: 'mqtts://broker.example.com:8883'
    username: myuser
    password: '${MQTT_PASSWORD}'

Webhook

Sends body composition as JSON to any HTTP endpoint. Works with n8n, Make, Zapier, or custom APIs.

FieldRequiredDefaultDescription
urlYesTarget URL
methodNoPOSTHTTP method
headersNoCustom headers (YAML object)
timeoutNo10000Request timeout in ms
yaml
global_exporters:
  - type: webhook
    url: 'https://example.com/hook'
    headers:
      X-Api-Key: '${WEBHOOK_API_KEY}'

InfluxDB

Writes metrics to InfluxDB v2 using line protocol. Float fields use 2 decimal places, integer fields use i suffix.

FieldRequiredDefaultDescription
urlYesInfluxDB server URL
tokenYesAPI token with write access
orgYesOrganization name
bucketYesDestination bucket
measurementNobody_compositionMeasurement name
yaml
global_exporters:
  - type: influxdb
    url: 'http://localhost:8086'
    token: '${INFLUXDB_TOKEN}'
    org: my-org
    bucket: my-bucket

Ntfy

Push notifications to phone/desktop via ntfy. Works with ntfy.sh or self-hosted instances.

FieldRequiredDefaultDescription
urlNohttps://ntfy.shNtfy server URL
topicYesTopic name
titleNoScale MeasurementNotification title
priorityNo3Priority (1–5)
tokenNoBearer token auth
usernameNoBasic auth username
passwordNoBasic auth password
yaml
global_exporters:
  - type: ntfy
    topic: my-scale
    priority: 4

Secrets

Use ${ENV_VAR} references in YAML for passwords and tokens. The variable must be defined in the environment or in a .env file:

yaml
global_exporters:
  - type: garmin
    email: '${GARMIN_EMAIL}'
    password: '${GARMIN_PASSWORD}'

See Configuration — Environment Variables for details.

Healthchecks

At startup, exporters are tested for connectivity. Failures are logged as warnings but don't block the scan.

ExporterMethod
MQTTConnect + disconnect
WebhookHEAD request
InfluxDB/health endpoint
Ntfy/v1/health endpoint
GarminNone (Python subprocess)

Released under the GPL-3.0 License.