Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: arduino/arduino-create-agent-js-client
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2.2.5
Choose a base ref
...
head repository: arduino/arduino-create-agent-js-client
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 21,644 additions and 8,830 deletions.
  1. +17 −9 .babelrc
  2. +1 −0 .gitignore
  3. +1 −0 .nvmrc
  4. +40 −0 CHANGELOG.md
  5. +1 −1 LICENSE.txt
  6. +20 −5 README.md
  7. +5 −2 demo/.babelrc
  8. +55 −22 demo/app.jsx
  9. +8 −6 demo/v2/install_tool.jsx
  10. +11 −9 demo/v2/v2.jsx
  11. +20,842 −8,545 package-lock.json
  12. +34 −33 package.json
  13. +17 −20 rollup.config.js
  14. +21 −17 src/chrome-app-daemon.js
  15. +67 −0 src/chrome-os-daemon.js
  16. +55 −8 src/daemon.js
  17. +114 −132 src/firmware-updater.js
  18. +2 −2 src/index.js
  19. +14 −0 src/signatures.js
  20. +17 −13 src/socket-daemon.js
  21. +3 −3 src/socket-daemon.v2.js
  22. +292 −0 src/web-serial-daemon.js
  23. +7 −3 webpack.config.js
26 changes: 17 additions & 9 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -2,19 +2,27 @@
"env": {
"commonjs": {
"presets": [
["env", {
"useBuiltIns": false
}]
[
"@babel/env",
{
"useBuiltIns": false
}
]
]
},
"es": {
"presets": [
["env", {
"useBuiltIns": false,
"modules": false
}]
[
"@babel/env",
{
"useBuiltIns": false,
"modules": false
}
]
]
}
},
"plugins": ["transform-object-rest-spread"]
}
"plugins": [
"@babel/proposal-object-rest-spread"
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -3,3 +3,4 @@ lib
dist
es
.tmp
misc
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v14.16.0
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Changelog
All notable changes to this project will be documented in this file.

## [2.11.0] - 2022-09-27
The main goal of this release is to improve support for the Web Serial API on ChromeOS.
Other platforms should not be affected.

### Changed
- When using Web Serial API, the interactions between the client library
(as an example, the Arduino `arduino-chromeos-uploader` libray) has been simplified.
- A new parameter `dialogCustomizations` has been added to the upload functionality. It's used
to provide custom confirmation dialogs when using the Web Serial API.
It has no effect with other daemons.

### Removed
- `cdcReset` functionality, now it's embedded in the `upload` functionality
in the Web Serial daemon.
### Changed

## [2.10.1] - 2022-09-08

### Changed
- Fixed a bug released in 2.9.1 caused by the wrong assumption that the build filename is always at the end of the command line. This fix makes the library backward compatible with older ESP boards.

## *DEPRECATED* [2.9.1] - 2022-09-06
### Added
- Added support for ESP32 boards

## [2.9.0] - 2022-06-06
### Added
- Added support for "Arduino RP2040 Connect" board
### Changed
- Improved support for Chrome's Web Serial API on ChromeOS. Other operating systems should not be affected.
- Simplified the communication with the Web Serial API via a messaging system which simulates
the [postMessage](https://developer.chrome.com/docs/extensions/reference/runtime/#method-Port-postMessage) function available in the Chrome App Daemon (see `chrome-app-daemon.js`).

## [2.8.0] - 2022-03-21
### Added
- Added support (still in Beta) for Chrome's Web Serial API on ChromeOS.
Other operating systems should not be affected.
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This file includes licensing information for arduino-create-agent-js-client.

Copyright (c) 2018
Authors: Alberto Iannaccone, Stefania Mellai, Gabriele Destefanis
Authors: Alberto Iannaccone, Stefania Mellai, Gabriele Destefanis, Christian Sarnataro

The software is released under the GNU General Public License, which covers the main body
of the arduino-create-agent-js-client code. The terms of this license can be found at:
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@
[![npm version](https://badge.fury.io/js/arduino-create-agent-js-client.svg)](https://badge.fury.io/js/arduino-create-agent-js-client)

# arduino-create-agent-js-client
JS module providing discovery of the [Arduino Create Plugin](https://github.com/arduino/arduino-create-agent) and communication with it
JS module providing discovery of the [Arduino Create Agent](https://github.com/arduino/arduino-create-agent) and communication with it

## Changelog
See [CHANGELOG.md](https://github.com/arduino/arduino-create-agent-js-client/blob/HEAD/CHANGELOG.md) for more details.

## Installation

@@ -38,11 +41,22 @@ daemon.devicesList.subscribe(({serial, network}) => {
// Open serial monitor
daemon.openSerialMonitor('port-name');

// Read from serial monitor
// Read from serial monitor (ouputs string)
daemon.serialMonitorMessages.subscribe(message => {
console.log(message);
});

// Read from serial monitor, output object with source port name
/*
{
"P": "dev/ttyACM0",
"D":"output text here\r\n"
}
*/
daemon.serialMonitorMessagesWithPort.subscribe(messageObj => {
console.log(messageObj);
});

// Write to serial monitor
daemon.writeSerial('port-name', 'message');

@@ -72,7 +86,7 @@ daemon.downloading.subscribe(download => {

## Version 2

Version 2 of the arduino-create-agent aims to provide a cleaner api based on promises.
Version 2 of the arduino-create-agent aims to provide a cleaner api based on promises.
It will remain confined to a v2 property on the daemon object until it will be stable.
At the moment it only supports tool management.

@@ -107,5 +121,6 @@ To enable communication between your [local installation](http://localhost:8000/
add `origins = http://localhost:8000` on your agent config.ini file
(if you are using https, add `origins = https://localhost:8000`).

- On macOs ~/Applications/ArduinoCreateAgent-1.1/ArduinoCreateAgent.app/Contents/MacOS/config.ini
- On Linux ~/ArduinoCreateAgent-1.1/config.ini
- On macOs ~/Applications/ArduinoCreateAgent/ArduinoCreateAgent.app/Contents/MacOS/config.ini
- On Linux ~/ArduinoCreateAgent/config.ini
- On Windows C:\Users\\[your user]\AppData\Roaming\ArduinoCreateAgent
7 changes: 5 additions & 2 deletions demo/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"presets": ["env", "react"]
}
"presets": [
"@babel/env",
"@babel/react"
]
}
77 changes: 55 additions & 22 deletions demo/app.jsx
Original file line number Diff line number Diff line change
@@ -27,6 +27,8 @@ import V2 from './v2/v2.jsx';

const chromeExtensionID = 'hfejhkbipnickajaidoppbadcomekkde';

const isChromeOs = () => window.navigator.userAgent.indexOf(' CrOS ') !== -1;

const scrollToBottom = (target) => {
if (target) {
target.scrollTop = target.scrollHeight; // eslint-disable-line no-param-reassign
@@ -36,32 +38,21 @@ const scrollToBottom = (target) => {
const daemon = new Daemon('https://builder.arduino.cc/v3/boards', chromeExtensionID);
const firmwareUpdater = new FirmwareUpdater(daemon);

const handleUpload = () => {
const target = {
board: 'arduino:samd:mkr1000',
port: '/dev/ttyACM0',
network: false
};

// Upload a compiled sketch.
daemon.uploadSerial(target, 'serial_mirror', { bin: HEX });
};

const handleBootloaderMode = (e, port) => {
e.preventDefault();
daemon.setBootloaderMode(port);
};

const handleUpdateFirmware = (e, boardId, port, wifiModule) => {
const handleUpdateFirmware = (e, boardId, port, firmwareVersion) => {
e.preventDefault();
if (![firmwareUpdater.updateStatusEnum.NOPE, firmwareUpdater.updateStatusEnum.DONE, firmwareUpdater.updateStatusEnum.ERROR].includes(firmwareUpdater.updating.getValue().status)) {
return;
}
firmwareUpdater.updateFirmware(boardId, port, wifiModule);
firmwareUpdater.updateFirmware(boardId, port, firmwareVersion);
firmwareUpdater.updatingDone.subscribe(() => {
console.log('Firmware updated successfully!');
});

firmwareUpdater.updatingError.subscribe(update => {
console.log('Something went wrong when trying to update the firmware');
console.error(update.err);
@@ -98,14 +89,16 @@ class App extends React.Component {
downloadStatus: '',
downloadError: '',
serialInput: '',
supportedBoards: []
supportedBoards: [],
uploadingPort: ''
};
this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleSend = this.handleSend.bind(this);
this.handleChangeSerial = this.handleChangeSerial.bind(this);
this.showError = this.showError.bind(this);
this.clearError = this.clearError.bind(this);
this.handleUpload = this.handleUpload.bind(this);
}

componentDidMount() {
@@ -121,6 +114,9 @@ class App extends React.Component {
});

daemon.error.subscribe(this.showError);
daemon.serialMonitorError.subscribe(this.showError);
daemon.uploadingError.subscribe(this.showError);
daemon.downloadingError.subscribe(this.showError);

daemon.devicesList.subscribe(({ serial, network }) => this.setState({
serialDevices: serial,
@@ -140,6 +136,10 @@ class App extends React.Component {
scrollToBottom(serialTextarea);
});

daemon.serialMonitorMessagesWithPort.subscribe(messageObj => {
console.log(messageObj);
});

daemon.uploading.subscribe(upload => {
this.setState({ uploadStatus: upload.status, uploadError: upload.err });
// console.log(upload);
@@ -153,8 +153,20 @@ class App extends React.Component {
}
}

requestDevicePermission = () => {
if ('serial' in navigator) {
navigator.serial.requestPort([{ usbVendorId: 0x2341 }]).then((port) => {
daemon.devicesList.next({
serial: [port],
network: []
});
});
}
};

showError(err) {
this.setState({ error: err });
scrollToBottom(document.body);
}

clearError() {
@@ -187,6 +199,24 @@ class App extends React.Component {
this.setState({ serialInput: '' });
}

handleUpload() {
const target = {
board: 'arduino:samd:mkr1000',
port: '/dev/ttyACM1',
network: false
};

this.setState({ uploadingPort: target.port });
daemon.boardPortAfterUpload.subscribe(portStatus => {
if (portStatus.hasChanged) {
this.setState({ uploadingPort: portStatus.newPort });
}
});

// Upload a compiled sketch.
daemon.uploadSerial(target, 'serial_mirror', { bin: HEX });
}

render() {
const listSerialDevices = this.state.serialDevices.map((device, i) => <li key={i}>
{device.Name} - IsOpen: <span className={device.IsOpen ? 'open' : 'closed'}>
@@ -197,10 +227,10 @@ class App extends React.Component {
close
</a> - <a href="#" onClick={(e) => handleBootloaderMode(e, device.Name)}>
bootloader mode
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkrwifi1010', device.Name, 'wifiNina')}>
Wifi NINA update firmware
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkr1000', device.Name, 'wifi101')}>
Wifi 101 update firmware
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkrwifi1010', device.Name, '1.2.1')}>
MKR WiFi 1010 update firmware
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkr1000', device.Name, '19.4.4')}>
MKR1000 update firmware
</a>
</li>);

@@ -258,8 +288,10 @@ class App extends React.Component {
</div>

<div className="section">
<h2>Connected Devices</h2>

<div>
<h2 style={{ display: 'inline-block', marginRight: 10 } }>Connected Devices </h2>
{ isChromeOs() && <button type="button" onClick={() => this.requestDevicePermission()}>Request access to serial port</button> }
</div>
<strong>serial:</strong>
<ul>
{ listSerialDevices }
@@ -302,8 +334,9 @@ class App extends React.Component {

<div className="section">
<h2>Upload a sample sketch on a MKR1000 at /dev/ttyACM0</h2>
<button onClick={ handleUpload } disabled={ this.state.uploadStatus === daemon.UPLOAD_IN_PROGRESS }>Upload Sketch</button><br/>
<button onClick={ this.handleUpload } disabled={ this.state.uploadStatus === daemon.UPLOAD_IN_PROGRESS }>Upload Sketch</button><br/>
<div>Upload status: <span className={ uploadClass }> { this.state.uploadStatus }</span> <span>{ this.state.uploadError }</span></div>
<div>Uploading port: { this.state.uploadingPort || '-' }</div>
</div>

{ daemon.downloading ? <div className="section">
14 changes: 8 additions & 6 deletions demo/v2/install_tool.jsx
Original file line number Diff line number Diff line change
@@ -21,12 +21,14 @@ export class V2InstallTool extends React.Component {
componentDidMount() {
this.daemon = this.props.daemon;

this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
});
if (this.daemon.agentV2Found) { // agentV2Found not available for instance on chromebooks
this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
});
}
}

handleChange(event) {
20 changes: 11 additions & 9 deletions demo/v2/v2.jsx
Original file line number Diff line number Diff line change
@@ -12,17 +12,19 @@ class V2 extends React.Component {
componentDidMount() {
this.daemon = this.props.daemon;

this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
this.daemonV2.installedTools().then(res => {
this.setState({
tools: res
if (this.daemon.agentV2Found) { // agentV2Found not available for instance on chromebooks
this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
this.daemonV2.installedTools().then(res => {
this.setState({
tools: res
});
});
});
});
}
}

render() {
Loading