mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-04-19 12:57:17 +00:00
Can list HW, build for it and upload
This commit is contained in:
parent
95ed43c9c4
commit
b2d16ff9a4
@ -75,10 +75,11 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr
|
||||
registry.registerCommand(ArduinoCommands.UPLOAD, {
|
||||
isVisible: widget => this.isArduinoEditor(widget),
|
||||
isEnabled: widget => this.isArduinoEditor(widget),
|
||||
execute: widget => {
|
||||
execute: async widget => {
|
||||
const uri = this.toUri(widget);
|
||||
if (uri) {
|
||||
this.messageService.info(`Uploading ${uri.toString()}`);
|
||||
const result = await this.coreService.upload({ uri: uri.toString() });
|
||||
console.log('upload result', result);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -4,40 +4,60 @@ import * as React from 'react';
|
||||
import { BoardsService, AttachedBoard } from '../../common/protocol/boards-service';
|
||||
|
||||
export class ConnectedBoards extends React.Component<ConnectedBoards.Props, ConnectedBoards.State> {
|
||||
|
||||
static TOOLBAR_ID: 'connected-boards-toolbar';
|
||||
|
||||
constructor(props: ConnectedBoards.Props) {
|
||||
super(props);
|
||||
this.state = { boardsLoading: false };
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
let label = "no board available";
|
||||
if (this.state.boardsLoading) {
|
||||
label = "Loading ...";
|
||||
} else if (!!this.state.current) {
|
||||
label = this.state.current.name;
|
||||
}
|
||||
|
||||
let content = [];
|
||||
if (!!this.state.boards) {
|
||||
content = this.state.boards.map((b, i) => <option value={i} key={i}>{b.name}</option>);
|
||||
} else {
|
||||
content = [ <option key="loading" value="0">{label}</option> ];
|
||||
}
|
||||
|
||||
return <div className={ConnectedBoards.Styles.CONNECTED_BOARDS_CLASS}>
|
||||
{this.select(this.state ? this.state.boards : undefined, this.state ? this.state.current : undefined)}
|
||||
<select disabled={!this.state.boards} onChange={this.onBoardSelect.bind(this)}>
|
||||
{ content }
|
||||
</select>
|
||||
</div>;
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.props.boardsService.attachedBoards().then(result => {
|
||||
const { boards } = result;
|
||||
this.setState({ boards });
|
||||
});
|
||||
this.reloadBoards();
|
||||
}
|
||||
|
||||
private select(boards: AttachedBoard[] | undefined, current: AttachedBoard | undefined): React.ReactNode {
|
||||
// Initial pessimistic.
|
||||
const options = [<option>Loading...</option>];
|
||||
protected async reloadBoards() {
|
||||
this.setState({ boardsLoading: true, boards: undefined, current: undefined });
|
||||
const { boards } = await this.props.boardsService.getAttachedBoards()
|
||||
this.setState({ boards, boardsLoading: false });
|
||||
|
||||
if (boards) {
|
||||
options.length = 0;
|
||||
options.push(...boards.map(b => b.name).map(name => <option value={name} key={name}>{name}</option>));
|
||||
this.selectBoard(boards[0]);
|
||||
}
|
||||
const onChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const current = (boards || []).find(board => board.name === event.target.value);
|
||||
this.setState({ current });
|
||||
};
|
||||
return <select
|
||||
onChange={onChange}
|
||||
value={current ? current.name : 'Loading...'}
|
||||
name={current ? current.name : 'Loading...'}
|
||||
>
|
||||
{options}
|
||||
</select>
|
||||
}
|
||||
|
||||
protected async onBoardSelect(evt: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const selectedBoard = (this.state.boards || [])[parseInt(evt.target.value, 10)];
|
||||
if (!selectedBoard) {
|
||||
return;
|
||||
}
|
||||
this.selectBoard(selectedBoard);
|
||||
}
|
||||
|
||||
protected async selectBoard(board: AttachedBoard) {
|
||||
await this.props.boardsService.selectBoard(board);
|
||||
this.setState({ current: board });
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,6 +69,7 @@ export namespace ConnectedBoards {
|
||||
}
|
||||
|
||||
export interface State {
|
||||
boardsLoading: boolean;
|
||||
boards?: AttachedBoard[];
|
||||
current?: AttachedBoard;
|
||||
}
|
||||
|
@ -3,7 +3,10 @@ import { ArduinoComponent } from "./arduino-component";
|
||||
export const BoardsServicePath = '/services/boards-service';
|
||||
export const BoardsService = Symbol('BoardsService');
|
||||
export interface BoardsService {
|
||||
attachedBoards(): Promise<{ boards: AttachedBoard[] }>;
|
||||
getAttachedBoards(): Promise<{ boards: AttachedBoard[] }>;
|
||||
selectBoard(board: AttachedBoard): Promise<void>;
|
||||
getSelectBoard(): Promise<AttachedBoard | undefined>;
|
||||
|
||||
search(options: { query?: string }): Promise<{ items: Board[] }>;
|
||||
install(board: Board): Promise<void>;
|
||||
}
|
||||
|
@ -2,10 +2,17 @@ export const CoreServicePath = '/services/core-service';
|
||||
export const CoreService = Symbol('CoreService');
|
||||
export interface CoreService {
|
||||
compile(options: CoreService.Compile.Options): Promise<void>;
|
||||
upload(): Promise<void>;
|
||||
upload(options: CoreService.Upload.Options): Promise<void>;
|
||||
}
|
||||
|
||||
export namespace CoreService {
|
||||
|
||||
export namespace Upload {
|
||||
export interface Options {
|
||||
readonly uri: string;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Compile {
|
||||
export interface Options {
|
||||
readonly uri: string;
|
||||
|
@ -33,13 +33,13 @@ export class ArduinoDaemon implements BackendApplicationContribution {
|
||||
});
|
||||
if (daemon.stdout) {
|
||||
daemon.stdout.on('data', data => {
|
||||
this.toolOutputService.publishNewOutput("daeomn", data.toString());
|
||||
this.toolOutputService.publishNewOutput("daemon", data.toString());
|
||||
DaemonLog.log(this.logger, data.toString());
|
||||
});
|
||||
}
|
||||
if (daemon.stderr) {
|
||||
daemon.stderr.on('data', data => {
|
||||
this.toolOutputService.publishNewOutput("daeomn error", data.toString());
|
||||
this.toolOutputService.publishNewOutput("daemon error", data.toString());
|
||||
DaemonLog.log(this.logger, data.toString());
|
||||
});
|
||||
}
|
||||
|
@ -10,7 +10,9 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
@inject(CoreClientProvider)
|
||||
protected readonly coreClientProvider: CoreClientProvider;
|
||||
|
||||
public async attachedBoards(): Promise<{ boards: AttachedBoard[] }> {
|
||||
protected selectedBoard: AttachedBoard | undefined;
|
||||
|
||||
public async getAttachedBoards(): Promise<{ boards: AttachedBoard[] }> {
|
||||
const { client, instance } = await this.coreClientProvider.getClient();
|
||||
|
||||
const req = new BoardListReq();
|
||||
@ -36,6 +38,14 @@ export class BoardsServiceImpl implements BoardsService {
|
||||
return { boards: serialBoards.concat(networkBoards) };
|
||||
}
|
||||
|
||||
async selectBoard(board: AttachedBoard): Promise<void> {
|
||||
this.selectedBoard = board;
|
||||
}
|
||||
|
||||
async getSelectBoard(): Promise<AttachedBoard | undefined> {
|
||||
return this.selectedBoard;
|
||||
}
|
||||
|
||||
async search(options: { query?: string }): Promise<{ items: Board[] }> {
|
||||
const { client, instance } = await this.coreClientProvider.getClient();
|
||||
|
||||
|
@ -2,10 +2,11 @@ import { inject, injectable } from 'inversify';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
|
||||
import { CoreService } from '../common/protocol/core-service';
|
||||
import { CompileReq, CompileResp } from './cli-protocol/compile_pb';
|
||||
import { BoardsService } from '../common/protocol/boards-service';
|
||||
import { BoardsService, AttachedSerialBoard } from '../common/protocol/boards-service';
|
||||
import { CoreClientProvider } from './core-client-provider';
|
||||
import * as path from 'path';
|
||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||
import { UploadReq, UploadResp } from './cli-protocol/upload_pb';
|
||||
|
||||
@injectable()
|
||||
export class CoreServiceImpl implements CoreService {
|
||||
@ -32,16 +33,19 @@ export class CoreServiceImpl implements CoreService {
|
||||
const sketchpath = path.dirname(sketchFilePath);
|
||||
|
||||
const { client, instance } = await this.coreClientProvider.getClient(uri);
|
||||
// const boards = await this.boardsService.connectedBoards();
|
||||
// if (!boards.current) {
|
||||
// throw new Error(`No selected board. The connected boards were: ${boards.boards}.`);
|
||||
// }
|
||||
// https://github.com/cmaglie/arduino-cli/blob/bd5e78701e7546787649d3cca6b21c5d22d0e438/cli/compile/compile.go#L78-L88
|
||||
|
||||
const currentBoard = await this.boardsService.getSelectBoard();
|
||||
if (!currentBoard) {
|
||||
throw new Error("no board selected");
|
||||
}
|
||||
if (!currentBoard.fqbn) {
|
||||
throw new Error(`selected board (${currentBoard.name}) has no FQBN`);
|
||||
}
|
||||
|
||||
const compilerReq = new CompileReq();
|
||||
compilerReq.setInstance(instance);
|
||||
compilerReq.setSketchpath(sketchpath);
|
||||
compilerReq.setFqbn('arduino:avr:uno'/*boards.current.name*/);
|
||||
compilerReq.setFqbn(currentBoard.fqbn!);
|
||||
compilerReq.setPreprocess(false);
|
||||
compilerReq.setVerbose(true);
|
||||
compilerReq.setQuiet(false);
|
||||
@ -57,8 +61,43 @@ export class CoreServiceImpl implements CoreService {
|
||||
});
|
||||
}
|
||||
|
||||
upload(): Promise<void> {
|
||||
throw new Error("Method not implemented.");
|
||||
async upload(options: CoreService.Upload.Options): Promise<void> {
|
||||
console.log('upload', options);
|
||||
const { uri } = options;
|
||||
const sketchFilePath = await this.fileSystem.getFsPath(options.uri);
|
||||
if (!sketchFilePath) {
|
||||
throw new Error(`Cannot resolve filesystem path for URI: ${uri}.`);
|
||||
}
|
||||
const sketchpath = path.dirname(sketchFilePath);
|
||||
|
||||
const currentBoard = await this.boardsService.getSelectBoard();
|
||||
if (!currentBoard) {
|
||||
throw new Error("no board selected");
|
||||
}
|
||||
if (!currentBoard.fqbn) {
|
||||
throw new Error(`selected board (${currentBoard.name}) has no FQBN`);
|
||||
}
|
||||
|
||||
const { client, instance } = await this.coreClientProvider.getClient(uri);
|
||||
|
||||
const req = new UploadReq();
|
||||
req.setInstance(instance);
|
||||
req.setSketchPath(sketchpath);
|
||||
req.setFqbn(currentBoard.fqbn);
|
||||
if (AttachedSerialBoard.is(currentBoard)) {
|
||||
req.setPort(currentBoard.port);
|
||||
} else {
|
||||
throw new Error("can only upload to serial boards");
|
||||
}
|
||||
const result = client.upload(req);
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
result.on('data', (cr: UploadResp) => {
|
||||
this.toolOutputService.publishNewOutput("upload", new Buffer(cr.getOutStream_asU8()).toString());
|
||||
this.toolOutputService.publishNewOutput("upload error", new Buffer(cr.getErrStream_asU8()).toString());
|
||||
});
|
||||
result.on('error', error => reject(error));
|
||||
result.on('end', () => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user