Compare commits
No commits in common. "c4119ab7cc5c2ac80efac6c4bd39ebf96c0e8b70" and "8b235bb6b0f13553bafab0d1a5672651974aa09b" have entirely different histories.
c4119ab7cc
...
8b235bb6b0
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"ext_port": 1111,
|
"ext_port": 1111,
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"mcopy": {
|
"mcopy": {
|
||||||
|
|
|
@ -54,13 +54,10 @@ class Arduino {
|
||||||
async init() {
|
async init() {
|
||||||
const Log = require('log');
|
const Log = require('log');
|
||||||
this.log = await Log({ label: 'arduino' });
|
this.log = await Log({ label: 'arduino' });
|
||||||
this.keys = Object.keys(cfg.arduino.cmd);
|
|
||||||
this.values = this.keys.map(key => cfg.arduino.cmd[key]);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Enumerate all connected devices that might be Arduinos
|
* Enumerate all connected devices that might be Arduinos
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @returns {Promise} Resolves after enumerating
|
* @returns {Promise} Resolves after enumerating
|
||||||
**/
|
**/
|
||||||
async enumerate() {
|
async enumerate() {
|
||||||
|
@ -101,10 +98,9 @@ class Arduino {
|
||||||
/**
|
/**
|
||||||
* Send a command to an Arduino using async/await
|
* Send a command to an Arduino using async/await
|
||||||
*
|
*
|
||||||
* @param {string} device The Arduino device identifier
|
* @param {string} device Arduino identifier
|
||||||
* @param {string} cmd Single character command to send
|
* @param {string} cmd Single character command to send
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @returns {Promise} Resolves after sending
|
* @returns {Promise} Resolves after sending
|
||||||
**/
|
**/
|
||||||
async sendAsync(device, cmd) {
|
async sendAsync(device, cmd) {
|
||||||
|
@ -123,15 +119,7 @@ class Arduino {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Sends a command to the specified Arduino and waits for a response.
|
|
||||||
* Handles the communication lock to prevent sending multiple commands simultaneously.
|
|
||||||
* Emits an 'arduino_send' event after successfully sending the command.
|
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @param {string} device - The Arduino device identifier.
|
|
||||||
* @param {string} cmd - The command to be sent to the Arduino.
|
|
||||||
* @returns {Promise<boolean|string>} Returns 'false' if the communication is locked, otherwise returns the response from the device.
|
|
||||||
* @throws {Error} Throws an error if the sendAsync method encounters an error.
|
|
||||||
**/
|
**/
|
||||||
async send(device, cmd) {
|
async send(device, cmd) {
|
||||||
const serial = this.alias[device];
|
const serial = this.alias[device];
|
||||||
|
@ -155,15 +143,7 @@ class Arduino {
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Sends a string to the specified Arduino.
|
|
||||||
* Handles different types of devices, including fake devices for testing purposes.
|
|
||||||
* Waits for a specified delay before sending the string.
|
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @param {string} device - The Arduino device identifier.
|
|
||||||
* @param {string} str - The string to be sent to the Arduino.
|
|
||||||
* @returns {Promise<boolean|string>} Returns 'true' if the string is sent successfully, otherwise returns an error message.
|
|
||||||
* @throws {Error} Throws an error if the writeAsync method encounters an error.
|
|
||||||
**/
|
**/
|
||||||
async sendString(device, str) {
|
async sendString(device, str) {
|
||||||
let writeSuccess;
|
let writeSuccess;
|
||||||
|
@ -260,13 +240,7 @@ class Arduino {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Handles the end of communication with the Arduino.
|
|
||||||
* Calculates the time taken for the communication, executes the callback,
|
|
||||||
* and emits an 'arduino_end' event. Handles errors and stray data received.
|
|
||||||
*
|
*
|
||||||
* @param {string} serial - The serial address of the Arduino device.
|
|
||||||
* @param {string} data - The data received from the Arduino.
|
|
||||||
* @returns {any} The time taken for the communication in milliseconds.
|
|
||||||
**/
|
**/
|
||||||
end(serial, data) {
|
end(serial, data) {
|
||||||
const end = new Date().getTime();
|
const end = new Date().getTime();
|
||||||
|
@ -290,42 +264,19 @@ class Arduino {
|
||||||
else if (data[0] === cfg.arduino.cmd.error) {
|
else if (data[0] === cfg.arduino.cmd.error) {
|
||||||
this.log.error(`Received error from device ${serial}`);
|
this.log.error(`Received error from device ${serial}`);
|
||||||
this.unlock(serial);
|
this.unlock(serial);
|
||||||
this.error(serial, data);
|
|
||||||
//error state
|
//error state
|
||||||
//stop sequence
|
//stop sequence
|
||||||
//throw error in ui
|
//throw error in ui
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.log.info('Received stray "' + data + '"'); //silent to user
|
//this.log.info('Received stray "' + data + '"') //silent to user
|
||||||
}
|
}
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}
|
||||||
error(serial, data) {
|
|
||||||
this.log.error("ERROR", data);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Associates an alias with an Arduinos serial address.
|
|
||||||
* Used to map multi-purpose devices onto the same serial connection.
|
|
||||||
*
|
|
||||||
* @param {string} device - The serial number of the target Arduino.
|
|
||||||
* @param {string} serial - The alias to be associated with the target device.
|
|
||||||
**/
|
|
||||||
aliasSerial(device, serial) {
|
aliasSerial(device, serial) {
|
||||||
//this.log.info(`Making "${serial}" an alias of ${device}`)
|
//this.log.info(`Making "${serial}" an alias of ${device}`)
|
||||||
this.alias[device] = serial;
|
this.alias[device] = serial;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Connects to an Arduino using its serial number.
|
|
||||||
* Sets up the SerialPort instance and path for the device, and handles data communication.
|
|
||||||
* Handles opening the connection and emitting 'arduino_end' or 'confirmEnd' events upon receiving data.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} device - The device identifier (common name).
|
|
||||||
* @param {string} serial - The serial address of the target Arduino (e.g., COM port on Windows).
|
|
||||||
* @param {function} confirm - A callback function to be executed upon receiving confirmation data.
|
|
||||||
* @returns {Promise<string>} Resolves with the device path if the connection is successful.
|
|
||||||
* @throws {Error} Rejects with an error message if the connection fails.
|
|
||||||
**/
|
|
||||||
async connect(device, serial, confirm) {
|
async connect(device, serial, confirm) {
|
||||||
//this.log.info(`connect device ${device}`)
|
//this.log.info(`connect device ${device}`)
|
||||||
//this.log.info(`connect serial ${serial}`)
|
//this.log.info(`connect serial ${serial}`)
|
||||||
|
@ -344,7 +295,7 @@ class Arduino {
|
||||||
connectSuccess = await this.openArduino(device);
|
connectSuccess = await this.openArduino(device);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
this.log.error(`Failed to open ${device} @ ${serial}: ` + e);
|
this.log.error('failed to open: ' + e);
|
||||||
return reject(e);
|
return reject(e);
|
||||||
}
|
}
|
||||||
this.log.info(`Opened connection with ${this.path[device]} as ${device}`);
|
this.log.info(`Opened connection with ${this.path[device]} as ${device}`);
|
||||||
|
@ -365,14 +316,30 @@ class Arduino {
|
||||||
return resolve(this.path[serial]);
|
return resolve(this.path[serial]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Handles the confirmation data received from an Arduino.
|
|
||||||
* Executes the confirmation callback function if the received data is present in the list of expected values.
|
|
||||||
*
|
|
||||||
* @param {string} data - The data received from the Arduino.
|
|
||||||
**/
|
|
||||||
confirmEnd(data) {
|
confirmEnd(data) {
|
||||||
if (this.values.indexOf(data) !== -1) {
|
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
|
||||||
|
|| data === cfg.arduino.cmd.capper_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_projector_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
|
||||||
this.confirmExec(null, data);
|
this.confirmExec(null, data);
|
||||||
this.confirmExec = {};
|
this.confirmExec = {};
|
||||||
this.unlock(this.alias['connect']);
|
this.unlock(this.alias['connect']);
|
||||||
|
@ -383,14 +350,6 @@ class Arduino {
|
||||||
this.unlock(this.alias['connect']);
|
this.unlock(this.alias['connect']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Verifies the connection to an Arduino by sending a connect command.
|
|
||||||
* The confirmation callback checks if the received data matches the expected connect command.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the connection is verified successfully.
|
|
||||||
* @throws {Error} Rejects with an error message if the connection verification fails.
|
|
||||||
**/
|
|
||||||
async verify() {
|
async verify() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const device = 'connect';
|
const device = 'connect';
|
||||||
|
@ -413,14 +372,6 @@ class Arduino {
|
||||||
return resolve(writeSuccess);
|
return resolve(writeSuccess);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Distinguishes the type of Arduino connected.
|
|
||||||
* Sends a command to the device to identify its type and resolves the promise with the received type.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<string>} Resolves with the type of the connected Arduino-based device.
|
|
||||||
* @throws {Error} Rejects with an error message if the distinguish operation fails.
|
|
||||||
**/
|
|
||||||
async distinguish() {
|
async distinguish() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const device = 'connect';
|
const device = 'connect';
|
||||||
|
@ -490,13 +441,6 @@ class Arduino {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Closes the connection to an Arduino.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the connection is closed successfully.
|
|
||||||
* @throws {Error} Throws an error if the closeArduino method encounters an error.
|
|
||||||
**/
|
|
||||||
async close() {
|
async close() {
|
||||||
const device = 'connect';
|
const device = 'connect';
|
||||||
let closeSuccess;
|
let closeSuccess;
|
||||||
|
@ -508,14 +452,6 @@ class Arduino {
|
||||||
}
|
}
|
||||||
return closeSuccess;
|
return closeSuccess;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Establishes a fake connection to an Arduino for testing purposes.
|
|
||||||
* Creates a fake SerialPort instance with custom write and string methods.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} serial - The device identifier of the fake Arduino.
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the fake connection is established successfully.
|
|
||||||
**/
|
|
||||||
async fakeConnect(device) {
|
async fakeConnect(device) {
|
||||||
const serial = '/dev/fake';
|
const serial = '/dev/fake';
|
||||||
this.aliasSerial(device, serial);
|
this.aliasSerial(device, serial);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const path_1 = require("path");
|
const path_1 = require("path");
|
||||||
const url_1 = require("url");
|
const url_1 = require("url");
|
||||||
const delay_1 = require("delay");
|
const delay_1 = require("delay");
|
||||||
const Log = require("log");
|
|
||||||
const { BrowserWindow } = require('electron');
|
const { BrowserWindow } = require('electron');
|
||||||
class WebView {
|
class WebView {
|
||||||
constructor(platform, display) {
|
constructor(platform, display) {
|
||||||
|
@ -32,7 +31,6 @@ class WebView {
|
||||||
pathname: pagePath,
|
pathname: pagePath,
|
||||||
protocol: 'file:'
|
protocol: 'file:'
|
||||||
});
|
});
|
||||||
this.init();
|
|
||||||
if (!display.primary) {
|
if (!display.primary) {
|
||||||
prefs.x = display.x + 50;
|
prefs.x = display.x + 50;
|
||||||
prefs.y = display.y + 50;
|
prefs.y = display.y + 50;
|
||||||
|
@ -53,9 +51,6 @@ class WebView {
|
||||||
this.ipc = require('electron').ipcMain;
|
this.ipc = require('electron').ipcMain;
|
||||||
this.ipc.on('display_load', this.onLoad.bind(this));
|
this.ipc.on('display_load', this.onLoad.bind(this));
|
||||||
}
|
}
|
||||||
async init() {
|
|
||||||
this.log = await Log({ label: 'devices' });
|
|
||||||
}
|
|
||||||
async open() {
|
async open() {
|
||||||
this.digitalWindow.show();
|
this.digitalWindow.show();
|
||||||
this.showing = true;
|
this.showing = true;
|
||||||
|
@ -69,14 +64,14 @@ class WebView {
|
||||||
async show(src) {
|
async show(src) {
|
||||||
const normalSrc = path_1.normalize(path_1.join(src));
|
const normalSrc = path_1.normalize(path_1.join(src));
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show "${src}" because window does not exist`);
|
console.warn(`Cannot show "${src}" because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.digitalWindow.webContents.send('display', { src: normalSrc });
|
this.digitalWindow.webContents.send('display', { src: normalSrc });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
this.showing = true;
|
this.showing = true;
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
|
@ -91,7 +86,7 @@ class WebView {
|
||||||
}
|
}
|
||||||
async focus() {
|
async focus() {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show focus screen because window does not exist`);
|
console.warn(`Cannot show focus screen because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay_1.delay(500);
|
await delay_1.delay(500);
|
||||||
|
@ -99,12 +94,12 @@ class WebView {
|
||||||
this.digitalWindow.webContents.send('focus', { focus: true });
|
this.digitalWindow.webContents.send('focus', { focus: true });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async field(ratio) {
|
async field(ratio) {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show field guide because window does not exist`);
|
console.warn(`Cannot show field guide because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay_1.delay(500);
|
await delay_1.delay(500);
|
||||||
|
@ -112,12 +107,12 @@ class WebView {
|
||||||
this.digitalWindow.webContents.send('field', { field: true, ratio });
|
this.digitalWindow.webContents.send('field', { field: true, ratio });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async meter() {
|
async meter() {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show meter screen because window does not exist`);
|
console.warn(`Cannot show meter screen because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay_1.delay(500);
|
await delay_1.delay(500);
|
||||||
|
@ -125,7 +120,7 @@ class WebView {
|
||||||
this.digitalWindow.webContents.send('meter', { meter: true });
|
this.digitalWindow.webContents.send('meter', { meter: true });
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hide() {
|
hide() {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "mcopy-app",
|
"name": "mcopy-app",
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "mcopy-app",
|
"name": "mcopy-app",
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"description": "GUI for the mcopy small gauge film optical printer platform",
|
"description": "GUI for the mcopy small gauge film optical printer platform",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"ext_port": 1111,
|
"ext_port": 1111,
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"mcopy": {
|
"mcopy": {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "mcopy",
|
"name": "mcopy",
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mcopy",
|
"name": "mcopy",
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"arduino": "file:app/lib/arduino",
|
"arduino": "file:app/lib/arduino",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "mcopy",
|
"name": "mcopy",
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"description": "Small gauge film optical printer platform",
|
"description": "Small gauge film optical printer platform",
|
||||||
"main": "build.js",
|
"main": "build.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.7.24",
|
"version": "1.7.22",
|
||||||
"ext_port": 1111,
|
"ext_port": 1111,
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"mcopy": {
|
"mcopy": {
|
||||||
|
|
|
@ -57,8 +57,6 @@ class Arduino {
|
||||||
private locks : any = {};
|
private locks : any = {};
|
||||||
private confirmExec : any;
|
private confirmExec : any;
|
||||||
private errorState : Function;
|
private errorState : Function;
|
||||||
private keys : string[];
|
|
||||||
private values : string[];
|
|
||||||
|
|
||||||
public stateStr : any = {};
|
public stateStr : any = {};
|
||||||
|
|
||||||
|
@ -70,14 +68,11 @@ class Arduino {
|
||||||
async init () {
|
async init () {
|
||||||
const Log = require('log');
|
const Log = require('log');
|
||||||
this.log = await Log({ label : 'arduino' });
|
this.log = await Log({ label : 'arduino' });
|
||||||
this.keys = Object.keys(cfg.arduino.cmd);
|
|
||||||
this.values = this.keys.map(key => cfg.arduino.cmd[key]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumerate all connected devices that might be Arduinos
|
* Enumerate all connected devices that might be Arduinos
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @returns {Promise} Resolves after enumerating
|
* @returns {Promise} Resolves after enumerating
|
||||||
**/
|
**/
|
||||||
public async enumerate () : Promise<string[]>{
|
public async enumerate () : Promise<string[]>{
|
||||||
|
@ -113,10 +108,9 @@ class Arduino {
|
||||||
/**
|
/**
|
||||||
* Send a command to an Arduino using async/await
|
* Send a command to an Arduino using async/await
|
||||||
*
|
*
|
||||||
* @param {string} device The Arduino device identifier
|
* @param {string} device Arduino identifier
|
||||||
* @param {string} cmd Single character command to send
|
* @param {string} cmd Single character command to send
|
||||||
*
|
*
|
||||||
* @async
|
|
||||||
* @returns {Promise} Resolves after sending
|
* @returns {Promise} Resolves after sending
|
||||||
**/
|
**/
|
||||||
private async sendAsync (device : string, cmd : string) : Promise<number> {
|
private async sendAsync (device : string, cmd : string) : Promise<number> {
|
||||||
|
@ -136,15 +130,7 @@ class Arduino {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a command to the specified Arduino and waits for a response.
|
*
|
||||||
* Handles the communication lock to prevent sending multiple commands simultaneously.
|
|
||||||
* Emits an 'arduino_send' event after successfully sending the command.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} device - The Arduino device identifier.
|
|
||||||
* @param {string} cmd - The command to be sent to the Arduino.
|
|
||||||
* @returns {Promise<boolean|string>} Returns 'false' if the communication is locked, otherwise returns the response from the device.
|
|
||||||
* @throws {Error} Throws an error if the sendAsync method encounters an error.
|
|
||||||
**/
|
**/
|
||||||
public async send (device : string, cmd : string) : Promise<any> {
|
public async send (device : string, cmd : string) : Promise<any> {
|
||||||
const serial : any = this.alias[device]
|
const serial : any = this.alias[device]
|
||||||
|
@ -169,15 +155,7 @@ class Arduino {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a string to the specified Arduino.
|
*
|
||||||
* Handles different types of devices, including fake devices for testing purposes.
|
|
||||||
* Waits for a specified delay before sending the string.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} device - The Arduino device identifier.
|
|
||||||
* @param {string} str - The string to be sent to the Arduino.
|
|
||||||
* @returns {Promise<boolean|string>} Returns 'true' if the string is sent successfully, otherwise returns an error message.
|
|
||||||
* @throws {Error} Throws an error if the writeAsync method encounters an error.
|
|
||||||
**/
|
**/
|
||||||
public async sendString (device : string, str : string) : Promise<any> {
|
public async sendString (device : string, str : string) : Promise<any> {
|
||||||
let writeSuccess : any
|
let writeSuccess : any
|
||||||
|
@ -278,15 +256,9 @@ class Arduino {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the end of communication with the Arduino.
|
*
|
||||||
* Calculates the time taken for the communication, executes the callback,
|
**/
|
||||||
* and emits an 'arduino_end' event. Handles errors and stray data received.
|
|
||||||
*
|
|
||||||
* @param {string} serial - The serial address of the Arduino device.
|
|
||||||
* @param {string} data - The data received from the Arduino.
|
|
||||||
* @returns {any} The time taken for the communication in milliseconds.
|
|
||||||
**/
|
|
||||||
private end (serial : string, data : string) : any {
|
private end (serial : string, data : string) : any {
|
||||||
const end : number = new Date().getTime()
|
const end : number = new Date().getTime()
|
||||||
const ms : number = end - this.timer
|
const ms : number = end - this.timer
|
||||||
|
@ -307,42 +279,20 @@ class Arduino {
|
||||||
} else if (data[0] === cfg.arduino.cmd.error) {
|
} else if (data[0] === cfg.arduino.cmd.error) {
|
||||||
this.log.error(`Received error from device ${serial}`)
|
this.log.error(`Received error from device ${serial}`)
|
||||||
this.unlock(serial)
|
this.unlock(serial)
|
||||||
this.error(serial, data)
|
|
||||||
//error state
|
//error state
|
||||||
//stop sequence
|
//stop sequence
|
||||||
//throw error in ui
|
//throw error in ui
|
||||||
} else {
|
} else {
|
||||||
this.log.info('Received stray "' + data + '"') //silent to user
|
//this.log.info('Received stray "' + data + '"') //silent to user
|
||||||
}
|
}
|
||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
private error(serial : string, data : string) {
|
|
||||||
this.log.error("ERROR", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates an alias with an Arduinos serial address.
|
|
||||||
* Used to map multi-purpose devices onto the same serial connection.
|
|
||||||
*
|
|
||||||
* @param {string} device - The serial number of the target Arduino.
|
|
||||||
* @param {string} serial - The alias to be associated with the target device.
|
|
||||||
**/
|
|
||||||
public aliasSerial (device : string, serial : string) {
|
public aliasSerial (device : string, serial : string) {
|
||||||
//this.log.info(`Making "${serial}" an alias of ${device}`)
|
//this.log.info(`Making "${serial}" an alias of ${device}`)
|
||||||
this.alias[device] = serial;
|
this.alias[device] = serial;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Connects to an Arduino using its serial number.
|
|
||||||
* Sets up the SerialPort instance and path for the device, and handles data communication.
|
|
||||||
* Handles opening the connection and emitting 'arduino_end' or 'confirmEnd' events upon receiving data.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} device - The device identifier (common name).
|
|
||||||
* @param {string} serial - The serial address of the target Arduino (e.g., COM port on Windows).
|
|
||||||
* @param {function} confirm - A callback function to be executed upon receiving confirmation data.
|
|
||||||
* @returns {Promise<string>} Resolves with the device path if the connection is successful.
|
|
||||||
* @throws {Error} Rejects with an error message if the connection fails.
|
|
||||||
**/
|
|
||||||
public async connect (device : string, serial : string, confirm : any) : Promise<any> {
|
public async connect (device : string, serial : string, confirm : any) : Promise<any> {
|
||||||
//this.log.info(`connect device ${device}`)
|
//this.log.info(`connect device ${device}`)
|
||||||
//this.log.info(`connect serial ${serial}`)
|
//this.log.info(`connect serial ${serial}`)
|
||||||
|
@ -360,7 +310,7 @@ class Arduino {
|
||||||
try {
|
try {
|
||||||
connectSuccess = await this.openArduino(device)
|
connectSuccess = await this.openArduino(device)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log.error(`Failed to open ${device} @ ${serial}: ` + e)
|
this.log.error('failed to open: ' + e)
|
||||||
return reject(e)
|
return reject(e)
|
||||||
}
|
}
|
||||||
this.log.info(`Opened connection with ${this.path[device]} as ${device}`)
|
this.log.info(`Opened connection with ${this.path[device]} as ${device}`)
|
||||||
|
@ -381,14 +331,35 @@ class Arduino {
|
||||||
return resolve(this.path[serial])
|
return resolve(this.path[serial])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Handles the confirmation data received from an Arduino.
|
|
||||||
* Executes the confirmation callback function if the received data is present in the list of expected values.
|
|
||||||
*
|
|
||||||
* @param {string} data - The data received from the Arduino.
|
|
||||||
**/
|
|
||||||
private confirmEnd (data : string) {
|
private confirmEnd (data : string) {
|
||||||
if (this.values.indexOf(data) !== -1) {
|
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
|
||||||
|
|
||||||
|
|| data === cfg.arduino.cmd.capper_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_projector_identifier
|
||||||
|
|| data === cfg.arduino.cmd.camera_capper_projectors_identifier) {
|
||||||
|
|
||||||
this.confirmExec(null, data)
|
this.confirmExec(null, data)
|
||||||
this.confirmExec = {}
|
this.confirmExec = {}
|
||||||
this.unlock(this.alias['connect'])
|
this.unlock(this.alias['connect'])
|
||||||
|
@ -398,14 +369,7 @@ class Arduino {
|
||||||
this.unlock(this.alias['connect'])
|
this.unlock(this.alias['connect'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Verifies the connection to an Arduino by sending a connect command.
|
|
||||||
* The confirmation callback checks if the received data matches the expected connect command.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the connection is verified successfully.
|
|
||||||
* @throws {Error} Rejects with an error message if the connection verification fails.
|
|
||||||
**/
|
|
||||||
public async verify () {
|
public async verify () {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const device : string = 'connect'
|
const device : string = 'connect'
|
||||||
|
@ -428,15 +392,8 @@ class Arduino {
|
||||||
return resolve(writeSuccess)
|
return resolve(writeSuccess)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Distinguishes the type of Arduino connected.
|
public async distinguish () {
|
||||||
* Sends a command to the device to identify its type and resolves the promise with the received type.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<string>} Resolves with the type of the connected Arduino-based device.
|
|
||||||
* @throws {Error} Rejects with an error message if the distinguish operation fails.
|
|
||||||
**/
|
|
||||||
public async distinguish () : Promise<string> {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const device : string = 'connect'
|
const device : string = 'connect'
|
||||||
let writeSuccess : any
|
let writeSuccess : any
|
||||||
|
@ -490,14 +447,8 @@ class Arduino {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Closes the connection to an Arduino.
|
public async close () {
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the connection is closed successfully.
|
|
||||||
* @throws {Error} Throws an error if the closeArduino method encounters an error.
|
|
||||||
**/
|
|
||||||
public async close () : Promise<boolean> {
|
|
||||||
const device : string = 'connect'
|
const device : string = 'connect'
|
||||||
let closeSuccess : boolean
|
let closeSuccess : boolean
|
||||||
try {
|
try {
|
||||||
|
@ -507,14 +458,7 @@ class Arduino {
|
||||||
}
|
}
|
||||||
return closeSuccess
|
return closeSuccess
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Establishes a fake connection to an Arduino for testing purposes.
|
|
||||||
* Creates a fake SerialPort instance with custom write and string methods.
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param {string} serial - The device identifier of the fake Arduino.
|
|
||||||
* @returns {Promise<boolean>} Resolves with 'true' if the fake connection is established successfully.
|
|
||||||
**/
|
|
||||||
public async fakeConnect (device : string) {
|
public async fakeConnect (device : string) {
|
||||||
const serial : string = '/dev/fake'
|
const serial : string = '/dev/fake'
|
||||||
this.aliasSerial(device, serial)
|
this.aliasSerial(device, serial)
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import { join as pathJoin, normalize as pathNormalize } from 'path';
|
import { join as pathJoin, normalize as pathNormalize } from 'path';
|
||||||
import { format as urlFormat } from 'url';
|
import { format as urlFormat } from 'url';
|
||||||
import { delay } from 'delay';
|
import { delay } from 'delay';
|
||||||
import Log = require('log');
|
|
||||||
|
|
||||||
const { BrowserWindow } = require('electron');
|
const { BrowserWindow } = require('electron');
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@ class WebView {
|
||||||
public display : any;
|
public display : any;
|
||||||
private loadWait : any = {};
|
private loadWait : any = {};
|
||||||
private ipc : any;
|
private ipc : any;
|
||||||
private log : any;
|
|
||||||
|
|
||||||
constructor (platform : string, display : any) {
|
constructor (platform : string, display : any) {
|
||||||
const prefs : any = {
|
const prefs : any = {
|
||||||
|
@ -41,8 +39,6 @@ class WebView {
|
||||||
pathname : pagePath,
|
pathname : pagePath,
|
||||||
protocol : 'file:'
|
protocol : 'file:'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.init();
|
|
||||||
if (!display.primary) {
|
if (!display.primary) {
|
||||||
prefs.x = display.x + 50;
|
prefs.x = display.x + 50;
|
||||||
prefs.y = display.y + 50;
|
prefs.y = display.y + 50;
|
||||||
|
@ -65,9 +61,6 @@ class WebView {
|
||||||
|
|
||||||
this.ipc.on('display_load', this.onLoad.bind(this));
|
this.ipc.on('display_load', this.onLoad.bind(this));
|
||||||
}
|
}
|
||||||
async init () {
|
|
||||||
this.log = await Log({ label : 'devices' })
|
|
||||||
}
|
|
||||||
async open () {
|
async open () {
|
||||||
this.digitalWindow.show();
|
this.digitalWindow.show();
|
||||||
this.showing = true;
|
this.showing = true;
|
||||||
|
@ -81,13 +74,13 @@ class WebView {
|
||||||
async show (src : string) {
|
async show (src : string) {
|
||||||
const normalSrc : string = pathNormalize(pathJoin(src));
|
const normalSrc : string = pathNormalize(pathJoin(src));
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show "${src}" because window does not exist`)
|
console.warn(`Cannot show "${src}" because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.digitalWindow.webContents.send('display', { src : normalSrc });
|
this.digitalWindow.webContents.send('display', { src : normalSrc });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
this.showing = true;
|
this.showing = true;
|
||||||
|
|
||||||
|
@ -104,38 +97,38 @@ class WebView {
|
||||||
}
|
}
|
||||||
async focus () {
|
async focus () {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show focus screen because window does not exist`);
|
console.warn(`Cannot show focus screen because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay(500);
|
await delay(500);
|
||||||
try {
|
try {
|
||||||
this.digitalWindow.webContents.send('focus', { focus : true });
|
this.digitalWindow.webContents.send('focus', { focus : true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async field (ratio : number) {
|
async field (ratio : number) {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show field guide because window does not exist`);
|
console.warn(`Cannot show field guide because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay(500);
|
await delay(500);
|
||||||
try {
|
try {
|
||||||
this.digitalWindow.webContents.send('field', { field : true, ratio });
|
this.digitalWindow.webContents.send('field', { field : true, ratio });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async meter () {
|
async meter () {
|
||||||
if (!this.digitalWindow) {
|
if (!this.digitalWindow) {
|
||||||
this.log.warn(`Cannot show meter screen because window does not exist`);
|
console.warn(`Cannot show meter screen because window does not exist`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await delay(500);
|
await delay(500);
|
||||||
try {
|
try {
|
||||||
this.digitalWindow.webContents.send('meter', { meter : true });
|
this.digitalWindow.webContents.send('meter', { meter : true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.log.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hide () {
|
hide () {
|
||||||
|
|
Loading…
Reference in New Issue