"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Device = void 0;
const events_1 = require("events");
const Consts = __importStar(require("../consts"));
/**
* @class Device
* @extends EventEmitter
*/
class Device extends events_1.EventEmitter {
constructor(hub, portId, modeMap = {}, type = Consts.DeviceType.UNKNOWN) {
super();
this.autoSubscribe = true;
this.values = {};
this._busy = false;
this._finishedCallbacks = [];
this._connected = true;
this._modeMap = {};
this._isVirtualPort = false;
this._eventTimer = null;
this._hub = hub;
this._portId = portId;
this._type = type;
this._modeMap = modeMap;
this._isWeDo2SmartHub = (this.hub.type === Consts.HubType.WEDO2_SMART_HUB);
this._isVirtualPort = this.hub.isPortVirtual(portId);
const eventAttachListener = (event) => {
if (event === "detach") {
return;
}
if (this.autoSubscribe) {
if (this._modeMap[event] !== undefined) {
this.subscribe(this._modeMap[event]);
}
}
};
const deviceDetachListener = (device) => {
if (device.portId === this.portId) {
this._connected = false;
this.hub.removeListener("detach", deviceDetachListener);
this.emit("detach");
}
};
for (const event in this._modeMap) {
if (this.hub.listenerCount(event) > 0) {
eventAttachListener(event);
}
}
this.hub.on("newListener", eventAttachListener);
this.on("newListener", eventAttachListener);
this.hub.on("detach", deviceDetachListener);
}
/**
* @readonly
* @property {boolean} connected Check if the device is still attached.
*/
get connected() {
return this._connected;
}
/**
* @readonly
* @property {Hub} hub The Hub the device is attached to.
*/
get hub() {
return this._hub;
}
get portId() {
return this._portId;
}
/**
* @readonly
* @property {string} portName The port the device is attached to.
*/
get portName() {
return this.hub.getPortNameForPortId(this.portId);
}
/**
* @readonly
* @property {number} type The type of the device
*/
get type() {
return this._type;
}
get typeName() {
return Consts.DeviceTypeNames[this.type];
}
/**
* @readonly
* @property {number} mode The mode the device is currently in
*/
get mode() {
return this._mode;
}
get isWeDo2SmartHub() {
return this._isWeDo2SmartHub;
}
/**
* @readonly
* @property {boolean} isVirtualPort Is this device attached to a virtual port (ie. a combined device)
*/
get isVirtualPort() {
return this._isVirtualPort;
}
writeDirect(mode, data) {
if (this.isWeDo2SmartHub) {
return this.send(Buffer.concat([Buffer.from([this.portId, 0x01, 0x02]), data]), Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE);
}
else {
return this.send(Buffer.concat([Buffer.from([0x81, this.portId, 0x11, 0x51, mode]), data]), Consts.BLECharacteristic.LPF2_ALL);
}
}
send(data, characteristic = Consts.BLECharacteristic.LPF2_ALL) {
this._ensureConnected();
return this.hub.send(data, characteristic);
}
subscribe(mode) {
this._ensureConnected();
if (mode !== this._mode) {
this._mode = mode;
this.hub.subscribe(this.portId, this.type, mode);
}
}
unsubscribe(mode) {
this._ensureConnected();
}
receive(message) {
this.notify("receive", { message });
}
notify(event, values) {
this.values[event] = values;
this.emit(event, values);
if (this.hub.listenerCount(event) > 0) {
this.hub.emit(event, this, values);
}
}
requestUpdate() {
this.send(Buffer.from([0x21, this.portId, 0x00]));
}
finish(message) {
if ((message & 0x10) === 0x10)
return; // "busy/full"
this._busy = (message & 0x01) === 0x01;
while (this._finishedCallbacks.length > Number(this._busy)) {
const callback = this._finishedCallbacks.shift();
if (callback) {
callback();
}
}
}
setEventTimer(timer) {
this._eventTimer = timer;
}
cancelEventTimer() {
if (this._eventTimer) {
clearTimeout(this._eventTimer);
this._eventTimer = null;
}
}
_ensureConnected() {
if (!this.connected) {
throw new Error("Device is not connected");
}
}
}
exports.Device = Device;
//# sourceMappingURL=device.js.map