filmout_manager/dist/camera/index.js

259 lines
8.7 KiB
JavaScript

"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 = Date.now();
let ms;
await this.confirm(Commands.CAMERA, Commands.CAMERA);
ms = (Date.now()) - start;
this.log.info(this.prefix + `frame() - ${ms}ms`);
return ms;
}
async open() {
const start = Date.now();
let ms;
await this.confirm(Commands.CAMERA_OPEN, Commands.CAMERA_OPEN);
ms = (Date.now()) - start;
this.log.info(this.prefix + `open() - ${ms}ms`);
return ms;
}
async close() {
const start = Date.now();
let ms;
await this.confirm(Commands.CAMERA_CLOSE, Commands.CAMERA_CLOSE);
ms = (Date.now()) - start;
this.log.info(this.prefix + `close() - ${ms}ms`);
return ms;
}
async direction(dir) {
const start = Date.now();
let ms;
const cmd = dir ? Commands.CAMERA_FORWARD : Commands.CAMERA_BACKWARD;
await this.confirm(cmd, cmd);
ms = (Date.now()) - start;
this.log.info(this.prefix + `direction(${dir}) - ${ms}ms`);
return ms;
}
}
exports.Camera = Camera;
module.exports = { Camera };
//# sourceMappingURL=index.js.map