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