-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Gudsfile <gudsfile@protonmail.com>
- Loading branch information
1 parent
b4e624c
commit ca9e723
Showing
8 changed files
with
114 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
APPLE_WATCH_INFLUX_DATABASE="apple_watch" | ||
APPLE_WATCH_INFLUX_BUCKET="apple_watch" | ||
APPLE_WATCH_INFLUX_ORG="my_org" | ||
APPLE_WATCH_INFLUX_USERNAME="my_user" | ||
APPLE_WATCH_INFLUX_PASSWORD="my_password" | ||
APPLE_WATCH_INFLUX_TOKEN="my_token" | ||
APPLE_WATCH_INFLUX_MEASUREMENT="workouts" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,98 @@ | ||
const Influx = require('influx') | ||
const { InfluxDB, Point } = require('@influxdata/influxdb-client') | ||
const { SetupAPI } = require('@influxdata/influxdb-client-apis') | ||
const { hostname } = require('node:os') | ||
const { Writable } = require('node:stream') | ||
|
||
let influx | ||
let influxWriteApi | ||
;(async () => { | ||
influxWriteApi = await loadInfluxInstance() | ||
})() | ||
|
||
const stream = new Writable({ | ||
async write(chunk, encoding, callback) { | ||
try { | ||
await loadInfluxInstance() | ||
|
||
const currentWorkout = JSON.parse(chunk.toString()) | ||
|
||
const influxPoints = [currentWorkout].map((workout) => ({ | ||
measurement: process.env.APPLE_WATCH_INFLUX_MEASUREMENT, | ||
tags: { type: workout.type, date: workout.startDate.substring(0, 10) }, | ||
fields: { | ||
duration: workout.duration, | ||
totalDistance: workout.totalDistance, | ||
totalEnergyBurned: workout.totalEnergyBurned, | ||
sourceName: workout.sourceName, | ||
sourceVersion: workout.sourceVersion, | ||
}, | ||
timestamp: new Date(workout.startDate), | ||
})) | ||
const influxPoints = [currentWorkout].map((workout) => | ||
new Point(process.env.APPLE_WATCH_INFLUX_MEASUREMENT) | ||
.tag('type', workout.type) | ||
.tag('date', workout.startDate.substring(0, 10)) | ||
.tag('sourceName', workout.sourceName) | ||
.tag('sourceVersion', workout.sourceVersion) | ||
.floatField('duration', workout.duration) | ||
.floatField('totalDistance', workout.totalDistance) | ||
.floatField('totalEnergyBurned', workout.totalEnergyBurned) | ||
.timestamp(new Date(workout.startDate)) | ||
) | ||
|
||
await influx.writePoints(influxPoints) | ||
influxWriteApi.writePoints(influxPoints) | ||
} catch (error) { | ||
console.error(error) | ||
console.log(`InfluxDB writing error: ${error.message}`) | ||
} | ||
|
||
callback() | ||
}, | ||
}) | ||
|
||
stream.on('close', () => { | ||
closeInfluxInstance(influxWriteApi) | ||
}) | ||
|
||
module.exports = () => { | ||
return stream | ||
} | ||
|
||
const loadInfluxInstance = async () => { | ||
if (influx !== undefined) { | ||
return | ||
} | ||
async function loadInfluxInstance() { | ||
const url = 'http://localhost:8086' | ||
const org = process.env.APPLE_WATCH_INFLUX_ORG | ||
const bucket = process.env.APPLE_WATCH_INFLUX_BUCKET | ||
const token = process.env.APPLE_WATCH_INFLUX_TOKEN | ||
const username = process.env.APPLE_WATCH_INFLUX_USERNAME | ||
const password = process.env.APPLE_WATCH_INFLUX_PASSWORD | ||
|
||
const influxInstance = new Influx.InfluxDB({ | ||
host: 'localhost', | ||
database: process.env.APPLE_WATCH_INFLUX_DATABASE, | ||
schema: [ | ||
{ | ||
measurement: process.env.APPLE_WATCH_INFLUX_MEASUREMENT, | ||
tags: ['type', 'date'], | ||
fields: { | ||
duration: Influx.FieldType.FLOAT, | ||
totalDistance: Influx.FieldType.FLOAT, | ||
totalEnergyBurned: Influx.FieldType.FLOAT, | ||
sourceName: Influx.FieldType.STRING, | ||
sourceVersion: Influx.FieldType.STRING, | ||
}, | ||
}, | ||
], | ||
}) | ||
const influx = new InfluxDB({ url, token }) | ||
const setupApi = new SetupAPI(influx) | ||
|
||
const databasesNames = await influxInstance.getDatabaseNames() | ||
if (!databasesNames.includes(process.env.APPLE_WATCH_INFLUX_DATABASE)) { | ||
await influxInstance.createDatabase(process.env.APPLE_WATCH_INFLUX_DATABASE) | ||
try { | ||
const { allowed } = await setupApi.getSetup() | ||
if (allowed) { | ||
await setupApi.postSetup({ | ||
body: { | ||
org, | ||
bucket, | ||
username, | ||
password, | ||
token, | ||
}, | ||
}) | ||
console.log(`InfluxDB '${url}' is now onboarded.`) | ||
} else { | ||
console.debug(`InfluxDB '${url}' is ready.`) | ||
} | ||
} catch (error) { | ||
console.error(error) | ||
console.log('\nInfluxDB setup ERROR') | ||
} | ||
|
||
influx = influxInstance | ||
const influxWriteApi = influx.getWriteApi(org, bucket, 's') | ||
influxWriteApi.useDefaultTags({ location: hostname() }) | ||
|
||
return influxWriteApi | ||
} | ||
|
||
async function closeInfluxInstance(influxWriteApi) { | ||
// WriteApi always buffer data into batches to optimize data transfer to InfluxDB server. | ||
// writeApi.flush() can be called to flush the buffered data. The data is always written | ||
// asynchronously, Moreover, a failed write (caused by a temporary networking or server failure) | ||
// is retried automatically. | ||
// | ||
// close() flushes the remaining buffered data and then cancels pending retries. | ||
|
||
try { | ||
await influxWriteApi.close() | ||
console.debug('InfluxDB connection closed successfully.') | ||
} catch (error) { | ||
console.error(error) | ||
console.log('\nInfluxDB connection closing ERROR') | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters