@ray-js/robot-data-stream 0.0.14 → 0.0.15-beta.2
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/createCommonOptions.d.ts +4 -2
- package/lib/mqtt/createCommonOptions.js +10 -5
- package/lib/mqtt/hooks/useStructuredMessage.d.ts +14 -0
- package/lib/mqtt/hooks/useStructuredMessage.js +131 -0
- package/lib/mqtt/mqttProvider.d.ts +19 -1
- package/lib/mqtt/mqttProvider.js +69 -8
- package/lib/mqtt/promise.d.ts +57 -4
- package/lib/mqtt/promise.js +115 -36
- package/lib/mqtt/type/fun.d.ts +49 -0
- package/lib/mqtt/type/fun.js +145 -0
- package/lib/mqtt/type/index.d.ts +0 -7
- package/lib/mqtt/type/index.js +0 -1
- package/lib/mqtt/type/protocols/base.d.ts +5 -0
- package/lib/mqtt/type/protocols/base.js +32 -0
- package/lib/mqtt/type/protocols/carpetCleanProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/carpetCleanProtocol.js +16 -0
- package/lib/mqtt/type/protocols/carpetProtocol.d.ts +41 -0
- package/lib/mqtt/type/protocols/carpetProtocol.js +202 -0
- package/lib/mqtt/type/protocols/devInfoProtocol.d.ts +5 -0
- package/lib/mqtt/type/protocols/devInfoProtocol.js +12 -0
- package/lib/mqtt/type/protocols/deviceModelProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/deviceModelProtocol.js +34 -0
- package/lib/mqtt/type/protocols/furnitureModelProtocol.d.ts +10 -0
- package/lib/mqtt/type/protocols/furnitureModelProtocol.js +35 -0
- package/lib/mqtt/type/protocols/historyMapProtocol.d.ts +17 -0
- package/lib/mqtt/type/protocols/historyMapProtocol.js +37 -0
- package/lib/mqtt/type/protocols/index.d.ts +20 -0
- package/lib/mqtt/type/protocols/index.js +20 -0
- package/lib/mqtt/type/protocols/partDivisionProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/partDivisionProtocol.js +12 -0
- package/lib/mqtt/type/protocols/partMergeProtocol.d.ts +7 -0
- package/lib/mqtt/type/protocols/partMergeProtocol.js +12 -0
- package/lib/mqtt/type/protocols/passwordProtocol.d.ts +11 -0
- package/lib/mqtt/type/protocols/passwordProtocol.js +25 -0
- package/lib/mqtt/type/protocols/quietHoursProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/quietHoursProtocol.js +35 -0
- package/lib/mqtt/type/protocols/resetMapProtocol.d.ts +4 -0
- package/lib/mqtt/type/protocols/resetMapProtocol.js +1 -0
- package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +14 -0
- package/lib/mqtt/type/protocols/roomPropertyProtocol.js +113 -0
- package/lib/mqtt/type/protocols/scheduleProtocol.d.ts +18 -0
- package/lib/mqtt/type/protocols/scheduleProtocol.js +100 -0
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.js +40 -0
- package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +9 -0
- package/lib/mqtt/type/protocols/spotCleanProtocol.js +72 -0
- package/lib/mqtt/type/protocols/virtualAreaProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/virtualAreaProtocol.js +36 -0
- package/lib/mqtt/type/protocols/virtualWallProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/virtualWallProtocol.js +25 -0
- package/lib/mqtt/type/protocols/voiceProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/voiceProtocol.js +23 -0
- package/lib/mqtt/type/protocols/wifiMapProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/wifiMapProtocol.js +14 -0
- package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +8 -0
- package/lib/mqtt/type/protocols/zoneCleanProtocol.js +49 -0
- package/lib/mqtt/useCarpet.d.ts +7 -67
- package/lib/mqtt/useCarpet.js +101 -181
- package/lib/mqtt/useCarpetClean.d.ts +2 -11
- package/lib/mqtt/useCarpetClean.js +24 -51
- package/lib/mqtt/useDevInfo.d.ts +8 -6
- package/lib/mqtt/useDevInfo.js +44 -36
- package/lib/mqtt/useDeviceModel.d.ts +6 -19
- package/lib/mqtt/useDeviceModel.js +29 -42
- package/lib/mqtt/useFurnitureModel.d.ts +6 -18
- package/lib/mqtt/useFurnitureModel.js +29 -43
- package/lib/mqtt/useHistoryMap.d.ts +2 -18
- package/lib/mqtt/useHistoryMap.js +102 -119
- package/lib/mqtt/usePartDivision.d.ts +2 -9
- package/lib/mqtt/usePartDivision.js +48 -57
- package/lib/mqtt/usePartMerge.d.ts +2 -8
- package/lib/mqtt/usePartMerge.js +34 -49
- package/lib/mqtt/usePassword.d.ts +6 -13
- package/lib/mqtt/usePassword.js +84 -74
- package/lib/mqtt/useQuiteHours.d.ts +4 -37
- package/lib/mqtt/useQuiteHours.js +66 -100
- package/lib/mqtt/useResetMap.d.ts +2 -8
- package/lib/mqtt/useResetMap.js +27 -34
- package/lib/mqtt/useRoomProperty.d.ts +8 -9
- package/lib/mqtt/useRoomProperty.js +67 -65
- package/lib/mqtt/useSchedule.d.ts +3 -23
- package/lib/mqtt/useSchedule.js +72 -101
- package/lib/mqtt/useSelectRoomClean.d.ts +3 -24
- package/lib/mqtt/useSelectRoomClean.js +107 -133
- package/lib/mqtt/useSpotClean.d.ts +5 -15
- package/lib/mqtt/useSpotClean.js +68 -121
- package/lib/mqtt/useVirtualArea.d.ts +6 -17
- package/lib/mqtt/useVirtualArea.js +109 -119
- package/lib/mqtt/useVirtualWall.d.ts +2 -18
- package/lib/mqtt/useVirtualWall.js +69 -90
- package/lib/mqtt/useVoice.d.ts +2 -16
- package/lib/mqtt/useVoice.js +48 -68
- package/lib/mqtt/useWifiMap.d.ts +6 -5
- package/lib/mqtt/useWifiMap.js +43 -42
- package/lib/mqtt/useZoneClean.d.ts +2 -21
- package/lib/mqtt/useZoneClean.js +125 -137
- package/lib/myLib/zod/mini/index.d.cts +1 -0
- package/lib/myLib/zod/mini/index.d.ts +1 -0
- package/lib/myLib/zod/mini/index.js +1 -0
- package/lib/myLib/zod/mini/package.json +6 -0
- package/lib/myLib/zod/src/mini/index.d.ts +1 -0
- package/lib/myLib/zod/src/mini/index.js +1 -0
- package/lib/myLib/zod/src/v4/core/api.d.ts +306 -0
- package/lib/myLib/zod/src/v4/core/api.js +1256 -0
- package/lib/myLib/zod/src/v4/core/checks.d.ts +278 -0
- package/lib/myLib/zod/src/v4/core/checks.js +816 -0
- package/lib/myLib/zod/src/v4/core/config.d.ts +9 -0
- package/lib/myLib/zod/src/v4/core/config.js +5 -0
- package/lib/myLib/zod/src/v4/core/core.d.ts +70 -0
- package/lib/myLib/zod/src/v4/core/core.js +95 -0
- package/lib/myLib/zod/src/v4/core/doc.d.ts +14 -0
- package/lib/myLib/zod/src/v4/core/doc.js +42 -0
- package/lib/myLib/zod/src/v4/core/errors.d.ts +220 -0
- package/lib/myLib/zod/src/v4/core/errors.js +232 -0
- package/lib/myLib/zod/src/v4/core/index.d.ts +15 -0
- package/lib/myLib/zod/src/v4/core/index.js +15 -0
- package/lib/myLib/zod/src/v4/core/json-schema-generator.d.ts +65 -0
- package/lib/myLib/zod/src/v4/core/json-schema-generator.js +120 -0
- package/lib/myLib/zod/src/v4/core/json-schema-processors.d.ts +49 -0
- package/lib/myLib/zod/src/v4/core/json-schema-processors.js +593 -0
- package/lib/myLib/zod/src/v4/core/json-schema.d.ts +88 -0
- package/lib/myLib/zod/src/v4/core/json-schema.js +1 -0
- package/lib/myLib/zod/src/v4/core/parse.d.ts +49 -0
- package/lib/myLib/zod/src/v4/core/parse.js +147 -0
- package/lib/myLib/zod/src/v4/core/regexes.d.ts +78 -0
- package/lib/myLib/zod/src/v4/core/regexes.js +146 -0
- package/lib/myLib/zod/src/v4/core/registries.d.ts +35 -0
- package/lib/myLib/zod/src/v4/core/registries.js +51 -0
- package/lib/myLib/zod/src/v4/core/schemas.d.ts +1136 -0
- package/lib/myLib/zod/src/v4/core/schemas.js +2745 -0
- package/lib/myLib/zod/src/v4/core/standard-schema.d.ts +126 -0
- package/lib/myLib/zod/src/v4/core/standard-schema.js +1 -0
- package/lib/myLib/zod/src/v4/core/to-json-schema.d.ts +114 -0
- package/lib/myLib/zod/src/v4/core/to-json-schema.js +488 -0
- package/lib/myLib/zod/src/v4/core/util.d.ts +199 -0
- package/lib/myLib/zod/src/v4/core/util.js +656 -0
- package/lib/myLib/zod/src/v4/core/versions.d.ts +5 -0
- package/lib/myLib/zod/src/v4/core/versions.js +5 -0
- package/lib/myLib/zod/src/v4/core/zsf.d.ts +91 -0
- package/lib/myLib/zod/src/v4/core/zsf.js +1 -0
- package/lib/myLib/zod/src/v4/mini/checks.d.ts +1 -0
- package/lib/myLib/zod/src/v4/mini/checks.js +1 -0
- package/lib/myLib/zod/src/v4/mini/coerce.d.ts +7 -0
- package/lib/myLib/zod/src/v4/mini/coerce.js +27 -0
- package/lib/myLib/zod/src/v4/mini/external.d.ts +11 -0
- package/lib/myLib/zod/src/v4/mini/external.js +16 -0
- package/lib/myLib/zod/src/v4/mini/index.d.ts +530 -0
- package/lib/myLib/zod/src/v4/mini/index.js +30 -0
- package/lib/myLib/zod/src/v4/mini/iso.d.ts +22 -0
- package/lib/myLib/zod/src/v4/mini/iso.js +46 -0
- package/lib/myLib/zod/src/v4/mini/parse.d.ts +1 -0
- package/lib/myLib/zod/src/v4/mini/parse.js +1 -0
- package/lib/myLib/zod/src/v4/mini/schemas.js +1244 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +2 -1
- package/package.json +5 -3
|
@@ -22,6 +22,8 @@ export interface CreateSetCommonParamsInput {
|
|
|
22
22
|
deviceId: string;
|
|
23
23
|
/** 请求类型 */
|
|
24
24
|
reqType: string;
|
|
25
|
+
/** 是否是局域网 */
|
|
26
|
+
isLocalOnLine: boolean;
|
|
25
27
|
/** 消息体(可选) */
|
|
26
28
|
message?: Partial<MqttMessage>;
|
|
27
29
|
/** 版本号(可选,默认为 1.0.0) */
|
|
@@ -36,7 +38,7 @@ export interface CreateSetCommonParamsOutput {
|
|
|
36
38
|
/** 设备ID */
|
|
37
39
|
deviceId: string;
|
|
38
40
|
/** 消息体 */
|
|
39
|
-
message: MqttMessage;
|
|
41
|
+
message: MqttMessage | string;
|
|
40
42
|
/** 选项 */
|
|
41
43
|
options: MqttOptions;
|
|
42
44
|
/** 协议号 */
|
|
@@ -62,4 +64,4 @@ export interface CreateSetCommonParamsOutput {
|
|
|
62
64
|
* });
|
|
63
65
|
* ```
|
|
64
66
|
*/
|
|
65
|
-
export declare const createSetCommonParams: ({ deviceId, reqType, message, version, options, }: CreateSetCommonParamsInput) => CreateSetCommonParamsOutput;
|
|
67
|
+
export declare const createSetCommonParams: ({ deviceId, reqType, isLocalOnLine, message, version, options, }: CreateSetCommonParamsInput) => CreateSetCommonParamsOutput;
|
|
@@ -46,18 +46,23 @@ export const createSetCommonParams = _ref => {
|
|
|
46
46
|
let {
|
|
47
47
|
deviceId,
|
|
48
48
|
reqType,
|
|
49
|
+
isLocalOnLine,
|
|
49
50
|
message = {},
|
|
50
51
|
version = DEFAULT_VERSION,
|
|
51
52
|
options = {}
|
|
52
53
|
} = _ref;
|
|
53
54
|
const taskId = Date.now();
|
|
55
|
+
const messageData = _objectSpread({
|
|
56
|
+
reqType,
|
|
57
|
+
version,
|
|
58
|
+
taskId: `${taskId}`
|
|
59
|
+
}, message);
|
|
54
60
|
return {
|
|
55
61
|
deviceId,
|
|
56
|
-
message:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}, message),
|
|
62
|
+
message: !isLocalOnLine ? messageData : JSON.stringify({
|
|
63
|
+
data: messageData,
|
|
64
|
+
reqType
|
|
65
|
+
}),
|
|
61
66
|
options,
|
|
62
67
|
protocol: ProtocolEnum.appToRobot
|
|
63
68
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一的 MQTT 消息发送 Hook
|
|
3
|
+
* 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
|
|
4
|
+
*/
|
|
5
|
+
export declare const useStructuredMessage: () => {
|
|
6
|
+
sendStructuredMessage: <T extends z.infer<any>>(reqType: string, message: Record<string, any> | undefined, resolve: (value: T) => void, reject: (reason?: any) => void, responseType?: string) => void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* 错误处理工具函数
|
|
10
|
+
* @param error 错误对象
|
|
11
|
+
* @param defaultMessage 默认错误消息
|
|
12
|
+
* @returns Error 对象
|
|
13
|
+
*/
|
|
14
|
+
export declare const handleMqttError: (error: unknown, defaultMessage: string) => Error;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import { getDeviceOnlineType, onDeviceOnlineStatusUpdate } from '@ray-js/ray';
|
|
3
|
+
import { isFunction } from 'lodash-es';
|
|
4
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
5
|
+
import { getBitValue, logger } from '../../utils';
|
|
6
|
+
import { createSetCommonParams } from '../createCommonOptions';
|
|
7
|
+
import { useMqtt } from '../mqttProvider';
|
|
8
|
+
import { normalResolve } from '../promise';
|
|
9
|
+
/**
|
|
10
|
+
* 统一的 MQTT 消息发送 Hook
|
|
11
|
+
* 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
|
|
12
|
+
*/
|
|
13
|
+
export const useStructuredMessage = () => {
|
|
14
|
+
const context = useMqtt();
|
|
15
|
+
const {
|
|
16
|
+
devId
|
|
17
|
+
} = context.devices.common.getDevInfo();
|
|
18
|
+
const isLocalOnLineRef = useRef(false);
|
|
19
|
+
const isWifiOnLineRef = useRef(true);
|
|
20
|
+
const _onDeviceOnlineStatusChange = useCallback(_ref => {
|
|
21
|
+
let {
|
|
22
|
+
onlineType
|
|
23
|
+
} = _ref;
|
|
24
|
+
// bit 0: WiFi在线
|
|
25
|
+
const wifiOnline = !!getBitValue(onlineType, 0);
|
|
26
|
+
// bit 1: 局域网在线
|
|
27
|
+
const localOnline = !!getBitValue(onlineType, 1);
|
|
28
|
+
logger('info', {
|
|
29
|
+
msg: `onDeviceOnlineStatusChange00000: onlineType ==>${onlineType}===>wifiOnline:${wifiOnline}===>localOnline:${localOnline}`
|
|
30
|
+
});
|
|
31
|
+
isLocalOnLineRef.current = localOnline;
|
|
32
|
+
isWifiOnLineRef.current = wifiOnline;
|
|
33
|
+
}, []);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!devId) return;
|
|
36
|
+
getDeviceOnlineType({
|
|
37
|
+
deviceId: devId,
|
|
38
|
+
success: _onDeviceOnlineStatusChange
|
|
39
|
+
});
|
|
40
|
+
onDeviceOnlineStatusUpdate(_onDeviceOnlineStatusChange);
|
|
41
|
+
}, [_onDeviceOnlineStatusChange, devId]);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 发送 MQTT 消息
|
|
45
|
+
* @param reqType 请求类型
|
|
46
|
+
* @param message 消息体(可选)
|
|
47
|
+
* @param responseType 响应类型(可选,如果不提供则使用 reqType)
|
|
48
|
+
* @param resolve Promise 的 resolve 回调
|
|
49
|
+
* @param reject Promise 的 reject 回调
|
|
50
|
+
*/
|
|
51
|
+
const sendStructuredMessage = useCallback((reqType, message, resolve, reject, responseType) => {
|
|
52
|
+
if (!devId) {
|
|
53
|
+
reject(new Error('devId is required'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// 检查是否使用 MQTT 模式
|
|
57
|
+
if (!context.useMqtt) {
|
|
58
|
+
reject(new Error(`Operation ${reqType} requires MQTT mode. Please enable useMqtt in MqttProvider.`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
var _ty, _ty2;
|
|
63
|
+
const params = createSetCommonParams({
|
|
64
|
+
deviceId: devId,
|
|
65
|
+
reqType,
|
|
66
|
+
message,
|
|
67
|
+
isLocalOnLine: isLocalOnLineRef.current
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// 优先使用局域网通信(LAN)
|
|
71
|
+
if (isLocalOnLineRef.current && (_ty = ty) !== null && _ty !== void 0 && _ty.device && isFunction(ty.device.publishLanMessage)) {
|
|
72
|
+
// @ts-ignore - publishLanMessage 可能不存在于类型定义中
|
|
73
|
+
ty.device.publishLanMessage(_objectSpread(_objectSpread({}, params), {}, {
|
|
74
|
+
success: () => {
|
|
75
|
+
logger('info', {
|
|
76
|
+
msg: `${reqType} LAN message publish success: ${JSON.stringify(params)}`
|
|
77
|
+
});
|
|
78
|
+
// 局域网通信成功回调
|
|
79
|
+
},
|
|
80
|
+
fail: e => {
|
|
81
|
+
logger('error', {
|
|
82
|
+
msg: `${reqType} LAN message publish failed: ${JSON.stringify(e)}`
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
// 如果局域网不可用,使用 WiFi MQTT 通信
|
|
88
|
+
else if (isWifiOnLineRef.current && (_ty2 = ty) !== null && _ty2 !== void 0 && _ty2.device && isFunction(ty.device.sendMqttMessage)) {
|
|
89
|
+
ty.device.sendMqttMessage(_objectSpread(_objectSpread({}, params), {}, {
|
|
90
|
+
success: () => {
|
|
91
|
+
// WiFi MQTT 通信成功回调
|
|
92
|
+
logger('info', {
|
|
93
|
+
msg: `${reqType} WiFi MQTT message send success: ${JSON.stringify(params)}`
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
fail: e => {
|
|
97
|
+
logger('error', {
|
|
98
|
+
msg: `${reqType} MQTT message send failed: ${JSON.stringify(e)}`
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
// 如果两种通信方式都不可用,抛出错误
|
|
104
|
+
else {
|
|
105
|
+
reject(new Error(`No available communication method. LAN online: ${isLocalOnLineRef.current}, WiFi online: ${isWifiOnLineRef.current}`));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// 如果指定了响应类型,使用响应类型;否则使用请求类型
|
|
109
|
+
|
|
110
|
+
normalResolve(responseType || reqType, resolve, reject);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
reject(error);
|
|
113
|
+
}
|
|
114
|
+
}, [devId, context.useMqtt]);
|
|
115
|
+
return {
|
|
116
|
+
sendStructuredMessage
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 错误处理工具函数
|
|
122
|
+
* @param error 错误对象
|
|
123
|
+
* @param defaultMessage 默认错误消息
|
|
124
|
+
* @returns Error 对象
|
|
125
|
+
*/
|
|
126
|
+
export const handleMqttError = (error, defaultMessage) => {
|
|
127
|
+
if (error instanceof Error) {
|
|
128
|
+
return error;
|
|
129
|
+
}
|
|
130
|
+
return new Error(defaultMessage);
|
|
131
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { MqttError } from './promise';
|
|
2
3
|
export interface MqttContextValue {
|
|
3
4
|
useMqtt: boolean;
|
|
4
5
|
commandVersion: '0' | '1';
|
|
@@ -19,15 +20,32 @@ export interface MqttContextValue {
|
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
export declare const SingletonContext: React.Context<MqttContextValue | null>;
|
|
23
|
+
export type MqttErrorHandler = (error: MqttError) => void;
|
|
22
24
|
export interface MqttProviderProps {
|
|
23
25
|
children: React.ReactNode;
|
|
24
26
|
useMqtt: boolean;
|
|
25
27
|
commandVersion: '0' | '1';
|
|
26
28
|
devices: MqttContextValue['devices'];
|
|
27
29
|
onMqttReady?: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* 可选的错误处理回调
|
|
32
|
+
* 当 MQTT 请求发生未捕获的错误时(如超时、请求失败等),会调用此回调
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* <MqttProvider
|
|
37
|
+
* onError={(error) => {
|
|
38
|
+
* console.error('MQTT Error:', error);
|
|
39
|
+
* // 可以发送到错误监控服务
|
|
40
|
+
* }}
|
|
41
|
+
* ...
|
|
42
|
+
* />
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
onError?: MqttErrorHandler;
|
|
28
46
|
}
|
|
29
47
|
export declare function useMqtt(): MqttContextValue;
|
|
30
|
-
export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onMqttReady, }: MqttProviderProps): React.JSX.Element;
|
|
48
|
+
export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onError, onMqttReady, }: MqttProviderProps): React.JSX.Element;
|
|
31
49
|
export declare namespace MqttProvider {
|
|
32
50
|
var defaultProps: {
|
|
33
51
|
onMqttReady: undefined;
|
package/lib/mqtt/mqttProvider.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import {
|
|
2
|
+
import { registerMQTTProtocolListener } from '@ray-js/ray';
|
|
3
|
+
import { get, isFunction, isNil } from 'lodash-es';
|
|
3
4
|
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
|
|
4
5
|
import { emitter } from '../utils';
|
|
6
|
+
import { setUnhandledRejectionHandler } from './promise';
|
|
5
7
|
import { ProtocolEnum } from './type';
|
|
8
|
+
import log4js from '@ray-js/log4js';
|
|
6
9
|
|
|
7
10
|
// Context 类型定义
|
|
8
11
|
|
|
9
12
|
// 创建一个Context
|
|
10
13
|
export const SingletonContext = /*#__PURE__*/createContext(null);
|
|
11
14
|
|
|
15
|
+
// MQTT 错误处理函数类型
|
|
16
|
+
|
|
12
17
|
// MqttProvider Props 类型定义
|
|
13
18
|
|
|
14
19
|
// MQTT 消息数据类型
|
|
@@ -27,13 +32,19 @@ export function MqttProvider(_ref) {
|
|
|
27
32
|
useMqtt,
|
|
28
33
|
commandVersion,
|
|
29
34
|
devices,
|
|
35
|
+
onError,
|
|
30
36
|
onMqttReady
|
|
31
37
|
} = _ref;
|
|
38
|
+
// const [isLocalOnLine, setIsLocalOnLine] = useState(false);
|
|
39
|
+
// const [isWifiOnLine, setIsWifiOnLine] = useState(true);
|
|
40
|
+
|
|
32
41
|
// 使用 useMemo 创建实例,确保只在依赖项变化时重新创建
|
|
33
42
|
const instance = useMemo(() => ({
|
|
34
43
|
useMqtt,
|
|
35
44
|
commandVersion,
|
|
36
45
|
devices
|
|
46
|
+
// isLocalOnLine,
|
|
47
|
+
// isWifiOnLine,
|
|
37
48
|
}), [useMqtt, commandVersion, devices]);
|
|
38
49
|
|
|
39
50
|
// 使用 ref 存储设备 ID 和初始化状态,避免重复初始化
|
|
@@ -67,9 +78,46 @@ export function MqttProvider(_ref) {
|
|
|
67
78
|
});
|
|
68
79
|
emitter.emit(reqType, responseData);
|
|
69
80
|
}, []);
|
|
81
|
+
const onSocketMessageReceived = useCallback(event => {
|
|
82
|
+
const {
|
|
83
|
+
message
|
|
84
|
+
} = event || {};
|
|
85
|
+
log4js.info('onSocketMessageReceived======>', {
|
|
86
|
+
msg: JSON.stringify(message)
|
|
87
|
+
});
|
|
88
|
+
if (message !== null && message !== void 0 && message.data && message !== null && message !== void 0 && message.reqType) {
|
|
89
|
+
emitter.emit(message.reqType, message.data);
|
|
90
|
+
}
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
// 设置全局错误处理器(不依赖 window,适用于小程序环境)
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (onError) {
|
|
96
|
+
// 设置全局错误处理器
|
|
97
|
+
setUnhandledRejectionHandler(error => {
|
|
98
|
+
try {
|
|
99
|
+
onError(error);
|
|
100
|
+
} catch (handlerError) {
|
|
101
|
+
// 避免错误处理器本身抛出错误导致无限循环
|
|
102
|
+
console.error('Error in MQTT error handler:', handlerError);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
// 如果没有提供错误处理器,设置默认处理器(记录警告)
|
|
107
|
+
setUnhandledRejectionHandler(error => {
|
|
108
|
+
console.warn(`[MQTT] Unhandled rejection for ${error.reqType}:`, error.message);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 清理函数:组件卸载时移除全局处理器
|
|
113
|
+
return () => {
|
|
114
|
+
setUnhandledRejectionHandler(null);
|
|
115
|
+
};
|
|
116
|
+
}, [onError]);
|
|
70
117
|
|
|
71
118
|
// 初始化 MQTT 监听器(只执行一次)
|
|
72
119
|
useEffect(() => {
|
|
120
|
+
var _ty;
|
|
73
121
|
// 防止重复初始化
|
|
74
122
|
if (isInitializedRef.current) return;
|
|
75
123
|
|
|
@@ -88,10 +136,11 @@ export function MqttProvider(_ref) {
|
|
|
88
136
|
}
|
|
89
137
|
|
|
90
138
|
// 注册 MQTT 协议监听器
|
|
91
|
-
|
|
139
|
+
registerMQTTProtocolListener({
|
|
92
140
|
protocol: ProtocolEnum.robotToApp,
|
|
93
141
|
success: () => {
|
|
94
142
|
console.log('注册mqtt成功');
|
|
143
|
+
onMqttReady === null || onMqttReady === void 0 || onMqttReady();
|
|
95
144
|
},
|
|
96
145
|
fail: error => {
|
|
97
146
|
console.error('注册mqtt失败:', error);
|
|
@@ -105,14 +154,26 @@ export function MqttProvider(_ref) {
|
|
|
105
154
|
}
|
|
106
155
|
});
|
|
107
156
|
|
|
157
|
+
// 注册设备服务监听器(如果方法存在)
|
|
158
|
+
// @ts-ignore - registerDeviceServiceListener 可能不存在于类型定义中
|
|
159
|
+
if ((_ty = ty) !== null && _ty !== void 0 && _ty.device && isFunction(ty.device.registerDeviceServiceListener)) {
|
|
160
|
+
var _ty2;
|
|
161
|
+
// @ts-ignore
|
|
162
|
+
ty.device.registerDeviceServiceListener({
|
|
163
|
+
success: event => {
|
|
164
|
+
console.log(event, '++++++++++2222++++++');
|
|
165
|
+
},
|
|
166
|
+
fail: e => {
|
|
167
|
+
console.log(e);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
// 注册 Socket 消息接收监听器
|
|
171
|
+
(_ty2 = ty) === null || _ty2 === void 0 || (_ty2 = _ty2.device) === null || _ty2 === void 0 || _ty2.onSocketMessageReceived(onSocketMessageReceived);
|
|
172
|
+
}
|
|
173
|
+
|
|
108
174
|
// 标记为已初始化
|
|
109
175
|
isInitializedRef.current = true;
|
|
110
|
-
|
|
111
|
-
// 调用 onMqttReady 回调,通知业务侧 MQTT 监听器已准备就绪
|
|
112
|
-
if (onMqttReadyRef.current) {
|
|
113
|
-
onMqttReadyRef.current();
|
|
114
|
-
}
|
|
115
|
-
}, [devices, onMqttMessageReceived]);
|
|
176
|
+
}, [devices, onMqttMessageReceived, onMqttReady]);
|
|
116
177
|
|
|
117
178
|
// 将实例作为 value 传递给消费组件
|
|
118
179
|
return /*#__PURE__*/React.createElement(SingletonContext.Provider, {
|
package/lib/mqtt/promise.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 设置全局未处理的 rejection 处理器
|
|
3
|
+
*
|
|
4
|
+
* @param handler 处理函数,接收 MqttError 作为参数
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* setUnhandledRejectionHandler((error) => {
|
|
9
|
+
* console.error('Unhandled MQTT error:', error);
|
|
10
|
+
* // 可以发送到错误监控服务
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function setUnhandledRejectionHandler(handler: ((error: MqttError) => void) | null): void;
|
|
15
|
+
/**
|
|
16
|
+
* MQTT 请求错误类
|
|
17
|
+
* 包含错误代码和请求类型信息
|
|
18
|
+
*/
|
|
19
|
+
export declare class MqttError extends Error {
|
|
2
20
|
errCode: number;
|
|
3
21
|
reqType: string;
|
|
4
22
|
constructor(message: string, { errCode, reqType }: {
|
|
@@ -6,8 +24,43 @@ declare class MyError extends Error {
|
|
|
6
24
|
reqType: string;
|
|
7
25
|
});
|
|
8
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* MQTT 响应消息类型(兼容 MQTT 响应格式)
|
|
29
|
+
*/
|
|
30
|
+
export interface MqttResponseMessage {
|
|
31
|
+
taskId: string | number;
|
|
32
|
+
errCode?: number;
|
|
33
|
+
data?: any;
|
|
34
|
+
reqType?: string;
|
|
35
|
+
version?: string;
|
|
36
|
+
success?: boolean;
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Promise 扩展类型,支持手动拒绝
|
|
41
|
+
*/
|
|
9
42
|
export type PromiseWithRejection = Promise<any> & {
|
|
10
|
-
reject: (reason?:
|
|
43
|
+
reject: (reason?: MqttError) => void;
|
|
11
44
|
};
|
|
12
|
-
|
|
13
|
-
|
|
45
|
+
/**
|
|
46
|
+
* 创建 MQTT 请求的 Promise,监听响应消息
|
|
47
|
+
*
|
|
48
|
+
* ⚠️ 注意:此函数不再使用 taskId 进行匹配,只要接收到对应 reqType 的响应就认为匹配
|
|
49
|
+
* ⚠️ 风险:如果同时发起多个相同 reqType 的请求,可能会匹配到错误的响应
|
|
50
|
+
* ⚠️ 建议:确保业务上不会同时发起多个相同类型的请求
|
|
51
|
+
*
|
|
52
|
+
* @param reqType 请求类型,用于匹配响应消息
|
|
53
|
+
* @param taskId 任务ID(已废弃,保留参数以保持向后兼容)
|
|
54
|
+
* @param resolve Promise 的 resolve 回调
|
|
55
|
+
* @param reject Promise 的 reject 回调
|
|
56
|
+
* @param timeout 超时时间(毫秒),默认 10 秒
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* return new Promise((resolve, reject) => {
|
|
61
|
+
* normalResolve('carpetQry', '', resolve, reject);
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function normalResolve(reqType: string, resolve: (value: any) => void, reject: (reason?: any) => void, timeout?: number): void;
|
|
66
|
+
export type MyError = MqttError;
|
package/lib/mqtt/promise.js
CHANGED
|
@@ -1,54 +1,133 @@
|
|
|
1
|
-
import { emitter } from '../utils';
|
|
1
|
+
import { emitter, logger } from '../utils';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* MQTT 请求超时时间(毫秒)
|
|
5
|
+
* 默认 10 秒
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_TIMEOUT = 10 * 1000;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 全局未处理的 rejection 处理器
|
|
11
|
+
* 当 Promise 被 reject 但没有被 catch 时调用
|
|
12
|
+
*/
|
|
13
|
+
let globalUnhandledRejectionHandler = null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 设置全局未处理的 rejection 处理器
|
|
17
|
+
*
|
|
18
|
+
* @param handler 处理函数,接收 MqttError 作为参数
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* setUnhandledRejectionHandler((error) => {
|
|
23
|
+
* console.error('Unhandled MQTT error:', error);
|
|
24
|
+
* // 可以发送到错误监控服务
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function setUnhandledRejectionHandler(handler) {
|
|
29
|
+
globalUnhandledRejectionHandler = handler;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* MQTT 请求错误类
|
|
34
|
+
* 包含错误代码和请求类型信息
|
|
35
|
+
*/
|
|
36
|
+
export class MqttError extends Error {
|
|
5
37
|
constructor(message, _ref) {
|
|
6
38
|
let {
|
|
7
39
|
errCode,
|
|
8
40
|
reqType
|
|
9
41
|
} = _ref;
|
|
10
42
|
super(message);
|
|
43
|
+
this.name = 'MqttError';
|
|
11
44
|
this.errCode = errCode;
|
|
12
45
|
this.reqType = reqType;
|
|
46
|
+
|
|
47
|
+
// 确保错误堆栈正确
|
|
48
|
+
if (Error.captureStackTrace) {
|
|
49
|
+
Error.captureStackTrace(this, MqttError);
|
|
50
|
+
}
|
|
13
51
|
}
|
|
14
52
|
}
|
|
15
53
|
|
|
16
|
-
|
|
54
|
+
/**
|
|
55
|
+
* MQTT 响应消息类型(兼容 MQTT 响应格式)
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Promise 扩展类型,支持手动拒绝
|
|
60
|
+
*/
|
|
17
61
|
|
|
18
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 创建 MQTT 请求的 Promise,监听响应消息
|
|
64
|
+
*
|
|
65
|
+
* ⚠️ 注意:此函数不再使用 taskId 进行匹配,只要接收到对应 reqType 的响应就认为匹配
|
|
66
|
+
* ⚠️ 风险:如果同时发起多个相同 reqType 的请求,可能会匹配到错误的响应
|
|
67
|
+
* ⚠️ 建议:确保业务上不会同时发起多个相同类型的请求
|
|
68
|
+
*
|
|
69
|
+
* @param reqType 请求类型,用于匹配响应消息
|
|
70
|
+
* @param taskId 任务ID(已废弃,保留参数以保持向后兼容)
|
|
71
|
+
* @param resolve Promise 的 resolve 回调
|
|
72
|
+
* @param reject Promise 的 reject 回调
|
|
73
|
+
* @param timeout 超时时间(毫秒),默认 10 秒
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* return new Promise((resolve, reject) => {
|
|
78
|
+
* normalResolve('carpetQry', '', resolve, reject);
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function normalResolve(reqType, resolve, reject) {
|
|
83
|
+
let timeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DEFAULT_TIMEOUT;
|
|
84
|
+
let isResolved = false;
|
|
19
85
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
86
|
+
// 设置超时定时器
|
|
87
|
+
const timer = setTimeout(() => {
|
|
88
|
+
if (!isResolved) {
|
|
89
|
+
isResolved = true;
|
|
90
|
+
// 确保在超时时也移除监听器
|
|
91
|
+
emitter.off(reqType, handle);
|
|
92
|
+
reject(new MqttError(`${reqType} Request timed out`, {
|
|
26
93
|
errCode: -1,
|
|
27
94
|
reqType
|
|
28
95
|
}));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
96
|
+
}
|
|
97
|
+
}, timeout);
|
|
98
|
+
const handle = message => {
|
|
99
|
+
var _response$errCode;
|
|
100
|
+
const response = typeof message.data === 'object' ? message.data : message;
|
|
101
|
+
|
|
102
|
+
// 如果已经处理过,直接返回(避免重复处理)
|
|
103
|
+
if (isResolved) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 标记为已处理(防止其他监听器处理)
|
|
108
|
+
isResolved = true;
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
logger('info', {
|
|
111
|
+
msg: `${reqType} normalResolve: response ==>${JSON.stringify(response)}`
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// 移除监听器(使用函数引用确保移除正确的监听器)
|
|
115
|
+
emitter.off(reqType, handle);
|
|
116
|
+
|
|
117
|
+
// 优先使用 errCode,如果没有则使用 success 字段判断
|
|
118
|
+
const errCode = (_response$errCode = response.errCode) !== null && _response$errCode !== void 0 ? _response$errCode : response.success === false ? -1 : 0;
|
|
119
|
+
if (errCode === 0) {
|
|
120
|
+
resolve(response);
|
|
121
|
+
} else {
|
|
122
|
+
reject(new MqttError('Request failed', {
|
|
123
|
+
errCode,
|
|
124
|
+
reqType
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// 监听指定类型的消息
|
|
130
|
+
emitter.on(reqType, handle);
|
|
131
|
+
}
|
|
50
132
|
|
|
51
|
-
|
|
52
|
-
emitter.on(reqType, handle);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
133
|
+
// 为了向后兼容,导出旧的类型别名
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as z from 'zod/mini';
|
|
2
|
+
import { pointsSchema, roomIdSchema, originSchema } from './protocols/partDivisionProtocol';
|
|
3
|
+
export declare const ProtocolSchemas: {
|
|
4
|
+
query_carpet: any;
|
|
5
|
+
add_carpet: any;
|
|
6
|
+
update_carpet: any;
|
|
7
|
+
delete_carpet: any;
|
|
8
|
+
set_carpet: any;
|
|
9
|
+
set_schedule: any;
|
|
10
|
+
request_schedule: any;
|
|
11
|
+
set_zone_clean: any;
|
|
12
|
+
set_wifi_map: any;
|
|
13
|
+
set_voice: any;
|
|
14
|
+
set_virtual_wall: any;
|
|
15
|
+
set_virtual_area: any;
|
|
16
|
+
set_spot_clean: any;
|
|
17
|
+
set_select_room_clean: any;
|
|
18
|
+
set_quiet_hours: any;
|
|
19
|
+
set_password: any;
|
|
20
|
+
check_password: any;
|
|
21
|
+
set_part_merge: any;
|
|
22
|
+
delete_history_map: any;
|
|
23
|
+
save_map: any;
|
|
24
|
+
change_current_map: any;
|
|
25
|
+
request_furniture_list: any;
|
|
26
|
+
set_furniture_model: any;
|
|
27
|
+
set_device_model: any;
|
|
28
|
+
set_carpet_clean: any;
|
|
29
|
+
set_room_property: any;
|
|
30
|
+
};
|
|
31
|
+
export type ProtocolTypes = {
|
|
32
|
+
[K in keyof typeof ProtocolSchemas]: z.infer<(typeof ProtocolSchemas)[K]>;
|
|
33
|
+
};
|
|
34
|
+
export declare class MiniProtocolValidator {
|
|
35
|
+
validate<T extends keyof ProtocolTypes>(protocol: T, data: unknown): ProtocolTypes[T];
|
|
36
|
+
/**
|
|
37
|
+
* 验证 set_part_division 的三个独立参数
|
|
38
|
+
* @param points 分隔点数组
|
|
39
|
+
* @param roomId 房间ID(可以是 int 或 string)
|
|
40
|
+
* @param origin 地图原点坐标
|
|
41
|
+
* @returns 验证后的数据对象
|
|
42
|
+
*/
|
|
43
|
+
validateSetPartDivision(points: unknown, roomId: unknown, origin: unknown): {
|
|
44
|
+
points: z.infer<typeof pointsSchema>;
|
|
45
|
+
roomId: z.infer<typeof roomIdSchema>;
|
|
46
|
+
origin: z.infer<typeof originSchema>;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export declare const validator: MiniProtocolValidator;
|