From 18152267d621b3adf805d225f6724ca2334ffb1a Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Thu, 8 Aug 2024 15:27:25 -0400 Subject: [PATCH 1/3] Add dockerfile --- .dockerignore | 3 +++ Dockerfile | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ffa7578 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +Makefile +README.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5343fbf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,2 @@ +FROM nginx +COPY . /usr/share/nginx/html -- 2.38.4 From 072cd60c34d13642b47283dd7654d3e4b64e05ba Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Thu, 8 Aug 2024 20:49:26 -0400 Subject: [PATCH 2/3] Still hitting error --- script.js | 88 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/script.js b/script.js index 0ec1a23..bea8934 100644 --- a/script.js +++ b/script.js @@ -9,6 +9,8 @@ const refreshPorts = document.getElementById('refresh-ports'); const scrollableElement = document.getElementById('scrollable-element'); const select = document.getElementById('serial-select'); +let isPortConnected = false; +let controller; let autoscroll = true; let serialPorts = []; let reader; @@ -33,26 +35,32 @@ clearButton.addEventListener('click', () => { } }); +function onPortConnect(){ + connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.textContent = 'Disconnect'; +} + +function onPortDisconnect(){ + connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.textContent = 'Connect'; +} + connectButton.addEventListener('click', async () => { const selectedPort = serialPorts[select.selectedIndex] const baudRate = Math.round(baud.value) - if (selectedPort) { + if (!isPortConnected) { await connectToSerialPort(selectedPort, baudRate); + } else { + isPortConnected = false; } }); refreshPorts.addEventListener('click', async () => { - while (select.children.length > 1) { - select.removeChild(select.lastChild); - } - ports = await navigator.serial.getPorts(); - - console.log(ports) - ports.forEach(port => { - const option = buildPortOption(port) - select.appendChild(option); - }); + serialPorts = ports + updateSerialSelect(ports) }); // Functions @@ -91,17 +99,45 @@ function scrollToBottom() { scrollableElement.scrollTop = scrollableElement.scrollHeight; } +// function onSerialConnect() { +// console.log("connected to port") +// connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); +// connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); +// connectButton.textContent = 'Disconnect'; +// isPortConnected = port; +// } + // Async Functions async function connectToSerialPort(port, baud) { + port.addEventListener("onconnect", () => { + console.log("connected to port") + connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.textContent = 'Disconnect'; + isPortConnected = true; + }); + + port.addEventListener('ondisconnect', () => { + console.log("disconnect from port") + connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.textContent = 'Connect'; + isPortConnected = false; + }); + + console.log("Opening port") await port.open({ baudRate: baud }); + onPortConnect() let buffer = '' const textDecoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(textDecoder.writable); - const reader = textDecoder.readable.getReader(); - + reader = textDecoder.readable.getReader(); + controller = new AbortController(); + const signal = controller.signal; try { - while (true) { - const { value, done } = await reader.read(); + isPortConnected = true; + while (isPortConnected) { + const { value, done } = await reader.read({signal}); if (done) { break; } @@ -119,9 +155,24 @@ async function connectToSerialPort(port, baud) { } catch (error) { console.error('Error reading data from serial port:', error); } finally { + console.log("Calling abort on read") + controller.abort(); + console.log("Calling releaseLock on reader") reader.releaseLock(); - await readableStreamClosed.catch(() => { }); - await port.close(); + try { + // Gracefully close the stream + await textDecoder.readable.cancel(); + } catch (error) { + console.error("Error encountered in readableStreamClosed:", error); + } + try { + console.log("Trying to close port") + await port.close(); + } catch (error) { + console.error("Error encountered closing port:", error); + } + console.log("Disconnected from port") + onPortDisconnect() } } @@ -133,9 +184,10 @@ async function updateSerialSelect(ports) { select.appendChild(option) return; } + select.innerHTML = '' ports.forEach(port => { const option = buildPortOption(port) select.appendChild(option); }); - select.removeChild(select.firstElementChild); + console.log('ports updated') } \ No newline at end of file -- 2.38.4 From ed19c50a37fdec03637d8a89da0b75e91673fad6 Mon Sep 17 00:00:00 2001 From: Drew Bednar Date: Thu, 8 Aug 2024 21:33:02 -0400 Subject: [PATCH 3/3] Working disconnect --- README.md | 2 +- script.js | 68 ++++++++++++++++++++----------------------------------- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index df79f9f..b8deb42 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Web Serial Console -Serial console access in the browser! This project uses an [experimental Web Serial API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API) available, as of 08/06/2024, on Chrome 89+, Edge 89+, or Opera 75+. +Serial console access in the browser! This project uses an [experimental Web Serial API](https://wicg.github.io/serial/) available, as of 08/06/2024, on Chrome 89+, Edge 89+, or Opera 75+. This is a work in progress and a learning experiment. Feel free to file an issue if you encounter one. diff --git a/script.js b/script.js index bea8934..16c945e 100644 --- a/script.js +++ b/script.js @@ -35,18 +35,6 @@ clearButton.addEventListener('click', () => { } }); -function onPortConnect(){ - connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); - connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); - connectButton.textContent = 'Disconnect'; -} - -function onPortDisconnect(){ - connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); - connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); - connectButton.textContent = 'Connect'; -} - connectButton.addEventListener('click', async () => { const selectedPort = serialPorts[select.selectedIndex] const baudRate = Math.round(baud.value) @@ -64,6 +52,19 @@ refreshPorts.addEventListener('click', async () => { }); // Functions +function onPortConnect() { + connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.textContent = 'Disconnect'; +} + +function onPortDisconnect() { + connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); + connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); + connectButton.textContent = 'Connect'; +} + + function buildPortOption(port) { const option = document.createElement('option'); option.value = port; @@ -99,36 +100,14 @@ function scrollToBottom() { scrollableElement.scrollTop = scrollableElement.scrollHeight; } -// function onSerialConnect() { -// console.log("connected to port") -// connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); -// connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); -// connectButton.textContent = 'Disconnect'; -// isPortConnected = port; -// } - // Async Functions async function connectToSerialPort(port, baud) { - port.addEventListener("onconnect", () => { - console.log("connected to port") - connectButton.classList.remove('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); - connectButton.classList.add('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); - connectButton.textContent = 'Disconnect'; - isPortConnected = true; - }); - - port.addEventListener('ondisconnect', () => { - console.log("disconnect from port") - connectButton.classList.remove('bg-red-500', 'hover:bg-red-600', 'focus:ring-red-500'); - connectButton.classList.add('bg-emerald-500', 'hover:bg-emerald-600', 'focus:ring-emerald-500'); - connectButton.textContent = 'Connect'; - isPortConnected = false; - }); - - console.log("Opening port") await port.open({ baudRate: baud }); onPortConnect() + let buffer = '' + // The TextDecoderStream interface of the Encoding API converts a stream of text in a binary encoding, + // such as UTF-8 etc., to a stream of strings const textDecoder = new TextDecoderStream(); const readableStreamClosed = port.readable.pipeTo(textDecoder.writable); reader = textDecoder.readable.getReader(); @@ -137,7 +116,7 @@ async function connectToSerialPort(port, baud) { try { isPortConnected = true; while (isPortConnected) { - const { value, done } = await reader.read({signal}); + const { value, done } = await reader.read({ signal }); if (done) { break; } @@ -155,23 +134,25 @@ async function connectToSerialPort(port, baud) { } catch (error) { console.error('Error reading data from serial port:', error); } finally { - console.log("Calling abort on read") controller.abort(); - console.log("Calling releaseLock on reader") + reader.releaseLock(); try { - // Gracefully close the stream await textDecoder.readable.cancel(); } catch (error) { console.error("Error encountered in readableStreamClosed:", error); } + + try { + await readableStreamClosed; + } catch (error) { + } + try { - console.log("Trying to close port") await port.close(); } catch (error) { console.error("Error encountered closing port:", error); } - console.log("Disconnected from port") onPortDisconnect() } } @@ -189,5 +170,4 @@ async function updateSerialSelect(ports) { const option = buildPortOption(port) select.appendChild(option); }); - console.log('ports updated') } \ No newline at end of file -- 2.38.4