@ray-js/robot-data-stream 0.0.16-beta.2 → 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.
- package/lib/mqtt/hooks/useStructuredMessage.d.ts +2 -7
- package/lib/mqtt/hooks/useStructuredMessage.js +1 -1
- package/lib/mqtt/type/index.d.ts +0 -12
- package/lib/mqtt/type/index.js +0 -14
- package/lib/mqtt/type/protocols/base.d.ts +23 -24
- package/lib/mqtt/type/protocols/base.js +1 -38
- package/lib/mqtt/type/protocols/carpetCleanProtocol.d.ts +6 -13
- package/lib/mqtt/type/protocols/carpetCleanProtocol.js +1 -14
- package/lib/mqtt/type/protocols/carpetProtocol.d.ts +52 -96
- package/lib/mqtt/type/protocols/carpetProtocol.js +1 -202
- package/lib/mqtt/type/protocols/devInfoProtocol.d.ts +5 -11
- package/lib/mqtt/type/protocols/devInfoProtocol.js +1 -10
- package/lib/mqtt/type/protocols/deviceModelProtocol.d.ts +14 -29
- package/lib/mqtt/type/protocols/deviceModelProtocol.js +1 -32
- package/lib/mqtt/type/protocols/furnitureModelProtocol.d.ts +15 -25
- package/lib/mqtt/type/protocols/furnitureModelProtocol.js +1 -27
- package/lib/mqtt/type/protocols/historyMapProtocol.d.ts +19 -36
- package/lib/mqtt/type/protocols/historyMapProtocol.js +1 -37
- package/lib/mqtt/type/protocols/partDivisionProtocol.d.ts +6 -20
- package/lib/mqtt/type/protocols/partDivisionProtocol.js +1 -12
- package/lib/mqtt/type/protocols/partMergeProtocol.d.ts +3 -12
- package/lib/mqtt/type/protocols/partMergeProtocol.js +1 -12
- package/lib/mqtt/type/protocols/passwordProtocol.d.ts +11 -21
- package/lib/mqtt/type/protocols/passwordProtocol.js +1 -25
- package/lib/mqtt/type/protocols/quietHoursProtocol.d.ts +17 -27
- package/lib/mqtt/type/protocols/quietHoursProtocol.js +1 -35
- package/lib/mqtt/type/protocols/resetMapProtocol.d.ts +2 -3
- package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +32 -46
- package/lib/mqtt/type/protocols/roomPropertyProtocol.js +1 -134
- package/lib/mqtt/type/protocols/scheduleProtocol.d.ts +18 -69
- package/lib/mqtt/type/protocols/scheduleProtocol.js +1 -117
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +22 -29
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.js +1 -48
- package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +18 -42
- package/lib/mqtt/type/protocols/spotCleanProtocol.js +1 -94
- package/lib/mqtt/type/protocols/virtualAreaProtocol.d.ts +17 -30
- package/lib/mqtt/type/protocols/virtualAreaProtocol.js +1 -36
- package/lib/mqtt/type/protocols/virtualWallProtocol.d.ts +11 -25
- package/lib/mqtt/type/protocols/virtualWallProtocol.js +1 -25
- package/lib/mqtt/type/protocols/voiceProtocol.d.ts +11 -19
- package/lib/mqtt/type/protocols/voiceProtocol.js +1 -23
- package/lib/mqtt/type/protocols/wifiMapProtocol.d.ts +6 -15
- package/lib/mqtt/type/protocols/wifiMapProtocol.js +1 -15
- package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +37 -50
- package/lib/mqtt/type/protocols/zoneCleanProtocol.js +1 -76
- package/lib/mqtt/useCarpet.js +21 -35
- package/lib/mqtt/useCarpetClean.js +1 -4
- package/lib/mqtt/useDeviceModel.js +1 -4
- package/lib/mqtt/useFurnitureModel.js +1 -4
- package/lib/mqtt/useHistoryMap.js +8 -21
- package/lib/mqtt/usePartDivision.js +6 -20
- package/lib/mqtt/usePartMerge.js +1 -3
- package/lib/mqtt/usePassword.js +2 -9
- package/lib/mqtt/useQuiteHours.js +1 -4
- package/lib/mqtt/useRoomProperty.js +3 -7
- package/lib/mqtt/useSchedule.js +8 -12
- package/lib/mqtt/useSelectRoomClean.js +6 -14
- package/lib/mqtt/useSpotClean.js +4 -10
- package/lib/mqtt/useVirtualArea.js +1 -4
- package/lib/mqtt/useVirtualWall.js +1 -4
- package/lib/mqtt/useVoice.js +4 -7
- package/lib/mqtt/useWifiMap.js +1 -5
- package/lib/mqtt/useZoneClean.js +10 -15
- package/lib/utils/index.d.ts +15 -0
- package/lib/utils/index.js +35 -1
- package/package.json +1 -1
- package/lib/mqtt/type/fun.d.ts +0 -248
- package/lib/mqtt/type/fun.js +0 -146
- package/lib/mqtt/waterPreference.d.ts +0 -20
- package/lib/mqtt/waterPreference.js +0 -70
- package/lib/myLib/zod/mini/index.d.cts +0 -1
- package/lib/myLib/zod/mini/index.d.ts +0 -1
- package/lib/myLib/zod/mini/index.js +0 -1
- package/lib/myLib/zod/mini/package.json +0 -6
- package/lib/myLib/zod/src/mini/index.d.ts +0 -1
- package/lib/myLib/zod/src/mini/index.js +0 -1
- package/lib/myLib/zod/src/v4/core/api.d.ts +0 -306
- package/lib/myLib/zod/src/v4/core/api.js +0 -1256
- package/lib/myLib/zod/src/v4/core/checks.d.ts +0 -278
- package/lib/myLib/zod/src/v4/core/checks.js +0 -816
- package/lib/myLib/zod/src/v4/core/config.d.ts +0 -9
- package/lib/myLib/zod/src/v4/core/config.js +0 -5
- package/lib/myLib/zod/src/v4/core/core.d.ts +0 -70
- package/lib/myLib/zod/src/v4/core/core.js +0 -95
- package/lib/myLib/zod/src/v4/core/doc.d.ts +0 -14
- package/lib/myLib/zod/src/v4/core/doc.js +0 -42
- package/lib/myLib/zod/src/v4/core/errors.d.ts +0 -220
- package/lib/myLib/zod/src/v4/core/errors.js +0 -232
- package/lib/myLib/zod/src/v4/core/index.d.ts +0 -15
- package/lib/myLib/zod/src/v4/core/index.js +0 -15
- package/lib/myLib/zod/src/v4/core/json-schema-generator.d.ts +0 -65
- package/lib/myLib/zod/src/v4/core/json-schema-generator.js +0 -120
- package/lib/myLib/zod/src/v4/core/json-schema-processors.d.ts +0 -49
- package/lib/myLib/zod/src/v4/core/json-schema-processors.js +0 -593
- package/lib/myLib/zod/src/v4/core/json-schema.d.ts +0 -88
- package/lib/myLib/zod/src/v4/core/json-schema.js +0 -1
- package/lib/myLib/zod/src/v4/core/parse.d.ts +0 -49
- package/lib/myLib/zod/src/v4/core/parse.js +0 -147
- package/lib/myLib/zod/src/v4/core/regexes.d.ts +0 -78
- package/lib/myLib/zod/src/v4/core/regexes.js +0 -146
- package/lib/myLib/zod/src/v4/core/registries.d.ts +0 -35
- package/lib/myLib/zod/src/v4/core/registries.js +0 -51
- package/lib/myLib/zod/src/v4/core/schemas.d.ts +0 -1136
- package/lib/myLib/zod/src/v4/core/schemas.js +0 -2745
- package/lib/myLib/zod/src/v4/core/standard-schema.d.ts +0 -126
- package/lib/myLib/zod/src/v4/core/standard-schema.js +0 -1
- package/lib/myLib/zod/src/v4/core/to-json-schema.d.ts +0 -114
- package/lib/myLib/zod/src/v4/core/to-json-schema.js +0 -488
- package/lib/myLib/zod/src/v4/core/util.d.ts +0 -199
- package/lib/myLib/zod/src/v4/core/util.js +0 -656
- package/lib/myLib/zod/src/v4/core/versions.d.ts +0 -5
- package/lib/myLib/zod/src/v4/core/versions.js +0 -5
- package/lib/myLib/zod/src/v4/core/zsf.d.ts +0 -91
- package/lib/myLib/zod/src/v4/core/zsf.js +0 -1
- package/lib/myLib/zod/src/v4/mini/checks.d.ts +0 -1
- package/lib/myLib/zod/src/v4/mini/checks.js +0 -1
- package/lib/myLib/zod/src/v4/mini/coerce.d.ts +0 -7
- package/lib/myLib/zod/src/v4/mini/coerce.js +0 -27
- package/lib/myLib/zod/src/v4/mini/external.d.ts +0 -11
- package/lib/myLib/zod/src/v4/mini/external.js +0 -16
- package/lib/myLib/zod/src/v4/mini/index.d.ts +0 -530
- package/lib/myLib/zod/src/v4/mini/index.js +0 -30
- package/lib/myLib/zod/src/v4/mini/iso.d.ts +0 -22
- package/lib/myLib/zod/src/v4/mini/iso.js +0 -46
- package/lib/myLib/zod/src/v4/mini/parse.d.ts +0 -1
- package/lib/myLib/zod/src/v4/mini/parse.js +0 -1
- package/lib/myLib/zod/src/v4/mini/schemas.js +0 -1244
|
@@ -4,7 +4,6 @@ import { DeleteMapEnum, SaveCurrentMapEnum, UseMapEnum } from './type';
|
|
|
4
4
|
import { SingletonContext } from './mqttProvider';
|
|
5
5
|
import { encodeDeleteMap0x2c, encodeSaveMap0x2a, encodeUseMap0x2e } from '@ray-js/robot-protocol';
|
|
6
6
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
7
|
-
import { validator } from './type/fun';
|
|
8
7
|
/**
|
|
9
8
|
* 自定义 Hook,用于管理历史地图
|
|
10
9
|
* @returns 包含删除历史地图、更改当前地图和保存地图的函数
|
|
@@ -45,16 +44,10 @@ export const useHistoryMap = () => {
|
|
|
45
44
|
return new Promise((resolve, reject) => {
|
|
46
45
|
(async () => {
|
|
47
46
|
try {
|
|
48
|
-
|
|
49
|
-
const validatedData = validator.validate('delete_history_map', {
|
|
50
|
-
mapId
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// 先删除地图文件
|
|
54
|
-
await deleteMultipleMapFile(validatedData.mapId, devId);
|
|
47
|
+
await deleteMultipleMapFile(mapId, devId);
|
|
55
48
|
if (useMqtt) {
|
|
56
49
|
sendStructuredMessage(DeleteMapEnum.set, {
|
|
57
|
-
mapId
|
|
50
|
+
mapId
|
|
58
51
|
}, resolve, error => reject(handleMqttError(error, 'Failed to delete history map')), DeleteMapEnum.rst // 响应类型是 rst,不是 set
|
|
59
52
|
);
|
|
60
53
|
return;
|
|
@@ -62,7 +55,7 @@ export const useHistoryMap = () => {
|
|
|
62
55
|
|
|
63
56
|
// 非 MQTT 模式:使用命令传输
|
|
64
57
|
const command = encodeDeleteMap0x2c({
|
|
65
|
-
id:
|
|
58
|
+
id: mapId
|
|
66
59
|
});
|
|
67
60
|
devices.common.model.actions.command_trans.set(command);
|
|
68
61
|
resolve({
|
|
@@ -82,25 +75,21 @@ export const useHistoryMap = () => {
|
|
|
82
75
|
return new Promise((resolve, reject) => {
|
|
83
76
|
(async () => {
|
|
84
77
|
try {
|
|
85
|
-
// 构建符合 Schema 的数据
|
|
86
78
|
const mapData = {
|
|
87
79
|
mapId,
|
|
88
80
|
url,
|
|
89
81
|
urlLen: url.length
|
|
90
82
|
};
|
|
91
|
-
|
|
92
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
93
|
-
const validatedData = validator.validate('change_current_map', mapData);
|
|
94
83
|
if (useMqtt) {
|
|
95
|
-
sendStructuredMessage(UseMapEnum.set,
|
|
84
|
+
sendStructuredMessage(UseMapEnum.set, mapData, resolve, error => reject(handleMqttError(error, 'Failed to change current map')), UseMapEnum.query // 响应类型是 query,不是 set
|
|
96
85
|
);
|
|
97
86
|
return;
|
|
98
87
|
}
|
|
99
88
|
|
|
100
89
|
// 非 MQTT 模式:使用命令传输
|
|
101
90
|
const command = encodeUseMap0x2e({
|
|
102
|
-
mapId:
|
|
103
|
-
url:
|
|
91
|
+
mapId: mapData.mapId,
|
|
92
|
+
url: mapData.url
|
|
104
93
|
});
|
|
105
94
|
devices.common.model.actions.command_trans.set(command);
|
|
106
95
|
resolve({
|
|
@@ -109,7 +98,7 @@ export const useHistoryMap = () => {
|
|
|
109
98
|
reqType: UseMapEnum.query,
|
|
110
99
|
version: commandVersion,
|
|
111
100
|
taskId: `${Date.now()}`,
|
|
112
|
-
mapId:
|
|
101
|
+
mapId: mapData.mapId
|
|
113
102
|
});
|
|
114
103
|
} catch (error) {
|
|
115
104
|
reject(handleMqttError(error, 'Failed to change current map'));
|
|
@@ -123,10 +112,8 @@ export const useHistoryMap = () => {
|
|
|
123
112
|
};
|
|
124
113
|
return new Promise((resolve, reject) => {
|
|
125
114
|
try {
|
|
126
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
127
|
-
const validatedData = validator.validate('save_map', data);
|
|
128
115
|
if (useMqtt) {
|
|
129
|
-
sendStructuredMessage(SaveCurrentMapEnum.set,
|
|
116
|
+
sendStructuredMessage(SaveCurrentMapEnum.set, data, resolve, error => reject(handleMqttError(error, 'Failed to save current map')), SaveCurrentMapEnum.query // 响应类型是 query,不是 set
|
|
130
117
|
);
|
|
131
118
|
return;
|
|
132
119
|
}
|
|
@@ -5,7 +5,6 @@ import { pointsToString } from '../utils';
|
|
|
5
5
|
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
6
6
|
import { SingletonContext } from './mqttProvider';
|
|
7
7
|
import { PartDivisionEnum } from './type';
|
|
8
|
-
import { validator } from './type/fun';
|
|
9
8
|
/**
|
|
10
9
|
* 自定义 Hook,用于房间分隔
|
|
11
10
|
* @returns 包含 setPartDivision 函数的对象
|
|
@@ -32,32 +31,19 @@ export const usePartDivision = () => {
|
|
|
32
31
|
setPartDivision: (points, roomId, origin) => {
|
|
33
32
|
return new Promise((resolve, reject) => {
|
|
34
33
|
try {
|
|
35
|
-
// 使用验证器验证三个独立参数
|
|
36
|
-
const validatedData = validator.validateSetPartDivision(points, roomId, origin);
|
|
37
|
-
const {
|
|
38
|
-
points: validatedPoints,
|
|
39
|
-
roomId: validatedRoomId,
|
|
40
|
-
origin: validatedOrigin
|
|
41
|
-
} = validatedData;
|
|
42
34
|
if (useMqtt) {
|
|
43
|
-
|
|
44
|
-
const pointStr = pointsToString(validatedPoints, validatedOrigin);
|
|
35
|
+
const pointStr = pointsToString(points, origin);
|
|
45
36
|
sendStructuredMessage(PartDivisionEnum.set, {
|
|
46
37
|
lines: [pointStr],
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}, resolve, error => reject(handleMqttError(error, 'Failed to set part division')), PartDivisionEnum.query // 响应类型是 query,不是 set
|
|
50
|
-
);
|
|
38
|
+
ids: [roomId]
|
|
39
|
+
}, resolve, error => reject(handleMqttError(error, 'Failed to set part division')), PartDivisionEnum.query);
|
|
51
40
|
return;
|
|
52
41
|
}
|
|
53
|
-
|
|
54
|
-
// 非 MQTT 模式:使用命令传输
|
|
55
|
-
// 将 roomId 转换为数字(如果它是字符串)
|
|
56
|
-
const roomIdNumber = typeof validatedRoomId === 'string' ? Number(validatedRoomId) : validatedRoomId;
|
|
42
|
+
const roomIdNumber = typeof roomId === 'string' ? Number(roomId) : roomId;
|
|
57
43
|
const command = encodePartitionDivision0x1c({
|
|
58
44
|
version: commandVersion,
|
|
59
|
-
origin
|
|
60
|
-
points
|
|
45
|
+
origin,
|
|
46
|
+
points,
|
|
61
47
|
roomId: roomIdNumber
|
|
62
48
|
});
|
|
63
49
|
devices.common.model.actions.command_trans.set(command);
|
package/lib/mqtt/usePartMerge.js
CHANGED
|
@@ -4,7 +4,6 @@ import { PartMergeEnum } from './type';
|
|
|
4
4
|
import { SingletonContext } from './mqttProvider';
|
|
5
5
|
import { encodePartitionMerge0x1e } from '@ray-js/robot-protocol';
|
|
6
6
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
7
|
-
import { validator } from './type/fun';
|
|
8
7
|
/**
|
|
9
8
|
* 自定义 Hook,用于分区合并
|
|
10
9
|
* @returns 包含 setPartMerge 函数的对象
|
|
@@ -28,8 +27,7 @@ export const usePartMerge = () => {
|
|
|
28
27
|
setPartMerge: data => {
|
|
29
28
|
return new Promise((resolve, reject) => {
|
|
30
29
|
try {
|
|
31
|
-
|
|
32
|
-
const ids = validator.validate('set_part_merge', data);
|
|
30
|
+
const ids = data;
|
|
33
31
|
if (useMqtt) {
|
|
34
32
|
sendStructuredMessage(PartMergeEnum.set, {
|
|
35
33
|
ids
|
package/lib/mqtt/usePassword.js
CHANGED
|
@@ -3,7 +3,6 @@ import { PasswordEnum } from './type';
|
|
|
3
3
|
import { useContext } from 'react';
|
|
4
4
|
import { SingletonContext } from './mqttProvider';
|
|
5
5
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
6
|
-
import { validator } from './type/fun';
|
|
7
6
|
/**
|
|
8
7
|
* 自定义 Hook,用于密码管理
|
|
9
8
|
* @returns 包含 requestPassword、setPassword 和 checkPassword 函数的对象
|
|
@@ -65,10 +64,7 @@ export const usePassword = () => {
|
|
|
65
64
|
oldPassword: params.oldPassword ? md5(params.oldPassword).toString() : undefined,
|
|
66
65
|
taskId: (_params$taskId = params.taskId) !== null && _params$taskId !== void 0 ? _params$taskId : String(Date.now())
|
|
67
66
|
};
|
|
68
|
-
|
|
69
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
70
|
-
const validatedData = validator.validate('set_password', passwordData);
|
|
71
|
-
sendStructuredMessage(PasswordEnum.set, validatedData, resolve, error => reject(handleMqttError(error, 'Failed to set password')), PasswordEnum.rst // 响应类型是 rst,不是 set
|
|
67
|
+
sendStructuredMessage(PasswordEnum.set, passwordData, resolve, error => reject(handleMqttError(error, 'Failed to set password')), PasswordEnum.rst // 响应类型是 rst,不是 set
|
|
72
68
|
);
|
|
73
69
|
} catch (error) {
|
|
74
70
|
reject(handleMqttError(error, 'Failed to set password'));
|
|
@@ -90,10 +86,7 @@ export const usePassword = () => {
|
|
|
90
86
|
password: md5(params.password).toString(),
|
|
91
87
|
taskId: (_params$taskId2 = params.taskId) !== null && _params$taskId2 !== void 0 ? _params$taskId2 : String(Date.now())
|
|
92
88
|
};
|
|
93
|
-
|
|
94
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
95
|
-
const validatedData = validator.validate('check_password', passwordData);
|
|
96
|
-
sendStructuredMessage(PasswordEnum.check, validatedData, resolve, error => reject(handleMqttError(error, 'Failed to check password')), PasswordEnum.checkRst // 响应类型是 checkRst,不是 check
|
|
89
|
+
sendStructuredMessage(PasswordEnum.check, passwordData, resolve, error => reject(handleMqttError(error, 'Failed to check password')), PasswordEnum.checkRst // 响应类型是 checkRst,不是 check
|
|
97
90
|
);
|
|
98
91
|
} catch (error) {
|
|
99
92
|
reject(handleMqttError(error, 'Failed to check password'));
|
|
@@ -4,7 +4,6 @@ import { useContext } from 'react';
|
|
|
4
4
|
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
5
5
|
import { SingletonContext } from './mqttProvider';
|
|
6
6
|
import { QuietHoursEnum } from './type';
|
|
7
|
-
import { validator } from './type/fun';
|
|
8
7
|
/**
|
|
9
8
|
* 自定义 Hook,用于勿扰模式
|
|
10
9
|
* @returns 包含 setQuiteHours 和 requestQuiteHours 函数的对象
|
|
@@ -34,14 +33,12 @@ export const useQuiteHours = () => {
|
|
|
34
33
|
setQuiteHours: params => {
|
|
35
34
|
return new Promise((resolve, reject) => {
|
|
36
35
|
try {
|
|
37
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
38
|
-
const validatedData = validator.validate('set_quiet_hours', params);
|
|
39
36
|
const {
|
|
40
37
|
startTime,
|
|
41
38
|
endTime,
|
|
42
39
|
active,
|
|
43
40
|
day
|
|
44
|
-
} =
|
|
41
|
+
} = params;
|
|
45
42
|
const {
|
|
46
43
|
hour: h0,
|
|
47
44
|
minute: m0
|
|
@@ -3,8 +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 {
|
|
7
|
-
import { normalizeWaterPreferencePayload } from './waterPreference';
|
|
6
|
+
import { pickWaterFields } from '../utils';
|
|
8
7
|
/**
|
|
9
8
|
* 自定义 Hook,用于房间属性管理
|
|
10
9
|
* @param devId 设备ID(可选,如果不提供则从 MqttProvider Context 获取)
|
|
@@ -71,11 +70,8 @@ export const useRoomProperty = () => {
|
|
|
71
70
|
orders: data.orders
|
|
72
71
|
}, data.routePreferences && {
|
|
73
72
|
routePreferences: data.routePreferences
|
|
74
|
-
}),
|
|
75
|
-
|
|
76
|
-
// 使用 TypeBox Schema 进行参数验证(包含自定义验证逻辑)
|
|
77
|
-
const validatedData = validator.validate('set_room_property', sendData);
|
|
78
|
-
sendStructuredMessage(RoomPropertyEnum.set, validatedData, resolve, error => reject(handleMqttError(error, 'Failed to set room property')), RoomPropertyEnum.query // 响应类型是 query,不是 set
|
|
73
|
+
}), pickWaterFields(len, data.cisterns, data.waterValues));
|
|
74
|
+
sendStructuredMessage(RoomPropertyEnum.set, sendData, resolve, error => reject(handleMqttError(error, 'Failed to set room property')), RoomPropertyEnum.query // 响应类型是 query,不是 set
|
|
79
75
|
);
|
|
80
76
|
} catch (error) {
|
|
81
77
|
reject(handleMqttError(error, 'Failed to set room property'));
|
package/lib/mqtt/useSchedule.js
CHANGED
|
@@ -6,11 +6,10 @@ 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 {
|
|
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';
|
|
13
|
-
import { validator } from './type/fun';
|
|
14
13
|
/**
|
|
15
14
|
* 自定义 Hook,用于定时任务
|
|
16
15
|
* @param devId 设备ID(可选,如果不提供则从 MqttProvider Context 获取)
|
|
@@ -44,9 +43,7 @@ export const useSchedule = () => {
|
|
|
44
43
|
};
|
|
45
44
|
return new Promise((resolve, reject) => {
|
|
46
45
|
try {
|
|
47
|
-
|
|
48
|
-
const validatedParams = validator.validate('request_schedule', message);
|
|
49
|
-
sendStructuredMessage(ScheduleEnum.query, validatedParams, resolve, error => reject(handleMqttError(error, 'Failed to request schedule')));
|
|
46
|
+
sendStructuredMessage(ScheduleEnum.query, message, resolve, error => reject(handleMqttError(error, 'Failed to request schedule')));
|
|
50
47
|
} catch (error) {
|
|
51
48
|
reject(handleMqttError(error, 'Failed to request schedule'));
|
|
52
49
|
}
|
|
@@ -55,19 +52,18 @@ export const useSchedule = () => {
|
|
|
55
52
|
setSchedule: message => {
|
|
56
53
|
return new Promise((resolve, reject) => {
|
|
57
54
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const list = validatedData.list.map(item => {
|
|
55
|
+
const list = message.list.map(item => {
|
|
56
|
+
var _item$ids$length, _item$ids;
|
|
61
57
|
const {
|
|
62
58
|
routePreferences
|
|
63
59
|
} = item,
|
|
64
60
|
rest = _objectWithoutProperties(item, _excluded);
|
|
65
|
-
return _objectSpread(_objectSpread(_objectSpread({}, rest),
|
|
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 && {
|
|
66
62
|
routePreferences
|
|
67
63
|
});
|
|
68
64
|
});
|
|
69
65
|
if (useMqtt) {
|
|
70
|
-
sendStructuredMessage(ScheduleEnum.set, _objectSpread(_objectSpread({},
|
|
66
|
+
sendStructuredMessage(ScheduleEnum.set, _objectSpread(_objectSpread({}, message), {}, {
|
|
71
67
|
list
|
|
72
68
|
}), resolve, error => reject(handleMqttError(error, 'Failed to set schedule')), ScheduleEnum.query // 响应类型是 query,不是 set
|
|
73
69
|
);
|
|
@@ -77,7 +73,7 @@ export const useSchedule = () => {
|
|
|
77
73
|
// 非 MQTT 模式:使用命令传输
|
|
78
74
|
const command = encodeDeviceTimer0x30({
|
|
79
75
|
version: commandVersion,
|
|
80
|
-
number:
|
|
76
|
+
number: message.num,
|
|
81
77
|
list: list.map(_ref => {
|
|
82
78
|
let {
|
|
83
79
|
active,
|
|
@@ -116,7 +112,7 @@ export const useSchedule = () => {
|
|
|
116
112
|
version: commandVersion,
|
|
117
113
|
taskId: `${Date.now()}`,
|
|
118
114
|
list,
|
|
119
|
-
num:
|
|
115
|
+
num: message.num
|
|
120
116
|
});
|
|
121
117
|
} catch (error) {
|
|
122
118
|
reject(handleMqttError(error, 'Failed to set schedule'));
|
|
@@ -9,8 +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 {
|
|
13
|
-
import { normalizeWaterPreferencePayload } from './waterPreference';
|
|
12
|
+
import { pickWaterFields } from '../utils';
|
|
14
13
|
/**
|
|
15
14
|
* 自定义 Hook,用于选区清扫
|
|
16
15
|
* @returns 包含 requestSelectRoomClean 和 setRoomClean 函数的对象
|
|
@@ -77,8 +76,7 @@ export const useSelectRoomClean = () => {
|
|
|
77
76
|
return new Promise((resolve, reject) => {
|
|
78
77
|
try {
|
|
79
78
|
var _rooms$0$cleanTimes, _rooms$;
|
|
80
|
-
|
|
81
|
-
const rooms = validator.validate('set_select_room_clean', data);
|
|
79
|
+
const rooms = data;
|
|
82
80
|
if (useMqtt) {
|
|
83
81
|
const ids = [];
|
|
84
82
|
const suctions = [];
|
|
@@ -94,13 +92,10 @@ export const useSelectRoomClean = () => {
|
|
|
94
92
|
yMops.push((_room$yMop = room.yMop) !== null && _room$yMop !== void 0 ? _room$yMop : -1);
|
|
95
93
|
sweepMopModes.push((_room$sweepMopMode = room.sweepMopMode) !== null && _room$sweepMopMode !== void 0 ? _room$sweepMopMode : 'only_sweep');
|
|
96
94
|
});
|
|
97
|
-
const waterPayload =
|
|
95
|
+
const waterPayload = pickWaterFields(rooms.length, rooms.map(room => {
|
|
98
96
|
var _room$cistern;
|
|
99
97
|
return (_room$cistern = room.cistern) !== null && _room$cistern !== void 0 ? _room$cistern : '';
|
|
100
|
-
}), rooms.map(room =>
|
|
101
|
-
var _room$waterValue;
|
|
102
|
-
return (_room$waterValue = room.waterValue) !== null && _room$waterValue !== void 0 ? _room$waterValue : '';
|
|
103
|
-
}));
|
|
98
|
+
}), rooms.map(room => room.waterValue));
|
|
104
99
|
sendStructuredMessage(RoomCleanSetEnum.set, _objectSpread(_objectSpread(_objectSpread({
|
|
105
100
|
ids,
|
|
106
101
|
suctions
|
|
@@ -129,13 +124,10 @@ export const useSelectRoomClean = () => {
|
|
|
129
124
|
var _room$suction2;
|
|
130
125
|
return (_room$suction2 = room.suction) !== null && _room$suction2 !== void 0 ? _room$suction2 : '';
|
|
131
126
|
});
|
|
132
|
-
const waterPayload =
|
|
127
|
+
const waterPayload = pickWaterFields(rooms.length, rooms.map(room => {
|
|
133
128
|
var _room$cistern2;
|
|
134
129
|
return (_room$cistern2 = room.cistern) !== null && _room$cistern2 !== void 0 ? _room$cistern2 : '';
|
|
135
|
-
}), rooms.map(room =>
|
|
136
|
-
var _room$waterValue2;
|
|
137
|
-
return (_room$waterValue2 = room.waterValue) !== null && _room$waterValue2 !== void 0 ? _room$waterValue2 : '';
|
|
138
|
-
}));
|
|
130
|
+
}), rooms.map(room => room.waterValue));
|
|
139
131
|
const cleanCounts = rooms.map(room => {
|
|
140
132
|
var _room$cleanTimes2;
|
|
141
133
|
return (_room$cleanTimes2 = room.cleanTimes) !== null && _room$cleanTimes2 !== void 0 ? _room$cleanTimes2 : 1;
|
package/lib/mqtt/useSpotClean.js
CHANGED
|
@@ -6,10 +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 { validator } from './type/fun';
|
|
12
|
-
import { normalizeWaterPreferencePayload } from './waterPreference';
|
|
13
11
|
/**
|
|
14
12
|
* 自定义 Hook,用于定点清扫
|
|
15
13
|
* @returns 包含 requestSpotClean 和 setSpotClean 函数的对象
|
|
@@ -52,16 +50,12 @@ export const useSpotClean = () => {
|
|
|
52
50
|
setSpotClean: message => {
|
|
53
51
|
return new Promise((resolve, reject) => {
|
|
54
52
|
try {
|
|
55
|
-
// 使用 TypeBox Schema 进行参数验证(包含自定义验证逻辑)
|
|
56
|
-
const validatedData = validator.validate('set_spot_clean', message);
|
|
57
53
|
const {
|
|
58
54
|
spots,
|
|
59
55
|
origin
|
|
60
|
-
} =
|
|
56
|
+
} = message;
|
|
61
57
|
const num = spots.length;
|
|
62
|
-
const waterPayload =
|
|
63
|
-
|
|
64
|
-
// 为可选字段设置默认值
|
|
58
|
+
const waterPayload = pickWaterFields(num, message.cisterns, message.waterValues);
|
|
65
59
|
const {
|
|
66
60
|
suctions = new Array(num).fill(''),
|
|
67
61
|
cleanCounts = new Array(num).fill(1),
|
|
@@ -69,7 +63,7 @@ export const useSpotClean = () => {
|
|
|
69
63
|
sweepMopModes = new Array(num).fill('only_sweep'),
|
|
70
64
|
routePreferences,
|
|
71
65
|
names
|
|
72
|
-
} =
|
|
66
|
+
} = message;
|
|
73
67
|
if (useMqtt) {
|
|
74
68
|
sendStructuredMessage(SpotCleanEnum.set, _objectSpread(_objectSpread(_objectSpread({
|
|
75
69
|
num,
|
|
@@ -8,7 +8,6 @@ import { pointsToString } from '../utils';
|
|
|
8
8
|
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
9
9
|
import { SingletonContext } from './mqttProvider';
|
|
10
10
|
import { VirtualAreaEnum } from './type';
|
|
11
|
-
import { validator } from './type/fun';
|
|
12
11
|
// 禁区
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -74,12 +73,10 @@ export const useVirtualArea = () => {
|
|
|
74
73
|
setVirtualArea: message => {
|
|
75
74
|
return new Promise((resolve, reject) => {
|
|
76
75
|
try {
|
|
77
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
78
|
-
const validatedData = validator.validate('set_virtual_area', message);
|
|
79
76
|
const {
|
|
80
77
|
data,
|
|
81
78
|
origin
|
|
82
|
-
} =
|
|
79
|
+
} = message;
|
|
83
80
|
if (useMqtt) {
|
|
84
81
|
const names = [];
|
|
85
82
|
const modes = [];
|
|
@@ -6,7 +6,6 @@ import { SingletonContext } from './mqttProvider';
|
|
|
6
6
|
import { encodeVirtualWall0x12, requestVirtualWall0x13 } from '@ray-js/robot-protocol';
|
|
7
7
|
import { pointsToString } from '../utils';
|
|
8
8
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
9
|
-
import { validator } from './type/fun';
|
|
10
9
|
/**
|
|
11
10
|
* 自定义 Hook,用于虚拟墙管理
|
|
12
11
|
* @returns 包含 requestVirtualWall 和 setVirtualWall 函数的对象
|
|
@@ -69,12 +68,10 @@ export const useVirtualWall = () => {
|
|
|
69
68
|
setVirtualWall: params => {
|
|
70
69
|
return new Promise((resolve, reject) => {
|
|
71
70
|
try {
|
|
72
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
73
|
-
const validatedData = validator.validate('set_virtual_wall', params);
|
|
74
71
|
const {
|
|
75
72
|
data,
|
|
76
73
|
origin
|
|
77
|
-
} =
|
|
74
|
+
} = params;
|
|
78
75
|
if (useMqtt) {
|
|
79
76
|
sendStructuredMessage(VirtualWallEnum.set, {
|
|
80
77
|
points: data.map(points => pointsToString(points, origin)),
|
package/lib/mqtt/useVoice.js
CHANGED
|
@@ -5,7 +5,6 @@ import { useContext } from 'react';
|
|
|
5
5
|
import { SingletonContext } from './mqttProvider';
|
|
6
6
|
import { encodeVoice0x34 } from '@ray-js/robot-protocol';
|
|
7
7
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
8
|
-
import { validator } from './type/fun';
|
|
9
8
|
/**
|
|
10
9
|
* 自定义 Hook,用于语音语言设置
|
|
11
10
|
* @returns 包含 requestAllVoices, requestVoiceInUse 和 setVoice 函数的对象
|
|
@@ -68,18 +67,16 @@ export const useVoice = () => {
|
|
|
68
67
|
setVoice: message => {
|
|
69
68
|
return new Promise((resolve, reject) => {
|
|
70
69
|
try {
|
|
71
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
72
|
-
const validatedData = validator.validate('set_voice', message);
|
|
73
70
|
if (useMqtt) {
|
|
74
|
-
const sendData = _objectSpread(_objectSpread({},
|
|
75
|
-
urlLen:
|
|
71
|
+
const sendData = _objectSpread(_objectSpread({}, message), {}, {
|
|
72
|
+
urlLen: message.url.length
|
|
76
73
|
});
|
|
77
74
|
sendStructuredMessage(VoiceLanguageEnum.set, sendData, resolve, error => reject(handleMqttError(error, 'Failed to set voice')), VoiceLanguageEnum.query);
|
|
78
75
|
return;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
// 非 MQTT 模式:使用命令传输
|
|
82
|
-
const command = encodeVoice0x34(
|
|
79
|
+
const command = encodeVoice0x34(message);
|
|
83
80
|
devices.common.model.actions.voice_data.set(command);
|
|
84
81
|
resolve({
|
|
85
82
|
success: true,
|
|
@@ -87,7 +84,7 @@ export const useVoice = () => {
|
|
|
87
84
|
reqType: VoiceLanguageEnum.query,
|
|
88
85
|
version: commandVersion,
|
|
89
86
|
taskId: `${Date.now()}`,
|
|
90
|
-
id:
|
|
87
|
+
id: message.id,
|
|
91
88
|
schedule: 0,
|
|
92
89
|
status: 0
|
|
93
90
|
});
|
package/lib/mqtt/useWifiMap.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { WifiMapEnum } from './type';
|
|
2
2
|
import { useStructuredMessage, handleMqttError } from './hooks/useStructuredMessage';
|
|
3
|
-
import { validator } from './type/fun';
|
|
4
3
|
/**
|
|
5
4
|
* 自定义 Hook,用于 WiFi 地图管理
|
|
6
5
|
* @returns 包含 requestWifiMap 和 setWifiMap 函数的对象
|
|
@@ -42,10 +41,7 @@ export const useWifiMap = () => {
|
|
|
42
41
|
taskId: data.taskId || String(Date.now()),
|
|
43
42
|
switch: (_data$switch = data.switch) !== null && _data$switch !== void 0 ? _data$switch : true
|
|
44
43
|
};
|
|
45
|
-
|
|
46
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
47
|
-
const validatedData = validator.validate('set_wifi_map', wifiMapData);
|
|
48
|
-
sendStructuredMessage(WifiMapEnum.set, validatedData, resolve, error => reject(handleMqttError(error, 'Failed to set WiFi map')), WifiMapEnum.rst // 响应类型是 rst,不是 set
|
|
44
|
+
sendStructuredMessage(WifiMapEnum.set, wifiMapData, resolve, error => reject(handleMqttError(error, 'Failed to set WiFi map')), WifiMapEnum.rst // 响应类型是 rst,不是 set
|
|
49
45
|
);
|
|
50
46
|
} catch (error) {
|
|
51
47
|
reject(handleMqttError(error, 'Failed to set WiFi map'));
|
package/lib/mqtt/useZoneClean.js
CHANGED
|
@@ -3,12 +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 { validator } from './type/fun';
|
|
11
|
-
import { normalizeWaterPreferencePayload } from './waterPreference';
|
|
12
10
|
/**
|
|
13
11
|
* 自定义 Hook,用于划区清扫
|
|
14
12
|
* @returns 包含 requestZoneClean 和 setZoneClean 函数的对象
|
|
@@ -75,7 +73,7 @@ export const useZoneClean = () => {
|
|
|
75
73
|
|
|
76
74
|
// 将业务参数转换为协议数据格式
|
|
77
75
|
const num = zones.length;
|
|
78
|
-
const waterPayload =
|
|
76
|
+
const waterPayload = pickWaterFields(num, params.cisterns, params.waterValues);
|
|
79
77
|
const {
|
|
80
78
|
suctions = new Array(num).fill(''),
|
|
81
79
|
cleanCounts = new Array(num).fill(1),
|
|
@@ -105,9 +103,6 @@ export const useZoneClean = () => {
|
|
|
105
103
|
}, routePreferences && {
|
|
106
104
|
routePreferences
|
|
107
105
|
});
|
|
108
|
-
|
|
109
|
-
// 使用 TypeBox Schema 进行参数验证
|
|
110
|
-
const validatedData = validator.validate('set_zone_clean', zoneCleanData);
|
|
111
106
|
const polygons = zones.map(_ref2 => {
|
|
112
107
|
let {
|
|
113
108
|
points
|
|
@@ -121,13 +116,13 @@ export const useZoneClean = () => {
|
|
|
121
116
|
return name || '';
|
|
122
117
|
});
|
|
123
118
|
const commonFields = _objectSpread(_objectSpread({
|
|
124
|
-
suctions:
|
|
119
|
+
suctions: zoneCleanData.suctions
|
|
125
120
|
}, waterPayload), {}, {
|
|
126
|
-
cleanCounts:
|
|
127
|
-
yMops:
|
|
128
|
-
sweepMopModes:
|
|
129
|
-
},
|
|
130
|
-
routePreferences:
|
|
121
|
+
cleanCounts: zoneCleanData.cleanCounts,
|
|
122
|
+
yMops: zoneCleanData.yMops,
|
|
123
|
+
sweepMopModes: zoneCleanData.sweepMopModes
|
|
124
|
+
}, zoneCleanData.routePreferences && {
|
|
125
|
+
routePreferences: zoneCleanData.routePreferences
|
|
131
126
|
});
|
|
132
127
|
if (useMqtt) {
|
|
133
128
|
sendStructuredMessage(ZoneCleanEnum.set, _objectSpread(_objectSpread({
|
|
@@ -144,8 +139,8 @@ export const useZoneClean = () => {
|
|
|
144
139
|
const command = encodeZoneClean0x3a({
|
|
145
140
|
protocolVersion: 1,
|
|
146
141
|
version: commandVersion,
|
|
147
|
-
origin:
|
|
148
|
-
zones:
|
|
142
|
+
origin: zoneCleanData.origin,
|
|
143
|
+
zones: zoneCleanData.zones.map(zone => ({
|
|
149
144
|
points: zone.points,
|
|
150
145
|
name: zone.name,
|
|
151
146
|
advanced: zone.advanced
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -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
|
+
};
|
package/lib/utils/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
};
|