568 lines
15 KiB
Markdown
568 lines
15 KiB
Markdown
|
|
# 设备处理器模块文档(Python 版本)
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
设备处理器模块提供了基于 VDA5050 协议的设备管理框架,支持 MQTT 通信,用于监听和处理各类设备(AGV小车、门、电梯等)的消息,并自动转发到指定的 topic。
|
|||
|
|
|
|||
|
|
## 核心概念
|
|||
|
|
|
|||
|
|
### 设备类型 (DeviceType)
|
|||
|
|
|
|||
|
|
系统支持以下设备类型:
|
|||
|
|
- `vehicle`: 小车/AGV
|
|||
|
|
- `door`: 门
|
|||
|
|
- `caller`: 呼叫器
|
|||
|
|
- `lift`: 电梯
|
|||
|
|
- `custom`: 自定义设备
|
|||
|
|
|
|||
|
|
### 设备品牌 (DeviceBrand)
|
|||
|
|
|
|||
|
|
系统支持以下品牌:
|
|||
|
|
- `huarui`: 华睿
|
|||
|
|
- `seer`: 仙工
|
|||
|
|
- `hikrobot`: 海康机器人
|
|||
|
|
- `standard`: 标准协议
|
|||
|
|
- `custom`: 自定义品牌
|
|||
|
|
|
|||
|
|
### 指令类型 (CommandType)
|
|||
|
|
|
|||
|
|
根据设备类型不同,支持的指令类型:
|
|||
|
|
- **小车设备**:`order`、`state`、`factsheet`、`instantActions`
|
|||
|
|
- **其他设备**:`instantActions`
|
|||
|
|
|
|||
|
|
## API 方法
|
|||
|
|
|
|||
|
|
### 注册并运行设备处理器
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids: List[str],
|
|||
|
|
device_type: str = "vehicle",
|
|||
|
|
brand_name: str = "huarui",
|
|||
|
|
command_type: str = None,
|
|||
|
|
handler: Callable = None,
|
|||
|
|
description: str = ""
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:批量注册设备处理器,系统会自动:
|
|||
|
|
1. 根据设备品牌和类型生成 MQTT topics
|
|||
|
|
2. 订阅相应的 topics
|
|||
|
|
3. 开始监听消息
|
|||
|
|
4. 消息到达时自动调用处理函数
|
|||
|
|
5. 自动转发处理结果
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `device_ids`: List[str] - 设备ID列表(必需)
|
|||
|
|
- `device_type`: str - 设备类型,默认 "vehicle"
|
|||
|
|
- `brand_name`: str - 设备品牌,默认 "huarui"
|
|||
|
|
- `command_type`: str - 指令类型(必需),如 "order"、"state"、"instantActions"
|
|||
|
|
- `handler`: Callable - 消息处理函数(必需)
|
|||
|
|
- `description`: str - 设备描述信息
|
|||
|
|
|
|||
|
|
**返回值**:
|
|||
|
|
- List[str] - 成功注册的设备ID列表
|
|||
|
|
|
|||
|
|
**处理函数格式**:
|
|||
|
|
|
|||
|
|
处理函数接收一个 `DeviceMessage` 对象作为参数,并返回一个字典,指示如何处理消息。
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def handler(message):
|
|||
|
|
"""
|
|||
|
|
消息处理函数
|
|||
|
|
|
|||
|
|
参数:
|
|||
|
|
message: DeviceMessage对象,包含以下属性:
|
|||
|
|
- device_id: str - 设备ID
|
|||
|
|
- device_type: DeviceType - 设备类型
|
|||
|
|
- topic: str - 接收消息的topic
|
|||
|
|
- payload: dict - 消息载荷(已解析为字典)
|
|||
|
|
- timestamp: float - 消息时间戳
|
|||
|
|
|
|||
|
|
返回值: dict - 处理结果,支持以下字段:
|
|||
|
|
{
|
|||
|
|
"forward": bool, # 是否转发消息(可选,默认True)
|
|||
|
|
"payload": dict, # 要转发的消息载荷(可选,默认使用原始消息)
|
|||
|
|
"response_topic": str, # 自定义响应topic(可选)
|
|||
|
|
"response": dict # 自定义响应消息载荷(可选,需配合response_topic)
|
|||
|
|
}
|
|||
|
|
"""
|
|||
|
|
# 处理逻辑
|
|||
|
|
return {"forward": True}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**返回值格式约束**:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 必需 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| forward | bool | 否 | 是否转发消息,默认 True |
|
|||
|
|
| payload | dict | 否 | 转发的消息载荷,默认使用原始消息 |
|
|||
|
|
| response_topic | str | 否 | 自定义响应的 topic |
|
|||
|
|
| response | dict | 否 | 自定义响应的消息载荷,需配合 response_topic |
|
|||
|
|
|
|||
|
|
**注意事项**:
|
|||
|
|
- 返回值必须是字典类型
|
|||
|
|
- `payload` 和 `response` 必须是字典类型
|
|||
|
|
- 如果提供 `response`,必须同时提供 `response_topic`
|
|||
|
|
|
|||
|
|
### 使用示例
|
|||
|
|
|
|||
|
|
#### 示例1:批量注册华瑞小车处理 order 指令
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def agv_order_processor(message):
|
|||
|
|
"""处理AGV订单指令"""
|
|||
|
|
VWED.log.info(f"收到订单: 设备 {message.device_id}")
|
|||
|
|
VWED.log.info(f"订单内容: {message.payload}")
|
|||
|
|
|
|||
|
|
# 提取订单信息
|
|||
|
|
order_id = message.payload.get("orderId")
|
|||
|
|
nodes = message.payload.get("nodes", [])
|
|||
|
|
|
|||
|
|
# 可以在这里添加业务逻辑,比如:
|
|||
|
|
# - 验证订单有效性
|
|||
|
|
# - 记录到数据库
|
|||
|
|
# - 通知其他系统
|
|||
|
|
|
|||
|
|
# 直接透传到设备
|
|||
|
|
return {
|
|||
|
|
"forward": True # 使用原始消息转发
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 注册处理器
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001", "AGV002", "AGV003"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="order",
|
|||
|
|
handler=agv_order_processor,
|
|||
|
|
description="华瑞小车order指令处理器"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例2:修改消息后转发
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def agv_state_processor(message):
|
|||
|
|
"""处理AGV状态消息,添加额外信息后转发"""
|
|||
|
|
state_data = message.payload
|
|||
|
|
|
|||
|
|
# 添加额外的业务信息
|
|||
|
|
enhanced_state = {
|
|||
|
|
**state_data,
|
|||
|
|
"processed_at": VWED.get_current_time(),
|
|||
|
|
"system_status": "online",
|
|||
|
|
"battery_warning": state_data.get("batteryState", {}).get("batteryCharge", 100) < 20
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 转发修改后的消息
|
|||
|
|
return {
|
|||
|
|
"forward": True,
|
|||
|
|
"payload": enhanced_state
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001", "AGV002"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="state",
|
|||
|
|
handler=agv_state_processor,
|
|||
|
|
description="AGV状态处理器(增强版)"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例3:不转发,仅记录
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def agv_monitor(message):
|
|||
|
|
"""仅监控AGV消息,不转发"""
|
|||
|
|
# 记录到数据库
|
|||
|
|
VWED.db.execute_update(
|
|||
|
|
"INSERT INTO agv_logs (device_id, message, created_at) VALUES (?, ?, ?)",
|
|||
|
|
[message.device_id, str(message.payload), VWED.get_current_time()]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 不转发
|
|||
|
|
return {"forward": False}
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="state",
|
|||
|
|
handler=agv_monitor,
|
|||
|
|
description="AGV监控(仅记录)"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例4:发送自定义响应
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def door_controller(message):
|
|||
|
|
"""门控制器,接收指令后返回确认"""
|
|||
|
|
action = message.payload.get("instantActions", [])
|
|||
|
|
|
|||
|
|
if action:
|
|||
|
|
action_type = action[0].get("actionType")
|
|||
|
|
|
|||
|
|
# 处理开门/关门指令
|
|||
|
|
if action_type == "openDoor":
|
|||
|
|
VWED.log.info(f"门 {message.device_id} 正在开启...")
|
|||
|
|
result = "success"
|
|||
|
|
elif action_type == "closeDoor":
|
|||
|
|
VWED.log.info(f"门 {message.device_id} 正在关闭...")
|
|||
|
|
result = "success"
|
|||
|
|
else:
|
|||
|
|
result = "unknown_action"
|
|||
|
|
|
|||
|
|
# 不转发原始消息,发送自定义响应
|
|||
|
|
return {
|
|||
|
|
"forward": False,
|
|||
|
|
"response_topic": f"devices/door/{message.device_id}/response",
|
|||
|
|
"response": {
|
|||
|
|
"device_id": message.device_id,
|
|||
|
|
"action": action_type,
|
|||
|
|
"result": result,
|
|||
|
|
"timestamp": VWED.get_current_time()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {"forward": False}
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["DOOR001", "DOOR002"],
|
|||
|
|
device_type="door",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="instantActions",
|
|||
|
|
handler=door_controller,
|
|||
|
|
description="门设备控制器"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 示例5:条件转发
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def smart_forwarder(message):
|
|||
|
|
"""根据条件决定是否转发"""
|
|||
|
|
battery = message.payload.get("batteryState", {}).get("batteryCharge", 100)
|
|||
|
|
|
|||
|
|
# 电量低于20%时不转发,发送告警
|
|||
|
|
if battery < 20:
|
|||
|
|
VWED.log.warning(f"设备 {message.device_id} 电量过低: {battery}%")
|
|||
|
|
|
|||
|
|
# 发送告警消息到告警topic
|
|||
|
|
return {
|
|||
|
|
"forward": False,
|
|||
|
|
"response_topic": "alerts/battery/low",
|
|||
|
|
"response": {
|
|||
|
|
"device_id": message.device_id,
|
|||
|
|
"battery": battery,
|
|||
|
|
"alert_level": "critical",
|
|||
|
|
"timestamp": VWED.get_current_time()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 正常转发
|
|||
|
|
return {"forward": True}
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001", "AGV002", "AGV003"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="state",
|
|||
|
|
handler=smart_forwarder,
|
|||
|
|
description="智能转发器(低电量告警)"
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 停止设备处理器
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.stop_handler(device_id: str)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:停止指定设备处理器的运行
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `device_id`: str - 设备ID
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
# 停止设备处理器
|
|||
|
|
VWED.device.stop_handler("AGV001")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 获取运行中的处理器列表
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.get_running_handlers() -> Dict[str, Any]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:获取所有正在运行的设备处理器信息
|
|||
|
|
|
|||
|
|
**返回值**:包含所有设备处理器状态的字典
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
handlers = VWED.device.get_running_handlers()
|
|||
|
|
VWED.log.info(f"运行中的处理器: {handlers}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 获取设备处理器状态
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.get_handler_status(device_id: str) -> Dict[str, Any]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:获取指定设备处理器的运行状态
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `device_id`: str - 设备ID
|
|||
|
|
|
|||
|
|
**返回值**:设备处理器状态信息
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
status = VWED.device.get_handler_status("AGV001")
|
|||
|
|
VWED.log.info(f"设备状态: {status}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 主动发布MQTT消息
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
await VWED.device.publish_message(topic: str, payload: Any)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:主动向指定 topic 发布 MQTT 消息(异步方法)
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `topic`: str - MQTT topic
|
|||
|
|
- `payload`: dict - 消息载荷
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
# 异步发布
|
|||
|
|
await VWED.device.publish_message(
|
|||
|
|
topic="factory/agv/command",
|
|||
|
|
payload={"action": "move", "x": 100, "y": 200}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 或使用同步方式
|
|||
|
|
VWED.device.sync_publish_message(
|
|||
|
|
topic="factory/agv/command",
|
|||
|
|
payload={"action": "move", "x": 100, "y": 200}
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 获取支持的设备类型
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.get_device_types() -> List[str]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:获取系统支持的所有设备类型
|
|||
|
|
|
|||
|
|
**返回值**:设备类型列表
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
types = VWED.device.get_device_types()
|
|||
|
|
VWED.log.info(f"支持的设备类型: {types}")
|
|||
|
|
# 输出: ['vehicle', 'door', 'caller', 'lift', 'conveyor', 'sensor', 'robot', 'camera', 'scanner', 'custom']
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 获取支持的设备品牌
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
VWED.device.get_device_brands() -> List[str]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:获取系统支持的所有设备品牌
|
|||
|
|
|
|||
|
|
**返回值**:设备品牌列表
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```python
|
|||
|
|
brands = VWED.device.get_device_brands()
|
|||
|
|
VWED.log.info(f"支持的设备品牌: {brands}")
|
|||
|
|
# 输出: ['huarui', 'seer', 'quicktron', 'geek', 'mushiny', 'flashhold', 'hikrobot', 'standard', 'custom']
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 完整应用示例
|
|||
|
|
|
|||
|
|
### 场景:AGV车队管理系统
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# AGV订单处理器
|
|||
|
|
def process_agv_order(message):
|
|||
|
|
"""处理AGV订单"""
|
|||
|
|
order_data = message.payload
|
|||
|
|
order_id = order_data.get("orderId")
|
|||
|
|
|
|||
|
|
# 记录订单到数据库
|
|||
|
|
VWED.db.execute_update(
|
|||
|
|
"INSERT INTO agv_orders (device_id, order_id, data, created_at) VALUES (?, ?, ?, ?)",
|
|||
|
|
[message.device_id, order_id, str(order_data), VWED.get_current_time()]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
VWED.log.info(f"AGV {message.device_id} 收到订单 {order_id}")
|
|||
|
|
|
|||
|
|
# 透传订单到设备
|
|||
|
|
return {"forward": True}
|
|||
|
|
|
|||
|
|
# AGV状态监控
|
|||
|
|
def monitor_agv_state(message):
|
|||
|
|
"""监控AGV状态并记录关键信息"""
|
|||
|
|
state = message.payload
|
|||
|
|
battery = state.get("batteryState", {}).get("batteryCharge", 100)
|
|||
|
|
position = state.get("agvPosition", {})
|
|||
|
|
errors = state.get("errors", [])
|
|||
|
|
|
|||
|
|
# 更新设备状态到数据库
|
|||
|
|
VWED.db.execute_update(
|
|||
|
|
"UPDATE agv_devices SET battery=?, position_x=?, position_y=?, last_update=? WHERE device_id=?",
|
|||
|
|
[battery, position.get("x"), position.get("y"), VWED.get_current_time(), message.device_id]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 处理错误
|
|||
|
|
if errors:
|
|||
|
|
for error in errors:
|
|||
|
|
VWED.log.error(f"AGV {message.device_id} 错误: {error.get('errorDescription')}")
|
|||
|
|
# 发送告警
|
|||
|
|
VWED.device.sync_publish_message(
|
|||
|
|
topic=f"alerts/agv/{message.device_id}/error",
|
|||
|
|
payload={
|
|||
|
|
"device_id": message.device_id,
|
|||
|
|
"error": error,
|
|||
|
|
"timestamp": VWED.get_current_time()
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 低电量告警
|
|||
|
|
if battery < 20:
|
|||
|
|
VWED.log.warning(f"AGV {message.device_id} 电量低: {battery}%")
|
|||
|
|
VWED.device.sync_publish_message(
|
|||
|
|
topic=f"alerts/agv/{message.device_id}/battery",
|
|||
|
|
payload={
|
|||
|
|
"device_id": message.device_id,
|
|||
|
|
"battery": battery,
|
|||
|
|
"level": "warning",
|
|||
|
|
"timestamp": VWED.get_current_time()
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 转发状态
|
|||
|
|
return {"forward": True}
|
|||
|
|
|
|||
|
|
# 注册华瑞AGV处理器
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["HR_AGV001", "HR_AGV002", "HR_AGV003"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="order",
|
|||
|
|
handler=process_agv_order,
|
|||
|
|
description="华瑞AGV订单处理器"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["HR_AGV001", "HR_AGV002", "HR_AGV003"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="state",
|
|||
|
|
handler=monitor_agv_state,
|
|||
|
|
description="华瑞AGV状态监控"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 注册仙工AGV处理器
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["SEER_AGV001", "SEER_AGV002"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="seer",
|
|||
|
|
command_type="order",
|
|||
|
|
handler=process_agv_order,
|
|||
|
|
description="仙工AGV订单处理器"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["SEER_AGV001", "SEER_AGV002"],
|
|||
|
|
device_type="vehicle",
|
|||
|
|
brand_name="seer",
|
|||
|
|
command_type="state",
|
|||
|
|
handler=monitor_agv_state,
|
|||
|
|
description="仙工AGV状态监控"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
VWED.log.info("AGV车队管理系统已启动")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### 1. 如何处理多个品牌的设备?
|
|||
|
|
|
|||
|
|
分别为每个品牌注册处理器,系统会自动根据品牌生成正确的 MQTT topic。
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 华瑞设备
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["HR_001", "HR_002"],
|
|||
|
|
brand_name="huarui",
|
|||
|
|
command_type="order",
|
|||
|
|
handler=handler_func
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 仙工设备
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["SEER_001", "SEER_002"],
|
|||
|
|
brand_name="seer",
|
|||
|
|
command_type="order",
|
|||
|
|
handler=handler_func
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 一个设备可以注册多个处理器吗?
|
|||
|
|
|
|||
|
|
可以,但需要处理不同的指令类型:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 处理order指令
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001"],
|
|||
|
|
command_type="order",
|
|||
|
|
handler=order_handler
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 处理state指令
|
|||
|
|
VWED.device.register_and_run(
|
|||
|
|
device_ids=["AGV001"],
|
|||
|
|
command_type="state",
|
|||
|
|
handler=state_handler
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 返回值必须是字典吗?
|
|||
|
|
|
|||
|
|
是的,必须返回字典类型,否则会记录错误日志并忽略该返回值。
|
|||
|
|
|
|||
|
|
### 4. 如何调试消息处理?
|
|||
|
|
|
|||
|
|
使用日志记录消息内容:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def debug_handler(message):
|
|||
|
|
VWED.log.info(f"收到消息:")
|
|||
|
|
VWED.log.info(f" 设备ID: {message.device_id}")
|
|||
|
|
VWED.log.info(f" Topic: {message.topic}")
|
|||
|
|
VWED.log.info(f" 载荷: {message.payload}")
|
|||
|
|
return {"forward": True}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
1. **处理函数必须返回字典**:返回值格式必须符合约定
|
|||
|
|
2. **payload 必须是字典类型**:转发和响应的 payload 都必须是字典
|
|||
|
|
3. **批量注册时所有设备使用相同的处理函数**:如果需要不同的处理逻辑,分别注册
|
|||
|
|
4. **处理函数应该快速返回**:避免长时间阻塞,影响其他消息处理
|
|||
|
|
5. **异常处理**:系统会自动捕获异常并记录日志,但建议在处理函数中添加适当的异常处理
|
|||
|
|
6. **资源清理**:脚本停止时会自动清理所有注册的设备处理器
|