modbus-connect
Version:
Modbus RTU over Web Serial and Node.js SerialPort
65 lines (54 loc) • 2.34 kB
JavaScript
// function-codes/report-slave-id.js
const FUNCTION_CODE = 0x11;
const MIN_RESPONSE_LENGTH = 4;
const HEADER_SIZE = 2;
const SLAVE_ID_OFFSET = 2;
const RUN_STATUS_OFFSET = 3;
const DATA_OFFSET = 4;
/**
* Строит PDU запроса Report Slave ID (0x11)
* @returns {Uint8Array}
*/
function buildReportSlaveIdRequest() {
// Используем ArrayBuffer + DataView для единообразия стиля
const buffer = new ArrayBuffer(1);
const view = new DataView(buffer);
view.setUint8(0, FUNCTION_CODE);
return new Uint8Array(buffer);
}
/**
* Разбирает PDU ответа на Report Slave ID
* @param {Uint8Array} pdu
* @returns {{ slaveId: number, isRunning: boolean, data: Uint8Array }}
*/
function parseReportSlaveIdResponse(pdu) {
if (!(pdu instanceof Uint8Array)) {
throw new TypeError('PDU must be Uint8Array');
}
const pduLength = pdu.length;
if (pduLength < MIN_RESPONSE_LENGTH) {
throw new Error(`PDU too short for Report Slave ID response: expected at least ${MIN_RESPONSE_LENGTH}, got ${pduLength}`);
}
if (pdu[0] !== FUNCTION_CODE) {
throw new Error(`Invalid function code: expected 0x${FUNCTION_CODE.toString(16)}, got 0x${pdu[0].toString(16)}`);
}
const byteCount = pdu[1];
const expectedLength = byteCount + HEADER_SIZE;
if (pduLength !== expectedLength) {
throw new Error(`Invalid byte count: expected ${expectedLength}, got ${pduLength}`);
}
// Используем оригинальный буфер без копирования данных
const buffer = pdu.buffer || pdu;
const byteOffset = pdu.byteOffset || 0;
return {
slaveId: pdu[SLAVE_ID_OFFSET], // Прямой доступ к Uint8Array быстрее, чем DataView для 8-битных значений
isRunning: pdu[RUN_STATUS_OFFSET] === 0xFF,
data: byteCount > 2
? new Uint8Array(buffer, byteOffset + DATA_OFFSET, byteCount - 2)
: new Uint8Array(0) // Возвращаем пустой массив если нет данных
};
}
module.exports = {
buildReportSlaveIdRequest: buildReportSlaveIdRequest,
parseReportSlaveIdResponse: parseReportSlaveIdResponse
};