@ray-js/robot-data-stream 0.0.2 → 0.0.3

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,43 @@ 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
+ onReceiveAIPicData,
56
+ onReceiveAIPicHDData
57
+ );
51
58
 
52
59
  return (
53
60
  <View className={styles.demoBlock}>
54
61
  <View className={styles.demoBlockTitle}>
55
62
  <Text className={styles.demoBlockTitleText}>{devId}</Text>
56
63
  </View>
57
- </View>
58
- )
64
+ </View>
65
+ );
59
66
  };
60
67
 
61
68
  export default function Home() {
@@ -65,5 +72,5 @@ export default function Home() {
65
72
  </View>
66
73
  );
67
74
  }
68
- ```
69
75
 
76
+ ```
@@ -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,7 @@
1
1
  /* eslint-disable no-shadow */
2
2
  import P2pApi from './p2pApi';
3
3
  import Base64 from 'base64-js';
4
- import { padStart } from 'lodash-es';
4
+ import { padStart, join, map } from 'lodash-es';
5
5
  import log4js from '@ray-js/log4js';
6
6
  /**
7
7
  * 基于P2p工具类的扫地机扩展实现
@@ -19,6 +19,18 @@ const FILE_NAME_MAP = {
19
19
  },
20
20
  'cleanPath.bin.stream': {
21
21
  type: 1
22
+ },
23
+ 'ai.bin': {
24
+ type: 4
25
+ },
26
+ 'ai.bin.stream': {
27
+ type: 4
28
+ },
29
+ 'aiHD_XXXX_YYYY.bin': {
30
+ type: 5
31
+ },
32
+ 'aiHD_XXXX_YYYY.bin.stream': {
33
+ type: 5
22
34
  }
23
35
  };
24
36
 
@@ -31,20 +43,14 @@ export class SweeperP2p extends P2pApi {
31
43
  this.downloadType = 1;
32
44
  this.fileIndex = -1; // -1 表示所有文件下载完成
33
45
  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
46
  this.cacheDir = ty.env.USER_DATA_PATH;
41
47
  this.readingMap = false;
42
48
  this.readingClean = false;
43
- this.readingNav = false;
44
49
  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()]]);
50
+ this.exitFiles = [];
51
+ 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]]);
52
+ 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]]);
53
+ 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
54
  }
49
55
  setStreamFilePath = () => {
50
56
  // this.streamFilePath = this.cacheDir + `/${this.albumName}/${devId}/stream`;
@@ -96,10 +102,10 @@ export class SweeperP2p extends P2pApi {
96
102
  dirPath: filePath,
97
103
  recursive: true
98
104
  });
99
- console.log('mkdirSync success: filePath ==>', filePath);
105
+ log4js.info('mkdirSync success: filePath ==>', filePath);
100
106
  return true;
101
107
  } catch (e) {
102
- console.log('mkdirSync error ==>', e);
108
+ log4js.error('mkdirSync error ==>', e);
103
109
  return false;
104
110
  }
105
111
  };
@@ -114,11 +120,11 @@ export class SweeperP2p extends P2pApi {
114
120
  ty.getFileSystemManager().access({
115
121
  path: filePath,
116
122
  success(params) {
117
- console.info('file access success ==>', params);
123
+ log4js.info('file access success ==>', params);
118
124
  resolve(true);
119
125
  },
120
126
  fail(params) {
121
- console.info('file access fail ==>', params);
127
+ log4js.warn('file access fail ==>', params);
122
128
  resolve(false);
123
129
  }
124
130
  });
@@ -150,8 +156,11 @@ export class SweeperP2p extends P2pApi {
150
156
  if (filename.indexOf('cleanPath') !== -1) {
151
157
  return 1;
152
158
  }
153
- if (filename.indexOf('navPath') !== -1) {
154
- return 3;
159
+ if (filename.indexOf('ai.') !== -1) {
160
+ return 4;
161
+ }
162
+ if (filename.indexOf('aiHD') !== -1) {
163
+ return 5;
155
164
  }
156
165
  return 2;
157
166
  };
@@ -185,7 +194,7 @@ export class SweeperP2p extends P2pApi {
185
194
  * @param downloadType
186
195
  * 0: 下载断开 1: 持续下载
187
196
  */
