@ray-js/robot-data-stream 0.0.16-beta.3 → 0.0.16-beta.5
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/type/protocols/base.d.ts +2 -2
- package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +5 -5
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +5 -5
- package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +3 -3
- package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +7 -7
- package/lib/mqtt/useRoomProperty.js +2 -2
- package/lib/mqtt/useSchedule.js +3 -2
- package/lib/mqtt/useSelectRoomClean.js +5 -11
- package/lib/mqtt/useSpotClean.js +2 -3
- package/lib/mqtt/useZoneClean.js +2 -3
- package/lib/utils/index.d.ts +15 -0
- package/lib/utils/index.js +39 -1
- package/package.json +1 -1
- package/lib/mqtt/waterPreference.d.ts +0 -20
- package/lib/mqtt/waterPreference.js +0 -70
|
@@ -5,8 +5,8 @@ export interface Point {
|
|
|
5
5
|
}
|
|
6
6
|
export interface RoomPreferenceFields {
|
|
7
7
|
suctions?: string[];
|
|
8
|
-
cisterns?:
|
|
9
|
-
waterValues?:
|
|
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
|
|
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?:
|
|
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?:
|
|
15
|
+
waterValues?: number[];
|
|
16
16
|
}
|
|
17
17
|
export interface RoomPropertyResponse extends BaseResponse {
|
|
18
18
|
suctions?: string[];
|
|
19
|
-
cisterns?:
|
|
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?:
|
|
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
|
|
1
|
+
import type { BaseResponse } from './base';
|
|
2
2
|
export interface SelectRoomCleanItem {
|
|
3
3
|
roomId: number;
|
|
4
4
|
suction?: string;
|
|
5
|
-
cistern?:
|
|
6
|
-
waterValue?:
|
|
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?:
|
|
17
|
-
waterValues?:
|
|
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
|
|
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?:
|
|
10
|
-
waterValues?:
|
|
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
|
|
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:
|
|
9
|
-
cistern:
|
|
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?:
|
|
21
|
-
waterValues?:
|
|
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?:
|
|
32
|
-
waterValues?:
|
|
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 {
|
|
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
|
-
}),
|
|
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) {
|
package/lib/mqtt/useSchedule.js
CHANGED
|
@@ -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 {
|
|
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),
|
|
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 {
|
|
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 =
|
|
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 =
|
|
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;
|
package/lib/mqtt/useSpotClean.js
CHANGED
|
@@ -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 =
|
|
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),
|
package/lib/mqtt/useZoneClean.js
CHANGED
|
@@ -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 =
|
|
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),
|
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
|
|
48
|
+
* (cisterns 缺省按 length 填充 'closed')。
|
|
49
|
+
* 只要 waterValues 含有 undefined/null/NaN,就整体降级到 cisterns,避免发出 [null] 等坏协议。
|
|
50
|
+
*/
|
|
51
|
+
export declare const pickWaterFields: (length: number, cisterns?: string[], waterValues?: Array<number | null | undefined>) => {
|
|
52
|
+
waterValues: number[];
|
|
53
|
+
} | {
|
|
54
|
+
cisterns: string[];
|
|
55
|
+
};
|
package/lib/utils/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.every.js";
|
|
3
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
1
4
|
import mitt from 'mitt';
|
|
2
5
|
import { floor, join, map } from 'lodash-es';
|
|
3
6
|
import log4js from '@ray-js/log4js';
|
|
4
7
|
import { logP2PData as originalLogP2PData } from '@ray-js/robot-custom-log';
|
|
8
|
+
import { CISTERN_MAP } from '../constant';
|
|
5
9
|
export const emitter = mitt();
|
|
6
10
|
const pointToString = point => {
|
|
7
11
|
return `${point.x},${point.y}`;
|
|
@@ -19,6 +23,7 @@ export const pointsToString = (points, origin) => {
|
|
|
19
23
|
});
|
|
20
24
|
return join(map(newPoints, pointToString), ',');
|
|
21
25
|
} catch (e) {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
22
27
|
console.error('pointsToString error', e);
|
|
23
28
|
throw new Error('pointsToString error');
|
|
24
29
|
}
|
|
@@ -96,4 +101,37 @@ export const logP2PDataIfEnabled = (enableCustomLog, devId, event, message) => {
|
|
|
96
101
|
}));
|
|
97
102
|
}
|
|
98
103
|
};
|
|
99
|
-
|
|
104
|
+
|
|
105
|
+
// eslint-disable-next-line no-bitwise
|
|
106
|
+
export const getBitValue = (num, idx) => (num & 1 << idx) >> idx;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 将自定义水量 / 标准水量统一归一化为设备命令需要的数值。
|
|
110
|
+
* 优先使用 waterValue,其次回退到 cistern。
|
|
111
|
+
*/
|
|
112
|
+
export const resolveWaterLevel = function (waterValue, cistern) {
|
|
113
|
+
let fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CISTERN_MAP.closed;
|
|
114
|
+
if (waterValue != null && Number.isFinite(waterValue)) {
|
|
115
|
+
return waterValue;
|
|
116
|
+
}
|
|
117
|
+
if (cistern && cistern in CISTERN_MAP) {
|
|
118
|
+
return CISTERN_MAP[cistern];
|
|
119
|
+
}
|
|
120
|
+
return fallback;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 水量字段:当 waterValues 每一项都是有效数字时只带 waterValues,否则带 cisterns
|
|
125
|
+
* (cisterns 缺省按 length 填充 'closed')。
|
|
126
|
+
* 只要 waterValues 含有 undefined/null/NaN,就整体降级到 cisterns,避免发出 [null] 等坏协议。
|
|
127
|
+
*/
|
|
128
|
+
export const pickWaterFields = (length, cisterns, waterValues) => {
|
|
129
|
+
if (waterValues !== null && waterValues !== void 0 && waterValues.length && waterValues.every(v => v != null && Number.isFinite(v))) {
|
|
130
|
+
return {
|
|
131
|
+
waterValues: waterValues
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
cisterns: cisterns ? cisterns.map(v => v == null ? '' : v) : new Array(length).fill('')
|
|
136
|
+
};
|
|
137
|
+
};
|
package/package.json
CHANGED
|
@@ -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
|
-
};
|