modbus-connect
Version:
Modbus RTU over Web Serial and Node.js SerialPort
63 lines (50 loc) • 1.95 kB
JavaScript
// function-codes/write-multiple-coils.js
const { FUNCTION_CODES } = require('../constants/constants.js');
const { allocUint8Array, uint16ToBytesBE, isUint8Array, bytesToUint16BE } = require('../utils/utils.js');
/**
* @param {number} startAddress - адрес первой катушки
* @param {boolean[]} values - массив значений катушек (true/false)
* @returns {Uint8Array}
*/
function buildWriteMultipleCoilsRequest(startAddress, values) {
if (!Array.isArray(values) || values.length < 1 || values.length > 0x07B0) {
throw new RangeError('Values must be an array of 1 to 1968 booleans');
}
const byteCount = Math.ceil(values.length / 8);
const pdu = allocUint8Array(6 + byteCount);
pdu[0] = FUNCTION_CODES.WRITE_MULTIPLE_COILS;
const addrBytes = uint16ToBytesBE(startAddress);
pdu[1] = addrBytes[0];
pdu[2] = addrBytes[1];
const qtyBytes = uint16ToBytesBE(values.length);
pdu[3] = qtyBytes[0];
pdu[4] = qtyBytes[1];
pdu[5] = byteCount;
for (let i = 0; i < values.length; i++) {
const byteIndex = Math.floor(i / 8);
const bitIndex = i % 8;
if (values[i]) {
pdu[6 + byteIndex] |= 1 << bitIndex;
}
}
return pdu;
}
/**
* @param {Uint8Array} pdu
* @returns {{ startAddress: number, quantity: number }}
*/
function parseWriteMultipleCoilsResponse(pdu) {
if (!isUint8Array(pdu)) {
throw new TypeError('PDU must be Uint8Array');
}
if (pdu[0] !== FUNCTION_CODES.WRITE_MULTIPLE_COILS) {
throw new Error(`Invalid function code: expected 0x0F, got 0x${pdu[0].toString(16)}`);
}
const startAddress = bytesToUint16BE(pdu, 1);
const quantity = bytesToUint16BE(pdu, 3);
return { startAddress, quantity };
}
module.exports = {
buildWriteMultipleCoilsRequest,
parseWriteMultipleCoilsResponse
}