@ray-js/robot-data-stream 0.0.14 → 0.0.15-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/api/sweeperP2p.js +1 -1
- package/lib/mqtt/createCommonOptions.d.ts +4 -2
- package/lib/mqtt/createCommonOptions.js +10 -5
- package/lib/mqtt/hooks/useStructuredMessage.d.ts +17 -0
- package/lib/mqtt/hooks/useStructuredMessage.js +206 -0
- package/lib/mqtt/mqttProvider.d.ts +28 -1
- package/lib/mqtt/mqttProvider.js +72 -9
- package/lib/mqtt/promise.d.ts +57 -4
- package/lib/mqtt/promise.js +115 -36
- package/lib/mqtt/type/fun.d.ts +233 -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 +21 -0
- package/lib/mqtt/type/protocols/base.js +32 -0
- package/lib/mqtt/type/protocols/carpetCleanProtocol.d.ts +14 -0
- package/lib/mqtt/type/protocols/carpetCleanProtocol.js +14 -0
- package/lib/mqtt/type/protocols/carpetProtocol.d.ts +102 -0
- package/lib/mqtt/type/protocols/carpetProtocol.js +202 -0
- package/lib/mqtt/type/protocols/devInfoProtocol.d.ts +11 -0
- package/lib/mqtt/type/protocols/devInfoProtocol.js +10 -0
- package/lib/mqtt/type/protocols/deviceModelProtocol.d.ts +31 -0
- package/lib/mqtt/type/protocols/deviceModelProtocol.js +32 -0
- package/lib/mqtt/type/protocols/furnitureModelProtocol.d.ts +27 -0
- package/lib/mqtt/type/protocols/furnitureModelProtocol.js +27 -0
- package/lib/mqtt/type/protocols/historyMapProtocol.d.ts +39 -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 +20 -0
- package/lib/mqtt/type/protocols/partDivisionProtocol.js +12 -0
- package/lib/mqtt/type/protocols/partMergeProtocol.d.ts +13 -0
- package/lib/mqtt/type/protocols/partMergeProtocol.js +12 -0
- package/lib/mqtt/type/protocols/passwordProtocol.d.ts +24 -0
- package/lib/mqtt/type/protocols/passwordProtocol.js +25 -0
- package/lib/mqtt/type/protocols/quietHoursProtocol.d.ts +29 -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 +42 -0
- package/lib/mqtt/type/protocols/roomPropertyProtocol.js +113 -0
- package/lib/mqtt/type/protocols/scheduleProtocol.d.ts +62 -0
- package/lib/mqtt/type/protocols/scheduleProtocol.js +100 -0
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +27 -0
- package/lib/mqtt/type/protocols/selectRoomCleanProtocol.js +40 -0
- package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +38 -0
- package/lib/mqtt/type/protocols/spotCleanProtocol.js +72 -0
- package/lib/mqtt/type/protocols/virtualAreaProtocol.d.ts +32 -0
- package/lib/mqtt/type/protocols/virtualAreaProtocol.js +36 -0
- package/lib/mqtt/type/protocols/virtualWallProtocol.d.ts +27 -0
- package/lib/mqtt/type/protocols/virtualWallProtocol.js +25 -0
- package/lib/mqtt/type/protocols/voiceProtocol.d.ts +21 -0
- package/lib/mqtt/type/protocols/voiceProtocol.js +23 -0
- package/lib/mqtt/type/protocols/wifiMapProtocol.d.ts +16 -0
- package/lib/mqtt/type/protocols/wifiMapProtocol.js +14 -0
- package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +47 -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 +26 -50
- 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 +31 -42
- package/lib/mqtt/useFurnitureModel.d.ts +6 -18
- package/lib/mqtt/useFurnitureModel.js +31 -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
package/lib/api/sweeperP2p.js
CHANGED
|
@@ -72,7 +72,7 @@ export class SweeperP2p extends P2pApi {
|
|
|
72
72
|
this.packetTotalMap = new Map([['map.bin', -1], ['map_structured.bin', -1], ['cleanPath.bin', -1], ['ai.bin', -1], ['aiHD_XXXX_YYYY.bin', -1], ['map.bin.stream', -1], ['map_structured.bin.stream', -1], ['cleanPath.bin.stream', -1], ['ai.bin.stream', -1], ['aiHD_XXXX_YYYY.bin.stream', -1]]);
|
|
73
73
|
this.packetSerialNumberCacheMap = new Map([['map.bin', -1], ['map_structured.bin', -1], ['cleanPath.bin', -1], ['ai.bin', -1], ['aiHD_XXXX_YYYY.bin', -1], ['map.bin.stream', -1], ['map_structured.bin.stream', -1], ['cleanPath.bin.stream', -1], ['ai.bin.stream', -1], ['aiHD_XXXX_YYYY.bin.stream', -1]]);
|
|
74
74
|
this.fileLengthCacheMap = new Map([['map.bin', -1], ['map_structured.bin', -1], ['cleanPath.bin', -1], ['ai.bin', -1], ['aiHD_XXXX_YYYY.bin', -1], ['map.bin.stream', -1], ['map_structured.bin.stream', -1], ['cleanPath.bin.stream', -1], ['ai.bin.stream', -1], ['aiHD_XXXX_YYYY.bin.stream', -1]]);
|
|
75
|
-
this.packetDataCacheMap = new Map([['map.bin', new Map()], ['map_structured.bin', new Map()], ['cleanPath.bin', new Map()], ['ai.bin', new Map()], ['aiHD_XXXX_YYYY.bin', new Map()], ['map.bin.stream', new Map()], ['map_structured.bin.stream', new Map()], ['cleanPath.bin.stream', new Map()], ['ai.bin.stream', new Map()], ['aiHD_XXXX_YYYY.bin.stream', new Map()]]);
|
|
75
|
+
this.packetDataCacheMap = new Map([['map.bin', new Map()], ['map_structured.bin', new Map()], ['cleanPath.bin', new Map()], ['ai.bin', new Map()], ['aiHD_XXXX_YYYY.bin', new Map()], ['map.bin.stream', new Map()], ['map_structured.bin.stream', new Map()], ['cleanPath.bin.stream', new Map()], ['wifi_map.bin', new Map()], ['wifi_map.bin.stream', new Map()], ['ai.bin.stream', new Map()], ['aiHD_XXXX_YYYY.bin.stream', new Map()]]);
|
|
76
76
|
}
|
|
77
77
|
setStreamFilePath = () => {
|
|
78
78
|
// this.streamFilePath = this.cacheDir + `/${this.albumName}/${devId}/stream`;
|
|
@@ -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,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一的 MQTT 消息发送 Hook
|
|
3
|
+
* 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
|
|
4
|
+
*/
|
|
5
|
+
export declare const useStructuredMessage: () => {
|
|
6
|
+
sendStructuredMessage: <T extends {
|
|
7
|
+
success: boolean;
|
|
8
|
+
errCode: number;
|
|
9
|
+
reqType: string;
|
|
10
|
+
version: string;
|
|
11
|
+
taskId: string;
|
|
12
|
+
}>(reqType: string, message: Record<string, any> | undefined, resolve: (value: T) => void, reject: (reason?: any) => void, responseType?: string) => void;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* 错误处理工具函数
|
|
16
|
+
*/
|
|
17
|
+
export declare const handleMqttError: (error: unknown, defaultMessage: string) => Error;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import { getDeviceOnlineType, offDeviceOnlineStatusUpdate, 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
|
+
const COMMUNICATION_CHANNELS = {
|
|
11
|
+
MQTT: 'mqtt',
|
|
12
|
+
LAN: 'lan'
|
|
13
|
+
};
|
|
14
|
+
const DEVICE_ONLINE_BITS = {
|
|
15
|
+
WIFI: 0,
|
|
16
|
+
LOCAL: 1
|
|
17
|
+
};
|
|
18
|
+
const LOG_LEVEL = {
|
|
19
|
+
INFO: 'info',
|
|
20
|
+
ERROR: 'error'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// 类型定义
|
|
24
|
+
|
|
25
|
+
// 通信方法接口
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 统一的 MQTT 消息发送 Hook
|
|
29
|
+
* 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
|
|
30
|
+
*/
|
|
31
|
+
export const useStructuredMessage = () => {
|
|
32
|
+
const context = useMqtt();
|
|
33
|
+
const {
|
|
34
|
+
devId
|
|
35
|
+
} = context.devices.common.getDevInfo();
|
|
36
|
+
const isLocalOnlineRef = useRef(false);
|
|
37
|
+
const isWifiOnlineRef = useRef(true);
|
|
38
|
+
|
|
39
|
+
// 设备在线状态处理器
|
|
40
|
+
const handleDeviceOnlineStatusChange = useCallback(_ref => {
|
|
41
|
+
let {
|
|
42
|
+
onlineType
|
|
43
|
+
} = _ref;
|
|
44
|
+
const wifiOnline = Boolean(getBitValue(onlineType, DEVICE_ONLINE_BITS.WIFI));
|
|
45
|
+
const localOnline = Boolean(getBitValue(onlineType, DEVICE_ONLINE_BITS.LOCAL));
|
|
46
|
+
isLocalOnlineRef.current = localOnline;
|
|
47
|
+
isWifiOnlineRef.current = wifiOnline;
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
// 订阅设备在线状态更新
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!devId) return;
|
|
53
|
+
(() => {
|
|
54
|
+
getDeviceOnlineType({
|
|
55
|
+
deviceId: devId,
|
|
56
|
+
success: handleDeviceOnlineStatusChange
|
|
57
|
+
});
|
|
58
|
+
})();
|
|
59
|
+
onDeviceOnlineStatusUpdate(handleDeviceOnlineStatusChange);
|
|
60
|
+
return offDeviceOnlineStatusUpdate(handleDeviceOnlineStatusChange);
|
|
61
|
+
}, [devId, handleDeviceOnlineStatusChange]);
|
|
62
|
+
|
|
63
|
+
// MQTT 通信方法
|
|
64
|
+
const mqttCommunication = {
|
|
65
|
+
isAvailable: () => {
|
|
66
|
+
var _ty;
|
|
67
|
+
return isWifiOnlineRef.current && ((_ty = ty) === null || _ty === void 0 ? void 0 : _ty.device) && isFunction(ty.device.sendMqttMessage);
|
|
68
|
+
},
|
|
69
|
+
send: (params, successCallback, failCallback) => {
|
|
70
|
+
const messageParams = _objectSpread(_objectSpread({}, params), {}, {
|
|
71
|
+
success: successCallback,
|
|
72
|
+
fail: failCallback
|
|
73
|
+
});
|
|
74
|
+
ty.device.sendMqttMessage(messageParams);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// LAN 通信方法
|
|
79
|
+
const lanCommunication = {
|
|
80
|
+
isAvailable: () => {
|
|
81
|
+
var _ty2;
|
|
82
|
+
return isLocalOnlineRef.current && ((_ty2 = ty) === null || _ty2 === void 0 ? void 0 : _ty2.device) && isFunction(ty.device.publishLanMessage);
|
|
83
|
+
},
|
|
84
|
+
send: (params, successCallback, failCallback) => {
|
|
85
|
+
const messageParams = _objectSpread(_objectSpread({}, params), {}, {
|
|
86
|
+
success: successCallback,
|
|
87
|
+
fail: failCallback
|
|
88
|
+
});
|
|
89
|
+
ty.device.publishLanMessage(messageParams);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// 创建消息参数
|
|
94
|
+
const createMessageParams = (reqType, message, useLocal) => {
|
|
95
|
+
return createSetCommonParams({
|
|
96
|
+
deviceId: devId,
|
|
97
|
+
reqType,
|
|
98
|
+
message,
|
|
99
|
+
isLocalOnLine: useLocal
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// 记录通信日志
|
|
104
|
+
const logCommunication = (level, reqType, message, params) => {
|
|
105
|
+
const baseMessage = `${reqType} ${message}`;
|
|
106
|
+
const fullMessage = params ? `${baseMessage}: ${JSON.stringify(params)}` : baseMessage;
|
|
107
|
+
logger(level, {
|
|
108
|
+
msg: fullMessage
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// 通信策略选择器
|
|
113
|
+
const selectCommunicationMethod = preferredChannel => {
|
|
114
|
+
const isPreferredMqtt = preferredChannel === COMMUNICATION_CHANNELS.MQTT;
|
|
115
|
+
const primaryMethod = isPreferredMqtt ? mqttCommunication : lanCommunication;
|
|
116
|
+
const fallbackMethod = isPreferredMqtt ? lanCommunication : mqttCommunication;
|
|
117
|
+
const useLocal = isPreferredMqtt ? false : true;
|
|
118
|
+
if (primaryMethod.isAvailable()) {
|
|
119
|
+
return {
|
|
120
|
+
method: primaryMethod,
|
|
121
|
+
useLocal
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (fallbackMethod.isAvailable()) {
|
|
125
|
+
return {
|
|
126
|
+
method: fallbackMethod,
|
|
127
|
+
useLocal: !useLocal
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// 处理通信失败
|
|
134
|
+
const handleCommunicationError = (preferredChannel, reject) => {
|
|
135
|
+
const errorMessage = preferredChannel === COMMUNICATION_CHANNELS.MQTT ? `操作需要 MQTT 模式,请在 MqttProvider 中启用 useMqtt` : `没有可用的通信方式。局域网在线: ${isLocalOnlineRef.current}, WiFi在线: ${isWifiOnlineRef.current}`;
|
|
136
|
+
reject(new Error(errorMessage));
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 发送结构化消息
|
|
141
|
+
*/
|
|
142
|
+
const sendStructuredMessage = useCallback((reqType, message, resolve, reject, responseType) => {
|
|
143
|
+
// 参数验证
|
|
144
|
+
if (!devId) {
|
|
145
|
+
reject(new Error('设备ID (devId) 为必填项'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (!context.useMqtt) {
|
|
149
|
+
reject(new Error(`操作 ${reqType} 需要 MQTT 模式。请在 MqttProvider 中启用 useMqtt。`));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const {
|
|
154
|
+
preferredChannel
|
|
155
|
+
} = context;
|
|
156
|
+
const selectedMethod = selectCommunicationMethod(preferredChannel);
|
|
157
|
+
if (!selectedMethod) {
|
|
158
|
+
handleCommunicationError(preferredChannel, reject);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const {
|
|
162
|
+
method,
|
|
163
|
+
useLocal
|
|
164
|
+
} = selectedMethod;
|
|
165
|
+
const messageParams = createMessageParams(reqType, message, useLocal);
|
|
166
|
+
|
|
167
|
+
// 成功回调
|
|
168
|
+
|
|
169
|
+
// 失败回调
|
|
170
|
+
|
|
171
|
+
// 发送消息
|
|
172
|
+
method.send(messageParams, () => {
|
|
173
|
+
const channelName = useLocal ? '局域网' : 'WiFi MQTT';
|
|
174
|
+
const fallbackSuffix = method === mqttCommunication && preferredChannel === COMMUNICATION_CHANNELS.LAN ? ' (备用)' : '';
|
|
175
|
+
logCommunication(LOG_LEVEL.INFO, reqType, `${channelName} 消息发送成功${fallbackSuffix}`, messageParams);
|
|
176
|
+
}, error => {
|
|
177
|
+
logCommunication(LOG_LEVEL.ERROR, reqType, '消息发送失败', _objectSpread(_objectSpread({}, messageParams), {}, {
|
|
178
|
+
error: JSON.stringify(error)
|
|
179
|
+
}));
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// 处理响应
|
|
183
|
+
|
|
184
|
+
normalResolve(responseType || reqType, resolve, reject);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
logCommunication(LOG_LEVEL.ERROR, reqType, `发送消息时发生异常: ${error}`);
|
|
187
|
+
reject(error);
|
|
188
|
+
}
|
|
189
|
+
}, [devId, context.useMqtt, context.preferredChannel]);
|
|
190
|
+
return {
|
|
191
|
+
sendStructuredMessage
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 错误处理工具函数
|
|
197
|
+
*/
|
|
198
|
+
export const handleMqttError = (error, defaultMessage) => {
|
|
199
|
+
if (error instanceof Error) {
|
|
200
|
+
return error;
|
|
201
|
+
}
|
|
202
|
+
if (typeof error === 'string') {
|
|
203
|
+
return new Error(error);
|
|
204
|
+
}
|
|
205
|
+
return new Error(defaultMessage);
|
|
206
|
+
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { MqttError } from './promise';
|
|
3
|
+
export type CommunicationChannel = 'mqtt' | 'lan';
|
|
2
4
|
export interface MqttContextValue {
|
|
3
5
|
useMqtt: boolean;
|
|
4
6
|
commandVersion: '0' | '1';
|
|
7
|
+
preferredChannel: CommunicationChannel;
|
|
5
8
|
devices: {
|
|
6
9
|
common: {
|
|
7
10
|
getDevInfo: () => {
|
|
@@ -19,15 +22,39 @@ export interface MqttContextValue {
|
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
24
|
export declare const SingletonContext: React.Context<MqttContextValue | null>;
|
|
25
|
+
export type MqttErrorHandler = (error: MqttError) => void;
|
|
22
26
|
export interface MqttProviderProps {
|
|
23
27
|
children: React.ReactNode;
|
|
24
28
|
useMqtt: boolean;
|
|
25
29
|
commandVersion: '0' | '1';
|
|
26
30
|
devices: MqttContextValue['devices'];
|
|
31
|
+
/**
|
|
32
|
+
* 优先选择的通信通道
|
|
33
|
+
* - 'mqtt': 优先使用 MQTT 通道(WiFi MQTT)
|
|
34
|
+
* - 'lan': 优先使用局域网通道(LAN)
|
|
35
|
+
* @default 'mqtt'
|
|
36
|
+
*/
|
|
37
|
+
preferredChannel?: CommunicationChannel;
|
|
27
38
|
onMqttReady?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* 可选的错误处理回调
|
|
41
|
+
* 当 MQTT 请求发生未捕获的错误时(如超时、请求失败等),会调用此回调
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* <MqttProvider
|
|
46
|
+
* onError={(error) => {
|
|
47
|
+
* console.error('MQTT Error:', error);
|
|
48
|
+
* // 可以发送到错误监控服务
|
|
49
|
+
* }}
|
|
50
|
+
* ...
|
|
51
|
+
* />
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
onError?: MqttErrorHandler;
|
|
28
55
|
}
|
|
29
56
|
export declare function useMqtt(): MqttContextValue;
|
|
30
|
-
export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onMqttReady, }: MqttProviderProps): React.JSX.Element;
|
|
57
|
+
export declare function MqttProvider({ children, useMqtt, commandVersion, devices, preferredChannel, onError, onMqttReady, }: MqttProviderProps): React.JSX.Element;
|
|
31
58
|
export declare namespace MqttProvider {
|
|
32
59
|
var defaultProps: {
|
|
33
60
|
onMqttReady: undefined;
|
package/lib/mqtt/mqttProvider.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
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';
|
|
9
|
+
|
|
10
|
+
// 通信通道类型
|
|
6
11
|
|
|
7
12
|
// Context 类型定义
|
|
8
13
|
|
|
9
14
|
// 创建一个Context
|
|
10
15
|
export const SingletonContext = /*#__PURE__*/createContext(null);
|
|
11
16
|
|
|
17
|
+
// MQTT 错误处理函数类型
|
|
18
|
+
|
|
12
19
|
// MqttProvider Props 类型定义
|
|
13
20
|
|
|
14
21
|
// MQTT 消息数据类型
|
|
@@ -27,14 +34,20 @@ export function MqttProvider(_ref) {
|
|
|
27
34
|
useMqtt,
|
|
28
35
|
commandVersion,
|
|
29
36
|
devices,
|
|
37
|
+
preferredChannel = 'mqtt',
|
|
38
|
+
onError,
|
|
30
39
|
onMqttReady
|
|
31
40
|
} = _ref;
|
|
41
|
+
// const [isLocalOnLine, setIsLocalOnLine] = useState(false);
|
|
42
|
+
// const [isWifiOnLine, setIsWifiOnLine] = useState(true);
|
|
43
|
+
|
|
32
44
|
// 使用 useMemo 创建实例,确保只在依赖项变化时重新创建
|
|
33
45
|
const instance = useMemo(() => ({
|
|
34
46
|
useMqtt,
|
|
35
47
|
commandVersion,
|
|
48
|
+
preferredChannel,
|
|
36
49
|
devices
|
|
37
|
-
}), [useMqtt, commandVersion, devices]);
|
|
50
|
+
}), [useMqtt, commandVersion, preferredChannel, devices]);
|
|
38
51
|
|
|
39
52
|
// 使用 ref 存储设备 ID 和初始化状态,避免重复初始化
|
|
40
53
|
const devIdRef = useRef(null);
|
|
@@ -67,9 +80,46 @@ export function MqttProvider(_ref) {
|
|
|
67
80
|
});
|
|
68
81
|
emitter.emit(reqType, responseData);
|
|
69
82
|
}, []);
|
|
83
|
+
const onSocketMessageReceived = useCallback(event => {
|
|
84
|
+
const {
|
|
85
|
+
message
|
|
86
|
+
} = event || {};
|
|
87
|
+
log4js.info('onSocketMessageReceived======>', {
|
|
88
|
+
msg: JSON.stringify(message)
|
|
89
|
+
});
|
|
90
|
+
if (message !== null && message !== void 0 && message.data && message !== null && message !== void 0 && message.reqType) {
|
|
91
|
+
emitter.emit(message.reqType, message.data);
|
|
92
|
+
}
|
|
93
|
+
}, []);
|
|
94
|
+
|
|
95
|
+
// 设置全局错误处理器(不依赖 window,适用于小程序环境)
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (onError) {
|
|
98
|
+
// 设置全局错误处理器
|
|
99
|
+
setUnhandledRejectionHandler(error => {
|
|
100
|
+
try {
|
|
101
|
+
onError(error);
|
|
102
|
+
} catch (handlerError) {
|
|
103
|
+
// 避免错误处理器本身抛出错误导致无限循环
|
|
104
|
+
console.error('Error in MQTT error handler:', handlerError);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
// 如果没有提供错误处理器,设置默认处理器(记录警告)
|
|
109
|
+
setUnhandledRejectionHandler(error => {
|
|
110
|
+
console.warn(`[MQTT] Unhandled rejection for ${error.reqType}:`, error.message);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 清理函数:组件卸载时移除全局处理器
|
|
115
|
+
return () => {
|
|
116
|
+
setUnhandledRejectionHandler(null);
|
|
117
|
+
};
|
|
118
|
+
}, [onError]);
|
|
70
119
|
|
|
71
120
|
// 初始化 MQTT 监听器(只执行一次)
|
|
72
121
|
useEffect(() => {
|
|
122
|
+
var _ty;
|
|
73
123
|
// 防止重复初始化
|
|
74
124
|
if (isInitializedRef.current) return;
|
|
75
125
|
|
|
@@ -88,10 +138,11 @@ export function MqttProvider(_ref) {
|
|
|
88
138
|
}
|
|
89
139
|
|
|
90
140
|
// 注册 MQTT 协议监听器
|
|
91
|
-
|
|
141
|
+
registerMQTTProtocolListener({
|
|
92
142
|
protocol: ProtocolEnum.robotToApp,
|
|
93
143
|
success: () => {
|
|
94
144
|
console.log('注册mqtt成功');
|
|
145
|
+
onMqttReady === null || onMqttReady === void 0 || onMqttReady();
|
|
95
146
|
},
|
|
96
147
|
fail: error => {
|
|
97
148
|
console.error('注册mqtt失败:', error);
|
|
@@ -105,14 +156,26 @@ export function MqttProvider(_ref) {
|
|
|
105
156
|
}
|
|
106
157
|
});
|
|
107
158
|
|
|
159
|
+
// 注册设备服务监听器(如果方法存在)
|
|
160
|
+
// @ts-ignore - registerDeviceServiceListener 可能不存在于类型定义中
|
|
161
|
+
if ((_ty = ty) !== null && _ty !== void 0 && _ty.device && isFunction(ty.device.registerDeviceServiceListener)) {
|
|
162
|
+
var _ty2;
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
ty.device.registerDeviceServiceListener({
|
|
165
|
+
success: event => {
|
|
166
|
+
console.log(event, '++++++++++2222++++++');
|
|
167
|
+
},
|
|
168
|
+
fail: e => {
|
|
169
|
+
console.log(e);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
// 注册 Socket 消息接收监听器
|
|
173
|
+
(_ty2 = ty) === null || _ty2 === void 0 || (_ty2 = _ty2.device) === null || _ty2 === void 0 || _ty2.onSocketMessageReceived(onSocketMessageReceived);
|
|
174
|
+
}
|
|
175
|
+
|
|
108
176
|
// 标记为已初始化
|
|
109
177
|
isInitializedRef.current = true;
|
|
110
|
-
|
|
111
|
-
// 调用 onMqttReady 回调,通知业务侧 MQTT 监听器已准备就绪
|
|
112
|
-
if (onMqttReadyRef.current) {
|
|
113
|
-
onMqttReadyRef.current();
|
|
114
|
-
}
|
|
115
|
-
}, [devices, onMqttMessageReceived]);
|
|
178
|
+
}, [devices, onMqttMessageReceived, onMqttReady]);
|
|
116
179
|
|
|
117
180
|
// 将实例作为 value 传递给消费组件
|
|
118
181
|
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;
|