@@ -11,19 +11,42 @@ interface ISerialPortDetail {
11
11
port : string ;
12
12
desc : string ;
13
13
hwid : string ;
14
- // vendorId: string;
15
- // productId: string;
14
+ vendorId : string ;
15
+ productId : string ;
16
16
}
17
17
18
18
export class SerialPortCtrl {
19
19
20
+ /**
21
+ * Launches the serial monitor to check which external usb devices are connected.
22
+ *
23
+ * @returns An array of ISerialPortDetail from external serial devices.
24
+ *
25
+ */
20
26
public static list ( ) : Promise < ISerialPortDetail [ ] > {
21
27
// TODO: Wrap this in a try catch block, catch error if no serial monitor at path
22
28
const stdout = execFileSync ( SerialPortCtrl . _serialCliPath , [ "list-ports" ] ) ;
23
29
const lists = JSON . parse ( stdout ) ;
30
+ lists . forEach ( ( port ) => {
31
+ const vidPid = this . _parseVidPid ( port [ "hwid" ] ) ;
32
+ port [ "vendorId" ] = vidPid [ "vid" ] ;
33
+ port [ "productId" ] = vidPid [ "pid" ] ;
34
+ } ) ;
24
35
return lists ;
25
36
}
26
37
38
+ /**
39
+ * Parse out vendor id and product id from the hardware id provided by the device.
40
+ *
41
+ * @param hwid: The hardware information for a sepcific device
42
+ *
43
+ * @returns vendor id and product id values in an array. Returns null if none are found.
44
+ */
45
+ private static _parseVidPid ( hwid : string ) : any {
46
+ const result = hwid . match ( / V I D : P I D = (?< vid > \w + ) : (?< pid > \w + ) / i) ;
47
+ return result !== null ? result [ "groups" ] : [ null , null ] ;
48
+ }
49
+
27
50
private static get _serialCliPath ( ) : string {
28
51
let fileName : string ;
29
52
if ( os . platform ( ) === "win32" ) {
@@ -56,17 +79,18 @@ export class SerialPortCtrl {
56
79
return this . _currentPort ;
57
80
}
58
81
59
- public open ( ) : Promise < any > {
82
+ public open ( ) : Promise < void > {
60
83
this . _outputChannel . appendLine ( `[Starting] Opening the serial port - ${ this . _currentPort } ` ) ;
61
84
this . _outputChannel . show ( ) ;
62
85
63
86
if ( this . _child ) {
64
- this . _child . stdin . write ( "close\n" ) ;
87
+ this . stop ( ) ;
65
88
}
66
- this . _child = spawn ( SerialPortCtrl . _serialCliPath ,
67
- [ "open" , this . _currentPort , "-b" , this . _currentBaudRate . toString ( ) , "--json" ] )
68
89
69
90
return new Promise ( ( resolve , reject ) => {
91
+ this . _child = spawn ( SerialPortCtrl . _serialCliPath ,
92
+ [ "open" , this . _currentPort , "-b" , this . _currentBaudRate . toString ( ) , "--json" ] )
93
+
70
94
this . _child . on ( "error" , ( err ) => {
71
95
reject ( err )
72
96
} ) ;
@@ -75,51 +99,56 @@ export class SerialPortCtrl {
75
99
const jsonObj = JSON . parse ( data . toString ( ) )
76
100
this . _outputChannel . append ( jsonObj [ "payload" ] + "\n" ) ;
77
101
} ) ;
78
- resolve ( true ) ;
102
+ // TODO: add message check to ensure _child spawned without errors
103
+ resolve ( ) ;
104
+ // The spawn event is only supported in node v15+ vscode
105
+ // this._child.on("spawn", (spawn) => {
106
+ // resolve();
107
+ // });
108
+
79
109
} ) ;
80
110
}
81
111
82
- public sendMessage ( text : string ) : Promise < any > {
112
+ public sendMessage ( text : string ) : Promise < void > {
83
113
return new Promise ( ( resolve , reject ) => {
84
114
if ( ! text || ! this . _currentSerialPort || ! this . isActive ) {
85
- resolve ( false ) ;
115
+ resolve ( ) ;
86
116
return ;
87
117
}
88
118
89
119
this . _currentSerialPort . write ( text + "\r\n" , ( error ) => {
90
120
if ( ! error ) {
91
- resolve ( true ) ;
121
+ resolve ( ) ;
92
122
} else {
93
123
return reject ( error ) ;
94
124
}
95
125
} ) ;
96
126
} ) ;
97
127
}
98
128
99
- public changePort ( newPort : string ) : Promise < any > {
129
+ public changePort ( newPort : string ) : Promise < void > {
100
130
return new Promise ( ( resolve , reject ) => {
101
131
if ( newPort === this . _currentPort ) {
102
- resolve ( true ) ;
132
+ resolve ( ) ;
103
133
return ;
104
134
}
105
135
this . _currentPort = newPort ;
106
136
if ( ! this . _currentSerialPort || ! this . isActive ) {
107
- resolve ( false ) ;
137
+ resolve ( ) ;
108
138
return ;
109
139
}
110
140
this . _currentSerialPort . close ( ( err ) => {
111
141
if ( err ) {
112
142
reject ( err ) ;
113
143
} else {
114
144
this . _currentSerialPort = null ;
115
- resolve ( true ) ;
145
+ resolve ( ) ;
116
146
}
117
147
} ) ;
118
148
} ) ;
119
149
}
120
150
121
- public stop ( ) : Promise < any > {
122
- this . _child . stdin . write ( '{"cmd": "close"}\n' ) ;
151
+ public stop ( ) : Promise < boolean > {
123
152
return new Promise ( ( resolve , reject ) => {
124
153
if ( ! this . isActive ) {
125
154
resolve ( false ) ;
@@ -138,18 +167,17 @@ export class SerialPortCtrl {
138
167
} ) ;
139
168
}
140
169
141
- public changeBaudRate ( newRate : number ) : Promise < any > {
142
- // this._outputChannel.appendLine(this.isActive.toString());
170
+ public changeBaudRate ( newRate : number ) : Promise < void > {
143
171
return new Promise ( ( resolve , reject ) => {
144
172
this . _currentBaudRate = newRate ;
145
173
if ( ! this . _child || ! this . isActive ) {
146
- resolve ( true ) ;
174
+ resolve ( ) ;
147
175
return ;
148
176
} else {
149
177
try {
150
178
this . stop ( ) ;
151
179
this . open ( ) ;
152
- resolve ( true ) ;
180
+ resolve ( ) ;
153
181
} catch ( error ) {
154
182
reject ( error ) ;
155
183
}
0 commit comments