Add reconnect m
This commit is contained in:
@@ -369,7 +369,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
setStatus(msg, level = 'info') {
|
setStatus(msg, level = 'info') {
|
||||||
console.log(msg);
|
console.error(msg);
|
||||||
uiStatusSpan.textContent = msg;
|
uiStatusSpan.textContent = msg;
|
||||||
uiStatusSpan.className = 'status status-' + level;
|
uiStatusSpan.className = 'status status-' + level;
|
||||||
}
|
}
|
||||||
@@ -596,24 +596,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async autoReconnectTimeout() {
|
||||||
|
this.reconnectTimeoutId = null;
|
||||||
|
if (!uiAutoReconnectCheckbox.checked) {
|
||||||
|
this.setStatus('Auto-reconnect stopped.', 'info');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.currentPort && !this.currentPort.isConnected) {
|
||||||
|
try {
|
||||||
|
await this.currentPort.connect();
|
||||||
|
this.setStatus('Reconnected successfully', 'info');
|
||||||
|
} catch (error) {
|
||||||
|
this.setStatus(`Reconnect failed: ${error.message}`, 'error');
|
||||||
|
// Try again after a delay
|
||||||
|
this.tryAutoReconnect();
|
||||||
|
} finally {
|
||||||
|
this.updateUIConnectionState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tryAutoReconnect() {
|
tryAutoReconnect() {
|
||||||
this.updateUIConnectionState();
|
this.updateUIConnectionState();
|
||||||
if (!uiAutoReconnectCheckbox.checked) return;
|
if (!uiAutoReconnectCheckbox.checked) return;
|
||||||
if (this.reconnectTimeoutId !== null) return; // already trying
|
if (this.reconnectTimeoutId !== null) return; // already trying
|
||||||
this.setStatus('Attempting to auto-reconnect...', 'info');
|
this.setStatus('Attempting to auto-reconnect...', 'info');
|
||||||
this.reconnectTimeoutId = setTimeout(async () => {
|
this.reconnectTimeoutId = setTimeout(async () => {
|
||||||
this.reconnectTimeoutId = null;
|
await this.autoReconnectTimeout();
|
||||||
if (!uiAutoReconnectCheckbox.checked) {
|
|
||||||
this.setStatus('Auto-reconnect stopped.', 'info');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.currentPort) {
|
|
||||||
try {
|
|
||||||
await this.currentPort.connect();
|
|
||||||
} finally {
|
|
||||||
this.updateUIConnectionState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,14 +771,15 @@
|
|||||||
// save <iso_date_time>,<received_line>
|
// save <iso_date_time>,<received_line>
|
||||||
let csvContent = 'data:text/csv;charset=utf-8,';
|
let csvContent = 'data:text/csv;charset=utf-8,';
|
||||||
for (const entry of this.receivedData) {
|
for (const entry of this.receivedData) {
|
||||||
let line = new Date(entry.time).toISOString() + ',"' + entry.text.replace(/[\r\n]+$/, '') + '"';
|
let sanitizedText = entry.text.replace(/"/g, '""').replace(/[\r\n]+$/, '');
|
||||||
|
let line = new Date(entry.time).toISOString() + ',"' + sanitizedText + '"';
|
||||||
csvContent += line + '\n';
|
csvContent += line + '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
const encodedUri = encodeURI(csvContent);
|
const encodedUri = encodeURI(csvContent);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.setAttribute('href', encodedUri);
|
link.setAttribute('href', encodedUri);
|
||||||
const filename = new Date().toISOString() + '_tinyusb_received_serial_data.csv';
|
const filename = new Date().toISOString().replace(/:/g, '-') + '_tinyusb_received_serial_data.csv';
|
||||||
link.setAttribute('download', filename);
|
link.setAttribute('download', filename);
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<label for="auto_reconnect_checkbox" class="controls">
|
<label for="auto_reconnect_checkbox" class="controls">
|
||||||
<input type="checkbox" id="auto_reconnect_checkbox" />
|
<input type="checkbox" id="auto_reconnect_checkbox" />
|
||||||
Auto Reconnect
|
Auto Reconnect WebUSB
|
||||||
</label>
|
</label>
|
||||||
<button id="forget_device_btn" class="controls btn danger">Forget Device</button>
|
<button id="forget_device_btn" class="controls btn danger">Forget Device</button>
|
||||||
<button id="forget_all_devices_btn" class="controls btn danger">Forget All Devices</button>
|
<button id="forget_all_devices_btn" class="controls btn danger">Forget All Devices</button>
|
||||||
|
@@ -116,7 +116,7 @@ class SerialPort {
|
|||||||
if (!this._port.writable) {
|
if (!this._port.writable) {
|
||||||
throw new Error('Port is not writable');
|
throw new Error('Port is not writable');
|
||||||
}
|
}
|
||||||
this._writer = port.writeable.getWriter();
|
this._writer = this._port.writable.getWriter();
|
||||||
if (!this._writer) {
|
if (!this._writer) {
|
||||||
throw new Error('Failed to get writer from port');
|
throw new Error('Failed to get writer from port');
|
||||||
}
|
}
|
||||||
@@ -141,6 +141,13 @@ class WebUsbSerialPort {
|
|||||||
this._readLoopPromise = null;
|
this._readLoopPromise = null;
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
this._keepReading = true;
|
this._keepReading = true;
|
||||||
|
|
||||||
|
this._vendorId = device.vendorId;
|
||||||
|
this._productId = device.productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isSameWebUsbSerialPort(webUsbSerialPort) {
|
||||||
|
return this._vendorId === webUsbSerialPort._vendorId && this._productId === webUsbSerialPort._productId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect and start reading loop
|
/// Connect and start reading loop
|
||||||
@@ -152,14 +159,9 @@ class WebUsbSerialPort {
|
|||||||
console.error('Error disconnecting previous device:', error);
|
console.error('Error disconnecting previous device:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._readLoopPromise) {
|
const webUsbSerialPorts = await serial.getWebUsbSerialPorts();
|
||||||
try {
|
const webUsbSerialPort = webUsbSerialPorts.find(serialPort => this._isSameWebUsbSerialPort(serialPort));
|
||||||
await this._readLoopPromise;
|
this._device = webUsbSerialPort ? webUsbSerialPort._device : this._device;
|
||||||
} catch (error) {
|
|
||||||
console.error('Error in read loop:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._readLoopPromise = null;
|
|
||||||
}
|
}
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
|
|
||||||
|
@@ -221,6 +221,12 @@ body.dark-mode {
|
|||||||
color: #d4d4d4;
|
color: #d4d4d4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.dark-mode input[type="checkbox"] {
|
||||||
|
border-color: #888;
|
||||||
|
accent-color: #2e2e2e;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
body.dark-mode .btn-theme {
|
body.dark-mode .btn-theme {
|
||||||
background-color: #b0b0b0;
|
background-color: #b0b0b0;
|
||||||
color: #000;
|
color: #000;
|
||||||
@@ -251,6 +257,7 @@ body.dark-mode .input:focus {
|
|||||||
|
|
||||||
body.dark-mode .scrollbox {
|
body.dark-mode .scrollbox {
|
||||||
background-color: #252526;
|
background-color: #252526;
|
||||||
|
scrollbar-color: #555 #2e2e2e;
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +294,3 @@ body.dark-mode option {
|
|||||||
background-color: #3c3c3c;
|
background-color: #3c3c3c;
|
||||||
color: #f0f0f0;
|
color: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.dark-mode .scrollbox {
|
|
||||||
scrollbar-color: #555 #2e2e2e;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user