@jiabaida/tools 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/cjs/core/OtaUpgrade.js +1 -1
- package/dist/cjs/core/Queue.js +1 -0
- package/dist/cjs/core/mqttServer.js +1 -1
- package/dist/cjs/core/tcpServer.js +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BaseParamProtocol.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/esm/core/OtaUpgrade.js +1 -1
- package/dist/esm/core/Queue.js +1 -0
- package/dist/esm/core/mqttServer.js +1 -1
- package/dist/esm/core/tcpServer.js +1 -0
- package/dist/esm/index.js +1 -1
- package/package.json +1 -1
- package/src/core/BleCmdAnalysis/BaseParamProtocol.js +71 -12
- package/src/core/BleCmdAnalysis/BleCmdDD.js +72 -13
- package/src/core/BleCmdAnalysis/readAndSetParam.js +97 -8
- package/src/core/OtaUpgrade.js +8 -2
- package/src/core/Queue.js +34 -0
- package/src/core/mqttServer.js +20 -1
- package/src/core/tcpServer.js +303 -0
- package/src/index.js +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { decimalToHex, decimalToTwoByteHexArray } from '../BleDataProcess.js';
|
|
2
|
-
import { enterFactory, existFactory, getDDA5FAAsync, getDDA5OldAsync, readExistFactory, setDDA5FAAsync, setDDA5OldAsync } from './BleCmdDD.js';
|
|
2
|
+
import { enterFactory, existFactory, getDD5AE1Async, getDD5AFBAsync, getDDA5FAAsync, getDDA5OldAsync, readExistFactory, resolveBaseDD, setDDA5FAAsync, setDDA5OldAsync } from './BleCmdDD.js';
|
|
3
3
|
|
|
4
4
|
// #region 发指令读取参数
|
|
5
5
|
/**
|
|
@@ -89,10 +89,12 @@ export const getSysParamCmd = async (chipType, deviceId, paramInfo, needFactoryM
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
// #region 系统写参数处理
|
|
92
|
+
// #region 系统写参数处理 判断wifi或蓝牙
|
|
93
93
|
/**
|
|
94
94
|
* @param {*} chipType 芯片类型
|
|
95
95
|
* @param {*} deviceId 设备deviceId
|
|
96
|
+
* @param {*} macAddr 设备macAddr
|
|
97
|
+
* @param {*} blueConnect 是否通过蓝牙连接 默认true
|
|
96
98
|
* @param {Array|Object} paramInfoArray 包含多个参数信息的数组或单个参数信息对象
|
|
97
99
|
* @param {*} paramInfoArray[].newValue 新设置的参数输入值十进制值
|
|
98
100
|
* @param {*} paramInfoArray[].paramValue 新设置的参数值十进制值 部分参数输入的值需单独处理
|
|
@@ -102,7 +104,7 @@ export const getSysParamCmd = async (chipType, deviceId, paramInfo, needFactoryM
|
|
|
102
104
|
* @param {*} paramInfoArray[].divisor 缩放系数(十进制)如 10
|
|
103
105
|
* @param {*} paramInfoArray[].isTemp 是否是温度参数
|
|
104
106
|
*/
|
|
105
|
-
export const setSysParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
107
|
+
export const setSysParamCmd = async (chipType, deviceId, paramInfoArray, macAddr, blueConnect = true) => {
|
|
106
108
|
try {
|
|
107
109
|
console.log('paramInfoArray: ', paramInfoArray);
|
|
108
110
|
|
|
@@ -113,13 +115,18 @@ export const setSysParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
|
113
115
|
const paramObjs = [];
|
|
114
116
|
|
|
115
117
|
for (const paramInfo of paramsToProcess) {
|
|
116
|
-
|
|
118
|
+
// 根据系数处理参数值
|
|
119
|
+
let value = Number(paramInfo?.paramValue || paramInfo.newValue) / Number(paramInfo?.divisor || 1);
|
|
117
120
|
console.log('value: ', value);
|
|
118
|
-
if (paramInfo.isTemp) {
|
|
121
|
+
if (paramInfo.isTemp && blueConnect) {
|
|
119
122
|
value = 2731 + (Number(paramInfo.newValue) * 10)
|
|
120
123
|
}
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
value = Math.round(value);
|
|
125
|
+
let valuesHexs = [];
|
|
126
|
+
if(blueConnect) {
|
|
127
|
+
valuesHexs = decimalToTwoByteHexArray(value);
|
|
128
|
+
console.log('valuesHexs: ', valuesHexs);
|
|
129
|
+
}
|
|
123
130
|
|
|
124
131
|
// 将处理后的参数对象添加到数组中
|
|
125
132
|
paramObjs.push({
|
|
@@ -127,11 +134,14 @@ export const setSysParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
|
127
134
|
length: paramInfo.paramLength / 2,
|
|
128
135
|
values: valuesHexs,
|
|
129
136
|
oldAddress: paramInfo.oldParamNo,
|
|
137
|
+
newValue: value,
|
|
130
138
|
});
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
// 一次性将所有参数对象数组传递给setParamCmd函数
|
|
142
|
+
console.log("chipType: 芯片", chipType);
|
|
134
143
|
await setParamCmd(chipType, deviceId, paramObjs);
|
|
144
|
+
|
|
135
145
|
} catch (error) {
|
|
136
146
|
console.error('error: 写系统参数报错 setSysParamCmd', error);
|
|
137
147
|
throw error
|
|
@@ -143,6 +153,7 @@ export const setSysParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
|
143
153
|
* 发指令设置参数
|
|
144
154
|
* @param {*} chipType 芯片类型
|
|
145
155
|
* @param {*} deviceId 设备deviceId
|
|
156
|
+
* @param {*} macAddr 设备macAddr
|
|
146
157
|
* @param {Array} paramInfoArray 参数信息数组 或单个对象
|
|
147
158
|
* @param {*} paramInfoArray[].address 新协议开始写入地址(十进制)如 31
|
|
148
159
|
* @param {*} paramInfoArray[].length 新协议写参数内容长度(写几个)(十进制)如 1
|
|
@@ -150,7 +161,7 @@ export const setSysParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
|
150
161
|
* @param {*} paramInfoArray[].oldAddress 旧协议写入地址 默认一个(十六进制字符串)如 '0x1f'
|
|
151
162
|
* @returns {Promise<Array>} 包含所有参数设置结果的数组
|
|
152
163
|
*/
|
|
153
|
-
export const setParamCmd = (chipType, deviceId, paramInfoArray) => {
|
|
164
|
+
export const setParamCmd = async (chipType, deviceId, paramInfoArray) => {
|
|
154
165
|
console.log("chipType: 芯片", chipType);
|
|
155
166
|
|
|
156
167
|
// 确保paramInfoArray是数组
|
|
@@ -212,6 +223,84 @@ export const setParamCmd = (chipType, deviceId, paramInfoArray) => {
|
|
|
212
223
|
});
|
|
213
224
|
}
|
|
214
225
|
|
|
226
|
+
/** 控制开关
|
|
227
|
+
* @param {*} deviceId
|
|
228
|
+
* @param {*} typeCmd 0x00 - 放电MOS 0x01 - 充电MOS
|
|
229
|
+
* @param {*} currentSwitch 当前修改开关状态 true - 打开 false - 关闭
|
|
230
|
+
* @param {*} anotherSwitch 另一个开关状态
|
|
231
|
+
* @returns 指令结果 Ooj.status: 00 - 成功 81/84 不支持 82/83 失败
|
|
232
|
+
*/
|
|
233
|
+
export const controlSwitch = async (deviceId, typeCmd, currentSwitch, anotherSwitch) => {
|
|
234
|
+
//充放电开关
|
|
235
|
+
const hex = await getDD5AFBAsync(
|
|
236
|
+
deviceId,
|
|
237
|
+
typeCmd,
|
|
238
|
+
currentSwitch ? "0x00" : "0x01",
|
|
239
|
+
);
|
|
240
|
+
const mosRes = resolveBaseDD(hex);
|
|
241
|
+
console.log("hex: ", hex);
|
|
242
|
+
let dataRes = mosRes
|
|
243
|
+
//FB指令控制mos失败或无响应,发送E1指令
|
|
244
|
+
if (!mosRes || mosRes?.status != '00') {
|
|
245
|
+
const cmd = getE1Cmd(typeCmd, currentSwitch, anotherSwitch);
|
|
246
|
+
const e1hex = await getDD5AE1Async(
|
|
247
|
+
deviceId,
|
|
248
|
+
cmd
|
|
249
|
+
);
|
|
250
|
+
dataRes = resolveBaseDD(e1hex);
|
|
251
|
+
}
|
|
252
|
+
return dataRes
|
|
253
|
+
}
|
|
254
|
+
/** 计算E1指令
|
|
255
|
+
* @param {*} typeCmd 0x00 - 放电MOS 0x01 - 充电MOS
|
|
256
|
+
* @param {*} currentSwitch 当前修改开关状态 true - 打开 false - 关闭
|
|
257
|
+
* @param {*} anotherSwitch 另一个开关状态 true - 打开 false - 关闭
|
|
258
|
+
* @returns 0x00 - 充电MOS打开 放电MOS打开
|
|
259
|
+
* 0x01 - 充电MOS关闭 放电MOS打开
|
|
260
|
+
* 0x02 - 充电MOS打开 放电MOS关闭
|
|
261
|
+
* 0x03 - 充电MOS关闭 放电MOS关闭
|
|
262
|
+
*/
|
|
263
|
+
export const getE1Cmd = (typeCmd, currentSwitch, anotherSwitch) => {
|
|
264
|
+
let cmd = '0x00'
|
|
265
|
+
// 根据E1指令码定义计算:
|
|
266
|
+
// 0x00 - 充电MOS打开 放电MOS打开
|
|
267
|
+
// 0x01 - 充电MOS关闭 放电MOS打开
|
|
268
|
+
// 0x02 - 充电MOS打开 放电MOS关闭
|
|
269
|
+
// 0x03 - 充电MOS关闭 放电MOS关闭
|
|
270
|
+
if (typeCmd === '0x00') {
|
|
271
|
+
// 当前是放电操作
|
|
272
|
+
if (currentSwitch && anotherSwitch) {
|
|
273
|
+
// 放电MOS打开,充电MOS打开
|
|
274
|
+
cmd = '0x00'
|
|
275
|
+
} else if (currentSwitch && !anotherSwitch) {
|
|
276
|
+
// 放电MOS打开,充电MOS关闭
|
|
277
|
+
cmd = '0x01'
|
|
278
|
+
} else if (!currentSwitch && anotherSwitch) {
|
|
279
|
+
// 放电MOS关闭,充电MOS打开
|
|
280
|
+
cmd = '0x02'
|
|
281
|
+
} else {
|
|
282
|
+
// 放电MOS关闭,充电MOS关闭
|
|
283
|
+
cmd = '0x03'
|
|
284
|
+
}
|
|
285
|
+
} else if (typeCmd === '0x01') {
|
|
286
|
+
// 当前是充电操作
|
|
287
|
+
if (currentSwitch && anotherSwitch) {
|
|
288
|
+
// 充电MOS打开,放电MOS打开
|
|
289
|
+
cmd = '0x00'
|
|
290
|
+
} else if (!currentSwitch && anotherSwitch) {
|
|
291
|
+
// 充电MOS关闭,放电MOS打开
|
|
292
|
+
cmd = '0x01'
|
|
293
|
+
} else if (currentSwitch && !anotherSwitch) {
|
|
294
|
+
// 充电MOS打开,放电MOS关闭
|
|
295
|
+
cmd = '0x02'
|
|
296
|
+
} else {
|
|
297
|
+
// 充电MOS关闭,放电MOS关闭
|
|
298
|
+
cmd = '0x03'
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return cmd
|
|
302
|
+
}
|
|
303
|
+
|
|
215
304
|
// #region 写入标称容量
|
|
216
305
|
/**写入标称容量 同步写入满充及循环
|
|
217
306
|
* @param {*} chipType 芯片类型
|
package/src/core/OtaUpgrade.js
CHANGED
|
@@ -184,7 +184,11 @@ export class OTAUpgrade {
|
|
|
184
184
|
...opt,
|
|
185
185
|
fail: async () => {
|
|
186
186
|
await this.sleep(this.delay * 2);
|
|
187
|
-
uni.writeBLECharacteristicValue({
|
|
187
|
+
uni.writeBLECharacteristicValue({
|
|
188
|
+
...opt, fail: () => {
|
|
189
|
+
console.error('写入失败: ', pkg);
|
|
190
|
+
this.fail('写入失败');
|
|
191
|
+
} });
|
|
188
192
|
},
|
|
189
193
|
});
|
|
190
194
|
},
|
|
@@ -317,16 +321,18 @@ export class OTAUpgrade {
|
|
|
317
321
|
}
|
|
318
322
|
}
|
|
319
323
|
|
|
320
|
-
transferFirmwareFile() {
|
|
324
|
+
async transferFirmwareFile() {
|
|
321
325
|
let nextTime = this.finishedTimes + 1;
|
|
322
326
|
const timeFor51 = nextTime > this.totalTimes;
|
|
323
327
|
if (timeFor51) {
|
|
324
328
|
const pkg = [0x00];
|
|
329
|
+
await BLE.sendDelay(20);
|
|
325
330
|
BLE.transferFirmwareFileCmd(this.deviceId, pkg, true, this.fail.bind(this));
|
|
326
331
|
console.log('[OTA]', '=== Send 51 ===', this.finishedTimes, this.totalTimes, pkg);
|
|
327
332
|
} else {
|
|
328
333
|
const pkg = this.fileHexArray.slice(this.finishedTimes * max, nextTime * max);
|
|
329
334
|
const index = Transfer.decimalToTwoByteHexArray(this.finishedTimes);
|
|
335
|
+
await BLE.sendDelay(20);
|
|
330
336
|
BLE.transferFirmwareFileCmd(this.deviceId, index.concat(pkg), false, this.fail.bind(this));
|
|
331
337
|
console.log('[OTA]', `S50-${this.finishedTimes}/${this.totalTimes}`);
|
|
332
338
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Queue {
|
|
2
|
+
constructor() {
|
|
3
|
+
this._items = [];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
enqueue(item) {
|
|
7
|
+
this._items.push(item);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
dequeue() {
|
|
11
|
+
return this._items.shift();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
head() {
|
|
15
|
+
return this._items[0];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
tail() {
|
|
19
|
+
return this._items[this._items.length - 1];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
isEmpty() {
|
|
23
|
+
return !this._items.length;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
size() {
|
|
27
|
+
return this._items.length;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
clear() {
|
|
31
|
+
this._items = [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export default Queue
|
package/src/core/mqttServer.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Transfer } from './Transfer.js';
|
|
|
9
9
|
|
|
10
10
|
// 新的MQTT服务类
|
|
11
11
|
export class MqttServer {
|
|
12
|
-
constructor({ mqttClient = {}, MQTT_HOST = 'wxs://mqtt.jiabaida.com/mqtt', DELAY_TIME = 300, networkModelUrl = 'https://cloud.jiabaida.com/bluetooth/server/device/networkModel', request }) {
|
|
12
|
+
constructor({ mqttClient = {}, MQTT_HOST = 'wxs://mqtt.jiabaida.com/mqtt', DELAY_TIME = 300, networkModelUrl = 'https://cloud.jiabaida.com/bluetooth/server/device/networkModel', request, store = null }) {
|
|
13
13
|
this.timer = null;
|
|
14
14
|
this.productKey = 'bms_wifi';
|
|
15
15
|
this.is0f = false;
|
|
@@ -23,6 +23,7 @@ export class MqttServer {
|
|
|
23
23
|
this.DELAY_TIME = DELAY_TIME;
|
|
24
24
|
this.networkModelUrl = networkModelUrl;
|
|
25
25
|
this.request = request; // 必须传入的http请求方法
|
|
26
|
+
this.$store = store;
|
|
26
27
|
// ...existing code...
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -88,6 +89,7 @@ export class MqttServer {
|
|
|
88
89
|
|
|
89
90
|
storeMqttClient(client) {
|
|
90
91
|
this.mqttClient[`${client.options.deviceId}_mqtt`] = client;
|
|
92
|
+
this.$store?.commit('setMqttClient', this.mqttClient);
|
|
91
93
|
console.log('存储的 MQTT 客户端:', this.mqttClient);
|
|
92
94
|
}
|
|
93
95
|
|
|
@@ -151,6 +153,8 @@ export class MqttServer {
|
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
|
|
157
|
+
|
|
154
158
|
async processMessageAsync(client, message) {
|
|
155
159
|
const msg = JSON.parse(message);
|
|
156
160
|
this.callbackId = msg.callbackId;
|
|
@@ -212,6 +216,7 @@ export class MqttServer {
|
|
|
212
216
|
if (isLast) {
|
|
213
217
|
await sleep(300);
|
|
214
218
|
this.mqttPublish = false;
|
|
219
|
+
this.$store?.commit('setMqttPublish', false);
|
|
215
220
|
uni.removeStorageSync && uni.removeStorageSync(`${deviceId}_mqttPublish`);
|
|
216
221
|
}
|
|
217
222
|
} catch (error) {
|
|
@@ -219,10 +224,21 @@ export class MqttServer {
|
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
|
|
227
|
+
closeMqttByDeviceId(deviceId) {
|
|
228
|
+
const client = this.mqttClient[`${deviceId}_mqtt`];
|
|
229
|
+
if (client) {
|
|
230
|
+
client.end(() => {
|
|
231
|
+
this.mqttClient[`${deviceId}_mqtt`] = null;
|
|
232
|
+
console.log(`MQTT 连接已关闭,设备ID: ${deviceId}`);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
222
237
|
handleMqttClose(client, res) {
|
|
223
238
|
console.log('MQTT 连接关闭', res, client);
|
|
224
239
|
client.end(() => {
|
|
225
240
|
this.mqttClient[`${client.options.deviceId}_mqtt`] = null;
|
|
241
|
+
this.$store?.commit('setMqttClient', this.mqttClient);
|
|
226
242
|
});
|
|
227
243
|
}
|
|
228
244
|
|
|
@@ -243,6 +259,7 @@ export class MqttServer {
|
|
|
243
259
|
if (this.publishObj.isLast) {
|
|
244
260
|
await sleep(300);
|
|
245
261
|
this.mqttPublish = false;
|
|
262
|
+
this.$store?.commit('setMqttPublish', false);
|
|
246
263
|
uni.removeStorageSync && uni.removeStorageSync(`${this.publishObj.deviceId}_mqttPublish`);
|
|
247
264
|
}
|
|
248
265
|
}
|
|
@@ -266,6 +283,7 @@ export class MqttServer {
|
|
|
266
283
|
async writePublishInfoCmd(values) {
|
|
267
284
|
clearTimeout(this.timer);
|
|
268
285
|
this.mqttPublish = true;
|
|
286
|
+
this.$store?.commit('setMqttPublish', true);
|
|
269
287
|
this.mqttCode = values[2];
|
|
270
288
|
let res = null;
|
|
271
289
|
// 下发指令逻辑
|
|
@@ -289,6 +307,7 @@ export class MqttServer {
|
|
|
289
307
|
}
|
|
290
308
|
this.timer = setTimeout(() => {
|
|
291
309
|
this.mqttPublish = false;
|
|
310
|
+
this.$store?.commit('setMqttPublish', false);
|
|
292
311
|
}, 30000);
|
|
293
312
|
}
|
|
294
313
|
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// import store from '@/store/index';
|
|
2
|
+
import {
|
|
3
|
+
reactive
|
|
4
|
+
} from "vue";
|
|
5
|
+
import { set_PlanCMD_DD } from './BleCmdAnalysis/BleCmdDD';
|
|
6
|
+
import { set_PlanCMD_FFAA } from './BleCmdAnalysis/BleCmdFFAA';
|
|
7
|
+
import { getCMDESInfoAsync } from './BleCmdAnalysis/BleCmdHVES.js';
|
|
8
|
+
import { sleep } from './BleDataProcess.js';
|
|
9
|
+
import Queue from './Queue.js';
|
|
10
|
+
import { Transfer } from './Transfer.js';
|
|
11
|
+
export const tcpSend = reactive({
|
|
12
|
+
isSending: false, //是否在下发平台指令
|
|
13
|
+
isLast: false,
|
|
14
|
+
code: null,
|
|
15
|
+
hasHeartbeat: false,
|
|
16
|
+
tcpClose: false,
|
|
17
|
+
devices: {}
|
|
18
|
+
})
|
|
19
|
+
// / 创建一个队列来存储接收到的消息
|
|
20
|
+
const messageQueue = new Queue();
|
|
21
|
+
let timer = null
|
|
22
|
+
export const tcpServer = {
|
|
23
|
+
version: '2.8.2', // 每次上传需要手动修改此 版本号
|
|
24
|
+
socketOpen: false, //是否建立连接
|
|
25
|
+
macAddr: '',
|
|
26
|
+
txnNo: '',
|
|
27
|
+
baseDelay: 1000, // 初始重试延迟(毫秒)
|
|
28
|
+
maxDelay: 60 * 1000, // 最大重试延迟(毫秒)
|
|
29
|
+
retryCount: 0, // 重试次数
|
|
30
|
+
url: {
|
|
31
|
+
address: 'cloud.jiabaida.com',
|
|
32
|
+
port: 10241
|
|
33
|
+
},
|
|
34
|
+
url1: {
|
|
35
|
+
address: '192.168.80.36',
|
|
36
|
+
port: 10240
|
|
37
|
+
},
|
|
38
|
+
timers: {},
|
|
39
|
+
heartBeatTimers: {},
|
|
40
|
+
tcpSockets: {},
|
|
41
|
+
isRetryings: {},
|
|
42
|
+
socketOpens: {},
|
|
43
|
+
async initTCPConnection(macAddr, deviceId) {
|
|
44
|
+
console.log('macAddr: init-------tcp', macAddr, deviceId);
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
try {
|
|
47
|
+
tcpSend.devices[macAddr] = {
|
|
48
|
+
macAddr,
|
|
49
|
+
deviceId
|
|
50
|
+
}
|
|
51
|
+
this.tcpSockets[`${deviceId}_socket`] = wx.createTCPSocket();
|
|
52
|
+
console.log('this.tcpSockets[`${deviceId}_socket`]: ', this.tcpSockets[`${deviceId}_socket`]);
|
|
53
|
+
this.tcpSockets[`${deviceId}_socket`].connect(this.url);
|
|
54
|
+
this.tcpSockets[`${deviceId}_socket`].onConnect(() => {
|
|
55
|
+
this.listenerConnect(macAddr, deviceId)
|
|
56
|
+
resolve(true)
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.tcpSockets[`${deviceId}_socket`].onMessage((message) => {
|
|
60
|
+
console.log('接收到消息:', message);
|
|
61
|
+
// 处理接收到的消息
|
|
62
|
+
// 将buffer转为常规数组 十六进制
|
|
63
|
+
const intArr = Array.prototype.map.call(
|
|
64
|
+
new Uint8Array(message.message),
|
|
65
|
+
function (bit) {
|
|
66
|
+
return bit;
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
// 将十六进制转为对应的字符
|
|
70
|
+
let valueString = String.fromCharCode(...intArr)
|
|
71
|
+
console.log(valueString, 'valueString');
|
|
72
|
+
// messageQueue.enqueue(valueString);
|
|
73
|
+
// this.processQueue()
|
|
74
|
+
this.processMessageAsync(valueString)
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
this.tcpSockets[`${deviceId}_socket`].onError((error) => {
|
|
78
|
+
this.listenerError(macAddr, deviceId, error)
|
|
79
|
+
reject(error)
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.tcpSockets[`${deviceId}_socket`].onClose(this.listenerClose(deviceId));
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('error: tcp连接失败', error);
|
|
85
|
+
reject(error)
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
},
|
|
89
|
+
listenerConnect(macAddr, deviceId) {
|
|
90
|
+
this.socketOpens[`open_${deviceId}`] = true
|
|
91
|
+
this.isRetryings[`retry_${deviceId}`] = false
|
|
92
|
+
console.log('TCP 连接已建立');
|
|
93
|
+
clearInterval(this.timers[`timer_${deviceId}`])
|
|
94
|
+
this.timers[`timer_${deviceId}`] = null
|
|
95
|
+
// 连接建立后,开始发送心跳包
|
|
96
|
+
this.sendHeartbeat(macAddr, deviceId);
|
|
97
|
+
},
|
|
98
|
+
listenerError(macAddr, deviceId, error) {
|
|
99
|
+
this.socketOpens[`open_${deviceId}`] = false
|
|
100
|
+
console.log('TCP 连接错误:', deviceId, error);
|
|
101
|
+
this.stopHeartBeat(deviceId)
|
|
102
|
+
if (!this.isRetryings[`retry_${deviceId}`]) {
|
|
103
|
+
this.retryCount = 0
|
|
104
|
+
// 重连
|
|
105
|
+
this.reConnect(macAddr, deviceId, true)
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
listenerClose(deviceId) {
|
|
109
|
+
this.socketOpens[`open_${deviceId}`] = false
|
|
110
|
+
console.log('TCP 连接已关闭');
|
|
111
|
+
},
|
|
112
|
+
// 关闭tcp连接
|
|
113
|
+
closeTcpSocket(deviceId) {
|
|
114
|
+
try {
|
|
115
|
+
clearInterval(this.timers[`timer_${deviceId}`])
|
|
116
|
+
this.timers[`timer_${deviceId}`] = null
|
|
117
|
+
if (this.tcpSockets[`${deviceId}_socket`]) {
|
|
118
|
+
this.socketOpens[`open_${deviceId}`] = false
|
|
119
|
+
this.stopHeartBeat(deviceId)
|
|
120
|
+
this.tcpSockets[`${deviceId}_socket`].offMessage()
|
|
121
|
+
this.tcpSockets[`${deviceId}_socket`].offConnect()
|
|
122
|
+
this.tcpSockets[`${deviceId}_socket`].offClose()
|
|
123
|
+
this.tcpSockets[`${deviceId}_socket`].offError()
|
|
124
|
+
this.tcpSockets[`${deviceId}_socket`].close()
|
|
125
|
+
this.tcpSockets[`${deviceId}_socket`] = null
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('error: closeTcpSocket', error);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
async reConnect(macAddr, deviceId, closeSocket = false) {
|
|
132
|
+
console.log('重连 this.macAddr', macAddr);
|
|
133
|
+
this.isRetryings[`retry_${deviceId}`] = true
|
|
134
|
+
// 关闭旧的连接再重连
|
|
135
|
+
if (closeSocket) this.tcpSockets[`${deviceId}_socket`].close()
|
|
136
|
+
this.tcpSockets[`${deviceId}_socket`].connect(this.url);
|
|
137
|
+
const delay = Math.min(this.baseDelay * Math.pow(2, this.retryCount), this.maxDelay);
|
|
138
|
+
console.log(`准备 ${delay}ms 后重试...`);
|
|
139
|
+
this.timers[`timer_${deviceId}`] = setTimeout(() => {
|
|
140
|
+
this.reConnect(macAddr, deviceId);
|
|
141
|
+
}, delay);
|
|
142
|
+
this.retryCount++
|
|
143
|
+
},
|
|
144
|
+
sendHeartbeat(macAddr, deviceId) {
|
|
145
|
+
let tokenStr = uni.getStorageSync('token')
|
|
146
|
+
let token = tokenStr.replace('Bearer ', '')
|
|
147
|
+
const heartbeatMsg = {
|
|
148
|
+
command: 96, //业务操作码,96代表心跳包
|
|
149
|
+
data: {
|
|
150
|
+
token,
|
|
151
|
+
appVersion: "xiaoxiang:" + this.version, //小程序版本号
|
|
152
|
+
macAddr,
|
|
153
|
+
},
|
|
154
|
+
txnNo: +new Date(), //当前时间戳
|
|
155
|
+
isAnonymous: 0, //是否匿名登录
|
|
156
|
+
};
|
|
157
|
+
console.log('heartbeatMsg: ', heartbeatMsg);
|
|
158
|
+
tcpSend.hasHeartbeat = false
|
|
159
|
+
this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(heartbeatMsg));
|
|
160
|
+
this.heartBeatTimers[`heartTimer_${deviceId}`] = setInterval(() => {
|
|
161
|
+
heartbeatMsg.txnNo = +new Date() //当前时间戳
|
|
162
|
+
//##console.log(heartbeatMsg, 'heartbeatMsg');
|
|
163
|
+
tcpSend.hasHeartbeat = false
|
|
164
|
+
this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(heartbeatMsg));
|
|
165
|
+
}, 30000); // 每5秒发送一次心跳包
|
|
166
|
+
},
|
|
167
|
+
// 清除心跳上报计时器
|
|
168
|
+
stopHeartBeat(deviceId) {
|
|
169
|
+
if (this.heartBeatTimers[`heartTimer_${deviceId}`]) {
|
|
170
|
+
clearInterval(this.heartBeatTimers[`heartTimer_${deviceId}`]);
|
|
171
|
+
this.heartBeatTimers[`heartTimer_${deviceId}`] = null;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
//上报基础 信息
|
|
175
|
+
sendReportData(data) {
|
|
176
|
+
const reportData = {
|
|
177
|
+
command: 999, //业务操作码,999代表上报
|
|
178
|
+
data: {
|
|
179
|
+
value: data.value,
|
|
180
|
+
cmdCode: 'jbd0F',
|
|
181
|
+
bluetoothName: data.bluetoothName,
|
|
182
|
+
},
|
|
183
|
+
macAddr: data.macAddr,
|
|
184
|
+
txnNo: +new Date(), //当前时间戳
|
|
185
|
+
};
|
|
186
|
+
console.log(reportData, 'reportData111上报基础数据');
|
|
187
|
+
this.tcpSockets[`${data.deviceId}_socket`].write(JSON.stringify(reportData));
|
|
188
|
+
},
|
|
189
|
+
// 执行完平台下发的指令后上报数据
|
|
190
|
+
sendWriteReportData(data, deviceId) {
|
|
191
|
+
console.warn('执行后上报数据data: ', data);
|
|
192
|
+
const reportData = {
|
|
193
|
+
command: 121, //业务操作码,代表执行上报
|
|
194
|
+
data: {
|
|
195
|
+
macAddr: this.macAddr,
|
|
196
|
+
content: data,
|
|
197
|
+
},
|
|
198
|
+
txnNo: this.txnNo, //callbackId
|
|
199
|
+
};
|
|
200
|
+
//##console.log(reportData, 'WriteReportData执行指令后上报数据');
|
|
201
|
+
this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(reportData));
|
|
202
|
+
if (tcpSend.isLast) {
|
|
203
|
+
tcpSend.isSending = false
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
// 处理队列中的消息
|
|
207
|
+
processQueue() {
|
|
208
|
+
if (!tcpSend.isSending) {
|
|
209
|
+
this.processNextMessage();
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
async processNextMessage() {
|
|
213
|
+
//##console.log('messageQueue-------', messageQueue);
|
|
214
|
+
|
|
215
|
+
if (!messageQueue.isEmpty()) {
|
|
216
|
+
const message = messageQueue.dequeue();
|
|
217
|
+
//##console.log('Processing:', message);
|
|
218
|
+
// 异步处理消息
|
|
219
|
+
this.processMessageAsync(message).then(() => {
|
|
220
|
+
this.processNextMessage();
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
await sleep(300)
|
|
224
|
+
tcpSend.isSending = false;
|
|
225
|
+
//##console.log('tcpSend.isSending发送完成', tcpSend.isSending);
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
async processMessageAsync(message) {
|
|
229
|
+
clearTimeout(timer)
|
|
230
|
+
// 假设这里是异步操作,例如写入数据库
|
|
231
|
+
return new Promise(async (resolve) => {
|
|
232
|
+
try {
|
|
233
|
+
console.log('Message processed:', message);
|
|
234
|
+
let msgObj = JSON.parse(message)
|
|
235
|
+
console.warn('----------msgObj后台下发的指令: -----------', msgObj);
|
|
236
|
+
// 为120,即接收到后台下发的指令
|
|
237
|
+
if (msgObj.command == 120) {
|
|
238
|
+
let value = msgObj.data.content
|
|
239
|
+
if (!value) return
|
|
240
|
+
|
|
241
|
+
// 使用正则表达式将字符串两两分隔为数组
|
|
242
|
+
let resultArray = value.match(/.{1,2}/g);
|
|
243
|
+
console.log('resultArray: ', resultArray);
|
|
244
|
+
// 给蓝牙设备发送指令
|
|
245
|
+
this.macAddr = msgObj.data.macAddr
|
|
246
|
+
let deviceId = null
|
|
247
|
+
for (let key in tcpSend.devices) {
|
|
248
|
+
if (tcpSend.devices[key].macAddr == this.macAddr) {
|
|
249
|
+
deviceId = tcpSend.devices[key].deviceId
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
console.log('deviceId: ', deviceId);
|
|
253
|
+
this.txnNo = msgObj.txnNo
|
|
254
|
+
tcpSend.isLast = msgObj.isLast
|
|
255
|
+
tcpSend.isSending = true
|
|
256
|
+
tcpSend.code = resultArray[2]
|
|
257
|
+
// 向蓝牙设备发送一个0x00的16进制数据,读取指令
|
|
258
|
+
let length = resultArray.length
|
|
259
|
+
const buffer = new ArrayBuffer(length);
|
|
260
|
+
const dataView = new DataView(buffer);
|
|
261
|
+
resultArray.forEach((el, index) => {
|
|
262
|
+
// 循环,取每一个十六进制值 添加到buffer
|
|
263
|
+
dataView.setUint8(index, '0x' + el);
|
|
264
|
+
})
|
|
265
|
+
console.log(buffer, "读取指令-----------------------");
|
|
266
|
+
// store.commit('setPassthroughType', 1);// 设置类型为 被动回复1
|
|
267
|
+
// BLE.sendMsgToKey(buffer, deviceId)
|
|
268
|
+
|
|
269
|
+
// this.mqttCode = resultArray[2];
|
|
270
|
+
let res = null;
|
|
271
|
+
// 下发指令逻辑
|
|
272
|
+
if (resultArray[0]?.toUpperCase() === 'FF' && resultArray[1]?.toUpperCase() === 'AA') {
|
|
273
|
+
res = await set_PlanCMD_FFAA(deviceId, resultArray.join(''));
|
|
274
|
+
} else if (resultArray[1]?.toUpperCase() === '78' || resultArray[1]?.toUpperCase() === '50') {
|
|
275
|
+
res = await getCMDESInfoAsync(deviceId, resultArray.join(''));
|
|
276
|
+
} else {
|
|
277
|
+
// DD
|
|
278
|
+
res = await set_PlanCMD_DD(deviceId, resultArray.join(''));
|
|
279
|
+
}
|
|
280
|
+
const content = res?.data || []
|
|
281
|
+
let code = Transfer.decimalToHex(content[1]);
|
|
282
|
+
if (content[0] == 0xff && content[1] == 0xaa) {
|
|
283
|
+
code = Transfer.decimalToHex(content[2]);
|
|
284
|
+
}
|
|
285
|
+
console.log('code: 回复的code', code);
|
|
286
|
+
if (code.toUpperCase() == tcpSend?.code?.toUpperCase()) {
|
|
287
|
+
this.sendWriteReportData(content, deviceId)
|
|
288
|
+
}
|
|
289
|
+
} else if (msgObj.command == 97) {
|
|
290
|
+
tcpSend.hasHeartbeat = true
|
|
291
|
+
}
|
|
292
|
+
// 超时 30s 未收到指令反馈 认为指令发送失败
|
|
293
|
+
timer = setTimeout(() => {
|
|
294
|
+
tcpSend.isSending = false
|
|
295
|
+
}, 30000)
|
|
296
|
+
resolve(true);
|
|
297
|
+
} catch (error) {
|
|
298
|
+
console.log('error: ', error);
|
|
299
|
+
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
}
|
package/src/index.js
CHANGED
|
@@ -9,5 +9,6 @@ export * from './core/keyAndPwdManager';
|
|
|
9
9
|
export * from './core/mqttServer.js';
|
|
10
10
|
export * from './core/OtaUpgrade';
|
|
11
11
|
export * from './core/rsaEncrypt';
|
|
12
|
+
export * from './core/tcpServer.js';
|
|
12
13
|
export * from './core/TelinkApi';
|
|
13
14
|
export * from './core/Transfer';
|