@ray-js/robot-data-stream 0.0.15-beta.1 → 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.
Files changed (53) hide show
  1. package/lib/api/sweeperP2p.js +1 -1
  2. package/lib/mqtt/hooks/useStructuredMessage.d.ts +7 -4
  3. package/lib/mqtt/hooks/useStructuredMessage.js +150 -75
  4. package/lib/mqtt/mqttProvider.d.ts +10 -1
  5. package/lib/mqtt/mqttProvider.js +5 -3
  6. package/lib/mqtt/type/fun.d.ts +211 -27
  7. package/lib/mqtt/type/protocols/base.d.ts +20 -4
  8. package/lib/mqtt/type/protocols/base.js +1 -1
  9. package/lib/mqtt/type/protocols/carpetCleanProtocol.d.ts +11 -5
  10. package/lib/mqtt/type/protocols/carpetCleanProtocol.js +2 -4
  11. package/lib/mqtt/type/protocols/carpetProtocol.d.ts +69 -8
  12. package/lib/mqtt/type/protocols/carpetProtocol.js +1 -1
  13. package/lib/mqtt/type/protocols/devInfoProtocol.d.ts +10 -4
  14. package/lib/mqtt/type/protocols/devInfoProtocol.js +1 -3
  15. package/lib/mqtt/type/protocols/deviceModelProtocol.d.ts +26 -3
  16. package/lib/mqtt/type/protocols/deviceModelProtocol.js +5 -7
  17. package/lib/mqtt/type/protocols/furnitureModelProtocol.d.ts +24 -7
  18. package/lib/mqtt/type/protocols/furnitureModelProtocol.js +7 -15
  19. package/lib/mqtt/type/protocols/historyMapProtocol.d.ts +28 -6
  20. package/lib/mqtt/type/protocols/historyMapProtocol.js +1 -1
  21. package/lib/mqtt/type/protocols/partDivisionProtocol.d.ts +16 -4
  22. package/lib/mqtt/type/protocols/partDivisionProtocol.js +1 -1
  23. package/lib/mqtt/type/protocols/partMergeProtocol.d.ts +9 -3
  24. package/lib/mqtt/type/protocols/partMergeProtocol.js +1 -1
  25. package/lib/mqtt/type/protocols/passwordProtocol.d.ts +17 -4
  26. package/lib/mqtt/type/protocols/passwordProtocol.js +1 -1
  27. package/lib/mqtt/type/protocols/quietHoursProtocol.d.ts +24 -3
  28. package/lib/mqtt/type/protocols/quietHoursProtocol.js +1 -1
  29. package/lib/mqtt/type/protocols/resetMapProtocol.d.ts +1 -1
  30. package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +31 -3
  31. package/lib/mqtt/type/protocols/roomPropertyProtocol.js +1 -1
  32. package/lib/mqtt/type/protocols/scheduleProtocol.d.ts +49 -5
  33. package/lib/mqtt/type/protocols/scheduleProtocol.js +1 -1
  34. package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +22 -3
  35. package/lib/mqtt/type/protocols/selectRoomCleanProtocol.js +1 -1
  36. package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +32 -3
  37. package/lib/mqtt/type/protocols/spotCleanProtocol.js +1 -1
  38. package/lib/mqtt/type/protocols/virtualAreaProtocol.d.ts +27 -3
  39. package/lib/mqtt/type/protocols/virtualAreaProtocol.js +1 -1
  40. package/lib/mqtt/type/protocols/virtualWallProtocol.d.ts +22 -3
  41. package/lib/mqtt/type/protocols/virtualWallProtocol.js +1 -1
  42. package/lib/mqtt/type/protocols/voiceProtocol.d.ts +16 -3
  43. package/lib/mqtt/type/protocols/voiceProtocol.js +1 -1
  44. package/lib/mqtt/type/protocols/wifiMapProtocol.d.ts +11 -3
  45. package/lib/mqtt/type/protocols/wifiMapProtocol.js +1 -1
  46. package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +42 -3
  47. package/lib/mqtt/type/protocols/zoneCleanProtocol.js +1 -1
  48. package/lib/mqtt/useCarpetClean.js +6 -3
  49. package/lib/mqtt/useDeviceModel.js +3 -1
  50. package/lib/mqtt/useFurnitureModel.js +3 -1
  51. package/lib/myLib/zod/src/v4/mini/index.d.ts +529 -2
  52. package/lib/myLib/zod/src/v4/mini/index.js +30 -3
  53. package/package.json +1 -1
