@ray-js/robot-data-stream 0.0.4 → 0.0.5-beta-1

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/README.md CHANGED
@@ -26,36 +26,46 @@ yarn start:tuya
26
26
  ## Usage
27
27
 
28
28
  ```tsx
29
-
30
- import React, { useEffect } from 'react';
29
+ import React from 'react';
31
30
  import { View, Text } from '@ray-js/ray';
32
31
  import { useP2PDataStream, StreamDataNotificationCenter } from '@ray-js/robot-data-stream';
33
32
  import styles from './index.module.less';
34
33
 
35
34
  const DemoBlock = ({ devId }) => {
36
-
37
35
  const onReceiveMapData = (data: string) => {
38
- StreamDataNotificationCenter.emit('receiveMapData', data)
39
- }
40
-
41
- const onReceivePathData = (data:string) => {
42
- StreamDataNotificationCenter.emit('receivePathData', data)
43
- }
44
-
45
-
46
- useEffect(() => {
47
-
48
- useP2PDataStream(devId, onReceiveMapData, onReceivePathData);
49
-
50
- }, []);
36
+ StreamDataNotificationCenter.emit('receiveMapData', data);
37
+ };
38
+
39
+ const onReceivePathData = (data: string) => {
40
+ StreamDataNotificationCenter.emit('receivePathData', data);
41
+ };
42
+
43
+ const onReceiveAIPicData = (data: string) => {
44
+ StreamDataNotificationCenter.emit('receiveAIPicData', data);
45
+ };
46
+
47
+ const onReceiveAIPicHDData = (data: string) => {
48
+ StreamDataNotificationCenter.emit('receiveAIPicHDData', data);
49
+ };
50
+
51
+ const { appendDownloadStreamDuringTask } = useP2PDataStream(
52
+ devId,
53
+ onReceiveMapData,
54
+ onReceivePathData,
55
+ {
56
+ logTag: 'Robot_Stream',
57
+ onReceiveAIPicData,
58
+ onReceiveAIPicHDData
59
+ }
60
+ );
51
61
 
52
62
  return (
53
63
  <View className={styles.demoBlock}>
54
64
  <View className={styles.demoBlockTitle}>
55
65
  <Text className={styles.demoBlockTitleText}>{devId}</Text>
56
66
  </View>
57
- </View>
58
- )
67
+ </View>
68
+ );
59
69
  };
60
70
 
61
71
  export default function Home() {
@@ -65,5 +75,5 @@ export default function Home() {
65
75
  </View>
66
76
  );
67
77
  }
68
- ```
69
78
 
