259 lines
8.7 KiB
JavaScript
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
|