UNPKG

obniz

Version:

obniz sdk for javascript

478 lines (477 loc) 14.4 kB
/** * @packageDocumentation * @module Parts.Linking */ /* ------------------------------------------------------------------ * node-linking - service-sensor.js * * Copyright (c) 2017-2019, Futomi Hatano, All rights reserved. * Released under the MIT license * Date: 2019-11-02 * ---------------------------------------------------------------- */ 'use strict'; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ieee754_1 = __importDefault(require("./ieee754")); class LinkingServiceSensor { constructor() { this.SERVICE_ID = 0x03; this.SERVICE_NAME = 'PeripheralDeviceSensorInformation'; this.MESSAGE_NAME_MAP = { '00': 'GET_SENSOR_INFO', '01': 'GET_SENSOR_INFO_RESP', '02': 'SET_NOTIFY_SENSOR_INFO', '03': 'SET_NOTIFY_SENSOR_INFO_RESP', '04': 'NOTIFY_PD_SENSOR_INFO', }; // Private this._WRITE_MESSAGE_ID_MAP = { GET_SENSOR_INFO: 0x00, SET_NOTIFY_SENSOR_INFO: 0x02, }; this._device = {}; } setDeviceInfo(info) { this._device = info; } parsePayload(pnum, buf) { let offset = 0; const parameters = []; let sensor_type = 0; try { for (let i = 0; i < pnum; i++) { const pid = buf.readUInt8(offset++); let plen_buf = buf.slice(offset, offset + 3); plen_buf = Buffer.concat([plen_buf, Buffer.from([0x00])]); const plen = plen_buf.readUInt32LE(0); offset += 3; const pvalue_buf = buf.slice(offset, offset + plen); offset += plen; const p = this._parseParameter(pid, pvalue_buf, sensor_type); if (pid === 0x02 && 'sensorTypeCode' in p) { sensor_type = p.sensorTypeCode; } parameters.push(p); } } catch (e) { // do nothing. } return parameters; } _parseParameter(pid, buf, sensor_type) { let parsed = {}; if (pid === 0x00) { parsed = this._parseResultCode(buf); } else if (pid === 0x01) { parsed = this._parseCancel(buf); } else if (pid === 0x02) { parsed = this._parseSensorType(buf); } else if (pid === 0x03) { parsed = this._parseStatus(buf); } else if (pid === 0x04) { parsed = this._parseX_value(buf); } else if (pid === 0x05) { parsed = this._parseY_value(buf); } else if (pid === 0x06) { parsed = this._parseZ_value(buf); } else if (pid === 0x07) { parsed = this._parseX_threshold(buf); } else if (pid === 0x08) { parsed = this._parseY_threshold(buf); } else if (pid === 0x09) { parsed = this._parseZ_threshold(buf); } else if (pid === 0x0a) { parsed = this._parseOriginalData(buf, sensor_type); } parsed.parameterId = pid; return parsed; } _parseResultCode(buf) { const code = buf.readUInt8(0); let text = ''; if (code === 0x00) { text = 'OK, request processed correctly'; } else if (code === 0x01) { text = 'Cancel'; } else if (code === 0x02) { text = 'Error, failed'; } else if (code === 0x03) { text = 'Error, no reason defined'; } else if (code === 0x04) { text = 'Error, data not available'; } else if (code === 0x05) { text = 'Error, not supported'; } return { name: 'ResultCode', resultCode: code, resultText: text, }; } _parseCancel(buf) { const code = buf.readUInt8(0); let text = ''; if (code === 0x00) { text = 'User cancel'; } return { name: 'Cancel', cancelCode: code, cancelText: text, }; } _parseSensorType(buf) { const code = buf.readUInt8(0); let text = ''; if (code === 0x00) { text = 'Gyroscope'; } else if (code === 0x01) { text = 'Accelerometer'; } else if (code === 0x02) { text = 'Orientation'; } else if (code === 0x03) { text = 'Battery'; } else if (code === 0x04) { text = 'Temperature'; } else if (code === 0x05) { text = 'Humidity'; } else if (code === 0x06) { text = 'Atmospheric pressure'; } else if (code === 0x07) { text = 'Opening and closing'; } else if (code === 0x08) { text = 'Human detection'; } else if (code === 0x09) { text = 'Move'; } else if (code === 0x0a) { text = 'Illuminance'; } return { name: 'SensorType', sensorTypeCode: code, sensorTypeText: text, }; } _parseStatus(buf) { const code = buf.readUInt8(0); let text = ''; if (code === 0x00) { text = 'OFF'; } else if (code === 0x01) { text = 'ON'; } return { name: 'Status', statusCode: code, statusText: text, }; } _parseX_value(buf) { return { name: 'X_value', xValue: buf.readFloatLE(0), }; } _parseY_value(buf) { return { name: 'Y_value', yValue: buf.readFloatLE(0), }; } _parseZ_value(buf) { return { name: 'Z_value', zValue: buf.readFloatLE(0), }; } _parseX_threshold(buf) { return { name: 'X_threshold', xThreshold: buf.readFloatLE(0), }; } _parseY_threshold(buf) { return { name: 'Y_threshold', yThreshold: buf.readFloatLE(0), }; } _parseZ_threshold(buf) { return { name: 'Z_threshold', zThreshold: buf.readFloatLE(0), }; } _parseOriginalData(buf, sensor_type) { const n = buf.readUInt16LE(0) & 0b0000111111111111; if (sensor_type === 0x03) { // Battery return { chargeRequired: n & 0b0000100000000000 ? true : false, chargeLevel: Math.min((n & 0b0000011111111111) / 10, 100), }; } else if (sensor_type === 0x04) { // Temperature return { temperature: ieee754_1.default.read(n, 1, 4, 7), }; } else if (sensor_type === 0x05) { // Humidity const v = ieee754_1.default.read(n, 0, 4, 8); return { humidity: v, }; } else if (sensor_type === 0x06) { // Atmospheric pressure return { pressure: buf.readFloatLE(0), }; } else if (sensor_type === 0x07) { // Opening and closing return { openingStatus: n & 0b0000100000000000 ? true : false, openingCount: Math.min((n & 0b0000011111111111) / 10, 100), }; } else if (sensor_type === 0x08) { // Human detection return { humanDetectionResponse: n & 0b0000100000000000 ? true : false, humanDetectionCount: n & 0b0000011111111111, }; } else if (sensor_type === 0x09) { // Move (Vibration Sensor) return { moveResponse: n & 0b0000100000000000 ? true : false, moveCount: n & 0b0000011111111111, }; } else if (sensor_type === 0x0a) { // Illuminance return { illuminance: buf.readFloatLE(0), }; } else { return {}; } } createRequest(message_name, params) { if (!(message_name in this._WRITE_MESSAGE_ID_MAP)) { return null; } const buf_list = []; // packet header const header_buf = Buffer.alloc(1); header_buf.writeUInt8(parseInt('00000001', 2)); buf_list.push(header_buf); // Service ID const sid_buf = Buffer.alloc(1); sid_buf.writeUInt8(this.SERVICE_ID); buf_list.push(sid_buf); // Message ID const mid_buf = Buffer.alloc(2); mid_buf.writeUInt16LE(this._WRITE_MESSAGE_ID_MAP[message_name]); buf_list.push(mid_buf); // Number of parameters + Payload const pl_buf = this._createPayload(message_name, params); if (!pl_buf) { return null; } buf_list.push(pl_buf); return Buffer.concat(buf_list); } _createPayload(message_name, params) { if (message_name === 'GET_SENSOR_INFO') { return this._createPayloadGetSensorInfo(params); } else if (message_name === 'SET_NOTIFY_SENSOR_INFO') { return this._createPayloadSetNotifySensorInfo(params); } else { return null; } } _createPropertyBlockBuffer(pid, val_buf) { const pid_buf = Buffer.from([pid]); let len = 0; if (val_buf) { len = val_buf.length; } let len_buf = Buffer.alloc(4); len_buf.writeUInt32LE(len); len_buf = len_buf.slice(0, 3); const buf_list = [pid_buf, len_buf]; if (val_buf) { buf_list.push(val_buf); } return Buffer.concat(buf_list); } _createPayloadGetSensorInfo(params) { let pnum = 0; let sensor_type = null; if ('SensorType' in params && typeof params.SensorType === 'number' && params.SensorType >= 0x00 && params.SensorType <= 0xff && params.SensorType % 1 === 0) { sensor_type = params.SensorType; pnum++; } else { return null; } // buffer list const buf_list = []; // Number of parameters const pnum_buf = Buffer.from([pnum]); buf_list.push(pnum_buf); // SensorType if (sensor_type !== null) { const val_buf = Buffer.from([sensor_type]); buf_list.push(this._createPropertyBlockBuffer(0x02, val_buf)); } // Create a packet return Buffer.concat(buf_list); } _createPayloadSetNotifySensorInfo(params) { let pnum = 0; let sensor_type = null; if ('SensorType' in params && typeof params.SensorType === 'number' && params.SensorType >= 0x00 && params.SensorType <= 0xff && params.SensorType % 1 === 0) { sensor_type = params.SensorType; pnum++; } else { return null; } let status = null; if ('Status' in params) { status = params.Status ? 1 : 0; pnum++; } else { return null; } let x = null; let y = null; let z = null; if (sensor_type <= 0x02) { if ('X_threshold' in params) { if (typeof params.X_threshold === 'number') { x = params.X_threshold; pnum++; } else { return null; } } if ('Y_threshold' in params) { if (typeof params.Y_threshold === 'number') { y = params.Y_threshold; pnum++; } else { return null; } } if ('Z_threshold' in params) { if (typeof params.Z_threshold === 'number') { z = params.Z_threshold; pnum++; } else { return null; } } } let odata = null; if ('OriginalData' in params) { if (params.OriginalData && params.OriginalData instanceof Buffer) { odata = params.OriginalData; pnum++; } else { return null; } } // buffer list const buf_list = []; // Number of parameters const pnum_buf = Buffer.from([pnum]); buf_list.push(pnum_buf); // SensorType if (sensor_type !== null) { const val_buf = Buffer.from([sensor_type]); buf_list.push(this._createPropertyBlockBuffer(0x02, val_buf)); } // Status if (status !== null) { const val_buf = Buffer.from([status]); buf_list.push(this._createPropertyBlockBuffer(0x03, val_buf)); } // X_threshold if (x !== null) { const val_buf = Buffer.alloc(4); val_buf.writeFloatLE(x, 0); buf_list.push(this._createPropertyBlockBuffer(0x07, val_buf)); } // Y_threshold if (y !== null) { const val_buf = Buffer.alloc(4); val_buf.writeFloatLE(y, 0); buf_list.push(this._createPropertyBlockBuffer(0x08, val_buf)); } // Z_threshold if (z !== null) { const val_buf = Buffer.alloc(4); val_buf.writeFloatLE(z, 0); buf_list.push(this._createPropertyBlockBuffer(0x09, val_buf)); } // OriginalData if (odata !== null) { const val_buf = odata; buf_list.push(this._createPropertyBlockBuffer(0x0a, val_buf)); } // Create a packet return Buffer.concat(buf_list); } } exports.default = LinkingServiceSensor;