UNPKG

timeline-state-resolver

Version:
218 lines • 8.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DeviceInstanceWrapper = void 0; const EventEmitter = require("eventemitter3"); const lib_1 = require("../lib"); const stateHandler_1 = require("./stateHandler"); const devices_1 = require("./devices"); /** * Top level container for setting up and interacting with any device integrations */ class DeviceInstanceWrapper extends EventEmitter { constructor(id, time, config, getRemoteCurrentTime) { super(); this.config = config; this.getRemoteCurrentTime = getRemoteCurrentTime; this._isActive = false; this._logDebug = false; this._logDebugStates = false; const deviceSpecs = devices_1.DevicesDict[config.type]; if (!deviceSpecs) { throw new Error('Could not find device of type ' + config.type); } this._device = new deviceSpecs.deviceClass(this._getDeviceContextAPI()); this._deviceId = id; this._deviceType = config.type; this._deviceName = deviceSpecs.deviceName(id, config); this._instanceId = Math.floor(Math.random() * 10000); this._startTime = time; this._updateTimeSync(); this._stateHandler = new stateHandler_1.StateHandler({ deviceId: id, logger: { debug: (...args) => this.emit('debug', ...args), info: (info) => this.emit('info', info), warn: (warn) => this.emit('warning', warn), error: (context, e) => this.emit('error', context, e), }, emitTimeTrace: (trace) => this.emit('timeTrace', trace), reportStateChangeMeasurement: (report) => { report.commands.forEach((cReport) => { if (cReport.executeDelay && cReport.executeDelay > (this.config.limitSlowSentCommand || 40)) { this.emit('slowSentCommand', { added: report.added, prepareTime: 0, plannedSend: report.scheduled, send: report.executed || 0, queueId: '', args: cReport.args, sendDelay: cReport.executeDelay, addedDelay: 0, internalDelay: 0, }); } if (cReport.fulfilledDelay && cReport.fulfilledDelay > (this.config.limitSlowFulfilledCommand || 100)) { this.emit('slowFulfilledCommand', { added: report.added, prepareTime: 0, plannedSend: report.scheduled, send: report.executed || 0, queueId: '', args: cReport.args, fullfilled: cReport.fulfilled || 0, fulfilledDelay: cReport.fulfilledDelay, }); } this.emit('commandReport', { plannedSend: report.scheduled, queueId: '', added: report.added, prepareTime: 0, send: cReport.executed, fullfilled: cReport.fulfilled || 0, args: cReport.args, }); }); }, getCurrentTime: () => this.getCurrentTime(), }, { executionType: deviceSpecs.executionMode(config.options), }, this._device); } async initDevice(_activeRundownPlaylistId) { return this._device.init(this.config.options); } async terminate() { await this._stateHandler.terminate(); return this._device.terminate(); } async executeAction(id, payload) { const action = this._device.actions[id]; if (!action) { return (0, lib_1.actionNotFoundMessage)(id); } return action(id, payload); } async makeReady(okToDestroyStuff) { return this._device.makeReady(okToDestroyStuff); } async standDown() { if (this._device.standDown) { return this._device.standDown(); } } /** @deprecated - just here for API compatiblity with the old class */ prepareForHandleState() { // } handleState(newState, newMappings) { this._stateHandler.handleState(newState, newMappings).catch((e) => { this.emit('error', 'Error while handling state', e); }); this._isActive = Object.keys(newMappings).length > 0; } clearFuture(t) { this._stateHandler.clearFutureAfterTimestamp(t); } getDetails() { return { deviceId: this._deviceId, deviceType: this._deviceType, deviceName: this._deviceName, instanceId: this._instanceId, startTime: this._startTime, supportsExpectedPlayoutItems: false, canConnect: devices_1.DevicesDict[this.config.type].canConnect, }; } handleExpectedPlayoutItems(_expectedPlayoutItems) { // do nothing yet, as this isn't implemented. } getStatus() { return { ...this._device.getStatus(), active: this._isActive }; } setDebugLogging(value) { this._logDebug = value; } setDebugState(value) { this._logDebugStates = value; } getCurrentTime() { if (!this._lastUpdateCurrentTime || this._tDiff === undefined || Date.now() - this._lastUpdateCurrentTime > 5 * 60 * 1000) { this._updateTimeSync(); } return Date.now() + (this._tDiff ?? 0); } _getDeviceContextAPI() { return { logger: { error: (context, err) => { this.emit('error', context, err); }, warning: (warning) => { this.emit('warning', warning); }, info: (info) => { this.emit('info', info); }, debug: (...debug) => { if (this._logDebug) this.emit('debug', ...debug); }, }, getCurrentTime: () => this.getCurrentTime(), emitDebugState: (state) => { if (this._logDebugStates) { this.emit('debugState', state); } }, connectionChanged: (status) => { this.emit('connectionChanged', { ...status, active: this._isActive, }); }, resetResolver: () => { this.emit('resetResolver'); }, commandError: (error, context) => { this.emit('commandError', error, context); }, updateMediaObject: (collectionId, docId, doc) => { this.emit('updateMediaObject', collectionId, docId, doc); }, clearMediaObjects: (collectionId) => { this.emit('clearMediaObjects', collectionId); }, timeTrace: (trace) => { this.emit('timeTrace', trace); }, resetState: async () => { await this._stateHandler.setCurrentState(undefined); await this._stateHandler.clearFutureStates(); this.emit('resyncStates'); }, resetToState: async (state) => { await this._stateHandler.setCurrentState(state); await this._stateHandler.clearFutureStates(); this.emit('resyncStates'); }, }; } _updateTimeSync() { this._lastUpdateCurrentTime = Date.now(); // set this first so we don't update twice at the same time const start = Date.now(); this.getRemoteCurrentTime() .then((t) => { const end = Date.now(); this._tDiff = t - Math.round((start + end) / 2); }) .catch((e) => { this.emit('error', 'Error when syncing time', e); }); } } exports.DeviceInstanceWrapper = DeviceInstanceWrapper; //# sourceMappingURL=DeviceInstance.js.map