UNPKG

obniz

Version:

obniz sdk for javascript

210 lines (209 loc) 6.97 kB
"use strict"; /** * @packageDocumentation * @module Parts.UT201BLE */ /* eslint rulesdir/non-ascii: 0 */ Object.defineProperty(exports, "__esModule", { value: true }); /** UT201BLE management class UT201BLEを管理するクラス */ class UT201BLE { constructor(peripheral, timezoneOffsetMinute) { if (!peripheral || !UT201BLE.isDevice(peripheral)) { throw new Error('peripheral is not UT201BLE'); } this._peripheral = peripheral; this._timezoneOffsetMinute = timezoneOffsetMinute; } static info() { return { name: 'UT201BLE', }; } /** * Verify that the received peripheral is from the UT201BLE * * 受け取ったPeripheralがUT201BLEのものかどうかを確認する * * @param peripheral instance of BleRemotePeripheral BleRemotePeripheralのインスタンス * * @returns Whether it is UT201BLE * * UT201BLEかどうか */ static isDevice(peripheral) { return (peripheral.localName && peripheral.localName.startsWith('A&D_UT201BLE_')); } isPairingMode() { if (!this._peripheral) { throw new Error('UT201BLE not found'); } // adv_data[2]はFlagsで、bit0が1の場合Pairng Mode(Limited Discoverable Mode) if (this._peripheral.adv_data[2] === 5) { return true; } else { return false; } } /** * Pair with the device * * デバイスとペアリング * * @returns pairing key ペアリングキー */ async pairingWait() { if (!this._peripheral) { throw new Error('UT201BLE not found'); } this._peripheral.ondisconnect = (reason) => { if (typeof this.ondisconnect === 'function') { this.ondisconnect(reason); } }; let key = null; await this._peripheral.connectWait({ pairingOption: { onPairedCallback: (pairingKey) => { key = pairingKey; }, }, }); const { timeChar, customServiceChar } = this._getChars(); await this._writeTimeCharWait(this._timezoneOffsetMinute); // await customServiceChar.writeWait([2, 1, 3]); // disconnect req return key; } /** * Get data from the UT201BLE * * UT201BLEからデータを取得 * * @param pairingKeys pairing key ペアリングキー * * @returns data from the UT201BLE UT201BLEから受け取ったデータ */ async getDataWait(pairingKeys) { if (!this._peripheral) { throw new Error('UT201BLE not found'); } await this._peripheral.connectWait({ pairingOption: { keys: pairingKeys, }, }); if (!this._peripheral) { throw new Error('UT201BLE not found'); } const results = []; const { temperatureMeasurementChar, timeChar, customServiceChar, batteryChar, } = this._getChars(); const waitDisconnect = new Promise((resolve, reject) => { if (!this._peripheral) return; this._peripheral.ondisconnect = (reason) => { resolve(results); }; }); const battery = await batteryChar.readWait(); await customServiceChar.writeWait([2, 0, 0xe1]); // send all data await this._writeTimeCharWait(this._timezoneOffsetMinute); await temperatureMeasurementChar.registerNotifyWait((data) => { results.push(this._analyzeData(data, battery)); }); return await waitDisconnect; } _readFloatLE(buffer, index) { const data = buffer.readUInt32LE(index); let mantissa = data & 0x00ffffff; if ((mantissa & 0x00800000) > 0) { mantissa = -1 * (~(mantissa - 0x01) & 0x00ffffff); } const exponential = data >> 24; return mantissa * Math.pow(10, exponential); } _analyzeData(data, battery) { const buf = Buffer.from(data); const flags = buf.readUInt8(0); let index = 1; const result = {}; if (flags & 0x01) { // Fahrenheit result.fahrenheit = this._readFloatLE(buf, index); index += 4; } else { // Celsius result.celsius = this._readFloatLE(buf, index); index += 4; } if (flags & 0x02) { // Time Stamp field present result.date = { year: buf.readUInt16LE(index), month: buf.readUInt8(index + 2), day: buf.readUInt8(index + 3), hour: buf.readUInt8(index + 4), minute: buf.readUInt8(index + 5), second: buf.readUInt8(index + 6), }; index += 7; } if (flags & 0x04) { const types = [ 'unknown', 'Armpit', 'Body', 'Ear', 'Finger', 'Gastro-intestinal Tract', 'Mouth', 'Rectum', 'Toe', 'Tympanum', ]; const value = buf.readUInt8(index); index++; result.temperatureType = types[value] || 'unknown'; result.battery = battery[0]; } return result; } _getChars() { if (!this._peripheral) { throw new Error('UT201BLE not found'); } const temperatureMeasurementChar = this._peripheral .getService('1809') .getCharacteristic('2A1C'); const timeChar = this._peripheral .getService('1809') .getCharacteristic('2A08'); const customServiceChar = this._peripheral .getService('233bf0005a341b6d975c000d5690abe4') .getCharacteristic('233bf0015a341b6d975c000d5690abe4'); const batteryChar = this._peripheral .getService('180F') .getCharacteristic('2A19'); return { temperatureMeasurementChar, timeChar, customServiceChar, batteryChar, }; } async _writeTimeCharWait(timeOffsetMinute) { const { timeChar } = this._getChars(); const date = new Date(); date.setTime(Date.now() + 1000 * 60 * timeOffsetMinute); const buf = Buffer.alloc(7); buf.writeUInt16LE(date.getUTCFullYear(), 0); buf.writeUInt8(date.getUTCMonth() + 1, 2); buf.writeUInt8(date.getUTCDate(), 3); buf.writeUInt8(date.getUTCHours(), 4); buf.writeUInt8(date.getUTCMinutes(), 5); buf.writeUInt8(date.getUTCSeconds(), 6); const arr = Array.from(buf); await timeChar.writeWait(arr); } } exports.default = UT201BLE;