@@ -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`;
@@ -3,12 +3,15 @@
3
3
  * 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
4
4
  */
5
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;
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;
7
13
  };
8
14
  /**
9
15
  * 错误处理工具函数
10
- * @param error 错误对象
11
- * @param defaultMessage 默认错误消息
12
- * @returns Error 对象
13
16
  */
14
17
  export declare const handleMqttError: (error: unknown, defaultMessage: string) => Error;
@@ -1,11 +1,29 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import { getDeviceOnlineType, onDeviceOnlineStatusUpdate } from '@ray-js/ray';
2
+ import { getDeviceOnlineType, offDeviceOnlineStatusUpdate, onDeviceOnlineStatusUpdate } from '@ray-js/ray';
3
3
  import { isFunction } from 'lodash-es';
4
4
  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
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
+
9
27
  /**
10
28
  * 统一的 MQTT 消息发送 Hook
11
29
  * 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
@@ -15,103 +33,160 @@ export const useStructuredMessage = () => {
15
33
  const {
16
34
  devId
17
35
  } = context.devices.common.getDevInfo();
18
- const isLocalOnLineRef = useRef(false);
19
- const isWifiOnLineRef = useRef(true);
20
- const _onDeviceOnlineStatusChange = useCallback(_ref => {
36
+ const isLocalOnlineRef = useRef(false);
37
+ const isWifiOnlineRef = useRef(true);
38
+
39
+ // 设备在线状态处理器
40
+ const handleDeviceOnlineStatusChange = useCallback(_ref => {
21
41
  let {
22
42
  onlineType
23
43
  } = _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;
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;
33
48
  }, []);
49
+
50
+ // 订阅设备在线状态更新
34
51
  useEffect(() => {
35
52
  if (!devId) return;
36
- getDeviceOnlineType({
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({
37
96
  deviceId: devId,
38
- success: _onDeviceOnlineStatusChange
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
39
109
  });
40
- onDeviceOnlineStatusUpdate(_onDeviceOnlineStatusChange);
41
- }, [_onDeviceOnlineStatusChange, devId]);
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
+ };
42
138
 
43
139
  /**
44
- * 发送 MQTT 消息
45
- * @param reqType 请求类型
46
- * @param message 消息体(可选)
47
- * @param responseType 响应类型(可选,如果不提供则使用 reqType)
48
- * @param resolve Promise 的 resolve 回调
49
- * @param reject Promise 的 reject 回调
140
+ * 发送结构化消息
50
141
  */
51
142
  const sendStructuredMessage = useCallback((reqType, message, resolve, reject, responseType) => {
143
+ // 参数验证
52
144
  if (!devId) {
53
- reject(new Error('devId is required'));
145
+ reject(new Error('设备ID (devId) 为必填项'));
54
146
  return;
55
147
  }
56
- // 检查是否使用 MQTT 模式
57
148
  if (!context.useMqtt) {
58
- reject(new Error(`Operation ${reqType} requires MQTT mode. Please enable useMqtt in MqttProvider.`));
149
+ reject(new Error(`操作 ${reqType} 需要 MQTT 模式。请在 MqttProvider 中启用 useMqtt。`));
59
150
  return;
60
151
  }
61
152
  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}`));
153
+ const {
154
+ preferredChannel
155
+ } = context;
156
+ const selectedMethod = selectCommunicationMethod(preferredChannel);
157
+ if (!selectedMethod) {
158
+ handleCommunicationError(preferredChannel, reject);
106
159
  return;
107
160
  }