79
+ ```
@@ -1,2 +1,2 @@
1
- import SweeperP2pInstance from "./sweeperP2p";
1
+ import SweeperP2pInstance from './sweeperP2p';
2
2
  export { SweeperP2pInstance };
package/lib/api/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import SweeperP2pInstance from "./sweeperP2p";
1
+ import SweeperP2pInstance from './sweeperP2p';
2
2
  export { SweeperP2pInstance };
@@ -39,6 +39,17 @@ export default class P2pApi {
39
39
  downloadStream: (files: {
40
40
  files: Array<string>;
41
41
  }, albumName: string, successCb?: () => void, failedCb?: () => void) => Promise<unknown> | undefined;
42
+ /**
43
+ * 在下载过程中加入下载文件,需要把之前下载中的文件名也一起带上
44
+ * @param files
45
+ * @param albumName
46
+ * @param successCb
47
+ * @param failedCb
48
+ * @returns
49
+ */
50
+ appendDownloadStream: (files: {
51
+ files: Array<string>;
52
+ }, albumName: string, successCb?: () => void, failedCb?: () => void) => Promise<boolean> | undefined;
42
53
  /**
43
54
  * 监听p2p传输数据流
44
55
  * @param callback
package/lib/api/p2pApi.js CHANGED
@@ -164,6 +164,43 @@ export default class P2pApi {
164
164
  }
165
165
  };
166
166
 
167
+ /**
168
+ * 在下载过程中加入下载文件,需要把之前下载中的文件名也一起带上
169
+ * @param files
170
+ * @param albumName
171
+ * @param successCb
172
+ * @param failedCb
173
+ * @returns
174
+ */
175
+ appendDownloadStream = (files, albumName, successCb, failedCb) => {
176
+ try {
177
+ if (this.isConnected) {
178
+ return new Promise(resolve => {
179
+ p2p.appendDownloadStream({
180
+ deviceId: this.devId,
181
+ albumName: albumName,
182
+ jsonfiles: JSON.stringify(files),
183
+ success: () => {
184
+ log4js.info('p2p appendDownloadStream success');
185
+ typeof successCb === 'function' && successCb();
186
+ resolve(true);
187
+ },
188
+ fail: params => {
189
+ log4js.warn('p2p appendDownloadStream failed ==>', params);
190
+ setTimeout(() => {
191
+ typeof failedCb === 'function' && failedCb();
192
+ }, 500);
193
+ resolve(false);
194
+ },
195
+ complete: () => {}
196
+ });
197
+ });
198
+ }
199
+ } catch (e) {
200
+ log4js.warn('p2p appendDownloadStream occur an error ==>', e);
201
+ }
202
+ };
203
+
167
204
  /**
168
205
  * 监听p2p传输数据流
169
206
  * @param callback
@@ -24,6 +24,18 @@ declare const FILE_NAME_MAP: {
24
24
  readonly 'cleanPath.bin.stream': {
25
25
  readonly type: 1;
26
26
  };
27
+ readonly 'ai.bin': {
28
+ readonly type: 4;
29
+ };
30
+ readonly 'ai.bin.stream': {
31
+ readonly type: 4;
32
+ };
33
+ readonly 'aiHD_XXXX_YYYY.bin': {
34
+ readonly type: 5;
35
+ };
36
+ readonly 'aiHD_XXXX_YYYY.bin.stream': {
37
+ readonly type: 5;
38
+ };
27
39
  };
28
40
  export declare class SweeperP2p extends P2pApi {
29
41
  file: {
@@ -33,24 +45,22 @@ export declare class SweeperP2p extends P2pApi {
33
45
  albumName: string;
34
46
  streamFilePath: string;
35
47
  dataFilePath: string;
36
- mapBinData: string;
37
- navPathBinData: string;
38
- cleanPathBinData: string;
39
- mapBinStream: string;
40
- navPathBinStream: string;
41
- cleanPathBinStream: string;
42
48
  downloadType: number;
43
49
  readingMap: boolean;
44
50
  readingClean: boolean;
45
- readingNav: boolean;
51
+ readingAI: boolean;
52
+ readingHD: boolean;
46
53
  cacheDir: string;
47
54
  fileIndex: number;
48
55
  cacheData: any;
56
+ exitFiles: Array<string>;
49
57
  packetDataCacheMap: Map<keyof typeof FILE_NAME_MAP, Map<number, string>>;
50
58
  packetSerialNumberCacheMap: Map<keyof typeof FILE_NAME_MAP, number>;
51
59
  packetTotalMap: Map<keyof typeof FILE_NAME_MAP, number>;
52
60
  onReceiveMapData: (data: string) => void;
53
61
  onReceivePathData: (data: string) => void;
62
+ onReceiveAIPicData: (data: string) => void;
63
+ onReceiveAIPicHDData: (data: string) => void;
54
64
  offFileDownloadComplete: () => void;
55
65
  offP2pStreamPacketReceive: () => void;
56
66
  offDownLoadProgressUpdate: () => void;
@@ -106,7 +116,15 @@ export declare class SweeperP2p extends P2pApi {
106
116
  * @param downloadType
107
117
  * 0: 下载断开 1: 持续下载
108
118
  */
109
- startObserverSweeperDataByP2P: (downloadType: number, devId: string, onReceiveMapData: (data: string) => void, onReceivePathData: (data: string) => void) => Promise<void>;
119
+ startObserverSweeperDataByP2P: (downloadType: number, devId: string, onReceiveMapData: (data: string) => void, onReceivePathData: (data: string) => void, onReceiveAIPicData?: ((data: string) => void) | undefined, onReceiveAIPicHDData?: ((data: string) => void) | undefined) => Promise<void>;
120
+ /**
121
+ * 在下载过程中继续添加下载文件
122
+ * @param files
123
+ * @param successCb
124
+ * @param failCb
125
+ * @returns
126
+ */
127
+ appendDownloadStreamDuringTask: (files: Array<string>, successCb?: () => void, failCb?: () => void) => Promise<boolean> | void;
110
128
  /**
111
129
  * 注册下载有关的监听
112
130
  */
@@ -1,7 +1,10 @@
1
+ import "core-js/modules/esnext.iterator.constructor.js";
2
+ import "core-js/modules/esnext.iterator.for-each.js";
3
+ import "core-js/modules/esnext.iterator.map.js";
1
4
  /* eslint-disable no-shadow */
2
5
  import P2pApi from './p2pApi';
3
6
  import Base64 from 'base64-js';
4
- import { padStart } from 'lodash-es';
7
+ import { padStart, join, map } from 'lodash-es';
5
8
  import log4js from '@ray-js/log4js';
6
9
  /**
7
10
  * 基于P2p工具类的扫地机扩展实现
@@ -19,6 +22,18 @@ const FILE_NAME_MAP = {
19
22
  },
20
23
  'cleanPath.bin.stream': {
21
24
  type: 1
25
+ },
26
+ 'ai.bin': {
27
+ type: 4
28
+ },
29
+ 'ai.bin.stream': {
30
+ type: 4
31
+ },
32
+ 'aiHD_XXXX_YYYY.bin': {
33
+ type: 5
34
+ },
35
+ 'aiHD_XXXX_YYYY.bin.stream': {
36
+ type: 5
22
37
  }
23
38
  };
24
39
 
@@ -31,20 +46,14 @@ export class SweeperP2p extends P2pApi {
31
46
  this.downloadType = 1;
32
47
  this.fileIndex = -1; // -1 表示所有文件下载完成
33
48
  this.albumName = 'ipc_sweeper_robot';
34
- this.mapBinData = 'map.bin';
35
- this.navPathBinData = 'navPath.bin';
36
- this.cleanPathBinData = 'cleanPath.bin';
37
- this.mapBinStream = 'map.bin.stream';
38
- this.navPathBinStream = 'navPath.bin.stream';
39
- this.cleanPathBinStream = 'cleanPath.bin.stream';
40
49
  this.cacheDir = ty.env.USER_DATA_PATH;
41
50
  this.readingMap = false;
42
51
  this.readingClean = false;
43
- this.readingNav = false;
44
52
  this.cacheData = {};
45
- this.packetTotalMap = new Map([['map.bin', -1], ['cleanPath.bin', -1], ['map.bin.stream', -1], ['cleanPath.bin.stream', -1]]);
46
- this.packetSerialNumberCacheMap = new Map([['map.bin', -1], ['cleanPath.bin', -1], ['map.bin.stream', -1], ['cleanPath.bin.stream', -1]]);
47
- this.packetDataCacheMap = new Map([['map.bin', new Map()], ['cleanPath.bin', new Map()], ['map.bin.stream', new Map()], ['cleanPath.bin.stream', new Map()]]);
53
+ this.exitFiles = [];
54
+ this.packetTotalMap = new Map([['map.bin', -1], ['cleanPath.bin', -1], ['ai.bin', -1], ['aiHD_XXXX_YYYY.bin', -1], ['map.bin.stream', -1], ['cleanPath.bin.stream', -1], ['ai.bin.stream', -1], ['aiHD_XXXX_YYYY.bin.stream', -1]]);
55
+ this.packetSerialNumberCacheMap = new Map([['map.bin', -1], ['cleanPath.bin', -1], ['ai.bin', -1], ['aiHD_XXXX_YYYY.bin', -1], ['map.bin.stream', -1], ['cleanPath.bin.stream', -1], ['ai.bin.stream', -1], ['aiHD_XXXX_YYYY.bin.stream', -1]]);
56
+ this.packetDataCacheMap = new Map([['map.bin', new Map()], ['cleanPath.bin', new Map()], ['ai.bin', new Map()], ['aiHD_XXXX_YYYY.bin', new Map()], ['map.bin.stream', new Map()], ['cleanPath.bin.stream', new Map()], ['ai.bin.stream', new Map()], ['aiHD_XXXX_YYYY.bin.stream', new Map()]]);
48
57
  }
49
58
  setStreamFilePath = () => {
50
59
  // this.streamFilePath = this.cacheDir + `/${this.albumName}/${devId}/stream`;
@@ -96,10 +105,10 @@ export class SweeperP2p extends P2pApi {
96
105
  dirPath: filePath,
97
106
  recursive: true
98
107
  });
99
- console.log('mkdirSync success: filePath ==>', filePath);
108
+ log4js.info('mkdirSync success: filePath ==>', filePath);
100
109
  return true;
101
110
  } catch (e) {
102
- console.log('mkdirSync error ==>', e);
111
+ log4js.error('mkdirSync error ==>', e);
103
112
  return false;
104
113
  }
105
114
  };
@@ -114,11 +123,11 @@ export class SweeperP2p extends P2pApi {
114
123
  ty.getFileSystemManager().access({
115
124
  path: filePath,
116
125
  success(params) {
117
- console.info('file access success ==>', params);
126
+ log4js.info('file access success ==>', params);
118
127
  resolve(true);
119
128
  },
120
129
  fail(params) {
121
- console.info('file access fail ==>', params);
130
+ log4js.warn('file access fail ==>', params);
122
131
  resolve(false);
123
132
  }
124
133
  });
@@ -150,8 +159,11 @@ export class SweeperP2p extends P2pApi {
150
159
  if (filename.indexOf('cleanPath') !== -1) {
151
160
  return 1;
152
161
  }
153
- if (filename.indexOf('navPath') !== -1) {
154
- return 3;
162
+ if (filename.indexOf('ai.') !== -1) {
163
+ return 4;
164
+ }
165
+ if (filename.indexOf('aiHD') !== -1) {
166
+ return 5;
155
167
  }
156
168
  return 2;
157
169
  };
@@ -185,7 +197,7 @@ export class SweeperP2p extends P2pApi {
185
197
  * @param downloadType
186
198
  * 0: 下载断开 1: 持续下载
187
199
  */
188
- startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData) => {
200
+ startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData) => {
189
201
  var _this$file$items;
190
202
  if (![0, 1].some(item => item === downloadType)) {
191
203
  log4js.warn('download type must be 0 or 1');
@@ -193,6 +205,8 @@ export class SweeperP2p extends P2pApi {
193
205
  }
194
206
  this.onReceiveMapData = onReceiveMapData;
195
207
  this.onReceivePathData = onReceivePathData;
208
+ this.onReceiveAIPicData = onReceiveAIPicData || (() => {});
209
+ this.onReceiveAIPicHDData = onReceiveAIPicHDData || (() => {});
196
210
  log4js.info('startObserverSweeperDataByP2P ==>');
197
211
  this.downloadType = downloadType;
198
212
  this.setDataFilePath(devId);
@@ -201,12 +215,14 @@ export class SweeperP2p extends P2pApi {
201
215
  this.removeP2pDownloadEvent();
202
216
  this.registerP2pDownloadEvent();
203
217
  if (!this.file) {
204
- //@ts-ignore
218
+ // @ts-ignore
205
219
  this.file = await this.queryAlbumFileIndexs(this.albumName);
206
220
  }
207
221
  if (this.file && ((_this$file$items = this.file.items) === null || _this$file$items === void 0 ? void 0 : _this$file$items.length) > 0) {
208
222
  if (this.downloadType === 0) {
209
223
  const exitFiles = this.queryNeedFiles(this.file.items);
224
+ // 赋值
225
+ this.exitFiles = exitFiles;
210
226
  if (exitFiles.length > 0) {
211
227
  if (shouldDownloadStream) {
212
228
  // 开启p2p流传输
@@ -221,6 +237,8 @@ export class SweeperP2p extends P2pApi {
221
237
  }
222
238
  } else if (this.downloadType === 1) {
223
239
  const exitFiles = this.queryNeedFiles(this.file.items);
240
+ // 赋值
241
+ this.exitFiles = exitFiles;
224
242
  if (exitFiles.length > 0) {
225
243
  if (shouldDownloadStream) {
226
244
  // 开启p2p流传输
@@ -238,6 +256,19 @@ export class SweeperP2p extends P2pApi {
238
256
  }
239
257
  };
240
258
 
259
+ /**
260
+ * 在下载过程中继续添加下载文件
261
+ * @param files
262
+ * @param successCb
263
+ * @param failCb
264
+ * @returns
265
+ */
266
+ appendDownloadStreamDuringTask = (files, successCb, failCb) => {
267
+ return this.appendDownloadStream({
268
+ files: [...this.exitFiles, ...files]
269
+ }, this.albumName, successCb, failCb);
270
+ };
271
+
241
272
  /**
242
273
  * 注册下载有关的监听
243
274
  */
@@ -306,12 +337,22 @@ export class SweeperP2p extends P2pApi {
306
337
  */
307
338
  p2pStreamPacketReceiveCallback = data => {
308
339
  const {
309
- fileName,
310
340
  packetData,
311
341
  fileSerialNumber,
312
342
  packetIndex,
313
343
  packetType
314
344
  } = data;
345
+ let {
346
+ fileName
347
+ } = data;
348
+
349
+ // 因为XXXX_YYYYY会被替换为坐标值,所以这里需要替换一下
350
+
351
+ if (/^aiHD.*\.bin$/.test(fileName)) {
352
+ fileName = 'aiHD_XXXX_YYYY.bin';
353
+ } else if (/^aiHD.*\.bin.stream$/.test(fileName)) {
354
+ fileName = 'aiHD_XXXX_YYYY.bin.stream';
355
+ }
315
356
  const cachePacketMap = this.packetDataCacheMap.get(fileName);
316
357
  const cacheSerialNumber = this.packetSerialNumberCacheMap.get(fileName);
317
358
 
@@ -351,6 +392,12 @@ export class SweeperP2p extends P2pApi {
351
392
  if (type === 1) {
352
393
  this.onReceivePathData(hexValue);
353
394
  }
395
+ if (type === 4) {
396
+ this.onReceiveAIPicData(hexValue);
397
+ }
398
+ if (type === 5) {
399
+ this.onReceiveAIPicHDData(hexValue);
400
+ }
354
401
  this.cacheData[type] = hexValue;
355
402
  }
356
403
  }
@@ -388,7 +435,7 @@ export class SweeperP2p extends P2pApi {
388
435
  success: params => {
389
436
  this.resetReading(fileName);
390
437
  const bytes = Base64.toByteArray(params.data);
391
- const hexValue = _(bytes).map(d => padStart(d.toString(16), 2, '0')).value().join('');
438
+ const hexValue = join(map(bytes, d => padStart(d.toString(16), 2, '0')), '');
392
439
  const type = this.getFileType(fileName);
393
440
  if (this.cacheData[type] !== hexValue) {
394
441
  if (hexValue.length === 0) {
@@ -401,6 +448,12 @@ export class SweeperP2p extends P2pApi {
401
448
  if (type === 1) {
402
449
  this.onReceivePathData(hexValue);
403
450
  }
451
+ if (type === 4) {
452
+ this.onReceiveAIPicData(hexValue);
453
+ }
454
+ if (type === 5) {
455
+ this.onReceiveAIPicHDData(hexValue);
456
+ }
404
457
  this.cacheData[type] = hexValue;
405
458
  }
406
459
  },
@@ -425,9 +478,14 @@ export class SweeperP2p extends P2pApi {
425
478
  this.readingClean = true;
426
479
  return true;
427
480
  }
428
- if (fileName.indexOf('navPath') !== -1) {
429
- if (this.readingNav === true) return false;
430
- this.readingNav = true;
481
+ if (fileName.indexOf('ai.') !== -1) {
482
+ if (this.readingAI === true) return false;
483
+ this.readingAI = true;
484
+ return true;
485
+ }
486
+ if (fileName.indexOf('aiHD') !== -1) {
487
+ if (this.readingHD === true) return false;
488
+ this.readingHD = true;
431
489
  return true;
432
490
  }
433
491
  return true;
@@ -437,8 +495,10 @@ export class SweeperP2p extends P2pApi {
437
495
  this.readingMap = false;
438
496
  } else if (fileName.indexOf('cleanPath') !== -1) {
439
497
  this.readingClean = false;
440
- } else if (fileName.indexOf('navPath') !== -1) {
441
- this.readingNav = false;
498
+ } else if (fileName.indexOf('ai.') !== -1) {
499
+ this.readingAI = false;
500
+ } else if (fileName.indexOf('aiHD') !== -1) {
501
+ this.readingHD = false;
442
502
  }
443
503
  };
444
504
 
package/lib/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  declare const useP2PDataStream: (devId: string, onReceiveMapData: (data: string) => void, onReceivePathData: (data: string) => void, opt?: {
2
2
  logTag?: string | undefined;
3
- } | undefined) => void;
3
+ onReceiveAIPicData?: ((data: string) => void) | undefined;
4
+ onReceiveAIPicHDData?: ((data: string) => void) | undefined;
5
+ } | undefined) => {
6
+ appendDownloadStreamDuringTask: (files: Array<string>, successCb?: () => void, failedCb?: () => void) => Promise<boolean> | void;
7
+ };
4
8
  declare const StreamDataNotificationCenter: import("mitt").Emitter<Record<import("mitt").EventType, unknown>>;
5
9
  export { useP2PDataStream, StreamDataNotificationCenter };
package/lib/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  /* eslint-disable consistent-return */
2
2
  import { useEffect, useRef } from 'react';
3
3
  import mitt from 'mitt';
4
- import { SweeperP2pInstance } from './api';
5
4
  import log4js from '@ray-js/log4js';
5
+ import { SweeperP2pInstance } from './api';
6
+ import sweeperP2pInstance from './api/sweeperP2p';
6
7
  const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData, opt) => {
7
8
  const {
8
- logTag
9
+ logTag,
10
+ onReceiveAIPicData,
11
+ onReceiveAIPicHDData
9
12
  } = opt || {};
10
13
  const isInit = useRef(null);
11
14
  const offSessionStatusChange = useRef(null);
@@ -37,11 +40,11 @@ const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData, opt) => {
37
40
  if (isInit.current) {
38
41
  SweeperP2pInstance.isConnecting = true;
39
42
  SweeperP2pInstance.connectDevice(() => {
40
- SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData);
43
+ SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData);
41
44
  offSessionStatusChange.current = SweeperP2pInstance.onSessionStatusChange(SweeperP2pInstance.sessionStatusCallback);
42
45
  }, () => {
43
46
  SweeperP2pInstance.reconnectP2p(() => {
44
- SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData);
47
+ SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData);
45
48
  // 这里失败重连需要注册断开重连的事件
46
49
  offSessionStatusChange.current = SweeperP2pInstance.onSessionStatusChange(SweeperP2pInstance.sessionStatusCallback);
47
50
  });
@@ -96,6 +99,9 @@ const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData, opt) => {
96
99
  }
97
100
  });
98
101
  };
102
+ return {
103
+ appendDownloadStreamDuringTask: sweeperP2pInstance.appendDownloadStreamDuringTask
104
+ };
99
105
  };
100
106
  const StreamDataNotificationCenter = mitt();
101
107
  export { useP2PDataStream, StreamDataNotificationCenter };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/robot-data-stream",
3
- "version": "0.0.4",
3
+ "version": "0.0.5-beta-1",
4
4
  "description": "扫地机P2P数据流标准化组件",
5
5
  "main": "lib/index",
6
6
  "files": [