Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 1718768

Browse files
Merge pull request #1430 from BelKed/serial-timestamp
Add option for printing timestamp before each line of Serial Monitor output
2 parents 251f307 + c63c581 commit 1718768

File tree

9 files changed

+102
-2
lines changed

9 files changed

+102
-2
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ This extension provides several commands in the Command Palette (<kbd>F1</kbd> o
4747
- **Arduino: Board Manager**: Manage packages for boards. You can add 3rd party Arduino board by configuring `Additional Board Manager URLs` in the board manager.
4848
- **Arduino: Change Baud Rate**: Change the baud rate of the selected serial port.
4949
- **Arduino: Change Board Type**: Change board type or platform.
50+
- **Arduino: Change Timestamp Format**: Change format of timestamp printed before each line of Serial Monitor output.
5051
- **Arduino: Close Serial Monitor**: Stop the serial monitor and release the serial port.
5152
- **Arduino: Examples**: Show list of examples.
5253
- **Arduino: Initialize**: Scaffold a VS Code project with an Arduino sketch.
@@ -79,6 +80,7 @@ This extension provides several commands in the Command Palette (<kbd>F1</kbd> o
7980
| `arduino.disableTestingOpen` | Enable/disable automatic sending of a test message to the serial port for checking the open status. The default value is `false` (a test message will be sent). |
8081
| `arduino.skipHeaderProvider` | Enable/disable the extension providing completion items for headers. This functionality is included in newer versions of the C++ extension. The default value is `false`.|
8182
| `arduino.defaultBaudRate` | Default baud rate for the serial port monitor. The default value is 115200. Supported values are 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400 and 250000 |
83+
| `arduino.defaultTimestampFormat` | Format of timestamp printed before each line of Serial Monitor output. You can find list of all available placeholders [here](https://strftime.org). |
8284
| `arduino.disableIntelliSenseAutoGen` | When `true` vscode-arduino will not auto-generate an IntelliSense configuration (i.e. `.vscode/c_cpp_properties.json`) by analyzing Arduino's compiler output. |
8385

8486
The following Visual Studio Code settings are available for the Arduino extension. These can be set in global user preferences <kbd>Ctrl</kbd> + <kbd>,</kbd> or workspace settings (`.vscode/settings.json`). The latter overrides the former.

package.json

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"onCommand:arduino.selectSerialPort",
4545
"onCommand:arduino.selectSketch",
4646
"onCommand:arduino.changeBaudRate",
47+
"onCommand:arduino.changeTimestampFormat",
4748
"onCommand:arduino.openSerialMonitor",
4849
"onCommand:arduino.sendMessageToSerialPort",
4950
"onCommand:arduino.closeSerialMonitor",
@@ -128,6 +129,10 @@
128129
"command": "arduino.changeBaudRate",
129130
"title": "Arduino: Change Baud Rate"
130131
},
132+
{
133+
"command": "arduino.changeTimestampFormat",
134+
"title": "Arduino: Change Timestamp Format"
135+
},
131136
{
132137
"command": "arduino.openSerialMonitor",
133138
"title": "Arduino: Open Serial Monitor"
@@ -531,6 +536,11 @@
531536
"type": "boolean",
532537
"default": false,
533538
"description": "When disabled vscode-arduino will not auto-generate an IntelliSense configuration (i.e. c_cpp_properties.json) by analyzing the compiler output."
539+
},
540+
"arduino.defaultTimestampFormat": {
541+
"type": "string",
542+
"default": "",
543+
"markdownDescription": "Format of timestamp printed before each line of Serial Monitor output. You can find list of all available placeholders [here](https://strftime.org)."
534544
}
535545
}
536546
},

src/arduino/arduinoSettings.ts

+17
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface IArduinoSettings {
2222
defaultBaudRate: number;
2323
preferences: Map<string, string>;
2424
useArduinoCli: boolean;
25+
defaultTimestampFormat: string;
2526
reloadPreferences(): void;
2627
}
2728

