modbus-connect
Version:
Modbus RTU over Web Serial and Node.js SerialPort
66 lines (58 loc) • 2.23 kB
JavaScript
// function-codes/SGM130/get-controller-time.js
const FUNCTION_CODE = 0x58; // Уточненный код функции GET_CONTROLLER_TIME
const EXPECTED_RESPONSE_SIZE = 10;
const DATA_OFFSET = 3;
// Смещения для полей времени в ответе
const TIME_FIELDS_OFFSET = {
SECONDS: 0,
MINUTES: 1,
HOURS: 2,
DAY: 3,
MONTH: 4,
YEAR_LOW: 5,
YEAR_HIGH: 6
};
/**
* Формирует PDU-запрос для получения текущего времени контроллера.
* @returns {Uint8Array}
*/
function buildGetControllerTimeRequest() {
const request = new Uint8Array(1);
request[0] = FUNCTION_CODE;
return request;
}
/**
* Разбирает PDU-ответ от контроллера с текущим временем.
* @param {Uint8Array} pdu
* @returns {{
* seconds: number,
* minutes: number,
* hours: number,
* day: number,
* month: number,
* year: number
* }}
* @throws {Error} При неверном формате ответа
*/
function parseGetControllerTimeResponse(pdu) {
if (!(pdu instanceof Uint8Array)) {
throw new TypeError('PDU must be Uint8Array');
}
if (pdu.length !== EXPECTED_RESPONSE_SIZE || pdu[0] !== FUNCTION_CODE) {
throw new Error(`Invalid response: expected 10 bytes starting with 0x${FUNCTION_CODE.toString(16)}, got ${pdu.length} bytes starting with 0x${pdu[0]?.toString(16) || 'null'}`);
}
// Используем DataView для более эффективного доступа к данным
const view = new DataView(pdu.buffer, pdu.byteOffset + DATA_OFFSET);
return {
seconds: view.getUint8(TIME_FIELDS_OFFSET.SECONDS),
minutes: view.getUint8(TIME_FIELDS_OFFSET.MINUTES),
hours: view.getUint8(TIME_FIELDS_OFFSET.HOURS),
day: view.getUint8(TIME_FIELDS_OFFSET.DAY),
month: view.getUint8(TIME_FIELDS_OFFSET.MONTH),
year: view.getUint8(TIME_FIELDS_OFFSET.YEAR_LOW) | (view.getUint8(TIME_FIELDS_OFFSET.YEAR_HIGH) << 8)
};
}
module.exports = {
buildGetControllerTimeRequest,
parseGetControllerTimeResponse
};