Solución:
Usando API de serie web. Estoy usando esto para leer SOLAMENTE los datos de mi báscula con interfaz serial RS232
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Serial</title>
</head>
<body>
<div>
<button>Connect with Serial Device</button>
</div>
<button>Get serial messages</button>
<div>
<div></div>
</div>
<script>
"use strict";
class SerialScaleController {
constructor() {
this.encoder = new TextEncoder();
this.decoder = new TextDecoder();
}
async init() {
if ('serial' in navigator) {
try {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
this.reader = port.readable.getReader();
let signals = await port.getSignals();
console.log(signals);
}
catch (err) {
console.error('There was an error opening the serial port:', err);
}
}
else {
console.error('Web serial doesn't seem to be enabled in your browser. Try enabling it by visiting:');
console.error('chrome://flags/#enable-experimental-web-platform-features');
console.error('opera://flags/#enable-experimental-web-platform-features');
console.error('edge://flags/#enable-experimental-web-platform-features');
}
}
async read() {
try {
const readerData = await this.reader.read();
console.log(readerData)
return this.decoder.decode(readerData.value);
}
catch (err) {
const errorMessage = `error reading data: ${err}`;
console.error(errorMessage);
return errorMessage;
}
}
}
const serialScaleController = new SerialScaleController();
const connect = document.getElementById('connect-to-serial');
const getSerialMessages = document.getElementById('get-serial-messages');
connect.addEventListener('pointerdown', () => {
serialScaleController.init();
});
getSerialMessages.addEventListener('pointerdown', async () => {
getSerialMessage();
});
async function getSerialMessage() {
document.querySelector("#serial-messages-container .message").innerText += await serialScaleController.read()
}
</script>
</body>
</html>
Consulte esta demostración y este código para ver un ejemplo más descriptivo.
Es posible que deba activar la función API serial en su navegador. A continuación se muestra la cita de las referencias.
Como puede imaginar, esta API solo es compatible con los navegadores de escritorio modernos basados en Chromium en este momento (abril de 2020), pero es de esperar que el soporte mejore en un futuro próximo. En este momento, debe habilitar las funciones de la plataforma web experimental de su navegador, simplemente copie y pegue la URL correcta:
chrome://flags/#enable-experimental-web-platform-features
opera://flags/#enable-experimental-web-platform-features
edge://flags/#enable-experimental-web-platform-features
Referencias:
https://dev.to/unjavascripter/the-amazing-powers-of-the-web-web-serial-api-3ilc
https://github.com/UnJavaScripter/web-serial-example
Bueno, una forma de hacerlo es desarrollar una aplicación de Chrome. Puede utilizar la API chrome.serial.
https://developer.chrome.com/apps/serial
Código de muestra,
En su manifest.json,
{
"name": "Serial Sample",
"description": "Read/Write from/to serial port.",
"version": "1.0",
"manifest_version": 2,
"permissions": ["serial"],
"app": {
"background": {
"scripts": ["background.js"]
}
}
}
En su background.js,
const DEVICE_PATH = 'COM1';
const serial = chrome.serial;
var dataRecieved="";
/* Interprets an ArrayBuffer as UTF-8 encoded string data. */
var ab2str = function(buf) {
var bufView = new Uint8Array(buf);
var encodedString = String.fromCharCode.apply(null, bufView);
return decodeURIComponent(escape(encodedString));
};
/* Converts a string to UTF-8 encoding in a Uint8Array; returns the array buffer. */
var str2ab = function(str) {
var encodedString = unescape(encodeURIComponent(str));
var bytes = new Uint8Array(encodedString.length);
for (var i = 0; i < encodedString.length; ++i) {
bytes[i] = encodedString.charCodeAt(i);
}
return bytes.buffer;
};
var SerialConnection = function() {
this.connectionId = -1;
this.lineBuffer = "";
this.boundOnReceive = this.onReceive.bind(this);
this.boundOnReceiveError = this.onReceiveError.bind(this);
this.onConnect = new chrome.Event();
this.onReadLine = new chrome.Event();
this.onError = new chrome.Event();
};
SerialConnection.prototype.onConnectComplete = function(connectionInfo) {
if (!connectionInfo) {
log("Connection failed.");
return;
}
this.connectionId = connectionInfo.connectionId;
chrome.serial.onReceive.addListener(this.boundOnReceive);
chrome.serial.onReceiveError.addListener(this.boundOnReceiveError);
this.onConnect.dispatch();
};
SerialConnection.prototype.onReceive = function(receiveInfo) {
if (receiveInfo.connectionId !== this.connectionId) {
return;
}
this.lineBuffer += ab2str(receiveInfo.data);
var index;
while ((index = this.lineBuffer.indexOf('n')) >= 0) {
var line = this.lineBuffer.substr(0, index + 1);
this.onReadLine.dispatch(line);
this.lineBuffer = this.lineBuffer.substr(index + 1);
}
};
SerialConnection.prototype.onReceiveError = function(errorInfo) {
if (errorInfo.connectionId === this.connectionId) {
this.onError.dispatch(errorInfo.error);
}
};
SerialConnection.prototype.connect = function(path) {
serial.connect(path, this.onConnectComplete.bind(this))
};
SerialConnection.prototype.send = function(msg) {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
serial.send(this.connectionId, str2ab(msg), function() {});
};
SerialConnection.prototype.disconnect = function() {
if (this.connectionId < 0) {
throw 'Invalid connection';
}
serial.disconnect(this.connectionId, function() {});
};
var connection = new SerialConnection();
connection.onConnect.addListener(function() {
//console.log('connected to: ' + DEVICE_PATH);
});
connection.onReadLine.addListener(function (line) {
//Serial port data recieve event.
dataRecieved = dataRecieved +line;
});
connection.connect(DEVICE_PATH);
Una vez que crea la aplicación Chrome para comunicarse con el puerto serie, lo siguiente es permitir que su página web externa se comunique con la aplicación Chrome usando JavaScript.
Para esto en su archivo manifest.json agregue,
"externally_connectable": {
"matches": ["*://*.example.com/*"]
}
Esto permitirá que la página web externa de su dominio example.com se comunique con su aplicación de Chrome.
En su página web,
// The ID of the extension we want to talk to.
var editorExtensionId = "nboladondmajlaalmcdupihoilpcketyl";
// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId,
{ data: "data to pass to the chrome app" },
function (response)
{
alert(response);
});
En tu aplicación de Chrome,
chrome.runtime.onMessageExternal.addListener(
function (request, sender, sendResponse) {
sendResponse("Send serial port data to the web page");
});
https://developer.chrome.com/apps/messaging