const { SerialPort } = require('serialport'); const config = require('../config/config'); const logger = require('../logger'); function createAstmSerialConnector(options = {}) { let port; let messageHandler = async () => {}; let errorHandler = (err) => logger.error({ err }, 'astm connector error'); const serialPath = options.port || options.comPort || config.connectors.astmSerialPath; const baudRate = Number(options.baudRate || config.connectors.astmSerialBaudRate); const dataBits = Number(options.dataBits || config.connectors.astmSerialDataBits); const stopBits = Number(options.stopBits || config.connectors.astmSerialStopBits); const parity = options.parity || config.connectors.astmSerialParity; const instrumentId = options.instrument_id || null; function processBufferedLines(state) { const lines = state.buffer.split(/\r?\n/); state.buffer = lines.pop() || ''; lines .map((line) => line.trim()) .filter(Boolean) .forEach((line) => { messageHandler({ payload: line, context: { connector: 'astm-serial', instrument_id: instrumentId, comPort: serialPath, baudRate, dataBits, stopBits, parity } }).catch(errorHandler); }); } return { name: () => 'astm-serial', type: () => 'astm-serial', async start() { const state = { buffer: '' }; port = new SerialPort({ path: serialPath, baudRate, dataBits, stopBits, parity, autoOpen: false }); port.on('data', (chunk) => { state.buffer += chunk.toString('utf8'); if (state.buffer.includes('\n')) { processBufferedLines(state); } }); port.on('error', (err) => errorHandler(err)); return new Promise((resolve, reject) => { port.open((err) => { if (err) { errorHandler(err); return reject(err); } logger.info({ instrument_id: instrumentId, comPort: serialPath, baudRate, dataBits, stopBits, parity }, 'astm serial connector opened'); resolve(); }); }); }, async stop() { if (!port) return; if (!port.isOpen) { port.removeAllListeners(); port = null; return; } return new Promise((resolve, reject) => { port.close((err) => { if (err) return reject(err); port.removeAllListeners(); port = null; resolve(); }); }); }, health() { return { status: port && port.isOpen ? 'up' : 'down', instrument_id: instrumentId, comPort: serialPath, baudRate }; }, onMessage(handler) { messageHandler = handler; }, onError(handler) { errorHandler = handler; } }; } module.exports = { createAstmSerialConnector };