"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Camera = void 0; const log_1 = require("../log"); const delay_1 = require("../delay"); const serialport_1 = require("serialport"); const parser_readline_1 = require("@serialport/parser-readline"); var Commands; (function (Commands) { Commands["CONNECT"] = "i"; Commands["MCOPY_IDENTIFIER"] = "m"; Commands["CAMERA_IDENTIFIER"] = "k"; Commands["CAMERA"] = "c"; Commands["CAMERA_FORWARD"] = "e"; Commands["CAMERA_BACKWARD"] = "f"; Commands["CAMERA_OPEN"] = "J"; Commands["CAMERA_CLOSE"] = "K"; })(Commands || (Commands = {})); class CameraSerialPortMock extends serialport_1.SerialPortMock { constructor(options, openCallback = null, parser) { super(options, openCallback); this.log = (0, log_1.createLog)('mock'); this.parser = parser; } write(buffer) { super.write(buffer); //this.log.info(this.prefix + `Received data: "${buffer}"`); switch (buffer) { case Commands.CONNECT: this._mockSend(Commands.CONNECT, 3); break; case Commands.MCOPY_IDENTIFIER: this._mockSend(Commands.CAMERA_IDENTIFIER, 2); break; case Commands.CAMERA: this._mockSend(Commands.CAMERA, 250); break; case Commands.CAMERA_OPEN: this._mockSend(Commands.CAMERA_OPEN, 125); break; case Commands.CAMERA_CLOSE: this._mockSend(Commands.CAMERA_CLOSE, 125); break; default: this.log.warn(`[MOCK] Command "${buffer}" does not exist on mock`); } return true; } _mockSend(buffer, delay) { setTimeout(function () { this.parser._events.data(buffer); }.bind(this), delay); } } class Camera { constructor(mock) { this.ready = false; this.connected = false; this.serial = null; this.baud = 57600; this.next = null; this.port = null; this.prefix = ''; this.mock = false; this.mock = mock; this.log = (0, log_1.createLog)('camera'); this.parser = new parser_readline_1.ReadlineParser({ delimiter: '\r\n' }); this.begin(); } async begin() { let ports = []; let selected = false; try { ports = await this.enumerate(); } catch (err) { this.log.error(this.prefix + 'Error calling enumerate()', err); } if (!this.mock && ports.length > 0) { for (let port of ports) { this.log.info(this.prefix + `Found USB serial device: ${port} ${selected ? '*' : ''}`); selected = false; } try { await this.connect(ports[0]); } catch (err) { this.log.error(this.prefix + `Error connecting to ${ports[0]}`, err); } } else { if (this.mock) { this.log.info(`Starting camera in MOCK mode due to system setting`); } else { this.log.warn(this.prefix + `No USB serial devices found, connecting to MOCK...`); } try { await this.connectMock(); } catch (err) { this.log.error(this.prefix + `Error connecting to MOCK USB serial device "/dev/fake"`, err); } } await (0, delay_1.delay)(3000); await this.verify(); } filter(port) { if ((port.manufacturer + '').toLowerCase().indexOf('arduino') !== -1 || (port.path + '').toLowerCase().indexOf('usbserial') !== -1 || (port.path + '').toLowerCase().indexOf('usbmodem') !== -1 || (port.path + '').toLowerCase().indexOf('ttyusb') !== -1) { return true; } return false; } async enumerate() { let listed = []; try { listed = await serialport_1.SerialPort.list(); } catch (err) { this.log.error(this.prefix + 'Error listing serial ports', err); } return listed.filter(this.filter).map((port) => port.path); } async connect(port) { this.port = port; try { this.serial = new serialport_1.SerialPort({ path: this.port, baudRate: this.baud, }); } catch (err) { this.log.error(this.prefix + 'Error creating SerialPort object', err); return; } if (this.serial !== null) { this.serial.pipe(this.parser); this.parser.on('data', this.onData.bind(this)); } return new Promise(function (resolve, reject) { this.serial.on('open', () => { this.log.info(this.prefix + `Connected to USB serial device ${this.port} @ ${this.baud} baud`); this.connected = true; return resolve(true); }); }.bind(this)); } async connectMock() { this.port = '/dev/fake'; try { serialport_1.SerialPortMock.binding.createPort(this.port); this.serial = new CameraSerialPortMock({ path: this.port, baudRate: this.baud }, null, this.parser); } catch (err) { this.log.error(this.prefix + 'Error creating SerialPortMock object', err); return; } if (this.serial !== null) { this.serial.pipe(this.parser); this.parser.on('data', this.onData.bind(this)); } return new Promise(function (resolve, reject) { this.serial.on('open', () => { this.prefix = '[MOCK] '; this.log.info(this.prefix + `Connected to MOCK USB serial device ${this.port} @ ${this.baud} baud`); this.connected = true; return resolve(true); }); }.bind(this)); } onData(data) { this.log.info(this.prefix + `Received data: "${data}"`); if (this.next !== null) { this.next(data); } } async verify() { try { await this.confirm(Commands.CONNECT, Commands.CONNECT); this.log.info(this.prefix + `Confirmed mcopy device`); } catch (err) { this.log.error(this.prefix + `Error connecting to mcopy device`, err); return; } try { await this.confirm(Commands.MCOPY_IDENTIFIER, Commands.CAMERA_IDENTIFIER); this.log.info(this.prefix + `Confirmed mcopy camera`); } catch (err) { this.log.error(this.prefix + `Error identifying device`, err); return; } this.ready = true; this.log.info(this.prefix + `Camera connected and ready`); } async confirm(cmd, res) { return new Promise(function (resolve, reject) { this.next = function (data) { this.next = null; if (data === res) { return resolve(true); } else { return reject(new Error(`Response ${data} !== ${res}`)); } }.bind(this); this.log.info(this.prefix + `Send data: "${cmd}"`); this.serial.write(cmd, (err, results) => { if (err) { this.log.error(this.prefix + 'Error writing to device', err); return reject(err); } }); }.bind(this)); } async frame() { const start = +new Date(); let ms; await this.confirm(Commands.CAMERA, Commands.CAMERA); ms = (+new Date()) - start; this.log.info(this.prefix + `frame() - ${ms}ms`); return ms; } async open() { const start = +new Date(); let ms; await this.confirm(Commands.CAMERA_OPEN, Commands.CAMERA_OPEN); ms = (+new Date()) - start; this.log.info(this.prefix + `open() - ${ms}ms`); return ms; } async close() { const start = +new Date(); let ms; await this.confirm(Commands.CAMERA_CLOSE, Commands.CAMERA_CLOSE); ms = (+new Date()) - start; this.log.info(this.prefix + `close() - ${ms}ms`); return ms; } async direction(dir) { const start = +new Date(); let ms; const cmd = dir ? Commands.CAMERA_FORWARD : Commands.CAMERA_BACKWARD; await this.confirm(cmd, cmd); ms = (+new Date()) - start; this.log.info(this.prefix + `direction(${dir}) - ${ms}ms`); return ms; } } exports.Camera = Camera; module.exports = { Camera }; //# sourceMappingURL=index.js.map