108
- // 如果指定了响应类型,使用响应类型;否则使用请求类型
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
+ // 处理响应
109
183
 
110
184
  normalResolve(responseType || reqType, resolve, reject);
111
185
  } catch (error) {
186
+ logCommunication(LOG_LEVEL.ERROR, reqType, `发送消息时发生异常: ${error}`);
112
187
  reject(error);
113
188
  }
114
- }, [devId, context.useMqtt]);
189
+ }, [devId, context.useMqtt, context.preferredChannel]);
115
190
  return {
116
191
  sendStructuredMessage
117
192
  };
@@ -119,13 +194,13 @@ export const useStructuredMessage = () => {
119
194
 
120
195
  /**
121
196
  * 错误处理工具函数
122
- * @param error 错误对象
123
- * @param defaultMessage 默认错误消息
124
- * @returns Error 对象
125
197
  */
126
198
  export const handleMqttError = (error, defaultMessage) => {
127
199
  if (error instanceof Error) {
128
200
  return error;
129
201
  }
202
+ if (typeof error === 'string') {
203
+ return new Error(error);
204
+ }
130
205
  return new Error(defaultMessage);
131
206
  };
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import { MqttError } from './promise';
3
+ export type CommunicationChannel = 'mqtt' | 'lan';
3
4
  export interface MqttContextValue {
4
5
  useMqtt: boolean;
5
6
  commandVersion: '0' | '1';
7
+ preferredChannel: CommunicationChannel;
6
8
  devices: {
7
9
  common: {
8
10
  getDevInfo: () => {
@@ -26,6 +28,13 @@ export interface MqttProviderProps {
26
28
  useMqtt: boolean;
27
29
  commandVersion: '0' | '1';
28
30
  devices: MqttContextValue['devices'];
31
+ /**
32
+ * 优先选择的通信通道
33
+ * - 'mqtt': 优先使用 MQTT 通道(WiFi MQTT)
34
+ * - 'lan': 优先使用局域网通道(LAN)
35
+ * @default 'mqtt'
36
+ */
37
+ preferredChannel?: CommunicationChannel;
29
38
  onMqttReady?: () => void;
30
39
  /**
31
40
  * 可选的错误处理回调
@@ -45,7 +54,7 @@ export interface MqttProviderProps {
45
54
  onError?: MqttErrorHandler;
46
55
  }
47
56
  export declare function useMqtt(): MqttContextValue;
48
- export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onError, onMqttReady, }: MqttProviderProps): React.JSX.Element;
57
+ export declare function MqttProvider({ children, useMqtt, commandVersion, devices, preferredChannel, onError, onMqttReady, }: MqttProviderProps): React.JSX.Element;
49
58
  export declare namespace MqttProvider {
50
59
  var defaultProps: {
51
60
  onMqttReady: undefined;
@@ -7,6 +7,8 @@ import { setUnhandledRejectionHandler } from './promise';
7
7
  import { ProtocolEnum } from './type';
8
8
  import log4js from '@ray-js/log4js';
9
9
 
10
+ // 通信通道类型
11
+
10
12
  // Context 类型定义
11
13
 
12
14
  // 创建一个Context
@@ -32,6 +34,7 @@ export function MqttProvider(_ref) {
32
34
  useMqtt,
33
35
  commandVersion,
34
36
  devices,
37
+ preferredChannel = 'mqtt',
35
38
  onError,
36
39
  onMqttReady
37
40
  } = _ref;
@@ -42,10 +45,9 @@ export function MqttProvider(_ref) {
42
45
  const instance = useMemo(() => ({
43
46
  useMqtt,
44
47
  commandVersion,
48
+ preferredChannel,
45
49
  devices
46
- // isLocalOnLine,
47
- // isWifiOnLine,
48
- }), [useMqtt, commandVersion, devices]);
50
+ }), [useMqtt, commandVersion, preferredChannel, devices]);
49
51
 
50
52
  // 使用 ref 存储设备 ID 和初始化状态,避免重复初始化
51
53
  const devIdRef = useRef(null);