Remove automatic connection

I did not heed the warning where 'only the path is guaranteed' when
listing open serial ports and made the assumption that the manufacturer
would be known (hint: it wasn't).
This commit is contained in:
Jacob Grossman 2021-12-01 21:19:05 -06:00
parent d7e44406ec
commit 2d2ca75177
4 changed files with 21 additions and 3286 deletions

3207
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -301,11 +301,6 @@
"description": "The number of words around the cursor to use when reading the cursor context",
"default": 1
},
"mindreader.connection.connectAutomatically": {
"type": "boolean",
"description": "Specifies whether to try to automatically detect and communicate with a connected Hub.",
"default": "true"
},
"mindreader.connection.portPath": {
"type": "string",
"markdownDescription": "Specifies the serial port path to use if `#mindreader.connectAutomatically#` is not set."

View File

@ -392,13 +392,8 @@ async function connectHub(): Promise<void> {
vscode.window.showWarningMessage('LEGO Hub is already connected, reconnecting...');
disconnectHub();
}
const config = vscode.workspace.getConfiguration();
try {
if (config.get('mindreader.connection.connectAutomatically')) {
hub = await HubManager.create();
vscode.window.showInformationMessage('LEGO Hub connected');
} else {
const ports = await HubManager.queryPorts();
if (ports.length === 0) {
@ -406,22 +401,25 @@ async function connectHub(): Promise<void> {
return;
}
let slots: vscode.QuickPickItem[] = [];
for (const port of ports) {
slots.push({ label: port.path });
let portPath: string | undefined = vscode.workspace.getConfiguration('mindreader.connection').get('portPath');
if (!portPath) {
let slots: vscode.QuickPickItem[] = [];
for (const port of ports) {
slots.push({ label: port.path });
}
let picked = await vscode.window.showQuickPick(slots);
if (!picked) {
return;
}
portPath = picked.label;
}
let picked = await vscode.window.showQuickPick(slots);
if (!picked) {
return;
}
hub = await HubManager.create({ port: picked.label });
hub = await HubManager.create(portPath);
vscode.window.showInformationMessage('LEGO Hub connected');
}
} catch (err) {
// TODO: better handling
vscode.window.showErrorMessage('Could not connect to LEGO Hub');
}
}

View File

@ -1,4 +1,3 @@
import * as vscode from 'vscode';
import * as SerialPort from 'serialport';
import * as fs from 'fs';
@ -30,17 +29,6 @@ type RPCResponse = {
'i': string | null;
};
/**
* @type HubOptions Connection options
*
* @prop {boolean=} `magic` automatically try and find a suitable port to connect. Defaults to `true`
* @prop {string=} `port` port to use if `magic` is disabled. Defaults to `'/dev/ttyACM0'`.
*/
type HubOptions = {
magic?: boolean;
port?: string;
};
/**
* Manages sending and receiving of JSON Remote Procedure Call (JSON-RPC) protocol messages
* to the Hub.
@ -48,14 +36,14 @@ type HubOptions = {
export default class HubManager {
private port: SerialPort;
private receiveBuffer: string = ''; // buffer for in-flight messages
private pendingRequests = new Map<string, [(result: any) => void, (error: string) => void]>();
private pendingRequests = new Map<string, [(result: any) => void, (error: string) => void]>(); // lists of requests that are still pending
// ======================== INSTANCE METHODS ========================
/**
* Private constructor, use static `create` + `init`
*/
private constructor(public options: HubOptions) { }
private constructor(public portPath: string) { }
public isOpen(): boolean {
return this.port.isOpen;
@ -122,7 +110,7 @@ export default class HubManager {
public async init(): Promise<void> {
try {
this.port = new SerialPort(
this.options.port!,
this.portPath,
{
autoOpen: true,
baudRate: 112500,
@ -359,46 +347,10 @@ export default class HubManager {
// ======================== INSTANCE METHODS ========================
public static async create(options?: HubOptions): Promise<HubManager> {
public static async create(portPath: string): Promise<HubManager> {
return new Promise(async (resolve) => {
// merge passed options into default options
options = {
port: '/dev/ttyACM0',
magic: true,
...options
};
let mgr: HubManager;
// try to detect port automatically
if (options.magic) {
const availablePorts = await HubManager.queryPorts();
// get paths from port information
const portPaths = availablePorts.map(x => x.path);
if (portPaths.length > 0) {
// try to establish connections to found ports
for (const port of portPaths) {
try {
mgr = new HubManager({ ...options, port });
await mgr.init();
return resolve(mgr);
} catch (err) {
// could not connect to port, try next port
continue;
}
}
}
// TODO: better error, this will do for now
vscode.window.showErrorMessage('Mind_Reader: Magic is enabled but no ports were found. Is the Hub plugged in and turned on');
}
// magic disabled or failed, try normally
try {
mgr = new HubManager(options);
let mgr = new HubManager(portPath);
await mgr.init();
return resolve(mgr);
@ -413,15 +365,12 @@ export default class HubManager {
/**
* Returns a list of serial devices
* advertising their manufacturer
* as `LEGO System A/S`
*/
public static async queryPorts() {
// get all ports
let ports = await SerialPort.list();
// filter by manufacturer
ports = ports.filter(x => x.manufacturer === 'LEGO System A/S');
return Promise.resolve(ports);
}