188
- startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData) => {
197
+ startObserverSweeperDataByP2P = async (downloadType, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData) => {
189
198
  var _this$file$items;
190
199
  if (![0, 1].some(item => item === downloadType)) {
191
200
  log4js.warn('download type must be 0 or 1');
@@ -193,6 +202,8 @@ export class SweeperP2p extends P2pApi {
193
202
  }
194
203
  this.onReceiveMapData = onReceiveMapData;
195
204
  this.onReceivePathData = onReceivePathData;
205
+ this.onReceiveAIPicData = onReceiveAIPicData || (() => {});
206
+ this.onReceiveAIPicHDData = onReceiveAIPicHDData || (() => {});
196
207
  log4js.info('startObserverSweeperDataByP2P ==>');
197
208
  this.downloadType = downloadType;
198
209
  this.setDataFilePath(devId);
@@ -201,12 +212,14 @@ export class SweeperP2p extends P2pApi {
201
212
  this.removeP2pDownloadEvent();
202
213
  this.registerP2pDownloadEvent();
203
214
  if (!this.file) {
204
- //@ts-ignore
215
+ // @ts-ignore
205
216
  this.file = await this.queryAlbumFileIndexs(this.albumName);
206
217
  }
207
218
  if (this.file && ((_this$file$items = this.file.items) === null || _this$file$items === void 0 ? void 0 : _this$file$items.length) > 0) {
208
219
  if (this.downloadType === 0) {
209
220
  const exitFiles = this.queryNeedFiles(this.file.items);
221
+ // 赋值
222
+ this.exitFiles = exitFiles;
210
223
  if (exitFiles.length > 0) {
211
224
  if (shouldDownloadStream) {
212
225
  // 开启p2p流传输
@@ -221,6 +234,8 @@ export class SweeperP2p extends P2pApi {
221
234
  }
222
235
  } else if (this.downloadType === 1) {
223
236
  const exitFiles = this.queryNeedFiles(this.file.items);
237
+ // 赋值
238
+ this.exitFiles = exitFiles;
224
239
  if (exitFiles.length > 0) {
225
240
  if (shouldDownloadStream) {
226
241
  // 开启p2p流传输
@@ -238,6 +253,19 @@ export class SweeperP2p extends P2pApi {
238
253
  }
239
254
  };
240
255
 
256
+ /**
257
+ * 在下载过程中继续添加下载文件
258
+ * @param files
259
+ * @param successCb
260
+ * @param failCb
261
+ * @returns
262
+ */
263
+ appendDownloadStreamDuringTask = (files, successCb, failCb) => {
264
+ return this.appendDownloadStream({
265
+ files: [...this.exitFiles, ...files]
266
+ }, this.albumName, successCb, failCb);
267
+ };
268
+
241
269
  /**
242
270
  * 注册下载有关的监听
243
271
  */
@@ -306,12 +334,22 @@ export class SweeperP2p extends P2pApi {
306
334
  */
307
335
  p2pStreamPacketReceiveCallback = data => {
308
336
  const {
309
- fileName,
310
337
  packetData,
311
338
  fileSerialNumber,
312
339
  packetIndex,
313
340
  packetType
314
341
  } = data;
342
+ let {
343
+ fileName
344
+ } = data;
345
+
346
+ // 因为XXXX_YYYYY会被替换为坐标值,所以这里需要替换一下
347
+
348
+ if (/^aiHD.*\.bin$/.test(fileName)) {
349
+ fileName = 'aiHD_XXXX_YYYY.bin';
350
+ } else if (/^aiHD.*\.bin.stream$/.test(fileName)) {
351
+ fileName = 'aiHD_XXXX_YYYY.bin.stream';
352
+ }
315
353
  const cachePacketMap = this.packetDataCacheMap.get(fileName);
316
354
  const cacheSerialNumber = this.packetSerialNumberCacheMap.get(fileName);
317
355
 
@@ -351,6 +389,12 @@ export class SweeperP2p extends P2pApi {
351
389
  if (type === 1) {
352
390
  this.onReceivePathData(hexValue);
353
391
  }
392
+ if (type === 4) {
393
+ this.onReceiveAIPicData(hexValue);
394
+ }
395
+ if (type === 5) {
396
+ this.onReceiveAIPicHDData(hexValue);
397
+ }
354
398
  this.cacheData[type] = hexValue;
355
399
  }
356
400
  }
@@ -388,7 +432,7 @@ export class SweeperP2p extends P2pApi {
388
432
  success: params => {
389
433
  this.resetReading(fileName);
390
434
  const bytes = Base64.toByteArray(params.data);
391
- const hexValue = _(bytes).map(d => padStart(d.toString(16), 2, '0')).value().join('');
435
+ const hexValue = join(map(bytes, d => padStart(d.toString(16), 2, '0')), '');
392
436
  const type = this.getFileType(fileName);
393
437
  if (this.cacheData[type] !== hexValue) {
394
438
  if (hexValue.length === 0) {
@@ -401,6 +445,12 @@ export class SweeperP2p extends P2pApi {
401
445
  if (type === 1) {
402
446
  this.onReceivePathData(hexValue);
403
447
  }
448
+ if (type === 4) {
449
+ this.onReceiveAIPicData(hexValue);
450
+ }
451
+ if (type === 5) {
452
+ this.onReceiveAIPicHDData(hexValue);
453
+ }
404
454
  this.cacheData[type] = hexValue;
405
455
  }
406
456
  },
@@ -425,9 +475,14 @@ export class SweeperP2p extends P2pApi {
425
475
  this.readingClean = true;
426
476
  return true;
427
477
  }
428
- if (fileName.indexOf('navPath') !== -1) {
429
- if (this.readingNav === true) return false;
430
- this.readingNav = true;
478
+ if (fileName.indexOf('ai.') !== -1) {
479
+ if (this.readingAI === true) return false;
480
+ this.readingAI = true;
481
+ return true;
482
+ }
483
+ if (fileName.indexOf('aiHD') !== -1) {
484
+ if (this.readingHD === true) return false;
485
+ this.readingHD = true;
431
486
  return true;
432
487
  }
433
488
  return true;
@@ -437,8 +492,10 @@ export class SweeperP2p extends P2pApi {
437
492
  this.readingMap = false;
438
493
  } else if (fileName.indexOf('cleanPath') !== -1) {
439
494
  this.readingClean = false;
440
- } else if (fileName.indexOf('navPath') !== -1) {
441
- this.readingNav = false;
495
+ } else if (fileName.indexOf('ai.') !== -1) {
496
+ this.readingAI = false;
497
+ } else if (fileName.indexOf('aiHD') !== -1) {
498
+ this.readingHD = false;
442
499
  }
443
500
  };
444
501
 
package/lib/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- declare const useP2PDataStream: (devId: string, onReceiveMapData: (data: string) => void, onReceivePathData: (data: string) => void) => void;
1
+ declare const useP2PDataStream: (devId: string, onReceiveMapData: (data: string) => void, onReceivePathData: (data: string) => void, onReceiveAIPicData?: ((data: string) => void) | undefined, onReceiveAIPicHDData?: ((data: string) => void) | undefined) => {
2
+ appendDownloadStreamDuringTask: (files: Array<string>, successCb?: () => void, failedCb?: () => void) => Promise<boolean> | void;
3
+ };
2
4
  declare const StreamDataNotificationCenter: import("mitt").Emitter<Record<import("mitt").EventType, unknown>>;
3
5
  export { useP2PDataStream, StreamDataNotificationCenter };
package/lib/index.js CHANGED
@@ -2,7 +2,8 @@ import { useEffect, useRef } from 'react';
2
2
  import mitt from 'mitt';
3
3
  import { SweeperP2pInstance } from './api';
4
4
  import log4js from '@ray-js/log4js';
5
- const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData) => {
5
+ import sweeperP2pInstance from './api/sweeperP2p';
6
+ const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData) => {
6
7
  const isInit = useRef(null);
7
8
  const offSessionStatusChange = useRef(null);
8
9
  const isAppOnBackground = useRef(false);
@@ -30,11 +31,11 @@ const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData) => {
30
31
  if (isInit.current) {
31
32
  SweeperP2pInstance.isConnecting = true;
32
33
  SweeperP2pInstance.connectDevice(() => {
33
- SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData);
34
+ SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData);
34
35
  offSessionStatusChange.current = SweeperP2pInstance.onSessionStatusChange(SweeperP2pInstance.sessionStatusCallback);
35
36
  }, () => {
36
37
  SweeperP2pInstance.reconnectP2p(() => {
37
- SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData);
38
+ SweeperP2pInstance.startObserverSweeperDataByP2P(1, devId, onReceiveMapData, onReceivePathData, onReceiveAIPicData, onReceiveAIPicHDData);
38
39
  // 这里失败重连需要注册断开重连的事件
39
40
  offSessionStatusChange.current = SweeperP2pInstance.onSessionStatusChange(SweeperP2pInstance.sessionStatusCallback);
40
41
  });
@@ -89,6 +90,9 @@ const useP2PDataStream = (devId, onReceiveMapData, onReceivePathData) => {
89
90
  }
90
91
  });
91
92
  };
93
+ return {
94
+ appendDownloadStreamDuringTask: sweeperP2pInstance.appendDownloadStreamDuringTask
95
+ };
92
96
  };
93
97
  const StreamDataNotificationCenter = mitt();
94
98
  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.2",
3
+ "version": "0.0.3",
4
4
  "description": "扫地机P2P数据流标准化组件",
5
5
  "main": "lib/index",
6
6
  "files": [
@@ -34,7 +34,7 @@
34
34
  "@ray-js/ray": "^1.5.0"
35
35
  },
36
36
  "dependencies": {
37
- "@ray-js/log4js": "^0.0.2",
37
+ "@ray-js/log4js": "^0.0.3",
38
38
  "clsx": "^1.2.1",
39
39
  "lodash-es": "^4.17.21",
40
40
  "mitt": "^3.0.1",