Camera connects and attaches
This commit is contained in:
parent
c5e03f669e
commit
e44fc61106
|
@ -2,12 +2,18 @@ export declare class Camera {
|
||||||
private log;
|
private log;
|
||||||
private parser;
|
private parser;
|
||||||
private ready;
|
private ready;
|
||||||
|
private connected;
|
||||||
private serial;
|
private serial;
|
||||||
private baud;
|
private baud;
|
||||||
|
private next;
|
||||||
|
private port;
|
||||||
constructor();
|
constructor();
|
||||||
private begin;
|
private begin;
|
||||||
private filter;
|
private filter;
|
||||||
private enumerate;
|
private enumerate;
|
||||||
private connect;
|
private connect;
|
||||||
|
private connectMock;
|
||||||
private onData;
|
private onData;
|
||||||
|
private verify;
|
||||||
|
private confirm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,17 @@
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Camera = void 0;
|
exports.Camera = void 0;
|
||||||
const log_1 = require("../log");
|
const log_1 = require("../log");
|
||||||
|
const delay_1 = require("../delay");
|
||||||
const serialport_1 = require("serialport");
|
const serialport_1 = require("serialport");
|
||||||
const parser_readline_1 = require("@serialport/parser-readline");
|
const parser_readline_1 = require("@serialport/parser-readline");
|
||||||
class Camera {
|
class Camera {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.ready = false;
|
this.ready = false;
|
||||||
|
this.connected = false;
|
||||||
this.serial = null;
|
this.serial = null;
|
||||||
this.baud = 57600;
|
this.baud = 57600;
|
||||||
|
this.next = null;
|
||||||
|
this.port = null;
|
||||||
this.log = (0, log_1.createLog)('camera');
|
this.log = (0, log_1.createLog)('camera');
|
||||||
this.parser = new parser_readline_1.ReadlineParser({ delimiter: '\r\n' });
|
this.parser = new parser_readline_1.ReadlineParser({ delimiter: '\r\n' });
|
||||||
this.begin();
|
this.begin();
|
||||||
|
@ -22,10 +26,7 @@ class Camera {
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error('Error calling enumerate()', err);
|
this.log.error('Error calling enumerate()', err);
|
||||||
}
|
}
|
||||||
if (ports.length === 0) {
|
if (ports.length > 0) {
|
||||||
this.log.warn('No USB camera devices connected');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let port of ports) {
|
for (let port of ports) {
|
||||||
this.log.info(`Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
this.log.info(`Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
||||||
selected = false;
|
selected = false;
|
||||||
|
@ -37,6 +38,18 @@ class Camera {
|
||||||
this.log.error(`Error connecting to ${ports[0]}`, err);
|
this.log.error(`Error connecting to ${ports[0]}`, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this.log.warn(`No USB serial devices found, connecting to MOCK...`);
|
||||||
|
try {
|
||||||
|
await this.connectMock();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.log.error(`Error connecting to MOCK USB serial device "/dev/fake"`, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await (0, delay_1.delay)(3000);
|
||||||
|
await this.verify();
|
||||||
|
}
|
||||||
filter(port) {
|
filter(port) {
|
||||||
if ((port.manufacturer + '').toLowerCase().indexOf('arduino') !== -1 ||
|
if ((port.manufacturer + '').toLowerCase().indexOf('arduino') !== -1 ||
|
||||||
(port.path + '').toLowerCase().indexOf('usbserial') !== -1 ||
|
(port.path + '').toLowerCase().indexOf('usbserial') !== -1 ||
|
||||||
|
@ -57,24 +70,99 @@ class Camera {
|
||||||
return listed.filter(this.filter).map((port) => port.path);
|
return listed.filter(this.filter).map((port) => port.path);
|
||||||
}
|
}
|
||||||
async connect(port) {
|
async connect(port) {
|
||||||
|
this.port = port;
|
||||||
try {
|
try {
|
||||||
this.serial = new serialport_1.SerialPort({
|
this.serial = new serialport_1.SerialPort({
|
||||||
path: port,
|
path: this.port,
|
||||||
autoOpen: false,
|
|
||||||
baudRate: this.baud,
|
baudRate: this.baud,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error('Error creating SerialPort object', err);
|
this.log.error('Error creating SerialPort object', err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (this.serial !== null) {
|
if (this.serial !== null) {
|
||||||
this.serial.pipe(this.parser);
|
this.serial.pipe(this.parser);
|
||||||
this.parser.on('data', this.onData.bind(this));
|
this.parser.on('data', this.onData.bind(this));
|
||||||
}
|
}
|
||||||
this.ready = true;
|
return new Promise(function (resolve, reject) {
|
||||||
|
this.serial.on('open', () => {
|
||||||
|
this.log.info(`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 serialport_1.SerialPortMock({
|
||||||
|
path: this.port,
|
||||||
|
baudRate: this.baud
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.log.error('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.log.info(`Connected to MOCK USB serial device ${this.port} @ ${this.baud} baud`);
|
||||||
|
this.connected = true;
|
||||||
|
return resolve(true);
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
onData(data) {
|
onData(data) {
|
||||||
this.log.info(`Data received: "${data}"`);
|
this.log.info(`Received data: "${data}"`);
|
||||||
|
if (this.next !== null) {
|
||||||
|
this.next(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async verify() {
|
||||||
|
try {
|
||||||
|
await this.confirm('i', 'i');
|
||||||
|
this.log.info(`Confirmed mcopy device`);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.log.error(`Error connecting to mcopy device`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.confirm('m', 'k');
|
||||||
|
this.log.info(`Confirmed mcopy camera`);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.log.error(`Error identifying device`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ready = true;
|
||||||
|
this.log.info(`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(`Send data: "${cmd}"`);
|
||||||
|
this.serial.write(cmd, (err, results) => {
|
||||||
|
if (err) {
|
||||||
|
this.log.error('Error writing to device', err);
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.Camera = Camera;
|
exports.Camera = Camera;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -36,11 +36,13 @@ const ws_1 = require("ws");
|
||||||
const log_1 = require("./log");
|
const log_1 = require("./log");
|
||||||
const files_1 = require("./files");
|
const files_1 = require("./files");
|
||||||
const ffmpeg_1 = require("./ffmpeg");
|
const ffmpeg_1 = require("./ffmpeg");
|
||||||
|
const camera_1 = require("./camera");
|
||||||
const log = (0, log_1.createLog)('fm');
|
const log = (0, log_1.createLog)('fm');
|
||||||
const app = (0, express_1.default)();
|
const app = (0, express_1.default)();
|
||||||
let wss;
|
let wss;
|
||||||
let fd;
|
let fd;
|
||||||
let ffmpeg;
|
let ffmpeg;
|
||||||
|
let camera;
|
||||||
let index;
|
let index;
|
||||||
let port;
|
let port;
|
||||||
let wsPort;
|
let wsPort;
|
||||||
|
@ -171,6 +173,7 @@ async function main() {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
ffmpeg = new ffmpeg_1.FFMPEG(process.env['FFMPEG']);
|
ffmpeg = new ffmpeg_1.FFMPEG(process.env['FFMPEG']);
|
||||||
|
camera = new camera_1.Camera();
|
||||||
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
|
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
|
||||||
app.listen(port, async () => {
|
app.listen(port, async () => {
|
||||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,10 @@
|
||||||
import { createLog } from '../log';
|
import { createLog } from '../log';
|
||||||
import type { Logger } from 'winston';
|
import type { Logger } from 'winston';
|
||||||
|
import { delay } from '../delay';
|
||||||
|
|
||||||
import { SerialPort } from 'serialport';
|
import { SerialPort, SerialPortMock } from 'serialport';
|
||||||
import { ReadlineParser } from '@serialport/parser-readline';
|
import { ReadlineParser } from '@serialport/parser-readline';
|
||||||
|
import { MockBinding } from '@serialport/binding-mock';
|
||||||
|
|
||||||
interface PortInfo {
|
interface PortInfo {
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -18,8 +20,11 @@ export class Camera {
|
||||||
private log : Logger;
|
private log : Logger;
|
||||||
private parser : ReadlineParser;
|
private parser : ReadlineParser;
|
||||||
private ready : boolean = false;
|
private ready : boolean = false;
|
||||||
private serial : any = null;
|
private connected : boolean = false;
|
||||||
|
private serial : SerialPort | SerialPortMock = null;
|
||||||
private baud : number = 57600;
|
private baud : number = 57600;
|
||||||
|
private next : Function = null;
|
||||||
|
private port : string = null;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this.log = createLog('camera');
|
this.log = createLog('camera');
|
||||||
|
@ -35,10 +40,7 @@ export class Camera {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error('Error calling enumerate()', err);
|
this.log.error('Error calling enumerate()', err);
|
||||||
}
|
}
|
||||||
if (ports.length === 0) {
|
if (ports.length > 0) {
|
||||||
this.log.warn('No USB camera devices connected');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let port of ports) {
|
for (let port of ports) {
|
||||||
this.log.info(`Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
this.log.info(`Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
||||||
selected = false;
|
selected = false;
|
||||||
|
@ -48,6 +50,16 @@ export class Camera {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error(`Error connecting to ${ports[0]}`, err);
|
this.log.error(`Error connecting to ${ports[0]}`, err);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.log.warn(`No USB serial devices found, connecting to MOCK...`)
|
||||||
|
try {
|
||||||
|
await this.connectMock();
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error(`Error connecting to MOCK USB serial device "/dev/fake"`, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await delay(3000);
|
||||||
|
await this.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
private filter (port : PortInfo) {
|
private filter (port : PortInfo) {
|
||||||
|
@ -71,24 +83,100 @@ export class Camera {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async connect (port : string) {
|
private async connect (port : string) {
|
||||||
|
this.port = port;
|
||||||
try {
|
try {
|
||||||
this.serial = new SerialPort({
|
this.serial = new SerialPort({
|
||||||
path : port,
|
path : this.port,
|
||||||
autoOpen : false,
|
|
||||||
baudRate: this.baud,
|
baudRate: this.baud,
|
||||||
})
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error('Error creating SerialPort object', err);
|
this.log.error('Error creating SerialPort object', err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (this.serial !== null) {
|
if (this.serial !== null) {
|
||||||
this.serial.pipe(this.parser);
|
this.serial.pipe(this.parser);
|
||||||
this.parser.on('data', this.onData.bind(this));
|
this.parser.on('data', this.onData.bind(this));
|
||||||
}
|
}
|
||||||
this.ready = true;
|
|
||||||
|
return new Promise(function (resolve : Function, reject : Function) {
|
||||||
|
this.serial.on('open', () => {
|
||||||
|
this.log.info(`Connected to USB serial device ${this.port} @ ${this.baud} baud`);
|
||||||
|
this.connected = true;
|
||||||
|
return resolve(true);
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async connectMock () {
|
||||||
|
this.port = '/dev/fake';
|
||||||
|
try {
|
||||||
|
SerialPortMock.binding.createPort(this.port);
|
||||||
|
this.serial = new SerialPortMock({
|
||||||
|
path : this.port,
|
||||||
|
baudRate: this.baud
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error('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 : Function, reject : Function) {
|
||||||
|
this.serial.on('open', () => {
|
||||||
|
this.log.info(`Connected to MOCK USB serial device ${this.port} @ ${this.baud} baud`);
|
||||||
|
this.connected = true;
|
||||||
|
return resolve(true);
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onData (data : string) {
|
private onData (data : string) {
|
||||||
this.log.info(`Data received: "${data}"`);
|
this.log.info(`Received data: "${data}"`);
|
||||||
|
if (this.next !== null) {
|
||||||
|
this.next(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async verify () {
|
||||||
|
try {
|
||||||
|
await this.confirm('i', 'i');
|
||||||
|
this.log.info(`Confirmed mcopy device`);
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error(`Error connecting to mcopy device`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.confirm('m', 'k');
|
||||||
|
this.log.info(`Confirmed mcopy camera`);
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error(`Error identifying device`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.ready = true;
|
||||||
|
this.log.info(`Camera connected and ready`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async confirm (cmd : string, res : string) : Promise<boolean> {
|
||||||
|
return new Promise (function (resolve : Function, reject: Function) {
|
||||||
|
this.next = function (data : string) {
|
||||||
|
this.next = null;
|
||||||
|
if (data === res) {
|
||||||
|
return resolve(true);
|
||||||
|
} else {
|
||||||
|
return reject(new Error(`Response ${data} !== ${res}`));
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
this.log.info(`Send data: "${cmd}"`);
|
||||||
|
this.serial.write(cmd, (err : any, results : any) => {
|
||||||
|
if (err) {
|
||||||
|
this.log.error('Error writing to device', err);
|
||||||
|
return reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,14 @@ import { Shell } from './shell';
|
||||||
import { delay } from './delay';
|
import { delay } from './delay';
|
||||||
import { FD } from './fd';
|
import { FD } from './fd';
|
||||||
import { FFMPEG } from './ffmpeg';
|
import { FFMPEG } from './ffmpeg';
|
||||||
|
import { Camera } from './camera';
|
||||||
|
|
||||||
const log : Logger = createLog('fm');
|
const log : Logger = createLog('fm');
|
||||||
const app : Express = express();
|
const app : Express = express();
|
||||||
let wss : Server;
|
let wss : Server;
|
||||||
let fd : FD;
|
let fd : FD;
|
||||||
let ffmpeg : FFMPEG;
|
let ffmpeg : FFMPEG;
|
||||||
|
let camera : Camera;
|
||||||
let index : HandlebarsTemplateDelegate<any>;
|
let index : HandlebarsTemplateDelegate<any>;
|
||||||
|
|
||||||
let port : number;
|
let port : number;
|
||||||
|
@ -160,6 +162,8 @@ async function main () {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
ffmpeg = new FFMPEG(process.env['FFMPEG']);
|
ffmpeg = new FFMPEG(process.env['FFMPEG']);
|
||||||
|
camera = new Camera();
|
||||||
|
|
||||||
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
|
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
|
||||||
app.listen(port, async () => {
|
app.listen(port, async () => {
|
||||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||||
|
@ -170,6 +174,8 @@ async function main () {
|
||||||
log.info(`filmout_manager WebSocket server running on port ${wsPort}`);
|
log.info(`filmout_manager WebSocket server running on port ${wsPort}`);
|
||||||
|
|
||||||
ffmpeg.listFormats();
|
ffmpeg.listFormats();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue