| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789 |
- // modbus.js - 优化版本
- let _globalSlaveAddress = 0x01; //全局初始从机地址
- let connected = false; // 连接状态
- let sharedHeartbeatInterval = null; // 心跳定时器变量
- let agreement = 'DEVICE_A'; //协议类型 默认为 DEVICE_A
- let taskInterval = 500; // 定时任务频率
- let timeStatus = true;
- import store from '@/store';
- // 先声明变量
- let ecUI, ecBLE;
- // #ifdef APP
- import _ecUI from '@/utils/ecUI.js'
- import _ecBLE from '@/utils/ecBLE/ecBLE.js'
- ecUI = _ecUI;
- ecBLE = _ecBLE;
- // #endif
- // #ifdef MP
- const _ecUI = require('@/utils/ecUI.js')
- const _ecBLE = require('@/utils/ecBLE/ecBLE.js')
- ecUI = _ecUI;
- ecBLE = _ecBLE;
- // #endif
- // 将 ecBLE 导出,供其他页面使用
- export { ecBLE, ecUI };
- // 获取连接状态
- export function getConnected() {
- return connected;
- }
- //设置协议类型
- export function setAgreement(type) {
- agreement = type;
- }
- export function setTime(value) {
- if (value === taskInterval && isHeartbeatRunning()){
- return;
- }
- taskInterval = value;
- stopHeartbeat();
- startHeartbeat();
- }
- export function setTimeStatus(value) {
- timeStatus = value;
- }
- export function initBLE() {
- // 监听连接状态变化
- ecBLE.onBLEConnectionStateChange((res) => {
- console.log(res);
- if (res.ok && !connected) {
- connected = true;
- console.log("连接成功");
- store.dispatch('ble/updateConnected', res.ok)
- ecBLE.stopBluetoothDevicesDiscovery();
- } else {
- store.dispatch('ble/updateConnected', false)
- connected = false;
- ecUI.hideLoading();
- this.$modal.showToast("请检查是否配置成功");
- }
- });
- // 接收数据
- ecBLE.onBLECharacteristicValueChange((str, strHex) => {
- try {
- console.log("数据来了");
- let data = strHex.replace(/[0-9a-fA-F]{2}/g, ' $&') ;
- const parsedData = readRegister(data)
- store.dispatch('ble/updateData', parsedData)
- } catch (error) {
- store.dispatch('ble/updateError', error)
- console.error('数据解析失败:', error);
- this.$modal.showToast("数据解析失败");
- }
- });
- }
- // Getter/Setter 管理全局从机地址
- export function setGlobalSlaveAddress(addr) {
- if (addr < 0 || addr > 247) {
- throw new RangeError('slaveAddress 必须在 0~247 之间');
- }
- _globalSlaveAddress = addr;
- }
- export function getGlobalSlaveAddress() {
- console.log(_globalSlaveAddress);
- return _globalSlaveAddress;
- }
- /**
- * 支持的 Modbus 类型
- */
- export const MODBUS_TYPES = {
- WRITE_ADDRESS: 'WRITE_ADDRESS',
- READ_REGISTER: 'READ_REGISTER',
- };
- /**
- * Modbus 协议帧配置
- */
- export const MODBUS_FRAME_CONFIG = {
- DEVICE_A: {
- WRITE_ADDRESS: { //写地址
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: 0x00,
- functionCode: 0x06,
- startAddress: 0x0017,
- value: null,
- },
- GET_ADDRESS: { //读取地址
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: 0xFF, // 从协议数据看是FF
- functionCode: 0x03, // 功能码03
- startAddress: 0x0001, // 起始地址0001
- value: "0x0046", // 读取0个寄存器(根据实际需求可调整)
- },
- TIMED_TASKS:{ //定时任务
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x03,
- startAddress: 0x0001,
- value: "0x0046",
- },
- RAIN:{ //雨
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0200",
- },
- SNOW:{ //雪
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0100",
- },
- WIND:{ //风
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0400",
- },
- FLATTEN:{ //放平
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0040",
- },
- STOP:{ //停止
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0080",
- },
- READ_MANUAL:{ //手动
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0010",
- },
- READ_AUTO:{ //自动
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0020",
- },
- READ_DOWN:{ //向东
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0018",
- },
- READ_UP:{ //向西
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0014",
- },
- READ_CANCEL:{ //取消
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0029,
- value: "0x0000",
- },
- READ_TIME:{ //校正时间
- type: MODBUS_TYPES.READ_REGISTER,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x10,
- startAddress: 0x002C,
- value: null,
- },
- READ_TEMPERATURE:{ //天文写入
- type: MODBUS_TYPES.READ_REGISTER,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x10,
- startAddress: 0x0032,
- value: null,
- },
- READ_LIMIT:{ //限位写入
- type: MODBUS_TYPES.READ_REGISTER,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x10,
- startAddress: 0x0040,
- value: null,
- },
- READ_INCLINATION:{ //坡度写入
- type: MODBUS_TYPES.READ_REGISTER,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x10,
- startAddress: 0x003C,
- value: null,
- },
- READ_FREQUENCY:{ //频点写入
- type: MODBUS_TYPES.READ_REGISTER,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x10,
- startAddress: 0x0019,
- value: null,
- },
- READ_DIRECTION:{ //电机方向 正转动
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0025,
- value: "0x0000",
- },
- READ_REVERSE:{ //电机方向 反转
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0025,
- value: "0x0001",
- },
- READ_RETURN:{ //夜返角度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0042,
- value: null,
- },
- READ_FLAT:{ //放平角度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0043,
- value: null,
- },
- READ_SPECIFY:{ //指定角度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0045,
- value: null,
- },
- READ_SNOW:{ //雪天角度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0044,
- value: null,
- },
- READ_WIND:{ //大风角度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0046,
- value: null,
- },
- READ_OVERCURRENT:{ //过流写入
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0026,
- value: null,
- },
- READ_TRACKING:{ //跟踪精度
- type: MODBUS_TYPES.WRITE_ADDRESS,
- slaveAddress: _globalSlaveAddress,
- functionCode: 0x06,
- startAddress: 0x0027,
- value: null,
- },
- },
- DEVICE_B: {
- },
- DEVICE_C: {
- },
- };
- /**
- * 写入操作
- */
- const TS = ['READ_TIME','READ_LIMIT','READ_INCLINATION','READ_FREQUENCY','READ_TEMPERATURE'];
- export function writeRegister(action, valueToWrite) {
- try{
- if (action !='TIMED_TASKS'){
- console.log("停止心跳--------");
- stopHeartbeat();
- }
- let value = valueToWrite;
- if (!TS.includes(action) && valueToWrite !== null && valueToWrite !== '' && valueToWrite !== undefined) {
- value = parseInt(valueToWrite, 10);
- }
- if (action =='WRITE_ADDRESS'){
- value = parseInt(valueToWrite, 10);
- setGlobalSlaveAddress(value);
- }
- const buffer = generateModbusFrame(agreement, action, value);
- const arrayBuffer = arrayBufferToHex(buffer);
- const writeBLECharacteristicValue = ecBLE.writeBLECharacteristicValue(arrayBuffer, true);
- return writeBLECharacteristicValue;
- }catch(exception){
- console.log("写入失败:", exception);
- }finally {
- if (action =='WRITE_ADDRESS'){
- setGlobalSlaveAddress(value);
- }else if (action !='TIMED_TASKS' && action !='GET_ADDRESS' && timeStatus){
- setTimeout(() => {
- if (getConnected() && timeStatus) {
- startHeartbeat();
- }
- }, 50);
- }
- }
- }
- /**
- * 读取寄存器
- */
- export function readRegister(buffer) {
- return parseBluetoothData(buffer);
- }
- //心跳函数
- export function heartbeat() {
- try {
- // 示例:发送一个读取寄存器的请求作为心跳
- writeRegister('TIMED_TASKS',null);
- } catch (error) {
- console.error('心跳请求失败:', error);
- // 可以在这里添加重连逻辑
- }
- }
- // 启动心跳定时器
- export function startHeartbeat() {
- if (!getConnected()) {
- return;
- }
- if (!isHeartbeatRunning()) {
- sharedHeartbeatInterval = setInterval(heartbeat, taskInterval);
- }
- }
- // 停止心跳定时器
- export function stopHeartbeat() {
- if (isHeartbeatRunning()) {
- clearInterval(sharedHeartbeatInterval);
- sharedHeartbeatInterval = null;
- }
- }
- // 检查心跳定时器是否正在运行
- export function isHeartbeatRunning() {
- return sharedHeartbeatInterval !== null;
- }
- /**
- * 参数校验函数
- */
- function validateParams({ slaveAddress, functionCode, startAddress, valueToWrite }) {
- if (slaveAddress < 0 || slaveAddress > 247) {
- throw new RangeError('slaveAddress 必须在 0~247 之间');
- }
- if (functionCode < 1 || functionCode > 255) {
- throw new RangeError('functionCode 必须在 1~255 之间');
- }
- if (startAddress < 0 || startAddress > 0xFFFF) {
- throw new RangeError('startAddress 必须在 0~65535 之间');
- }
- if (valueToWrite < 0 || valueToWrite > 0xFFFF) {
- throw new RangeError('valueToWrite 必须在 0~65535 之间');
- }
- }
- /**
- * 创建 Modbus RTU 请求帧(根据配置)
- * @param {string} protocol 设备协议类型(DEVICE_A / DEVICE_B / DEVICE_C)
- * @param {string} action 操作
- * @param {number} [valueToWrite=0] 写入值 (0~65535)
- * @returns {Buffer} Modbus RTU 请求帧
- */
- function generateModbusFrame(protocol, action, valueToWrite) {
- console.log(_globalSlaveAddress);
- const config = MODBUS_FRAME_CONFIG[protocol]?.[action];
- if (!config) {
- throw new Error(`不支持的协议或写入类型: ${protocol} - ${action}`);
- }
- let { type, slaveAddress, functionCode, startAddress, value } = config;
- if ((valueToWrite == NaN || valueToWrite == null) && config.value !== undefined && config.value !== null) {
- valueToWrite = config.value;
- }
- if (action !== 'WRITE_ADDRESS' && action !== "GET_ADDRESS"){
- slaveAddress = _globalSlaveAddress;
- }
- // validateParams({ slaveAddress, functionCode, startAddress, valueToWrite });
- let buffer;
- if (type === MODBUS_TYPES.READ_REGISTER) {
- // valueToWrite 应该包含日期数据
- const dateData = valueToWrite; // 应该是一个数组,包含年、月、日、时、分、秒
- let buffer1 = new Uint8Array(7 + dateData.length * 2); // 基础7字节 + 数据字节
- buffer1[0] = slaveAddress;
- buffer1[1] = functionCode;
- buffer1[2] = (startAddress >> 8) & 0xFF;
- buffer1[3] = startAddress & 0xFF;
- buffer1[4] = (dateData.length >> 8) & 0xFF; // 寄存器数量高字节
- buffer1[5] = dateData.length & 0xFF; // 寄存器数量低字节
- buffer1[6] = dateData.length * 2; // 字节数
- // 填充数据
- for (let i = 0; i < dateData.length; i++) {
- buffer1[7 + i*2] = (dateData[i] >> 8) & 0xFF; // 高字节
- buffer1[8 + i*2] = dateData[i] & 0xFF; // 低字节
- }
- const crc = calculateCRC(buffer1.subarray(0, 7 + dateData.length * 2));
- const finalBuffer = new Uint8Array(buffer1.length + 2);
- finalBuffer.set(buffer1);
- finalBuffer[buffer1.length] = crc[0];
- finalBuffer[buffer1.length + 1] = crc[1];
- buffer = finalBuffer;
- } else {
- buffer = new Uint8Array(6);
- buffer[0] = slaveAddress;
- buffer[1] = functionCode;
- buffer[2] = (startAddress >> 8) & 0xFF;
- buffer[3] = startAddress & 0xFF;
- buffer[4] = (valueToWrite >> 8) & 0xFF;
- buffer[5] = valueToWrite & 0xFF;
- const crc = calculateCRC(buffer);
- const finalBuffer = new Uint8Array(buffer.length + crc.length);
- finalBuffer.set(buffer);
- finalBuffer.set(crc, buffer.length);
- buffer = finalBuffer;
- }
- return buffer;
- }
- function calculateCRC(buffer) {
- let crc = 0xFFFF;
- for (let i = 0; i < buffer.length; i++) {
- const tableIndex = (crc ^ buffer[i]) & 0xFF;
- crc = (crc >> 8) ^ crcTable[tableIndex];
- }
- const crcBuffer = new Uint8Array(2);
- crcBuffer[0] = crc & 0xFF;
- crcBuffer[1] = (crc >> 8) & 0xFF;
- return crcBuffer;
- }
- // CRC 表只构建一次
- const crcTable = buildCRCTable();
- function buildCRCTable() {
- const table = new Uint16Array(256);
- for (let i = 0; i < 256; i++) {
- let crc = i;
- for (let j = 0; j < 8; j++) {
- if (crc & 0x0001) {
- crc = (crc >> 1) ^ 0xA001;
- } else {
- crc >>= 1;
- }
- }
- table[i] = crc;
- }
- return table;
- }
- /**
- * 将 ArrayBuffer 转为十六进制字符串
- */
- export function arrayBufferToHex(buffer, withSpaces = false) {
- const hexArray = [...new Uint8Array(buffer)]
- .map(b => b.toString(16).padStart(2, '0'));
- if (withSpaces) {
- return hexArray.join(' ').toUpperCase();
- } else {
- return hexArray.join('').toUpperCase();
- }
- }
- /**
- * 解析蓝牙数据
- */
- export function parseBluetoothData(hexString) {
- ecBLE.saveWriteDataToLocal("TX: " + hexString,"tx");
- if (!hexString || hexString.length < 6) {
- const error = new Error('蓝牙数据不完整');
- throw error;
- }
- // 移除所有空格并重新格式化为标准格式
- const cleanHexString = hexString.replace(/\s/g, '');
- if (cleanHexString.length < 6) {
- throw new Error('蓝牙数据不完整');
- }
- // 将连续的十六进制字符串转换为带空格的格式
- const formattedHexString = cleanHexString.match(/.{1,2}/g)?.join(' ') || cleanHexString;
- const byteStrings = formattedHexString.split(' ').filter(s => s.length > 0);
- console.log("字节字符串数组:", JSON.stringify(byteStrings));
- console.log("字节数组长度:", byteStrings.length);
- if (byteStrings.length < 10 ){ //其他操作执行成功
- // 其他操作执行成功
- return;
- }
- if (!byteStrings || byteStrings.length < 3) {
- throw new Error('蓝牙数据不完整');
- }
- const register = {
- device: '',
- function: '',
- registerNumber: '',
- Addres_23: '',
- Frequence_25: '',
- NetworkId_26: '',
- modAddre_27: '',
- MotorCurrent_30: '',
- MotorCurrent_35: '',
- Battery_32: '',
- Temperature_33: '',
- MotDrection_37: '',
- OverProtection_38: '',
- TrackingAccuracy_39: '',
- Message_40: '',
- WorkModle_41: '',
- TargetAngle_42: '',
- RealAngle_43: '',
- RealAngle_31: '',
- Year_44: '',
- Month_45: '',
- Day_46: '',
- Hour_47: '',
- Minute_48: '',
- Second_49: '',
- nowtime: '',
- Longitude_50: '',
- Latitude_51: '',
- TimeZone_52: '',
- EleAngle_53: '',
- Azimuth_54: '',
- width_60: '',
- inter_61: '',
- UpGrade_62: '',
- DownGrade_63: '',
- EasternLimit_64: '',
- WesternLimit_65: '',
- NightAngle_66: '',
- FlatAngle_67: '',
- SnowAngle_68: '',
- SpecifiedAngle_69: '',
- WindAngle_70: '',
- qAzimuth_54: '',
- qwidth_60: '',
- Interval_61: '',
- qEasternLimit_64: '',
- qWesternLimit_65: '',
- qNightAngle_66: '',
- qFlatAngle_67: '',
- qSnowAngle_68: '',
- qSpecifiedAngle_69: '',
- qWindAngle_70: '',
- qEleAngle_53: '',
- qTargetAngle_42: '',
- qRealAngle_43: '',
- qRealAngle_31: ''
- };
- register.device = parseInt(byteStrings[0], 16);
- register.function = parseInt(byteStrings[1], 16);
- register.registerNumber = parseInt(byteStrings[2], 16);
- const formattedOutput = [];
- for (let i = 3; i < byteStrings.length; i += 2) {
- const byte1 = parseInt(byteStrings[i], 16);
- const byte2 = i + 1 < byteStrings.length ? parseInt(byteStrings[i + 1], 16) : 0;
- const combined = ((byte1 << 8) | byte2).toString(16).padStart(4, '0');
- formattedOutput.push(combined.toUpperCase());
- }
- // 参照mainwindow.cpp的解析逻辑补全
- for (let i = 1; i < formattedOutput.length; i++) {
- const value = parseInt(formattedOutput[i], 16);
- const valueInt16 = (value > 0x7FFF) ? value - 0x10000 : value; // 转换为有符号16位整数
- if (i === 22) { // 地址写入
- register.Addres_23 = valueInt16.toString();
- } else if (i === 24) { // 频点[0-83]
- register.Frequence_25 = valueInt16.toString();
- } else if (i === 25) { // 网络ID[0-255]
- register.NetworkId_26 = valueInt16.toString();
- } else if (i === 26) { // 模块地址
- register.modAddre_27 = (parseInt(register.NetworkId_26, 10) * 256) + register.device;
- } else if (i === 29) { // 电机1电流1位小数(A)
- register.MotorCurrent_30 = valueInt16.toString();
- register.MotorCurrent_30 = insertDecimal(register.MotorCurrent_30, 1);
- } else if (i === 34) { // 电机2电流1位小数(A)
- register.MotorCurrent_35 = valueInt16.toString();
- register.MotorCurrent_35 = insertDecimal(register.MotorCurrent_35, 1);
- } else if (i === 31) { // 电池1位小数(V)
- register.Battery_32 = valueInt16.toString();
- register.Battery_32 = insertDecimal(register.Battery_32, 1);
- } else if (i === 32) { // 温度(度)
- register.Temperature_33 = valueInt16.toString();
- } else if (i === 35) { // 标定有效
- register.Demarcate_36 = valueInt16.toString();
- } else if (i === 36) { // 电机方向
- register.MotDrection_37 = valueInt16.toString();
- } else if (i === 37) { // 过流保护(A)
- register.OverProtection_38 = valueInt16.toString();
- } else if (i === 38) { // 跟踪精度
- register.TrackingAccuracy_39 = valueInt16.toString();
- } else if (i === 39) { // 十进制转二进制0111倾角+过流+限位
- register.Message_40 = valueInt16.toString(2); // 转二进制
- } else if (i === 40) { // 工作模式
- register.WorkModle_41 = valueInt16.toString(2); // 转二进制
- } else if (i === 41) { // 目标角度_两位小数
- register.TargetAngle_42 = valueInt16;
- register.qTargetAngle_42 = insertDecimal(register.TargetAngle_42.toString(), 2);
- } else if (i === 42) { // 实际角度1_两位小数
- register.RealAngle_43 = valueInt16;
- register.qRealAngle_43 = insertDecimal(register.RealAngle_43.toString(), 2);
- } else if (i === 30) { // 实际角度2_两位小数
- register.RealAngle_31 = valueInt16;
- register.qRealAngle_31 = insertDecimal(register.RealAngle_31.toString(), 2);
- } else if (i === 43) { // 年
- register.Year_44 = valueInt16.toString();
- } else if (i === 44) { // 月
- register.Month_45 = valueInt16.toString();
- } else if (i === 45) { // 日
- register.Day_46 = valueInt16.toString();
- } else if (i === 46) { // 时
- register.Hour_47 = valueInt16.toString();
- } else if (i === 47) { // 分
- register.Minute_48 = valueInt16.toString();
- } else if (i === 48) { // 秒
- register.Second_49 = valueInt16.toString();
- register.nowtime = `${register.Year_44}-${register.Month_45}-${register.Day_46} ${register.Hour_47.padStart(2, '0')}:${register.Minute_48.padStart(2, '0')}:${register.Second_49.padStart(2, '0')}`;
- } else if (i === 49) { // 太阳经度_两位小数
- register.Longitude_50 = valueInt16.toString();
- register.Longitude_50 = insertDecimal(register.Longitude_50, 2);
- } else if (i === 50) { // 太阳纬度_两位小数
- register.Latitude_51 = valueInt16.toString();
- register.Latitude_51 = insertDecimal(register.Latitude_51, 2);
- } else if (i === 51) { // 时区_两位小数800
- register.TimeZone_52 = valueInt16.toString();
- register.TimeZone_52 = insertDecimal(register.TimeZone_52, 2);
- } else if (i === 52) { // 太阳高度角_两位小数
- register.EleAngle_53 = valueInt16;
- register.qEleAngle_53 = insertDecimal(register.EleAngle_53.toString(), 2);
- } else if (i === 53) { // 太阳方位角_两位小数180调零
- register.Azimuth_54 = valueInt16;
- register.qAzimuth_54 = insertDecimal(register.Azimuth_54.toString(), 2);
- } else if (i === 59) { // 宽度_两位小数
- register.width_60 = valueInt16;
- register.qwidth_60 = insertDecimal(register.width_60.toString(), 2);
- } else if (i === 60) { // 间距_两位小数
- register.inter_61 = valueInt16;
- register.Interval_61 = insertDecimal(register.inter_61.toString(), 2);
- } else if (i === 61) { // 上坡度_两位小数
- register.UpGrade_62 = valueInt16.toString();
- register.UpGrade_62 = insertDecimal(register.UpGrade_62, 2);
- } else if (i === 62) { // 下坡度_两位小数
- register.DownGrade_63 = valueInt16.toString();
- register.DownGrade_63 = insertDecimal(register.DownGrade_63, 2);
- } else if (i === 63) { // 东限位
- register.EasternLimit_64 = valueInt16;
- register.qEasternLimit_64 = register.EasternLimit_64.toString();
- } else if (i === 64) { // 西限位
- register.WesternLimit_65 = valueInt16;
- register.qWesternLimit_65 = register.WesternLimit_65.toString();
- } else if (i === 65) { // 夜返角
- register.NightAngle_66 = valueInt16;
- register.qNightAngle_66 = register.NightAngle_66.toString();
- } else if (i === 66) { // 放平角度
- register.FlatAngle_67 = valueInt16;
- register.qFlatAngle_67 = register.FlatAngle_67.toString();
- } else if (i === 67) { // 雪天角度
- register.SnowAngle_68 = valueInt16;
- register.qSnowAngle_68 = register.SnowAngle_68.toString();
- } else if (i === 68) { // 指定角度
- register.SpecifiedAngle_69 = valueInt16;
- register.qSpecifiedAngle_69 = register.SpecifiedAngle_69.toString();
- } else if (i === 69) { // 大风角度
- register.WindAngle_70 = valueInt16;
- register.qWindAngle_70 = register.WindAngle_70.toString();
- }
- }
- console.log(JSON.stringify( register));
- return register;
- }
- /**
- * 在数字中插入小数点
- */
- export function insertDecimal(value, digits = 2) {
- // 处理空值或无效值
- if (value === null || value === undefined || value === '') {
- return (0).toFixed(digits);
- }
- // 确保是数字类型
- const numValue = Number(value);
- // 如果不是有效数字,返回默认值
- if (isNaN(numValue)) {
- return (0).toFixed(digits);
- }
- // 计算除数
- const divisor = Math.pow(10, digits);
- // 执行除法并格式化为指定小数位数
- return (numValue / divisor).toFixed(digits);
- }
- /**
- * 显示接收数据(格式化为 16 字节一行)
- */
- export function displayReceiveData(buffer) {
- const hexStr = HexToAscii(buffer);
- const lines = hexStr.split(' ');
- let str = '';
- for (let i = 0; i < lines.length; i++) {
- str += lines[i] + ' ';
- if ((i + 1) % 16 === 0) str += '\n';
- }
- return str;
- }
- /**
- * 将字节数组转为十六进制字符串
- */
- export function HexToAscii(buffer) {
- return [...new Uint8Array(buffer)]
- .map(b => b.toString(16).padStart(2, '0'))
- .join(' ')
- .trim();
- }
|