adds support for ant+ heart rate monitors
This commit is contained in:
parent
15c1553e42
commit
d385ad78d7
|
|
@ -24,7 +24,7 @@ Open Rowing Monitor implements a physics model to simulate the typical metrics o
|
|||
* Strokes per Minute
|
||||
* Calories used (kcal)
|
||||
* Training Duration
|
||||
* Heart Rate (requires a BLE Heart Rate Monitor)
|
||||
* Heart Rate (supports BLE and ANT+ heart rate monitors, ANT+ requires an ANT+ USB stick)
|
||||
|
||||
### Web Interface
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
'use strict'
|
||||
/*
|
||||
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
|
||||
|
||||
This manager creates a module to listen to ANT+ devices.
|
||||
This currently can be used to get the heart rate from ANT+ heart rate sensors.
|
||||
|
||||
Requires an ANT+ USB stick, the following models might work:
|
||||
- Garmin USB or USB2 ANT+ or an off-brand clone of it (ID 0x1008)
|
||||
- Garmin mini ANT+ (ID 0x1009)
|
||||
*/
|
||||
import log from 'loglevel'
|
||||
import Ant from 'ant-plus'
|
||||
import EventEmitter from 'node:events'
|
||||
|
||||
function createAntManager () {
|
||||
const emitter = new EventEmitter()
|
||||
const antStick = new Ant.GarminStick2()
|
||||
const antStick3 = new Ant.GarminStick3()
|
||||
const heartrateSensor = new Ant.HeartRateSensor(antStick)
|
||||
|
||||
heartrateSensor.on('hbData', (data) => {
|
||||
emitter.emit('heartrateMeasurement', { heartrate: data.ComputedHeartRate, batteryLevel: data.BatteryLevel })
|
||||
})
|
||||
|
||||
heartrateSensor.on('attached', () => {
|
||||
log.info('heart rate sensor attached')
|
||||
})
|
||||
|
||||
heartrateSensor.on('detached', () => {
|
||||
log.info('heart rate sensor detached')
|
||||
})
|
||||
|
||||
antStick.on('startup', () => {
|
||||
log.info('classic ANT+ stick found')
|
||||
heartrateSensor.attach(0, 0)
|
||||
})
|
||||
|
||||
antStick3.on('startup', () => {
|
||||
log.info('mini ANT+ stick found')
|
||||
heartrateSensor.attach(0, 0)
|
||||
})
|
||||
|
||||
antStick.on('shutdown', () => {
|
||||
log.info('classic ANT+ stick lost')
|
||||
})
|
||||
|
||||
antStick3.on('shutdown', () => {
|
||||
log.info('mini ANT+ stick lost')
|
||||
})
|
||||
|
||||
if (!antStick.open()) {
|
||||
log.debug('classic ANT+ stick not found')
|
||||
}
|
||||
|
||||
if (!antStick3.open()) {
|
||||
log.debug('mini ANT+ stick not found')
|
||||
}
|
||||
|
||||
return Object.assign(emitter, {
|
||||
})
|
||||
}
|
||||
|
||||
export { createAntManager }
|
||||
|
|
@ -15,6 +15,7 @@ import { createRowingEngine } from './engine/RowingEngine.js'
|
|||
import { createRowingStatistics } from './engine/RowingStatistics.js'
|
||||
import { createWebServer } from './WebServer.js'
|
||||
import { createPeripheralManager } from './ble/PeripheralManager.js'
|
||||
import { createAntManager } from './ant/AntManager.js'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { replayRowingSession } from './tools/RowingRecorder.js'
|
||||
|
||||
|
|
@ -87,10 +88,19 @@ rowingStatistics.on('metricsUpdate', (metrics) => {
|
|||
peripheralManager.notifyMetrics('metricsUpdate', metrics)
|
||||
})
|
||||
|
||||
const bleCentralService = fork('./app/ble/CentralService.js')
|
||||
bleCentralService.on('message', (heartrateMeasurement) => {
|
||||
rowingStatistics.handleHeartrateMeasurement(heartrateMeasurement)
|
||||
})
|
||||
if (config.heartrateMonitorBLE) {
|
||||
const bleCentralService = fork('./app/ble/CentralService.js')
|
||||
bleCentralService.on('message', (heartrateMeasurement) => {
|
||||
rowingStatistics.handleHeartrateMeasurement(heartrateMeasurement)
|
||||
})
|
||||
}
|
||||
|
||||
if (config.heartrateMonitorANT) {
|
||||
const antManager = createAntManager()
|
||||
antManager.on('heartrateMeasurement', (heartrateMeasurement) => {
|
||||
rowingStatistics.handleHeartrateMeasurement(heartrateMeasurement)
|
||||
})
|
||||
}
|
||||
|
||||
const webServer = createWebServer()
|
||||
webServer.on('messageReceived', (message) => {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@ export default {
|
|||
// supported modes: FTMS, FTMSBIKE, PM5
|
||||
bluetoothMode: 'FTMS',
|
||||
|
||||
// turn this on if you want support for Bluetooth Low Energy heart rate monitors
|
||||
// will currenty the hear rate and battery level of the first device found
|
||||
heartrateMonitorBLE: true,
|
||||
|
||||
// turn this on if you want support for ANT+ heart rate monitors
|
||||
// you will need an ANT+ USB stick for this to work, the following models might work:
|
||||
// - Garmin USB or USB2 ANT+ or an off-brand clone of it (ID 0x1008)
|
||||
// - Garmin mini ANT+ (ID 0x1009)
|
||||
heartrateMonitorANT: false,
|
||||
|
||||
// defines the name that is used to announce the FTMS Rower via Bluetooth Low Energy (BLE)
|
||||
// some rowing training applications expect that the rowing device is announced with a certain name
|
||||
ftmsRowerPeripheralName: 'OpenRowingMonitor',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ This is the very minimalistic Backlog for further development of this project.
|
|||
|
||||
## Soon
|
||||
|
||||
* add support for ANT+ heart rate monitors with USB dongles
|
||||
* add an option to the installation script to directly attach a touchscreen to the Raspberry Pi and automatically show WebUI on this in kiosk mode
|
||||
* validate FTMS with more training applications and harden implementation (i.e. Holofit and Coxswain)
|
||||
* record a longer rowing session and analyze two encountered problems: 1) rarely the stroke rate doubles for a short duration (might be a problem with stroke detection when measurements are imprecise), 2) in one occasion the measured power jumped to a very high value after a break (40000 watts)
|
||||
|
|
|
|||
|
|
@ -35,12 +35,27 @@ Open Rowing Monitor does not provide proper releases (yet), but you can update t
|
|||
sudo /opt/openrowingmonitor/install/update.sh
|
||||
```
|
||||
|
||||
### If you want to run Bluetooth Low Energy and the Web-Server on port 80 without root
|
||||
### Running Open Rowing Monitor without root permissions
|
||||
|
||||
The default installation will run Open Rowing Monitor with root permissions. If you want you can also run it as user by modifying the following system services:
|
||||
|
||||
#### To use BLE and open the Web-Server on port 80
|
||||
|
||||
Issue the following command:
|
||||
|
||||
```zsh
|
||||
sudo setcap cap_net_bind_service,cap_net_raw=+eip $(eval readlink -f `which node`)
|
||||
```
|
||||
|
||||
#### To access ANT+ USB sticks
|
||||
|
||||
Create a file `/etc/udev/rules.d/51-garmin-usb.rules` with the following content:
|
||||
|
||||
```zsh
|
||||
ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1008", MODE="0666"
|
||||
ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1009", MODE="0666"
|
||||
```
|
||||
|
||||
## Hardware Installation
|
||||
|
||||
Basically all that's left to do is hook up your sensor to the GPIO pins of the Raspberry Pi and configure the rowing machine specific parameters of the software.
|
||||
|
|
@ -68,4 +83,4 @@ If your machine does not have something like this or if the sensor is not access
|
|||
* PAS sensor (i.e. from an E-bike)
|
||||
* Optical chopper wheel
|
||||
|
||||
You should now adjust the rower specific parameters in `config/config.js` to suit your rowing machine.
|
||||
You should now adjust the rower specific parameters in `config/config.js` to suit your rowing machine. Have a look at [config/default.config.js](../config/default.config.js) to see what config parameters are available.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "openrowingmonitor",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -130,9 +130,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@npmcli/git": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.7.tgz",
|
||||
"integrity": "sha512-HUSqNDWYsTpboc7yV1C4yPd/jbaGXfWVmGoTyB+h3QQSKMpYPzTXLrqUMpz+LEA6Dt9usUeRtjytwcrfoBMJpg==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.8.tgz",
|
||||
"integrity": "sha512-LPnzyBZ+1p7+JzHVwwKycMF8M3lr1ze3wxGRnxn/QxJtk++Y3prSJQrdBDGCxJyRpFsup6J3lrRBVYBhJVrM8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@npmcli/promise-spawn": "^1.3.2",
|
||||
|
|
@ -215,9 +215,9 @@
|
|||
}
|
||||
},
|
||||
"@npmcli/run-script": {
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.4.tgz",
|
||||
"integrity": "sha512-Yd9HXTtF1JGDXZw0+SOn+mWLYS0e7bHBHVC/2C8yqs4wUrs/k8rwBSinD7rfk+3WG/MFGRZKxjyoD34Pch2E/A==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.5.tgz",
|
||||
"integrity": "sha512-NQspusBCpTjNwNRFMtz2C5MxoxyzlbuJ4YEhxAKrIonTiirKDtatsZictx9RgamQIx6+QuHMNmPl0wQdoESs9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@npmcli/node-gyp": "^1.0.2",
|
||||
|
|
@ -317,6 +317,14 @@
|
|||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"ant-plus": {
|
||||
"version": "0.1.24",
|
||||
"resolved": "https://registry.npmjs.org/ant-plus/-/ant-plus-0.1.24.tgz",
|
||||
"integrity": "sha512-otEIAN+9jtu/1mwHL81au0sO7muJT1QrWOm9j29NEg3x1Y+ZsSIYX+LSdY+BBr2mLA4hT/vpqv5pWX9KDWceVg==",
|
||||
"requires": {
|
||||
"usb": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
|
|
@ -406,8 +414,7 @@
|
|||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"optional": true
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
|
|
@ -434,7 +441,6 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
|
|
@ -445,7 +451,6 @@
|
|||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
|
|
@ -476,7 +481,6 @@
|
|||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
|
|
@ -606,9 +610,9 @@
|
|||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
|
|
@ -659,8 +663,7 @@
|
|||
"chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
||||
},
|
||||
"clean-stack": {
|
||||
"version": "2.2.0",
|
||||
|
|
@ -760,7 +763,6 @@
|
|||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"mimic-response": "^2.0.0"
|
||||
}
|
||||
|
|
@ -836,8 +838,7 @@
|
|||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"optional": true
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"diff": {
|
||||
"version": "5.0.0",
|
||||
|
|
@ -905,7 +906,6 @@
|
|||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
|
|
@ -1348,8 +1348,7 @@
|
|||
"expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
|
|
@ -1491,8 +1490,7 @@
|
|||
"fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"optional": true
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.7",
|
||||
|
|
@ -1570,8 +1568,7 @@
|
|||
"github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
|
||||
"optional": true
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
|
|
@ -1750,8 +1747,7 @@
|
|||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"optional": true
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
|
|
@ -2259,9 +2255,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
|
||||
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^2.0.1"
|
||||
|
|
@ -2308,8 +2304,7 @@
|
|||
"mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||
"optional": true
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
||||
},
|
||||
"mini-debounce": {
|
||||
"version": "1.0.8",
|
||||
|
|
@ -2531,8 +2526,7 @@
|
|||
"mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"optional": true
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
||||
},
|
||||
"mri": {
|
||||
"version": "1.1.6",
|
||||
|
|
@ -2553,8 +2547,7 @@
|
|||
"napi-build-utils": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
|
||||
},
|
||||
"napi-thread-safe-callback": {
|
||||
"version": "0.0.6",
|
||||
|
|
@ -2596,10 +2589,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.21.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.21.0.tgz",
|
||||
"integrity": "sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg==",
|
||||
"optional": true,
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.26.0.tgz",
|
||||
"integrity": "sha512-ag/Vos/mXXpWLLAYWsAoQdgS+gW7IwvgMLOgqopm/DbzAjazLltzgzpVMsFlgmo9TzG5hGXeaBZx2AI731RIsQ==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
|
|
@ -2737,8 +2729,7 @@
|
|||
"noop-logger": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
|
||||
"optional": true
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.3",
|
||||
|
|
@ -2768,9 +2759,9 @@
|
|||
"integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA=="
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
|
||||
"integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
|
||||
"integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
|
||||
"requires": {
|
||||
"npm-normalize-package-bin": "^1.0.1"
|
||||
}
|
||||
|
|
@ -3056,9 +3047,9 @@
|
|||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
|
||||
"integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz",
|
||||
"integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==",
|
||||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
|
|
@ -3395,7 +3386,6 @@
|
|||
"version": "5.3.6",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz",
|
||||
"integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
|
|
@ -3456,7 +3446,6 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
|
|
@ -3743,14 +3732,12 @@
|
|||
"simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"optional": true
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
|
|
@ -3807,9 +3794,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"snowpack": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/snowpack/-/snowpack-3.3.0.tgz",
|
||||
"integrity": "sha512-LXoWtVQ9SGD7XhkFS9ixOoGO4eofJW/yj8gUYBopYhYIcOSeuokzJWkW0gF5M6pM7Vw9TMO8gK9KSfc2wAwTDw==",
|
||||
"version": "3.3.5",
|
||||
"resolved": "https://registry.npmjs.org/snowpack/-/snowpack-3.3.5.tgz",
|
||||
"integrity": "sha512-QI6/PcSud39ZAmrs7IiBSCr3PWXxc4/w2SNJp32+n7XsXxSB4waJ+jpG5rtJAeif5pqRNkX4887PKwWsMzFRCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cli-spinners": "^2.5.0",
|
||||
|
|
@ -3825,9 +3812,9 @@
|
|||
}
|
||||
},
|
||||
"socks": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.0.tgz",
|
||||
"integrity": "sha512-mNmr9owlinMplev0Wd7UHFlqI4ofnBnNzFuzrm63PPaHgbkqCFe4T5LzwKmtQ/f2tX0NTpcdVLyD/FHxFBstYw==",
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
|
||||
"integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ip": "^1.1.5",
|
||||
|
|
@ -4008,9 +3995,9 @@
|
|||
}
|
||||
},
|
||||
"table": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-6.1.0.tgz",
|
||||
"integrity": "sha512-T4G5KMmqIk6X87gLKWyU5exPpTjLjY5KyrFWaIjv3SvgaIUGXV7UEzGEnZJdTA38/yUS6f9PlKezQ0bYXG3iIQ==",
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-6.3.2.tgz",
|
||||
"integrity": "sha512-I9/Ca6Huf2oxFag7crD0DhA+arIdfLtWunSn0NIXSzjtUlDgIBGVZY7SsMkNPNT3Psd/z4gza0nuEpmra9eRbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^8.0.1",
|
||||
|
|
@ -4095,7 +4082,6 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
|
|
@ -4107,7 +4093,6 @@
|
|||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
|
|
@ -4120,7 +4105,6 @@
|
|||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
|
|
@ -4263,7 +4247,6 @@
|
|||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/usb/-/usb-1.7.0.tgz",
|
||||
"integrity": "sha512-LHm9d389NCzZSMd0DnilxT5Lord4P2E3ETwP1LeuJcEBmI5uLJv8Sd18z/9bairUMbDnnNqX+Hi5Xkl93Kvdmw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bindings": "^1.4.0",
|
||||
"node-addon-api": "3.0.2",
|
||||
|
|
@ -4273,8 +4256,7 @@
|
|||
"node-addon-api": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.2.tgz",
|
||||
"integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg==",
|
||||
"optional": true
|
||||
"integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -4374,8 +4356,7 @@
|
|||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
|
||||
"optional": true
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
|
|
@ -4397,9 +4378,9 @@
|
|||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
|
||||
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
|
||||
"version": "7.4.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
|
||||
"integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
|
||||
},
|
||||
"xpc-connect": {
|
||||
"version": "2.0.0",
|
||||
|
|
|
|||
|
|
@ -26,13 +26,14 @@
|
|||
"dependencies": {
|
||||
"@abandonware/bleno": "^0.5.1-4",
|
||||
"@abandonware/noble": "^1.9.2-13",
|
||||
"ant-plus": "^0.1.24",
|
||||
"finalhandler": "^1.1.2",
|
||||
"http": "0.0.1-security",
|
||||
"loglevel": "^1.7.1",
|
||||
"nosleep.js": "^0.12.0",
|
||||
"onoff": "^6.0.2",
|
||||
"serve-static": "^1.14.1",
|
||||
"ws": "^7.4.4"
|
||||
"ws": "^7.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.24.0",
|
||||
|
|
@ -43,7 +44,7 @@
|
|||
"husky": "^6.0.0",
|
||||
"markdownlint-cli": "^0.27.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"snowpack": "^3.3.0",
|
||||
"snowpack": "^3.3.5",
|
||||
"uvu": "^0.5.1",
|
||||
"uvu-watch": "^1.0.11"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue