Remove the cli project. It was unmaintained and unnecessarily adds to the project complexity.
This commit is contained in:
parent
338a60f947
commit
232f39b861
|
@ -1 +0,0 @@
|
|||
node_modules
|
|
@ -1,184 +0,0 @@
|
|||
{
|
||||
"version": "1.6.6",
|
||||
"ext_port": 1111,
|
||||
"profiles": {
|
||||
"mcopy": {
|
||||
"label": "Default mcopy profile",
|
||||
"cam": {
|
||||
"time": 850,
|
||||
"delay": 50,
|
||||
"momentary": 0
|
||||
},
|
||||
"proj": {
|
||||
"time": 1400,
|
||||
"delay": 50,
|
||||
"momentary": 0
|
||||
},
|
||||
"black": {
|
||||
"before": 0,
|
||||
"after": 0
|
||||
},
|
||||
"light": false
|
||||
},
|
||||
"jk103": {
|
||||
"label": "JK103",
|
||||
"cam": {
|
||||
"time": 600,
|
||||
"delay": 50,
|
||||
"momentary": 240
|
||||
},
|
||||
"proj": {
|
||||
"time": 950,
|
||||
"delay": 50,
|
||||
"momentary": 240
|
||||
},
|
||||
"black": {
|
||||
"before": 0,
|
||||
"after": 0
|
||||
},
|
||||
"light": false
|
||||
},
|
||||
"jk_original": {
|
||||
"label": "JK45 profile",
|
||||
"cam": {
|
||||
"time": 750,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"proj": {
|
||||
"time": 1300,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"black": {
|
||||
"before": 250,
|
||||
"after": 250
|
||||
},
|
||||
"light": false
|
||||
},
|
||||
"intval3": {
|
||||
"label": "INTVAL3",
|
||||
"cam": {
|
||||
"time": 630,
|
||||
"delay": 50,
|
||||
"momentary": 0
|
||||
},
|
||||
"light": false
|
||||
},
|
||||
"jk_mono": {
|
||||
"label": "MONO's JK",
|
||||
"cam": {
|
||||
"time": 750,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"proj": {
|
||||
"time": 1300,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"light": false,
|
||||
"projector_second": true
|
||||
},
|
||||
"oxberry": {
|
||||
"label": "Oxberry",
|
||||
"cam": {
|
||||
"time": 550,
|
||||
"delay": 50,
|
||||
"momentary": 130
|
||||
},
|
||||
"proj": {
|
||||
"time": 1340,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"light": false
|
||||
},
|
||||
"norris": {
|
||||
"label": "Norris",
|
||||
"cam": {
|
||||
"time": 650,
|
||||
"delay": 50,
|
||||
"momentary": 130
|
||||
},
|
||||
"light": false
|
||||
}
|
||||
},
|
||||
"cmd": {
|
||||
"camera_forward": "CF",
|
||||
"camera_backward": "CB",
|
||||
"projector_forward": "PF",
|
||||
"projector_backward": "PB",
|
||||
"black_forward": "BF",
|
||||
"black_backward": "BB",
|
||||
"camera_second_forward": "C2F",
|
||||
"camera_second_backward": "C2B",
|
||||
"cameras_forward": "CCF",
|
||||
"cameras_backward": "CCB",
|
||||
"camera_forward_camera_second_backward": "CFCB",
|
||||
"camera_backward_camera_second_forward": "CBCF",
|
||||
"projector_second_forward": "P2F",
|
||||
"projector_second_backward": "P2B",
|
||||
"projectors_forward": "PPF",
|
||||
"projectors_backward": "PPB",
|
||||
"projector_forward_projector_second_backward": "PFPB",
|
||||
"projector_backward_projector_second_forward": "PBPF",
|
||||
"pause": "PA",
|
||||
"alert": "AL"
|
||||
},
|
||||
"arduino": {
|
||||
"baud": 57600,
|
||||
"board": "uno",
|
||||
"serialDelay": 20,
|
||||
"sequenceDelay": 100,
|
||||
"cam": {
|
||||
"time": 850,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"proj": {
|
||||
"time": 1300,
|
||||
"delay": 50,
|
||||
"momentary": 300
|
||||
},
|
||||
"black": {
|
||||
"before": 250,
|
||||
"after": 250
|
||||
},
|
||||
"cmd": {
|
||||
"debug": "d",
|
||||
"connect": "i",
|
||||
"light": "l",
|
||||
"camera": "c",
|
||||
"projector": "p",
|
||||
"black": "b",
|
||||
"camera_forward": "e",
|
||||
"camera_backward": "f",
|
||||
"projector_forward": "g",
|
||||
"projector_backward": "h",
|
||||
"projector_identifier": "j",
|
||||
"camera_identifier": "k",
|
||||
"mcopy_identifier": "m",
|
||||
"camera_timed": "n",
|
||||
"light_identifier": "o",
|
||||
"projector_light_identifier": "q",
|
||||
"projector_camera_light_identifier": "r",
|
||||
"projector_camera_identifier": "s",
|
||||
"projector_second_identifier": "t",
|
||||
"projectors_identifier": "d",
|
||||
"projector_second_forward": "u",
|
||||
"projector_second_backward": "v",
|
||||
"projector_second": "w",
|
||||
"projectors": "x",
|
||||
"camera_second_identifier": "y",
|
||||
"cameras_identifier": "a",
|
||||
"camera_second_forward": "1",
|
||||
"camera_second_backward": "2",
|
||||
"camera_second": "3",
|
||||
"cameras": "4",
|
||||
"camera_projectors_identifier": "5",
|
||||
"cameras_projector_identifier": "6",
|
||||
"cameras_projectors_identifier": "7"
|
||||
}
|
||||
}
|
||||
}
|
99
cli/index.js
99
cli/index.js
|
@ -1,99 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const program = require('commander')
|
||||
const uuid = require('uuid')
|
||||
const moment = require('moment')
|
||||
const events = require('events')
|
||||
const ee = new events.EventEmitter()
|
||||
|
||||
const cfg = require('../app/data/cfg.json')
|
||||
const pkg = require('./package.json')
|
||||
|
||||
const { delay } = require('delay')
|
||||
const { exit } = require('exit')
|
||||
const intval = require('intval')
|
||||
const arduino = require('arduino')(cfg, ee)
|
||||
const Mscript = require('mscript')
|
||||
const mscript = new Mscript()
|
||||
|
||||
const dev = require('device')(arduino)
|
||||
let log
|
||||
let readline
|
||||
|
||||
let devices
|
||||
|
||||
async function command () {
|
||||
return new Promise ((resolve, reject) => {
|
||||
return readline.question(`Input:`, (str) => {
|
||||
log.info(str)
|
||||
console.dir(mscript.interpret(str))
|
||||
|
||||
//interpret string
|
||||
//readline.close()
|
||||
return resolve(true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function live () {
|
||||
readline = require('readline').createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
log.info('Starting live control mode')
|
||||
while (true) {
|
||||
try {
|
||||
await command()
|
||||
} catch (err) {
|
||||
log.error('Error executing command', err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parsePattern () {
|
||||
|
||||
}
|
||||
|
||||
async function main (arg) {
|
||||
log = await require('log')(arg)
|
||||
|
||||
log.info('mcopy-cli')
|
||||
|
||||
try {
|
||||
devices = await arduino.enumerate()
|
||||
} catch (err) {
|
||||
log.error('Error enumerating devices')
|
||||
log.error(err)
|
||||
}
|
||||
|
||||
if (!devices ||devices.length > 1) {
|
||||
//return exit('No devices found', 1)
|
||||
devices = []
|
||||
}
|
||||
|
||||
await dev.all(devices)
|
||||
|
||||
if (arg.pattern) {
|
||||
|
||||
}
|
||||
|
||||
if (arg.live) {
|
||||
try {
|
||||
await live()
|
||||
} catch (err) {
|
||||
log.error('Error running in live control mode', err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
program
|
||||
.version(pkg.version)
|
||||
.option('-l, --live', 'Live control mode')
|
||||
.option('-f, --frames', 'Number of frames to capture with camera')
|
||||
.option('-p, --pattern', 'Pattern of sequence to be repeated')
|
||||
.option('-i, --intval', 'URL of intval3')
|
||||
.option('-m, --mscript', 'Execute an mscript file')
|
||||
.option('-q, --quiet', 'Suppresses all log messages')
|
||||
.parse(process.argv)
|
||||
|
||||
main(program)
|
|
@ -1,37 +0,0 @@
|
|||
## Functions
|
||||
|
||||
<dl>
|
||||
<dt><a href="#dependencies">dependencies(platform)</a></dt>
|
||||
<dd><p>Evaluates system dependencies for digital
|
||||
projector features by executing processes with
|
||||
--help flag. If they do not exist, log to console</p>
|
||||
</dd>
|
||||
<dt><a href="#system">system()</a> ⇒ <code>object</code></dt>
|
||||
<dd><p>Profile the current system and return an object with
|
||||
data about the displays and dependencies for the digital
|
||||
projector feature.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<a name="dependencies"></a>
|
||||
|
||||
## dependencies(platform)
|
||||
Evaluates system dependencies for digital
|
||||
projector features by executing processes with
|
||||
--help flag. If they do not exist, log to console
|
||||
|
||||
**Kind**: global function
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| platform | <code>string</code> | Operating system type |
|
||||
|
||||
<a name="system"></a>
|
||||
|
||||
## system() ⇒ <code>object</code>
|
||||
Profile the current system and return an object with
|
||||
data about the displays and dependencies for the digital
|
||||
projector feature.
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>object</code> - Object containing system information
|
|
@ -1,71 +0,0 @@
|
|||
<a name="Arduino"></a>
|
||||
|
||||
## Arduino
|
||||
Class representing the arduino communication features
|
||||
|
||||
**Kind**: global class
|
||||
|
||||
* [Arduino](#Arduino)
|
||||
* [.enumerate()](#Arduino+enumerate) ⇒ <code>Promise</code>
|
||||
* [.sendAsync(device, cmd)](#Arduino+sendAsync) ⇒ <code>Promise</code>
|
||||
* [.writeAsync(device, str)](#Arduino+writeAsync) ⇒ <code>Promise</code>
|
||||
* [.openArduino(device)](#Arduino+openArduino) ⇒ <code>Promise</code>
|
||||
* [.closeArduino(device)](#Arduino+closeArduino) ⇒ <code>Promise</code>
|
||||
|
||||
<a name="Arduino+enumerate"></a>
|
||||
|
||||
### arduino.enumerate() ⇒ <code>Promise</code>
|
||||
Enumerate all connected devices that might be Arduinos
|
||||
|
||||
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
|
||||
**Returns**: <code>Promise</code> - Resolves after enumerating
|
||||
<a name="Arduino+sendAsync"></a>
|
||||
|
||||
### arduino.sendAsync(device, cmd) ⇒ <code>Promise</code>
|
||||
Send a command to an Arduino using async/await
|
||||
|
||||
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
|
||||
**Returns**: <code>Promise</code> - Resolves after sending
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| device | <code>string</code> | Arduino identifier |
|
||||
| cmd | <code>string</code> | Single character command to send |
|
||||
|
||||
<a name="Arduino+writeAsync"></a>
|
||||
|
||||
### arduino.writeAsync(device, str) ⇒ <code>Promise</code>
|
||||
Send a string to an Arduino using async/await
|
||||
|
||||
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
|
||||
**Returns**: <code>Promise</code> - Resolves after sending
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| device | <code>string</code> | Arduino identifier |
|
||||
| str | <code>string</code> | String to send |
|
||||
|
||||
<a name="Arduino+openArduino"></a>
|
||||
|
||||
### arduino.openArduino(device) ⇒ <code>Promise</code>
|
||||
Connect to an Arduino using async/await
|
||||
|
||||
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
|
||||
**Returns**: <code>Promise</code> - Resolves after opening
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| device | <code>string</code> | Arduino identifier |
|
||||
|
||||
<a name="Arduino+closeArduino"></a>
|
||||
|
||||
### arduino.closeArduino(device) ⇒ <code>Promise</code>
|
||||
Close a connection to an Arduino using async/await
|
||||
|
||||
**Kind**: instance method of [<code>Arduino</code>](#Arduino)
|
||||
**Returns**: <code>Promise</code> - Resolves after closing
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| device | <code>string</code> | Arduino identifier |
|
||||
|
|
@ -1,408 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//import Log = require('log');
|
||||
const delay_1 = require("delay");
|
||||
const SerialPort = require('serialport');
|
||||
const Readline = SerialPort.parsers.Readline;
|
||||
const exec = require('child_process').exec;
|
||||
const parser = new Readline('');
|
||||
const newlineRe = new RegExp('\n', 'g');
|
||||
const returnRe = new RegExp('\r', 'g');
|
||||
let eventEmitter;
|
||||
let cfg;
|
||||
let arduino;
|
||||
const KNOWN = [
|
||||
'/dev/tty.usbmodem1a161',
|
||||
'/dev/tty.usbserial-A800f8dk',
|
||||
'/dev/tty.usbserial-A900cebm',
|
||||
'/dev/tty.usbmodem1a131',
|
||||
'/dev/tty.usbserial-a900f6de',
|
||||
'/dev/tty.usbmodem1a141',
|
||||
'/dev/ttyACM0',
|
||||
'COM3'
|
||||
];
|
||||
/**
|
||||
* Class representing the arduino communication features
|
||||
**/
|
||||
class Arduino {
|
||||
constructor(errorState) {
|
||||
this.path = {};
|
||||
this.known = KNOWN;
|
||||
this.alias = {};
|
||||
this.serial = { connect: {}, projector: {}, camera: {}, light: {} };
|
||||
this.baud = 57600;
|
||||
this.queue = {};
|
||||
this.timer = 0;
|
||||
this.lock = false;
|
||||
this.locks = {};
|
||||
this.errorState = errorState;
|
||||
this.init();
|
||||
}
|
||||
async init() {
|
||||
const Log = require('log');
|
||||
this.log = await Log({ label: 'arduino' });
|
||||
}
|
||||
/**
|
||||
* Enumerate all connected devices that might be Arduinos
|
||||
*
|
||||
* @returns {Promise} Resolves after enumerating
|
||||
**/
|
||||
async enumerate() {
|
||||
let ports;
|
||||
let matches = [];
|
||||
try {
|
||||
ports = await SerialPort.list();
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
this.log.info('Available ports:');
|
||||
this.log.info(ports.map((port) => { return port.path; }).join(','));
|
||||
ports.forEach((port) => {
|
||||
if (this.known.indexOf(port.path) !== -1) {
|
||||
matches.push(port.path);
|
||||
}
|
||||
else if ((port.manufacturer + '').toLowerCase().indexOf('arduino') !== -1) {
|
||||
matches.push(port.path);
|
||||
}
|
||||
else if ((port.path + '').toLowerCase().indexOf('usbserial') !== -1) {
|
||||
matches.push(port.path);
|
||||
}
|
||||
else if ((port.path + '').toLowerCase().indexOf('usbmodem') !== -1) {
|
||||
matches.push(port.path);
|
||||
}
|
||||
else if ((port.path + '').toLowerCase().indexOf('ttyusb') !== -1) {
|
||||
matches.push(port.path);
|
||||
}
|
||||
});
|
||||
if (matches.length === 0) {
|
||||
throw new Error('No USB devices found');
|
||||
}
|
||||
else if (matches.length > 0) {
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Send a command to an Arduino using async/await
|
||||
*
|
||||
* @param {string} device Arduino identifier
|
||||
* @param {string} cmd Single character command to send
|
||||
*
|
||||
* @returns {Promise} Resolves after sending
|
||||
**/
|
||||
async sendAsync(device, cmd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.queue[cmd] = (ms) => {
|
||||
return resolve(ms);
|
||||
};
|
||||
return this.serial[device].write(cmd, (err, results) => {
|
||||
if (err) {
|
||||
//console.error(err)
|
||||
return reject(err);
|
||||
}
|
||||
//
|
||||
});
|
||||
});
|
||||
}
|
||||
async send(serial, cmd) {
|
||||
const device = this.alias[serial];
|
||||
let results;
|
||||
console.log(`${cmd} -> ${serial}`);
|
||||
if (this.locks[serial]) {
|
||||
return false;
|
||||
}
|
||||
this.timer = new Date().getTime();
|
||||
this.locks[serial] = true;
|
||||
await delay_1.delay(cfg.arduino.serialDelay);
|
||||
try {
|
||||
results = await this.sendAsync(device, cmd);
|
||||
}
|
||||
catch (e) {
|
||||
return console.error(e);
|
||||
}
|
||||
this.locks[serial] = false;
|
||||
await eventEmitter.emit('arduino_send', cmd);
|
||||
return results;
|
||||
}
|
||||
async string(serial, str) {
|
||||
const device = this.alias[serial];
|
||||
let writeSuccess;
|
||||
await delay_1.delay(cfg.arduino.serialDelay);
|
||||
if (typeof this.serial[device].fake !== 'undefined'
|
||||
&& this.serial[device].fake) {
|
||||
return this.serial[device].string(str);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
writeSuccess = await this.writeAsync(device, str);
|
||||
}
|
||||
catch (e) {
|
||||
return console.error(e);
|
||||
}
|
||||
return writeSuccess;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Send a string to an Arduino using async/await
|
||||
*
|
||||
* @param {string} device Arduino identifier
|
||||
* @param {string} str String to send
|
||||
*
|
||||
* @returns {Promise} Resolves after sending
|
||||
**/
|
||||
async writeAsync(device, str) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.serial[device].write(str, function (err, results) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(results);
|
||||
});
|
||||
});
|
||||
}
|
||||
end(serial, data) {
|
||||
const end = new Date().getTime();
|
||||
const ms = end - this.timer;
|
||||
let complete;
|
||||
console.log(`${serial} -> ${data}`);
|
||||
if (this.queue[data] !== undefined) {
|
||||
this.locks[serial] = false;
|
||||
complete = this.queue[data](ms); //execute callback
|
||||
eventEmitter.emit('arduino_end', data);
|
||||
delete this.queue[data];
|
||||
}
|
||||
else if (data === 'E') {
|
||||
//error state
|
||||
//stop sequence
|
||||
//throw error in ui
|
||||
}
|
||||
else {
|
||||
//console.log('Received stray "' + data + '"'); //silent to user
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
aliasSerial(serial, device) {
|
||||
//this.log.info(`Making "${serial}" an alias of ${device}`);
|
||||
this.alias[serial] = device;
|
||||
}
|
||||
async connect(serial, device, confirm) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let connectSuccess;
|
||||
this.path[serial] = device;
|
||||
this.alias[serial] = device;
|
||||
this.serial[device] = new SerialPort(this.path[serial], {
|
||||
autoOpen: false,
|
||||
baudRate: cfg.arduino.baud,
|
||||
parser: parser
|
||||
});
|
||||
this.locks[device] = false;
|
||||
try {
|
||||
connectSuccess = await this.openArduino(device);
|
||||
}
|
||||
catch (e) {
|
||||
console.error('failed to open: ' + e);
|
||||
return reject(e);
|
||||
}
|
||||
//console.log(`Opened connection with ${this.path[serial]} as ${serial}`);
|
||||
if (!confirm) {
|
||||
this.serial[device].on('data', async (data) => {
|
||||
let d = data.toString('utf8');
|
||||
d = d.replace(newlineRe, '').replace(returnRe, '');
|
||||
return this.end(serial, d);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.serial[device].on('data', async (data) => {
|
||||
let d = data.toString('utf8');
|
||||
d = d.replace(newlineRe, '').replace(returnRe, '');
|
||||
return await this.confirmEnd(d);
|
||||
});
|
||||
}
|
||||
return resolve(this.path[serial]);
|
||||
});
|
||||
}
|
||||
confirmEnd(data) {
|
||||
//console.dir(data)
|
||||
if (data === cfg.arduino.cmd.connect
|
||||
|| data === cfg.arduino.cmd.projector_identifier
|
||||
|| data === cfg.arduino.cmd.camera_identifier
|
||||
|| data === cfg.arduino.cmd.light_identifier
|
||||
|| data === cfg.arduino.cmd.projector_light_identifier
|
||||
|| data === cfg.arduino.cmd.projector_camera_light_identifier
|
||||
|| data === cfg.arduino.cmd.projector_camera_identifier
|
||||
|| data === cfg.arduino.cmd.projector_second_identifier
|
||||
|| data === cfg.arduino.cmd.projectors_identifier
|
||||
|| data === cfg.arduino.cmd.projector_second_forward
|
||||
|| data === cfg.arduino.cmd.projector_second_backward
|
||||
|| data === cfg.arduino.cmd.projector_second
|
||||
|| data === cfg.arduino.cmd.projectors
|
||||
|| data === cfg.arduino.cmd.camera_second_identifier
|
||||
|| data === cfg.arduino.cmd.cameras_identifier
|
||||
|| data === cfg.arduino.cmd.camera_second_forward
|
||||
|| data === cfg.arduino.cmd.camera_second_backward
|
||||
|| data === cfg.arduino.cmd.camera_second
|
||||
|| data === cfg.arduino.cmd.cameras) {
|
||||
this.confirmExec(null, data);
|
||||
this.confirmExec = {};
|
||||
}
|
||||
}
|
||||
async verify() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const device = this.alias['connect'];
|
||||
let writeSuccess;
|
||||
this.confirmExec = function (err, data) {
|
||||
if (data === cfg.arduino.cmd.connect) {
|
||||
return resolve(true);
|
||||
}
|
||||
else {
|
||||
return reject('Wrong data returned');
|
||||
}
|
||||
};
|
||||
await delay_1.delay(cfg.arduino.serialDelay);
|
||||
try {
|
||||
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.connect);
|
||||
}
|
||||
catch (e) {
|
||||
return reject(e);
|
||||
}
|
||||
return resolve(writeSuccess);
|
||||
});
|
||||
}
|
||||
async distinguish() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const device = this.alias['connect'];
|
||||
let writeSuccess;
|
||||
let type;
|
||||
this.confirmExec = function (err, data) {
|
||||
if (data === cfg.arduino.cmd.projector_identifier) {
|
||||
type = 'projector';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.camera_identifier) {
|
||||
type = 'camera';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.light_identifier) {
|
||||
type = 'light';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.projector_light_identifier) {
|
||||
type = 'projector,light';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.projector_camera_light_identifier) {
|
||||
type = 'projector,camera,light';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.projector_camera_identifier) {
|
||||
type = 'projector,camera';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.projector_second_identifier) {
|
||||
type = 'projector_second';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.projectors_identifier) {
|
||||
type = 'projector,projector_second';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.camera_second_identifier) {
|
||||
type = 'camera_second';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.cameras_identifier) {
|
||||
type = 'camera,camera_second';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.camera_projectors_identifier) {
|
||||
type = 'camera,projector,projector_second';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.cameras_projector_identifier) {
|
||||
type = 'camera,camera_second,projector';
|
||||
}
|
||||
else if (data === cfg.arduino.cmd.cameras_projectors_identifier) {
|
||||
type = 'camera,camera_second,projector,projector_second';
|
||||
}
|
||||
return resolve(type);
|
||||
};
|
||||
await delay_1.delay(cfg.arduino.serialDelay);
|
||||
try {
|
||||
writeSuccess = await this.sendAsync(device, cfg.arduino.cmd.mcopy_identifier);
|
||||
}
|
||||
catch (e) {
|
||||
return reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
async close() {
|
||||
const device = this.alias['connect'];
|
||||
let closeSuccess;
|
||||
try {
|
||||
closeSuccess = await this.closeArduino(device);
|
||||
}
|
||||
catch (e) {
|
||||
throw e;
|
||||
}
|
||||
return closeSuccess;
|
||||
}
|
||||
;
|
||||
async fakeConnect(serial) {
|
||||
const device = '/dev/fake';
|
||||
this.alias[serial] = device;
|
||||
this.serial[device] = {
|
||||
write: async function (cmd, cb) {
|
||||
const t = {
|
||||
c: cfg.arduino.cam.time + cfg.arduino.cam.delay,
|
||||
p: cfg.arduino.proj.time + cfg.arduino.proj.delay
|
||||
};
|
||||
let timeout = t[cmd];
|
||||
if (typeof timeout === 'undefined')
|
||||
timeout = 10;
|
||||
arduino.timer = +new Date();
|
||||
await delay_1.delay(timeout);
|
||||
arduino.end(serial, cmd);
|
||||
return cb();
|
||||
},
|
||||
string: async function (str) {
|
||||
//do nothing
|
||||
return true;
|
||||
},
|
||||
fake: true
|
||||
};
|
||||
//console.log('Connected to fake arduino! Not real! Does not exist!');
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Connect to an Arduino using async/await
|
||||
*
|
||||
* @param {string} device Arduino identifier
|
||||
*
|
||||
* @returns {Promise} Resolves after opening
|
||||
**/
|
||||
async openArduino(device) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.serial[device].open((err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Close a connection to an Arduino using async/await
|
||||
*
|
||||
* @param {string} device Arduino identifier
|
||||
*
|
||||
* @returns {Promise} Resolves after closing
|
||||
**/
|
||||
async closeArduino(device) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return this.serial[device].close((err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (typeof module !== 'undefined' && module.parent) {
|
||||
module.exports = function (c, ee, errorState) {
|
||||
eventEmitter = ee;
|
||||
cfg = c;
|
||||
arduino = new Arduino(errorState);
|
||||
return arduino;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "arduino",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<a name="Camera"></a>
|
||||
|
||||
## Camera
|
||||
class representing camera functions
|
||||
|
||||
**Kind**: global class
|
||||
|
||||
* [Camera](#Camera)
|
||||
* [.init()](#Camera+init)
|
||||
* [.listen()](#Camera+listen)
|
||||
* [.set()](#Camera+set)
|
||||
* [.move()](#Camera+move)
|
||||
* [.exposure()](#Camera+exposure)
|
||||
* [.connectIntval()](#Camera+connectIntval)
|
||||
* [.listener()](#Camera+listener)
|
||||
* [.end()](#Camera+end)
|
||||
|
||||
<a name="Camera+init"></a>
|
||||
|
||||
### camera.init()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+listen"></a>
|
||||
|
||||
### camera.listen()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+set"></a>
|
||||
|
||||
### camera.set()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+move"></a>
|
||||
|
||||
### camera.move()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+exposure"></a>
|
||||
|
||||
### camera.exposure()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+connectIntval"></a>
|
||||
|
||||
### camera.connectIntval()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+listener"></a>
|
||||
|
||||
### camera.listener()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
||||
<a name="Camera+end"></a>
|
||||
|
||||
### camera.end()
|
||||
**Kind**: instance method of [<code>Camera</code>](#Camera)
|
|
@ -1,224 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const intval_1 = require("intval");
|
||||
/** class representing camera functions **/
|
||||
class Camera {
|
||||
/**
|
||||
*
|
||||
**/
|
||||
constructor(arduino, cfg, ui, filmout, second = false) {
|
||||
this.state = {
|
||||
pos: 0,
|
||||
dir: true
|
||||
};
|
||||
this.arduino = null;
|
||||
this.intval = null;
|
||||
this.id = 'camera';
|
||||
this.arduino = arduino;
|
||||
this.cfg = cfg;
|
||||
this.ui = ui;
|
||||
this.filmout = filmout;
|
||||
if (second)
|
||||
this.id += '_second';
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async init() {
|
||||
const Log = require('log');
|
||||
this.log = await Log({ label: this.id });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on(this.id, this.listener.bind(this));
|
||||
this.ipc.on('intval', this.connectIntval.bind(this));
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async set(dir, id) {
|
||||
let cmd;
|
||||
let ms;
|
||||
if (dir) {
|
||||
cmd = this.cfg.arduino.cmd[`${this.id}_forward`];
|
||||
}
|
||||
else {
|
||||
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
|
||||
}
|
||||
this.state.dir = dir;
|
||||
if (this.intval) {
|
||||
try {
|
||||
ms = await this.intval.setDir(dir);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
return await this.end(cmd, id, ms);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async move(frame, id) {
|
||||
const cmd = this.cfg.arduino.cmd[this.id];
|
||||
let ms;
|
||||
if (this.filmout.state.enabled) {
|
||||
await this.filmout.start();
|
||||
}
|
||||
if (this.intval) {
|
||||
try {
|
||||
ms = await this.intval.move();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
if (this.filmout.state.enabled) {
|
||||
//await delay(100 * 1000);
|
||||
await this.filmout.end();
|
||||
}
|
||||
//this.log.info('Camera move time', { ms });
|
||||
return this.end(cmd, id, ms);
|
||||
}
|
||||
async both(frame, id) {
|
||||
const cmd = this.cfg.arduino.cmd[id];
|
||||
let ms;
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error moving ${this.id}`, err);
|
||||
}
|
||||
//this.log.info('Cameras move time', { ms });
|
||||
return await this.end(cmd, id, ms);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
exposure(exposure, id) {
|
||||
let cmd = 'E';
|
||||
this.intval.setExposure(this.id, exposure, (ms) => {
|
||||
this.end(cmd, id, ms);
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async connectIntval(event, arg) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (arg.connect) {
|
||||
this.intval = new intval_1.Intval(arg.url);
|
||||
this.intval.connect((err, ms, state) => {
|
||||
if (err) {
|
||||
this.ui.send('intval', { connected: false });
|
||||
this.log.info(`Cannot connect to ${arg.url}`, 'INTVAL');
|
||||
this.intval = null;
|
||||
}
|
||||
else {
|
||||
this.ui.send('intval', { connected: true, url: arg.url, state: state });
|
||||
this.log.info(`Connected to INTVAL3 @ ${arg.url}`, 'INTVAL');
|
||||
}
|
||||
return resolve(true);
|
||||
});
|
||||
}
|
||||
else if (arg.disconnect) {
|
||||
this.intval = null;
|
||||
return resolve(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async listener(event, arg) {
|
||||
if (typeof arg.dir !== 'undefined') {
|
||||
try {
|
||||
await this.set(arg.dir, arg.id);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else if (typeof arg.frame !== 'undefined') {
|
||||
try {
|
||||
await this.move(arg.frame, arg.id);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else if (typeof arg.val !== 'undefined') {
|
||||
this.state.pos = arg.val;
|
||||
}
|
||||
event.returnValue = true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async end(cmd, id, ms) {
|
||||
let message = '';
|
||||
if (cmd === this.cfg.arduino.cmd.camera_forward) {
|
||||
message = 'Camera set to FORWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camera_backward) {
|
||||
message = 'Camera set to BACKWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camera_second_forward) {
|
||||
message = 'Camera second set to FORWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camera_second_backward) {
|
||||
message = 'Camera second set to BACKWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camera) {
|
||||
message = 'Camera ';
|
||||
if (this.state.dir) {
|
||||
message += 'ADVANCED';
|
||||
}
|
||||
else {
|
||||
message += 'REWOUND';
|
||||
}
|
||||
message += ' 1 frame';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camera_second) {
|
||||
message = 'Camera second ';
|
||||
if (this.state.dir) {
|
||||
message += 'ADVANCED';
|
||||
}
|
||||
else {
|
||||
message += 'REWOUND';
|
||||
}
|
||||
message += ' 1 frame';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.camerass) {
|
||||
message += 'Cameras both MOVED 1 frame each';
|
||||
}
|
||||
message += ` ${ms}ms`;
|
||||
this.log.info(message);
|
||||
this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
|
||||
}
|
||||
}
|
||||
module.exports = function (arduino, cfg, ui, filmout, second) {
|
||||
return new Camera(arduino, cfg, ui, filmout, second);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "cam",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,577 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const uuid_1 = require("uuid");
|
||||
const delay_1 = require("delay");
|
||||
class Commands {
|
||||
/**
|
||||
* @constructor
|
||||
* Assign all connected devices and mock devices as private classes.
|
||||
*
|
||||
* @param {object} cfg Configuration object
|
||||
* @param {object} proj Projector 1
|
||||
* @param {object} cam Camera 1
|
||||
* @param {object} light Light source
|
||||
* @param {object} cam2 (optional) Camera 2
|
||||
* @param {object} proj2 {optional} Projector 2
|
||||
**/
|
||||
constructor(cfg, proj, cam, light, cam2 = null, proj2 = null) {
|
||||
this.cfg = cfg;
|
||||
this.proj = proj;
|
||||
this.cam = cam;
|
||||
this.light = light;
|
||||
if (cam2)
|
||||
this.cam2 = cam2;
|
||||
if (proj2)
|
||||
this.proj2 = proj2;
|
||||
this.ipc = require('electron').ipcMain;
|
||||
}
|
||||
/**
|
||||
* Move the projector one frame forward
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_forward() {
|
||||
let ms;
|
||||
try {
|
||||
if (!this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.proj.move();
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the projector one frame backward
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_backward() {
|
||||
let ms;
|
||||
try {
|
||||
if (this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.proj.move();
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the camera one frame forward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_forward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (!this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the camera one frame forward with light off
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async black_forward() {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (!this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id); //make sure set to off
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the camera one frame backward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_backward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the camera one frame forward, light set to black or off
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async black_backward() {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id); //make sure set to off
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the second camera one frame forward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_second_forward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (!this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam2.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the second camera one frame backward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_second_backward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let ms;
|
||||
try {
|
||||
if (this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.cam2.move();
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the both cameras one frame forward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async cameras_forward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (!this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(true);
|
||||
}
|
||||
if (!this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
|
||||
ms = await this.cam.both();
|
||||
}
|
||||
else {
|
||||
this.cam.move();
|
||||
this.cam2.move();
|
||||
both = [await this.cam.move, await this.cam2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the both cameras one frame backward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async cameras_backward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(false);
|
||||
}
|
||||
if (this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
|
||||
ms = await this.cam.both();
|
||||
}
|
||||
else {
|
||||
this.cam.move();
|
||||
this.cam2.move();
|
||||
both = [await this.cam.move, await this.cam2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move first camera one frame forward and rewind secondary camera one frame backward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frames
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_forward_camera_second_backward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (!this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(true);
|
||||
}
|
||||
if (this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
|
||||
ms = await this.cam.both();
|
||||
}
|
||||
else {
|
||||
this.cam.move();
|
||||
this.cam2.move();
|
||||
both = [await this.cam.move, await this.cam2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Rewind first camera one frame backward and move secondary camera one frame forward
|
||||
*
|
||||
* @param {array} rgb Color to set light for frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async camera_backward_camera_second_forward(rgb = [255, 255, 255]) {
|
||||
const id = uuid_1.v4();
|
||||
const off = [0, 0, 0];
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (this.cam.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam.set(false);
|
||||
}
|
||||
if (!this.cam2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.cam2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(rgb, id);
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
if (this.cam && this.cam2 && this.cam.arduino.alias.camera === this.cam.arduino.alias.camera_second) {
|
||||
ms = await this.cam.both();
|
||||
}
|
||||
else {
|
||||
this.cam.move();
|
||||
this.cam.move();
|
||||
both = [await this.cam.move, await this.proj2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.light.set(off, id);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the secondary projector forward one frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_second_forward() {
|
||||
let ms;
|
||||
try {
|
||||
if (!this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.proj2.move();
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Rewind the secondary projector backward one frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_second_backward() {
|
||||
let ms;
|
||||
try {
|
||||
if (this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
ms = await this.proj2.move();
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the both projectors forward one frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projectors_forward() {
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (!this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(true);
|
||||
}
|
||||
if (!this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
|
||||
ms = await this.proj.both();
|
||||
}
|
||||
else {
|
||||
this.proj.move();
|
||||
this.proj2.move();
|
||||
both = [await this.proj.move, await this.proj2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Rewind both projectors backwards one frame
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projectors_backward() {
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(false);
|
||||
}
|
||||
if (this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
//run one projector without await?
|
||||
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
|
||||
ms = await this.proj.both();
|
||||
}
|
||||
else {
|
||||
this.proj.move();
|
||||
this.proj2.move();
|
||||
both = [await this.proj.move, await this.proj2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Move the primary projector forward one frame and rewind the secondary projector
|
||||
* one frame backwards.
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_forward_projector_second_backward() {
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (!this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(true);
|
||||
}
|
||||
if (this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(false);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
//run one projector without await?
|
||||
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
|
||||
ms = await this.proj.both();
|
||||
}
|
||||
else {
|
||||
this.proj.move();
|
||||
this.proj2.move();
|
||||
both = [await this.proj.move, await this.proj2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
/**
|
||||
* Rewind the primary projector backwards one frame and move the secondary
|
||||
* projector forward one frame.
|
||||
*
|
||||
* @returns {integer} Length of action in ms
|
||||
**/
|
||||
async projector_backward_projector_second_forward() {
|
||||
let both;
|
||||
let ms;
|
||||
try {
|
||||
if (this.proj.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj.set(false);
|
||||
}
|
||||
if (!this.proj2.state.dir) {
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
await this.proj2.set(true);
|
||||
}
|
||||
await delay_1.delay(this.cfg.arduino.serialDelay);
|
||||
//run one projector without await?
|
||||
if (this.proj && this.proj2 && this.proj.arduino.alias.projector === this.proj.arduino.alias.projector_second) {
|
||||
ms = await this.proj.both();
|
||||
}
|
||||
else {
|
||||
this.proj.move();
|
||||
this.proj2.move();
|
||||
both = [await this.proj.move, await this.proj2.move];
|
||||
ms = Math.max(...both);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
}
|
||||
module.exports = function (cfg, proj, cam, light, cam2, proj2) {
|
||||
return new Commands(cfg, proj, cam, light, cam2, proj2);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "cmd",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<a name="delay"></a>
|
||||
|
||||
## delay(ms) ⇒ <code>Promise</code>
|
||||
Delay in an async/await function
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise</code> - Promise to resolve after timeout
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| ms | <code>integer</code> | Milliseconds to delay for |
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
'use strict';
|
||||
/**
|
||||
* Delay in an async/await function
|
||||
*
|
||||
* @param {integer} ms Milliseconds to delay for
|
||||
*
|
||||
* @returns {Promise} Promise to resolve after timeout
|
||||
**/
|
||||
function delay(ms) {
|
||||
return new Promise((resolve) => {
|
||||
return setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
module.exports.delay = delay;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delay/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,KAAK,CAAE,EAAW;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAa,EAAE,EAAE;QACpC,OAAO,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "delay",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,301 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
let arduino
|
||||
const log = require('log')({quiet : false})
|
||||
const dev = {}
|
||||
|
||||
dev.init = function () {
|
||||
dev.listen()
|
||||
}
|
||||
|
||||
dev.listen = function () {
|
||||
ipcMain.on('profile', (event, arg) => {
|
||||
log.info(`Saving profile ${arg.profile}`, 'SETTINGS', false, false)
|
||||
settings.update('profile', arg.profile)
|
||||
settings.save()
|
||||
})
|
||||
}
|
||||
|
||||
dev.enumerate = async function () {
|
||||
let devices
|
||||
try{
|
||||
devices = await arduino.enumerate()
|
||||
} catch (err) {
|
||||
log.info(err, 'SERIAL', false, true)
|
||||
await delay(1000)
|
||||
return dev.all([])
|
||||
}
|
||||
log.info(`Found ${devices.length} USB devices`, 'SERIAL', true, true)
|
||||
devices = dev.favor(devices)
|
||||
return await dev.all(devices)
|
||||
}
|
||||
|
||||
dev.favor = function (devices) {
|
||||
const past = mcopy.settings.devices.filter(device => {
|
||||
if (device.arduino) {
|
||||
return device
|
||||
}
|
||||
}).map(device => {
|
||||
return device.arduino
|
||||
})
|
||||
if (past.length === 0) {
|
||||
return devices
|
||||
}
|
||||
devices.sort((a, b) => {
|
||||
if (past.indexOf(a) !== -1 && past.indexOf(b) === -1) {
|
||||
return 1
|
||||
} else if (past.indexOf(a) === -1 && past.indexOf(b) !== -1) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return devices
|
||||
}
|
||||
|
||||
dev.distinguish = async function (device) {
|
||||
let connectSuccess
|
||||
let verifySuccess
|
||||
let type
|
||||
|
||||
try {
|
||||
connectSuccess = await arduino.connect('connect', device, true)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return null
|
||||
}
|
||||
|
||||
await delay(2000)
|
||||
|
||||
try {
|
||||
verifySuccess = await arduino.verify()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return null
|
||||
}
|
||||
|
||||
log.info(`Verified ${device} as mcopy device`, 'SERIAL', true, true)
|
||||
|
||||
await delay(1000)
|
||||
|
||||
try {
|
||||
type = await arduino.distinguish()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return null
|
||||
}
|
||||
|
||||
dev.remember('arduino', device, type)
|
||||
log.info(`Determined ${device} to be ${type}`, 'SERIAL', true, true)
|
||||
|
||||
return type
|
||||
}
|
||||
|
||||
dev.fakeProjector = async function () {
|
||||
dev.connected.projector = '/dev/fake'
|
||||
try {
|
||||
await arduino.fakeConnect('projector')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
log.error(`Error connecting to fake PRONECTOR device`, 'SERIAL', true, true)
|
||||
return false
|
||||
}
|
||||
log.info('Connected to fake PROJECTOR device', 'SERIAL', true, true)
|
||||
return true
|
||||
}
|
||||
dev.fakeCamera = async function () {
|
||||
dev.connected.camera = '/dev/fake'
|
||||
try {
|
||||
await arduino.fakeConnect('camera')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
log.error(`Error connecting to fake CAMERA device`, 'SERIAL', true, true)
|
||||
return false
|
||||
}
|
||||
log.info('Connected to fake CAMERA device', 'SERIAL', true, true)
|
||||
return true
|
||||
}
|
||||
dev.fakeLight = async function () {
|
||||
dev.connected.light = '/dev/fake'
|
||||
try {
|
||||
await arduino.fakeConnect('light')
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
log.error(`Error connecting to fake LIGHT device`, 'SERIAL', true, true)
|
||||
return false
|
||||
}
|
||||
log.info('Connected to fake LIGHT device', 'SERIAL', true, true)
|
||||
return true
|
||||
}
|
||||
|
||||
dev.connectDevice = async function (device, type) {
|
||||
let closeSuccess
|
||||
let connectSuccess
|
||||
try {
|
||||
closeSuccess = await arduino.close()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
if (type === 'projector') {
|
||||
dev.connected.projector = device
|
||||
try {
|
||||
connectSuccess = await arduino.connect('projector', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as PROJECTOR`, 'SERIAL', true, true)
|
||||
} else if (type === 'camera') {
|
||||
dev.connected.camera = device
|
||||
try {
|
||||
connectSuccess = await arduino.connect('camera', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as CAMERA`, 'SERIAL', true, true)
|
||||
} else if (type === 'light') {
|
||||
dev.connected.light = device
|
||||
try {
|
||||
connectSuccess = await arduino.connect('light', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as LIGHT`, 'SERIAL', true, true)
|
||||
} else if (type === 'projector,light') {
|
||||
dev.connected.projector = device
|
||||
dev.connected.light = device
|
||||
arduino.alias('light', device)
|
||||
try{
|
||||
connectSuccess = await arduino.connect('projector', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as PROJECTOR + LIGHT`, 'SERIAL', true, true)
|
||||
|
||||
} else if (type === 'projector,camera,light') {
|
||||
dev.connected.projector = device
|
||||
dev.connected.camera = device
|
||||
dev.connected.light = device
|
||||
arduino.alias('camera', device)
|
||||
arduino.alias('light', device)
|
||||
try {
|
||||
connectSuccess = await arduino.connect('projector', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as PROJECTOR + CAMERA + LIGHT`, 'SERIAL', true, true)
|
||||
|
||||
} else if (type === 'projector,camera') {
|
||||
dev.connected.projector = device
|
||||
dev.connected.camera = device
|
||||
arduino.alias('camera', device)
|
||||
try {
|
||||
connectSuccess = await arduino.connect('projector', device, false)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return false
|
||||
}
|
||||
log.info(`Connected to ${device} as PROJECTOR`, 'SERIAL', true, true)
|
||||
}
|
||||
return connectSuccess
|
||||
}
|
||||
|
||||
//Cases for 1 or 2 arduinos connected
|
||||
dev.all = async function (devices) {
|
||||
let c = {}
|
||||
let p = {}
|
||||
let l = {}
|
||||
let type
|
||||
let d
|
||||
|
||||
|
||||
dev.connected = {
|
||||
projector : false,
|
||||
camera : false,
|
||||
light : false
|
||||
}
|
||||
|
||||
let checklist = []
|
||||
|
||||
for (let device of devices) {
|
||||
try {
|
||||
type = await dev.distinguish(device)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
try {
|
||||
await dev.connectDevice(device, type)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return reject(err)
|
||||
}
|
||||
}
|
||||
|
||||
//done checking devices
|
||||
|
||||
if (!dev.connected.projector) {
|
||||
await dev.fakeProjector()
|
||||
}
|
||||
p.arduino = dev.connected.projector
|
||||
if (!dev.connected.camera) {
|
||||
await dev.fakeCamera()
|
||||
}
|
||||
c.arduino = dev.connected.camera
|
||||
|
||||
if (mcopy.settings.camera.intval) {
|
||||
c.intval = mcopy.settings.camera.intval
|
||||
await delay(1000)
|
||||
await cam.connectIntval(null, { connect : true, url : c.intval })
|
||||
}
|
||||
|
||||
if (!dev.connected.light) {
|
||||
await dev.fakeLight()
|
||||
}
|
||||
|
||||
l.arduino = dev.connected.light
|
||||
|
||||
return dev.ready(p, c, l)
|
||||
}
|
||||
|
||||
dev.remember = function (which, device, type) {
|
||||
let deviceEntry
|
||||
const match = mcopy.settings.devices.filter(dev => {
|
||||
if (dev[which] && dev[which] === device) {
|
||||
return dev
|
||||
}
|
||||
})
|
||||
if (match.length === 0) {
|
||||
deviceEntry = {
|
||||
type : type
|
||||
}
|
||||
deviceEntry[which] = device
|
||||
mcopy.settings.devices.push(deviceEntry)
|
||||
settings.update('devices', mcopy.settings.devices)
|
||||
settings.save()
|
||||
}
|
||||
};
|
||||
|
||||
dev.ready = function (projector, camera, light) {
|
||||
mainWindow.webContents.send('ready', {
|
||||
camera,
|
||||
projector,
|
||||
light,
|
||||
profile: mcopy.settings.profile
|
||||
})
|
||||
settings.update('camera', camera)
|
||||
settings.update('projector', projector)
|
||||
settings.update('light', light)
|
||||
settings.save()
|
||||
return true
|
||||
};
|
||||
|
||||
module.exports = function (a) {
|
||||
arduino = a
|
||||
return dev
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "device",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
<a name="Devices"></a>
|
||||
|
||||
## Devices
|
||||
class representing the device discovery features
|
||||
|
||||
**Kind**: global class
|
||||
|
||||
* [Devices](#Devices)
|
||||
* [.init()](#Devices+init)
|
||||
* [.listen()](#Devices+listen)
|
||||
* [.listener()](#Devices+listener)
|
||||
* [.enumerate()](#Devices+enumerate)
|
||||
* [.favor()](#Devices+favor)
|
||||
* [.distinguish()](#Devices+distinguish)
|
||||
* [.fakeProjector()](#Devices+fakeProjector)
|
||||
* [.fakeCamera()](#Devices+fakeCamera)
|
||||
* [.fakeLight()](#Devices+fakeLight)
|
||||
* [.connectDevice()](#Devices+connectDevice)
|
||||
* [.all()](#Devices+all)
|
||||
* [.remember()](#Devices+remember)
|
||||
* [.ready()](#Devices+ready)
|
||||
|
||||
<a name="Devices+init"></a>
|
||||
|
||||
### devices.init()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+listen"></a>
|
||||
|
||||
### devices.listen()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+listener"></a>
|
||||
|
||||
### devices.listener()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+enumerate"></a>
|
||||
|
||||
### devices.enumerate()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+favor"></a>
|
||||
|
||||
### devices.favor()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+distinguish"></a>
|
||||
|
||||
### devices.distinguish()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+fakeProjector"></a>
|
||||
|
||||
### devices.fakeProjector()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+fakeCamera"></a>
|
||||
|
||||
### devices.fakeCamera()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+fakeLight"></a>
|
||||
|
||||
### devices.fakeLight()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+connectDevice"></a>
|
||||
|
||||
### devices.connectDevice()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+all"></a>
|
||||
|
||||
### devices.all()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+remember"></a>
|
||||
|
||||
### devices.remember()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
||||
<a name="Devices+ready"></a>
|
||||
|
||||
### devices.ready()
|
||||
**Kind**: instance method of [<code>Devices</code>](#Devices)
|
|
@ -1,466 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const delay_1 = require("delay");
|
||||
const Log = require("log");
|
||||
/**
|
||||
* class representing the device discovery features
|
||||
*
|
||||
*
|
||||
**/
|
||||
class Devices {
|
||||
/**
|
||||
* Constructor assigns arduino, settings, UI browser window and cam objects
|
||||
* locally to this class for reference.
|
||||
**/
|
||||
constructor(arduino, settings, mainWindow, cam) {
|
||||
this.connected = {};
|
||||
this.arduino = arduino;
|
||||
this.settings = settings;
|
||||
this.mainWindow = mainWindow;
|
||||
this.ui = this.mainWindow.webContents;
|
||||
this.cam = cam;
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
* Initialize the log for "devices". Establish an ipc connection to the UI.
|
||||
* Start listening on that ipc connection.
|
||||
**/
|
||||
async init() {
|
||||
this.log = await Log({ label: 'devices' });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
* Listen to the "profile" channel for messages from the UI.
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on('profile', this.listener.bind(this));
|
||||
}
|
||||
/**
|
||||
* The "profile" channel callback. If a profile is changed, set it in the
|
||||
* local settings object.
|
||||
**/
|
||||
listener(event, arg) {
|
||||
this.log.info(`Saving profile ${arg.profile}`, 'SETTINGS', false, false);
|
||||
this.settings.update('profile', arg.profile);
|
||||
this.settings.save();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async enumerate() {
|
||||
let devices;
|
||||
try {
|
||||
devices = await this.arduino.enumerate();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.warn(err, 'SERIAL', false, true);
|
||||
await delay_1.delay(1000);
|
||||
return this.all([]);
|
||||
}
|
||||
this.log.info(`Found ${devices.length} USB devices`, 'SERIAL', true, true);
|
||||
devices = this.favor(devices);
|
||||
return await this.all(devices);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
favor(devices) {
|
||||
const past = this.settings.state.devices.filter((device) => {
|
||||
if (device.arduino) {
|
||||
return device;
|
||||
}
|
||||
}).map((device) => {
|
||||
return device.arduino;
|
||||
});
|
||||
if (past.length === 0) {
|
||||
return devices;
|
||||
}
|
||||
devices.sort((a, b) => {
|
||||
if (past.indexOf(a) !== -1 && past.indexOf(b) === -1) {
|
||||
return 1;
|
||||
}
|
||||
else if (past.indexOf(a) === -1 && past.indexOf(b) !== -1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
return devices;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async distinguish(device) {
|
||||
let connectSuccess;
|
||||
let verifySuccess;
|
||||
let type;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('connect', device, true);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting', err);
|
||||
return null;
|
||||
}
|
||||
await delay_1.delay(2000);
|
||||
try {
|
||||
verifySuccess = await this.arduino.verify();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error verifying device', err);
|
||||
return null;
|
||||
}
|
||||
this.log.info(`Verified ${device} as mcopy device`, 'SERIAL', true, true);
|
||||
await delay_1.delay(1000);
|
||||
try {
|
||||
type = await this.arduino.distinguish();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error distinguishing device', err);
|
||||
return null;
|
||||
}
|
||||
this.remember('arduino', device, type);
|
||||
this.log.info(`Determined ${device} to be ${type}`, 'SERIAL', true, true);
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async fakeProjector() {
|
||||
this.connected.projector = '/dev/fake';
|
||||
try {
|
||||
await this.arduino.fakeConnect('projector');
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
this.log.error(`Error connecting to fake PRONECTOR device`, 'SERIAL', true, true);
|
||||
return false;
|
||||
}
|
||||
this.log.info('Connected to fake PROJECTOR device', 'SERIAL', true, true);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async fakeCamera() {
|
||||
this.connected.camera = '/dev/fake';
|
||||
try {
|
||||
await this.arduino.fakeConnect('camera');
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
this.log.error(`Error connecting to fake CAMERA device`, 'SERIAL', true, true);
|
||||
return false;
|
||||
}
|
||||
this.log.info('Connected to fake CAMERA device', 'SERIAL', true, true);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async fakeLight() {
|
||||
this.connected.light = '/dev/fake';
|
||||
try {
|
||||
await this.arduino.fakeConnect('light');
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
this.log.error(`Error connecting to fake LIGHT device`, 'SERIAL', true, true);
|
||||
return false;
|
||||
}
|
||||
this.log.info('Connected to fake LIGHT device', 'SERIAL', true, true);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async connectDevice(device, type) {
|
||||
let closeSuccess;
|
||||
let connectSuccess;
|
||||
try {
|
||||
closeSuccess = await this.arduino.close();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error closing arduino connection', err);
|
||||
return false;
|
||||
}
|
||||
if (type === 'projector') {
|
||||
this.connected.projector = device;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to projector', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as PROJECTOR`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'camera') {
|
||||
this.connected.camera = device;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to camera', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as CAMERA`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'light') {
|
||||
this.connected.light = device;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('light', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to light', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as LIGHT`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'projector,light') {
|
||||
this.connected.projector = device;
|
||||
this.connected.light = device;
|
||||
this.arduino.aliasSerial('light', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to projector and light', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as PROJECTOR + LIGHT`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'projector,camera,light') {
|
||||
this.connected.projector = device;
|
||||
this.connected.camera = device;
|
||||
this.connected.light = device;
|
||||
this.arduino.aliasSerial('camera', device);
|
||||
this.arduino.aliasSerial('light', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to projector, camera and light', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA + LIGHT`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'projector,camera') {
|
||||
this.connected.projector = device;
|
||||
this.connected.camera = device;
|
||||
this.arduino.aliasSerial('camera', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to projector and camera', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as PROJECTOR + CAMERA`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'projector_second') {
|
||||
this.connected.projector_second = device;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector_second', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to secondary projector', err);
|
||||
return false;
|
||||
}
|
||||
this.log.info(`Connected to ${device} as PROJECTOR_SECOND`, 'SERIAL', true, true);
|
||||
}
|
||||
else if (type === 'projector,projector_second') {
|
||||
this.connected.projector = device;
|
||||
this.connected.projector_second = device;
|
||||
this.arduino.aliasSerial('projector_second', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('projector', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to projector and secondary projector', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type === 'camera_second') {
|
||||
this.connected.camera_second = device;
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera_second', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (type === 'camera,camera_second') {
|
||||
this.connected.camera = device;
|
||||
this.connected.camera_second = device;
|
||||
this.arduino.aliasSerial('camera_second', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to camera, camera_secondary and projector', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ('camera,projector,projector_second') {
|
||||
this.connected.camera = device;
|
||||
this.connected.projector = device;
|
||||
this.connected.projector_second = device;
|
||||
this.arduino.aliasSerial('projector', device);
|
||||
this.arduino.aliasSerial('projector_second', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to camera, projector and projector_second', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ('camera,camera_second,projector') {
|
||||
this.connected.camera = device;
|
||||
this.connected.camera_second = device;
|
||||
this.connected.projector = device;
|
||||
this.arduino.aliasSerial('camera_second', device);
|
||||
this.arduino.aliasSerial('projector', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to camera, camera_second and projector', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ('camera,camera_second,projector,projector_second') {
|
||||
this.connected.camera = device;
|
||||
this.connected.camera_second = device;
|
||||
this.connected.projector = device;
|
||||
this.connected.projector_second = device;
|
||||
this.arduino.aliasSerial('camera_second', device);
|
||||
this.arduino.aliasSerial('projector', device);
|
||||
this.arduino.aliasSerial('projector_second', device);
|
||||
try {
|
||||
connectSuccess = await this.arduino.connect('camera', device, false);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to camera, camera_second, projector and projector_second', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return connectSuccess;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
//Cases for 1 or 2 arduinos connected
|
||||
async all(devices) {
|
||||
let c = {};
|
||||
let p = {};
|
||||
let l = {};
|
||||
let type;
|
||||
let d;
|
||||
let cs = {};
|
||||
let ps = {};
|
||||
let checklist = [];
|
||||
this.connected = {
|
||||
projector: false,
|
||||
camera: false,
|
||||
light: false,
|
||||
projector_second: false
|
||||
};
|
||||
for (let device of devices) {
|
||||
try {
|
||||
type = await this.distinguish(device);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error distinguishing device', err);
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
await this.connectDevice(device, type);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error connecting to device', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
//done checking devices
|
||||
if (!this.connected.projector) {
|
||||
await this.fakeProjector();
|
||||
}
|
||||
p.arduino = this.connected.projector;
|
||||
if (!this.connected.camera) {
|
||||
await this.fakeCamera();
|
||||
}
|
||||
c.arduino = this.connected.camera;
|
||||
if (!this.connected.light) {
|
||||
await this.fakeLight();
|
||||
}
|
||||
l.arduino = this.connected.light;
|
||||
if (this.connected.camera_second) {
|
||||
cs = { arduino: this.connected.camera_second };
|
||||
}
|
||||
if (this.connected.projector_second) {
|
||||
ps = { arduino: this.connected.projector_second };
|
||||
}
|
||||
if (this.settings.state.camera && this.settings.state.camera.intval) {
|
||||
c.intval = this.settings.state.camera.intval;
|
||||
}
|
||||
return this.ready(p, c, l, cs, ps);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
remember(which, device, type) {
|
||||
let deviceEntry;
|
||||
const match = this.settings.state.devices.filter((dev) => {
|
||||
if (dev[which] && dev[which] === device) {
|
||||
return dev;
|
||||
}
|
||||
});
|
||||
if (match.length === 0) {
|
||||
deviceEntry = {
|
||||
type: type
|
||||
};
|
||||
deviceEntry[which] = device;
|
||||
this.settings.state.devices.push(deviceEntry);
|
||||
this.settings.update('devices', this.settings.state.devices);
|
||||
this.settings.save();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
ready(projector, camera, light, camera_second, projector_second) {
|
||||
let args = {
|
||||
camera,
|
||||
projector,
|
||||
light,
|
||||
profile: this.settings.state.profile
|
||||
};
|
||||
if (projector_second && projector_second.arduino) {
|
||||
args.projector_second = projector_second;
|
||||
this.settings.update('projector_second', projector_second);
|
||||
this.mainWindow.setSize(800, 800);
|
||||
}
|
||||
if (camera_second && camera_second.arduino) {
|
||||
args.camera_second = camera_second;
|
||||
this.settings.update('camera_second', camera_second);
|
||||
if (projector_second && projector_second.arduino) {
|
||||
this.mainWindow.setSize(900, 800);
|
||||
}
|
||||
else {
|
||||
this.mainWindow.setSize(800, 800);
|
||||
}
|
||||
}
|
||||
this.settings.update('camera', camera);
|
||||
this.settings.update('projector', projector);
|
||||
this.settings.update('light', light);
|
||||
this.settings.save();
|
||||
this.ui.send('ready', args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
module.exports = function (arduino, settings, mainWindow, cam) {
|
||||
return new Devices(arduino, settings, mainWindow, cam);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "devices",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* @module display
|
||||
* Provides features for displaying a full screen display of images for the digital module.
|
||||
**/
|
||||
const path_1 = require("path");
|
||||
const url_1 = require("url");
|
||||
const delay_1 = require("delay");
|
||||
const { BrowserWindow } = require('electron');
|
||||
class WebView {
|
||||
constructor(platform, display) {
|
||||
this.opened = false;
|
||||
this.showing = false;
|
||||
this.loadWait = {};
|
||||
const prefs = {
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
allowRunningInsecureContent: false
|
||||
},
|
||||
width: 800,
|
||||
height: 600,
|
||||
minWidth: 800,
|
||||
minHeight: 600 //,
|
||||
//icon: path.join(__dirname, '../../assets/icons/icon.png')
|
||||
};
|
||||
const pagePath = path_1.normalize(path_1.join(__dirname, '../../display.html'));
|
||||
const pageUrl = url_1.format({
|
||||
pathname: pagePath,
|
||||
protocol: 'file:'
|
||||
});
|
||||
if (!display.primary) {
|
||||
prefs.x = display.x + 50;
|
||||
prefs.y = display.y + 50;
|
||||
}
|
||||
this.digitalWindow = new BrowserWindow(prefs);
|
||||
this.digitalWindow.loadURL(pageUrl);
|
||||
if (process.argv.indexOf('-d') !== -1 || process.argv.indexOf('--dev') !== -1) {
|
||||
this.digitalWindow.webContents.openDevTools();
|
||||
}
|
||||
this.digitalWindow.on('closed', () => {
|
||||
this.digitalWindow = null;
|
||||
this.close();
|
||||
});
|
||||
//this.digitalWindow.hide();
|
||||
this.platform = platform;
|
||||
this.display = display;
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.ipc.on('display_load', this.onLoad.bind(this));
|
||||
}
|
||||
async open() {
|
||||
this.digitalWindow.show();
|
||||
this.showing = true;
|
||||
this.opened = true;
|
||||
await this.digitalWindow.setFullScreen(true);
|
||||
await delay_1.delay(300);
|
||||
if (this.platform === 'osx') {
|
||||
await delay_1.delay(300); //give macs an extra 300ms to open fullscreen
|
||||
}
|
||||
}
|
||||
async show(src) {
|
||||
const normalSrc = path_1.normalize(path_1.join(src));
|
||||
if (!this.digitalWindow) {
|
||||
console.warn(`Cannot show "${src}" because window does not exist`);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
this.digitalWindow.webContents.send('display', { src: normalSrc });
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
this.showing = true;
|
||||
return new Promise(function (resolve) {
|
||||
this.loadWait[src] = resolve;
|
||||
}.bind(this));
|
||||
}
|
||||
onLoad(evt, arg) {
|
||||
if (this.loadWait[arg.src]) {
|
||||
this.loadWait[arg.src]();
|
||||
delete this.loadWait[arg.src];
|
||||
}
|
||||
}
|
||||
async focus() {
|
||||
if (!this.digitalWindow) {
|
||||
console.warn(`Cannot show focus screen because window does not exist`);
|
||||
return false;
|
||||
}
|
||||
await delay_1.delay(500);
|
||||
try {
|
||||
this.digitalWindow.webContents.send('focus', { focus: true });
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
async field(ratio) {
|
||||
if (!this.digitalWindow) {
|
||||
console.warn(`Cannot show field guide because window does not exist`);
|
||||
return false;
|
||||
}
|
||||
await delay_1.delay(500);
|
||||
try {
|
||||
this.digitalWindow.webContents.send('field', { field: true, ratio });
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
async meter() {
|
||||
if (!this.digitalWindow) {
|
||||
console.warn(`Cannot show meter screen because window does not exist`);
|
||||
return false;
|
||||
}
|
||||
await delay_1.delay(500);
|
||||
try {
|
||||
this.digitalWindow.webContents.send('meter', { meter: true });
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
hide() {
|
||||
if (this.digitalWindow) {
|
||||
this.digitalWindow.hide();
|
||||
}
|
||||
this.showing = false;
|
||||
return true;
|
||||
}
|
||||
close() {
|
||||
this.hide();
|
||||
if (this.digitalWindow) {
|
||||
this.digitalWindow.close();
|
||||
this.digitalWindow = null;
|
||||
}
|
||||
this.opened = false;
|
||||
this.showing = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class Display {
|
||||
constructor(sys) {
|
||||
this.platform = sys.platform;
|
||||
this.displays = sys.displays;
|
||||
this.tmpdir = path_1.join(sys.tmp, 'mcopy_digital');
|
||||
this.display = this.displays.find((display) => {
|
||||
if (display.primary)
|
||||
return true;
|
||||
});
|
||||
}
|
||||
async open() {
|
||||
if (this.wv && this.wv.display && this.wv.display.id !== this.display.id) {
|
||||
this.wv.close();
|
||||
}
|
||||
if (!this.wv || !this.wv.opened) {
|
||||
this.wv = new WebView(this.platform, this.display);
|
||||
await this.wv.open();
|
||||
}
|
||||
}
|
||||
async show(src) {
|
||||
await this.wv.show(src);
|
||||
}
|
||||
async showPath(pathStr) {
|
||||
return await this.wv.show(pathStr);
|
||||
}
|
||||
hide() {
|
||||
}
|
||||
async close() {
|
||||
return await this.wv.close();
|
||||
}
|
||||
async focus() {
|
||||
return await this.wv.focus();
|
||||
}
|
||||
async field(ratio) {
|
||||
return await this.wv.field(ratio);
|
||||
}
|
||||
async meter() {
|
||||
return await this.wv.meter();
|
||||
}
|
||||
change(id) {
|
||||
this.display = this.displays.find((display) => {
|
||||
if (display.id == id)
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = function (sys) {
|
||||
return new Display(sys);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "display",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<a name="exec"></a>
|
||||
|
||||
## exec(cmd, arg, opts) ⇒ <code>Promise.<{stdout: string, stderr: stderr}></code>
|
||||
Promisified child_process.exec
|
||||
|
||||
**Kind**: global function
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| cmd | | |
|
||||
| arg | | |
|
||||
| opts | | See child_process.exec node docs |
|
||||
| opts.stdout | <code>stream.Writable</code> | If defined, child process stdout will be piped to it. |
|
||||
| opts.stderr | <code>stream.Writable</code> | If defined, child process stderr will be piped to it. |
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
'use strict';
|
||||
const execRaw = require('child_process').exec;
|
||||
/**
|
||||
* Promisified child_process.exec
|
||||
*
|
||||
* @param cmd
|
||||
* @param arg
|
||||
* @param opts See child_process.exec node docs
|
||||
* @param {stream.Writable} opts.stdout If defined, child process stdout will be piped to it.
|
||||
* @param {stream.Writable} opts.stderr If defined, child process stderr will be piped to it.
|
||||
*
|
||||
* @returns {Promise<{ stdout: string, stderr: stderr }>}
|
||||
*/
|
||||
async function exec(...args) {
|
||||
let cmd = args[0];
|
||||
let argz = null;
|
||||
let opts = null;
|
||||
if (typeof args[1] === 'object' && Array.isArray(args[1])) {
|
||||
argz = args[1];
|
||||
}
|
||||
if (argz === null && typeof args[1] === 'object') {
|
||||
opts = args[1];
|
||||
}
|
||||
else if (typeof args[2] === 'object') {
|
||||
opts = args[2];
|
||||
}
|
||||
if (opts === null) {
|
||||
opts = { maxBuffer: 1024 * 1024 };
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = execRaw(cmd, opts, (err, stdout, stderr) => err ? reject(err) : resolve({
|
||||
stdout,
|
||||
stderr
|
||||
}));
|
||||
if (opts.stdout) {
|
||||
child.stdout.pipe(opts.stdout);
|
||||
}
|
||||
if (opts.stderr) {
|
||||
child.stderr.pipe(opts.stderr);
|
||||
}
|
||||
});
|
||||
}
|
||||
module.exports.exec = exec;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exec/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,KAAK,UAAU,IAAI,CAAC,GAAG,IAAe;IACrC,IAAI,GAAG,GAAY,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,IAAI,GAAY,IAAI,CAAA;IACxB,IAAI,IAAI,GAAS,IAAI,CAAA;IAErB,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1D,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACjD,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;SAAM,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;QACvC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACd;IACD,IAAI,IAAI,KAAK,IAAI,EAAE;QAClB,IAAI,GAAG,EAAE,SAAS,EAAG,IAAI,GAAG,IAAI,EAAE,CAAA;KAClC;IACE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EACjC,CAAC,GAAW,EAAE,MAAe,EAAE,MAAc,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7E,MAAM;YACN,MAAM;SACN,CAAC,CAAC,CAAC;QACC,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAClC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "exec",
|
||||
"version": "1.0.0",
|
||||
"description": "<a name=\"exec\"></a>",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<a name="exit"></a>
|
||||
|
||||
## exit(msg, code)
|
||||
Exit process with either a 0 code or other
|
||||
specified failure code. Print message to console first.
|
||||
|
||||
**Kind**: global function
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| msg | <code>string</code> | | Reason for exit |
|
||||
| code | <code>integer</code> | <code>0</code> | process exit code, default 0 |
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
'use strict';
|
||||
/**
|
||||
* Exit process with either a 0 code or other
|
||||
* specified failure code. Print message to console first.
|
||||
*
|
||||
* @param {string} msg Reason for exit
|
||||
* @param {integer} code process exit code, default 0
|
||||
**/
|
||||
function exit(msg, code = 0) {
|
||||
if (code === 0) {
|
||||
console.log(msg);
|
||||
process.exit();
|
||||
}
|
||||
else {
|
||||
console.error(msg);
|
||||
process.exit(code);
|
||||
}
|
||||
}
|
||||
module.exports.exit = exit;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exit/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;IAMI;AAEJ,SAAS,IAAI,CAAE,GAAY,EAAE,OAAgB,CAAC;IAC7C,IAAI,IAAI,KAAK,CAAC,EAAE;QACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,IAAI,EAAE,CAAC;KACf;SAAM;QACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACnB;AACF,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "exit",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,353 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/** @module ffmpeg **/
|
||||
const path_1 = require("path");
|
||||
const fs_extra_1 = require("fs-extra");
|
||||
const exec_1 = require("exec");
|
||||
const child_process_1 = require("child_process");
|
||||
async function spawnAsync(bin, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = child_process_1.spawn(bin, args);
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
child.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
return resolve({ stdout, stderr });
|
||||
}
|
||||
else {
|
||||
console.error(`Process exited with code: ${code}`);
|
||||
console.error(stderr);
|
||||
return reject(stderr);
|
||||
}
|
||||
});
|
||||
child.stdout.on('data', (data) => {
|
||||
stdout += data;
|
||||
});
|
||||
child.stderr.on('data', (data) => {
|
||||
stderr += data;
|
||||
});
|
||||
return child;
|
||||
});
|
||||
}
|
||||
/** @class FFMPEG **/
|
||||
class FFMPEG {
|
||||
/**
|
||||
* @constructor
|
||||
* Creates an ffmpeg class
|
||||
*
|
||||
* @param {object} sys System object to be used to get temp directory
|
||||
**/
|
||||
constructor(sys) {
|
||||
this.id = 'ffmpeg';
|
||||
this.onProgress = () => { };
|
||||
this.bin = sys.deps.ffmpeg;
|
||||
this.TMPDIR = path_1.join(sys.tmp, 'mcopy_digital');
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
* Async method to call async functions from constructor
|
||||
**/
|
||||
async init() {
|
||||
const Log = require('log');
|
||||
this.log = await Log({ label: this.id });
|
||||
await this.checkDir();
|
||||
}
|
||||
/**
|
||||
* Add padding to a number to 5 places. Return a string.
|
||||
*
|
||||
* @param {integer} i Integer to pad
|
||||
*
|
||||
* @returns {string} Padded string
|
||||
**/
|
||||
padded_frame(i) {
|
||||
let len = (i + '').length;
|
||||
let str = i + '';
|
||||
for (let x = 0; x < 8 - len; x++) {
|
||||
str = '0' + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
/**
|
||||
* Parse the stderr output of ffmpeg
|
||||
*
|
||||
* @param {string} line Stderr line
|
||||
**/
|
||||
parseStderr(line) {
|
||||
//frame= 6416 fps= 30 q=31.0 size= 10251kB time=00:03:34.32 bitrate= 391.8kbits/s speed= 1x
|
||||
let obj = {};
|
||||
if (line.substring(0, 'frame='.length) === 'frame=') {
|
||||
try {
|
||||
obj.frame = line.split('frame=')[1].split('fps=')[0];
|
||||
obj.frame = parseInt(obj.frame);
|
||||
obj.fps = line.split('fps=')[1].split('q=')[0];
|
||||
obj.fps = parseFloat(obj.fps);
|
||||
obj.time = line.split('time=')[1].split('bitrate=')[0];
|
||||
obj.speed = line.split('speed=')[1].trim().replace('x', '');
|
||||
obj.speed = parseFloat(obj.speed);
|
||||
obj.size = line.split('size=')[1].split('time=')[0].trim();
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
console.log(line);
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* Render a single frame from a video or image to a png.
|
||||
*
|
||||
* @param {object} state State object containing file data
|
||||
* @param {object} light Object containing color information for frame
|
||||
*
|
||||
* @returns {string} Path of frame
|
||||
**/
|
||||
async frame(state, light) {
|
||||
const frameNum = state.frame;
|
||||
const video = state.path;
|
||||
const w = state.info.width;
|
||||
const h = state.info.height;
|
||||
const padded = this.padded_frame(frameNum);
|
||||
let ext = 'png';
|
||||
let rgb = light.color;
|
||||
let rgba = {};
|
||||
let tmpoutput;
|
||||
let cmd;
|
||||
let output;
|
||||
let fileExists = false;
|
||||
let scale = '';
|
||||
if (w && h) {
|
||||
scale = `,scale=${w}:${h}`;
|
||||
}
|
||||
tmpoutput = path_1.join(this.TMPDIR, `${state.hash}-export-${padded}.${ext}`);
|
||||
try {
|
||||
fileExists = await fs_extra_1.exists(tmpoutput);
|
||||
}
|
||||
catch (err) {
|
||||
//
|
||||
}
|
||||
if (fileExists) {
|
||||
this.log.info(`File ${tmpoutput} exists`);
|
||||
return tmpoutput;
|
||||
}
|
||||
//
|
||||
cmd = `${this.bin} -y -i "${video}" -vf "select='gte(n\\,${frameNum})'${scale}" -vframes 1 -compression_algo raw -pix_fmt rgb24 -crf 0 "${tmpoutput}"`;
|
||||
//cmd2 = `${this.convert} "${tmpoutput}" -resize ${w}x${h} -size ${w}x${h} xc:"rgb(${rgb[0]},${rgb[1]},${rgb[2]})" +swap -compose Darken -composite "${tmpoutput}"`;
|
||||
//ffmpeg -i "${video}" -ss 00:00:07.000 -vframes 1 "export-${time}.jpg"
|
||||
//ffmpeg -i "${video}" -compression_algo raw -pix_fmt rgb24 "export-%05d.tiff"
|
||||
//-vf "select=gte(n\,${frame})" -compression_algo raw -pix_fmt rgb24 "export-${padded}.png"
|
||||
try {
|
||||
this.log.info(cmd);
|
||||
output = await exec_1.exec(cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
if (output && output.stdout)
|
||||
this.log.info(`"${output.stdout.trim()}"`);
|
||||
if (rgb[0] !== 255 || rgb[1] !== 255 || rgb[2] !== 255) {
|
||||
rgb = rgb.map((e) => {
|
||||
return parseInt(e);
|
||||
});
|
||||
rgba = { r: rgb[0], g: rgb[1], b: rgb[2], a: 255 };
|
||||
try {
|
||||
//await Frame.blend(tmpoutput, rgba, tmpoutput);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
return tmpoutput;
|
||||
}
|
||||
/**
|
||||
* Render all frames in a video to the temp directory.
|
||||
* Not in use.
|
||||
*
|
||||
* @param {string} video Path to video
|
||||
* @param {object} obj Not sure
|
||||
*
|
||||
* @returns {?}
|
||||
**/
|
||||
async frames(state) {
|
||||
const video = state.path;
|
||||
const w = state.info.width;
|
||||
const h = state.info.height;
|
||||
const tmppath = this.TMPDIR;
|
||||
let ext = 'png';
|
||||
let tmpoutput = path_1.join(tmppath, `${state.hash}-export-%08d.${ext}`);
|
||||
let args;
|
||||
let output;
|
||||
let estimated = -1;
|
||||
//cmd = `${this.bin} -y -i "${video}" -vf "${scale}" -compression_algo raw -pix_fmt rgb24 -crf 0 "${tmpoutput}"`;
|
||||
args = [
|
||||
'-y',
|
||||
'-i', video
|
||||
];
|
||||
if (w && h) {
|
||||
args.push('-vf');
|
||||
args.push(`scale=${w}:${h}`);
|
||||
}
|
||||
args = args.concat([
|
||||
'-compression_algo', 'raw',
|
||||
'-pix_fmt', 'rgb24',
|
||||
'-crf', '0',
|
||||
tmpoutput
|
||||
]);
|
||||
//console.dir(args)
|
||||
//console.dir(state)
|
||||
try {
|
||||
await fs_extra_1.mkdir(tmppath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code && err.code === 'EEXIST') {
|
||||
//directory exists
|
||||
}
|
||||
else {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
//ffmpeg -i "${video}" -compression_algo raw -pix_fmt rgb24 "${tmpoutput}"
|
||||
return new Promise((resolve, reject) => {
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
this.log.info(`${this.bin} ${args.join(' ')}`);
|
||||
this.child = child_process_1.spawn(this.bin, args);
|
||||
this.child.on('exit', (code) => {
|
||||
//console.log('GOT TO EXIT');
|
||||
if (code === 0) {
|
||||
console.log(stderr);
|
||||
console.log(stdout);
|
||||
return resolve(true);
|
||||
}
|
||||
else {
|
||||
console.error(`Process exited with code: ${code}`);
|
||||
console.error(stderr);
|
||||
return reject(stderr + stdout);
|
||||
}
|
||||
});
|
||||
this.child.stdout.on('data', (data) => {
|
||||
const line = data.toString();
|
||||
stdout += line;
|
||||
});
|
||||
this.child.stderr.on('data', (data) => {
|
||||
const line = data.toString();
|
||||
const obj = this.parseStderr(line);
|
||||
if (obj.frame && state.frames) {
|
||||
obj.progress = obj.frame / state.frames;
|
||||
}
|
||||
if (obj.frame && obj.speed && state.frames && state.info.fps) {
|
||||
//scale by speed
|
||||
obj.remaining = ((state.frames - obj.frame) / state.info.fps) / obj.speed;
|
||||
obj.estimated = state.info.seconds / obj.speed;
|
||||
if (obj.estimated > estimated) {
|
||||
estimated = obj.estimated;
|
||||
}
|
||||
}
|
||||
if (obj.frame) {
|
||||
//log.info(`${input.name} ${obj.frame}/${input.frames} ${Math.round(obj.progress * 1000) / 10}% ${Math.round(obj.remaining)} seconds remaining of ${Math.round(obj.estimated)}`);
|
||||
this.onProgress(obj);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
cancel() {
|
||||
if (this.child) {
|
||||
this.child.kill();
|
||||
this.log.info(`Stopped exporting sequence with ffmpeg`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clears a specific frame from the tmp directory
|
||||
*
|
||||
* @param {integer} frame Integer of frame to clear
|
||||
*
|
||||
* @returns {boolean} True if successful, false if not
|
||||
**/
|
||||
async clear(state) {
|
||||
const padded = this.padded_frame(state.frame);
|
||||
let ext = 'png';
|
||||
let tmppath;
|
||||
let fileExists;
|
||||
tmppath = path_1.join(this.TMPDIR, `${state.hash}-export-${padded}.${ext}`);
|
||||
try {
|
||||
fileExists = await fs_extra_1.exists(tmppath);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
if (!fileExists)
|
||||
return false;
|
||||
try {
|
||||
await fs_extra_1.unlink(tmppath);
|
||||
this.log.info(`Cleared frame ${tmppath}`);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Deletes all frames in temp directory.
|
||||
*
|
||||
**/
|
||||
async clearAll() {
|
||||
const tmppath = this.TMPDIR;
|
||||
let files;
|
||||
try {
|
||||
files = await fs_extra_1.readdir(tmppath);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
files = files.filter((file) => {
|
||||
if (file.indexOf('-export-') !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (files) {
|
||||
files.forEach(async (file, index) => {
|
||||
try {
|
||||
await fs_extra_1.unlink(path_1.join(tmppath, file));
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if mcopy temp directory exists. If it doesn't,
|
||||
* creates it.
|
||||
**/
|
||||
async checkDir() {
|
||||
let fileExists;
|
||||
try {
|
||||
fileExists = await fs_extra_1.exists(this.TMPDIR);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error checking for tmp dir', err);
|
||||
}
|
||||
if (!fileExists) {
|
||||
try {
|
||||
await fs_extra_1.mkdir(this.TMPDIR);
|
||||
this.log.info(`Created tmpdir ${this.TMPDIR}`);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error creating tmp dir', err);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await this.clearAll();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = (sys) => {
|
||||
return new FFMPEG(sys);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "ffmpeg",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/** @module FFPROBE **/
|
||||
const fs_extra_1 = require("fs-extra");
|
||||
const path_1 = require("path");
|
||||
const exec_1 = require("exec");
|
||||
//const spawn = require('spawn');
|
||||
//const exit = require('exit');
|
||||
class FFPROBE {
|
||||
constructor(sys) {
|
||||
this.bin = sys.deps.ffprobe;
|
||||
}
|
||||
/**
|
||||
* Parse the fps entry into a float representing the fps of a video
|
||||
**/
|
||||
parseFps(fpsStr) {
|
||||
let fps = 30.0;
|
||||
let parts;
|
||||
if (fpsStr.indexOf('/') !== -1) {
|
||||
parts = fpsStr.split('/');
|
||||
fps = parseFloat(parts[0]) / parseFloat(parts[1]);
|
||||
}
|
||||
else {
|
||||
fps = parseFloat(fpsStr);
|
||||
}
|
||||
return fps;
|
||||
}
|
||||
/**
|
||||
* Get info on a video in json format. Use for filmout.
|
||||
*
|
||||
* @param {string} video Path to video
|
||||
*
|
||||
* @returns {object} Video info in an object
|
||||
**/
|
||||
async info(video) {
|
||||
const cmd = `${this.bin} -v quiet -print_format json -show_format -show_streams "${video}"`;
|
||||
let fileExists;
|
||||
let raw;
|
||||
let json;
|
||||
let vid; //whether video has stream with video data
|
||||
try {
|
||||
fileExists = await fs_extra_1.exists(video);
|
||||
}
|
||||
catch (err) {
|
||||
return exit(err, 5);
|
||||
}
|
||||
if (!fileExists) {
|
||||
//return exit(`File ${video} does not exist`, 6);
|
||||
console.error(new Error(`File ${video} does not exist`));
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
console.log(cmd);
|
||||
raw = await exec_1.exec(cmd);
|
||||
}
|
||||
catch (err) {
|
||||
//return exit(err, 7);
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
json = JSON.parse(raw.stdout);
|
||||
}
|
||||
catch (err) {
|
||||
return raw.stdout;
|
||||
}
|
||||
if (json.format && json.format.duration) {
|
||||
json.seconds = parseFloat(json.format.duration);
|
||||
}
|
||||
if (json && json.streams) {
|
||||
vid = json.streams.find((stream) => {
|
||||
if (stream.width && stream.height)
|
||||
return stream;
|
||||
});
|
||||
}
|
||||
if (vid) {
|
||||
json.width = vid.width;
|
||||
json.height = vid.height;
|
||||
json.fps = this.parseFps(vid.r_frame_rate);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
/**
|
||||
* Count the number of frames in the video using one of two methods.
|
||||
* The first uses -select_streams and is very fast. The second uses
|
||||
* -count_frames and is VERY slow.
|
||||
*
|
||||
* @param {string} video Path to video
|
||||
*
|
||||
* @returns {integer} Number of frames in video
|
||||
**/
|
||||
async frames(video) {
|
||||
const ext = path_1.extname(video.toLowerCase());
|
||||
let cmd = `${this.bin} -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 "${video}"`;
|
||||
let backup_cmd = `${this.bin} -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 "${video}"`;
|
||||
let gif_cmd = `identify -format "%n\n" "${video}" | head -1`;
|
||||
let fileExists;
|
||||
let raw;
|
||||
let frames;
|
||||
try {
|
||||
fileExists = await fs_extra_1.exists(video);
|
||||
}
|
||||
catch (err) {
|
||||
//return exit(err, 5);
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
if (!fileExists) {
|
||||
//return exit(`File ${video} does not exist`, 6);
|
||||
console.error(new Error(`File ${video} does not exist`));
|
||||
return false;
|
||||
}
|
||||
if (ext === '.mkv') {
|
||||
cmd = backup_cmd;
|
||||
}
|
||||
else if (ext === '.gif') {
|
||||
cmd = gif_cmd;
|
||||
}
|
||||
try {
|
||||
console.log(cmd);
|
||||
raw = await exec_1.exec(cmd);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
frames = parseInt(raw.stdout);
|
||||
}
|
||||
catch (err) {
|
||||
return raw.stdout;
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
}
|
||||
/*
|
||||
function map (obj : any) {
|
||||
console.dir(obj);
|
||||
}
|
||||
*/
|
||||
module.exports = (sys) => {
|
||||
return new FFPROBE(sys);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ffprobe/index.ts"],"names":[],"mappings":"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"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "ffprobe",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<a name="Digital"></a>
|
||||
|
||||
## Digital
|
||||
**Kind**: global class
|
||||
|
||||
* [Digital](#Digital)
|
||||
* [.init()](#Digital+init)
|
||||
* [.listen()](#Digital+listen)
|
||||
* [.set()](#Digital+set)
|
||||
* [.move()](#Digital+move)
|
||||
* [.start()](#Digital+start)
|
||||
* [.end()](#Digital+end)
|
||||
* [.connectDigital()](#Digital+connectDigital)
|
||||
|
||||
<a name="Digital+init"></a>
|
||||
|
||||
### digital.init()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+listen"></a>
|
||||
|
||||
### digital.listen()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+set"></a>
|
||||
|
||||
### digital.set()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+move"></a>
|
||||
|
||||
### digital.move()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+start"></a>
|
||||
|
||||
### digital.start()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+end"></a>
|
||||
|
||||
### digital.end()
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
||||
<a name="Digital+connectDigital"></a>
|
||||
|
||||
### digital.connectDigital()
|
||||
Use a file as the "digital" source on "projector"
|
||||
|
||||
**Kind**: instance method of [<code>Digital</code>](#Digital)
|
|
@ -1,382 +0,0 @@
|
|||
'use strict';
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const animated_gif_detector_1 = __importDefault(require("animated-gif-detector"));
|
||||
const path_1 = require("path");
|
||||
const fs_extra_1 = require("fs-extra");
|
||||
const delay_1 = require("delay");
|
||||
const crypto_1 = require("crypto");
|
||||
const frame_1 = __importDefault(require("frame"));
|
||||
/**
|
||||
* @module FilmOut
|
||||
**/
|
||||
class FilmOut {
|
||||
/**
|
||||
* @constructor
|
||||
* Builds FilmOut class with display, ffmpeg, ffprobe, ui and light as internal properties.
|
||||
*
|
||||
* @param {object} display Display object for showing frames
|
||||
* @param {object} ffmpeg FFMPEG wrapper
|
||||
* @param {object} ffprobe FFPROBE wrapper for file info
|
||||
* @param {object} ui Electron ui object
|
||||
* @param {object} light Light device object
|
||||
**/
|
||||
constructor(display, ffmpeg, ffprobe, ui, light) {
|
||||
this.id = 'filmout';
|
||||
this.videoExtensions = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4'];
|
||||
this.stillExtensions = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
|
||||
this.gifExtension = '.gif';
|
||||
this.state = {
|
||||
frame: 0,
|
||||
frames: 0,
|
||||
still: false,
|
||||
path: null,
|
||||
fileName: null,
|
||||
info: {},
|
||||
dir: true,
|
||||
enabled: false
|
||||
};
|
||||
this.display = display;
|
||||
this.ffmpeg = ffmpeg;
|
||||
this.ffprobe = ffprobe;
|
||||
this.ui = ui;
|
||||
this.light = light;
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
* Async function for requiring log, ipcMain and bind events.
|
||||
**/
|
||||
async init() {
|
||||
const Log = require('log');
|
||||
this.log = await Log({ label: this.id });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on(this.id, this.onConnect.bind(this));
|
||||
this.ipc.on('focus', this.focus.bind(this));
|
||||
this.ipc.on('field', this.field.bind(this));
|
||||
this.ipc.on('meter', this.meter.bind(this));
|
||||
this.ipc.on('filmout_close', this.close.bind(this));
|
||||
this.ipc.on('preview', this.preview.bind(this));
|
||||
this.ipc.on('preview_frame', this.previewFrame.bind(this));
|
||||
this.ipc.on('display', this.onDisplay.bind(this));
|
||||
this.ipc.on('pre_export', this.onPreExport.bind(this));
|
||||
this.ffmpeg.onProgress = (obj) => {
|
||||
this.ui.send('pre_export_progress', { progress: obj });
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a hash of a string.
|
||||
*
|
||||
* @param {string} data Data to produce hash of
|
||||
*/
|
||||
hash(data) {
|
||||
return crypto_1.createHash('sha1').update(data).digest('hex');
|
||||
}
|
||||
/**
|
||||
* Sets filmout direction.
|
||||
*
|
||||
* @param {boolean} dir Direction of filmout
|
||||
**/
|
||||
set(dir) {
|
||||
this.state.dir = dir;
|
||||
}
|
||||
/**
|
||||
* Moves filmout a frame at a time.
|
||||
**/
|
||||
async move() {
|
||||
let start = +new Date();
|
||||
if (this.state.still) {
|
||||
return false;
|
||||
}
|
||||
if (this.state.dir) {
|
||||
this.state.frame++;
|
||||
}
|
||||
else {
|
||||
this.state.frame--;
|
||||
}
|
||||
if (this.state.frame < 1) {
|
||||
this.state.frame = 1;
|
||||
}
|
||||
return (+new Date()) - start;
|
||||
}
|
||||
/**
|
||||
* Begin the process of exporting single frames from the video for display.
|
||||
**/
|
||||
async start() {
|
||||
let path;
|
||||
try {
|
||||
path = await this.ffmpeg.frame(this.state, this.light.state);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
throw err;
|
||||
}
|
||||
await this.display.show(path);
|
||||
await delay_1.delay(20);
|
||||
}
|
||||
/**
|
||||
* Ends the filmout process and closes the display.
|
||||
**/
|
||||
async end() {
|
||||
await delay_1.delay(20);
|
||||
this.display.hide();
|
||||
}
|
||||
/**
|
||||
* Use a video file as a film out source on "projector"
|
||||
*
|
||||
* @param {object} evt Original connect event
|
||||
* @param {object} arg Arguments from ipc message
|
||||
**/
|
||||
async onConnect(evt, arg) {
|
||||
let frames = 0;
|
||||
let isAnimated = false;
|
||||
let info;
|
||||
let ext;
|
||||
ext = path_1.extname(arg.fileName.toLowerCase());
|
||||
if (ext === this.gifExtension) {
|
||||
try {
|
||||
isAnimated = await this.isGifAnimated(arg.path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
await this.ui.send(this.id, { valid: false });
|
||||
return false;
|
||||
}
|
||||
this.state.still = !isAnimated;
|
||||
}
|
||||
else if (this.stillExtensions.indexOf(ext) !== -1) {
|
||||
this.state.still = true;
|
||||
}
|
||||
else if (this.videoExtensions.indexOf(ext) !== -1) {
|
||||
this.state.still = false;
|
||||
}
|
||||
else {
|
||||
this.log.error(`File is not of a valid file type`, 'FILMOUT', true, true);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await this.ffmpeg.clearAll();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
throw err;
|
||||
}
|
||||
if (this.state.still) {
|
||||
try {
|
||||
info = await this.stillInfo(arg.path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
this.state.enabled = false;
|
||||
await this.ui.send(this.id, { valid: false });
|
||||
return false;
|
||||
}
|
||||
frames = 1;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
info = await this.ffprobe.info(arg.path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
this.state.enabled = false;
|
||||
await this.ui.send(this.id, { valid: false });
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
frames = await this.ffprobe.frames(arg.path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
this.state.enabled = false;
|
||||
await this.ui.send(this.id, { valid: false });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.state.frame = 0;
|
||||
this.state.path = arg.path;
|
||||
this.state.fileName = arg.fileName;
|
||||
this.state.frames = frames;
|
||||
this.state.info = info;
|
||||
this.state.hash = this.hash(arg.path);
|
||||
if (info.seconds) {
|
||||
this.state.seconds = info.seconds;
|
||||
}
|
||||
else if (info.fps && frames) {
|
||||
this.state.seconds = frames / info.fps;
|
||||
}
|
||||
this.log.info(`Opened ${this.state.fileName}`, 'FILMOUT', true, true);
|
||||
this.log.info(`Frames : ${frames}`, 'FILMOUT', true, true);
|
||||
this.state.enabled = true;
|
||||
return await this.ui.send(this.id, { valid: true, state: JSON.stringify(this.state) });
|
||||
}
|
||||
/**
|
||||
* Pre-export all frames from video for display.
|
||||
*
|
||||
* @param {object} evt IPC event
|
||||
* @param {object} arg IPC args
|
||||
*/
|
||||
async onPreExport(evt, arg) {
|
||||
if (!this.state.path) {
|
||||
return await this.ui.send('pre_export', { complete: false, err: 'No file to pre export.' });
|
||||
}
|
||||
try {
|
||||
await this.ffmpeg.frames(this.state);
|
||||
}
|
||||
catch (err) {
|
||||
return await this.ui.send('pre_export', { complete: false, err });
|
||||
}
|
||||
return await this.ui.send('pre_export', { complete: true });
|
||||
}
|
||||
/**
|
||||
* Return true if gif is animated, false if it is a still
|
||||
*
|
||||
* @param {string} pathStr Path to gif to check
|
||||
*
|
||||
* @returns {boolean} Whether or not gif is animated
|
||||
**/
|
||||
async isGifAnimated(pathStr) {
|
||||
let gifBuffer;
|
||||
try {
|
||||
gifBuffer = await fs_extra_1.readFile(pathStr);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
return false;
|
||||
}
|
||||
return animated_gif_detector_1.default(gifBuffer);
|
||||
}
|
||||
/**
|
||||
* Return information on a still image using the sharp module
|
||||
*
|
||||
* @param {string} pathStr Path to gif to check
|
||||
*
|
||||
* @returns {object} Info about still from sharp
|
||||
**/
|
||||
async stillInfo(pathStr) {
|
||||
let info;
|
||||
try {
|
||||
info = await frame_1.default.info(pathStr);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
/**
|
||||
* Preview a frame from the selected video.
|
||||
*
|
||||
* @param {object} evt Original event
|
||||
* @param {object} arg Arguments from message
|
||||
**/
|
||||
async previewFrame(evt, arg) {
|
||||
const state = JSON.parse(JSON.stringify(this.state));
|
||||
let path;
|
||||
state.frame = arg.frame;
|
||||
try {
|
||||
path = await this.ffmpeg.frame(state, { color: [255, 255, 255] });
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
;
|
||||
throw err;
|
||||
}
|
||||
this.ui.send('preview_frame', { path, frame: arg.frame });
|
||||
}
|
||||
/**
|
||||
* Open a single frame in a display window to preview filmout.
|
||||
*
|
||||
* @param {object} evt Original event
|
||||
* @param {object} arg Arguments from message
|
||||
**/
|
||||
async preview(evt, arg) {
|
||||
const state = JSON.parse(JSON.stringify(this.state));
|
||||
let path;
|
||||
state.frame = arg.frame;
|
||||
this.log.info(`Previewing frame ${state.frame} of ${state.fileName}`);
|
||||
try {
|
||||
path = await this.ffmpeg.frame(state, { color: [255, 255, 255] });
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
await this.display.open();
|
||||
await this.display.show(path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async focus(evt, arg) {
|
||||
this.log.info(`Showing focus screen`);
|
||||
try {
|
||||
await this.display.open();
|
||||
await this.display.focus();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async field(evt, arg) {
|
||||
const ratio = arg.ratio;
|
||||
this.log.info(`Showing field guide screen`);
|
||||
try {
|
||||
await this.display.open();
|
||||
await this.display.field(ratio);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async meter(evt, arg) {
|
||||
this.log.info(`Showing meter screen`);
|
||||
try {
|
||||
await this.display.open();
|
||||
await this.display.meter();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async close(evt, arg) {
|
||||
try {
|
||||
await this.display.hide();
|
||||
await this.display.close();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err, 'FILMOUT', true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
onDisplay(evt, arg) {
|
||||
this.display.change(arg.display);
|
||||
this.log.info(`Changing the display to ${arg.display}`);
|
||||
}
|
||||
}
|
||||
module.exports = (display, ffmpeg, ffprobe, ui, light) => {
|
||||
return new FilmOut(display, ffmpeg, ffprobe, ui, light);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "digital",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
'use strict';
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const jimp_1 = __importDefault(require("jimp"));
|
||||
class Frame {
|
||||
static async info(imagePath) {
|
||||
let image;
|
||||
try {
|
||||
image = await jimp_1.default.read(imagePath);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return {
|
||||
width: image.bitmap.width,
|
||||
height: image.bitmap.height
|
||||
};
|
||||
}
|
||||
static async solidColor(width, height, color) {
|
||||
//@ts-ignore
|
||||
const colorInt = jimp_1.default.rgbaToInt(color.r, color.g, color.b, color.a);
|
||||
return new Promise((resolve, reject) => {
|
||||
return new jimp_1.default(width, height, colorInt, (err, image) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(image);
|
||||
});
|
||||
});
|
||||
}
|
||||
static async blend(inPath, color, imagePath) {
|
||||
//cmd2 = `${this.convert} "${tmpoutput}" -resize ${w}x${h} -size ${w}x${h} xc:"rgb(${rgb[0]},${rgb[1]},${rgb[2]})" +swap -compose Darken -composite "${tmpoutput}"`;
|
||||
const options = {
|
||||
mode: jimp_1.default.BLEND_DARKEN,
|
||||
opacitySource: 1.0,
|
||||
opacityDest: 1.0
|
||||
};
|
||||
let width;
|
||||
let height;
|
||||
let bottom;
|
||||
let top;
|
||||
try {
|
||||
top = await jimp_1.default.read(inPath);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
width = top.bitmap.width;
|
||||
height = top.bitmap.height;
|
||||
try {
|
||||
bottom = await Frame.solidColor(width, height, color);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
bottom.composite(top, 0, 0, options);
|
||||
try {
|
||||
await bottom.writeAsync(imagePath);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return imagePath;
|
||||
}
|
||||
}
|
||||
exports.default = Frame;
|
||||
module.exports = Frame;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/frame/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;AAEb,gDAAwB;AASxB,MAAqB,KAAK;IACzB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAE,SAAkB;QACpC,IAAI,KAAW,CAAC;QAChB,IAAI;YACH,KAAK,GAAG,MAAM,cAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SACnC;QAAC,OAAO,GAAG,EAAE;YACb,MAAM,GAAG,CAAC;SACV;QACD,OAAO;YACN,KAAK,EAAG,KAAK,CAAC,MAAM,CAAC,KAAK;YAC1B,MAAM,EAAG,KAAK,CAAC,MAAM,CAAC,MAAM;SAC5B,CAAC;IACH,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAE,KAAc,EAAE,MAAe,EAAE,KAAY;QACrE,YAAY;QACZ,MAAM,QAAQ,GAAY,cAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAkB,EAAE,MAAiB,EAAE,EAAE;YAC5D,OAAO,IAAI,cAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBACrD,IAAI,GAAG,EAAE;oBACR,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;iBAClB;gBACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,CAAE,MAAY,EAAE,KAAY,EAAE,SAAkB;QACjE,oKAAoK;QACpK,MAAM,OAAO,GAAS;YACrB,IAAI,EAAE,cAAI,CAAC,YAAY;YACvB,aAAa,EAAE,GAAG;YAClB,WAAW,EAAE,GAAG;SAChB,CAAC;QACF,IAAI,KAAc,CAAC;QACnB,IAAI,MAAe,CAAC;QACpB,IAAI,MAAY,CAAC;QACjB,IAAI,GAAS,CAAC;QAEd,IAAI;YACH,GAAG,GAAG,MAAM,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC9B;QAAC,OAAO,GAAG,EAAE;YACb,MAAM,GAAG,CAAC;SACV;QAED,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;QAE3B,IAAI;YACH,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACtD;QAAC,OAAO,GAAG,EAAE;YACb,MAAM,GAAG,CAAC;SACV;QAED,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAErC,IAAI;YACH,MAAM,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;SACnC;QAAC,OAAO,GAAG,EAAE;YACb,MAAM,GAAG,CAAC;SACV;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AA/DD,wBA+DC;AAED,MAAM,CAAC,OAAO,GAAG,KAAK,CAAA"}
|
|
@ -1,68 +0,0 @@
|
|||
'use strict';
|
||||
class Intval {
|
||||
constructor(url) {
|
||||
this._baseUrl = `http://${url}`;
|
||||
this.req = require('request');
|
||||
}
|
||||
async move() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeStart = +new Date();
|
||||
const url = `${this._baseUrl}/frame`;
|
||||
//console.log(url)
|
||||
return this.req(url, (err, res, body) => {
|
||||
let ms = (+new Date()) - timeStart;
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(ms);
|
||||
});
|
||||
});
|
||||
}
|
||||
async setDir(dir) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeStart = +new Date();
|
||||
const url = `${this._baseUrl}/dir?dir=${dir}`;
|
||||
//console.log(url)
|
||||
return this.req(url, (err, res, body) => {
|
||||
let ms = (+new Date()) - timeStart;
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(ms);
|
||||
});
|
||||
});
|
||||
}
|
||||
async setExposure(exposure, cb) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeStart = +new Date();
|
||||
const url = `${this._baseUrl}/exposure?exposure=${exposure}`;
|
||||
//console.log(url)
|
||||
return this.req(url, (err, res, body) => {
|
||||
let ms = (+new Date()) - timeStart;
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
return resolve(ms);
|
||||
});
|
||||
});
|
||||
}
|
||||
connect(cb) {
|
||||
const timeStart = +new Date();
|
||||
const url = `${this._baseUrl}/status`;
|
||||
const opts = {
|
||||
method: 'GET',
|
||||
uri: url,
|
||||
timeout: 5000
|
||||
};
|
||||
this.req(opts, (err, res, body) => {
|
||||
let ms = (+new Date()) - timeStart;
|
||||
if (err) {
|
||||
//console.error(err)
|
||||
return cb(err, ms);
|
||||
}
|
||||
cb(null, ms, body);
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports.Intval = Intval;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/intval/index.ts"],"names":[],"mappings":"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"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "intval",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<a name="Light"></a>
|
||||
|
||||
## Light
|
||||
**Kind**: global class
|
||||
|
||||
* [Light](#Light)
|
||||
* [.init()](#Light+init)
|
||||
* [.listen()](#Light+listen)
|
||||
* [.listener()](#Light+listener)
|
||||
* [.set()](#Light+set)
|
||||
* [.end()](#Light+end)
|
||||
|
||||
<a name="Light+init"></a>
|
||||
|
||||
### light.init()
|
||||
**Kind**: instance method of [<code>Light</code>](#Light)
|
||||
<a name="Light+listen"></a>
|
||||
|
||||
### light.listen()
|
||||
**Kind**: instance method of [<code>Light</code>](#Light)
|
||||
<a name="Light+listener"></a>
|
||||
|
||||
### light.listener()
|
||||
**Kind**: instance method of [<code>Light</code>](#Light)
|
||||
<a name="Light+set"></a>
|
||||
|
||||
### light.set()
|
||||
**Kind**: instance method of [<code>Light</code>](#Light)
|
||||
<a name="Light+end"></a>
|
||||
|
||||
### light.end()
|
||||
**Kind**: instance method of [<code>Light</code>](#Light)
|
|
@ -1,97 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const delay_1 = require("delay");
|
||||
const Log = require("log");
|
||||
class Light {
|
||||
/**
|
||||
*
|
||||
**/
|
||||
constructor(arduino, cfg, ui) {
|
||||
this.state = { color: [0, 0, 0] };
|
||||
this.enabled = true;
|
||||
this.id = 'light';
|
||||
this.arduino = arduino;
|
||||
this.cfg = cfg;
|
||||
this.ui = ui;
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async init() {
|
||||
this.log = await Log({ label: this.id });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on(this.id, this.listener.bind(this));
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async listener(event, arg) {
|
||||
if (typeof arg.rgb !== 'undefined') {
|
||||
try {
|
||||
await this.set(arg.rgb, arg.id, true);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error setting light', err);
|
||||
}
|
||||
}
|
||||
else if (typeof arg.enable !== 'undefined') {
|
||||
this.enabled = true;
|
||||
}
|
||||
else if (typeof arg.disable !== 'undefined') {
|
||||
this.enabled = false;
|
||||
}
|
||||
event.returnValue = true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async set(rgb, id, on = true) {
|
||||
const str = rgb.join(',');
|
||||
let ms;
|
||||
this.state.color = rgb;
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, this.cfg.arduino.cmd.light);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error sending light command', err);
|
||||
}
|
||||
await delay_1.delay(1);
|
||||
try {
|
||||
this.arduino.string(this.id, str);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error('Error sending light string', err);
|
||||
}
|
||||
await delay_1.delay(1);
|
||||
await ms;
|
||||
return await this.end(rgb, id, ms);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async end(rgb, id, ms) {
|
||||
let res;
|
||||
//console.trace()
|
||||
this.log.info(`Light set to ${rgb.join(',')}`, 'LIGHT', true, true);
|
||||
try {
|
||||
//console.dir({ rgb, id, ms })
|
||||
res = await this.ui.send(this.id, { rgb, id, ms });
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
module.exports = function (arduino, cfg, ui) {
|
||||
return new Light(arduino, cfg, ui);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/light/index.ts"],"names":[],"mappings":"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"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "light",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<a name="logFile"></a>
|
||||
|
||||
## logFile() ⇒ <code>string</code>
|
||||
Determine the location of the log file based on the operating system
|
||||
and return as an absolute string from os.homedir()
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>string</code> - Path to log file
|
|
@ -1,85 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const winston_1 = require("winston");
|
||||
const path_1 = require("path");
|
||||
const fs_extra_1 = require("fs-extra");
|
||||
const os_1 = require("os");
|
||||
const logTime = 'MM/DD/YY-HH:mm:ss';
|
||||
let transport;
|
||||
/**
|
||||
* Determine the location of the log file based on the operating system
|
||||
* and return as an absolute string from os.homedir()
|
||||
*
|
||||
* @returns {string} Path to log file
|
||||
**/
|
||||
async function logFile() {
|
||||
const homeDir = os_1.homedir();
|
||||
const linuxDir = `/.mcopy/`;
|
||||
const macDir = `/Library/Logs/mcopy/`;
|
||||
const winDir = `/AppData/Roaming/mcopy/`;
|
||||
let logPath = path_1.normalize(path_1.join(homeDir, linuxDir));
|
||||
let dirExists;
|
||||
if (process.platform === 'darwin') {
|
||||
logPath = path_1.normalize(path_1.join(homeDir, macDir));
|
||||
}
|
||||
else if (process.platform === 'win32') {
|
||||
logPath = path_1.normalize(path_1.join(homeDir, winDir));
|
||||
}
|
||||
try {
|
||||
dirExists = await fs_extra_1.exists(logPath);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
if (!dirExists) {
|
||||
try {
|
||||
await fs_extra_1.mkdir(logPath);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`Error creating directory for mcopy log file, ${logPath}`);
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
return path_1.join(logPath, 'mcopy.log');
|
||||
}
|
||||
/**
|
||||
* Create and return the logger transport based on settings determined in
|
||||
* arguments object
|
||||
*
|
||||
* @param {object} arg Arguments from process
|
||||
*
|
||||
* @returns {object} Logger transport
|
||||
**/
|
||||
module.exports = async function (arg) {
|
||||
let consoleFormat = {
|
||||
colorize: true
|
||||
};
|
||||
let fileFormat = {
|
||||
filename: await logFile(),
|
||||
json: true
|
||||
};
|
||||
if (arg && arg.quiet) {
|
||||
transport = {
|
||||
info: function () { return false; },
|
||||
warn: function () { return false; },
|
||||
error: function () { return false; }
|
||||
};
|
||||
}
|
||||
else {
|
||||
if (arg && arg.label) {
|
||||
consoleFormat.label = arg.label;
|
||||
fileFormat.label = arg.label;
|
||||
}
|
||||
transport = winston_1.createLogger({
|
||||
format: winston_1.format.combine(winston_1.format.label({ label: arg.label || 'mcopy' }), winston_1.format.timestamp({
|
||||
format: 'YYYY-MM-DD HH:mm:ss'
|
||||
}), winston_1.format.printf((info) => `${info.timestamp} [${info.label}] ${info.level}: ${info.message}` + (info.splat !== undefined ? `${info.splat}` : " "))),
|
||||
transports: [
|
||||
new (winston_1.transports.Console)(consoleFormat),
|
||||
new (winston_1.transports.File)(fileFormat)
|
||||
]
|
||||
});
|
||||
}
|
||||
return transport;
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/log/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,qCAA2D;AAC3D,+BAAuC;AACvC,uCAAyC;AACzC,2BAA6B;AAE7B,MAAM,OAAO,GAAG,mBAAmB,CAAA;AACnC,IAAI,SAAe,CAAA;AAEnB;;;;;IAKI;AACJ,KAAK,UAAU,OAAO;IACrB,MAAM,OAAO,GAAY,YAAO,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAY,UAAU,CAAC;IACrC,MAAM,MAAM,GAAY,sBAAsB,CAAC;IAC/C,MAAM,MAAM,GAAY,yBAAyB,CAAC;IAClD,IAAI,OAAO,GAAY,gBAAS,CAAC,WAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1D,IAAI,SAAmB,CAAC;IAExB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE;QAClC,OAAO,GAAG,gBAAS,CAAC,WAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;KAC3C;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;QACxC,OAAO,GAAG,gBAAS,CAAC,WAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;KAC3C;IAED,IAAI;QACH,SAAS,GAAG,MAAM,iBAAM,CAAC,OAAO,CAAC,CAAC;KAClC;IAAC,OAAO,GAAG,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACnB;IAED,IAAI,CAAC,SAAS,EAAE;QACf,IAAI;YACH,MAAM,gBAAK,CAAC,OAAO,CAAC,CAAC;SACrB;QAAC,OAAO,GAAG,EAAE;YACb,OAAO,CAAC,KAAK,CAAC,gDAAgD,OAAO,EAAE,CAAC,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACnB;KACD;IAED,OAAO,WAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACnC,CAAC;AACD;;;;;;;IAOI;AACJ,MAAM,CAAC,OAAO,GAAG,KAAK,WAAW,GAAS;IACzC,IAAI,aAAa,GAAS;QACzB,QAAQ,EAAG,IAAI;KACf,CAAA;IACD,IAAI,UAAU,GAAS;QACtB,QAAQ,EAAG,MAAM,OAAO,EAAE;QAC1B,IAAI,EAAG,IAAI;KACX,CAAA;IACD,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE;QACrB,SAAS,GAAG;YACX,IAAI,EAAG,cAAc,OAAO,KAAK,CAAA,CAAC,CAAC;YACnC,IAAI,EAAG,cAAc,OAAO,KAAK,CAAA,CAAC,CAAC;YACnC,KAAK,EAAG,cAAc,OAAO,KAAK,CAAA,CAAC,CAAC;SACpC,CAAA;KACD;SAAM;QACN,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE;YACrB,aAAa,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAChC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;SAC7B;QACD,SAAS,GAAG,sBAAY,CAAC;YACxB,MAAM,EAAG,gBAAM,CAAC,OAAO,CACnB,gBAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAG,GAAG,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC,EACjD,gBAAM,CAAC,SAAS,CAAC;gBAChB,MAAM,EAAE,qBAAqB;aAC7B,CAAC,EACF,gBAAM,CAAC,MAAM,CAAC,CAAC,IAAU,EAAG,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,GAAC,CAAC,IAAI,CAAC,KAAK,KAAG,SAAS,CAAA,CAAC,CAAA,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA,CAAC,CAAA,GAAG,CAAC,CAAC,CAC7I;YACH,UAAU,EAAE;gBACX,IAAI,CAAC,oBAAU,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC;gBACvC,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;aACjC;SACD,CAAC,CAAA;KACF;IACD,OAAO,SAAS,CAAA;AACjB,CAAC,CAAA"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "log",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
<a name="module_lib/mscript"></a>
|
||||
|
||||
## lib/mscript
|
||||
|
||||
* [lib/mscript](#module_lib/mscript)
|
||||
* [~Mscript](#module_lib/mscript..Mscript)
|
||||
* [.clear()](#module_lib/mscript..Mscript+clear)
|
||||
* [.interpret()](#module_lib/mscript..Mscript+interpret)
|
||||
* [.basic_cmd()](#module_lib/mscript..Mscript+basic_cmd)
|
||||
* [.new_loop()](#module_lib/mscript..Mscript+new_loop)
|
||||
* [.end_loop()](#module_lib/mscript..Mscript+end_loop)
|
||||
* [.move_cam()](#module_lib/mscript..Mscript+move_cam)
|
||||
* [.move_proj()](#module_lib/mscript..Mscript+move_proj)
|
||||
* [.set_state()](#module_lib/mscript..Mscript+set_state)
|
||||
* [.last_loop()](#module_lib/mscript..Mscript+last_loop)
|
||||
* [.parent_loop()](#module_lib/mscript..Mscript+parent_loop)
|
||||
* [.loop_count()](#module_lib/mscript..Mscript+loop_count)
|
||||
* [.fade()](#module_lib/mscript..Mscript+fade)
|
||||
* [.fade_count()](#module_lib/mscript..Mscript+fade_count)
|
||||
* [.fade_start()](#module_lib/mscript..Mscript+fade_start)
|
||||
* [.fade_end()](#module_lib/mscript..Mscript+fade_end)
|
||||
* [.update()](#module_lib/mscript..Mscript+update)
|
||||
* [.str_to_arr()](#module_lib/mscript..Mscript+str_to_arr)
|
||||
* [.light_to_arr()](#module_lib/mscript..Mscript+light_to_arr)
|
||||
* [.light_state()](#module_lib/mscript..Mscript+light_state)
|
||||
* [.fail()](#module_lib/mscript..Mscript+fail)
|
||||
* [~startsWith()](#module_lib/mscript..startsWith)
|
||||
|
||||
<a name="module_lib/mscript..Mscript"></a>
|
||||
|
||||
### lib/mscript~Mscript
|
||||
class Mscript
|
||||
|
||||
**Kind**: inner class of [<code>lib/mscript</code>](#module_lib/mscript)
|
||||
|
||||
* [~Mscript](#module_lib/mscript..Mscript)
|
||||
* [.clear()](#module_lib/mscript..Mscript+clear)
|
||||
* [.interpret()](#module_lib/mscript..Mscript+interpret)
|
||||
* [.basic_cmd()](#module_lib/mscript..Mscript+basic_cmd)
|
||||
* [.new_loop()](#module_lib/mscript..Mscript+new_loop)
|
||||
* [.end_loop()](#module_lib/mscript..Mscript+end_loop)
|
||||
* [.move_cam()](#module_lib/mscript..Mscript+move_cam)
|
||||
* [.move_proj()](#module_lib/mscript..Mscript+move_proj)
|
||||
* [.set_state()](#module_lib/mscript..Mscript+set_state)
|
||||
* [.last_loop()](#module_lib/mscript..Mscript+last_loop)
|
||||
* [.parent_loop()](#module_lib/mscript..Mscript+parent_loop)
|
||||
* [.loop_count()](#module_lib/mscript..Mscript+loop_count)
|
||||
* [.fade()](#module_lib/mscript..Mscript+fade)
|
||||
* [.fade_count()](#module_lib/mscript..Mscript+fade_count)
|
||||
* [.fade_start()](#module_lib/mscript..Mscript+fade_start)
|
||||
* [.fade_end()](#module_lib/mscript..Mscript+fade_end)
|
||||
* [.update()](#module_lib/mscript..Mscript+update)
|
||||
* [.str_to_arr()](#module_lib/mscript..Mscript+str_to_arr)
|
||||
* [.light_to_arr()](#module_lib/mscript..Mscript+light_to_arr)
|
||||
* [.light_state()](#module_lib/mscript..Mscript+light_state)
|
||||
* [.fail()](#module_lib/mscript..Mscript+fail)
|
||||
|
||||
<a name="module_lib/mscript..Mscript+clear"></a>
|
||||
|
||||
#### mscript.clear()
|
||||
Clear the state of the script
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+interpret"></a>
|
||||
|
||||
#### mscript.interpret()
|
||||
Main function, accepts multi-line string, parses into lines
|
||||
and interprets the instructions from the text. Returns an array
|
||||
of steps to be fed into the mcopy.
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+basic_cmd"></a>
|
||||
|
||||
#### mscript.basic\_cmd()
|
||||
Apply a basic two character command
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+new_loop"></a>
|
||||
|
||||
#### mscript.new\_loop()
|
||||
Start a new loop
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+end_loop"></a>
|
||||
|
||||
#### mscript.end\_loop()
|
||||
Close the most recent loop
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+move_cam"></a>
|
||||
|
||||
#### mscript.move\_cam()
|
||||
Move camera to explicitly-defined frame
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+move_proj"></a>
|
||||
|
||||
#### mscript.move\_proj()
|
||||
Move projector to explicitly-defined frame
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+set_state"></a>
|
||||
|
||||
#### mscript.set\_state()
|
||||
Set the state of either the cam or projector
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+last_loop"></a>
|
||||
|
||||
#### mscript.last\_loop()
|
||||
Return the last loop
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+parent_loop"></a>
|
||||
|
||||
#### mscript.parent\_loop()
|
||||
Return the second-last loop
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+loop_count"></a>
|
||||
|
||||
#### mscript.loop\_count()
|
||||
Extract the loop count integer from a LOOP cmd
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+fade"></a>
|
||||
|
||||
#### mscript.fade()
|
||||
Execute a fade of frame length, from color to another color
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+fade_count"></a>
|
||||
|
||||
#### mscript.fade\_count()
|
||||
Extract the fade length integer from a FADE cmd
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+fade_start"></a>
|
||||
|
||||
#### mscript.fade\_start()
|
||||
Extract the start color from a string
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+fade_end"></a>
|
||||
|
||||
#### mscript.fade\_end()
|
||||
Extract the end color from a string
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+update"></a>
|
||||
|
||||
#### mscript.update()
|
||||
Increase the state of a specific object, such as the camera/projector,
|
||||
by the value defined in val
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+str_to_arr"></a>
|
||||
|
||||
#### mscript.str\_to\_arr()
|
||||
Split string on command, extract any integers from string
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+light_to_arr"></a>
|
||||
|
||||
#### mscript.light\_to\_arr()
|
||||
Split a string on a command to extract data for light array
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+light_state"></a>
|
||||
|
||||
#### mscript.light\_state()
|
||||
Split a string to extract an rgb color value
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..Mscript+fail"></a>
|
||||
|
||||
#### mscript.fail()
|
||||
Throw an error with specific message
|
||||
|
||||
**Kind**: instance method of [<code>Mscript</code>](#module_lib/mscript..Mscript)
|
||||
<a name="module_lib/mscript..startsWith"></a>
|
||||
|
||||
### lib/mscript~startsWith()
|
||||
startswith function from lodash, do not want the entire lib for this
|
||||
|
||||
**Kind**: inner method of [<code>lib/mscript</code>](#module_lib/mscript)
|
|
@ -1,13 +0,0 @@
|
|||
# TODO - mscript
|
||||
|
||||
* Add variables and simple evaluation
|
||||
* Add "Light" feature
|
||||
|
||||
Bash-like variables?
|
||||
Similar to LESS/SASS?
|
||||
Makes a tokenization easier
|
||||
|
||||
@ is better than $
|
||||
|
||||
RangeError: Invalid array length
|
||||
at Mscript.str_to_arr (./mcopy/app/lib/mscript/index.js:474:9)
|
|
@ -1,691 +0,0 @@
|
|||
'use strict';
|
||||
const BLACK = '0,0,0';
|
||||
const WHITE = '255,255,255';
|
||||
const CMD = [
|
||||
'CF',
|
||||
'PF',
|
||||
'BF',
|
||||
'CB',
|
||||
'PB',
|
||||
'BB'
|
||||
];
|
||||
const ALTS = {
|
||||
'CF': ['CAMERA FORWARD', 'CAM FORWARD'],
|
||||
'PF': ['PROJECTOR FORWARD', 'PROJ FORWARD'],
|
||||
'BF': ['BLACK FORWARD', 'BLACK', 'BLANK FORWARD', 'BLANK'],
|
||||
'CB': ['CAMERA BACKWARD', 'CAM BACKWARD', 'CAMERA BACK', 'CAM BACK'],
|
||||
'PB': ['PROJECTOR FORWARD', 'PROJ FORWARD', 'PROJECTOR BACK', 'PROJ BACK'],
|
||||
'BB': ['BLACK BACKWARD', 'BLACK BACK', 'BLANK BACK'],
|
||||
'L ': ['LIGHT', 'COLOR', 'LAMP'],
|
||||
'F ': ['FADE']
|
||||
};
|
||||
const PAUSE = 'PAUSE';
|
||||
const ALERT = 'ALERT';
|
||||
/** helper functions */
|
||||
/** startswith function from lodash, do not want the entire lib for this
|
||||
* @param str {string} Text to evaluate
|
||||
* @param target {string} Text to compare string against
|
||||
* @param position {integer} Position in the string to make comparison at
|
||||
*
|
||||
* @returns {boolean} True for match, false for no match
|
||||
**/
|
||||
function startsWith(str, target, position) {
|
||||
const { length } = str;
|
||||
position = position == null ? 0 : position;
|
||||
if (position < 0) {
|
||||
position = 0;
|
||||
}
|
||||
else if (position > length) {
|
||||
position = length;
|
||||
}
|
||||
target = `${target}`;
|
||||
return str.slice(position, position + target.length) == target;
|
||||
}
|
||||
/** class Mscript */
|
||||
class Mscript {
|
||||
/**
|
||||
* @constructor
|
||||
* Create new Mscript interpreter
|
||||
**/
|
||||
constructor() {
|
||||
this.output = {};
|
||||
}
|
||||
/**
|
||||
* Clear the state of the script
|
||||
*/
|
||||
clear() {
|
||||
this.lines = [];
|
||||
this.cam = 0;
|
||||
this.proj = 0;
|
||||
this.color = '';
|
||||
this.loops = [];
|
||||
this.rec = -1;
|
||||
this.two = '';
|
||||
this.arr = [];
|
||||
this.meta = [];
|
||||
this.target = 0; //move to target using CAM # or PROJ #
|
||||
this.dist = 0;
|
||||
this.variables = {};
|
||||
this.output = {};
|
||||
}
|
||||
/**
|
||||
* Main function, accepts multi-line string, parses into lines
|
||||
* and interprets the instructions from the text. Returns an array
|
||||
* of steps to be fed into the mcopy sequence.
|
||||
*
|
||||
* @param {string} text Mscript text to interpret
|
||||
* @param {function} callback Function to call when string is interpreted
|
||||
*
|
||||
* @returns {object} if callback is not provided
|
||||
*/
|
||||
interpret(text, callback) {
|
||||
this.clear();
|
||||
if (typeof text === 'undefined') {
|
||||
return this.fail('No input');
|
||||
}
|
||||
//split string into lines, each containing a command
|
||||
this.lines = text.split('\n');
|
||||
this.lines = this.lines.map(line => {
|
||||
line = line.replace(/\t+/g, ''); //strip tabs
|
||||
line = line.trim(); //remove excess whitespace before and after command
|
||||
line = line.toUpperCase();
|
||||
return line;
|
||||
});
|
||||
for (let line of this.lines) {
|
||||
this.two = line.substring(0, 2);
|
||||
if (CMD.indexOf(this.two) !== -1) {
|
||||
this.basic_cmd(line);
|
||||
}
|
||||
else if (startsWith(line, PAUSE)) {
|
||||
this.pause(line);
|
||||
}
|
||||
else if (startsWith(line, ALERT)) {
|
||||
this.alert(line);
|
||||
}
|
||||
else if (startsWith(line, '@') || line.indexOf('@') !== -1) {
|
||||
this.variable(line);
|
||||
}
|
||||
else if (startsWith(line, 'LOOP')) {
|
||||
this.new_loop(line);
|
||||
}
|
||||
else if (startsWith(line, 'L ')) {
|
||||
this.light_state(line);
|
||||
}
|
||||
else if (startsWith(line, 'F ')) {
|
||||
this.new_loop(line, true);
|
||||
}
|
||||
else if (startsWith(line, 'END')) {
|
||||
this.end_loop(line);
|
||||
}
|
||||
else if (startsWith(line, 'CAM')) { //directly go to that frame (black?)
|
||||
this.move_cam(line);
|
||||
}
|
||||
else if (startsWith(line, 'PROJ')) { //directly go to that frame
|
||||
this.move_proj(line);
|
||||
}
|
||||
else if (startsWith(line, 'SET')) { //set that state
|
||||
this.set_state(line);
|
||||
}
|
||||
else if (startsWith(line, '#') || startsWith(line, '//')) {
|
||||
//comments
|
||||
//ignore while parsing
|
||||
}
|
||||
else if (startsWith(line, 'ALERT')) {
|
||||
}
|
||||
else if (startsWith(line, 'PAUSE')) {
|
||||
this.pause(line);
|
||||
}
|
||||
}
|
||||
this.output.success = true;
|
||||
this.output.arr = this.arr; //all instructions
|
||||
this.output.meta = this.meta; //all metadata for instructions
|
||||
this.output.cam = this.cam;
|
||||
this.output.proj = this.proj;
|
||||
if (typeof callback !== 'undefined') {
|
||||
//should only be invoked by running mscript.tests()
|
||||
callback(this.output);
|
||||
}
|
||||
else {
|
||||
return this.output;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Interprets variables for complex sequence behavior.
|
||||
* TODO: Fully implement, add test coverage
|
||||
*
|
||||
* @param {string} line Line containing a variable assignment
|
||||
*
|
||||
**/
|
||||
variable(line) {
|
||||
let parts = line.split('=');
|
||||
let key = parts[0];
|
||||
let value = parts[1];
|
||||
let update = false;
|
||||
if (value && value.indexOf('#') !== -1) {
|
||||
value = value.split('#')[0];
|
||||
}
|
||||
if (value && value.indexOf('//') !== -1) {
|
||||
value = value.split('//')[0];
|
||||
}
|
||||
if (value && value.indexOf('+') !== -1) {
|
||||
if (value)
|
||||
update = true;
|
||||
}
|
||||
if (line.indexOf('-') !== -1) {
|
||||
update = true;
|
||||
}
|
||||
if (line.indexOf(',') === -1) { //if not color string
|
||||
try {
|
||||
value = parseInt(value);
|
||||
}
|
||||
catch (err) {
|
||||
//supress parsing error
|
||||
}
|
||||
}
|
||||
//console.dir(parts)
|
||||
if (!this.variables[key] || update) {
|
||||
this.variables[key] = value;
|
||||
}
|
||||
//console.dir(this.variables)
|
||||
}
|
||||
/**
|
||||
* Replace variable with value at time of interpretation
|
||||
* TODO: Implement this please
|
||||
*
|
||||
* @param {string} line Line containing variable to be replaced with value
|
||||
*
|
||||
* @returns {string} New string to be interpreted
|
||||
**/
|
||||
variable_replace(line) {
|
||||
return line;
|
||||
}
|
||||
/**
|
||||
* Interpret a basic two character command
|
||||
*
|
||||
* @param {string} line Line of script to interpret
|
||||
*/
|
||||
basic_cmd(line) {
|
||||
if (this.rec !== -1) {
|
||||
//hold generated arr in state loop array
|
||||
this.loops[this.rec].arr
|
||||
.push.apply(this.loops[this.rec].arr, this.str_to_arr(line, this.two));
|
||||
this.loops[this.rec].meta
|
||||
.push.apply(this.loops[this.rec].meta, this.light_to_arr(line, this.two));
|
||||
}
|
||||
else {
|
||||
this.arr.push.apply(this.arr, this.str_to_arr(line, this.two));
|
||||
this.meta.push.apply(this.meta, this.light_to_arr(line, this.two));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Start a new loop
|
||||
*
|
||||
* @param {string} line Line to evaluate as either loop or fade
|
||||
* @param {boolean} fade Flag as boolean if true
|
||||
*/
|
||||
new_loop(line, fade) {
|
||||
this.rec++;
|
||||
this.loops[this.rec] = {
|
||||
arr: [],
|
||||
meta: [],
|
||||
cam: 0,
|
||||
proj: 0,
|
||||
cmd: line + ''
|
||||
};
|
||||
if (fade) {
|
||||
this.fade(line);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Close the most recent loop
|
||||
*
|
||||
* @param {string} line Line to interpret
|
||||
*/
|
||||
end_loop(line) {
|
||||
let meta_arr;
|
||||
let start;
|
||||
let end;
|
||||
let len;
|
||||
for (let x = 0; x < this.loop_count(this.loops[this.rec].cmd); x++) {
|
||||
meta_arr = this.loops[this.rec].meta;
|
||||
if (this.loops[this.rec].fade) {
|
||||
start = this.loops[this.rec].start;
|
||||
end = this.loops[this.rec].end;
|
||||
len = this.loops[this.rec].fade_len;
|
||||
meta_arr = meta_arr.map(l => {
|
||||
return this.fade_rgb(start, end, len, x);
|
||||
});
|
||||
}
|
||||
if (this.rec === 0) {
|
||||
this.arr.push.apply(this.arr, this.loops[this.rec].arr);
|
||||
this.meta.push.apply(this.meta, meta_arr);
|
||||
}
|
||||
else if (this.rec >= 1) {
|
||||
this.loops[this.rec - 1].arr
|
||||
.push.apply(this.loops[this.rec - 1].arr, this.loops[this.rec].arr);
|
||||
this.loops[this.rec - 1].meta
|
||||
.push.apply(this.loops[this.rec - 1].meta, meta_arr);
|
||||
}
|
||||
}
|
||||
this.update('END', this.loop_count(this.loops[this.rec].cmd));
|
||||
delete this.loops[this.rec];
|
||||
this.rec--;
|
||||
}
|
||||
/**
|
||||
* Move camera to explicitly-defined frame
|
||||
*
|
||||
* @param {string} line Line to interpret with camera move statement
|
||||
*/
|
||||
move_cam(line) {
|
||||
this.target = parseInt(line.split('CAM ')[1]);
|
||||
if (this.rec !== -1) {
|
||||
if (this.target > this.cam) {
|
||||
this.dist = this.target - this.cam;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.loops[this.rec].arr.push('BF');
|
||||
this.loops[this.rec].meta.push(BLACK);
|
||||
this.update('BF');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.dist = this.cam - this.target;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.loops[this.rec].arr.push('BB');
|
||||
this.loops[this.rec].meta.push(BLACK);
|
||||
this.update('BB');
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.target > this.cam) {
|
||||
this.dist = this.target - this.cam;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.arr.push('BF');
|
||||
this.meta.push(BLACK);
|
||||
this.update('BF');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.dist = this.cam - this.target;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.arr.push('BB');
|
||||
this.meta.push(BLACK);
|
||||
this.update('BB');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Move projector to explicitly-defined frame
|
||||
*
|
||||
* @param {string} line Line containing `move` statement to interpret
|
||||
*/
|
||||
move_proj(line) {
|
||||
this.target = parseInt(line.split('PROJ ')[1]);
|
||||
if (this.rec !== -1) {
|
||||
if (this.target > this.proj) {
|
||||
this.dist = this.target - this.proj;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.loops[this.rec].arr.push('PF');
|
||||
this.loops[this.rec].meta.push('');
|
||||
this.update('PF');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.dist = this.proj - this.target;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.loops[this.rec].arr.push('PB');
|
||||
this.loops[this.rec].meta.push('');
|
||||
this.update('PB');
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.target > this.proj) {
|
||||
this.dist = this.target - this.proj;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.arr.push('PF');
|
||||
this.meta.push('');
|
||||
this.update('PF');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.dist = this.proj - this.target;
|
||||
for (let x = 0; x < this.dist; x++) {
|
||||
this.arr.push('PB');
|
||||
this.meta.push('');
|
||||
this.update('PB');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the state of either the cam or projector
|
||||
*
|
||||
* @param line {string} String containing set statement
|
||||
*/
|
||||
set_state(line) {
|
||||
if (startsWith(line, 'SET CAM')) {
|
||||
this.cam = parseInt(line.split('SET CAM')[1]);
|
||||
}
|
||||
else if (startsWith(line, 'SET PROJ')) {
|
||||
this.proj = parseInt(line.split('SET PROJ')[1]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the last loop
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
last_loop() {
|
||||
return this.loops[this.loops.length - 1];
|
||||
}
|
||||
/**
|
||||
* Return the second-last loop
|
||||
*
|
||||
* @returns {object} Loop array
|
||||
*/
|
||||
parent_loop() {
|
||||
return this.loops[this.loops.length - 2];
|
||||
}
|
||||
/**
|
||||
* Extract the loop count integer from a LOOP cmd
|
||||
*
|
||||
* @returns {integer} Loop count in string parsed into integer
|
||||
*/
|
||||
loop_count(str) {
|
||||
return parseInt(str.split(' ')[1]);
|
||||
}
|
||||
/**
|
||||
* Execute a fade of frame length, from color to another color
|
||||
*
|
||||
* @param {string} line Line containing a fade initiator
|
||||
*/
|
||||
fade(line) {
|
||||
let len = this.fade_count(line);
|
||||
let start = this.fade_start(line);
|
||||
let end = this.fade_end(line);
|
||||
this.loops[this.rec].start = start;
|
||||
this.loops[this.rec].end = end;
|
||||
this.loops[this.rec].fade = true;
|
||||
this.loops[this.rec].fade_count = 0;
|
||||
this.loops[this.rec].fade_len = len;
|
||||
}
|
||||
/**
|
||||
* Extract the fade length integer from a FADE cmd
|
||||
*
|
||||
* @param {string} str Line containing the length of fade in frames
|
||||
*/
|
||||
fade_count(str) {
|
||||
return parseInt(str.split(' ')[1]);
|
||||
}
|
||||
/**
|
||||
* Extract the start color from a string
|
||||
*
|
||||
* @param {string} str Line containing the start color value in a fade initiator
|
||||
*
|
||||
* @returns {array} Array containing RGB color values
|
||||
*/
|
||||
fade_start(str) {
|
||||
let color = str.split(' ')[2];
|
||||
return this.rgb(color.trim());
|
||||
}
|
||||
/**
|
||||
* Extract the end color from a string
|
||||
*
|
||||
* @param {string} str Line containing the end color value in a fade initiator
|
||||
*
|
||||
* @returns {array} Array containing RGB color values
|
||||
*/
|
||||
fade_end(str) {
|
||||
let color = str.split(' ')[3];
|
||||
return this.rgb(color.trim());
|
||||
}
|
||||
/**
|
||||
* Determine the state of a fade at a particular frame in the sequence, x
|
||||
*
|
||||
* @param {array} start Color the fade starts at
|
||||
* @param {array} end Color the fade finishes at
|
||||
* @param {integer} len Total length of the fade in frames
|
||||
* @param {integer} x Position of the fade to get color value of
|
||||
*
|
||||
* @returns {array} Array containing RGB color values
|
||||
*/
|
||||
fade_rgb(start, end, len, x) {
|
||||
let cur = [];
|
||||
let diff;
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (x === len - 1) {
|
||||
cur[i] = end[i];
|
||||
}
|
||||
else if (start[i] >= end[i]) {
|
||||
diff = start[i] - end[i];
|
||||
cur[i] = start[i] - Math.round((diff / (len - 1)) * x);
|
||||
}
|
||||
else {
|
||||
diff = end[i] - start[i];
|
||||
cur[i] = start[i] + Math.round((diff / (len - 1)) * x);
|
||||
}
|
||||
}
|
||||
return this.rgb_str(cur);
|
||||
}
|
||||
/**
|
||||
* Parse string into array of RGB color values. 0-255 octet.
|
||||
*
|
||||
* @param {string} str String containing only color values as `#,#,#`
|
||||
**/
|
||||
rgb(str) {
|
||||
let rgb = str.split(',');
|
||||
return rgb.map((char) => {
|
||||
return parseInt(char);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Cast RGB color values as string
|
||||
*
|
||||
* @param {array} arr Array to join into string
|
||||
*
|
||||
* @returns {string} String of RGB values
|
||||
**/
|
||||
rgb_str(arr) {
|
||||
return arr.join(',');
|
||||
}
|
||||
/**
|
||||
* Increase the state of a specific object, such as the camera/projector,
|
||||
* by the value defined in val.
|
||||
*
|
||||
* @param {string} cmd String representing command to interpret and update state
|
||||
*/
|
||||
update(cmd, val = 1) {
|
||||
if (cmd === 'END') {
|
||||
//I don't understand this loop
|
||||
for (let i = 0; i < val; i++) {
|
||||
if (this.rec === 0) {
|
||||
this.cam += this.loops[this.rec].cam;
|
||||
this.proj += this.loops[this.rec].proj;
|
||||
}
|
||||
else if (this.rec >= 1) {
|
||||
this.loops[this.rec - 1].cam += this.loops[this.rec].cam;
|
||||
this.loops[this.rec - 1].proj += this.loops[this.rec].proj;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cmd === 'CF') {
|
||||
if (this.rec === -1) {
|
||||
this.cam += val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].cam += val;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'CB') {
|
||||
if (this.rec === -1) {
|
||||
this.cam -= val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].cam--;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'PF') {
|
||||
if (this.rec === -1) {
|
||||
this.proj += val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].proj += val;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'PB') {
|
||||
if (this.rec === -1) {
|
||||
this.proj -= val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].proj--;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'BF') {
|
||||
if (this.rec === -1) {
|
||||
this.cam += val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].cam += val;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'BB') {
|
||||
if (this.rec === -1) {
|
||||
this.cam -= val;
|
||||
}
|
||||
else {
|
||||
this.loops[this.rec].cam -= val;
|
||||
}
|
||||
}
|
||||
else if (cmd === 'L ') {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Split string on command, turn into array of commands
|
||||
* as long as count variable. Default 1.
|
||||
*
|
||||
* @param {string} str String to split
|
||||
* @param {string} cmd String representing command to split at
|
||||
*
|
||||
* @returns {array} Array containing commands
|
||||
*/
|
||||
str_to_arr(str, cmd) {
|
||||
const cnt = str.split(cmd);
|
||||
let c = parseInt(cnt[1]);
|
||||
let arr = [];
|
||||
if (cnt[1] === '') {
|
||||
c = 1;
|
||||
}
|
||||
else {
|
||||
c = parseInt(cnt[1]);
|
||||
}
|
||||
arr = new Array(c).fill(cmd);
|
||||
this.update(cmd, c);
|
||||
return arr;
|
||||
}
|
||||
/**
|
||||
* Split a string on a command to extract data for light array
|
||||
*
|
||||
* @param {string} str String containing light command
|
||||
* @param {string} cmd String representing command
|
||||
*
|
||||
* @returns {array} An RGB array containing the color values
|
||||
*/
|
||||
light_to_arr(str, cmd) {
|
||||
const cnt = str.split(cmd);
|
||||
let c = parseInt(cnt[1]);
|
||||
let arr = [];
|
||||
if (cnt[1] === '') {
|
||||
c = 1;
|
||||
}
|
||||
else {
|
||||
c = parseInt(cnt[1]);
|
||||
}
|
||||
for (let i = 0; i < c; i++) {
|
||||
if (cmd === 'CF'
|
||||
|| cmd === 'CB') {
|
||||
arr.push(this.color);
|
||||
}
|
||||
else if (cmd === 'BF'
|
||||
|| cmd === 'BB') {
|
||||
arr.push(BLACK);
|
||||
}
|
||||
else {
|
||||
arr.push('');
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
/**
|
||||
* Split a string to extract an rgb color value
|
||||
*
|
||||
* @param {string} Color string assign to color property
|
||||
*/
|
||||
light_state(str) {
|
||||
//add parsers for other color spaces
|
||||
const color = str.replace('L ', '').trim();
|
||||
this.color = color;
|
||||
}
|
||||
/**
|
||||
* Interpret a pause command
|
||||
*
|
||||
* @param {string} line String containing pause command
|
||||
**/
|
||||
pause(line) {
|
||||
let lenStr = line.split(' ')[1] || '';
|
||||
let len;
|
||||
lenStr = lenStr.trim();
|
||||
try {
|
||||
len = parseInt(lenStr, 10); //clean up string or fail
|
||||
}
|
||||
catch (err) {
|
||||
len = 0;
|
||||
}
|
||||
if (isNaN(len)) {
|
||||
len = 0;
|
||||
}
|
||||
lenStr = String(len);
|
||||
if (this.rec !== -1) {
|
||||
//hold generated arr in state loop array
|
||||
this.loops[this.rec].arr
|
||||
.push('PA');
|
||||
this.loops[this.rec].meta
|
||||
.push(lenStr);
|
||||
}
|
||||
else {
|
||||
this.arr.push('AL');
|
||||
this.meta.push(lenStr);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Interpret an alert command
|
||||
*
|
||||
* @param {string} line String containing pause command
|
||||
**/
|
||||
alert(line) {
|
||||
let msg = line.split(' ')[1] || '';
|
||||
msg = msg.trim();
|
||||
if (this.rec !== -1) {
|
||||
//hold generated arr in state loop array
|
||||
this.loops[this.rec].arr
|
||||
.push('AL');
|
||||
this.loops[this.rec].meta
|
||||
.push(msg);
|
||||
}
|
||||
else {
|
||||
this.arr.push('AL');
|
||||
this.meta.push(msg);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Throw an error with specific message
|
||||
*
|
||||
* @param {string} msg Error message to print
|
||||
*/
|
||||
fail(msg) {
|
||||
throw new Error(msg);
|
||||
}
|
||||
}
|
||||
module.exports = Mscript;
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,476 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
/** @module lib/mscript */
|
||||
|
||||
let fs;
|
||||
let input;
|
||||
|
||||
/** object mscript */
|
||||
const mscript = {};
|
||||
|
||||
/**
|
||||
* Check for the presence of specific arguments in process
|
||||
* argv
|
||||
*
|
||||
* @param {string} shrt Short version of argument or flag
|
||||
* @param {string} lng Long version of argument or flag
|
||||
*
|
||||
* @return {boolean} Is flag present
|
||||
*/
|
||||
mscript.arg = function arg (shrt, lng) {
|
||||
if (process.argv.indexOf(shrt) !== -1 ||
|
||||
process.argv.indexOf(lng) !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check for the position of specific arguments in process
|
||||
* argv
|
||||
*
|
||||
* @param {string} shrt Short version of argument or flag
|
||||
* @param {string} lng Long version of argument or flag
|
||||
*
|
||||
* @return {boolean} Position of arg or flag, for locating input
|
||||
*/
|
||||
mscript.arg_pos = function arg_pos (shrt, lng) {
|
||||
var pos = -1;
|
||||
pos = process.argv.indexOf(shrt);
|
||||
if (pos === -1) {
|
||||
pos = process.argv.indexOf(lng);
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
mscript.black = '0,0,0';
|
||||
mscript.cmd = [
|
||||
'CF',
|
||||
'PF',
|
||||
'BF',
|
||||
'CB',
|
||||
'PB',
|
||||
'BB'
|
||||
];
|
||||
mscript.alts = {
|
||||
'CF' : ['CAMERA FORWARD', 'CAM FORWARD'],
|
||||
'PF' : ['PROJECTOR FORWARD', 'PROJ FORWARD'],
|
||||
'BF' : ['BLACK FORWARD', 'BLACK', 'BLANK FORWARD', 'BLANK'],
|
||||
'CB' : ['CAMERA BACKWARD', 'CAM BACKWARD', 'CAMERA BACK', 'CAM BACK'],
|
||||
'PB' : ['PROJECTOR FORWARD', 'PROJ FORWARD', 'PROJECTOR BACK', 'PROJ BACK'],
|
||||
'BB' : ['BLACK BACKWARD', 'BLACK BACK', 'BLANK BACK'],
|
||||
'L ' : ['LIGHT', 'COLOR', 'LAMP'],
|
||||
'F ' : ['FADE']
|
||||
};
|
||||
|
||||
mscript.state = {};
|
||||
|
||||
/**
|
||||
* Clear the state object
|
||||
*/
|
||||
mscript.state_clear = function state_clear () {
|
||||
mscript.state = {
|
||||
cam : 0,
|
||||
proj : 0,
|
||||
color : '',
|
||||
loops : [],
|
||||
rec : -1
|
||||
};
|
||||
};
|
||||
/**
|
||||
* This is never used and doesn't do anything?
|
||||
*/
|
||||
mscript.alts_unique = function alts_unique () {
|
||||
var ids = Object.keys(mscript.alts),
|
||||
all = [];
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
if (all.indexOf(ids[i]) === -1) {
|
||||
all.push(ids[i]);
|
||||
} else {
|
||||
mscript.fail("Can't compile");
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.interpret = function interpret (text, callback) {
|
||||
mscript.state_clear();
|
||||
if (typeof text === 'undefined') {
|
||||
mscript.fail('No input');
|
||||
}
|
||||
var lines = text.split('\n'),
|
||||
two = '',
|
||||
arr = [],
|
||||
light = [],
|
||||
target = 0,
|
||||
dist = 0, //?
|
||||
output = {};
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
lines[i] = lines[i].replace(/\t+/g, ""); //strip tabs
|
||||
lines[i] = lines[i].trim(); //remove excess whitespace before and after command
|
||||
two = lines[i].substring(0, 2);
|
||||
if (mscript.cmd.indexOf(two) !== -1) {
|
||||
|
||||
if (mscript.state.loops.length > 0) {
|
||||
//hold generated arr in state loop array
|
||||
mscript.state.loops[mscript.state.rec].arr
|
||||
.push.apply(mscript.state.loops[mscript.state.rec].arr,
|
||||
mscript.str_to_arr(lines[i],
|
||||
two));
|
||||
mscript.state.loops[mscript.state.rec].light
|
||||
.push.apply(mscript.state.loops[mscript.state.rec].light,
|
||||
mscript.light_to_arr(lines[i],
|
||||
two));
|
||||
} else {
|
||||
arr.push.apply(arr, mscript.str_to_arr(lines[i], two));
|
||||
light.push.apply(light, mscript.light_to_arr(lines[i], two))
|
||||
}
|
||||
|
||||
} else if (lines[i].substring(0, 4) === 'LOOP') {
|
||||
mscript.state.rec++;
|
||||
mscript.state.loops[mscript.state.rec] = {
|
||||
arr : [],
|
||||
light : [],
|
||||
cam : 0,
|
||||
proj : 0,
|
||||
cmd : lines[i] + ''
|
||||
};
|
||||
} else if (lines[i].substring(0, 2) === 'L ') {
|
||||
mscript.light_state(lines[i]);
|
||||
} else if (lines[i].substring(0, 3) === 'END') {
|
||||
for (var x = 0; x < mscript.loop_count(mscript.state.loops[mscript.state.rec].cmd); x++) {
|
||||
if (mscript.state.rec === 0) {
|
||||
arr.push.apply(arr, mscript.state.loops[mscript.state.rec].arr);
|
||||
light.push.apply(light, mscript.state.loops[mscript.state.rec].light);
|
||||
} else if (mscript.state.rec >= 1) {
|
||||
mscript.state.loops[mscript.state.rec - 1].arr
|
||||
.push.apply(mscript.state.loops[mscript.state.rec - 1].arr,
|
||||
mscript.state.loops[mscript.state.rec].arr);
|
||||
mscript.state.loops[mscript.state.rec - 1].light
|
||||
.push.apply(mscript.state.loops[mscript.state.rec - 1].light,
|
||||
mscript.state.loops[mscript.state.rec].light);
|
||||
}
|
||||
}
|
||||
mscript.state_update('END', mscript.loop_count(mscript.state.loops[mscript.state.rec].cmd));
|
||||
delete mscript.state.loops[mscript.state.rec];
|
||||
mscript.state.rec--;
|
||||
} else if (lines[i].substring(0, 3) === 'CAM') { //directly go to that frame (black?)
|
||||
target = parseInt(lines[i].split('CAM ')[1]);
|
||||
if (mscript.state.loops.length > 0) {
|
||||
if (target > mscript.state.cam) {
|
||||
dist = target - mscript.state.cam;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
mscript.state.loops[mscript.state.rec].arr.push('BF');
|
||||
mscript.state.loops[mscript.state.rec].light.push(mscript.black);
|
||||
mscript.state_update('BF');
|
||||
}
|
||||
} else {
|
||||
dist = mscript.state.cam - target;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
mscript.state.loops[mscript.state.rec].arr.push('BB');
|
||||
mscript.state.loops[mscript.state.rec].light.push(mscript.black);
|
||||
mscript.state_update('BB');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (target > mscript.state.cam) {
|
||||
dist = target - mscript.state.cam;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
arr.push('BF');
|
||||
light.push(mscript.black);
|
||||
mscript.state_update('BF');
|
||||
}
|
||||
} else {
|
||||
dist = mscript.state.cam - target;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
arr.push('BB');
|
||||
light.push(mscript.black);
|
||||
mscript.state_update('BB');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (lines[i].substring(0, 4) === 'PROJ') { //directly go to that frame
|
||||
target = parseInt(lines[i].split('PROJ ')[1]);
|
||||
if (mscript.state.loops.length > 0) {
|
||||
if (target > mscript.state.proj) {
|
||||
dist = target - mscript.state.proj;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
mscript.state.loops[mscript.state.rec].arr.push('PF');
|
||||
mscript.state.loops[mscript.state.rec].light.push('');
|
||||
mscript.state_update('PF');
|
||||
}
|
||||
} else {
|
||||
dist = mscript.state.proj - target;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
mscript.state.loops[mscript.state.rec].arr.push('PB');
|
||||
mscript.state.loops[mscript.state.rec].light.push('');
|
||||
mscript.state_update('PB');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (target > mscript.state.proj) {
|
||||
dist = target - mscript.state.proj;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
arr.push('PF');
|
||||
light.push('');
|
||||
mscript.state_update('PF');
|
||||
}
|
||||
} else {
|
||||
dist = mscript.state.proj - target;
|
||||
for (var x = 0; x < dist; x++) {
|
||||
arr.push('PB');
|
||||
light.push('');
|
||||
mscript.state_update('PB');
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (lines[i].substring(0, 3) === 'SET') { //set that state
|
||||
if (lines[i].substring(0, 7) === 'SET CAM') {
|
||||
mscript.state.cam = parseInt(lines[i].split('SET CAM')[1]);
|
||||
} else if (lines[i].substring(0, 8) === 'SET PROJ') {
|
||||
mscript.state.proj = parseInt(lines[i].split('SET PROJ')[1]);
|
||||
}
|
||||
} else if (lines[i].substring(0, 1) === '#' || lines[i].substring(0, 2) === '//') {
|
||||
//comments
|
||||
//ignore while parsing
|
||||
}
|
||||
}
|
||||
output.success = true;
|
||||
output.arr = arr;
|
||||
output.light = light;
|
||||
output.cam = mscript.state.cam;
|
||||
output.proj = mscript.state.proj;
|
||||
if (typeof callback !== 'undefined') {
|
||||
//should only be invoked by running mscript.tests()
|
||||
callback(output);
|
||||
} else {
|
||||
return mscript.output(output);
|
||||
}
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.last_loop = function last_loop () {
|
||||
return mscript.state.loops[mscript.state.loops.length - 1];
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.parent_loop = function parent_loop () {
|
||||
return mscript.state.loops[mscript.state.loops.length - 2];
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.state_update = function state_update (cmd, val) {
|
||||
if (cmd === 'END') {
|
||||
for (var i = 0; i < val; i++) {
|
||||
if (mscript.state.rec === 0) {
|
||||
mscript.state.cam += mscript.state.loops[mscript.state.rec].cam;
|
||||
mscript.state.proj += mscript.state.loops[mscript.state.rec].proj;
|
||||
} else if (mscript.state.rec >= 1) {
|
||||
mscript.state.loops[mscript.state.rec - 1].cam += mscript.state.loops[mscript.state.rec].cam;
|
||||
mscript.state.loops[mscript.state.rec - 1].proj += mscript.state.loops[mscript.state.rec].proj;
|
||||
}
|
||||
}
|
||||
} else if (cmd === 'CF') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.cam++;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].cam++;
|
||||
}
|
||||
} else if (cmd === 'CB') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.cam--;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].cam--;
|
||||
}
|
||||
} else if (cmd === 'PF') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.proj++;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].proj++;
|
||||
}
|
||||
} else if (cmd === 'PB') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.proj--;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].proj--;
|
||||
}
|
||||
} else if (cmd === 'BF') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.cam++;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].cam++;
|
||||
}
|
||||
} else if (cmd === 'BB') {
|
||||
if (mscript.state.loops.length < 1) {
|
||||
mscript.state.cam--;
|
||||
} else {
|
||||
mscript.state.loops[mscript.state.rec].cam++;
|
||||
}
|
||||
} else if (cmd === 'L ') {
|
||||
|
||||
}
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.str_to_arr = function str_to_arr (str, cmd) {
|
||||
var cnt = str.split(cmd),
|
||||
c = parseInt(cnt[1]),
|
||||
arr = [];
|
||||
if (cnt[1] === '') {
|
||||
c = 1;
|
||||
} else {
|
||||
c = parseInt(cnt[1]);
|
||||
}
|
||||
for (var i = 0; i < c; i++) {
|
||||
arr.push(cmd);
|
||||
mscript.state_update(cmd);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.light_state = function light_state (str) {
|
||||
//add parsers for other color spaces
|
||||
var color = str.replace('L ', '').trim();
|
||||
mscript.state.color = color;
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.light_to_arr = function light_to_arr (str, cmd) {
|
||||
var cnt = str.split(cmd),
|
||||
c = parseInt(cnt[1]),
|
||||
arr = [];
|
||||
if (cnt[1] === '') {
|
||||
c = 1;
|
||||
} else {
|
||||
c = parseInt(cnt[1]);
|
||||
}
|
||||
for (var i = 0; i < c; i++) {
|
||||
if (cmd === 'CF'
|
||||
|| cmd === 'CB') {
|
||||
arr.push(mscript.state.color);
|
||||
} else if (cmd === 'BF'
|
||||
|| cmd === 'BB') {
|
||||
arr.push(mscript.black);
|
||||
} else {
|
||||
arr.push('');
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.loop_count = function loop_count (str) {
|
||||
return parseInt(str.split(' ')[1]);
|
||||
};
|
||||
mscript.fade_count = function fade_count (str) {
|
||||
return parseInt(str.split(' ')[1]);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.fail = function fail (reason) {
|
||||
console.error(JSON.stringify({success: false, error: true, msg : reason}));
|
||||
if (process) process.exit();
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.output = function output (data) {
|
||||
var json = true; //default
|
||||
if (mscript.arg('-j', '--json')) {
|
||||
json = true;
|
||||
}
|
||||
|
||||
if (mscript.arg('-t', '--text')) {
|
||||
json = false;
|
||||
}
|
||||
|
||||
if (json) {
|
||||
console.log(JSON.stringify(data));
|
||||
} else {
|
||||
var ids = Object.keys(data);
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
console.log(ids[i] + ': ' + data[ids[i]]);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mscript.init = function init () {
|
||||
if (mscript.arg('-t', '--tests')) {
|
||||
return mscript.tests();
|
||||
}
|
||||
|
||||
if (mscript.arg('-v', '--verbose')) {
|
||||
console.time('mscript');
|
||||
}
|
||||
|
||||
if (mscript.arg('-c', '--cam')) {
|
||||
mscript.state.cam = parseInt(process.argv[mscript.arg_pos('-c', '--cam') + 1]);
|
||||
}
|
||||
|
||||
if (mscript.arg('-p', '--proj')) {
|
||||
mscript.state.proj = parseInt(process.argv[mscript.arg_pos('-p', '--proj') + 1]);
|
||||
}
|
||||
|
||||
if (mscript.arg('-f', '--file')) {
|
||||
input = process.argv[mscript.arg_pos('-f', '--file') + 1];
|
||||
mscript.interpret(fs.readFileSync(input, 'utf8'));
|
||||
} else {
|
||||
mscript.interpret(input);
|
||||
}
|
||||
|
||||
if (mscript.arg('-v', '--verbose')) {
|
||||
console.timeEnd('mscript');
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof document === 'undefined'
|
||||
&& typeof module !== 'undefined'
|
||||
&& !module.parent) {
|
||||
//node script
|
||||
fs = require('fs');
|
||||
input = process.argv[2];
|
||||
mscript.init();
|
||||
} else if (typeof module !== 'undefined' && module.parent) {
|
||||
//module
|
||||
fs = require('fs');
|
||||
module.exports = mscript;
|
||||
} else {
|
||||
//web
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
CAM # - go to camera frame #
|
||||
PROJ # - go to projector frame #
|
||||
|
||||
SET CAM # - sets camera count to #
|
||||
SET PROJ # - sets projector count to #
|
||||
|
||||
LOOP # - begin loop, can nest recursively, # times
|
||||
END LOOP - (or END) closes loop
|
||||
|
||||
L #RGB - sets light to rgb value
|
||||
|
||||
FADE
|
||||
|
||||
CF - Camera forwards
|
||||
PF - Projector forwards
|
||||
BF - Black forwards
|
||||
CB - Camera backwards
|
||||
PB - Projector backwards
|
||||
BB - Black backwards
|
||||
|
||||
*/
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "mscript",
|
||||
"version": "1.0.0",
|
||||
"description": "<a name=\"module_lib/mscript\"></a>",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<a name="Projector"></a>
|
||||
|
||||
## Projector
|
||||
**Kind**: global class
|
||||
|
||||
* [Projector](#Projector)
|
||||
* [.init()](#Projector+init)
|
||||
* [.listen()](#Projector+listen)
|
||||
* [.set()](#Projector+set)
|
||||
* [.move()](#Projector+move)
|
||||
* [.listener()](#Projector+listener)
|
||||
* [.end()](#Projector+end)
|
||||
|
||||
<a name="Projector+init"></a>
|
||||
|
||||
### projector.init()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
||||
<a name="Projector+listen"></a>
|
||||
|
||||
### projector.listen()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
||||
<a name="Projector+set"></a>
|
||||
|
||||
### projector.set()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
||||
<a name="Projector+move"></a>
|
||||
|
||||
### projector.move()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
||||
<a name="Projector+listener"></a>
|
||||
|
||||
### projector.listener()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
||||
<a name="Projector+end"></a>
|
||||
|
||||
### projector.end()
|
||||
**Kind**: instance method of [<code>Projector</code>](#Projector)
|
|
@ -1,175 +0,0 @@
|
|||
"use strict";
|
||||
/** class representing the Projector features **/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Log = require("log");
|
||||
class Projector {
|
||||
/**
|
||||
*
|
||||
**/
|
||||
constructor(arduino, cfg, ui, filmout, second = false) {
|
||||
this.state = {
|
||||
pos: 0,
|
||||
dir: true
|
||||
};
|
||||
this.arduino = null;
|
||||
this.id = 'projector';
|
||||
this.arduino = arduino;
|
||||
this.cfg = cfg;
|
||||
this.ui = ui;
|
||||
this.filmout = filmout;
|
||||
if (second)
|
||||
this.id += '_second';
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async init() {
|
||||
this.log = await Log({ label: this.id });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on(this.id, this.listener.bind(this));
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async set(dir, id) {
|
||||
let cmd;
|
||||
let ms;
|
||||
if (dir) {
|
||||
cmd = this.cfg.arduino.cmd[`${this.id}_forward`];
|
||||
}
|
||||
else {
|
||||
cmd = this.cfg.arduino.cmd[`${this.id}_backward`];
|
||||
}
|
||||
this.state.dir = dir;
|
||||
if (this.filmout.state.enabled) {
|
||||
this.filmout.set(dir);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error setting ${this.id} direction`, err);
|
||||
}
|
||||
}
|
||||
return await this.end(cmd, id, ms);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async move(frame, id) {
|
||||
const cmd = this.cfg.arduino.cmd[this.id];
|
||||
let ms;
|
||||
if (this.filmout.state.enabled) {
|
||||
try {
|
||||
ms = await this.filmout.move();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error moving ${this.id}`, err);
|
||||
}
|
||||
}
|
||||
//this.log.info('Projector move time', { ms });
|
||||
return await this.end(cmd, id, ms);
|
||||
}
|
||||
async both(frame, id) {
|
||||
const cmd = this.cfg.arduino.cmd[this.id + 's'];
|
||||
let ms;
|
||||
try {
|
||||
ms = await this.arduino.send(this.id, cmd);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error moving ${this.id}`, err);
|
||||
}
|
||||
//this.log.info('Projectors move time', { ms });
|
||||
return await this.end(cmd, id, ms);
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async listener(event, arg) {
|
||||
if (typeof arg.dir !== 'undefined') {
|
||||
try {
|
||||
await this.set(arg.dir, arg.id);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else if (typeof arg.frame !== 'undefined') {
|
||||
try {
|
||||
await this.move(arg.frame, arg.id);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
else if (typeof arg.val !== 'undefined') {
|
||||
this.state.pos = arg.val;
|
||||
this.filmout.state.frame = arg.val;
|
||||
}
|
||||
event.returnValue = true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async end(cmd, id, ms) {
|
||||
let message = '';
|
||||
if (cmd === this.cfg.arduino.cmd.projector_forward) {
|
||||
message = 'Projector set to FORWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projector_backward) {
|
||||
message = 'Projector set to BACKWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projector_second_forward) {
|
||||
message = 'Projector second set to FORWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projector_second_backward) {
|
||||
message = 'Projector second set to BACKWARD';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projector) {
|
||||
message = 'Projector ';
|
||||
if (this.state.dir) {
|
||||
message += 'ADVANCED';
|
||||
}
|
||||
else {
|
||||
message += 'REWOUND';
|
||||
}
|
||||
message += ' 1 frame';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projector_second) {
|
||||
message = 'Projector second ';
|
||||
if (this.state.dir) {
|
||||
message += 'ADVANCED';
|
||||
}
|
||||
else {
|
||||
message += 'REWOUND';
|
||||
}
|
||||
message += ' 1 frame';
|
||||
}
|
||||
else if (cmd === this.cfg.arduino.cmd.projectors) {
|
||||
message += 'Projectors both MOVED 1 frame each';
|
||||
}
|
||||
message += ` ${ms}ms`;
|
||||
this.log.info(message, 'PROJECTOR');
|
||||
return await this.ui.send(this.id, { cmd: cmd, id: id, ms: ms });
|
||||
}
|
||||
}
|
||||
module.exports = function (arduino, cfg, ui, filmout, second) {
|
||||
return new Projector(arduino, cfg, ui, filmout, second);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "proj",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,240 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Log = require("log");
|
||||
const electron_1 = require("electron");
|
||||
/** @module lib/sequencer **/
|
||||
let seq;
|
||||
class Sequencer {
|
||||
/**
|
||||
* @constructor
|
||||
* Create a new sequencer and assign command and UI as private sub-classes
|
||||
*
|
||||
* @param {object} cfg Configuration object
|
||||
* @param {object} cmd Shared command class
|
||||
* @param {object} ui Electron UI, browser window
|
||||
**/
|
||||
constructor(cfg, cmd, ui) {
|
||||
this.running = false;
|
||||
this.paused = false;
|
||||
this.grid = [];
|
||||
this.gridLoops = 1;
|
||||
this.arr = []; //store sequence from gui
|
||||
this.loops = 1;
|
||||
this.CMDS = {};
|
||||
this.id = 'sequence';
|
||||
this.alerted = false;
|
||||
this.cfg = cfg;
|
||||
this.cmd = cmd;
|
||||
this.ui = ui;
|
||||
this.cmds(cfg.cmd);
|
||||
this.init();
|
||||
}
|
||||
/**
|
||||
* Take configuration object and assign all commands as keys
|
||||
* in the internal CMDS object.
|
||||
*
|
||||
* @param {object} obj Configuration object
|
||||
**/
|
||||
cmds(obj) {
|
||||
let keys = Object.keys(obj);
|
||||
for (let key of keys) {
|
||||
this.CMDS[obj[key]] = key;
|
||||
}
|
||||
//
|
||||
//
|
||||
}
|
||||
/**
|
||||
* Initialize the class by requiring ipcMain from electron
|
||||
* and creating logger.
|
||||
*
|
||||
**/
|
||||
async init() {
|
||||
this.log = await Log({ label: this.id });
|
||||
this.ipc = require('electron').ipcMain;
|
||||
this.listen();
|
||||
}
|
||||
/**
|
||||
* Bind ipc listener to channel 'sequencer' or current id of
|
||||
* class.
|
||||
**/
|
||||
listen() {
|
||||
this.ipc.on(this.id, this.listener.bind(this));
|
||||
}
|
||||
/**
|
||||
* Listener callback function. Called whenever ipc
|
||||
* message is sent to channel 'sequencer'.
|
||||
*
|
||||
* @param {object} event IPC message event
|
||||
* @param {object} arg Arguments provided in message
|
||||
**/
|
||||
async listener(event, arg) {
|
||||
if (arg && arg.start) {
|
||||
this.start(arg);
|
||||
}
|
||||
else if (arg && arg.stop) {
|
||||
this.stop();
|
||||
}
|
||||
else if (arg && arg.pause) {
|
||||
this.pause();
|
||||
}
|
||||
else if (arg && arg.set) {
|
||||
this.setSteps(arg.set);
|
||||
}
|
||||
else if (arg && arg.unset) {
|
||||
this.unsetSteps(arg.unset);
|
||||
}
|
||||
else if (arg && arg.loops) {
|
||||
this.setLoops(arg.loops);
|
||||
}
|
||||
event.returnValue = true;
|
||||
}
|
||||
/**
|
||||
* Sets the value of the loops in the grid sequence
|
||||
* to value sent by UI in ipc message.
|
||||
*
|
||||
* @param {integer} count Number of loops to set grid sequence to
|
||||
**/
|
||||
setLoops(count) {
|
||||
this.gridLoops = count;
|
||||
this.log.info(`Set loop count to ${count}`);
|
||||
}
|
||||
/**
|
||||
* Sets multiple steps at once
|
||||
*
|
||||
* @param {array} steps Array of steps to set or update
|
||||
**/
|
||||
setSteps(steps) {
|
||||
for (let step of steps) {
|
||||
this.grid[step.x] = step;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resets multiple steps to default 'undefined' state
|
||||
*
|
||||
* @param {array} steps Array containing the x location of steps to unset
|
||||
**/
|
||||
unsetSteps(steps) {
|
||||
for (let x of steps) {
|
||||
this.grid[x] = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Starts a sequence with the existing grid sequence,
|
||||
* or if one is provided in the arg object, starts
|
||||
* that sequence.
|
||||
*
|
||||
* @param {object} arg Arguments from ipc message
|
||||
**/
|
||||
async start(arg) {
|
||||
const psbId = electron_1.powerSaveBlocker.start('prevent-display-sleep');
|
||||
let startTime = +new Date();
|
||||
let ms;
|
||||
if (arg && arg.arr) {
|
||||
this.arr = arg.arr; //overwrite sequence
|
||||
}
|
||||
else {
|
||||
this.arr = this.grid;
|
||||
}
|
||||
if (arg && arg.loops) {
|
||||
this.loops = arg.loops; //overwrite loops
|
||||
}
|
||||
else {
|
||||
this.loops = this.gridLoops;
|
||||
}
|
||||
this.running = true;
|
||||
this.paused = false;
|
||||
//start sequence
|
||||
this.log.info(`Starting sequence...`);
|
||||
this.ui.send(this.id, { start: true });
|
||||
if (this.cmd.proj.filmout.state.enabled === true) {
|
||||
await this.cmd.proj.filmout.display.open();
|
||||
}
|
||||
for (let x = 0; x < this.loops; x++) {
|
||||
//start loop
|
||||
this.log.info(`Starting loop ${x + 1}`);
|
||||
this.ui.send(this.id, { loop: x, start: true });
|
||||
for (let y = 0; y < this.arr.length; y++) {
|
||||
//start step
|
||||
if (!this.running) {
|
||||
break;
|
||||
}
|
||||
//UI initiates pause, not planned
|
||||
while (this.paused) {
|
||||
await delay(42);
|
||||
}
|
||||
if (typeof this.arr[y] === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
this.log.info(`Starting step ${y + 1} of loop ${x + 1}`);
|
||||
this.ui.send(this.id, { step: y, loop: x, start: true });
|
||||
await this.step(y);
|
||||
//end step
|
||||
this.log.info(`Ended step ${y + 1} of loop ${x + 1}`);
|
||||
this.ui.send(this.id, { step: y, loop: x, stop: true });
|
||||
}
|
||||
if (!this.running) {
|
||||
break;
|
||||
}
|
||||
//end loop
|
||||
this.log.info(`Ended loop ${x + 1}`);
|
||||
this.ui.send(this.id, { loop: x, stop: true });
|
||||
}
|
||||
if (this.cmd.proj.filmout.state.enabled === true) {
|
||||
await this.cmd.proj.filmout.display.close();
|
||||
}
|
||||
electron_1.powerSaveBlocker.stop(psbId);
|
||||
this.psbId = null;
|
||||
ms = (+new Date()) - startTime;
|
||||
//end sequence
|
||||
this.log.info(`Ended sequence`);
|
||||
this.ui.send(this.id, { stop: true, ms });
|
||||
}
|
||||
/**
|
||||
* Pauses sequence from UI.
|
||||
**/
|
||||
pause() {
|
||||
this.paused = true;
|
||||
}
|
||||
/**
|
||||
* Stops the sequence
|
||||
**/
|
||||
stop() {
|
||||
if (this.cmd.proj.filmout.state.enabled === true) {
|
||||
this.cmd.proj.filmout.display.close();
|
||||
}
|
||||
this.running = false;
|
||||
if (this.psbId) {
|
||||
electron_1.powerSaveBlocker.stop(this.psbId);
|
||||
}
|
||||
//clear?
|
||||
}
|
||||
/**
|
||||
* Execute command @ step x. Wrapper with try catch.
|
||||
*
|
||||
* @param {integer} x Step to execute command at
|
||||
**/
|
||||
async step(x) {
|
||||
try {
|
||||
await this.cmdExec(x);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Locate step @ position x and execute the command.
|
||||
*
|
||||
* @param {integer} x Step to execute command at
|
||||
**/
|
||||
async cmdExec(x) {
|
||||
const cmdOriginal = this.arr[x].cmd;
|
||||
const cmd = this.CMDS[cmdOriginal];
|
||||
this.log.info(`CMD: '${cmdOriginal}' -> ${cmd}`);
|
||||
//I wrote this when I was very tired and delirious
|
||||
return await this.cmd[cmd]();
|
||||
}
|
||||
}
|
||||
module.exports = function (cfg, cmd, ui) {
|
||||
return new Sequencer(cfg, cmd, ui);
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "sequencer",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<a name="Settings"></a>
|
||||
|
||||
## Settings
|
||||
**Kind**: global class
|
||||
|
||||
* [Settings](#Settings)
|
||||
* [.checkDir()](#Settings+checkDir)
|
||||
* [.save()](#Settings+save)
|
||||
* [.update()](#Settings+update)
|
||||
* [.get()](#Settings+get)
|
||||
* [.all()](#Settings+all)
|
||||
* [.restore()](#Settings+restore)
|
||||
* [.reset()](#Settings+reset)
|
||||
|
||||
<a name="Settings+checkDir"></a>
|
||||
|
||||
### settings.checkDir()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+save"></a>
|
||||
|
||||
### settings.save()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+update"></a>
|
||||
|
||||
### settings.update()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+get"></a>
|
||||
|
||||
### settings.get()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+all"></a>
|
||||
|
||||
### settings.all()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+restore"></a>
|
||||
|
||||
### settings.restore()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
||||
<a name="Settings+reset"></a>
|
||||
|
||||
### settings.reset()
|
||||
**Kind**: instance method of [<code>Settings</code>](#Settings)
|
|
@ -1,113 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const fs = require("fs-extra");
|
||||
class Settings {
|
||||
/**
|
||||
*
|
||||
**/
|
||||
constructor() {
|
||||
this.file = path.join(os.homedir(), `/.mcopy/settings.json`);
|
||||
this.defaultState = {
|
||||
server: {
|
||||
port: 1111,
|
||||
enabled: true
|
||||
},
|
||||
devices: [],
|
||||
profile: 'mcopy',
|
||||
camera: {},
|
||||
projector: {},
|
||||
light: {}
|
||||
};
|
||||
this.state = this.freshState();
|
||||
}
|
||||
freshState() {
|
||||
return JSON.parse(JSON.stringify(this.defaultState));
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async checkDir() {
|
||||
const dir = path.join(os.homedir(), '.mcopy/');
|
||||
const exists = await fs.exists(dir);
|
||||
if (!exists) {
|
||||
try {
|
||||
await fs.mkdir(dir);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'EEXIST')
|
||||
return true;
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async save() {
|
||||
const str = JSON.stringify(this.state, null, '\t');
|
||||
this.checkDir();
|
||||
try {
|
||||
await fs.writeFile(this.file, str, 'utf8');
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
update(key, val) {
|
||||
this.state[key] = val;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
get(key) {
|
||||
return this.state[key];
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
all() {
|
||||
return this.state;
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async restore() {
|
||||
let exists;
|
||||
let str;
|
||||
this.checkDir();
|
||||
exists = await fs.exists(this.file);
|
||||
if (exists) {
|
||||
str = await fs.readFile(this.file, 'utf8');
|
||||
this.state = JSON.parse(str);
|
||||
//console.dir(this.state)
|
||||
}
|
||||
else {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
**/
|
||||
async reset() {
|
||||
const exists = await fs.exists(this.file);
|
||||
if (exists) {
|
||||
try {
|
||||
await fs.unlink(this.file);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
this.state = this.freshState();
|
||||
this.restore();
|
||||
}
|
||||
;
|
||||
}
|
||||
module.exports = new Settings();
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"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"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "settings",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<a name="spawn"></a>
|
||||
|
||||
## spawn()
|
||||
Wrapper function around spawn that prints to console
|
||||
after process closes. Not used.
|
||||
|
||||
**Kind**: global function
|
|
@ -1,22 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const spawnRaw = require('child_process').spawn;
|
||||
|
||||
/**
|
||||
* Wrapper function around spawn that prints to console
|
||||
* after process closes. Not used.
|
||||
**/
|
||||
function spawn (cmd, args) {
|
||||
const sp = spawnRaw(cmd, args);
|
||||
let output = '';
|
||||
sp.stderr.on('data', (data) => {
|
||||
output += data;
|
||||
//console.log(`${data}`);
|
||||
});
|
||||
sp.on('close', (code) => {
|
||||
console.log(output);
|
||||
});
|
||||
return sp;
|
||||
}
|
||||
|
||||
module.exports = spawn;
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "spawn",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
## Functions
|
||||
|
||||
<dl>
|
||||
<dt><a href="#dependencies">dependencies(platform)</a></dt>
|
||||
<dd><p>Evaluates system dependencies for digital
|
||||
projector features by executing processes with
|
||||
--help flag. If they do not exist, log to console</p>
|
||||
</dd>
|
||||
<dt><a href="#system">system()</a> ⇒ <code>object</code></dt>
|
||||
<dd><p>Profile the current system and return an object with
|
||||
data about the displays and dependencies for the digital
|
||||
projector feature.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<a name="dependencies"></a>
|
||||
|
||||
## dependencies(platform)
|
||||
Evaluates system dependencies for digital
|
||||
projector features by executing processes with
|
||||
--help flag. If they do not exist, log to console
|
||||
|
||||
**Kind**: global function
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| platform | <code>string</code> | Operating system type |
|
||||
|
||||
<a name="system"></a>
|
||||
|
||||
## system() ⇒ <code>object</code>
|
||||
Profile the current system and return an object with
|
||||
data about the displays and dependencies for the digital
|
||||
projector feature.
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>object</code> - Object containing system information
|
|
@ -1,122 +0,0 @@
|
|||
'use strict';
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os_1 = require("os");
|
||||
const electron_1 = require("electron");
|
||||
//private
|
||||
const exec_1 = require("exec");
|
||||
/**
|
||||
* Evaluates system dependencies for digital
|
||||
* projector features by executing `which` on binary.
|
||||
* If they do not exist, log to console
|
||||
*
|
||||
* @param {string} platform Operating system type
|
||||
*
|
||||
* @returns {object} Object containing path to dependency from `which`, if they exist
|
||||
**/
|
||||
async function dependencies(platform) {
|
||||
let obj = {};
|
||||
let ffmpeg = require('ffmpeg-static');
|
||||
let ffprobe = require('ffprobe-static');
|
||||
let ffoutput;
|
||||
//let imoutput : ExecOutput;
|
||||
let eogoutput;
|
||||
obj.ffmpeg = ffmpeg; /*.replace(
|
||||
'app.asar',
|
||||
'app.asar.unpacked'
|
||||
);*/
|
||||
obj.ffprobe = ffprobe.path; /*.replace(
|
||||
'app.asar',
|
||||
'app.asar.unpacked'
|
||||
);*/
|
||||
try {
|
||||
//imoutput = await exec('which convert');
|
||||
}
|
||||
catch (err) {
|
||||
console.error('imagemagick is not installed', err);
|
||||
}
|
||||
/*if (!imoutput || imoutput.stdout.trim() === '') {
|
||||
console.error('imagemagick is not installed');
|
||||
} else {
|
||||
obj.convert = imoutput.stdout.trim();
|
||||
}*/
|
||||
//if linux
|
||||
if (platform === 'nix') {
|
||||
try {
|
||||
eogoutput = await exec_1.exec('which eog');
|
||||
}
|
||||
catch (err) {
|
||||
console.error('eog is not installed', err);
|
||||
}
|
||||
if (!eogoutput || eogoutput.stdout.trim() === '') {
|
||||
console.error('eog is not installed');
|
||||
}
|
||||
else {
|
||||
obj.eog = eogoutput.stdout.trim();
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
function displayMap(obj) {
|
||||
const sm = {
|
||||
id: obj.id,
|
||||
width: obj.size.width,
|
||||
height: obj.size.height,
|
||||
x: obj.bounds.x,
|
||||
y: obj.bounds.y,
|
||||
scale: obj.scaleFactor,
|
||||
primary: (obj.bounds.x === 0 && obj.bounds.y === 0)
|
||||
};
|
||||
const primary = sm.primary ? ' (Primary)' : '';
|
||||
sm.name = `${sm.width}x${sm.height}${primary}`;
|
||||
return sm;
|
||||
}
|
||||
function displaySort(a, b) {
|
||||
if (a.primary) {
|
||||
return -1;
|
||||
}
|
||||
else if (b.primary) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
async function displays() {
|
||||
let displays = electron_1.screen.getAllDisplays();
|
||||
displays = displays.map(displayMap);
|
||||
displays.sort(displaySort);
|
||||
return displays;
|
||||
}
|
||||
/**
|
||||
* Profile the current system and return an object with
|
||||
* data about the displays and dependencies for the digital
|
||||
* projector feature.
|
||||
*
|
||||
* @returns {object} Object containing system information
|
||||
*/
|
||||
async function system(ui) {
|
||||
const obj = {};
|
||||
let platform;
|
||||
try {
|
||||
obj.tmp = os_1.tmpdir();
|
||||
}
|
||||
catch (err) {
|
||||
obj.tmp = '/tmp';
|
||||
}
|
||||
platform = os_1.type();
|
||||
if (platform === 'Darwin') {
|
||||
obj.platform = 'osx';
|
||||
}
|
||||
else if (platform === 'Windows_NT') {
|
||||
obj.platform = 'win';
|
||||
}
|
||||
else {
|
||||
obj.platform = 'nix';
|
||||
}
|
||||
obj.displays = await displays();
|
||||
obj.deps = await dependencies(obj.platform);
|
||||
setTimeout(() => {
|
||||
ui.send('system', obj);
|
||||
}, 3000);
|
||||
return obj;
|
||||
}
|
||||
module.exports = system;
|
||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/system/index.ts"],"names":[],"mappings":"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"}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "system",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,51 +0,0 @@
|
|||
{
|
||||
"name": "mcopy-cli",
|
||||
"version": "1.6.6",
|
||||
"description": "CLI for controlling the mcopy optical printer platform",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sixteenmillimeter/mcopy.git"
|
||||
},
|
||||
"author": "mmcwilliams",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sixteenmillimeter/mcopy/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sixteenmillimeter/mcopy#readme",
|
||||
"dependencies": {
|
||||
"arduino": "file:lib/arduino",
|
||||
"cam": "file:lib/cam",
|
||||
"cmd": "file:lib/cmd",
|
||||
"commander": "^4.0.1",
|
||||
"delay": "file:../app/lib/delay",
|
||||
"device": "file:lib/device",
|
||||
"devices": "file:lib/devices",
|
||||
"filmout": "file:lib/filmout",
|
||||
"display": "file:lib/display",
|
||||
"exec": "file:lib/exec",
|
||||
"exit": "file:lib/exit",
|
||||
"fs-extra": "^8.1.0",
|
||||
"humanize-duration": "^3.21.0",
|
||||
"intval": "file:lib/intval",
|
||||
"light": "file:lib/light",
|
||||
"log": "file:lib/log",
|
||||
"moment": "^2.24.0",
|
||||
"mscript": "file:../app/lib/mscript",
|
||||
"proj": "file:lib/proj",
|
||||
"request": "^2.88.0",
|
||||
"sequencer": "file:lib/sequencer",
|
||||
"serialport": "^8.0.5",
|
||||
"settings": "file:lib/settings",
|
||||
"spawn": "file:lib/spawn",
|
||||
"systeminformation": "^4.27.11",
|
||||
"uuid": "^3.3.3",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"pkg": "^4.4.2"
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { exec } = require('pkg')
|
||||
const execRaw = require('child_process').exec
|
||||
const os = require('os')
|
||||
const fs = require('fs-extra')
|
||||
const packageJson = require('./package.json')
|
||||
|
||||
const platform = os.platform()
|
||||
const arch = os.arch()
|
||||
const name = packageJson.name;
|
||||
|
||||
/**
|
||||
* Shells out to execute a command with async/await.
|
||||
* Async wrapper to exec module.
|
||||
*
|
||||
* @param {string} cmd Command to execute
|
||||
*
|
||||
* @returns {Promise} Promise containing the complete stdio
|
||||
**/
|
||||
async function shell_out (cmd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return execRaw(cmd, (err, stdio, stderr) => {
|
||||
if (err) return reject(err)
|
||||
return resolve(stdio)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//exec(args) takes an array of command line arguments and returns a promise. For example:
|
||||
|
||||
if (!fs.existsSync(`./dist/${platform}_${arch}`)) {
|
||||
fs.mkdirSync(`./dist/${platform}_${arch}`)
|
||||
}
|
||||
|
||||
console.log(`Building frameloom and saving in dist/${platform}_${arch}...`)
|
||||
console.time('frameloom')
|
||||
exec([ 'frameloom', '--target', 'host', '--output', `./dist/${platform}_${arch}/frameloom` ]).then(async (res) => {
|
||||
try {
|
||||
await shell_out(`zip -r ./dist/frameloom_${platform}_${arch}_${packageJson.version}.zip ./dist/${platform}_${arch}/frameloom`)
|
||||
console.log(`Compressed binary to dist/frameloom_${platform}_${arch}_${packageJson.version}.zip`)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
process.exit(err)
|
||||
}
|
||||
|
||||
console.timeEnd('frameloom')
|
||||
console.log('built')
|
||||
}).catch(err => {
|
||||
console.error(err)
|
||||
})
|
|
@ -7,10 +7,8 @@ mkdir -p lib
|
|||
#electron-build fails when local modules are in parent directory
|
||||
#copy them into lib directory
|
||||
cp -r ./lib/* ./app/lib/
|
||||
cp -r ./lib/* ./cli/lib/
|
||||
|
||||
rm -r ./lib
|
||||
|
||||
cp ./data/cfg.json ./app/data/
|
||||
cp ./data/cfg.json ./cli/data/
|
||||
cp ./data/cfg.json ./processing/mcopy/
|
|
@ -6,7 +6,7 @@ npm version --no-git-tag-version ${1}
|
|||
version=$(jq -r '.version' ./package.json)
|
||||
echo "VERSION: $version"
|
||||
|
||||
declare -a fileArr=("./data/cfg.json" "./app/package.json" "./cli/package.json")
|
||||
declare -a fileArr=("./data/cfg.json" "./app/package.json")
|
||||
|
||||
for i in "${fileArr[@]}"
|
||||
do
|
||||
|
|
Loading…
Reference in New Issue