-
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #161 from arduino/development
Development to Main > Release
- Loading branch information
Showing
23 changed files
with
752 additions
and
229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const { ipcRenderer } = require('electron') | ||
const path = require('path') | ||
|
||
const SerialBridge = { | ||
loadPorts: async () => { | ||
return await ipcRenderer.invoke('serial', 'loadPorts') | ||
}, | ||
connect: async (path) => { | ||
return await ipcRenderer.invoke('serial', 'connect', path) | ||
}, | ||
disconnect: async () => { | ||
return await ipcRenderer.invoke('serial', 'disconnect') | ||
}, | ||
run: async (code) => { | ||
return await ipcRenderer.invoke('serial', 'run', code) | ||
}, | ||
execFile: async (path) => { | ||
return await ipcRenderer.invoke('serial', 'execFile', path) | ||
}, | ||
getPrompt: async () => { | ||
return await ipcRenderer.invoke('serial', 'getPrompt') | ||
}, | ||
keyboardInterrupt: async () => { | ||
await ipcRenderer.invoke('serial', 'keyboardInterrupt') | ||
return Promise.resolve() | ||
}, | ||
reset: async () => { | ||
await ipcRenderer.invoke('serial', 'reset') | ||
return Promise.resolve() | ||
}, | ||
eval: (d) => { | ||
return ipcRenderer.invoke('serial', 'eval', d) | ||
}, | ||
onData: (callback) => { | ||
// Remove all previous listeners | ||
if (ipcRenderer.listeners("serial-on-data").length > 0) { | ||
ipcRenderer.removeAllListeners("serial-on-data") | ||
} | ||
ipcRenderer.on('serial-on-data', (event, data) => { | ||
callback(data) | ||
}) | ||
}, | ||
listFiles: async (folder) => { | ||
return await ipcRenderer.invoke('serial', 'listFiles', folder) | ||
}, | ||
ilistFiles: async (folder) => { | ||
return await ipcRenderer.invoke('serial', 'ilistFiles', folder) | ||
}, | ||
loadFile: async (file) => { | ||
return await ipcRenderer.invoke('serial', 'loadFile', file) | ||
}, | ||
removeFile: async (file) => { | ||
return await ipcRenderer.invoke('serial', 'removeFile', file) | ||
}, | ||
saveFileContent: async (filename, content, dataConsumer) => { | ||
return await ipcRenderer.invoke('serial', 'saveFileContent', filename, content, dataConsumer) | ||
}, | ||
uploadFile: async (src, dest, dataConsumer) => { | ||
return await ipcRenderer.invoke('serial', 'uploadFile', src, dest, dataConsumer) | ||
}, | ||
downloadFile: async (src, dest) => { | ||
let contents = await ipcRenderer.invoke('serial', 'loadFile', src) | ||
return ipcRenderer.invoke('save-file', dest, contents) | ||
}, | ||
renameFile: async (oldName, newName) => { | ||
return await ipcRenderer.invoke('serial', 'renameFile', oldName, newName) | ||
}, | ||
onConnectionClosed: async (callback) => { | ||
// Remove all previous listeners | ||
if (ipcRenderer.listeners("serial-on-connection-closed").length > 0) { | ||
ipcRenderer.removeAllListeners("serial-on-connection-closed") | ||
} | ||
ipcRenderer.on('serial-on-connection-closed', (event) => { | ||
callback() | ||
}) | ||
}, | ||
createFolder: async (folder) => { | ||
return await ipcRenderer.invoke('serial', 'createFolder', folder) | ||
}, | ||
removeFolder: async (folder) => { | ||
return await ipcRenderer.invoke('serial', 'removeFolder', folder) | ||
}, | ||
getNavigationPath: (navigation, target) => { | ||
return path.posix.join(navigation, target) | ||
}, | ||
getFullPath: (root, navigation, file) => { | ||
return path.posix.join(root, navigation, file) | ||
}, | ||
getParentPath: (navigation) => { | ||
return path.posix.dirname(navigation) | ||
}, | ||
fileExists: async (filePath) => { | ||
return await ipcRenderer.invoke('serial', 'fileExists', filePath) | ||
} | ||
} | ||
|
||
module.exports = SerialBridge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
const MicroPython = require('micropython.js') | ||
|
||
class Serial { | ||
constructor(win = null) { | ||
this.win = win | ||
this.board = new MicroPython() | ||
this.board.chunk_size = 192 | ||
this.board.chunk_sleep = 200 | ||
} | ||
|
||
async loadPorts() { | ||
let ports = await this.board.list_ports() | ||
return ports.filter(p => p.vendorId && p.productId) | ||
} | ||
|
||
async connect(path) { | ||
await this.board.open(path) | ||
this.registerCallbacks() | ||
} | ||
|
||
async disconnect() { | ||
return await this.board.close() | ||
} | ||
|
||
async run(code) { | ||
return await this.board.run(code) | ||
} | ||
|
||
async execFile(path) { | ||
return await this.board.execfile(path) | ||
} | ||
|
||
async getPrompt() { | ||
return await this.board.get_prompt() | ||
} | ||
|
||
async keyboardInterrupt() { | ||
await this.board.stop() | ||
return Promise.resolve() | ||
} | ||
|
||
async reset() { | ||
await this.board.stop() | ||
await this.board.exit_raw_repl() | ||
await this.board.reset() | ||
return Promise.resolve() | ||
} | ||
|
||
async eval(d) { | ||
return await this.board.eval(d) | ||
} | ||
|
||
registerCallbacks() { | ||
this.board.serial.on('data', (data) => { | ||
this.win.webContents.send('serial-on-data', data) | ||
}) | ||
|
||
this.board.serial.on('close', () => { | ||
this.board.serial.removeAllListeners("data") | ||
this.board.serial.removeAllListeners("close") | ||
this.win.webContents.send('serial-on-connection-closed') | ||
}) | ||
} | ||
|
||
async listFiles(folder) { | ||
return await this.board.fs_ls(folder) | ||
} | ||
|
||
async ilistFiles(folder) { | ||
return await this.board.fs_ils(folder) | ||
} | ||
|
||
async loadFile(file) { | ||
const output = await this.board.fs_cat_binary(file) | ||
return output || '' | ||
} | ||
|
||
async removeFile(file) { | ||
return await this.board.fs_rm(file) | ||
} | ||
|
||
async saveFileContent(filename, content, dataConsumer) { | ||
return await this.board.fs_save(content || ' ', filename, dataConsumer) | ||
} | ||
|
||
async uploadFile(src, dest, dataConsumer) { | ||
return await this.board.fs_put(src, dest.replaceAll(path.win32.sep, path.posix.sep), dataConsumer) | ||
} | ||
|
||
async renameFile(oldName, newName) { | ||
return await this.board.fs_rename(oldName, newName) | ||
} | ||
|
||
async createFolder(folder) { | ||
return await this.board.fs_mkdir(folder) | ||
} | ||
|
||
async removeFolder(folder) { | ||
return await this.board.fs_rmdir(folder) | ||
} | ||
|
||
async fileExists(filePath) { | ||
const output = await this.board.run(` | ||
import os | ||
try: | ||
os.stat("${filePath}") | ||
print(0) | ||
except OSError: | ||
print(1) | ||
`) | ||
return output[2] === '0' | ||
} | ||
} | ||
|
||
const sharedInstance = new Serial() | ||
|
||
module.exports = {sharedInstance, Serial} |
Oops, something went wrong.