Use port properties from the discovery.

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>

Closes #740
This commit is contained in:
Akos Kitta 2022-08-18 15:48:43 +02:00 committed by Akos Kitta
parent b5f9aa0f15
commit f7f644cf36
14 changed files with 239 additions and 197 deletions

View File

@ -354,7 +354,7 @@ export class BoardsConfig extends React.Component<
<div className="ports list"> <div className="ports list">
{ports.map((port) => ( {ports.map((port) => (
<Item<Port> <Item<Port>
key={`${port.id}`} key={`${Port.keyOf(port)}`}
item={port} item={port}
label={Port.toString(port)} label={Port.toString(port)}
selected={Port.sameAs(this.state.selectedPort, port)} selected={Port.sameAs(this.state.selectedPort, port)}

View File

@ -13,6 +13,7 @@ import {
AttachedBoardsChangeEvent, AttachedBoardsChangeEvent,
BoardWithPackage, BoardWithPackage,
BoardUserField, BoardUserField,
AvailablePorts,
} from '../../common/protocol'; } from '../../common/protocol';
import { BoardsConfig } from './boards-config'; import { BoardsConfig } from './boards-config';
import { naturalCompare } from '../../common/utils'; import { naturalCompare } from '../../common/utils';
@ -21,6 +22,7 @@ import { StorageWrapper } from '../storage-wrapper';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { Deferred } from '@theia/core/lib/common/promise-util'; import { Deferred } from '@theia/core/lib/common/promise-util';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { Unknown } from '../../common/nls';
@injectable() @injectable()
export class BoardsServiceProvider implements FrontendApplicationContribution { export class BoardsServiceProvider implements FrontendApplicationContribution {
@ -96,11 +98,12 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
); );
this.appStateService.reachedState('ready').then(async () => { this.appStateService.reachedState('ready').then(async () => {
const [attachedBoards, availablePorts] = await Promise.all([ const [state] = await Promise.all([
this.boardsService.getAttachedBoards(), this.boardsService.getState(),
this.boardsService.getAvailablePorts(),
this.loadState(), this.loadState(),
]); ]);
const { boards: attachedBoards, ports: availablePorts } =
AvailablePorts.split(state);
this._attachedBoards = attachedBoards; this._attachedBoards = attachedBoards;
this._availablePorts = availablePorts; this._availablePorts = availablePorts;
this.onAvailablePortsChangedEmitter.fire(this._availablePorts); this.onAvailablePortsChangedEmitter.fire(this._availablePorts);
@ -558,7 +561,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
}; };
} else { } else {
availableBoard = { availableBoard = {
name: nls.localize('arduino/common/unknown', 'Unknown'), name: Unknown,
port: boardPort, port: boardPort,
state: AvailableBoard.State.incomplete, state: AvailableBoard.State.incomplete,
}; };

View File

@ -331,7 +331,7 @@ PID: ${PID}`;
} }
}; };
const grouped = AvailablePorts.byProtocol(availablePorts); const grouped = AvailablePorts.groupByProtocol(availablePorts);
let protocolOrder = 100; let protocolOrder = 100;
// We first show serial and network ports, then all the rest // We first show serial and network ports, then all the rest
['serial', 'network'].forEach((protocol) => { ['serial', 'network'].forEach((protocol) => {

View File

@ -145,7 +145,10 @@ export class MonitorManagerProxyClientImpl
if ( if (
selectedBoard?.fqbn !== selectedBoard?.fqbn !==
this.lastConnectedBoard?.selectedBoard?.fqbn || this.lastConnectedBoard?.selectedBoard?.fqbn ||
selectedPort?.id !== this.lastConnectedBoard?.selectedPort?.id Port.keyOf(selectedPort) !==
(this.lastConnectedBoard.selectedPort
? Port.keyOf(this.lastConnectedBoard.selectedPort)
: undefined)
) { ) {
this.onMonitorShouldResetEmitter.fire(null); this.onMonitorShouldResetEmitter.fire(null);
this.lastConnectedBoard = { this.lastConnectedBoard = {

View File

@ -5,6 +5,7 @@ import { isOSX } from '@theia/core/lib/common/os';
import { DisposableCollection, nls } from '@theia/core/lib/common'; import { DisposableCollection, nls } from '@theia/core/lib/common';
import { BoardsServiceProvider } from '../../boards/boards-service-provider'; import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { MonitorModel } from '../../monitor-model'; import { MonitorModel } from '../../monitor-model';
import { Unknown } from '../../../common/nls';
export namespace SerialMonitorSendInput { export namespace SerialMonitorSendInput {
export interface Props { export interface Props {
@ -86,8 +87,8 @@ export class SerialMonitorSendInput extends React.Component<
? Board.toString(board, { ? Board.toString(board, {
useFqbn: false, useFqbn: false,
}) })
: 'unknown', : Unknown,
port ? port.address : 'unknown' port ? port.address : Unknown
); );
} }

View File

@ -5,6 +5,7 @@ import { Installable } from '../../../common/protocol/installable';
import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { ArduinoComponent } from '../../../common/protocol/arduino-component';
import { ComponentListItem } from './component-list-item'; import { ComponentListItem } from './component-list-item';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { Unknown } from '../../../common/nls';
@injectable() @injectable()
export class ListItemRenderer<T extends ArduinoComponent> { export class ListItemRenderer<T extends ArduinoComponent> {
@ -42,11 +43,7 @@ export class ListItemRenderer<T extends ArduinoComponent> {
} else if ((item as any).id) { } else if ((item as any).id) {
nameAndAuthor = <span className="name">{(item as any).id}</span>; nameAndAuthor = <span className="name">{(item as any).id}</span>;
} else { } else {
nameAndAuthor = ( nameAndAuthor = <span className="name">{Unknown}</span>;
<span className="name">
{nls.localize('arduino/common/unknown', 'Unknown')}
</span>
);
} }
const onClickUninstall = () => uninstall(item); const onClickUninstall = () => uninstall(item);
const installedVersion = !!item.installedVersion && ( const installedVersion = !!item.installedVersion && (

View File

@ -0,0 +1,3 @@
import { nls } from '@theia/core/lib/common/nls';
export const Unknown = nls.localize('arduino/common/unknown', 'Unknown');

View File

@ -5,7 +5,7 @@ import { ArduinoComponent } from './arduino-component';
export type AvailablePorts = Record<string, [Port, Array<Board>]>; export type AvailablePorts = Record<string, [Port, Array<Board>]>;
export namespace AvailablePorts { export namespace AvailablePorts {
export function byProtocol( export function groupByProtocol(
availablePorts: AvailablePorts availablePorts: AvailablePorts
): Map<string, AvailablePorts> { ): Map<string, AvailablePorts> {
const grouped = new Map<string, AvailablePorts>(); const grouped = new Map<string, AvailablePorts>();
@ -20,6 +20,21 @@ export namespace AvailablePorts {
} }
return grouped; return grouped;
} }
export function split(
state: AvailablePorts
): Readonly<{ boards: Board[]; ports: Port[] }> {
const availablePorts: Port[] = [];
const attachedBoards: Board[] = [];
for (const key of Object.keys(state)) {
const [port, boards] = state[key];
availablePorts.push(port);
attachedBoards.push(...boards);
}
return {
boards: attachedBoards,
ports: availablePorts,
};
}
} }
export interface AttachedBoardsChangeEvent { export interface AttachedBoardsChangeEvent {
@ -117,16 +132,6 @@ export const BoardsService = Symbol('BoardsService');
export interface BoardsService export interface BoardsService
extends Installable<BoardsPackage>, extends Installable<BoardsPackage>,
Searchable<BoardsPackage> { Searchable<BoardsPackage> {
/**
* Deprecated. `getState` should be used to correctly map a board with a port.
* @deprecated
*/
getAttachedBoards(): Promise<Board[]>;
/**
* Deprecated. `getState` should be used to correctly map a board with a port.
* @deprecated
*/
getAvailablePorts(): Promise<Port[]>;
getState(): Promise<AvailablePorts>; getState(): Promise<AvailablePorts>;
getBoardDetails(options: { fqbn: string }): Promise<BoardDetails | undefined>; getBoardDetails(options: { fqbn: string }): Promise<BoardDetails | undefined>;
getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>; getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>;
@ -141,28 +146,55 @@ export interface BoardsService
} }
export interface Port { export interface Port {
// id is the combination of address and protocol
// formatted like "<address>|<protocol>" used
// to uniquely recognize a port
readonly id: string;
readonly address: string; readonly address: string;
readonly addressLabel: string; readonly addressLabel: string;
readonly protocol: string; readonly protocol: string;
readonly protocolLabel: string; readonly protocolLabel: string;
readonly properties?: Record<string, string>;
} }
export namespace Port { export namespace Port {
export function is(arg: any): arg is Port { export type Properties = Record<string, string>;
return ( export namespace Properties {
!!arg && export function create(
'address' in arg && properties: [string, string][] | undefined
typeof arg['address'] === 'string' && ): Properties {
'protocol' in arg && if (!properties) {
typeof arg['protocol'] === 'string' return {};
); }
return properties.reduce((acc, curr) => {
const [key, value] = curr;
acc[key] = value;
return acc;
}, {} as Record<string, string>);
}
}
export function is(arg: unknown): arg is Port {
if (typeof arg === 'object') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const object = arg as any;
return (
'address' in object &&
typeof object['address'] === 'string' &&
'addressLabel' in object &&
typeof object['addressLabel'] === 'string' &&
'protocol' in object &&
typeof object['protocol'] === 'string' &&
'protocolLabel' in object &&
typeof object['protocolLabel'] === 'string'
);
}
return false;
} }
export function toString(port: Port): string { /**
return `${port.addressLabel} ${port.protocolLabel}`; * Key is the combination of address and protocol formatted like `'${address}|${protocol}'` used to uniquely identify a port.
*/
export function keyOf({ address, protocol }: Port): string {
return `${address}|${protocol}`;
}
export function toString({ addressLabel, protocolLabel }: Port): string {
return `${addressLabel} ${protocolLabel}`;
} }
export function compare(left: Port, right: Port): number { export function compare(left: Port, right: Port): number {

View File

@ -3,6 +3,7 @@ import { sha256 } from 'hash.js';
import { randomBytes } from 'crypto'; import { randomBytes } from 'crypto';
import btoa = require('btoa'); // TODO: check why we cannot import btoa = require('btoa'); // TODO: check why we cannot
import { AuthenticationSession } from './types'; import { AuthenticationSession } from './types';
import { Unknown } from '../../common/nls';
export interface IToken { export interface IToken {
accessToken: string; // When unable to refresh due to network problems, the access token becomes undefined accessToken: string; // When unable to refresh due to network problems, the access token becomes undefined
@ -62,10 +63,10 @@ export function token2IToken(token: Token): IToken {
sessionId: parsedIdToken.sub, sessionId: parsedIdToken.sub,
scope: token.scope, scope: token.scope,
account: { account: {
id: parsedIdToken.sub || 'unknown', id: parsedIdToken.sub || Unknown,
email: parsedIdToken.email || 'unknown', email: parsedIdToken.email || Unknown,
nickname: parsedIdToken.nickname || 'unknown', nickname: parsedIdToken.nickname || Unknown,
picture: parsedIdToken.picture || 'unknown', picture: parsedIdToken.picture || Unknown,
}, },
}; };
} }

View File

@ -1,27 +1,30 @@
import { injectable, inject, named } from '@theia/core/shared/inversify';
import { ClientDuplexStream } from '@grpc/grpc-js'; import { ClientDuplexStream } from '@grpc/grpc-js';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { ILogger } from '@theia/core/lib/common/logger'; import { ILogger } from '@theia/core/lib/common/logger';
import { deepClone } from '@theia/core/lib/common/objects'; import { deepClone } from '@theia/core/lib/common/objects';
import { CoreClientAware } from './core-client-provider'; import { Deferred } from '@theia/core/lib/common/promise-util';
import { BackendApplicationContribution } from '@theia/core/lib/node';
import { inject, injectable, named } from '@theia/core/shared/inversify';
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
import { v4 } from 'uuid';
import { Unknown } from '../common/nls';
import {
AttachedBoardsChangeEvent,
AvailablePorts,
Board,
NotificationServiceServer,
Port,
} from '../common/protocol';
import { import {
BoardListWatchRequest, BoardListWatchRequest,
BoardListWatchResponse, BoardListWatchResponse,
DetectedPort as RpcDetectedPort,
} from './cli-protocol/cc/arduino/cli/commands/v1/board_pb'; } from './cli-protocol/cc/arduino/cli/commands/v1/board_pb';
import {
Board,
Port,
NotificationServiceServer,
AvailablePorts,
AttachedBoardsChangeEvent,
} from '../common/protocol';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb'; import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
import { v4 } from 'uuid'; import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import { CoreClientAware } from './core-client-provider';
import { ServiceError } from './service-error'; import { ServiceError } from './service-error';
import { BackendApplicationContribution } from '@theia/core/lib/node';
import { Deferred } from '@theia/core/lib/common/promise-util';
type Duplex = ClientDuplexStream<BoardListWatchRequest, BoardListWatchResponse>; type Duplex = ClientDuplexStream<BoardListWatchRequest, BoardListWatchResponse>;
interface StreamWrapper extends Disposable { interface StreamWrapper extends Disposable {
@ -125,8 +128,8 @@ export class BoardDiscovery
}); });
} }
setUploadInProgress(uploadAttemptInProgress: boolean): void { setUploadInProgress(uploadInProgress: boolean): void {
this.uploadInProgress = uploadAttemptInProgress; this.uploadInProgress = uploadInProgress;
} }
private createTimeout( private createTimeout(
@ -216,7 +219,7 @@ export class BoardDiscovery
} else { } else {
throw new Error(`Unhandled object type: ${arg}`); throw new Error(`Unhandled object type: ${arg}`);
} }
return JSON.stringify(object); return JSON.stringify(object, null, 2); // TODO: remove `space`?
} }
async start(): Promise<void> { async start(): Promise<void> {
@ -234,103 +237,7 @@ export class BoardDiscovery
this.logger.info('start new deferred'); this.logger.info('start new deferred');
const { client, instance } = await this.coreClient; const { client, instance } = await this.coreClient;
const wrapper = await this.createWrapper(client); const wrapper = await this.createWrapper(client);
wrapper.stream.on('data', async (resp: BoardListWatchResponse) => { wrapper.stream.on('data', (resp) => this.onBoardListWatchResponse(resp));
this.logger.info('onData', this.toJson(resp));
if (resp.getEventType() === 'quit') {
this.logger.info('quit received');
this.stop();
return;
}
const detectedPort = resp.getPort();
if (detectedPort) {
let eventType: 'add' | 'remove' | 'unknown' = 'unknown';
if (resp.getEventType() === 'add') {
eventType = 'add';
} else if (resp.getEventType() === 'remove') {
eventType = 'remove';
} else {
eventType = 'unknown';
}
if (eventType === 'unknown') {
throw new Error(`Unexpected event type: '${resp.getEventType()}'`);
}
const oldState = deepClone(this._availablePorts);
const newState = deepClone(this._availablePorts);
const address = (detectedPort as any).getPort().getAddress();
const protocol = (detectedPort as any).getPort().getProtocol();
// Different discoveries can detect the same port with different
// protocols, so we consider the combination of address and protocol
// to be the id of a certain port to distinguish it from others.
// If we'd use only the address of a port to store it in a map
// we can have conflicts the same port is found with multiple
// protocols.
const portID = `${address}|${protocol}`;
const label = (detectedPort as any).getPort().getLabel();
const protocolLabel = (detectedPort as any)
.getPort()
.getProtocolLabel();
const port = {
id: portID,
address,
addressLabel: label,
protocol,
protocolLabel,
};
const boards: Board[] = [];
for (const item of detectedPort.getMatchingBoardsList()) {
boards.push({
fqbn: item.getFqbn(),
name: item.getName() || 'unknown',
port,
});
}
if (eventType === 'add') {
if (newState[portID]) {
const [, knownBoards] = newState[portID];
this.logger.warn(
`Port '${Port.toString(
port
)}' was already available. Known boards before override: ${JSON.stringify(
knownBoards
)}`
);
}
newState[portID] = [port, boards];
} else if (eventType === 'remove') {
if (!newState[portID]) {
this.logger.warn(
`Port '${Port.toString(port)}' was not available. Skipping`
);
return;
}
delete newState[portID];
}
const oldAvailablePorts = this.getAvailablePorts(oldState);
const oldAttachedBoards = this.getAttachedBoards(oldState);
const newAvailablePorts = this.getAvailablePorts(newState);
const newAttachedBoards = this.getAttachedBoards(newState);
const event: AttachedBoardsChangeEvent = {
oldState: {
ports: oldAvailablePorts,
boards: oldAttachedBoards,
},
newState: {
ports: newAvailablePorts,
boards: newAttachedBoards,
},
uploadInProgress: this.uploadInProgress,
};
this._availablePorts = newState;
this.notificationService.notifyAttachedBoardsDidChange(event);
}
});
this.logger.info('start request start watch'); this.logger.info('start request start watch');
await this.requestStartWatch( await this.requestStartWatch(
new BoardListWatchRequest().setInstance(instance), new BoardListWatchRequest().setInstance(instance),
@ -341,21 +248,124 @@ export class BoardDiscovery
this.logger.info('start resolved watching'); this.logger.info('start resolved watching');
} }
getAttachedBoards(state: AvailablePorts = this.availablePorts): Board[] { // XXX: make this `protected` and override for tests if IDE2 wants to mock events from the CLI.
const attachedBoards: Board[] = []; private onBoardListWatchResponse(resp: BoardListWatchResponse): void {
for (const portID of Object.keys(state)) { this.logger.info(this.toJson(resp));
const [, boards] = state[portID]; const eventType = EventType.parse(resp.getEventType());
attachedBoards.push(...boards);
if (eventType === EventType.Quit) {
this.logger.info('quit received');
this.stop();
return;
}
const detectedPort = resp.getPort();
if (detectedPort) {
const { port, boards } = this.fromRpc(detectedPort);
if (!port) {
if (!!boards.length) {
console.warn(
`Could not detect the port, but unexpectedly received discovered boards. This is most likely a bug! Response was: ${this.toJson(
resp
)}`
);
}
return;
}
const oldState = deepClone(this._availablePorts);
const newState = deepClone(this._availablePorts);
const key = Port.keyOf(port);
if (eventType === EventType.Add) {
if (newState[key]) {
const [, knownBoards] = newState[key];
this.logger.warn(
`Port '${Port.toString(
port
)}' was already available. Known boards before override: ${JSON.stringify(
knownBoards
)}`
);
}
newState[key] = [port, boards];
} else if (eventType === EventType.Remove) {
if (!newState[key]) {
this.logger.warn(
`Port '${Port.toString(port)}' was not available. Skipping`
);
return;
}
delete newState[key];
}
const event: AttachedBoardsChangeEvent = {
oldState: {
...AvailablePorts.split(oldState),
},
newState: {
...AvailablePorts.split(newState),
},
uploadInProgress: this.uploadInProgress,
};
this._availablePorts = newState;
this.notificationService.notifyAttachedBoardsDidChange(event);
} }
return attachedBoards;
} }
getAvailablePorts(state: AvailablePorts = this.availablePorts): Port[] { private fromRpc(detectedPort: RpcDetectedPort): DetectedPort {
const availablePorts: Port[] = []; const rpcPort = detectedPort.getPort();
for (const portID of Object.keys(state)) { const port = rpcPort && this.fromRpcPort(rpcPort);
const [port] = state[portID]; const boards = detectedPort.getMatchingBoardsList().map(
availablePorts.push(port); (board) =>
} ({
return availablePorts; fqbn: board.getFqbn(),
name: board.getName() || Unknown,
port,
} as Board)
);
return {
boards,
port,
};
}
private fromRpcPort(rpcPort: RpcPort): Port {
const port = {
address: rpcPort.getAddress(),
addressLabel: rpcPort.getLabel(),
protocol: rpcPort.getProtocol(),
protocolLabel: rpcPort.getProtocolLabel(),
properties: Port.Properties.create(rpcPort.getPropertiesMap().toObject()),
};
return port;
} }
} }
enum EventType {
Add,
Remove,
Quit,
}
namespace EventType {
export function parse(type: string): EventType {
const normalizedType = type.toLowerCase();
switch (normalizedType) {
case 'add':
return EventType.Add;
case 'remove':
return EventType.Remove;
case 'quit':
return EventType.Quit;
default:
throw new Error(
`Unexpected 'BoardListWatchResponse' event type: '${type}.'`
);
}
}
}
interface DetectedPort {
port: Port | undefined;
boards: Board[];
}

View File

@ -6,7 +6,6 @@ import {
Installable, Installable,
BoardsPackage, BoardsPackage,
Board, Board,
Port,
BoardDetails, BoardDetails,
Tool, Tool,
ConfigOption, ConfigOption,
@ -65,14 +64,6 @@ export class BoardsServiceImpl
return this.boardDiscovery.availablePorts; return this.boardDiscovery.availablePorts;
} }
async getAttachedBoards(): Promise<Board[]> {
return this.boardDiscovery.getAttachedBoards();
}
async getAvailablePorts(): Promise<Port[]> {
return this.boardDiscovery.getAvailablePorts();
}
async getBoardDetails(options: { async getBoardDetails(options: {
fqbn: string; fqbn: string;
}): Promise<BoardDetails | undefined> { }): Promise<BoardDetails | undefined> {

View File

@ -25,7 +25,7 @@ import {
import { ResponseService } from '../common/protocol/response-service'; import { ResponseService } from '../common/protocol/response-service';
import { OutputMessage, Port, Status } from '../common/protocol'; import { OutputMessage, Port, Status } from '../common/protocol';
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb'; import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
import { Port as GrpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb'; import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import { ApplicationError, CommandService, Disposable, nls } from '@theia/core'; import { ApplicationError, CommandService, Disposable, nls } from '@theia/core';
import { MonitorManager } from './monitor-manager'; import { MonitorManager } from './monitor-manager';
import { AutoFlushingBuffer } from './utils/buffers'; import { AutoFlushingBuffer } from './utils/buffers';
@ -411,15 +411,20 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
} }
} }
private createPort(port: Port | undefined): GrpcPort { private createPort(port: Port | undefined): RpcPort {
const grpcPort = new GrpcPort(); const rpcPort = new RpcPort();
if (port) { if (port) {
grpcPort.setAddress(port.address); rpcPort.setAddress(port.address);
grpcPort.setLabel(port.addressLabel); rpcPort.setLabel(port.addressLabel);
grpcPort.setProtocol(port.protocol); rpcPort.setProtocol(port.protocol);
grpcPort.setProtocolLabel(port.protocolLabel); rpcPort.setProtocolLabel(port.protocolLabel);
if (port.properties) {
for (const [key, value] of Object.entries(port.properties)) {
rpcPort.getPropertiesMap().set(key, value);
}
}
} }
return grpcPort; return rpcPort;
} }
} }
type StreamingResponse = type StreamingResponse =

View File

@ -12,7 +12,7 @@ import {
} from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb'; } from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb';
import { CoreClientAware } from './core-client-provider'; import { CoreClientAware } from './core-client-provider';
import { WebSocketProvider } from './web-socket/web-socket-provider'; import { WebSocketProvider } from './web-socket/web-socket-provider';
import { Port as gRPCPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb'; import { Port as RpcPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import { import {
MonitorSettings, MonitorSettings,
PluggableMonitorSettings, PluggableMonitorSettings,
@ -193,10 +193,10 @@ export class MonitorService extends CoreClientAware implements Disposable {
monitorRequest.setFqbn(this.board.fqbn); monitorRequest.setFqbn(this.board.fqbn);
} }
if (this.port?.address && this.port?.protocol) { if (this.port?.address && this.port?.protocol) {
const port = new gRPCPort(); const rpcPort = new RpcPort();
port.setAddress(this.port.address); rpcPort.setAddress(this.port.address);
port.setProtocol(this.port.protocol); rpcPort.setProtocol(this.port.protocol);
monitorRequest.setPort(port); monitorRequest.setPort(rpcPort);
} }
const config = new MonitorPortConfiguration(); const config = new MonitorPortConfiguration();
for (const id in this.settings.pluggableMonitorSettings) { for (const id in this.settings.pluggableMonitorSettings) {

View File

@ -5,7 +5,6 @@ export const aBoard: Board = {
fqbn: 'some:board:fqbn', fqbn: 'some:board:fqbn',
name: 'Some Arduino Board', name: 'Some Arduino Board',
port: { port: {
id: '/lol/port1234|serial',
address: '/lol/port1234', address: '/lol/port1234',
addressLabel: '/lol/port1234', addressLabel: '/lol/port1234',
protocol: 'serial', protocol: 'serial',
@ -13,7 +12,6 @@ export const aBoard: Board = {
}, },
}; };
export const aPort: Port = { export const aPort: Port = {
id: aBoard.port!.id,
address: aBoard.port!.address, address: aBoard.port!.address,
addressLabel: aBoard.port!.addressLabel, addressLabel: aBoard.port!.addressLabel,
protocol: aBoard.port!.protocol, protocol: aBoard.port!.protocol,
@ -27,7 +25,6 @@ export const anotherBoard: Board = {
fqbn: 'another:board:fqbn', fqbn: 'another:board:fqbn',
name: 'Another Arduino Board', name: 'Another Arduino Board',
port: { port: {
id: '/kek/port5678|serial',
address: '/kek/port5678', address: '/kek/port5678',
addressLabel: '/kek/port5678', addressLabel: '/kek/port5678',
protocol: 'serial', protocol: 'serial',
@ -35,7 +32,6 @@ export const anotherBoard: Board = {
}, },
}; };
export const anotherPort: Port = { export const anotherPort: Port = {
id: anotherBoard.port!.id,
address: anotherBoard.port!.address, address: anotherBoard.port!.address,
addressLabel: anotherBoard.port!.addressLabel, addressLabel: anotherBoard.port!.addressLabel,
protocol: anotherBoard.port!.protocol, protocol: anotherBoard.port!.protocol,