Skip to content

Instantly share code, notes, and snippets.

@ynakajima
Last active November 14, 2021 11:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ynakajima/06822682535defbf3f63d676d742ddbb to your computer and use it in GitHub Desktop.
Save ynakajima/06822682535defbf3f63d676d742ddbb to your computer and use it in GitHub Desktop.
3000円の Bluetooth 対応体重計を Raspberry Pi を使って Google Fit に対応させてみた
# Created by https://www.gitignore.io/api/osx,node,visualstudiocode
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
### OSX ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# End of https://www.gitignore.io/api/osx,node,visualstudiocode
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後サービス(0xfff0)を探査
peripheral.once('connect', () => {
peripheral.discoverServices(['fff0'])
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの特性を探査
function onServiceDiscover (services) {
services
.forEach((service) => {
console.log('Discover Service: Device Information\n')
service.once('characteristicsDiscover', onCharacteristicsDiscover)
service.discoverCharacteristics()
})
}
// 探査された特性の内容を出力
function onCharacteristicsDiscover (characteristics) {
console.log('Discover Characteristics:\n')
characteristics
.forEach(characteristic => {
// 不要なデータを削除
delete characteristic._noble
delete characteristic._peripheralId
delete characteristic._serviceUuid
console.dir(characteristic)
console.log()
})
}
// discover-characteristic.js
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後サービスを探査
peripheral.once('connect', () => {
peripheral.discoverServices()
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの中から
// Device Infomation サービスを見つけて
// その特性を探査
function onServiceDiscover (services) {
services
.forEach((service) => {
// Device Information(0x180A)であれば
// 特性(Characteristic)を探査
if (service.uuid === '180a') {
console.log('Discover Service: Device Information\n')
service.once('characteristicsDiscover', onCharacteristicsDiscover)
service.discoverCharacteristics()
}
})
}
// 探査された特性の内容を出力
function onCharacteristicsDiscover (characteristics) {
console.log('Discover Characteristics:\n')
characteristics
.forEach(characteristic => {
// 不要な情報を削除
delete characteristic._noble
delete characteristic._peripheralId
console.dir(characteristic)
console.log()
})
}
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後サービスを探査
peripheral.once('connect', () => {
peripheral.discoverServices()
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの内容を出力
function onServiceDiscover (services) {
services
.forEach((service) => {
// 不必要な情報を削除
delete service._noble
delete service._peripheralId
// 内容を出力
console.dir(service)
console.log()
})
// 接続を解除
this.disconnect()
}
{
"dependencies": {
"noble": "^1.8.1"
}
}
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後サービス(0xfff0)を探査
peripheral.once('connect', () => {
peripheral.discoverServices(['fff0'])
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの特性を探査
function onServiceDiscover (services) {
services
.forEach((service) => {
console.log('Discover Service: Device Information\n')
service.once('characteristicsDiscover', onCharacteristicsDiscover)
service.discoverCharacteristics()
})
}
// 探査された特性の値を出力
function onCharacteristicsDiscover (characteristics) {
console.log('Discover Characteristics:\n')
characteristics
.forEach(characteristic => {
characteristic.read((err, data) => {
if (err) throw err
console.log(`(${characteristic.uuid}): ${data.toString('hex')}`)
})
})
}
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後 Device information サービス(0x180a)を探査
peripheral.once('connect', () => {
peripheral.discoverServices(['180a'])
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの特性を探査
function onServiceDiscover (services) {
services
.forEach((service) => {
console.log('Discover Service: Device Information\n')
service.once('characteristicsDiscover', onCharacteristicsDiscover)
service.discoverCharacteristics()
})
}
// 探査された特性の値を出力
function onCharacteristicsDiscover (characteristics) {
console.log('Discover Characteristics:\n')
characteristics
.forEach(characteristic => {
characteristic.read((err, data) => {
if (err) throw err
// type に _string を含む場合は文字列として値を取得
// その他の場合は16進数として取得
let value = (characteristic.type.indexOf('_string') !== -1)
? data.toString() : data.toString('hex')
console.log(`(${characteristic.uuid}) ${characteristic.name} : ${value}`)
})
})
}
const noble = require('noble')
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、情報を出力
noble.on('discover', (peripheral) => {
console.log('discover peripheral:')
// 不必要な情報を削除
delete peripheral._noble
// 出力
console.dir(peripheral)
})
const noble = require('noble')
const FAT_SCALE = '000FatScale01'
// Bluetooth のステータスを監視
noble.on('stateChange', (state) => {
console.log(`\nstateChange: ${state}\n`)
if (state === 'poweredOn') {
// Bluetooth がオンの場合は周辺機器のスキャンを開始
noble.startScanning()
} else {
// Bluetooth がオフの場合は周辺機器のスキャンを停止
noble.stopScanning()
}
})
// 周辺機器が見つかったら、接続後サービスを探査
noble.on('discover', (peripheral) => {
const localName = peripheral.advertisement.localName
if (localName === FAT_SCALE) {
console.log(`discover peripheral: ${FAT_SCALE}\n`)
// スキャンを停止
noble.stopScanning()
// 接続後サービス(0xfff0)を探査
peripheral.once('connect', () => {
peripheral.discoverServices(['fff0'])
})
// 接続が切られたら出力
peripheral.once('connect', () => {
console.log(`disconnect: ${FAT_SCALE}`)
})
// 探査されたサービスを出力
peripheral.once('servicesDiscover', onServiceDiscover)
// 見つかった 000FatScale01 に接続
peripheral.connect()
}
})
// 探査されたサービスの特性を探査
function onServiceDiscover (services) {
services
.forEach((service) => {
console.log('Discover Service: Device Information\n')
service.once('characteristicsDiscover', onCharacteristicsDiscover)
service.discoverCharacteristics()
})
}
// 探査された特性の値を出力
function onCharacteristicsDiscover (characteristics) {
console.log('Discover Characteristics:\n')
characteristics
.forEach(characteristic => {
// notify が許可されている場合
if (characteristic.properties.includes('notify')) {
// 通知を受信したら値を出力
characteristic.on('data', (data) => {
console.log(`(${characteristic.uuid}):`)
console.dir(data)
})
// 通知を購読
characteristic.subscribe((err) => {
if (err) throw err
console.log(`(${characteristic.uuid}): start subscribe`)
})
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment