@ray-js/robot-data-stream 0.0.16-beta.3 → 0.0.16-beta.4

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.
@@ -5,8 +5,8 @@ export interface Point {
5
5
  }
6
6
  export interface RoomPreferenceFields {
7
7
  suctions?: string[];
8
- cisterns?: StringOrNumber[];
9
- waterValues?: StringOrNumber[];
8
+ cisterns?: string[];
9
+ waterValues?: number[];
10
10
  cleanCounts?: number[];
11
11
  yMops?: number[];
12
12
  sweepMopModes?: string[];
@@ -1,9 +1,9 @@
1
- import type { BaseResponse, StringOrNumber } from './base';
1
+ import type { BaseResponse } from './base';
2
2
  export interface SetRoomPropertyData {
3
3
  num?: number;
4
4
  ids: number[];
5
5
  suctions?: string[];
6
- cisterns?: StringOrNumber[];
6
+ cisterns?: string[];
7
7
  cleanCounts?: number[];
8
8
  yMops?: number[];
9
9
  sweepMopModes?: string[];
@@ -12,11 +12,11 @@ export interface SetRoomPropertyData {
12
12
  nameLabels?: number[];
13
13
  orders?: number[];
14
14
  routePreferences?: string[];
15
- waterValues?: StringOrNumber[];
15
+ waterValues?: number[];
16
16
  }
17
17
  export interface RoomPropertyResponse extends BaseResponse {
18
18
  suctions?: string[];
19
- cisterns?: StringOrNumber[];
19
+ cisterns?: string[];
20
20
  cleanCounts?: number[];
21
21
  yMops?: number[];
22
22
  sweepMopModes?: string[];
@@ -28,7 +28,7 @@ export interface RoomPropertyResponse extends BaseResponse {
28
28
  nameLabels?: number[];
29
29
  orders?: number[];
30
30
  routePreferences?: string[];
31
- waterValues?: StringOrNumber[];
31
+ waterValues?: number[];
32
32
  }
33
33
  export type TRequestRoomProperty = () => Promise<RoomPropertyResponse>;
34
34
  export type TSetRoomProperty = (data: SetRoomPropertyData) => Promise<RoomPropertyResponse>;
@@ -1,9 +1,9 @@
1
- import type { BaseResponse, StringOrNumber } from './base';
1
+ import type { BaseResponse } from './base';
2
2
  export interface SelectRoomCleanItem {
3
3
  roomId: number;
4
4
  suction?: string;
5
- cistern?: StringOrNumber;
6
- waterValue?: StringOrNumber;
5
+ cistern?: string;
6
+ waterValue?: number;
7
7
  cleanTimes?: number;
8
8
  yMop?: number;
9
9
  sweepMopMode?: string;
@@ -13,8 +13,8 @@ export type SetSelectRoomCleanData = SelectRoomCleanItem[];
13
13
  export interface SelectRoomCleanResponse extends BaseResponse {
14
14
  ids: number[];
15
15
  suctions?: string[];
16
- cisterns?: StringOrNumber[];
17
- waterValues?: StringOrNumber[];
16
+ cisterns?: string[];
17
+ waterValues?: number[];
18
18
  cleanCounts?: number[];
19
19
  yMops?: number[];
20
20
  sweepMopModes?: string[];
@@ -1,4 +1,4 @@
1
- import type { BaseResponse, Point, RoomPreferenceFields, StringOrNumber } from './base';
1
+ import type { BaseResponse, Point, RoomPreferenceFields } from './base';
2
2
  export interface SetSpotCleanData extends RoomPreferenceFields {
3
3
  spots: Point[];
4
4
  origin?: Point;
@@ -6,8 +6,8 @@ export interface SetSpotCleanData extends RoomPreferenceFields {
6
6
  }
7
7
  export interface SpotCleanResponse extends BaseResponse {
8
8
  suctions?: string[];
9
- cisterns?: StringOrNumber[];
10
- waterValues?: StringOrNumber[];
9
+ cisterns?: string[];
10
+ waterValues?: number[];
11
11
  cleanCounts?: number[];
12
12
  yMops?: number[];
13
13
  sweepMopModes?: string[];
@@ -1,12 +1,12 @@
1
- import type { BaseResponse, Point, StringOrNumber } from './base';
1
+ import type { BaseResponse, Point } from './base';
2
2
  export interface ZoneAdvancedConfig {
3
3
  id: number;
4
4
  localSave: number;
5
5
  cleanMode: number;
6
6
  order: number;
7
7
  cleanTimes: number;
8
- suction: number;
9
- cistern: number;
8
+ suction: string;
9
+ cistern: string;
10
10
  }
11
11
  export interface ZoneCleanItem {
12
12
  points: Point[];
@@ -17,8 +17,8 @@ export interface SetZoneCleanData {
17
17
  zones: ZoneCleanItem[];
18
18
  origin: Point;
19
19
  suctions?: string[];
20
- cisterns?: StringOrNumber[];
21
- waterValues?: StringOrNumber[];
20
+ cisterns?: string[];
21
+ waterValues?: number[];
22
22
  cleanCounts?: number[];
23
23
  yMops?: number[];
24
24
  sweepMopModes?: string[];
@@ -28,8 +28,8 @@ export interface ZoneCleanResponse extends BaseResponse {
28
28
  polygons: string[];
29
29
  names?: string[];
30
30
  suctions?: string[];
31
- cisterns?: StringOrNumber[];
32
- waterValues?: StringOrNumber[];
31
+ cisterns?: string[];
32
+ waterValues?: number[];
33
33
  cleanCounts?: number[];
34
34
  yMops?: number[];
35
35
  sweepMopModes?: string[];
@@ -3,7 +3,7 @@ import { useContext } from 'react';
3
3
  import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
4
4
  import { SingletonContext } from './mqttProvider';
5
5
  import { RoomPropertyEnum } from './type';
6
- import { normalizeWaterPreferencePayload } from './waterPreference';
6
+ import { pickWaterFields } from '../utils';
7
7
  /**
8
8
  * 自定义 Hook,用于房间属性管理
9
9
  * @param devId 设备ID(可选,如果不提供则从 MqttProvider Context 获取)
@@ -70,7 +70,7 @@ export const useRoomProperty = () => {
70
70
  orders: data.orders
71
71
  }, data.routePreferences && {
72
72
  routePreferences: data.routePreferences
73
- }), normalizeWaterPreferencePayload(data.cisterns, data.waterValues));
73
+ }), pickWaterFields(len, data.cisterns, data.waterValues));
74
74
  sendStructuredMessage(RoomPropertyEnum.set, sendData, resolve, error => reject(handleMqttError(error, 'Failed to set room property')), RoomPropertyEnum.query // 响应类型是 query,不是 set
75
75
  );
76
76
  } catch (error) {
@@ -6,7 +6,7 @@ import "core-js/modules/esnext.iterator.map.js";
6
6
  import { encodeDeviceTimer0x30 } from '@ray-js/robot-protocol';
7
7
  import { useContext } from 'react';
8
8
  import { CLEAN_MODE_MAP, SUCTION_MAP, ROUTE_PREFERENCE_MAP } from '../constant';
9
- import { normalizeWaterPreferencePayload, resolveWaterLevel } from './waterPreference';
9
+ import { pickWaterFields, resolveWaterLevel } from '../utils';
10
10
  import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
11
11
  import { SingletonContext } from './mqttProvider';
12
12
  import { ScheduleEnum } from './type';
@@ -53,11 +53,12 @@ export const useSchedule = () => {
53
53
  return new Promise((resolve, reject) => {
54
54
  try {
55
55
  const list = message.list.map(item => {
56
+ var _item$ids$length, _item$ids;
56
57
  const {
57
58
  routePreferences
58
59
  } = item,
59
60
  rest = _objectWithoutProperties(item, _excluded);
60
- return _objectSpread(_objectSpread(_objectSpread({}, rest), normalizeWaterPreferencePayload(item.cisterns, item.waterValues)), routePreferences && {
61
+ return _objectSpread(_objectSpread(_objectSpread({}, rest), pickWaterFields((_item$ids$length = (_item$ids = item.ids) === null || _item$ids === void 0 ? void 0 : _item$ids.length) !== null && _item$ids$length !== void 0 ? _item$ids$length : 0, item.cisterns, item.waterValues)), routePreferences && {
61
62
  routePreferences
62
63
  });
63
64
  });
@@ -9,7 +9,7 @@ import { useContext } from 'react';
9
9
  import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
10
10
  import { SingletonContext } from './mqttProvider';
11
11
  import { RoomCleanSetEnum } from './type';
12
- import { normalizeWaterPreferencePayload } from './waterPreference';
12
+ import { pickWaterFields } from '../utils';
13
13
  /**
14
14
  * 自定义 Hook,用于选区清扫
15
15
  * @returns 包含 requestSelectRoomClean 和 setRoomClean 函数的对象
@@ -92,13 +92,10 @@ export const useSelectRoomClean = () => {
92
92
  yMops.push((_room$yMop = room.yMop) !== null && _room$yMop !== void 0 ? _room$yMop : -1);
93
93
  sweepMopModes.push((_room$sweepMopMode = room.sweepMopMode) !== null && _room$sweepMopMode !== void 0 ? _room$sweepMopMode : 'only_sweep');
94
94
  });
95
- const waterPayload = normalizeWaterPreferencePayload(rooms.map(room => {
95
+ const waterPayload = pickWaterFields(rooms.length, rooms.map(room => {
96
96
  var _room$cistern;
97
97
  return (_room$cistern = room.cistern) !== null && _room$cistern !== void 0 ? _room$cistern : '';
98
- }), rooms.map(room => {
99
- var _room$waterValue;
100
- return (_room$waterValue = room.waterValue) !== null && _room$waterValue !== void 0 ? _room$waterValue : '';
101
- }));
98
+ }), rooms.map(room => room.waterValue));
102
99
  sendStructuredMessage(RoomCleanSetEnum.set, _objectSpread(_objectSpread(_objectSpread({
103
100
  ids,
104
101
  suctions
@@ -127,13 +124,10 @@ export const useSelectRoomClean = () => {
127
124
  var _room$suction2;
128
125
  return (_room$suction2 = room.suction) !== null && _room$suction2 !== void 0 ? _room$suction2 : '';
129
126
  });
130
- const waterPayload = normalizeWaterPreferencePayload(rooms.map(room => {
127
+ const waterPayload = pickWaterFields(rooms.length, rooms.map(room => {
131
128
  var _room$cistern2;
132
129
  return (_room$cistern2 = room.cistern) !== null && _room$cistern2 !== void 0 ? _room$cistern2 : '';
133
- }), rooms.map(room => {
134
- var _room$waterValue2;
135
- return (_room$waterValue2 = room.waterValue) !== null && _room$waterValue2 !== void 0 ? _room$waterValue2 : '';
136
- }));
130
+ }), rooms.map(room => room.waterValue));
137
131
  const cleanCounts = rooms.map(room => {
138
132
  var _room$cleanTimes2;
139
133
  return (_room$cleanTimes2 = room.cleanTimes) !== null && _room$cleanTimes2 !== void 0 ? _room$cleanTimes2 : 1;
@@ -6,9 +6,8 @@ import { useContext } from 'react';
6
6
  import { SpotCleanEnum } from './type';
7
7
  import { SingletonContext } from './mqttProvider';
8
8
  import { encodeSpotClean0x16 } from '@ray-js/robot-protocol';
9
- import { pointsToString } from '../utils';
9
+ import { pointsToString, pickWaterFields } from '../utils';
10
10
  import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
11
- import { normalizeWaterPreferencePayload } from './waterPreference';
12
11
  /**
13
12
  * 自定义 Hook,用于定点清扫
14
13
  * @returns 包含 requestSpotClean 和 setSpotClean 函数的对象
@@ -56,7 +55,7 @@ export const useSpotClean = () => {
56
55
  origin
57
56
  } = message;
58
57
  const num = spots.length;
59
- const waterPayload = normalizeWaterPreferencePayload(message.cisterns, message.waterValues);
58
+ const waterPayload = pickWaterFields(num, message.cisterns, message.waterValues);
60
59
  const {
61
60
  suctions = new Array(num).fill(''),
62
61
  cleanCounts = new Array(num).fill(1),
@@ -3,11 +3,10 @@ import "core-js/modules/esnext.iterator.map.js";
3
3
  // 划区清扫
4
4
  import { encodeZoneClean0x3a, requestZoneClean0x3b } from '@ray-js/robot-protocol';
5
5
  import { useContext } from 'react';
6
- import { pointsToString } from '../utils';
6
+ import { pointsToString, pickWaterFields } from '../utils';
7
7
  import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
8
8
  import { SingletonContext } from './mqttProvider';
9
9
  import { ZoneCleanEnum } from './type';
10
- import { normalizeWaterPreferencePayload } from './waterPreference';
11
10
  /**
12
11
  * 自定义 Hook,用于划区清扫
13
12
  * @returns 包含 requestZoneClean 和 setZoneClean 函数的对象
@@ -74,7 +73,7 @@ export const useZoneClean = () => {
74
73
 
75
74
  // 将业务参数转换为协议数据格式
76
75
  const num = zones.length;
77
- const waterPayload = normalizeWaterPreferencePayload(params.cisterns, params.waterValues);
76
+ const waterPayload = pickWaterFields(num, params.cisterns, params.waterValues);
78
77
  const {
79
78
  suctions = new Array(num).fill(''),
80
79
  cleanCounts = new Array(num).fill(1),
@@ -38,3 +38,18 @@ export declare const createLogger: (onLogger?: ((type: 'warn' | 'error' | 'info'
38
38
  */
39
39
  export declare const logP2PDataIfEnabled: (enableCustomLog: boolean, devId: string, event: string, message: string) => void;
40
40
  export declare const getBitValue: (num: number, idx: number) => number;
41
+ /**
42
+ * 将自定义水量 / 标准水量统一归一化为设备命令需要的数值。
43
+ * 优先使用 waterValue,其次回退到 cistern。
44
+ */
45
+ export declare const resolveWaterLevel: (waterValue?: number, cistern?: string, fallback?: number) => number;
46
+ /**
47
+ * 水量字段:有自定义水量(waterValues)时只带 waterValues,否则带 cisterns(缺省按 length 填充 'closed')。
48
+ */
49
+ export declare const pickWaterFields: (length: number, cisterns?: string[], waterValues?: number[]) => {
50
+ waterValues: number[];
51
+ cisterns?: undefined;
52
+ } | {
53
+ cisterns: any[];
54
+ waterValues?: undefined;
55
+ };
@@ -1,7 +1,9 @@
1
+ import "core-js/modules/esnext.iterator.map.js";
1
2
  import mitt from 'mitt';
2
3
  import { floor, join, map } from 'lodash-es';
3
4
  import log4js from '@ray-js/log4js';
4
5
  import { logP2PData as originalLogP2PData } from '@ray-js/robot-custom-log';
6
+ import { CISTERN_MAP } from '../constant';
5
7
  export const emitter = mitt();
6
8
  const pointToString = point => {
7
9
  return `${point.x},${point.y}`;
@@ -19,6 +21,7 @@ export const pointsToString = (points, origin) => {
19
21
  });
20
22
  return join(map(newPoints, pointToString), ',');
21
23
  } catch (e) {
24
+ // eslint-disable-next-line no-console
22
25
  console.error('pointsToString error', e);
23
26
  throw new Error('pointsToString error');
24
27
  }
@@ -96,4 +99,35 @@ export const logP2PDataIfEnabled = (enableCustomLog, devId, event, message) => {
96
99
  }));
97
100
  }
98
101
  };
99
- export const getBitValue = (num, idx) => (num & 1 << idx) >> idx;
102
+
103
+ // eslint-disable-next-line no-bitwise
104
+ export const getBitValue = (num, idx) => (num & 1 << idx) >> idx;
105
+
106
+ /**
107
+ * 将自定义水量 / 标准水量统一归一化为设备命令需要的数值。
108
+ * 优先使用 waterValue,其次回退到 cistern。
109
+ */
110
+ export const resolveWaterLevel = function (waterValue, cistern) {
111
+ let fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CISTERN_MAP.closed;
112
+ if (waterValue != null && Number.isFinite(waterValue)) {
113
+ return waterValue;
114
+ }
115
+ if (cistern && cistern in CISTERN_MAP) {
116
+ return CISTERN_MAP[cistern];
117
+ }
118
+ return fallback;
119
+ };
120
+
121
+ /**
122
+ * 水量字段:有自定义水量(waterValues)时只带 waterValues,否则带 cisterns(缺省按 length 填充 'closed')。
123
+ */
124
+ export const pickWaterFields = (length, cisterns, waterValues) => {
125
+ if (waterValues !== null && waterValues !== void 0 && waterValues.length) {
126
+ return {
127
+ waterValues
128
+ };
129
+ }
130
+ return {
131
+ cisterns: cisterns ? cisterns.map(v => v == null ? 'closed' : v) : new Array(length).fill('closed')
132
+ };
133
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/robot-data-stream",
3
- "version": "0.0.16-beta.3",
3
+ "version": "0.0.16-beta.4",
4
4
  "description": "扫地机P2P数据流标准化组件",
5
5
  "main": "lib/index",
6
6
  "files": [
@@ -1,20 +0,0 @@
1
- export type WaterPreferenceValue = string | number;
2
- /**
3
- * 将自定义水量 / 标准水量统一归一化为设备命令需要的数值。
4
- * 优先使用 waterValue,其次回退到 cistern。
5
- */
6
- export declare const resolveWaterLevel: (waterValue?: WaterPreferenceValue, cistern?: WaterPreferenceValue, fallback?: number) => number;
7
- export declare const hasPreferenceValue: (value?: WaterPreferenceValue | null) => boolean;
8
- /**
9
- * MQTT 水量相关字段是可选的。
10
- * 当数组里全是空字符串时,认为该字段未设置,避免把空 cisterns/waterValues 发给设备。
11
- */
12
- export declare const normalizeOptionalPreferenceArray: <T extends WaterPreferenceValue>(values?: T[] | undefined) => T[] | undefined;
13
- /**
14
- * 自定义水量优先于旧 cistern 水量。
15
- * 当某一项存在自定义水量时,同位置的 cistern 会被清空;最终空数组字段会被省略。
16
- */
17
- export declare const normalizeWaterPreferencePayload: (cisterns?: WaterPreferenceValue[], waterValues?: WaterPreferenceValue[]) => {
18
- cisterns?: WaterPreferenceValue[] | undefined;
19
- waterValues?: WaterPreferenceValue[] | undefined;
20
- };
@@ -1,70 +0,0 @@
1
- import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import "core-js/modules/esnext.iterator.constructor.js";
3
- import "core-js/modules/esnext.iterator.some.js";
4
- import { CISTERN_MAP } from '../constant';
5
- /**
6
- * 将自定义水量 / 标准水量统一归一化为设备命令需要的数值。
7
- * 优先使用 waterValue,其次回退到 cistern。
8
- */
9
- export const resolveWaterLevel = function (waterValue, cistern) {
10
- var _ref, _resolveValue;
11
- let fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CISTERN_MAP.closed;
12
- const resolveValue = value => {
13
- if (typeof value === 'number' && Number.isFinite(value)) {
14
- return value;
15
- }
16
- if (typeof value !== 'string') {
17
- return undefined;
18
- }
19
- if (value in CISTERN_MAP) {
20
- return CISTERN_MAP[value];
21
- }
22
- const parsed = Number(value);
23
- return Number.isFinite(parsed) ? parsed : undefined;
24
- };
25
- return (_ref = (_resolveValue = resolveValue(waterValue)) !== null && _resolveValue !== void 0 ? _resolveValue : resolveValue(cistern)) !== null && _ref !== void 0 ? _ref : fallback;
26
- };
27
- export const hasPreferenceValue = value => value !== '' && value !== null && value !== undefined;
28
-
29
- /**
30
- * MQTT 水量相关字段是可选的。
31
- * 当数组里全是空字符串时,认为该字段未设置,避免把空 cisterns/waterValues 发给设备。
32
- */
33
- export const normalizeOptionalPreferenceArray = values => {
34
- if (!values) {
35
- return undefined;
36
- }
37
- return values.some(hasPreferenceValue) ? values : undefined;
38
- };
39
-
40
- /**
41
- * 自定义水量优先于旧 cistern 水量。
42
- * 当某一项存在自定义水量时,同位置的 cistern 会被清空;最终空数组字段会被省略。
43
- */
44
- export const normalizeWaterPreferencePayload = (cisterns, waterValues) => {
45
- var _cisterns$length, _waterValues$length;
46
- const maxLength = Math.max((_cisterns$length = cisterns === null || cisterns === void 0 ? void 0 : cisterns.length) !== null && _cisterns$length !== void 0 ? _cisterns$length : 0, (_waterValues$length = waterValues === null || waterValues === void 0 ? void 0 : waterValues.length) !== null && _waterValues$length !== void 0 ? _waterValues$length : 0);
47
- if (maxLength === 0) {
48
- return {};
49
- }
50
- const normalizedCisterns = normalizeOptionalPreferenceArray(Array.from({
51
- length: maxLength
52
- }, (_, index) => {
53
- var _cisterns$index;
54
- if (hasPreferenceValue(waterValues === null || waterValues === void 0 ? void 0 : waterValues[index])) {
55
- return '';
56
- }
57
- return (_cisterns$index = cisterns === null || cisterns === void 0 ? void 0 : cisterns[index]) !== null && _cisterns$index !== void 0 ? _cisterns$index : '';
58
- }));
59
- const normalizedWaterValues = normalizeOptionalPreferenceArray(Array.from({
60
- length: maxLength
61
- }, (_, index) => {
62
- var _waterValues$index;
63
- return (_waterValues$index = waterValues === null || waterValues === void 0 ? void 0 : waterValues[index]) !== null && _waterValues$index !== void 0 ? _waterValues$index : '';
64
- }));
65
- return _objectSpread(_objectSpread({}, normalizedCisterns ? {
66
- cisterns: normalizedCisterns
67
- } : {}), normalizedWaterValues ? {
68
- waterValues: normalizedWaterValues
69
- } : {});
70
- };