modbus-connect
Version:
Modbus RTU over Web Serial and Node.js SerialPort
64 lines (52 loc) • 1.9 kB
JavaScript
// function-codes/read-coils.js
const { FUNCTION_CODES } = require('../constants/constants.js');
const { allocUint8Array, uint16ToBytesBE, isUint8Array } = require('../utils/utils.js');
/**
* Строит PDU-запрос для чтения дискретных выходов (coils)
* @param {number} startAddress - начальный адрес
* @param {number} quantity - количество битов (1–2000)
* @returns {Uint8Array}
*/
function buildReadCoilsRequest(startAddress, quantity) {
if (quantity < 1 || quantity > 2000) {
throw new RangeError('Quantity must be between 1 and 2000');
}
const pdu = allocUint8Array(5);
pdu[0] = FUNCTION_CODES.READ_COILS;
const addrBytes = uint16ToBytesBE(startAddress);
pdu[1] = addrBytes[0];
pdu[2] = addrBytes[1];
const qtyBytes = uint16ToBytesBE(quantity);
pdu[3] = qtyBytes[0];
pdu[4] = qtyBytes[1];
return pdu;
}
/**
* Разбирает PDU-ответ с дискретными выходами (coils)
* @param {Uint8Array} pdu
* @returns {boolean[]}
*/
function parseReadCoilsResponse(pdu) {
if (!isUint8Array(pdu)) {
throw new TypeError('PDU must be Uint8Array');
}
if (pdu[0] !== FUNCTION_CODES.READ_COILS) {
throw new Error(`Invalid function code: expected 0x01, got 0x${pdu[0].toString(16)}`);
}
const byteCount = pdu[1];
if (pdu.length !== byteCount + 2) {
throw new Error(`Invalid byte count: expected ${byteCount} bytes, got ${pdu.length - 2}`);
}
const bits = [];
for (let i = 0; i < byteCount; i++) {
const byte = pdu[2 + i];
for (let b = 0; b < 8; b++) {
bits.push((byte & (1 << b)) !== 0);
}
}
return bits;
}
module.exports = {
buildReadCoilsRequest,
parseReadCoilsResponse
}