@@ -40,6 +41,8 @@ export class ArduinoSettings implements IArduinoSettings {
4041

4142
private _useArduinoCli: boolean;
4243

44+
private _defaultTimestampFormat: string;
45+
4346
public constructor() {
4447
}
4548

@@ -49,6 +52,7 @@ export class ArduinoSettings implements IArduinoSettings {
4952
this._useArduinoCli = VscodeSettings.getInstance().useArduinoCli;
5053
await this.tryResolveArduinoPath();
5154
await this.tryGetDefaultBaudRate();
55+
await this.tryGetDefaultTimestampFormat();
5256
if (platform === "win32") {
5357
await this.updateWindowsPath();
5458
if (this._commandPath === "") {
@@ -161,6 +165,10 @@ export class ArduinoSettings implements IArduinoSettings {
161165
return this._defaultBaudRate;
162166
}
163167

168+
public get defaultTimestampFormat() {
169+
return this._defaultTimestampFormat;
170+
}
171+
164172
public reloadPreferences() {
165173
this._preferences = util.parseConfigFile(this.preferencePath);
166174
if (this.preferences.get("sketchbook.path")) {
@@ -234,4 +242,13 @@ export class ArduinoSettings implements IArduinoSettings {
234242
this._defaultBaudRate = configValue;
235243
}
236244
}
245+
246+
private async tryGetDefaultTimestampFormat(): Promise<void> {
247+
const configValue = VscodeSettings.getInstance().defaultTimestampFormat;
248+
if (!configValue) {
249+
this._defaultTimestampFormat = "";
250+
} else {
251+
this._defaultTimestampFormat = configValue;
252+
}
253+
}
237254
}

src/arduino/vscodeSettings.ts

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const configKeys = {
1919
DEFAULT_BAUD_RATE: "arduino.defaultBaudRate",
2020
USE_ARDUINO_CLI: "arduino.useArduinoCli",
2121
DISABLE_INTELLISENSE_AUTO_GEN: "arduino.disableIntelliSenseAutoGen",
22+
DEFAULT_TIMESTAMP_FORMAT: "arduino.defaultTimestampFormat",
2223
};
2324

2425
export interface IVscodeSettings {
@@ -35,6 +36,7 @@ export interface IVscodeSettings {
3536
defaultBaudRate: number;
3637
useArduinoCli: boolean;
3738
disableIntelliSenseAutoGen: boolean;
39+
defaultTimestampFormat: string;
3840
updateAdditionalUrls(urls: string[]): void;
3941
}
4042

@@ -118,6 +120,10 @@ export class VscodeSettings implements IVscodeSettings {
118120
return this.getConfigValue<boolean>(configKeys.DISABLE_INTELLISENSE_AUTO_GEN);
119121
}
120122

123+
public get defaultTimestampFormat(): string {
124+
return this.getConfigValue<string>(configKeys.DEFAULT_TIMESTAMP_FORMAT);
125+
}
126+
121127
public async updateAdditionalUrls(value) {
122128
await this.setConfigValue(configKeys.ADDITIONAL_URLS, value, true);
123129
}

src/common/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const statusBarPriority = {
4343
PORT: 20,
4444
OPEN_PORT: 30,
4545
BAUD_RATE: 40,
46+
TIMESTAMP_FORMAT: 50,
4647
BOARD: 60,
4748
ENDING: 70,
4849
SKETCH: 80,

src/extension.ts

+1
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ export async function activate(context: vscode.ExtensionContext) {
284284
registerNonArduinoCommand("arduino.selectSerialPort", () => serialMonitor.selectSerialPort(null, null));
285285
registerNonArduinoCommand("arduino.openSerialMonitor", () => serialMonitor.openSerialMonitor());
286286
registerNonArduinoCommand("arduino.changeBaudRate", () => serialMonitor.changeBaudRate());
287+
registerNonArduinoCommand("arduino.changeTimestampFormat", () => serialMonitor.changeTimestampFormat());
287288
registerNonArduinoCommand("arduino.sendMessageToSerialPort", () => serialMonitor.sendMessageToSerialPort());
288289
registerNonArduinoCommand("arduino.closeSerialMonitor", (port, showWarning = true) => serialMonitor.closeSerialMonitor(port, showWarning));
289290

src/serialmonitor/serialMonitor.ts

+41
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export class SerialMonitor implements vscode.Disposable {
2323

2424
public static DEFAULT_BAUD_RATE: number = 115200;
2525

26+
public static DEFAULT_TIMESTAMP_FORMAT: string = "";
27+
2628
public static listBaudRates(): number[] {
2729
return [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000, 2000000];
2830
}
@@ -40,12 +42,16 @@ export class SerialMonitor implements vscode.Disposable {
4042

4143
private _currentBaudRate: number;
4244

45+
private _currentTimestampFormat: string;
46+
4347
private _portsStatusBar: vscode.StatusBarItem;
4448

4549
private _openPortStatusBar: vscode.StatusBarItem;
4650

4751
private _baudRateStatusBar: vscode.StatusBarItem;
4852

53+
private _timestampFormatStatusBar: vscode.StatusBarItem;
54+
4955
private _serialPortCtrl: SerialPortCtrl = null;
5056

5157
private _outputChannel: vscode.OutputChannel;
@@ -59,9 +65,16 @@ export class SerialMonitor implements vscode.Disposable {
5965
} else {
6066
defaultBaudRate = SerialMonitor.DEFAULT_BAUD_RATE;
6167
}
68+
let defaultTimestampFormat;
69+
if (ArduinoContext.arduinoApp && ArduinoContext.arduinoApp.settings && ArduinoContext.arduinoApp.settings.defaultTimestampFormat) {
70+
defaultTimestampFormat = ArduinoContext.arduinoApp.settings.defaultTimestampFormat;
71+
} else {
72+
defaultTimestampFormat = SerialMonitor.DEFAULT_TIMESTAMP_FORMAT;
73+
}
6274
this._outputChannel = vscode.window.createOutputChannel(SerialMonitor.SERIAL_MONITOR);
6375
this._bufferedOutputChannel = new BufferedOutputChannel(this._outputChannel.append, 300);
6476
this._currentBaudRate = defaultBaudRate;
77+
this._currentTimestampFormat = defaultTimestampFormat;
6578
this._portsStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.PORT);
6679
this._portsStatusBar.command = "arduino.selectSerialPort";
6780
this._portsStatusBar.tooltip = "Select Serial Port";
@@ -77,6 +90,12 @@ export class SerialMonitor implements vscode.Disposable {
7790
this._baudRateStatusBar.command = "arduino.changeBaudRate";
7891
this._baudRateStatusBar.tooltip = "Baud Rate";
7992
this._baudRateStatusBar.text = defaultBaudRate.toString();
93+
94+
this._timestampFormatStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right,
95+
constants.statusBarPriority.TIMESTAMP_FORMAT);
96+
this._timestampFormatStatusBar.command = "arduino.changeTimestampFormat";
97+
this._timestampFormatStatusBar.tooltip = `Timestamp Format: "${defaultTimestampFormat}"`;
98+
this._timestampFormatStatusBar.text = `$(watch)`;
8099
this.updatePortListStatus();
81100

82101
const dc = DeviceContext.getInstance();
@@ -154,6 +173,7 @@ export class SerialMonitor implements vscode.Disposable {
154173
this._serialPortCtrl = new SerialPortCtrl(
155174
this._currentPort,
156175
this._currentBaudRate,
176+
this._currentTimestampFormat,
157177
this._bufferedOutputChannel,
158178
this._outputChannel.show);
159179
}
@@ -206,6 +226,25 @@ export class SerialMonitor implements vscode.Disposable {
206226
this._baudRateStatusBar.text = chosen;
207227
}
208228

229+
public async changeTimestampFormat() {
230+
const timestampFormat = await vscode.window.showInputBox();
231+
if (!timestampFormat) {
232+
Logger.warn("No timestamp format inputted, keeping previous timestamp format.");
233+
return;
234+
}
235+
if (timestampFormat.indexOf("%") < 0) {
236+
Logger.warn("Invalid timestamp format, keeping previous timestamp format.", { value: timestampFormat });
237+
return;
238+
}
239+
if (!this._serialPortCtrl) {
240+
Logger.warn("Serial Monitor has not been started.");
241+
return;
242+
}
243+
await this._serialPortCtrl.changeTimestampFormat(timestampFormat);
244+
this._currentTimestampFormat = timestampFormat;
245+
this._timestampFormatStatusBar.tooltip = `Timestamp Format: "${timestampFormat}"`;
246+
}
247+
209248
public async closeSerialMonitor(port: string, showWarning: boolean = true): Promise<boolean> {
210249
if (this._serialPortCtrl) {
211250
if (port && port !== this._serialPortCtrl.currentPort) {
@@ -241,11 +280,13 @@ export class SerialMonitor implements vscode.Disposable {
241280
this._openPortStatusBar.text = `$(x)`;
242281
this._openPortStatusBar.tooltip = "Close Serial Monitor";
243282
this._baudRateStatusBar.show();
283+
this._timestampFormatStatusBar.show();
244284
} else {
245285
this._openPortStatusBar.command = "arduino.openSerialMonitor";
246286
this._openPortStatusBar.text = `$(plug)`;
247287
this._openPortStatusBar.tooltip = "Open Serial Monitor";
248288
this._baudRateStatusBar.hide();
289+
this._timestampFormatStatusBar.hide();
249290
}
250291

251292
}

src/serialmonitor/serialportctrl.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ export class SerialPortCtrl {
6262
private _currentPort: string;
6363
private _currentBaudRate: number;
6464
private _currentSerialPort = null;
65+
private _currentTimestampFormat: string;
6566

6667
public constructor(
6768
port: string,
6869
baudRate: number,
70+
timestampFormat: string,
6971
private _bufferedOutputChannel: BufferedOutputChannel,
7072
private showOutputChannel: (preserveFocus?: boolean) => void) {
7173
this._currentBaudRate = baudRate;
7274
this._currentPort = port;
75+
this._currentTimestampFormat = timestampFormat;
7376
}
7477

7578
/*
@@ -93,7 +96,7 @@ export class SerialPortCtrl {
9396

9497
return new Promise((resolve, reject) => {
9598
this._child = spawn(SerialPortCtrl._serialCliPath,
96-
["open", this._currentPort, "-b", this._currentBaudRate.toString(), "--json"])
99+
["open", this._currentPort, "-b", this._currentBaudRate.toString(), "-t", this._currentTimestampFormat, "--json"])
97100

98101
this._child.on("error", (err) => {
99102
reject(err)
@@ -102,7 +105,7 @@ export class SerialPortCtrl {
102105
this._child.stdout.on("data", (data) => {
103106
if (this.isActive) {
104107
const jsonObj = JSON.parse(data.toString())
105-
this._bufferedOutputChannel.append(jsonObj["payload"] + "\n");
108+
this._bufferedOutputChannel.append(jsonObj["timestamp"] + jsonObj["payload"] + "\n");
106109
}
107110
});
108111
// TODO: add message check to ensure _child spawned without errors
@@ -189,4 +192,22 @@ export class SerialPortCtrl {
189192
}
190193
});
191194
}
195+
196+
public changeTimestampFormat(newTimestampFormat: string): Promise<void> {
197+
return new Promise((resolve, reject) => {
198+
this._currentTimestampFormat = newTimestampFormat;
199+
if (!this._child || !this.isActive) {
200+
resolve();
201+
return;
202+
} else {
203+
try {
204+
this.stop();
205+
this.open();
206+
resolve();
207+
} catch (error) {
208+
reject(error);
209+
}
210+
}
211+
});
212+
}
192213
}

test/extension.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ suite("Arduino: Extension Tests", () => {
4848
"arduino.selectSerialPort",
4949
"arduino.openSerialMonitor",
5050
"arduino.changeBaudRate",
51+
"arduino.changeTimestampFormat",
5152
"arduino.sendMessageToSerialPort",
5253
"arduino.closeSerialMonitor",
5354
"arduino.reloadExample",

0 commit comments

Comments
 (0)