Add reconnect m

This commit is contained in:
raldone01
2025-07-29 15:51:54 +02:00
parent f36f97c45a
commit 9c1115e066
4 changed files with 44 additions and 29 deletions

View File

@@ -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();

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;
}