@ray-js/robot-data-stream 0.0.13-beta-5 → 0.0.13-beta-7
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/lib/api/index.d.ts +12 -2
- package/lib/api/index.js +172 -1
- package/lib/api/p2pApi.d.ts +27 -8
- package/lib/api/p2pApi.js +169 -271
- package/lib/api/sweeperP2p.d.ts +23 -49
- package/lib/api/sweeperP2p.js +248 -311
- package/lib/constant.d.ts +52 -0
- package/lib/constant.js +54 -0
- package/lib/index.d.ts +1 -10
- package/lib/index.js +2 -165
- package/lib/mqtt/createCommonOptions.d.ts +56 -15
- package/lib/mqtt/createCommonOptions.js +44 -8
- package/lib/mqtt/index.d.ts +2 -1
- package/lib/mqtt/index.js +2 -1
- package/lib/mqtt/mqttProvider.d.ts +23 -15
- package/lib/mqtt/mqttProvider.js +63 -26
- package/lib/mqtt/promise.js +8 -3
- package/lib/mqtt/type/index.d.ts +14 -0
- package/lib/mqtt/type/index.js +14 -0
- package/lib/mqtt/type/requestType.d.ts +8 -0
- package/lib/mqtt/type/requestType.js +10 -0
- package/lib/mqtt/useDevInfo.d.ts +2 -7
- package/lib/mqtt/useDevInfo.js +25 -9
- package/lib/mqtt/useHistoryMap.d.ts +13 -21
- package/lib/mqtt/useHistoryMap.js +82 -32
- package/lib/mqtt/usePartDivision.d.ts +5 -7
- package/lib/mqtt/usePartDivision.js +41 -16
- package/lib/mqtt/usePartMerge.d.ts +5 -7
- package/lib/mqtt/usePartMerge.js +36 -18
- package/lib/mqtt/usePassword.js +59 -28
- package/lib/mqtt/useQuiteHours.d.ts +9 -24
- package/lib/mqtt/useQuiteHours.js +95 -52
- package/lib/mqtt/useResetMap.d.ts +10 -7
- package/lib/mqtt/useResetMap.js +40 -11
- package/lib/mqtt/useRoomProperty.js +23 -16
- package/lib/mqtt/useSchedule.d.ts +17 -4
- package/lib/mqtt/useSchedule.js +101 -49
- package/lib/mqtt/useSelectRoomClean.d.ts +20 -16
- package/lib/mqtt/useSelectRoomClean.js +145 -49
- package/lib/mqtt/useSpotClean.d.ts +3 -3
- package/lib/mqtt/useSpotClean.js +72 -50
- package/lib/mqtt/useVirtualArea.d.ts +6 -9
- package/lib/mqtt/useVirtualArea.js +112 -42
- package/lib/mqtt/useVirtualWall.d.ts +13 -10
- package/lib/mqtt/useVirtualWall.js +97 -34
- package/lib/mqtt/useVoice.d.ts +3 -6
- package/lib/mqtt/useVoice.js +73 -33
- package/lib/mqtt/useWifiMap.d.ts +8 -0
- package/lib/mqtt/useWifiMap.js +53 -0
- package/lib/mqtt/useZoneClean.d.ts +13 -13
- package/lib/mqtt/useZoneClean.js +149 -76
- package/lib/ttt/index.d.ts +153 -0
- package/lib/ttt/index.js +458 -0
- package/lib/utils/index.d.ts +20 -1
- package/lib/utils/index.js +19 -0
- package/package.json +1 -1
- package/lib/mqtt/myError.d.ts +0 -4
- package/lib/mqtt/myError.js +0 -6
package/lib/api/sweeperP2p.js
CHANGED
|
@@ -1,49 +1,32 @@
|
|
|
1
1
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.filter.js";
|
|
2
3
|
import "core-js/modules/esnext.iterator.for-each.js";
|
|
3
4
|
import "core-js/modules/esnext.iterator.map.js";
|
|
4
|
-
/* eslint-disable no-shadow */
|
|
5
5
|
import Base64 from 'base64-js';
|
|
6
|
-
import { join, map,
|
|
6
|
+
import { join, map, once, padStart } from 'lodash-es';
|
|
7
|
+
import { FILE_NAME_MAP, FileNameEnum } from '../constant';
|
|
7
8
|
import { trace } from '../trace';
|
|
8
|
-
import {
|
|
9
|
+
import { checkIfDirIsExist, createFilePath } from '../ttt';
|
|
9
10
|
import P2pApi from './p2pApi';
|
|
10
11
|
/**
|
|
11
12
|
* 基于P2p工具类的扫地机扩展实现
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'map_structured.bin.stream': {
|
|
30
|
-
type: 6
|
|
31
|
-
},
|
|
32
|
-
'cleanPath.bin.stream': {
|
|
33
|
-
type: 1
|
|
34
|
-
},
|
|
35
|
-
'ai.bin': {
|
|
36
|
-
type: 4
|
|
37
|
-
},
|
|
38
|
-
'ai.bin.stream': {
|
|
39
|
-
type: 4
|
|
40
|
-
},
|
|
41
|
-
'aiHD_XXXX_YYYY.bin': {
|
|
42
|
-
type: 5
|
|
43
|
-
},
|
|
44
|
-
'aiHD_XXXX_YYYY.bin.stream': {
|
|
45
|
-
type: 5
|
|
46
|
-
}
|
|
15
|
+
// 需要初始化的文件名列表(不包括 wifi_map)
|
|
16
|
+
const FILE_NAMES_TO_INIT = [FileNameEnum.map, FileNameEnum.mapStructured, FileNameEnum.cleanPath, FileNameEnum.ai, FileNameEnum.aiHD, FileNameEnum.mapStream, FileNameEnum.mapStructuredStream, FileNameEnum.cleanPathStream, FileNameEnum.aiStream, FileNameEnum.aiHDStream];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 创建初始化的 Map,所有键值都设置为初始值
|
|
20
|
+
*/
|
|
21
|
+
const createInitializedMap = initialValue => {
|
|
22
|
+
return new Map(FILE_NAMES_TO_INIT.map(key => [key, initialValue]));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 创建初始化的 Map,值为新的 Map 实例
|
|
27
|
+
*/
|
|
28
|
+
const createMapOfMaps = () => {
|
|
29
|
+
return new Map(FILE_NAMES_TO_INIT.map(key => [key, new Map()]));
|
|
47
30
|
};
|
|
48
31
|
|
|
49
32
|
// 走p2p流传输(新) or 读取bin文件(旧)
|
|
@@ -61,10 +44,11 @@ export class SweeperP2p extends P2pApi {
|
|
|
61
44
|
this.cacheData = {};
|
|
62
45
|
this.exitFiles = [];
|
|
63
46
|
this.firstPackageTime = Date.now();
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
47
|
+
// 使用辅助函数初始化 Map,减少重复代码
|
|
48
|
+
this.packetTotalMap = createInitializedMap(-1);
|
|
49
|
+
this.packetSerialNumberCacheMap = createInitializedMap(-1);
|
|
50
|
+
this.fileLengthCacheMap = createInitializedMap(-1);
|
|
51
|
+
this.packetDataCacheMap = createMapOfMaps();
|
|
68
52
|
}
|
|
69
53
|
setStreamFilePath = () => {
|
|
70
54
|
// this.streamFilePath = this.cacheDir + `/${this.albumName}/${devId}/stream`;
|
|
@@ -81,7 +65,7 @@ export class SweeperP2p extends P2pApi {
|
|
|
81
65
|
if (/usr/.test(this.cacheDir)) {
|
|
82
66
|
this.dataFilePath = this.cacheDir;
|
|
83
67
|
} else {
|
|
84
|
-
this.
|
|
68
|
+
this.dataFilePath = this.cacheDir + 'usr';
|
|
85
69
|
}
|
|
86
70
|
// 检查存储文件目录是否存在
|
|
87
71
|
// this.initFilePath(this.dataFilePath);
|
|
@@ -105,70 +89,17 @@ export class SweeperP2p extends P2pApi {
|
|
|
105
89
|
return this.dataFilePath + '/' + fileName;
|
|
106
90
|
};
|
|
107
91
|
|
|
108
|
-
/**
|
|
109
|
-
* 创建文件路径文件夹
|
|
110
|
-
* @param filePath
|
|
111
|
-
* @returns
|
|
112
|
-
*/
|
|
113
|
-
createFilePath = filePath => {
|
|
114
|
-
try {
|
|
115
|
-
ty.getFileSystemManager().mkdirSync({
|
|
116
|
-
dirPath: filePath,
|
|
117
|
-
recursive: true
|
|
118
|
-
});
|
|
119
|
-
logger('info', {
|
|
120
|
-
msg: 'mkdirSync success: filePath ==>',
|
|
121
|
-
filePath
|
|
122
|
-
}, this.onLogger);
|
|
123
|
-
return true;
|
|
124
|
-
} catch (e) {
|
|
125
|
-
logger('error', {
|
|
126
|
-
msg: 'mkdirSync error ==>',
|
|
127
|
-
e
|
|
128
|
-
}, this.onLogger);
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* 检查当前文件目录是否存在
|
|
135
|
-
* @param filePath
|
|
136
|
-
* @returns
|
|
137
|
-
*/
|
|
138
|
-
checkIfDirIsExist = filePath => {
|
|
139
|
-
return new Promise(resolve => {
|
|
140
|
-
ty.getFileSystemManager().access({
|
|
141
|
-
path: filePath,
|
|
142
|
-
success(params) {
|
|
143
|
-
logger('info', {
|
|
144
|
-
msg: 'file access success ==>',
|
|
145
|
-
params
|
|
146
|
-
}, this.onLogger);
|
|
147
|
-
resolve(true);
|
|
148
|
-
},
|
|
149
|
-
fail(params) {
|
|
150
|
-
logger('warn', {
|
|
151
|
-
msg: 'file access fail ==>',
|
|
152
|
-
params
|
|
153
|
-
}, this.onLogger);
|
|
154
|
-
resolve(false);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
|
|
160
92
|
/**
|
|
161
93
|
* 初始化文件目录
|
|
162
94
|
* @param filePath
|
|
163
95
|
* @returns
|
|
164
96
|
*/
|
|
165
97
|
initFilePath = async filePath => {
|
|
166
|
-
const isDir = await
|
|
98
|
+
const isDir = await checkIfDirIsExist(filePath);
|
|
167
99
|
if (!isDir) {
|
|
168
|
-
|
|
169
|
-
return result;
|
|
100
|
+
return await createFilePath(filePath, this.onLogger);
|
|
170
101
|
}
|
|
171
|
-
return
|
|
102
|
+
return true;
|
|
172
103
|
};
|
|
173
104
|
|
|
174
105
|
/**
|
|
@@ -176,72 +107,186 @@ export class SweeperP2p extends P2pApi {
|
|
|
176
107
|
* @param filename
|
|
177
108
|
*/
|
|
178
109
|
getFileType = filename => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (filename.indexOf('map.') !== -1) {
|
|
183
|
-
return 0;
|
|
110
|
+
// 首先尝试精确匹配 FILE_NAME_MAP 中的键
|
|
111
|
+
if (filename in FILE_NAME_MAP) {
|
|
112
|
+
return FILE_NAME_MAP[filename].type;
|
|
184
113
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
return
|
|
114
|
+
|
|
115
|
+
// 处理 aiHD_XXXX_YYYY.bin 模式(XXXX_YYYY 会被替换为实际值)
|
|
116
|
+
|
|
117
|
+
if (/^aiHD.*\.bin(\.stream)?$/.test(filename)) {
|
|
118
|
+
return FILE_NAME_MAP[FileNameEnum.aiHD].type;
|
|
190
119
|
}
|
|
191
|
-
|
|
192
|
-
|
|
120
|
+
|
|
121
|
+
// 按优先级顺序匹配文件名(更具体的模式优先)
|
|
122
|
+
// 注意:map_structured 必须在 map 之前匹配
|
|
123
|
+
const matchOrder = [{
|
|
124
|
+
pattern: /map_structured/,
|
|
125
|
+
enumKey: FileNameEnum.mapStructured
|
|
126
|
+
}, {
|
|
127
|
+
pattern: /^map\./,
|
|
128
|
+
enumKey: FileNameEnum.map
|
|
129
|
+
}, {
|
|
130
|
+
pattern: /cleanPath/,
|
|
131
|
+
enumKey: FileNameEnum.cleanPath
|
|
132
|
+
}, {
|
|
133
|
+
pattern: /^ai\./,
|
|
134
|
+
enumKey: FileNameEnum.ai
|
|
135
|
+
}, {
|
|
136
|
+
pattern: /wifi_map/,
|
|
137
|
+
enumKey: FileNameEnum.wifiMap
|
|
138
|
+
}];
|
|
139
|
+
for (const {
|
|
140
|
+
pattern,
|
|
141
|
+
enumKey
|
|
142
|
+
} of matchOrder) {
|
|
143
|
+
if (pattern.test(filename)) {
|
|
144
|
+
return FILE_NAME_MAP[enumKey].type;
|
|
145
|
+
}
|
|
193
146
|
}
|
|
147
|
+
|
|
148
|
+
// 默认返回 2
|
|
194
149
|
return 2;
|
|
195
150
|
};
|
|
196
151
|
|
|
152
|
+
/**
|
|
153
|
+
* 根据文件类型处理数据并调用相应的回调函数
|
|
154
|
+
*/
|
|
155
|
+
handleDataByType = (() => {
|
|
156
|
+
var _this = this;
|
|
157
|
+
return function (type, hexValue) {
|
|
158
|
+
let shouldCache = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
159
|
+
if (_this.cacheData[type] === hexValue) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
switch (type) {
|
|
163
|
+
case 0:
|
|
164
|
+
case 6:
|
|
165
|
+
_this.onReceiveMapData(hexValue);
|
|
166
|
+
if (shouldCache) {
|
|
167
|
+
_this.cacheData[type] = hexValue;
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
case 1:
|
|
171
|
+
_this.log.info({
|
|
172
|
+
msg: 'push new path data'
|
|
173
|
+
});
|
|
174
|
+
_this.onReceivePathData(hexValue);
|
|
175
|
+
if (shouldCache) {
|
|
176
|
+
_this.cacheData[type] = hexValue;
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case 4:
|
|
180
|
+
_this.onReceiveAIPicData(hexValue);
|
|
181
|
+
break;
|
|
182
|
+
case 5:
|
|
183
|
+
_this.onReceiveAIPicHDData(hexValue);
|
|
184
|
+
break;
|
|
185
|
+
case 7:
|
|
186
|
+
_this.onReceiveWifiMapData(hexValue);
|
|
187
|
+
break;
|
|
188
|
+
default:
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
})();
|
|
193
|
+
|
|
197
194
|
/**
|
|
198
195
|
* 设备连接状态发生改变
|
|
199
196
|
* @param data
|
|
200
197
|
*/
|
|
201
198
|
sessionStatusCallback = data => {
|
|
202
|
-
|
|
199
|
+
this.log.info({
|
|
203
200
|
msg: 'sessionStatusCallback ==>',
|
|
204
201
|
data
|
|
205
|
-
}
|
|
202
|
+
});
|
|
206
203
|
if (data) {
|
|
207
204
|
const {
|
|
208
205
|
status
|
|
209
206
|
} = data;
|
|
210
207
|
if (status < 0) {
|
|
211
|
-
|
|
208
|
+
this.log.info({
|
|
212
209
|
msg: 'receive disconnect notice ==>',
|
|
213
210
|
status
|
|
214
|
-
}
|
|
211
|
+
});
|
|
215
212
|
this.isConnected = false;
|
|
216
213
|
if (!this.isConnecting) {
|
|
217
214
|
this.reconnectP2p(() => {
|
|
218
215
|
// 重连之后重新开启文件下载, 这里的成功不需要注册断开事件
|
|
219
|
-
this.startObserverSweeperDataByP2P(this.downloadType, this.devId, this.onReceiveMapData, this.onReceivePathData, this.onReceiveAIPicData, this.onReceiveAIPicHDData);
|
|
216
|
+
this.startObserverSweeperDataByP2P(this.downloadType, this.devId, this.onReceiveMapData, this.onReceivePathData, this.onReceiveAIPicData, this.onReceiveAIPicHDData, this.onReceiveWifiMapData);
|
|
220
217
|
}, '');
|
|
221
218
|
} else {
|
|
222
|
-
|
|
219
|
+
this.log.warn({
|
|
223
220
|
msg: 'receive disconnect notice, but connectDevice is connecting'
|
|
224
|
-
}
|
|
221
|
+
});
|
|
225
222
|
}
|
|
226
223
|
}
|
|
227
224
|
}
|
|
228
225
|
};
|
|
229
226
|
|
|
227
|
+
/**
|
|
228
|
+
* 创建下载失败时的重连回调函数
|
|
229
|
+
*/
|
|
230
|
+
createReconnectCallback = () => {
|
|
231
|
+
return () => {
|
|
232
|
+
this.log.error({
|
|
233
|
+
msg: `${this.downloadType} p2p downloadStream failed and try reConnect Device===>`
|
|
234
|
+
});
|
|
235
|
+
this.removeP2pDownloadEvent();
|
|
236
|
+
this.disconnectDevice().then(() => {
|
|
237
|
+
this.isConnected = false;
|
|
238
|
+
this.isConnecting = false;
|
|
239
|
+
this.connectDevice(() => {
|
|
240
|
+
// 重连之后重新开启文件下载, 这里的成功不需要注册断开事件
|
|
241
|
+
this.startObserverSweeperDataByP2P(this.downloadType, this.devId, this.onReceiveMapData, this.onReceivePathData, this.onReceiveAIPicData, this.onReceiveAIPicHDData, this.onReceiveWifiMapData);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* 执行文件下载逻辑
|
|
249
|
+
*/
|
|
250
|
+
async executeDownload(exitFiles, filePath) {
|
|
251
|
+
if (exitFiles.length === 0) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (shouldDownloadStream) {
|
|
255
|
+
// 开启p2p流传输
|
|
256
|
+
await this.downloadStream({
|
|
257
|
+
files: exitFiles
|
|
258
|
+
}, this.albumName, () => {
|
|
259
|
+
this.log.info({
|
|
260
|
+
msg: `${this.downloadType} p2p downloadStream success===>`
|
|
261
|
+
});
|
|
262
|
+
}, this.createReconnectCallback());
|
|
263
|
+
} else if (await this.initFilePath(filePath)) {
|
|
264
|
+
// 每次要下载前都需要先检查文件目录是否存在 防止中间过程被删除掉文件目录
|
|
265
|
+
await this.downloadFile({
|
|
266
|
+
files: exitFiles
|
|
267
|
+
}, this.albumName, filePath);
|
|
268
|
+
}
|
|
269
|
+
this.firstPackageTime = Date.now();
|
|
270
|
+
}
|
|
271
|
+
|
|
230
272
|
/**
|
|
231
273
|
* 开始进行文件下载
|
|
232
274
|
* @param downloadType
|
|
233
275
|
* 0: 下载断开 1: 持续下载
|
|
234
276
|
*/
|
|
235
|
-
startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData, onDefineStructuredMode) => {
|
|
236
|
-
var _this$file
|
|
237
|
-
if (![0, 1].
|
|
238
|
-
|
|
277
|
+
startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData, onReceiveWifiMapData, onDefineStructuredMode) => {
|
|
278
|
+
var _this$file;
|
|
279
|
+
if (![0, 1].includes(downloadType)) {
|
|
280
|
+
this.log.warn({
|
|
239
281
|
msg: 'download type must be 0 or 1'
|
|
240
|
-
}
|
|
282
|
+
});
|
|
241
283
|
return;
|
|
242
284
|
}
|
|
285
|
+
|
|
286
|
+
// 初始化回调函数
|
|
243
287
|
this.onReceiveMapData = onReceiveMapData;
|
|
244
288
|
this.onReceivePathData = onReceivePathData;
|
|
289
|
+
this.onReceiveWifiMapData = onReceiveWifiMapData;
|
|
245
290
|
this.onDefineStructuredMode = onDefineStructuredMode;
|
|
246
291
|
this.onReceiveAIPicData = onReceiveAIPicData || (() => {
|
|
247
292
|
// do nothing
|
|
@@ -249,9 +294,9 @@ export class SweeperP2p extends P2pApi {
|
|
|
249
294
|
this.onReceiveAIPicHDData = onReceiveAIPicHDData || (() => {
|
|
250
295
|
// do nothing
|
|
251
296
|
});
|
|
252
|
-
|
|
297
|
+
this.log.info({
|
|
253
298
|
msg: 'startObserverSweeperDataByP2P ==>'
|
|
254
|
-
}
|
|
299
|
+
});
|
|
255
300
|
trace.pointFn({
|
|
256
301
|
devId,
|
|
257
302
|
eventName: 'startObserverSweeperDataByP2P'
|
|
@@ -259,85 +304,27 @@ export class SweeperP2p extends P2pApi {
|
|
|
259
304
|
this.downloadType = downloadType;
|
|
260
305
|
this.setDataFilePath(devId);
|
|
261
306
|
this.setStreamFilePath(devId);
|
|
307
|
+
|
|
262
308
|
// 先移除监听,再重新注册
|
|
263
309
|
this.removeP2pDownloadEvent();
|
|
264
310
|
this.registerP2pDownloadEvent();
|
|
311
|
+
|
|
312
|
+
// 查询文件列表
|
|
265
313
|
if (!this.file) {
|
|
266
314
|
// @ts-ignore
|
|
267
315
|
this.file = await this.queryAlbumFileIndexs(this.albumName);
|
|
268
316
|
}
|
|
269
|
-
if (this.file && (
|
|
270
|
-
|
|
271
|
-
const exitFiles = this.queryNeedFiles(this.file.items);
|
|
272
|
-
// 赋值
|
|
273
|
-
this.exitFiles = exitFiles;
|
|
274
|
-
if (exitFiles.length > 0) {
|
|
275
|
-
if (shouldDownloadStream) {
|
|
276
|
-
// 开启p2p流传输
|
|
277
|
-
await this.downloadStream({
|
|
278
|
-
files: exitFiles
|
|
279
|
-
}, this.albumName, () => {
|
|
280
|
-
logger('info', {
|
|
281
|
-
msg: `${downloadType} p2p downloadStream success===>`
|
|
282
|
-
}, this.onLogger);
|
|
283
|
-
}, () => {
|
|
284
|
-
logger('error', {
|
|
285
|
-
msg: `${downloadType} p2p downloadStream failed and try reConnect Device===>`
|
|
286
|
-
}, this.onLogger);
|
|
287
|
-
this.removeP2pDownloadEvent();
|
|
288
|
-
this.disconnectDevice().then(() => {
|
|
289
|
-
this.isConnected = false;
|
|
290
|
-
this.isConnecting = false;
|
|
291
|
-
this.connectDevice(() => {
|
|
292
|
-
// 重连之后重新开启文件下载, 这里的成功不需要注册断开事件
|
|
293
|
-
this.startObserverSweeperDataByP2P(this.downloadType, this.devId, this.onReceiveMapData, this.onReceivePathData, this.onReceiveAIPicData, this.onReceiveAIPicHDData);
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
} else if (await this.initFilePath(this.dataFilePath)) {
|
|
298
|
-
await this.downloadFile({
|
|
299
|
-
files: exitFiles
|
|
300
|
-
}, this.albumName, this.dataFilePath);
|
|
301
|
-
}
|
|
302
|
-
this.firstPackageTime = Date.now();
|
|
303
|
-
}
|
|
304
|
-
} else if (this.downloadType === 1) {
|
|
305
|
-
const exitFiles = this.queryNeedFiles(this.file.items);
|
|
306
|
-
// 赋值
|
|
307
|
-
this.exitFiles = exitFiles;
|
|
308
|
-
if (exitFiles.length > 0) {
|
|
309
|
-
if (shouldDownloadStream) {
|
|
310
|
-
// 开启p2p流传输
|
|
311
|
-
await this.downloadStream({
|
|
312
|
-
files: exitFiles
|
|
313
|
-
}, this.albumName, () => {
|
|
314
|
-
logger('info', {
|
|
315
|
-
msg: `${downloadType} p2p downloadStream success===>`
|
|
316
|
-
}, this.onLogger);
|
|
317
|
-
}, () => {
|
|
318
|
-
logger('error', {
|
|
319
|
-
msg: `${downloadType} p2p downloadStream failed and try reConnect Device===>`
|
|
320
|
-
}, this.onLogger);
|
|
321
|
-
this.removeP2pDownloadEvent();
|
|
322
|
-
this.disconnectDevice().then(() => {
|
|
323
|
-
this.isConnected = false;
|
|
324
|
-
this.isConnecting = false;
|
|
325
|
-
this.connectDevice(() => {
|
|
326
|
-
// 重连之后重新开启文件下载, 这里的成功不需要注册断开事件
|
|
327
|
-
this.startObserverSweeperDataByP2P(this.downloadType, this.devId, this.onReceiveMapData, this.onReceivePathData, this.onReceiveAIPicData, this.onReceiveAIPicHDData);
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
} else if (await this.initFilePath(this.streamFilePath)) {
|
|
332
|
-
// 每次要下载前都需要先检查文件目录是否存在 防止中间过程被删除掉文件目录
|
|
333
|
-
await this.downloadFile({
|
|
334
|
-
files: exitFiles
|
|
335
|
-
}, this.albumName, this.streamFilePath);
|
|
336
|
-
}
|
|
337
|
-
this.firstPackageTime = Date.now();
|
|
338
|
-
}
|
|
339
|
-
}
|
|
317
|
+
if (!((_this$file = this.file) !== null && _this$file !== void 0 && (_this$file = _this$file.items) !== null && _this$file !== void 0 && _this$file.length)) {
|
|
318
|
+
return;
|
|
340
319
|
}
|
|
320
|
+
|
|
321
|
+
// 根据 downloadType 选择文件路径
|
|
322
|
+
const filePath = downloadType === 0 ? this.dataFilePath : this.streamFilePath;
|
|
323
|
+
const exitFiles = this.queryNeedFiles(this.file.items);
|
|
324
|
+
this.exitFiles = exitFiles;
|
|
325
|
+
|
|
326
|
+
// 执行下载
|
|
327
|
+
await this.executeDownload(exitFiles, filePath);
|
|
341
328
|
};
|
|
342
329
|
|
|
343
330
|
/**
|
|
@@ -357,9 +344,9 @@ export class SweeperP2p extends P2pApi {
|
|
|
357
344
|
* 注册下载有关的监听
|
|
358
345
|
*/
|
|
359
346
|
registerP2pDownloadEvent = () => {
|
|
360
|
-
|
|
347
|
+
this.log.info({
|
|
361
348
|
msg: 'registerP2pDownloadEvent ==>'
|
|
362
|
-
}
|
|
349
|
+
});
|
|
363
350
|
if (shouldDownloadStream) {
|
|
364
351
|
// p2p数据流监听
|
|
365
352
|
this.offP2pStreamPacketReceive = this.onP2pStreamPacketReceive(this.p2pStreamPacketReceiveCallback);
|
|
@@ -380,29 +367,25 @@ export class SweeperP2p extends P2pApi {
|
|
|
380
367
|
* 移除下载有关的监听
|
|
381
368
|
*/
|
|
382
369
|
removeP2pDownloadEvent = () => {
|
|
383
|
-
|
|
370
|
+
var _this$offFileDownload, _this$offP2pStreamPac;
|
|
371
|
+
this.log.info({
|
|
384
372
|
msg: 'removeP2pDownloadEvent ==>'
|
|
385
|
-
}
|
|
373
|
+
});
|
|
386
374
|
if (shouldDownloadStream) {
|
|
387
|
-
|
|
375
|
+
// 重置所有 Map 的值为初始状态
|
|
376
|
+
FILE_NAMES_TO_INIT.forEach(key => {
|
|
388
377
|
this.packetSerialNumberCacheMap.set(key, -1);
|
|
389
|
-
});
|
|
390
|
-
[...this.fileLengthCacheMap.keys()].forEach(key => {
|
|
391
378
|
this.fileLengthCacheMap.set(key, -1);
|
|
392
|
-
});
|
|
393
|
-
[...this.packetTotalMap.keys()].forEach(key => {
|
|
394
379
|
this.packetTotalMap.set(key, -1);
|
|
395
|
-
});
|
|
396
|
-
[...this.packetDataCacheMap.keys()].forEach(key => {
|
|
397
380
|
this.packetDataCacheMap.set(key, new Map());
|
|
398
381
|
});
|
|
399
382
|
}
|
|
400
383
|
this.cacheData = {};
|
|
401
|
-
this.offFileDownloadComplete
|
|
402
|
-
this.offP2pStreamPacketReceive
|
|
384
|
+
(_this$offFileDownload = this.offFileDownloadComplete) === null || _this$offFileDownload === void 0 || _this$offFileDownload.call(this);
|
|
385
|
+
(_this$offP2pStreamPac = this.offP2pStreamPacketReceive) === null || _this$offP2pStreamPac === void 0 || _this$offP2pStreamPac.call(this);
|
|
403
386
|
|
|
404
|
-
// this.offDownLoadProgressUpdate
|
|
405
|
-
// this.offTotalDownLoadProgressUpdate
|
|
387
|
+
// this.offDownLoadProgressUpdate?.();
|
|
388
|
+
// this.offTotalDownLoadProgressUpdate?.();
|
|
406
389
|
};
|
|
407
390
|
|
|
408
391
|
/**
|
|
@@ -451,15 +434,15 @@ export class SweeperP2p extends P2pApi {
|
|
|
451
434
|
// 因为XXXX_YYYYY会被替换为坐标值,所以这里需要替换一下
|
|
452
435
|
|
|
453
436
|
if (/^aiHD.*\.bin$/.test(fileName)) {
|
|
454
|
-
fileName =
|
|
437
|
+
fileName = FileNameEnum.aiHD;
|
|
455
438
|
} else if (/^aiHD.*\.bin.stream$/.test(fileName)) {
|
|
456
|
-
fileName =
|
|
439
|
+
fileName = FileNameEnum.aiHDStream;
|
|
457
440
|
}
|
|
458
441
|
const cachePacketMap = this.packetDataCacheMap.get(fileName);
|
|
459
442
|
if (!cachePacketMap) {
|
|
460
|
-
|
|
443
|
+
this.log.warn({
|
|
461
444
|
msg: `p2pStreamPacketReceiveCallback: fileName : ${fileName} is not support`
|
|
462
|
-
}
|
|
445
|
+
});
|
|
463
446
|
return;
|
|
464
447
|
}
|
|
465
448
|
const cacheSerialNumber = this.packetSerialNumberCacheMap.get(fileName);
|
|
@@ -493,16 +476,16 @@ export class SweeperP2p extends P2pApi {
|
|
|
493
476
|
}).join('');
|
|
494
477
|
const cacheFileLength = this.fileLengthCacheMap.get(fileName);
|
|
495
478
|
if (cacheFileLength > 0 && hexValue.length !== cacheFileLength * 2) {
|
|
496
|
-
|
|
479
|
+
this.log.warn({
|
|
497
480
|
msg: `p2pStreamPacketReceiveCallback: fileName : ${fileName} length mismatch, expected: ${cacheFileLength * 2}, received: ${hexValue.length}`
|
|
498
|
-
}
|
|
481
|
+
});
|
|
499
482
|
return;
|
|
500
483
|
}
|
|
501
484
|
if (this.firstPackageTime > 0 && fileName.indexOf('map') !== -1) {
|
|
502
485
|
const packageTime = Date.now() - this.firstPackageTime;
|
|
503
|
-
|
|
486
|
+
this.log.info({
|
|
504
487
|
msg: `receive first full package, cost time: ${packageTime} ms, fileName: ${fileName}`
|
|
505
|
-
}
|
|
488
|
+
});
|
|
506
489
|
trace.pointFn({
|
|
507
490
|
devId: this.devId,
|
|
508
491
|
eventName: 'receiveFirstFullPackage'
|
|
@@ -512,25 +495,7 @@ export class SweeperP2p extends P2pApi {
|
|
|
512
495
|
const {
|
|
513
496
|
type
|
|
514
497
|
} = FILE_NAME_MAP[fileName];
|
|
515
|
-
|
|
516
|
-
if (type === 0 || type === 6) {
|
|
517
|
-
this.onReceiveMapData(hexValue);
|
|
518
|
-
this.cacheData[type] = hexValue;
|
|
519
|
-
}
|
|
520
|
-
if (type === 1) {
|
|
521
|
-
logger('info', {
|
|
522
|
-
msg: `push new path data`
|
|
523
|
-
}, this.onLogger);
|
|
524
|
-
this.onReceivePathData(hexValue);
|
|
525
|
-
this.cacheData[type] = hexValue;
|
|
526
|
-
}
|
|
527
|
-
if (type === 4) {
|
|
528
|
-
this.onReceiveAIPicData(hexValue);
|
|
529
|
-
}
|
|
530
|
-
if (type === 5) {
|
|
531
|
-
this.onReceiveAIPicHDData(hexValue);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
498
|
+
this.handleDataByType(type, hexValue);
|
|
534
499
|
}
|
|
535
500
|
}
|
|
536
501
|
};
|
|
@@ -552,83 +517,65 @@ export class SweeperP2p extends P2pApi {
|
|
|
552
517
|
const bytes = Base64.toByteArray(params.data);
|
|
553
518
|
const hexValue = join(map(bytes, d => padStart(d.toString(16), 2, '0')), '');
|
|
554
519
|
const type = this.getFileType(fileName);
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
if (type === 0 || type === 6) {
|
|
563
|
-
this.onReceiveMapData(hexValue);
|
|
564
|
-
}
|
|
565
|
-
if (type === 1) {
|
|
566
|
-
this.onReceivePathData(hexValue);
|
|
567
|
-
}
|
|
568
|
-
if (type === 4) {
|
|
569
|
-
this.onReceiveAIPicData(hexValue);
|
|
570
|
-
}
|
|
571
|
-
if (type === 5) {
|
|
572
|
-
this.onReceiveAIPicHDData(hexValue);
|
|
573
|
-
}
|
|
574
|
-
this.cacheData[type] = hexValue;
|
|
520
|
+
if (hexValue.length === 0) {
|
|
521
|
+
this.log.warn({
|
|
522
|
+
msg: 'receive empty data'
|
|
523
|
+
});
|
|
524
|
+
return;
|
|
575
525
|
}
|
|
526
|
+
this.handleDataByType(type, hexValue);
|
|
576
527
|
},
|
|
577
528
|
fail: e => {
|
|
578
|
-
|
|
529
|
+
this.log.warn({
|
|
579
530
|
msg: 'readFileFromPath failed ==>',
|
|
580
531
|
e
|
|
581
|
-
}
|
|
532
|
+
});
|
|
582
533
|
this.resetReading(fileName);
|
|
583
534
|
}
|
|
584
535
|
});
|
|
585
536
|
} catch (e) {
|
|
586
537
|
this.resetReading(fileName);
|
|
587
|
-
|
|
538
|
+
this.log.error({
|
|
588
539
|
msg: 'readFileFromPath ==>',
|
|
589
540
|
e
|
|
590
|
-
}
|
|
541
|
+
});
|
|
591
542
|
}
|
|
592
543
|
};
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* 根据文件名获取对应的 reading 状态标志
|
|
547
|
+
*/
|
|
548
|
+
getReadingFlag = fileName => {
|
|
549
|
+
if (fileName.includes('map_structured') || fileName.includes('map.')) {
|
|
550
|
+
return 'readingMap';
|
|
598
551
|
}
|
|
599
|
-
if (fileName.
|
|
600
|
-
|
|
601
|
-
this.readingMap = true;
|
|
602
|
-
return true;
|
|
552
|
+
if (fileName.includes('cleanPath')) {
|
|
553
|
+
return 'readingClean';
|
|
603
554
|
}
|
|
604
|
-
if (fileName.
|
|
605
|
-
|
|
606
|
-
this.readingClean = true;
|
|
607
|
-
return true;
|
|
555
|
+
if (fileName.includes('ai.') && !fileName.includes('aiHD')) {
|
|
556
|
+
return 'readingAI';
|
|
608
557
|
}
|
|
609
|
-
if (fileName.
|
|
610
|
-
|
|
611
|
-
this.readingAI = true;
|
|
612
|
-
return true;
|
|
558
|
+
if (fileName.includes('aiHD')) {
|
|
559
|
+
return 'readingHD';
|
|
613
560
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
561
|
+
return null;
|
|
562
|
+
};
|
|
563
|
+
setReading = fileName => {
|
|
564
|
+
const flag = this.getReadingFlag(fileName);
|
|
565
|
+
if (!flag) {
|
|
617
566
|
return true;
|
|
618
567
|
}
|
|
568
|
+
const readingState = this[flag];
|
|
569
|
+
if (readingState) {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
this[flag] = true;
|
|
619
573
|
return true;
|
|
620
574
|
};
|
|
621
575
|
resetReading = fileName => {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
this.readingMap = false;
|
|
626
|
-
} else if (fileName.indexOf('cleanPath') !== -1) {
|
|
627
|
-
this.readingClean = false;
|
|
628
|
-
} else if (fileName.indexOf('ai.') !== -1) {
|
|
629
|
-
this.readingAI = false;
|
|
630
|
-
} else if (fileName.indexOf('aiHD') !== -1) {
|
|
631
|
-
this.readingHD = false;
|
|
576
|
+
const flag = this.getReadingFlag(fileName);
|
|
577
|
+
if (flag) {
|
|
578
|
+
this[flag] = false;
|
|
632
579
|
}
|
|
633
580
|
};
|
|
634
581
|
|
|
@@ -637,21 +584,11 @@ export class SweeperP2p extends P2pApi {
|
|
|
637
584
|
* @param fileList
|
|
638
585
|
*/
|
|
639
586
|
queryNeedFiles = fileList => {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (dataPattern.test(item.filename)) {
|
|
646
|
-
exitFiles.push(item.filename);
|
|
647
|
-
}
|
|
648
|
-
} else if (this.downloadType === 1) {
|
|
649
|
-
if (streamPattern.test(item.filename)) {
|
|
650
|
-
exitFiles.push(item.filename);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
});
|
|
654
|
-
return exitFiles;
|
|
587
|
+
if (!(fileList !== null && fileList !== void 0 && fileList.length)) {
|
|
588
|
+
return [];
|
|
589
|
+
}
|
|
590
|
+
const pattern = this.downloadType === 0 ? /\.bin$/ : /\.bin\.stream$/;
|
|
591
|
+
return fileList.filter(item => pattern.test(item.filename)).map(item => item.filename);
|
|
655
592
|
};
|
|
656
593
|
|
|
657
594
|
/**
|
|
@@ -660,13 +597,13 @@ export class SweeperP2p extends P2pApi {
|
|
|
660
597
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, consistent-return
|
|
661
598
|
stopObserverSweeperDataByP2P = () => {
|
|
662
599
|
try {
|
|
663
|
-
|
|
600
|
+
this.log.info({
|
|
664
601
|
msg: `isConnected: ${this.isConnected}, devId: ${this.devId}`
|
|
665
|
-
}
|
|
602
|
+
});
|
|
666
603
|
if (this.isConnected) {
|
|
667
|
-
|
|
604
|
+
this.log.info({
|
|
668
605
|
msg: `try disconnect device, devId: ${this.devId}`
|
|
669
|
-
}
|
|
606
|
+
});
|
|
670
607
|
this.disconnectDevice();
|
|
671
608
|
}
|
|
672
609
|
this.removeP2pDownloadEvent();
|
|
@@ -677,10 +614,10 @@ export class SweeperP2p extends P2pApi {
|
|
|
677
614
|
typeof this.offSessionStatusChange === 'function' && this.offSessionStatusChange();
|
|
678
615
|
// 销毁初始化时,先进行断连操作
|
|
679
616
|
} catch (e) {
|
|
680
|
-
|
|
617
|
+
this.log.error({
|
|
681
618
|
msg: 'stopObserverSweeperDataByP2P occur error ==>',
|
|
682
619
|
e
|
|
683
|
-
}
|
|
620
|
+
});
|
|
684
621
|
return false;
|
|
685
622
|
}
|
|
686
623
|
};
|