UNPKG

modbus-connect

Version:

Modbus RTU over Web Serial and Node.js SerialPort

74 lines (60 loc) 2.65 kB
// function-codes/write-single-coil.js const FUNCTION_CODE = 0x05; const COIL_ON = 0xFF00; const COIL_OFF = 0x0000; const PDU_SIZE = 5; const MIN_ADDRESS = 0; const MAX_ADDRESS = 0xFFFF; function validateCoilAddress(address) { if ((address | 0) !== address || address < MIN_ADDRESS || address > MAX_ADDRESS) { throw new RangeError(`Address must be ${MIN_ADDRESS}-${MAX_ADDRESS}, got ${address}`); } } function validateCoilValue(value) { // Быстрая проверка булевых значений и 1/0 if (value !== !!value && value !== (value | 0)) { throw new TypeError(`Value must be boolean or 0/1, got ${typeof value} ${value}`); } } function buildWriteSingleCoilRequest(address, value) { // Валидация параметров validateCoilAddress(address); validateCoilValue(value); // Создаем буфер и представление const buffer = new ArrayBuffer(PDU_SIZE); const view = new DataView(buffer); // Заполняем PDU view.setUint8(0, FUNCTION_CODE); view.setUint16(1, address, false); view.setUint16(3, value ? COIL_ON : COIL_OFF, false); return new Uint8Array(buffer); } function parseWriteSingleCoilResponse(pdu) { // Проверка типа и длины if (!(pdu instanceof Uint8Array)) { throw new TypeError(`PDU must be Uint8Array, got ${pdu?.constructor?.name || typeof pdu}`); } if (pdu.length !== PDU_SIZE) { throw new Error(`Invalid PDU length: expected ${PDU_SIZE}, got ${pdu.length}`); } if (pdu[0] !== FUNCTION_CODE) { throw new Error(`Invalid function code: expected 0x${FUNCTION_CODE.toString(16)}, got 0x${pdu[0].toString(16)}`); } // Используем оригинальный буфер без копирования const buffer = pdu.buffer || pdu; const byteOffset = pdu.byteOffset || 0; const view = new DataView(buffer, byteOffset, PDU_SIZE); const address = view.getUint16(1, false); const valueRaw = view.getUint16(3, false); // Проверка значения через switch (быстрее для 2 вариантов) switch (valueRaw) { case COIL_ON: return { address, value: true }; case COIL_OFF: return { address, value: false }; default: throw new Error(`Invalid coil value: expected 0x${COIL_ON.toString(16)} or 0x${COIL_OFF.toString(16)}, got 0x${valueRaw.toString(16)}`); } } module.exports = { buildWriteSingleCoilRequest, parseWriteSingleCoilResponse };