@ray-js/robot-data-stream 0.0.16 → 0.0.17-beta.10
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/cruise.d.ts +2 -0
- package/lib/mqtt/cruise.js +9 -0
- package/lib/mqtt/hooks/useStructuredMessage.d.ts +2 -1
- package/lib/mqtt/hooks/useStructuredMessage.js +13 -6
- package/lib/mqtt/index.d.ts +6 -1
- package/lib/mqtt/index.js +6 -1
- package/lib/mqtt/mqttProvider.js +20 -18
- package/lib/mqtt/promise.d.ts +12 -0
- package/lib/mqtt/promise.js +27 -0
- package/lib/mqtt/spotPolygons.d.ts +7 -0
- package/lib/mqtt/spotPolygons.js +18 -0
- package/lib/mqtt/type/protocols/cruiseProtocol.d.ts +39 -0
- package/lib/mqtt/type/protocols/cruiseProtocol.js +1 -0
- package/lib/mqtt/type/protocols/index.d.ts +5 -0
- package/lib/mqtt/type/protocols/index.js +6 -1
- package/lib/mqtt/type/protocols/mcsRoomInfoProtocol.d.ts +18 -0
- package/lib/mqtt/type/protocols/mcsRoomInfoProtocol.js +1 -0
- package/lib/mqtt/type/protocols/purifierScheduleProtocol.d.ts +50 -0
- package/lib/mqtt/type/protocols/purifierScheduleProtocol.js +1 -0
- package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +4 -0
- package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +2 -0
- package/lib/mqtt/type/protocols/spotPolygonsProtocol.d.ts +21 -0
- package/lib/mqtt/type/protocols/spotPolygonsProtocol.js +1 -0
- package/lib/mqtt/type/protocols/thresholdProtocol.d.ts +22 -0
- package/lib/mqtt/type/protocols/thresholdProtocol.js +1 -0
- package/lib/mqtt/type/requestType.d.ts +19 -0
- package/lib/mqtt/type/requestType.js +34 -0
- package/lib/mqtt/useCruise.d.ts +9 -0
- package/lib/mqtt/useCruise.js +67 -0
- package/lib/mqtt/useMcsRoomInfo.d.ts +9 -0
- package/lib/mqtt/useMcsRoomInfo.js +43 -0
- package/lib/mqtt/usePurifierSchedule.d.ts +9 -0
- package/lib/mqtt/usePurifierSchedule.js +66 -0
- package/lib/mqtt/useRoomProperty.js +3 -1
- package/lib/mqtt/useSpotClean.js +8 -3
- package/lib/mqtt/useSpotPolygons.d.ts +9 -0
- package/lib/mqtt/useSpotPolygons.js +48 -0
- package/lib/mqtt/useThreshold.d.ts +10 -0
- package/lib/mqtt/useThreshold.js +88 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
export const createCruisePayload = message => {
|
|
3
|
+
if (message.polygons && message.num === undefined) {
|
|
4
|
+
return _objectSpread(_objectSpread({}, message), {}, {
|
|
5
|
+
num: message.polygons.length
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return message;
|
|
9
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MqttError } from '../promise';
|
|
1
2
|
import { BaseResponse } from '../type/protocols/base';
|
|
2
3
|
/**
|
|
3
4
|
* 统一的 MQTT 消息发送 Hook
|
|
@@ -9,4 +10,4 @@ export declare const useStructuredMessage: () => {
|
|
|
9
10
|
/**
|
|
10
11
|
* 错误处理工具函数
|
|
11
12
|
*/
|
|
12
|
-
export declare const handleMqttError: (error: unknown, defaultMessage: string) =>
|
|
13
|
+
export declare const handleMqttError: (error: unknown, defaultMessage: string) => MqttError;
|
|
@@ -5,7 +5,7 @@ import { useCallback, useEffect, useRef } from 'react';
|
|
|
5
5
|
import { getBitValue, logger } from '../../utils';
|
|
6
6
|
import { createSetCommonParams } from '../createCommonOptions';
|
|
7
7
|
import { useMqtt } from '../mqttProvider';
|
|
8
|
-
import { normalResolve } from '../promise';
|
|
8
|
+
import { MqttError, normalResolve } from '../promise';
|
|
9
9
|
// 常量定义
|
|
10
10
|
const COMMUNICATION_CHANNELS = {
|
|
11
11
|
MQTT: 'mqtt',
|
|
@@ -196,11 +196,18 @@ export const useStructuredMessage = () => {
|
|
|
196
196
|
* 错误处理工具函数
|
|
197
197
|
*/
|
|
198
198
|
export const handleMqttError = (error, defaultMessage) => {
|
|
199
|
-
|
|
199
|
+
var _errCode, _reqType;
|
|
200
|
+
// 已是本库错误则直接透传
|
|
201
|
+
if (error instanceof MqttError) {
|
|
200
202
|
return error;
|
|
201
203
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
|
|
205
|
+
// 统一包装为 MqttError,打上标记,便于全局 unhandledrejection 兜底时识别为本库错误
|
|
206
|
+
const message = error instanceof Error ? error.message : typeof error === 'string' ? error : defaultMessage;
|
|
207
|
+
const errCode = (_errCode = error === null || error === void 0 ? void 0 : error.errCode) !== null && _errCode !== void 0 ? _errCode : -1;
|
|
208
|
+
const reqType = (_reqType = error === null || error === void 0 ? void 0 : error.reqType) !== null && _reqType !== void 0 ? _reqType : '';
|
|
209
|
+
return new MqttError(message, {
|
|
210
|
+
errCode,
|
|
211
|
+
reqType
|
|
212
|
+
});
|
|
206
213
|
};
|
package/lib/mqtt/index.d.ts
CHANGED
|
@@ -19,4 +19,9 @@ import { useCarpet } from './useCarpet';
|
|
|
19
19
|
import { useCarpetClean } from './useCarpetClean';
|
|
20
20
|
import { useDeviceModel } from './useDeviceModel';
|
|
21
21
|
import { useFurnitureModel } from './useFurnitureModel';
|
|
22
|
-
|
|
22
|
+
import { usePurifierSchedule } from './usePurifierSchedule';
|
|
23
|
+
import { useCruise } from './useCruise';
|
|
24
|
+
import { useSpotPolygons } from './useSpotPolygons';
|
|
25
|
+
import { useMcsRoomInfo } from './useMcsRoomInfo';
|
|
26
|
+
import { useThreshold } from './useThreshold';
|
|
27
|
+
export { useCarpet, useCarpetClean, useVoice, MqttProvider, useDeviceModel, useFurnitureModel, useDevInfo, usePartMerge, usePartDivision, usePassword, useWifiMap, useQuiteHours, useVirtualArea, useSpotClean, useZoneClean, useSelectRoomClean, useVirtualWall, useSchedule, useHistoryMap, useRoomProperty, useResetMap, usePurifierSchedule, useCruise, useSpotPolygons, useMcsRoomInfo, useThreshold, };
|
package/lib/mqtt/index.js
CHANGED
|
@@ -19,4 +19,9 @@ import { useCarpet } from './useCarpet';
|
|
|
19
19
|
import { useCarpetClean } from './useCarpetClean';
|
|
20
20
|
import { useDeviceModel } from './useDeviceModel';
|
|
21
21
|
import { useFurnitureModel } from './useFurnitureModel';
|
|
22
|
-
|
|
22
|
+
import { usePurifierSchedule } from './usePurifierSchedule';
|
|
23
|
+
import { useCruise } from './useCruise';
|
|
24
|
+
import { useSpotPolygons } from './useSpotPolygons';
|
|
25
|
+
import { useMcsRoomInfo } from './useMcsRoomInfo';
|
|
26
|
+
import { useThreshold } from './useThreshold';
|
|
27
|
+
export { useCarpet, useCarpetClean, useVoice, MqttProvider, useDeviceModel, useFurnitureModel, useDevInfo, usePartMerge, usePartDivision, usePassword, useWifiMap, useQuiteHours, useVirtualArea, useSpotClean, useZoneClean, useSelectRoomClean, useVirtualWall, useSchedule, useHistoryMap, useRoomProperty, useResetMap, usePurifierSchedule, useCruise, useSpotPolygons, useMcsRoomInfo, useThreshold };
|
package/lib/mqtt/mqttProvider.js
CHANGED
|
@@ -3,7 +3,7 @@ import { registerMQTTProtocolListener } from '@ray-js/ray';
|
|
|
3
3
|
import { get, isFunction, isNil } from 'lodash-es';
|
|
4
4
|
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
|
|
5
5
|
import { emitter } from '../utils';
|
|
6
|
-
import { setUnhandledRejectionHandler } from './promise';
|
|
6
|
+
import { dispatchUnhandledRejection, setUnhandledRejectionHandler } from './promise';
|
|
7
7
|
import { ProtocolEnum } from './type';
|
|
8
8
|
import log4js from '@ray-js/log4js';
|
|
9
9
|
|
|
@@ -94,25 +94,27 @@ export function MqttProvider(_ref) {
|
|
|
94
94
|
|
|
95
95
|
// 设置全局错误处理器(不依赖 window,适用于小程序环境)
|
|
96
96
|
useEffect(() => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
var _tyGlobal$onUnhandled;
|
|
98
|
+
// 注册处理器:业务方传了 onError 就用它,否则退化为警告日志
|
|
99
|
+
setUnhandledRejectionHandler(onError !== null && onError !== void 0 ? onError : error => {
|
|
100
|
+
console.warn(`[MQTT] Unhandled rejection for ${error.reqType}:`, error.message);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 兜底:监听小程序全局未处理的 Promise rejection。
|
|
104
|
+
// 当业务方"即发即忘"地调用 query/request(未 catch)且失败时,rejection 会走到这里;
|
|
105
|
+
// dispatchUnhandledRejection 只转发本库产生的 MqttError 给上面注册的处理器(onError),
|
|
106
|
+
// 从而避免这类错误作为未处理异常继续向上冒泡,同时不会误吞无关的应用级 rejection。
|
|
107
|
+
const onGlobalUnhandledRejection = res => {
|
|
108
|
+
dispatchUnhandledRejection(res === null || res === void 0 ? void 0 : res.reason);
|
|
109
|
+
};
|
|
110
|
+
// 部分环境 / 旧类型定义未声明该 API,做类型收窄 + 运行时判空,避免非小程序环境(如测试)报错
|
|
111
|
+
const tyGlobal = typeof ty === 'undefined' ? undefined : ty;
|
|
112
|
+
tyGlobal === null || tyGlobal === void 0 || (_tyGlobal$onUnhandled = tyGlobal.onUnhandledRejection) === null || _tyGlobal$onUnhandled === void 0 || _tyGlobal$onUnhandled.call(tyGlobal, onGlobalUnhandledRejection);
|
|
113
113
|
|
|
114
|
-
//
|
|
114
|
+
// 清理函数:组件卸载时移除全局处理器与监听
|
|
115
115
|
return () => {
|
|
116
|
+
var _tyGlobal$offUnhandle;
|
|
117
|
+
tyGlobal === null || tyGlobal === void 0 || (_tyGlobal$offUnhandle = tyGlobal.offUnhandledRejection) === null || _tyGlobal$offUnhandle === void 0 || _tyGlobal$offUnhandle.call(tyGlobal, onGlobalUnhandledRejection);
|
|
116
118
|
setUnhandledRejectionHandler(null);
|
|
117
119
|
};
|
|
118
120
|
}, [onError]);
|
package/lib/mqtt/promise.d.ts
CHANGED
|
@@ -24,6 +24,18 @@ export declare class MqttError extends Error {
|
|
|
24
24
|
reqType: string;
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* 判断是否为本库(MQTT 请求)产生的错误。
|
|
29
|
+
* 用于全局 unhandledrejection 兜底时,只处理本库错误,避免误吞/误报无关的应用级 rejection。
|
|
30
|
+
*/
|
|
31
|
+
export declare function isMqttError(error: unknown): error is MqttError;
|
|
32
|
+
/**
|
|
33
|
+
* 分发一个未被业务方 catch 的 rejection。
|
|
34
|
+
* 仅当它是本库产生的 MQTT 错误、且已通过 setUnhandledRejectionHandler 注册处理器时,才转发给该处理器。
|
|
35
|
+
*
|
|
36
|
+
* @returns 是否已被本库处理(true 表示已转发给 onError,可视为"已消费")
|
|
37
|
+
*/
|
|
38
|
+
export declare function dispatchUnhandledRejection(reason: unknown): boolean;
|
|
27
39
|
/**
|
|
28
40
|
* MQTT 响应消息类型(兼容 MQTT 响应格式)
|
|
29
41
|
*/
|
package/lib/mqtt/promise.js
CHANGED
|
@@ -51,6 +51,33 @@ export class MqttError extends Error {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* 判断是否为本库(MQTT 请求)产生的错误。
|
|
56
|
+
* 用于全局 unhandledrejection 兜底时,只处理本库错误,避免误吞/误报无关的应用级 rejection。
|
|
57
|
+
*/
|
|
58
|
+
export function isMqttError(error) {
|
|
59
|
+
return error instanceof MqttError || (error === null || error === void 0 ? void 0 : error.name) === 'MqttError';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 分发一个未被业务方 catch 的 rejection。
|
|
64
|
+
* 仅当它是本库产生的 MQTT 错误、且已通过 setUnhandledRejectionHandler 注册处理器时,才转发给该处理器。
|
|
65
|
+
*
|
|
66
|
+
* @returns 是否已被本库处理(true 表示已转发给 onError,可视为"已消费")
|
|
67
|
+
*/
|
|
68
|
+
export function dispatchUnhandledRejection(reason) {
|
|
69
|
+
if (!isMqttError(reason) || !globalUnhandledRejectionHandler) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
globalUnhandledRejectionHandler(reason);
|
|
74
|
+
} catch (handlerError) {
|
|
75
|
+
// 避免错误处理器本身抛出错误导致无限循环
|
|
76
|
+
console.error('Error in MQTT error handler:', handlerError);
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
54
81
|
/**
|
|
55
82
|
* MQTT 响应消息类型(兼容 MQTT 响应格式)
|
|
56
83
|
*/
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SetSpotPolygonsData } from './type/protocols/spotPolygonsProtocol';
|
|
2
|
+
export declare const createSpotPolygonsPayload: ({ polygons, spotNames, version, }: SetSpotPolygonsData) => {
|
|
3
|
+
version?: string | undefined;
|
|
4
|
+
num: number;
|
|
5
|
+
polygons: string[];
|
|
6
|
+
spotNames: string[];
|
|
7
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
export const createSpotPolygonsPayload = _ref => {
|
|
3
|
+
let {
|
|
4
|
+
polygons,
|
|
5
|
+
spotNames,
|
|
6
|
+
version
|
|
7
|
+
} = _ref;
|
|
8
|
+
if (polygons.length !== spotNames.length) {
|
|
9
|
+
throw new Error('polygons and spotNames must have the same length');
|
|
10
|
+
}
|
|
11
|
+
return _objectSpread({
|
|
12
|
+
num: polygons.length,
|
|
13
|
+
polygons,
|
|
14
|
+
spotNames
|
|
15
|
+
}, version && {
|
|
16
|
+
version
|
|
17
|
+
});
|
|
18
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { BaseResponse } from './base';
|
|
2
|
+
/** 巡航控制指令 */
|
|
3
|
+
export type CruiseCmd = 'start' | 'pause' | 'resume' | 'stop';
|
|
4
|
+
/** 巡航状态:idle 未巡航 / cruising 巡航中 / paused 已暂停 */
|
|
5
|
+
export type CruiseStatus = 'idle' | 'cruising' | 'paused';
|
|
6
|
+
/** 巡航类型:whole_house 全屋巡航 / spot 定点巡航(按净化点坐标) */
|
|
7
|
+
export type CruiseType = 'whole_house' | 'spot';
|
|
8
|
+
export interface SetCruiseData {
|
|
9
|
+
/** start 开始 / pause 暂停 / resume 继续 / stop 结束 */
|
|
10
|
+
cmd: CruiseCmd;
|
|
11
|
+
/** 巡航类型,cmd 为 start 时必填 */
|
|
12
|
+
cruiseType?: CruiseType;
|
|
13
|
+
/** spot 定点巡航时的净化点坐标列表,格式 "x, y";不传表示全部净化点 */
|
|
14
|
+
polygons?: string[];
|
|
15
|
+
/** spot 定点巡航时的净化点数量,= polygons.length;不传时由设备侧根据 polygons 长度推断 */
|
|
16
|
+
num?: number;
|
|
17
|
+
version?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface RequestCruiseData {
|
|
20
|
+
version?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CruiseResponse extends BaseResponse {
|
|
23
|
+
/** Wiki 协议中的当前巡航指令/状态字段 */
|
|
24
|
+
cmd?: CruiseCmd;
|
|
25
|
+
/** 兼容旧设备的巡航状态 */
|
|
26
|
+
status?: CruiseStatus;
|
|
27
|
+
/** 当前地图 ID,设备可不返回 */
|
|
28
|
+
mapId?: number;
|
|
29
|
+
/** 巡航类型;idle 时可不携带 */
|
|
30
|
+
cruiseType?: CruiseType;
|
|
31
|
+
/** spot 定点巡航时的净化点坐标列表,格式 "x, y" */
|
|
32
|
+
polygons?: string[];
|
|
33
|
+
/** spot 定点巡航时的净化点数量 */
|
|
34
|
+
num?: number;
|
|
35
|
+
/** 当前正在净化的坐标 "x, y" */
|
|
36
|
+
currentPolygon?: string;
|
|
37
|
+
}
|
|
38
|
+
export type TRequestCruise = (message?: RequestCruiseData) => Promise<CruiseResponse>;
|
|
39
|
+
export type TSetCruise = (message: SetCruiseData) => Promise<CruiseResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -18,3 +18,8 @@ export * from './deviceModelProtocol';
|
|
|
18
18
|
export * from './carpetCleanProtocol';
|
|
19
19
|
export * from './devInfoProtocol';
|
|
20
20
|
export * from './roomPropertyProtocol';
|
|
21
|
+
export * from './purifierScheduleProtocol';
|
|
22
|
+
export * from './cruiseProtocol';
|
|
23
|
+
export * from './spotPolygonsProtocol';
|
|
24
|
+
export * from './mcsRoomInfoProtocol';
|
|
25
|
+
export * from './thresholdProtocol';
|
|
@@ -17,4 +17,9 @@ export * from './furnitureModelProtocol';
|
|
|
17
17
|
export * from './deviceModelProtocol';
|
|
18
18
|
export * from './carpetCleanProtocol';
|
|
19
19
|
export * from './devInfoProtocol';
|
|
20
|
-
export * from './roomPropertyProtocol';
|
|
20
|
+
export * from './roomPropertyProtocol';
|
|
21
|
+
export * from './purifierScheduleProtocol';
|
|
22
|
+
export * from './cruiseProtocol';
|
|
23
|
+
export * from './spotPolygonsProtocol';
|
|
24
|
+
export * from './mcsRoomInfoProtocol';
|
|
25
|
+
export * from './thresholdProtocol';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BaseResponse } from './base';
|
|
2
|
+
export interface RequestMcsRoomInfoData {
|
|
3
|
+
/** 协议版本;默认 '1.0.0' */
|
|
4
|
+
version?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* McsRoomInfoQry 应答(RVC SDK Alexa 语音方案协议)。
|
|
8
|
+
* 注意:房间字段为 snake_case(与设备端 MCS_ROOM_INFO_S 结构体对应)。
|
|
9
|
+
*/
|
|
10
|
+
export interface McsRoomInfoResponse extends BaseResponse {
|
|
11
|
+
/** 当前地图 ID */
|
|
12
|
+
mapId: number;
|
|
13
|
+
/** 设备当前所在房间 ID(与 roomPropertyQry 的 ids 对应) */
|
|
14
|
+
curr_room_id: number;
|
|
15
|
+
/** 设备当前所在房间名称 */
|
|
16
|
+
curr_room_name: string;
|
|
17
|
+
}
|
|
18
|
+
export type TRequestMcsRoomInfo = (message?: RequestMcsRoomInfoData) => Promise<McsRoomInfoResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { BaseResponse } from './base';
|
|
2
|
+
/**
|
|
3
|
+
* 工作类型:
|
|
4
|
+
* - select_room 选房净化(携带 ids)
|
|
5
|
+
* - whole_house 整屋净化
|
|
6
|
+
* - spot 定点净化
|
|
7
|
+
* - current_location 原地净化
|
|
8
|
+
*/
|
|
9
|
+
export type PurifierWorkType = 'select_room' | 'whole_house' | 'spot' | 'current_location';
|
|
10
|
+
/** 风速档位,透传字符串,不限制具体取值(不同设备支持的档位不同) */
|
|
11
|
+
export type PurifierFanMode = string;
|
|
12
|
+
export interface PurifierScheduleItem {
|
|
13
|
+
/** 是否启用:1 启用 / 0 禁用 */
|
|
14
|
+
active: number;
|
|
15
|
+
/** 周重复,长度 7(周一~周日),1 生效;全 0 表示仅执行一次 */
|
|
16
|
+
cycle: number[];
|
|
17
|
+
/** 执行时间 [时, 分],24 小时制 */
|
|
18
|
+
time: number[];
|
|
19
|
+
/** 房间 ID 列表;workTypes 为 whole_house / spot / current_location 时为空数组 */
|
|
20
|
+
ids: number[];
|
|
21
|
+
/** 工作类型,与 ids 对齐;非 select_room 时为单元素 */
|
|
22
|
+
workTypes: PurifierWorkType[];
|
|
23
|
+
/** 风速,与 ids 对齐(整屋时单元素) */
|
|
24
|
+
fanModes: PurifierFanMode[];
|
|
25
|
+
/** 风速速度百分比 percent_setting(0-100),与 ids 对齐(整屋时单元素);仅当对应 fanMode 为 manual 时才下发 */
|
|
26
|
+
percents?: number[];
|
|
27
|
+
/** 净化顺序,与 ids 对齐 */
|
|
28
|
+
orders?: number[];
|
|
29
|
+
/** 房间名称,与 ids 对齐 */
|
|
30
|
+
names?: string[];
|
|
31
|
+
/** 净化点坐标 "x, y",与 ids 对齐 */
|
|
32
|
+
polygons?: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface SetPurifierScheduleData {
|
|
35
|
+
/** 定时任务数量,= list.length */
|
|
36
|
+
num: number;
|
|
37
|
+
/** 定时任务列表(覆盖式全量下发) */
|
|
38
|
+
list: PurifierScheduleItem[];
|
|
39
|
+
version?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface RequestPurifierScheduleData {
|
|
42
|
+
version?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface PurifierScheduleResponse extends BaseResponse {
|
|
45
|
+
mapId: number;
|
|
46
|
+
num: number;
|
|
47
|
+
list: PurifierScheduleItem[];
|
|
48
|
+
}
|
|
49
|
+
export type TRequestPurifierSchedule = (message?: RequestPurifierScheduleData) => Promise<PurifierScheduleResponse>;
|
|
50
|
+
export type TSetPurifierSchedule = (message: SetPurifierScheduleData) => Promise<PurifierScheduleResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -13,6 +13,8 @@ export interface SetRoomPropertyData {
|
|
|
13
13
|
orders?: number[];
|
|
14
14
|
routePreferences?: string[];
|
|
15
15
|
waterValues?: number[];
|
|
16
|
+
/** 净化点坐标 "x, y",与 ids 一一对应;空字符串表示该房间未设置净化点 */
|
|
17
|
+
polygons?: string[];
|
|
16
18
|
}
|
|
17
19
|
export interface RoomPropertyResponse extends BaseResponse {
|
|
18
20
|
suctions?: string[];
|
|
@@ -29,6 +31,8 @@ export interface RoomPropertyResponse extends BaseResponse {
|
|
|
29
31
|
orders?: number[];
|
|
30
32
|
routePreferences?: string[];
|
|
31
33
|
waterValues?: number[];
|
|
34
|
+
/** 净化点坐标 "x, y",与 ids 一一对应;空字符串表示该房间未设置净化点 */
|
|
35
|
+
polygons?: string[];
|
|
32
36
|
}
|
|
33
37
|
export type TRequestRoomProperty = () => Promise<RoomPropertyResponse>;
|
|
34
38
|
export type TSetRoomProperty = (data: SetRoomPropertyData) => Promise<RoomPropertyResponse>;
|
|
@@ -3,6 +3,7 @@ export interface SetSpotCleanData extends RoomPreferenceFields {
|
|
|
3
3
|
spots: Point[];
|
|
4
4
|
origin?: Point;
|
|
5
5
|
names?: string[];
|
|
6
|
+
spotNames?: string[];
|
|
6
7
|
}
|
|
7
8
|
export interface SpotCleanResponse extends BaseResponse {
|
|
8
9
|
suctions?: string[];
|
|
@@ -15,6 +16,7 @@ export interface SpotCleanResponse extends BaseResponse {
|
|
|
15
16
|
ids?: number[];
|
|
16
17
|
polygons: string[];
|
|
17
18
|
names?: string[];
|
|
19
|
+
spotNames?: string[];
|
|
18
20
|
}
|
|
19
21
|
export type TRequestSpotClean = () => Promise<SpotCleanResponse>;
|
|
20
22
|
export type TSetSpotClean = (data: SetSpotCleanData) => Promise<SpotCleanResponse>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BaseResponse } from './base';
|
|
2
|
+
export interface SetSpotPolygonsData {
|
|
3
|
+
/** 定点位置坐标,格式为 "x,y" */
|
|
4
|
+
polygons: string[];
|
|
5
|
+
/** 定点位置名称,与 polygons 一一对应 */
|
|
6
|
+
spotNames: string[];
|
|
7
|
+
version?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface RequestSpotPolygonsData {
|
|
10
|
+
version?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SpotPolygonsResponse extends BaseResponse {
|
|
13
|
+
/** 定点位置数量 */
|
|
14
|
+
num: number;
|
|
15
|
+
/** 定点位置坐标,格式为 "x,y" */
|
|
16
|
+
polygons: string[];
|
|
17
|
+
/** 定点位置名称,与 polygons 一一对应 */
|
|
18
|
+
spotNames: string[];
|
|
19
|
+
}
|
|
20
|
+
export type TRequestSpotPolygons = (message?: RequestSpotPolygonsData) => Promise<SpotPolygonsResponse>;
|
|
21
|
+
export type TSetSpotPolygons = (message: SetSpotPolygonsData) => Promise<SpotPolygonsResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BaseResponse, Point } from './base';
|
|
2
|
+
export interface ThresholdItem {
|
|
3
|
+
/** 门槛的 4 个顶点,面板坐标系(未减地图原点) */
|
|
4
|
+
points: Point[];
|
|
5
|
+
/** 门槛类型:0 可通过门槛,1 不可通过门槛,2 坡道 */
|
|
6
|
+
type: number;
|
|
7
|
+
/** 门槛名称,协议预留字段,不传按空字符串下发 */
|
|
8
|
+
name?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SetThresholdData {
|
|
11
|
+
data: ThresholdItem[];
|
|
12
|
+
origin: Point;
|
|
13
|
+
}
|
|
14
|
+
export interface ThresholdResponse extends BaseResponse {
|
|
15
|
+
num: number;
|
|
16
|
+
polygons: string[];
|
|
17
|
+
types: number[];
|
|
18
|
+
names: string[];
|
|
19
|
+
mapId: number;
|
|
20
|
+
}
|
|
21
|
+
export type TRequestThreshold = () => Promise<ThresholdResponse>;
|
|
22
|
+
export type TSetThreshold = (data: SetThresholdData) => Promise<ThresholdResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -46,6 +46,10 @@ export declare enum VirtualAreaEnum {
|
|
|
46
46
|
query = "restrictedAreaQry",
|
|
47
47
|
set = "restrictedAreaSet"
|
|
48
48
|
}
|
|
49
|
+
export declare enum ThresholdEnum {
|
|
50
|
+
query = "thresholdQry",
|
|
51
|
+
set = "thresholdSet"
|
|
52
|
+
}
|
|
49
53
|
export declare enum VoiceLanguageEnum {
|
|
50
54
|
query = "voiceLanguageQry",
|
|
51
55
|
set = "voiceLanguageSet"
|
|
@@ -92,3 +96,18 @@ export declare enum CarpetCleanEnum {
|
|
|
92
96
|
query = "carpetCleanQry",
|
|
93
97
|
set = "carpetCleanSet"
|
|
94
98
|
}
|
|
99
|
+
export declare enum PurifierScheduleEnum {
|
|
100
|
+
query = "purifierScheduleQry",
|
|
101
|
+
set = "purifierScheduleSet"
|
|
102
|
+
}
|
|
103
|
+
export declare enum CruiseEnum {
|
|
104
|
+
query = "purifierCruiseQry",
|
|
105
|
+
set = "purifierCruiseSet"
|
|
106
|
+
}
|
|
107
|
+
export declare enum SpotPolygonsEnum {
|
|
108
|
+
query = "spotPolygonsQry",
|
|
109
|
+
set = "spotPolygonsSet"
|
|
110
|
+
}
|
|
111
|
+
export declare enum McsRoomInfoEnum {
|
|
112
|
+
query = "McsRoomInfoQry"
|
|
113
|
+
}
|
|
@@ -66,6 +66,13 @@ export let VirtualAreaEnum = /*#__PURE__*/function (VirtualAreaEnum) {
|
|
|
66
66
|
return VirtualAreaEnum;
|
|
67
67
|
}({});
|
|
68
68
|
|
|
69
|
+
// 门槛
|
|
70
|
+
export let ThresholdEnum = /*#__PURE__*/function (ThresholdEnum) {
|
|
71
|
+
ThresholdEnum["query"] = "thresholdQry";
|
|
72
|
+
ThresholdEnum["set"] = "thresholdSet";
|
|
73
|
+
return ThresholdEnum;
|
|
74
|
+
}({});
|
|
75
|
+
|
|
69
76
|
// 语音语言枚举
|
|
70
77
|
export let VoiceLanguageEnum = /*#__PURE__*/function (VoiceLanguageEnum) {
|
|
71
78
|
VoiceLanguageEnum["query"] = "voiceLanguageQry";
|
|
@@ -137,4 +144,31 @@ export let CarpetCleanEnum = /*#__PURE__*/function (CarpetCleanEnum) {
|
|
|
137
144
|
CarpetCleanEnum["query"] = "carpetCleanQry";
|
|
138
145
|
CarpetCleanEnum["set"] = "carpetCleanSet";
|
|
139
146
|
return CarpetCleanEnum;
|
|
147
|
+
}({});
|
|
148
|
+
|
|
149
|
+
// 净化定时(移动空气净化器)
|
|
150
|
+
export let PurifierScheduleEnum = /*#__PURE__*/function (PurifierScheduleEnum) {
|
|
151
|
+
PurifierScheduleEnum["query"] = "purifierScheduleQry";
|
|
152
|
+
PurifierScheduleEnum["set"] = "purifierScheduleSet";
|
|
153
|
+
return PurifierScheduleEnum;
|
|
154
|
+
}({});
|
|
155
|
+
|
|
156
|
+
// 巡航(面板通用能力,设备侧使用净化器巡航协议)
|
|
157
|
+
export let CruiseEnum = /*#__PURE__*/function (CruiseEnum) {
|
|
158
|
+
CruiseEnum["query"] = "purifierCruiseQry";
|
|
159
|
+
CruiseEnum["set"] = "purifierCruiseSet";
|
|
160
|
+
return CruiseEnum;
|
|
161
|
+
}({});
|
|
162
|
+
|
|
163
|
+
// 定点位置
|
|
164
|
+
export let SpotPolygonsEnum = /*#__PURE__*/function (SpotPolygonsEnum) {
|
|
165
|
+
SpotPolygonsEnum["query"] = "spotPolygonsQry";
|
|
166
|
+
SpotPolygonsEnum["set"] = "spotPolygonsSet";
|
|
167
|
+
return SpotPolygonsEnum;
|
|
168
|
+
}({});
|
|
169
|
+
|
|
170
|
+
// 设备当前所在房间(MCS 房间信息;RVC SDK Alexa 语音方案协议,通常仅在任务中查询)
|
|
171
|
+
export let McsRoomInfoEnum = /*#__PURE__*/function (McsRoomInfoEnum) {
|
|
172
|
+
McsRoomInfoEnum["query"] = "McsRoomInfoQry";
|
|
173
|
+
return McsRoomInfoEnum;
|
|
140
174
|
}({});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TRequestCruise, type TSetCruise } from './type/protocols/cruiseProtocol';
|
|
2
|
+
/**
|
|
3
|
+
* 自定义 Hook,用于移动设备巡航状态查询与控制(如移动空气净化器、移动垃圾桶)
|
|
4
|
+
* @returns 包含 requestCruise 和 setCruise 函数的对象
|
|
5
|
+
*/
|
|
6
|
+
export declare const useCruise: () => {
|
|
7
|
+
requestCruise: TRequestCruise;
|
|
8
|
+
setCruise: TSetCruise;
|
|
9
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// 巡航(通用:移动空气净化器、移动垃圾桶等移动设备)
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
4
|
+
import { SingletonContext } from './mqttProvider';
|
|
5
|
+
import { createCruisePayload } from './cruise';
|
|
6
|
+
import { CruiseEnum } from './type';
|
|
7
|
+
/**
|
|
8
|
+
* 自定义 Hook,用于移动设备巡航状态查询与控制(如移动空气净化器、移动垃圾桶)
|
|
9
|
+
* @returns 包含 requestCruise 和 setCruise 函数的对象
|
|
10
|
+
*/
|
|
11
|
+
export const useCruise = () => {
|
|
12
|
+
const {
|
|
13
|
+
useMqtt
|
|
14
|
+
} = useContext(SingletonContext);
|
|
15
|
+
const {
|
|
16
|
+
sendStructuredMessage
|
|
17
|
+
} = useStructuredMessage();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 查询巡航状态(status)与巡航类型(cruiseType)
|
|
21
|
+
* @param message 可选参数,包含版本号
|
|
22
|
+
* @returns Promise<CruiseResponse> 响应结果
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 巡航控制:cmd 为 start / pause / resume / stop;start 时需携带 cruiseType
|
|
27
|
+
* @param message 巡航控制数据
|
|
28
|
+
* @returns Promise<CruiseResponse> 响应结果
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
requestCruise: function () {
|
|
33
|
+
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
34
|
+
version: '1.0.0'
|
|
35
|
+
};
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
try {
|
|
38
|
+
if (!useMqtt) {
|
|
39
|
+
reject(new Error('useMqtt is not used'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
sendStructuredMessage(CruiseEnum.query, message, resolve, error => reject(handleMqttError(error, 'Failed to request cruise')));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
reject(handleMqttError(error, 'Failed to request cruise'));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
setCruise: message => {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
try {
|
|
51
|
+
if (!useMqtt) {
|
|
52
|
+
reject(new Error('useMqtt is not used'));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (message.cmd === 'start' && !message.cruiseType) {
|
|
56
|
+
reject(new Error('cruiseType is required when cmd is "start"'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
sendStructuredMessage(CruiseEnum.set, createCruisePayload(message), resolve, error => reject(handleMqttError(error, 'Failed to set cruise')), CruiseEnum.query // 响应类型是 query,不是 set
|
|
60
|
+
);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
reject(handleMqttError(error, 'Failed to set cruise'));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TRequestMcsRoomInfo } from './type/protocols/mcsRoomInfoProtocol';
|
|
2
|
+
/**
|
|
3
|
+
* 自定义 Hook,用于查询设备当前所在房间(mapId / currNameId / currName)。
|
|
4
|
+
* 面板通常仅在设备处于任务中时查询,用于展示「当前位置」。
|
|
5
|
+
* @returns 包含 requestMcsRoomInfo 函数的对象
|
|
6
|
+
*/
|
|
7
|
+
export declare const useMcsRoomInfo: () => {
|
|
8
|
+
requestMcsRoomInfo: TRequestMcsRoomInfo;
|
|
9
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// 设备当前所在房间(MCS 房间信息)
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
4
|
+
import { SingletonContext } from './mqttProvider';
|
|
5
|
+
import { McsRoomInfoEnum } from './type';
|
|
6
|
+
/**
|
|
7
|
+
* 自定义 Hook,用于查询设备当前所在房间(mapId / currNameId / currName)。
|
|
8
|
+
* 面板通常仅在设备处于任务中时查询,用于展示「当前位置」。
|
|
9
|
+
* @returns 包含 requestMcsRoomInfo 函数的对象
|
|
10
|
+
*/
|
|
11
|
+
export const useMcsRoomInfo = () => {
|
|
12
|
+
const {
|
|
13
|
+
useMqtt
|
|
14
|
+
} = useContext(SingletonContext);
|
|
15
|
+
const {
|
|
16
|
+
sendStructuredMessage
|
|
17
|
+
} = useStructuredMessage();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 查询设备当前所在房间
|
|
21
|
+
* @param message 可选参数,包含版本号
|
|
22
|
+
* @returns Promise<McsRoomInfoResponse> 响应结果
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
requestMcsRoomInfo: function () {
|
|
27
|
+
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
28
|
+
version: '1.0.0'
|
|
29
|
+
};
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
try {
|
|
32
|
+
if (!useMqtt) {
|
|
33
|
+
reject(new Error('useMqtt is not used'));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
sendStructuredMessage(McsRoomInfoEnum.query, message, resolve, error => reject(handleMqttError(error, 'Failed to request mcs room info')));
|
|
37
|
+
} catch (error) {
|
|
38
|
+
reject(handleMqttError(error, 'Failed to request mcs room info'));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TRequestPurifierSchedule, type TSetPurifierSchedule } from './type/protocols/purifierScheduleProtocol';
|
|
2
|
+
/**
|
|
3
|
+
* 自定义 Hook,用于净化定时任务管理(移动空气净化器)
|
|
4
|
+
* @returns 包含 requestPurifierSchedule 和 setPurifierSchedule 函数的对象
|
|
5
|
+
*/
|
|
6
|
+
export declare const usePurifierSchedule: () => {
|
|
7
|
+
requestPurifierSchedule: TRequestPurifierSchedule;
|
|
8
|
+
setPurifierSchedule: TSetPurifierSchedule;
|
|
9
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
// 净化定时(移动空气净化器)
|
|
3
|
+
import { useContext } from 'react';
|
|
4
|
+
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
5
|
+
import { SingletonContext } from './mqttProvider';
|
|
6
|
+
import { PurifierScheduleEnum } from './type';
|
|
7
|
+
/**
|
|
8
|
+
* 自定义 Hook,用于净化定时任务管理(移动空气净化器)
|
|
9
|
+
* @returns 包含 requestPurifierSchedule 和 setPurifierSchedule 函数的对象
|
|
10
|
+
*/
|
|
11
|
+
export const usePurifierSchedule = () => {
|
|
12
|
+
const {
|
|
13
|
+
useMqtt
|
|
14
|
+
} = useContext(SingletonContext);
|
|
15
|
+
const {
|
|
16
|
+
sendStructuredMessage
|
|
17
|
+
} = useStructuredMessage();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 请求净化定时数据
|
|
21
|
+
* @param message 可选参数,包含版本号
|
|
22
|
+
* @returns Promise<PurifierScheduleResponse> 响应结果
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 设置净化定时数据(覆盖式全量下发)
|
|
27
|
+
* @param message 定时任务数据
|
|
28
|
+
* @returns Promise<PurifierScheduleResponse> 响应结果
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
requestPurifierSchedule: function () {
|
|
33
|
+
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
34
|
+
version: '1.0.0'
|
|
35
|
+
};
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
try {
|
|
38
|
+
if (!useMqtt) {
|
|
39
|
+
reject(new Error('useMqtt is not used'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
sendStructuredMessage(PurifierScheduleEnum.query, message, resolve, error => reject(handleMqttError(error, 'Failed to request purifier schedule')));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
reject(handleMqttError(error, 'Failed to request purifier schedule'));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
setPurifierSchedule: message => {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
try {
|
|
51
|
+
var _message$num;
|
|
52
|
+
if (!useMqtt) {
|
|
53
|
+
reject(new Error('useMqtt is not used'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
sendStructuredMessage(PurifierScheduleEnum.set, _objectSpread(_objectSpread({}, message), {}, {
|
|
57
|
+
num: (_message$num = message.num) !== null && _message$num !== void 0 ? _message$num : message.list.length
|
|
58
|
+
}), resolve, error => reject(handleMqttError(error, 'Failed to set purifier schedule')), PurifierScheduleEnum.query // 响应类型是 query,不是 set
|
|
59
|
+
);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
reject(handleMqttError(error, 'Failed to set purifier schedule'));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
};
|
|
@@ -57,7 +57,7 @@ export const useRoomProperty = () => {
|
|
|
57
57
|
ids
|
|
58
58
|
} = data;
|
|
59
59
|
const len = ids.length;
|
|
60
|
-
const sendData = _objectSpread(_objectSpread({
|
|
60
|
+
const sendData = _objectSpread(_objectSpread(_objectSpread({
|
|
61
61
|
num: (_data$num = data.num) !== null && _data$num !== void 0 ? _data$num : len,
|
|
62
62
|
ids,
|
|
63
63
|
suctions: (_data$suctions = data.suctions) !== null && _data$suctions !== void 0 ? _data$suctions : new Array(len).fill('closed'),
|
|
@@ -70,6 +70,8 @@ export const useRoomProperty = () => {
|
|
|
70
70
|
orders: data.orders
|
|
71
71
|
}, data.routePreferences && {
|
|
72
72
|
routePreferences: data.routePreferences
|
|
73
|
+
}), data.polygons && {
|
|
74
|
+
polygons: data.polygons
|
|
73
75
|
}), pickWaterFields(len, data.cisterns, data.waterValues));
|
|
74
76
|
sendStructuredMessage(RoomPropertyEnum.set, sendData, resolve, error => reject(handleMqttError(error, 'Failed to set room property')), RoomPropertyEnum.query // 响应类型是 query,不是 set
|
|
75
77
|
);
|
package/lib/mqtt/useSpotClean.js
CHANGED
|
@@ -62,10 +62,11 @@ export const useSpotClean = () => {
|
|
|
62
62
|
yMops = new Array(num).fill(-1),
|
|
63
63
|
sweepMopModes = new Array(num).fill('only_sweep'),
|
|
64
64
|
routePreferences,
|
|
65
|
-
names
|
|
65
|
+
names,
|
|
66
|
+
spotNames
|
|
66
67
|
} = message;
|
|
67
68
|
if (useMqtt) {
|
|
68
|
-
sendStructuredMessage(SpotCleanEnum.set, _objectSpread(_objectSpread(_objectSpread({
|
|
69
|
+
sendStructuredMessage(SpotCleanEnum.set, _objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
69
70
|
num,
|
|
70
71
|
polygons: spots.map(spot => pointsToString([spot], origin)),
|
|
71
72
|
suctions
|
|
@@ -77,6 +78,8 @@ export const useSpotClean = () => {
|
|
|
77
78
|
routePreferences
|
|
78
79
|
}), names && {
|
|
79
80
|
names
|
|
81
|
+
}), spotNames && {
|
|
82
|
+
spotNames
|
|
80
83
|
}), resolve, error => reject(handleMqttError(error, 'Failed to set spot clean')), SpotCleanEnum.query // 响应类型是 query,不是 set
|
|
81
84
|
);
|
|
82
85
|
return;
|
|
@@ -89,7 +92,7 @@ export const useSpotClean = () => {
|
|
|
89
92
|
point: spots[0]
|
|
90
93
|
});
|
|
91
94
|
devices.common.model.actions.command_trans.set(command);
|
|
92
|
-
resolve(_objectSpread(_objectSpread(_objectSpread({
|
|
95
|
+
resolve(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
93
96
|
success: true,
|
|
94
97
|
errCode: 0,
|
|
95
98
|
reqType: SpotCleanEnum.query,
|
|
@@ -105,6 +108,8 @@ export const useSpotClean = () => {
|
|
|
105
108
|
routePreferences
|
|
106
109
|
}), names && {
|
|
107
110
|
names
|
|
111
|
+
}), spotNames && {
|
|
112
|
+
spotNames
|
|
108
113
|
}));
|
|
109
114
|
} catch (error) {
|
|
110
115
|
reject(handleMqttError(error, 'Failed to set spot clean'));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TRequestSpotPolygons, type TSetSpotPolygons } from './type/protocols/spotPolygonsProtocol';
|
|
2
|
+
/**
|
|
3
|
+
* 自定义 Hook,用于定点位置查询与设置
|
|
4
|
+
* @returns 包含 requestSpotPolygons 和 setSpotPolygons 函数的对象
|
|
5
|
+
*/
|
|
6
|
+
export declare const useSpotPolygons: () => {
|
|
7
|
+
requestSpotPolygons: TRequestSpotPolygons;
|
|
8
|
+
setSpotPolygons: TSetSpotPolygons;
|
|
9
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
3
|
+
import { SingletonContext } from './mqttProvider';
|
|
4
|
+
import { createSpotPolygonsPayload } from './spotPolygons';
|
|
5
|
+
import { SpotPolygonsEnum } from './type';
|
|
6
|
+
/**
|
|
7
|
+
* 自定义 Hook,用于定点位置查询与设置
|
|
8
|
+
* @returns 包含 requestSpotPolygons 和 setSpotPolygons 函数的对象
|
|
9
|
+
*/
|
|
10
|
+
export const useSpotPolygons = () => {
|
|
11
|
+
const {
|
|
12
|
+
useMqtt
|
|
13
|
+
} = useContext(SingletonContext);
|
|
14
|
+
const {
|
|
15
|
+
sendStructuredMessage
|
|
16
|
+
} = useStructuredMessage();
|
|
17
|
+
return {
|
|
18
|
+
requestSpotPolygons: function () {
|
|
19
|
+
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
20
|
+
version: '1.0.0'
|
|
21
|
+
};
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
try {
|
|
24
|
+
if (!useMqtt) {
|
|
25
|
+
reject(new Error('useMqtt is not used'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
sendStructuredMessage(SpotPolygonsEnum.query, message, resolve, error => reject(handleMqttError(error, 'Failed to request spot polygons')));
|
|
29
|
+
} catch (error) {
|
|
30
|
+
reject(handleMqttError(error, 'Failed to request spot polygons'));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
setSpotPolygons: message => {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
try {
|
|
37
|
+
if (!useMqtt) {
|
|
38
|
+
reject(new Error('useMqtt is not used'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
sendStructuredMessage(SpotPolygonsEnum.set, createSpotPolygonsPayload(message), resolve, error => reject(handleMqttError(error, 'Failed to set spot polygons')), SpotPolygonsEnum.query);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
reject(handleMqttError(error, 'Failed to set spot polygons'));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type TRequestThreshold, type TSetThreshold } from './type/protocols';
|
|
2
|
+
/**
|
|
3
|
+
* 自定义 Hook,用于门槛管理(可通过门槛 / 不可通过门槛 / 坡道)
|
|
4
|
+
* 门槛协议仅支持 MQTT / LAN 结构化消息通道,未启用 useMqtt 时直接 reject
|
|
5
|
+
* @returns 包含 requestThreshold 和 setThreshold 函数的对象
|
|
6
|
+
*/
|
|
7
|
+
export declare const useThreshold: () => {
|
|
8
|
+
requestThreshold: TRequestThreshold;
|
|
9
|
+
setThreshold: TSetThreshold;
|
|
10
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.for-each.js";
|
|
3
|
+
// 门槛(可通过门槛 / 不可通过门槛 / 坡道)
|
|
4
|
+
import { useContext } from 'react';
|
|
5
|
+
import { pointsToString } from '../utils';
|
|
6
|
+
import { handleMqttError, useStructuredMessage } from './hooks/useStructuredMessage';
|
|
7
|
+
import { SingletonContext } from './mqttProvider';
|
|
8
|
+
import { ThresholdEnum } from './type';
|
|
9
|
+
// 门槛
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 自定义 Hook,用于门槛管理(可通过门槛 / 不可通过门槛 / 坡道)
|
|
13
|
+
* 门槛协议仅支持 MQTT / LAN 结构化消息通道,未启用 useMqtt 时直接 reject
|
|
14
|
+
* @returns 包含 requestThreshold 和 setThreshold 函数的对象
|
|
15
|
+
*/
|
|
16
|
+
export const useThreshold = () => {
|
|
17
|
+
const {
|
|
18
|
+
useMqtt
|
|
19
|
+
} = useContext(SingletonContext);
|
|
20
|
+
const {
|
|
21
|
+
sendStructuredMessage
|
|
22
|
+
} = useStructuredMessage();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 请求门槛数据
|
|
26
|
+
* @returns Promise<ThresholdResponse> 响应结果
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 设置门槛数据(全量覆盖,传空数组表示清空全部门槛)
|
|
31
|
+
* @param message 包含门槛设置参数的对象
|
|
32
|
+
* @param message.data 门槛的数据数组,每项含 4 个顶点、类型与可选名称
|
|
33
|
+
* @param message.origin 原点坐标
|
|
34
|
+
* @returns Promise<ThresholdResponse> 响应结果
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
requestThreshold: () => {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
try {
|
|
41
|
+
if (!useMqtt) {
|
|
42
|
+
reject(new Error('useMqtt is not used'));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
sendStructuredMessage(ThresholdEnum.query, {}, resolve, error => reject(handleMqttError(error, 'Failed to request threshold')));
|
|
46
|
+
} catch (error) {
|
|
47
|
+
reject(handleMqttError(error, 'Failed to request threshold'));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
setThreshold: message => {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
try {
|
|
54
|
+
if (!useMqtt) {
|
|
55
|
+
reject(new Error('useMqtt is not used'));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const {
|
|
59
|
+
data,
|
|
60
|
+
origin
|
|
61
|
+
} = message;
|
|
62
|
+
const polygons = [];
|
|
63
|
+
const types = [];
|
|
64
|
+
const names = [];
|
|
65
|
+
data.forEach(_ref => {
|
|
66
|
+
let {
|
|
67
|
+
points,
|
|
68
|
+
type,
|
|
69
|
+
name
|
|
70
|
+
} = _ref;
|
|
71
|
+
polygons.push(pointsToString(points, origin));
|
|
72
|
+
types.push(type);
|
|
73
|
+
names.push(name !== null && name !== void 0 ? name : '');
|
|
74
|
+
});
|
|
75
|
+
sendStructuredMessage(ThresholdEnum.set, {
|
|
76
|
+
num: data.length,
|
|
77
|
+
polygons,
|
|
78
|
+
types,
|
|
79
|
+
names
|
|
80
|
+
}, resolve, error => reject(handleMqttError(error, 'Failed to set threshold')), ThresholdEnum.query // 响应类型是 query,不是 set
|
|
81
|
+
);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
reject(handleMqttError(error, 'Failed to set threshold'));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
};
|