comms changes
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
|
||||
const nano = {
|
||||
get(pid, tid, vid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ pid: pid, tid: tid, vid: vid, value: 0.0 });
|
||||
});
|
||||
},
|
||||
|
||||
set(pid, tid, vid, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({ pid: pid, tid: tid, vid: vid, value: value });
|
||||
});
|
||||
},
|
||||
|
||||
onValueReceived(listener) {
|
||||
}
|
||||
};
|
||||
|
||||
export default nano;
|
||||
@@ -1,23 +1,137 @@
|
||||
import { SerialPort } from 'serialport';
|
||||
|
||||
|
||||
const NANO_PRODUCT_ID = '7523';
|
||||
const NANO_VENDOR_ID = '1a86';
|
||||
const NANO_BAUD_RATE = 115200;
|
||||
|
||||
|
||||
const nanodevices = {
|
||||
list() {
|
||||
return [];
|
||||
|
||||
all_nano_devices: {},
|
||||
connected_nano_devices: {},
|
||||
|
||||
_list() {
|
||||
let p = new Promise();
|
||||
SerialPort.list().then((ports, err) => {
|
||||
if (err) {
|
||||
p.reject(err); // TODO format for errors?
|
||||
}
|
||||
else {
|
||||
console.log('ports', ports)
|
||||
let found_nano_devices = []
|
||||
for (let port of ports) {
|
||||
if (port.productId === NANO_PRODUCT_ID && port.vendorId === NANO_VENDOR_ID) {
|
||||
found_nano_devices.push(port.serialNumber);
|
||||
if (this.all_nano_devices[port.serialNumber] === undefined) {
|
||||
this.all_nano_devices[port.serialNumber] = port;
|
||||
this.emit('nanodevices:device-attached', { id: port.serialNumber });
|
||||
}
|
||||
}
|
||||
}
|
||||
p.resolve(found_nano_devices);
|
||||
for (let serialNumber in this.all_nano_devices) {
|
||||
if (found_nano_devices.indexOf(serialNumber) === -1) {
|
||||
delete this.all_nano_devices[serialNumber];
|
||||
this.emit('nanodevices:device-detached', { id: serialNumber });
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return p;
|
||||
},
|
||||
|
||||
async connect(devicename) {
|
||||
return true;
|
||||
|
||||
_handle_data(connected_port, data) {
|
||||
connected_port.data += data;
|
||||
let lines = connected_port.data.split('\n');
|
||||
if (lines.length > 1) {
|
||||
for (let i = 0; i < lines.length - 1; i++) {
|
||||
this.emit('nanodevices:update', connected_port.serialNumber, lines[i]);
|
||||
}
|
||||
connected_port.data = lines[lines.length - 1];
|
||||
}
|
||||
},
|
||||
|
||||
async disconnect() {
|
||||
return true;
|
||||
|
||||
list_devices() {
|
||||
let result = [];
|
||||
for (const [key, value] of Object.entries(this.all_nano_devices)) {
|
||||
if (value.serialNumber)
|
||||
result.push(key);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
onAttach(listener) {
|
||||
|
||||
async send(deviceid, jsonstr) {
|
||||
let connected_port = this.connected_nano_devices[deviceid];
|
||||
if (connected_port === undefined) {
|
||||
return Promise.reject('Device not connected');
|
||||
}
|
||||
else {
|
||||
connected_port.port.write(jsonstr+'\n');
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
onDetach(listener) {
|
||||
|
||||
|
||||
async connect(deviceid) {
|
||||
let p = new Promise();
|
||||
let nano_device = this.all_nano_devices[deviceid];
|
||||
if (nano_device === undefined) {
|
||||
p.reject('Device not attached');
|
||||
}
|
||||
else {
|
||||
let port = new SerialPort(nano_device.path, { baudRate: NANO_BAUD_RATE, autoOpen: false });
|
||||
port.on('error', (err) => {
|
||||
// forward error to FE
|
||||
this.emit('nanodevices:error', { id: nano_device.serialNumber }, err);
|
||||
});
|
||||
port.on('close', (err) => {
|
||||
if (err && err.disconnected) {
|
||||
// forward close to FE
|
||||
this.emit('nanodevices:disconnected', { id: nano_device.serialNumber });
|
||||
}
|
||||
delete this.connected_nano_devices[nano_device.serialNumber];
|
||||
});
|
||||
port.on('open', () => {
|
||||
p.resolve(nano_device.serialNumber);
|
||||
this.connected_nano_devices[nano_device.serialNumber] = { port: port, data: '' };
|
||||
this.emit('nanodevices:connected', { id: nano_device.serialNumber });
|
||||
});
|
||||
port.on('data', (data) => {
|
||||
let connected_port = this.connected_nano_devices[nano_device.serialNumber];
|
||||
this._handle_data(connected_port, data);
|
||||
});
|
||||
port.open((err)=>{
|
||||
if (err) {
|
||||
p.reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
return p;
|
||||
},
|
||||
|
||||
|
||||
disconnect(deviceid) {
|
||||
let p = new Promise();
|
||||
let nano_device = this.all_nano_devices[deviceid];
|
||||
if (nano_device === undefined) {
|
||||
p.reject('Device not attached');
|
||||
}
|
||||
else {
|
||||
if (this.connected_nano_devices[nano_device.serialNumber] === undefined) {
|
||||
p.reject('Device not connected');
|
||||
}
|
||||
else {
|
||||
nano_device.close();
|
||||
p.resolve(nano_device.serialNumber);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default nanodevices;
|
||||
|
||||
45
src/main.js
45
src/main.js
@@ -3,8 +3,6 @@ import path from 'path'
|
||||
import ess from 'electron-squirrel-startup'
|
||||
import { ipcMain } from 'electron'
|
||||
import nanodevices from './backend/nanodevices.js'
|
||||
import nano from './backend/nano.js'
|
||||
|
||||
|
||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||
if (ess) {
|
||||
@@ -130,11 +128,10 @@ const createLoadingWindow = (mainWindow) => {
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
ipcMain.handle('nanodevices:list', nanodevices.list)
|
||||
ipcMain.handle('nanodevices:list_devices', nanodevices.list_devices)
|
||||
ipcMain.handle('nanodevices:connect', nanodevices.connect)
|
||||
ipcMain.handle('nanodevices:disconnect', nanodevices.disconnect)
|
||||
ipcMain.handle('nano:get', nano.get)
|
||||
ipcMain.handle('nano:set', nano.set)
|
||||
ipcMain.handle('nanodevices:send', nanodevices.send)
|
||||
const mainWindow = createMainWindow()
|
||||
createLoadingWindow(mainWindow)
|
||||
ipcMain.on('electron:minimizeWindow', () => mainWindow.minimize())
|
||||
@@ -149,17 +146,33 @@ app.whenReady().then(() => {
|
||||
ipcMain.on('electron:openExternal', (_event, url) => shell.openExternal(url))
|
||||
ipcMain.on('electron:openDevTools', () => mainWindow.webContents.toggleDevTools())
|
||||
ipcMain.on('electron:reload', () => mainWindow.webContents.reloadIgnoringCache())
|
||||
nanodevices.onAttach((device) => {
|
||||
console.log('Attached device', device)
|
||||
mainWindow.webContents.send('nanodevice-attached', device)
|
||||
})
|
||||
nanodevices.onDetach((device) => {
|
||||
console.log('Detached device', device)
|
||||
mainWindow.webContents.send('nanodevice-detached', device)
|
||||
})
|
||||
nano.onValueReceived((value) => {
|
||||
console.log('Value received', value)
|
||||
mainWindow.webContents.send('nano-onvalue', value)
|
||||
// nanodevices.on('nanodevices:device-attached', (evt, device) => { // TODO cumbersome, is there a shorthand line nanodevice-* ?
|
||||
// console.log('Attached device', device)
|
||||
// mainWindow.webContents.send('nanodevices:device-attached', device)
|
||||
// })
|
||||
// nanodevices.on('nanodevices:device-detached', (device) => {
|
||||
// console.log('Detached device', device)
|
||||
// mainWindow.webContents.send('nanodevices:device-detached', device)
|
||||
// })
|
||||
// nanodevices.on('nanodevices:connected', (device) => {
|
||||
// console.log('Connected device', device)
|
||||
// mainWindow.webContents.send('nanodevices:connected', device)
|
||||
// })
|
||||
// nanodevices.on('nanodevices:disconnected', (device) => {
|
||||
// console.log('Disconnected device', device)
|
||||
// mainWindow.webContents.send('nanodevices:disconnected', device)
|
||||
// })
|
||||
// nanodevices.on('nanodevices:error', (device, error) => {
|
||||
// console.log('Error on device', device, error)
|
||||
// mainWindow.webContents.send('nanodevices:error', device, error)
|
||||
// })
|
||||
// nanodevices.on('nanodevices:update', (deviceid, jsonstr) => {
|
||||
// console.log('Nano update', jsonstr)
|
||||
// mainWindow.webContents.send('nanodevices:update', deviceid, jsonstr)
|
||||
// })
|
||||
nanodevices.on('nanodevices:event', (eventid, deviceid, ...data) => {
|
||||
console.log('Nano event', eventid, deviceid, data)
|
||||
mainWindow.webContents.send('nanodevices:event', eventid, deviceid, ...data)
|
||||
})
|
||||
const menu = new Menu()
|
||||
for (const menuItem of Object.values(appMenu)) {
|
||||
|
||||
@@ -3,40 +3,27 @@
|
||||
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
|
||||
// expose an API to choose available devices
|
||||
contextBridge.exposeInMainWorld('nanodevices', {
|
||||
list() {
|
||||
ipcRenderer.invoke('nanodevices:list')
|
||||
list_devices() {
|
||||
ipcRenderer.invoke('nanodevices:list_devices');
|
||||
},
|
||||
connect(devicename) {
|
||||
ipcRenderer.invoke('nanodevices:connect', devicename)
|
||||
connect(deviceid) {
|
||||
ipcRenderer.invoke('nanodevices:connect', deviceid);
|
||||
},
|
||||
disconnect() {
|
||||
ipcRenderer.invoke('nanodevices:disconnect')
|
||||
disconnect(deviceid) {
|
||||
ipcRenderer.invoke('nanodevices:disconnect', deviceid);
|
||||
},
|
||||
on_device_attached(listener) {
|
||||
ipcRenderer.on('nanodevice-attached', (_event, value) => listener(value))
|
||||
},
|
||||
on_device_detached(listener) {
|
||||
ipcRenderer.on('nanodevice-detached', (_event, value) => listener(value))
|
||||
},
|
||||
})
|
||||
on(eventid_filter, callback) {
|
||||
ipcRenderer.on('nanodevices:event', (_event, eventid, deviceid, ...data) => {
|
||||
if (eventid_filter=="*" || eventid_filter==eventid) {
|
||||
callback(eventid, deviceid, ...data);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// expose an API to communicate with the nano device
|
||||
contextBridge.exposeInMainWorld('nanodevice', {
|
||||
get_value(pid, tid, vid) {
|
||||
ipcRenderer.invoke('nano:get', pid, tid, vid)
|
||||
},
|
||||
set_value(pid, tid, vid, value) {
|
||||
ipcRenderer.invoke('nano:set', pid, tid, vid, value)
|
||||
},
|
||||
on_value(listener) {
|
||||
ipcRenderer.on('nano-onvalue', (_event, value) => listener(value))
|
||||
},
|
||||
})
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
platform: process.platform,
|
||||
isDevelopment: process.env.NODE_ENV !== 'production',
|
||||
@@ -47,8 +34,8 @@ contextBridge.exposeInMainWorld('electron', {
|
||||
onMaximized: (callback) => ipcRenderer.on('electron:maximized', callback),
|
||||
onUnmaximized: (callback) => ipcRenderer.on('electron:unmaximized', callback),
|
||||
onMenu: (callback) => ipcRenderer.on('electron:menu', (event, key) => {
|
||||
callback(key)
|
||||
callback(key);
|
||||
}),
|
||||
openDevTools: () => ipcRenderer.send('electron:openDevTools'),
|
||||
reload: () => ipcRenderer.send('electron:reload'),
|
||||
})
|
||||
});
|
||||
@@ -50,4 +50,9 @@ app.use(i18n)
|
||||
|
||||
app.config.globalProperties.window = window
|
||||
|
||||
app.mount('#app')
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
window.nanodevices.on('*', (eventid, deviceid, ...data) => {
|
||||
console.log(eventid, deviceid, data)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user