3000円の Bluetooth 対応体重計を Raspberry Pi を使って Google Fit に対応させてみた その1
3000円の Bluetooth 対応体重計を Raspberry Pi を使って Google Fit に対応させてみた その2
# 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`) | |
}) | |
} | |
}) | |
} |