@openhps/sphero
Version:
Open Hybrid Positioning System - Sphero component
213 lines • 9 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Core = exports.Event = exports.decodeType = exports.commandsType = void 0;
const commands_1 = require("../commands");
const decoder_1 = require("../commands/decoder");
const types_1 = require("../commands/types");
const queue_1 = require("./queue");
const types_2 = require("./types");
const utils_1 = require("./utils");
exports.commandsType = false && (0, commands_1.factory)();
exports.decodeType = false && (0, decoder_1.factory)(_ => null);
var Event;
(function (Event) {
Event["onCollision"] = "onCollision";
Event["onSensor"] = "onSensor";
})(Event = exports.Event || (exports.Event = {}));
class Core {
constructor(p) {
this.maxVoltage = 0;
this.minVoltage = 1;
this.apiVersion = types_2.APIVersion.V2;
this.sensorMask = {
v2: [],
v21: []
};
this.peripheral = p;
}
batteryVoltage() {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.queueCommand(this.commands.power.batteryVoltage());
return (0, decoder_1.number)(response.command.payload, 1) / 100;
});
}
batteryLevel() {
return __awaiter(this, void 0, void 0, function* () {
const voltage = yield this.batteryVoltage();
const percent = (voltage - this.minVoltage) / (this.maxVoltage - this.minVoltage);
return percent > 1 ? 1 : percent;
});
}
wake() {
return this.queueCommand(this.commands.power.wake());
}
sleep() {
return this.queueCommand(this.commands.power.sleep());
}
start() {
return __awaiter(this, void 0, void 0, function* () {
yield this.init();
yield this.write(this.antiDoSCharacteristic, 'usetheforce...band');
this.started = true;
try {
yield this.wake();
}
catch (e) {
console.error('error', e);
}
});
}
appVersion() {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.queueCommand(this.commands.systemInfo.appVersion());
return {
major: (0, decoder_1.number)(response.command.payload, 1),
minor: (0, decoder_1.number)(response.command.payload, 3)
};
});
}
on(eventName, handler) {
this.eventsListeners[eventName] = handler;
}
destroy() {
this.eventsListeners = {};
this.peripheral.gatt.disconnect();
}
configureSensorStream(interval) {
return __awaiter(this, void 0, void 0, function* () {
const sensorMask = [
types_2.SensorMaskValues.accelerometer,
types_2.SensorMaskValues.orientation,
types_2.SensorMaskValues.locator,
types_2.SensorMaskValues.gyro
];
this.sensorMask = (0, utils_1.sensorValuesToRaw)(sensorMask, this.apiVersion);
yield this.queueCommand(this.commands.sensor.sensorMask((0, utils_1.flatSensorMask)(this.sensorMask.v2), interval ? interval : types_2.SensorControlDefaults.interval));
if (this.sensorMask.v21.length > 0) {
yield this.queueCommand(this.commands.sensor.sensorMaskExtended((0, utils_1.flatSensorMask)(this.sensorMask.v21)));
}
});
}
enableCollisionDetection() {
return this.queueCommand(this.commands.sensor.enableCollisionAsync());
}
configureCollisionDetection(xThreshold = 100, yThreshold = 100, xSpeed = 100, ySpeed = 100, deadTime = 10, method = 0x01) {
return this.queueCommand(this.commands.sensor.configureCollision(xThreshold, yThreshold, xSpeed, ySpeed, deadTime, method));
}
queueCommand(command) {
return this.queue.queue({
characteristic: this.apiV2Characteristic,
command
});
}
init() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
this.queue = new queue_1.Queue({
match: (cA, cB) => this.match(cA, cB),
onExecute: item => this.onExecute(item)
});
this.eventsListeners = {};
this.commands = (0, commands_1.factory)();
this.decoder = (0, decoder_1.factory)((error, packet) => this.onPacketRead(error, packet));
this.started = false;
this.server = yield this.peripheral.gatt.connect();
yield this.bindServices();
this.bindListeners();
resolve(undefined);
}));
});
}
onExecute(item) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.started) {
return;
}
yield this.write(item.characteristic, item.command.raw);
});
}
match(commandA, commandB) {
return (commandA.command.deviceId === commandB.command.deviceId &&
commandA.command.commandId === commandB.command.commandId &&
commandA.command.sequenceNumber === commandB.command.sequenceNumber);
}
bindServices() {
return new Promise((resolve, reject) => {
this.server.getPrimaryService(types_2.ServicesUUID.apiV2ControlService).then((service) => __awaiter(this, void 0, void 0, function* () {
this.apiV2Characteristic = yield service.getCharacteristic(types_2.CharacteristicUUID.apiV2Characteristic);
this.server.getPrimaryService(types_2.ServicesUUID.nordicDfuService).then((service) => __awaiter(this, void 0, void 0, function* () {
this.antiDoSCharacteristic = yield service.getCharacteristic(types_2.CharacteristicUUID.antiDoSCharacteristic);
this.dfuControlCharacteristic = yield service.getCharacteristic(types_2.CharacteristicUUID.dfuControlCharacteristic);
this.subsCharacteristic = yield service.getCharacteristic(types_2.CharacteristicUUID.subsCharacteristic);
resolve();
}));
}));
});
}
bindListeners() {
this.apiV2Characteristic.startNotifications().then(() => {
this.apiV2Characteristic.addEventListener('characteristicvaluechanged', (event) => {
this.onApiRead(new Uint8Array(event.target.value.buffer));
});
});
this.dfuControlCharacteristic.startNotifications().then(() => {
this.dfuControlCharacteristic.addEventListener('characteristicvaluechanged', (_) => {
this.onDFUControlNotify();
});
});
}
onPacketRead(error, command) {
if (error) {
}
else if (command.sequenceNumber === 255) {
this.eventHandler(command);
}
else {
this.queue.onCommandProcessed({ command });
}
}
eventHandler(command) {
if (command.deviceId === types_1.DeviceId.sensor &&
command.commandId === types_1.SensorCommandIds.collisionDetectedAsync) {
this.handleCollision(command);
}
else if (command.deviceId === types_1.DeviceId.sensor &&
command.commandId === types_1.SensorCommandIds.sensorResponse) {
this.handleSensorUpdate(command);
}
}
handleCollision(command) {
const handler = this.eventsListeners.onCollision;
if (handler) {
handler(command);
}
}
handleSensorUpdate(command) {
const handler = this.eventsListeners.onSensor;
if (handler) {
const parsedEvent = (0, utils_1.parseSensorEvent)(command.payload, this.sensorMask);
handler(parsedEvent);
}
}
onApiRead(data) {
data.forEach(byte => this.decoder.add(byte));
}
onDFUControlNotify() {
return this.write(this.dfuControlCharacteristic, new Uint8Array([0x30]));
}
write(c, data) {
let buff = Buffer.from(data);
return c.writeValue(buff);
}
}
exports.Core = Core;
//# sourceMappingURL=core.js.map