-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(app,app-shell): usb request via app-shell #12292
Conversation
Adds a silly node client that uses https://www.npmjs.com/package/agent-base to build an http agent that redirects everything through a node serialport stream https://serialport.io/docs/api-serialport including working through node-fetch (although right now you have to mess with the url). Many things to continue working on but this works shockingly well
makes a GET /instruments request from the app device details page via serial cable connection. facilitated via promise-based electron IPC communication and custom usb HTTP agent created in discovery-client
Codecov Report
@@ Coverage Diff @@
## edge #12292 +/- ##
==========================================
- Coverage 73.26% 73.15% -0.11%
==========================================
Files 1508 1488 -20
Lines 49453 48997 -456
Branches 3006 2903 -103
==========================================
- Hits 36230 35843 -387
+ Misses 12764 12698 -66
+ Partials 459 456 -3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh man this is so cool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is fkn awesome! we should do a group review with @sfoster1 to discuss next steps. seems reasonable to merge into the prototyping branch though
app-shell/package.json
Outdated
@@ -59,6 +59,7 @@ | |||
"node-stream-zip": "1.8.2", | |||
"pump": "3.0.0", | |||
"semver": "5.5.0", | |||
"serialport": "^10.5.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we prolly wanna pin this to a fixed version
app-shell/src/discovery.ts
Outdated
.getSerialPorts?.() | ||
.find(port => port.productId === DEFAULT_PRODUCT_ID) | ||
|
||
// TODO: handle null case properly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we can't find a serial port we prolly wanna just bail and do nothing for now
discovery-client/package.json
Outdated
"devDependencies": { | ||
"@opentrons/usb-bridge/node-client": "link:../usb-bridge/node-client" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a normal dep right?
* TODO: poll via serial port if connection present and combine in same object if same robot? | ||
* will poll serial port for every robot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that makes sense to me cc @sfoster1
@@ -54,6 +55,11 @@ export const getRobots: ( | |||
} | |||
) | |||
|
|||
export const getSerialPorts: (state: State) => PortInfo[] = createSelector( | |||
state => state.serialPorts, | |||
serialPorts => serialPorts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can either get rid of line 60 or not use reselect since this is just pulling from state
robotsByName: robotsByNameReducer, | ||
hostsByIp: hostsByIpReducer, | ||
manualAddresses: manualAddressesReducer, | ||
serialPorts: serialPortsReducer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we somehow roll serial ports into hostsByIp
(we'd have to rename it to be something else), all of the info should be the same it would just be a serial port instad of an ip address. hostsByIp
returns a HostsByIpMap
interface:
export interface HostsByIpMap {
[ipAddress: string]: HostState
}
export interface HostState extends Address {
/** Whether this IP has been seen via mDNS or HTTP while the client has been running */
seen: boolean
/** How the last GET /health responded (null if no response yet) */
healthStatus: HealthStatus | null
/** How the last GET /server/update/health responded (null if no response yet) */
serverHealthStatus: HealthStatus | null
/** Error status and response from /health if last request was not 200 */
healthError: HealthErrorResponse | null
/** Error status and response from /server/update/health if last request was not 200 */
serverHealthError: HealthErrorResponse | null
/** Robot that this IP points to */
robotName: string
/** the robot model advertised in mdns, if known */
advertisedModel: string | null
}
This is so cool! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is awesome! tested it out and seems to work pretty smoothly. excited to get this into the next internal release. great job @brenthagen!
// prefer ip hostname | ||
const isIpSort = isIp(b.ip) ? 1 : -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅
@@ -33,6 +34,7 @@ | |||
"@babel/eslint-parser": "^7.12.1", | |||
"@babel/plugin-proposal-class-properties": "^7.12.1", | |||
"@babel/plugin-transform-modules-commonjs": "^7.12.1", | |||
"@babel/plugin-transform-typescript": "^7.14.5", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can already use the types syntax — how come we need this plugin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this error happens when trying to use the declare
keyword:
[shell] Module build failed (from ../node_modules/babel-loader/lib/index.js):
[shell] SyntaxError: /Users/brenthagen/opentrons/usb-bridge/node-client/src/usb-agent.ts: TypeScript 'declare' fields must first be transformed by @babel/plugin-transform-typescript.
[shell] If you have already enabled that plugin (or '@babel/preset-typescript'), make sure that it runs before any plugin related to additional class features:
[shell] - @babel/plugin-proposal-class-properties
[shell] - @babel/plugin-proposal-private-methods
[shell] - @babel/plugin-proposal-decorators
[shell] 140 | } = { path: '' }
[shell] 141 |
[shell] > 142 | declare totalSocketCount: number
[shell] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
so i inserted @babel/plugin-transform-typescript
above @babel/plugin-proposal-class-properties
in our babel config
## overview | ||
|
||
## api | ||
|
||
``` | ||
|
||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm we should either fill these sections out or delete em
#!/usr/bin/env node | ||
'use strict' | ||
require('../lib/cli') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not following why this is necessary. if our ts config is set up correctly (which i think it is?) we shouldn't have to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is boilerplate i believe seth copied over from the discovery-client
to enable cli requests. I left that in, do we want to take it out?
usb-bridge/node-client/package.json
Outdated
"dependencies": { | ||
"serialport": "10.5.0", | ||
"yargs": "15.4.0", | ||
"node-fetch": "^2.6.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably pin this to a specific version to avoid surprises
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems reasonable to pin to 2.6.7 in app-shell, discovery-client, and here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is awesome! tested it out and seems to work pretty smoothly. excited to get this into the next internal release. great job @brenthagen!
no idea how the last review got duplicated... and i cant seem to delete them |
This (large) PR enables http communication between the opentrons desktop app and an OT-3 robot via usb serial port connection. It adds a new package
usb-bridge/node-client
and uses it as follows:app
detects OT-3 usb device connectionapp-shell
fetches OT-3 serial port path associated with OT-3app-shell
creates a custom serial port http agent singletondiscovery client
polls health for assigned hostnameopentrons-usb
using serial port http agentopentrons-usb
hostname,app
passes electron two-way IPC invoke requestor function toApiHostProvider
host contextapi-client
uses provided requestor function for http requestsapp-shell
handles IPC http requests, makes axios requests using serial port http agenta handful of work left for this or follow-on PRs:
electron-dl
) doesn't work with a custom agent - either inactivate for a usb connection or refactor how app-shell downloadsusb-bridge/node-client
documentation