# VWED设备处理器使用示例文档 ## 概述 本文档详细说明了在VWED在线脚本中如何使用更新后的设备处理器功能,特别是对VDA5050协议的支持。 **核心特点:** - **消息透传模式**: 消息直接透传,不进行编解码处理,保持原始数据格式 - **内置MQTT服务**: 集成自己的MQTT客户端,自主管理连接和重连 - **多设备类型支持**: 支持vehicle、door、caller、lift、sensor、robot等设备类型 - **多品牌支持**: 支持huarui、seer、quicktron、geek等主流设备品牌 - **注册即运行**: 调用 `VWED.device.register_and_run()` 后立即开始监听MQTT消息 - **自动处理**: 消息到达时自动调用您定义的处理函数 - **自动转发**: 处理完成后自动发送到指定topic - **持续运行**: 一次注册,持续处理消息直到手动停止 - **脚本ID自动关联**: `script_id` 参数由系统在热加载时自动传入,无需用户手动提供 --- ## 1. VDA5050协议小车设备示例 ### 1.1 VDA5050小车注册和处理 ```python #!/usr/bin/env python # -*- coding: utf-8 -*- def boot(): """VDA5050小车处理脚本启动函数""" # 注册华睿小车处理器(消息透传模式) VWED.device.register_and_run( device_id="huarui_agv_001", device_type="vehicle", listen_topics=["vda5050/v2/huarui_agv_001/state", "vda5050/v2/huarui_agv_001/factsheet"], forward_topics=["fleet/huarui_agv_001/status"], handler=vda5050_vehicle_handler, device_brand="huarui", protocol_type="vda5050", # 协议类型 description="华睿小车处理器" ) def vda5050_vehicle_handler(message): """VDA5050小车消息处理器""" device_id = message.device_id payload = message.payload VWED.log.sync_info(f"收到VDA5050小车 {device_id} 消息: {payload}") # 根据消息内容处理(消息透传,保持原始格式) # 可以根据实际消息格式调整解析逻辑 message_type = payload.get('message_type', payload.get('command_type', 'unknown')) if message_type == 'state_response' or 'driving' in payload: # 处理状态响应 driving = payload.get('driving', False) paused = payload.get('paused', False) operating_mode = payload.get('operating_mode', 'unknown') battery_state = payload.get('battery_state', {}) agv_position = payload.get('agv_position', {}) VWED.log.sync_info(f"小车状态 - 运行: {driving}, 暂停: {paused}, 模式: {operating_mode}") VWED.log.sync_info(f"电池状态: {battery_state}") VWED.log.sync_info(f"位置: {agv_position}") # 检查低电量警告 battery_charge = battery_state.get('batteryCharge', 100) if battery_charge < 20: VWED.log.sync_warning(f"小车 {device_id} 电量不足: {battery_charge}%") # 发送低电量警报 alert = { "type": "low_battery_alert", "device_id": device_id, "battery_level": battery_charge, "timestamp": VWED.util.now() } return { "forward": True, "topics": ["fleet/alerts", "fleet/huarui_agv_001/status"], "payload": [alert, payload] } elif message_type == 'factsheet_response' or 'manufacturer' in payload: # 处理设备信息响应 manufacturer = payload.get('manufacturer', '') serial_number = payload.get('serial_number', '') type_spec = payload.get('type_specification', {}) VWED.log.sync_info(f"设备信息 - 制造商: {manufacturer}, 序列号: {serial_number}") # 存储设备信息到缓存 VWED.data.set(f"device_info_{device_id}", { "manufacturer": manufacturer, "serial_number": serial_number, "type_specification": type_spec, "updated_at": VWED.util.now() }) # 默认转发消息 return { "forward": True, "payload": { "device_id": device_id, "original_data": payload, "processed_at": VWED.util.now() } } # VDA5050指令发送示例 def send_vda5050_order_example(): """发送VDA5050订单指令示例""" # 构建订单数据 order_data = { "order_id": f"order_{int(VWED.util.timestamp())}", "nodes": [ { "nodeId": "pickup_station", "sequenceId": 1, "nodePosition": {"x": 10.5, "y": 20.3, "theta": 0.0, "mapId": "warehouse_map"}, "actions": [ { "actionType": "pick", "actionId": "pick_001", "actionDescription": "Pick up cargo", "blockingType": "HARD", "actionParameters": [ {"key": "load_type", "value": "box"}, {"key": "weight", "value": "5"} ] } ] }, { "nodeId": "delivery_station", "sequenceId": 2, "nodePosition": {"x": 30.0, "y": 45.0, "theta": 1.57, "mapId": "warehouse_map"}, "actions": [ { "actionType": "drop", "actionId": "drop_001", "actionDescription": "Drop cargo", "blockingType": "HARD" } ] } ], "edges": [ { "edgeId": "edge_pickup_to_delivery", "sequenceId": 1, "startNodeId": "pickup_station", "endNodeId": "delivery_station", "maxSpeed": 1.5, "actions": [] } ] } # 发送订单 VWED.device.send_order("huarui_agv_001", order_data) VWED.log.sync_info("订单已发送") def send_emergency_stop(): """发送紧急停止指令""" emergency_actions = [ { "actionType": "cancelOrder", "actionId": f"emergency_stop_{int(VWED.util.timestamp())}", "actionDescription": "Emergency stop - cancel current order", "blockingType": "HARD" } ] VWED.device.send_instant_action("huarui_agv_001", emergency_actions) VWED.log.sync_warning("紧急停止指令已发送") def request_vehicle_state(): """请求小车状态""" VWED.device.request_state("huarui_agv_001") VWED.log.sync_info("状态查询请求已发送") ``` ### 1.2 门设备即时动作示例 ```python def boot(): """门设备VDA5050即时动作处理""" # 注册门设备处理器 VWED.device.register_and_run( device_id="door_001", device_type="door", listen_topics=["door/door_001/status"], forward_topics=["facility/door_001/events"], handler=door_instant_action_handler, device_brand="standard", protocol_type="vda5050", description="门设备处理器" ) def door_instant_action_handler(message): """门设备即时动作处理器""" device_id = message.device_id payload = message.payload VWED.log.sync_info(f"收到门设备 {device_id} 消息: {payload}") door_status = payload.get('door_status', 'unknown') if door_status == 'access_requested': # 处理门禁访问请求 card_id = payload.get('card_id') # 验证访问权限 if is_authorized_card(card_id): # 发送开门指令 open_actions = [ { "actionType": "open", "actionId": f"open_{int(VWED.util.timestamp())}", "actionDescription": f"Open door for card {card_id}", "blockingType": "SOFT", "actionParameters": [ {"key": "duration", "value": "5"}, # 开门5秒 {"key": "card_id", "value": card_id} ] } ] VWED.device.send_instant_action("door_001", open_actions, "door/door_001/control") VWED.log.sync_info(f"已授权开门: {card_id}") return { "forward": True, "payload": { "event": "access_granted", "card_id": card_id, "timestamp": VWED.util.now() } } else: VWED.log.sync_warning(f"未授权访问被拒绝: {card_id}") return { "forward": True, "payload": { "event": "access_denied", "card_id": card_id, "reason": "unauthorized", "timestamp": VWED.util.now() } } return {"forward": True, "payload": payload} def is_authorized_card(card_id): """检查卡片是否有权限""" authorized_cards = VWED.data.get("authorized_cards", ["CARD001", "CARD002", "CARD003"]) return card_id in authorized_cards ``` ### 1.3 通用设备即时动作示例 ```python def boot(): """传感器设备即时动作处理""" # 注册传感器设备 VWED.device.register_and_run( device_id="temp_sensor_001", device_type="sensor", listen_topics=["sensors/temperature/001/data"], forward_topics=["environmental/alerts"], handler=sensor_instant_action_handler, device_brand="standard", protocol_type="vda5050", description="温度传感器处理器" ) def sensor_instant_action_handler(message): """传感器即时动作处理器""" device_id = message.device_id payload = message.payload temperature = payload.get('temperature', 0) VWED.log.sync_info(f"传感器 {device_id} 温度: {temperature}°C") if temperature > 35: # 温度过高,发送冷却指令 cooling_actions = [ { "actionType": "cooling_control", "actionId": f"cool_{int(VWED.util.timestamp())}", "actionDescription": "Activate cooling system", "blockingType": "SOFT", "actionParameters": [ {"key": "target_temp", "value": "25"}, {"key": "priority", "value": "high"} ] } ] VWED.device.send_instant_action("temp_sensor_001", cooling_actions, "hvac/control") return { "forward": True, "payload": { "alert_type": "temperature_high", "temperature": temperature, "action_taken": "cooling_activated", "timestamp": VWED.util.now() } } return {"forward": False} # 正常温度不转发 ``` --- ## 2. 传统协议小车设备示例 ### 1.1 基本小车命令处理 ```python #!/usr/bin/env python # -*- coding: utf-8 -*- def boot(): """脚本启动函数""" # 注册并运行AGV设备处理器 VWED.device.register_and_run( device_id="agv_001", device_type="vehicle", listen_topics=["factory/agv/command"], forward_topics=["factory/agv/execute"], handler=agv_command_processor, device_brand="standard", protocol_type="vda5050", description="AGV命令处理器 - 添加安全检查" ) def agv_command_processor(message): """AGV命令处理逻辑 - 消息到达时自动执行""" # 记录接收到的消息 VWED.log.sync_info(f"收到AGV命令: {message.payload}") command = message.payload.get("command") if command == "move": # 添加安全检查逻辑 x = message.payload.get("x", 0) y = message.payload.get("y", 0) speed = message.payload.get("speed", 100) # 限制最大速度 safe_speed = min(speed, 50) # 检查坐标范围 if x < 0 or x > 1000 or y < 0 or y > 800: VWED.log.sync_warning(f"AGV坐标超出安全范围: x={x}, y={y}") return { "forward": False, # 不转发 "response": { "status": "error", "message": "坐标超出安全范围" }, "response_topic": "factory/agv/response" } # 构建安全的移动命令 safe_command = { "command": "move_safe", "x": x, "y": y, "speed": safe_speed, "safety_check": True, "timestamp": VWED.util.now(), "processed_by": "agv_001_processor" } VWED.log.sync_info(f"AGV安全命令已生成: 速度限制 {speed} -> {safe_speed}") return { "forward": True, "payload": safe_command } elif command == "stop": # 紧急停止 - 直接转发 emergency_stop = { "command": "emergency_stop", "reason": message.payload.get("reason", "manual_stop"), "timestamp": VWED.util.now() } return { "forward": True, "payload": emergency_stop } else: # 未知命令 - 记录并拒绝 VWED.log.sync_warning(f"未知AGV命令: {command}") return { "forward": False, "response": { "status": "error", "message": f"不支持的命令: {command}" }, "response_topic": "factory/agv/response" } ``` **MQTT消息流转示例:** ``` 输入topic: factory/agv/command 输入消息: {"command": "move", "x": 100, "y": 200, "speed": 80} 处理后输出topic: factory/agv/execute 输出消息: {"command": "move_safe", "x": 100, "y": 200, "speed": 50, "safety_check": true, "timestamp": "2024-01-01T12:00:00", "processed_by": "agv_001_processor"} ``` ### 1.2 多AGV协调处理 ```python def boot(): """多AGV统一处理""" # 注册AGV车队控制器 VWED.device.register_and_run( device_id="agv_fleet_controller", device_type="vehicle", listen_topics=["factory/agv/+/command"], # 监听所有AGV命令 forward_topics=["factory/agv/coordination"], handler=agv_fleet_coordinator, device_brand="standard", protocol_type="vda5050", description="AGV车队协调器" ) def agv_fleet_coordinator(message): """AGV车队协调逻辑""" # 解析AGV ID topic_parts = message.topic.split("/") agv_id = topic_parts[2] if len(topic_parts) > 2 else "unknown" command = message.payload.get("command") if command == "move": # 检查路径冲突 x = message.payload.get("x") y = message.payload.get("y") # 获取其他AGV位置(从缓存中) other_agvs = VWED.data.get("agv_positions", {}) # 简单的冲突检测 conflict_detected = False for other_id, other_pos in other_agvs.items(): if other_id != agv_id: distance = ((x - other_pos["x"])**2 + (y - other_pos["y"])**2)**0.5 if distance < 50: # 50cm安全距离 conflict_detected = True break if conflict_detected: # 发送等待指令 wait_command = { "command": "wait", "reason": "path_conflict", "retry_after": 3, # 3秒后重试 "timestamp": VWED.util.now() } VWED.log.sync_warning(f"AGV {agv_id} 路径冲突,指令等待") return { "forward": True, "topics": [f"factory/agv/{agv_id}/execute"], "payload": wait_command } else: # 更新AGV位置缓存 other_agvs[agv_id] = {"x": x, "y": y, "timestamp": VWED.util.now()} VWED.data.set("agv_positions", other_agvs) # 转发原始命令 return { "forward": True, "topics": [f"factory/agv/{agv_id}/execute"], "payload": message.payload } # 默认转发 return { "forward": True, "topics": [f"factory/agv/{agv_id}/execute"], "payload": message.payload } ``` --- ## 2. 门禁(Door)设备处理示例 ### 2.1 基本门禁控制 ```python def boot(): """门禁系统处理器""" VWED.device.register_and_run( device_id="door_main_entrance", device_type="door", listen_topics=["building/door/access_request"], forward_topics=["building/door/control"], handler=door_access_controller, device_brand="standard", protocol_type="vda5050", description="主入口门禁控制器" ) def door_access_controller(message): """门禁访问控制逻辑""" # 获取访问请求信息 card_id = message.payload.get("card_id") door_id = message.payload.get("door_id", "main_entrance") request_time = message.payload.get("timestamp", VWED.util.now()) VWED.log.sync_info(f"门禁访问请求: 卡号={card_id}, 门={door_id}") # 权限验证逻辑 if not card_id: return { "forward": False, "response": {"status": "error", "message": "缺少卡号"}, "response_topic": "building/door/response" } # 检查黑名单 blacklist = VWED.data.get("door_blacklist", []) if card_id in blacklist: VWED.log.sync_warning(f"黑名单卡号访问被拒绝: {card_id}") return { "forward": False, "response": { "status": "denied", "reason": "blacklist", "card_id": card_id, "timestamp": request_time }, "response_topic": "building/door/response" } # 检查白名单 whitelist = VWED.data.get("door_whitelist", [ "CARD001", "CARD002", "CARD003" # 默认白名单 ]) if card_id in whitelist: # 授权开门 open_command = { "action": "open", "door_id": door_id, "card_id": card_id, "authorized_by": "door_main_entrance", "open_duration": 5, # 开门5秒 "timestamp": request_time } # 记录访问日志 access_log = VWED.data.get("door_access_log", []) access_log.append({ "card_id": card_id, "door_id": door_id, "status": "granted", "timestamp": request_time }) # 只保留最近100条记录 if len(access_log) > 100: access_log = access_log[-100:] VWED.data.set("door_access_log", access_log) VWED.log.sync_info(f"门禁访问已授权: {card_id}") return { "forward": True, "payload": open_command } else: # 未授权卡号 VWED.log.sync_warning(f"未授权卡号访问被拒绝: {card_id}") return { "forward": False, "response": { "status": "denied", "reason": "unauthorized", "card_id": card_id, "timestamp": request_time }, "response_topic": "building/door/response" } ``` ### 2.2 门禁状态监控 ```python def boot(): """门禁状态监控""" # 监控门禁状态 VWED.device.register_and_run( device_id="door_status_monitor", device_type="door", listen_topics=["building/door/+/status"], forward_topics=["building/security/alerts"], handler=door_status_monitor, device_brand="standard", protocol_type="vda5050", description="门禁状态监控器" ) def door_status_monitor(message): """门禁状态监控逻辑""" # 解析门ID topic_parts = message.topic.split("/") door_id = topic_parts[2] if len(topic_parts) > 2 else "unknown" status = message.payload.get("status") timestamp = message.payload.get("timestamp", VWED.util.now()) # 更新门状态缓存 door_states = VWED.data.get("door_states", {}) door_states[door_id] = { "status": status, "timestamp": timestamp, "last_update": VWED.util.now() } VWED.data.set("door_states", door_states) # 异常状态检测 if status == "forced_open": # 门被强制打开 - 发送安全警报 alert = { "type": "security_alert", "level": "high", "door_id": door_id, "event": "forced_open", "message": f"门 {door_id} 被强制打开", "timestamp": timestamp, "requires_action": True } VWED.log.sync_error(f"安全警报: 门 {door_id} 被强制打开") return { "forward": True, "payload": alert } elif status == "open_timeout": # 门打开超时 - 发送提醒 alert = { "type": "maintenance_alert", "level": "medium", "door_id": door_id, "event": "open_timeout", "message": f"门 {door_id} 打开时间过长", "timestamp": timestamp, "requires_action": False } VWED.log.sync_warning(f"维护提醒: 门 {door_id} 打开时间过长") return { "forward": True, "payload": alert } # 正常状态 - 不转发 return {"forward": False} ``` --- ## 3. 呼叫器(Caller)设备处理示例 ### 3.1 基本呼叫处理 ```python def boot(): """呼叫器处理系统""" VWED.device.register_and_run( device_id="caller_lobby_01", device_type="caller", listen_topics=["building/caller/signal"], forward_topics=["building/caller/response", "building/notification/broadcast"], handler=caller_signal_processor, device_brand="standard", protocol_type="vda5050", description="大厅呼叫器信号处理器" ) def caller_signal_processor(message): """呼叫器信号处理逻辑""" caller_id = message.payload.get("caller_id") signal_type = message.payload.get("signal_type") location = message.payload.get("location", "unknown") priority = message.payload.get("priority", "normal") VWED.log.sync_info(f"收到呼叫信号: {caller_id} - {signal_type} ({priority})") # 根据信号类型处理 if signal_type == "emergency": # 紧急呼叫 - 立即响应 emergency_response = { "type": "emergency_response", "caller_id": caller_id, "location": location, "status": "received", "response_time": "immediate", "assigned_staff": "security_team", "message": "紧急响应团队已派遣", "timestamp": VWED.util.now() } # 广播紧急通知 emergency_broadcast = { "type": "emergency_broadcast", "level": "critical", "message": f"紧急呼叫: {location} ({caller_id})", "location": location, "caller_id": caller_id, "timestamp": VWED.util.now() } VWED.log.sync_error(f"紧急呼叫处理: {caller_id} 位置: {location}") return { "forward": True, "topics": ["building/caller/response", "building/notification/broadcast"], "payload": [emergency_response, emergency_broadcast] } elif signal_type == "service": # 服务请求 - 分配服务人员 service_response = { "type": "service_response", "caller_id": caller_id, "location": location, "status": "queued", "estimated_time": "5-10 minutes", "queue_position": get_queue_position(location), "message": "服务请求已接收,请稍候", "timestamp": VWED.util.now() } VWED.log.sync_info(f"服务请求处理: {caller_id}") return { "forward": True, "topics": ["building/caller/response"], "payload": service_response } elif signal_type == "information": # 信息查询 - 提供自动回复 info_response = { "type": "information_response", "caller_id": caller_id, "location": location, "status": "completed", "information": get_location_info(location), "timestamp": VWED.util.now() } return { "forward": True, "topics": ["building/caller/response"], "payload": info_response } else: # 未知信号类型 error_response = { "type": "error_response", "caller_id": caller_id, "status": "error", "message": f"不支持的信号类型: {signal_type}", "timestamp": VWED.util.now() } return { "forward": True, "topics": ["building/caller/response"], "payload": error_response } def get_queue_position(location): """获取队列位置""" queue = VWED.data.get(f"service_queue_{location}", []) return len(queue) + 1 def get_location_info(location): """获取位置信息""" location_data = { "lobby": "大厅 - 营业时间: 8:00-18:00, 电话: 123-456-7890", "elevator": "电梯区域 - 共6部电梯, 楼层: B1-F20", "parking": "停车场 - 地下3层, 收费标准: 5元/小时" } return location_data.get(location, "暂无相关信息") ``` ### 3.2 呼叫器多级响应 ```python def boot(): """多级呼叫响应系统""" VWED.device.register_and_run( device_id="caller_escalation_manager", device_type="caller", listen_topics=["building/caller/+/urgent"], forward_topics=["building/staff/notification"], handler=caller_escalation_handler, device_brand="standard", protocol_type="vda5050", description="呼叫升级管理器" ) def caller_escalation_handler(message): """呼叫升级处理逻辑""" # 解析呼叫器ID topic_parts = message.topic.split("/") caller_id = topic_parts[2] if len(topic_parts) > 2 else "unknown" urgency_level = message.payload.get("urgency", "medium") repeat_count = message.payload.get("repeat_count", 1) last_response_time = message.payload.get("last_response_time") # 升级逻辑 if repeat_count >= 3: # 第3次重复呼叫 - 升级到管理层 escalation = { "type": "management_escalation", "caller_id": caller_id, "urgency": "high", "repeat_count": repeat_count, "reason": "multiple_unattended_calls", "notify_roles": ["supervisor", "manager"], "message": f"呼叫器 {caller_id} 连续{repeat_count}次呼叫未响应", "timestamp": VWED.util.now() } VWED.log.sync_warning(f"呼叫升级到管理层: {caller_id} ({repeat_count}次)") return { "forward": True, "payload": escalation } elif repeat_count == 2: # 第2次重复呼叫 - 通知高级员工 notification = { "type": "senior_staff_notification", "caller_id": caller_id, "urgency": "medium", "repeat_count": repeat_count, "notify_roles": ["senior_staff"], "message": f"呼叫器 {caller_id} 重复呼叫,请优先处理", "timestamp": VWED.util.now() } return { "forward": True, "payload": notification } else: # 首次呼叫 - 正常通知 notification = { "type": "normal_notification", "caller_id": caller_id, "urgency": urgency_level, "notify_roles": ["staff"], "message": f"呼叫器 {caller_id} 请求服务", "timestamp": VWED.util.now() } return { "forward": True, "payload": notification } ``` --- ## 4. 综合设备处理示例 ### 4.1 智能楼宇综合管理 ```python def boot(): """智能楼宇综合管理系统""" # 环境监控 VWED.device.register_and_run( device_id="environmental_monitor", device_type="sensor", listen_topics=["building/sensors/+/data"], forward_topics=["building/hvac/control", "building/alerts"], handler=environmental_processor, description="环境监控处理器" ) # 电梯调度 VWED.device.register_and_run( device_id="elevator_scheduler", device_type="lift", listen_topics=["building/elevator/call"], forward_topics=["building/elevator/+/command"], handler=elevator_scheduler, description="电梯调度器" ) # 安全系统集成 VWED.device.register_and_run( device_id="security_integrator", device_type="custom", listen_topics=["building/security/+/event"], forward_topics=["building/security/response"], handler=security_event_processor, description="安全系统集成器" ) def environmental_processor(message): """环境数据处理""" # 解析传感器ID topic_parts = message.topic.split("/") sensor_id = topic_parts[2] if len(topic_parts) > 2 else "unknown" temperature = message.payload.get("temperature") humidity = message.payload.get("humidity") air_quality = message.payload.get("air_quality") controls = [] alerts = [] # 温度控制 if temperature is not None: if temperature > 26: controls.append({ "device": "hvac", "action": "cool", "target_temp": 24, "reason": f"温度过高: {temperature}°C" }) elif temperature < 20: controls.append({ "device": "hvac", "action": "heat", "target_temp": 22, "reason": f"温度过低: {temperature}°C" }) # 湿度控制 if humidity is not None: if humidity > 70: controls.append({ "device": "dehumidifier", "action": "on", "target_humidity": 60, "reason": f"湿度过高: {humidity}%" }) # 空气质量监控 if air_quality is not None and air_quality < 50: alerts.append({ "type": "air_quality_alert", "level": "medium", "sensor_id": sensor_id, "value": air_quality, "message": "空气质量较差,建议开启新风系统" }) # 返回控制指令和警报 responses = [] if controls: responses.append(("building/hvac/control", {"controls": controls, "timestamp": VWED.util.now()})) if alerts: responses.append(("building/alerts", {"alerts": alerts, "timestamp": VWED.util.now()})) if responses: return { "forward": True, "topics": [topic for topic, _ in responses], "payload": [payload for _, payload in responses] } return {"forward": False} def elevator_scheduler(message): """电梯调度逻辑""" floor_from = message.payload.get("from_floor") floor_to = message.payload.get("to_floor") priority = message.payload.get("priority", "normal") # 获取电梯状态 elevator_status = VWED.data.get("elevator_status", { "elevator_1": {"current_floor": 1, "status": "idle"}, "elevator_2": {"current_floor": 10, "status": "busy"}, "elevator_3": {"current_floor": 5, "status": "idle"} }) # 选择最佳电梯 best_elevator = None min_distance = float('inf') for elevator_id, status in elevator_status.items(): if status["status"] == "idle": distance = abs(status["current_floor"] - floor_from) if distance < min_distance: min_distance = distance best_elevator = elevator_id if best_elevator: # 分配电梯 command = { "elevator_id": best_elevator, "action": "goto", "from_floor": floor_from, "to_floor": floor_to, "priority": priority, "estimated_time": min_distance * 3, # 假设每层3秒 "timestamp": VWED.util.now() } # 更新电梯状态 elevator_status[best_elevator]["status"] = "busy" VWED.data.set("elevator_status", elevator_status) return { "forward": True, "topics": [f"building/elevator/{best_elevator}/command"], "payload": command } else: # 无空闲电梯 - 加入队列 queue = VWED.data.get("elevator_queue", []) queue.append({ "from_floor": floor_from, "to_floor": floor_to, "priority": priority, "request_time": VWED.util.now() }) VWED.data.set("elevator_queue", queue) return { "forward": False, "response": { "status": "queued", "position": len(queue), "estimated_wait": len(queue) * 30 # 每个请求30秒 }, "response_topic": "building/elevator/response" } def security_event_processor(message): """安全事件处理""" event_type = message.payload.get("event_type") location = message.payload.get("location") severity = message.payload.get("severity", "medium") if event_type == "intrusion_detected": # 入侵检测 - 立即响应 response = { "action": "lockdown", "location": location, "alert_level": "high", "notify_security": True, "timestamp": VWED.util.now() } return { "forward": True, "payload": response } elif event_type == "fire_alarm": # 火警 - 疏散程序 response = { "action": "evacuation", "location": location, "alert_level": "critical", "notify_fire_dept": True, "timestamp": VWED.util.now() } return { "forward": True, "payload": response } # 其他事件正常处理 return { "forward": True, "payload": message.payload } ``` --- ## 5. 设备处理器管理功能 ### 5.1 设备状态监控 ```python def boot(): """设备管理和监控""" # 注册设备状态监控 VWED.device.register_and_run( device_id="device_status_monitor", device_type="custom", listen_topics=["system/device/+/heartbeat"], forward_topics=["system/alerts"], handler=device_heartbeat_monitor, description="设备心跳监控器" ) # 定时检查设备状态 VWED.timer.interval( seconds=60, # 每分钟检查一次 handler=check_device_status ) def device_heartbeat_monitor(message): """设备心跳监控""" device_id = message.payload.get("device_id") status = message.payload.get("status") timestamp = message.payload.get("timestamp", VWED.util.now()) # 更新设备心跳记录 heartbeats = VWED.data.get("device_heartbeats", {}) heartbeats[device_id] = { "status": status, "last_heartbeat": timestamp, "updated_at": VWED.util.now() } VWED.data.set("device_heartbeats", heartbeats) # 如果设备状态异常,发送警报 if status in ["error", "offline", "malfunction"]: alert = { "type": "device_alert", "device_id": device_id, "status": status, "message": f"设备 {device_id} 状态异常: {status}", "timestamp": timestamp, "requires_attention": True } return { "forward": True, "payload": alert } return {"forward": False} def check_device_status(): """定时检查设备状态""" current_time = VWED.util.timestamp() heartbeats = VWED.data.get("device_heartbeats", {}) for device_id, info in heartbeats.items(): last_heartbeat = info.get("last_heartbeat") if last_heartbeat: # 检查是否超过5分钟没有心跳 if current_time - last_heartbeat > 300: # 5分钟 VWED.log.sync_warning(f"设备 {device_id} 心跳超时") # 发送超时警报 VWED.device.sync_publish_message( topic="system/alerts", payload={ "type": "device_timeout", "device_id": device_id, "last_seen": last_heartbeat, "timeout_duration": current_time - last_heartbeat, "timestamp": VWED.util.now() } ) ``` ### 5.2 设备处理器动态管理 ```python def boot(): """动态设备管理""" # 设备管理控制器 VWED.device.register_and_run( device_id="device_manager", device_type="custom", listen_topics=["system/device/control"], forward_topics=["system/device/response"], handler=device_management_handler, description="设备动态管理控制器" ) def device_management_handler(message): """设备管理控制处理""" action = message.payload.get("action") device_id = message.payload.get("device_id") if action == "status": # 获取设备状态 status = VWED.device.get_handler_status(device_id) return { "forward": True, "payload": { "action": "status_response", "device_id": device_id, "status": status, "timestamp": VWED.util.now() } } elif action == "stop": # 停止设备处理器 try: VWED.device.stop_handler(device_id) return { "forward": True, "payload": { "action": "stop_response", "device_id": device_id, "status": "stopped", "timestamp": VWED.util.now() } } except Exception as e: return { "forward": True, "payload": { "action": "stop_response", "device_id": device_id, "status": "error", "error": str(e), "timestamp": VWED.util.now() } } elif action == "restart": # 重启设备处理器 try: VWED.device.restart_handler(device_id) return { "forward": True, "payload": { "action": "restart_response", "device_id": device_id, "status": "restarted", "timestamp": VWED.util.now() } } except Exception as e: return { "forward": True, "payload": { "action": "restart_response", "device_id": device_id, "status": "error", "error": str(e), "timestamp": VWED.util.now() } } elif action == "list": # 获取所有设备列表 handlers = VWED.device.get_running_handlers() return { "forward": True, "payload": { "action": "list_response", "handlers": handlers, "timestamp": VWED.util.now() } } else: return { "forward": True, "payload": { "action": "error_response", "message": f"不支持的操作: {action}", "timestamp": VWED.util.now() } } ``` --- ## 6. 调试和故障排除 ### 6.1 设备处理器调试 ```python def boot(): """设备处理器调试模式""" # 启用调试模式 debug_mode = True if debug_mode: # 注册调试设备处理器 VWED.device.register_and_run( device_id="debug_processor", device_type="custom", listen_topics=["debug/+/+"], # 监听所有调试消息 forward_topics=[], handler=debug_message_handler, description="调试消息处理器" ) def debug_message_handler(message): """调试消息处理""" # 详细记录消息信息 VWED.log.sync_info(f"调试消息 - Topic: {message.topic}") VWED.log.sync_info(f"调试消息 - Payload: {message.payload}") VWED.log.sync_info(f"调试消息 - Device: {message.device_id}") VWED.log.sync_info(f"调试消息 - Type: {message.device_type}") VWED.log.sync_info(f"调试消息 - Timestamp: {message.timestamp}") # 保存调试日志 debug_logs = VWED.data.get("debug_logs", []) debug_logs.append({ "topic": message.topic, "payload": message.payload, "device_id": message.device_id, "device_type": message.device_type.value if hasattr(message.device_type, 'value') else str(message.device_type), "timestamp": message.timestamp, "processed_at": VWED.util.now() }) # 只保留最近50条调试日志 if len(debug_logs) > 50: debug_logs = debug_logs[-50:] VWED.data.set("debug_logs", debug_logs) # 不转发调试消息 return {"forward": False} def get_debug_statistics(): """获取调试统计信息""" handlers = VWED.device.get_running_handlers() debug_logs = VWED.data.get("debug_logs", []) return { "total_handlers": handlers.get("device_count", 0), "running_handlers": handlers.get("running_devices", 0), "debug_log_count": len(debug_logs), "last_debug_time": debug_logs[-1]["processed_at"] if debug_logs else None } ``` --- ## 总结 本文档提供了VWED设备处理器的完整使用示例,包括: ### 主要功能 1. **设备类型支持** - 小车、门禁、呼叫器、电梯、传感器等 2. **注册即运行** - 一次注册,持续监听和处理MQTT消息 3. **自动转发** - 处理完成后自动发送到指定topic 4. **动态管理** - 支持运行时启停、重启设备处理器 5. **状态监控** - 实时监控设备状态和处理统计 ### 关键特点 - **分离式设计** - 注册和处理逻辑分离,保持代码清晰 - **消息驱动** - MQTT消息自动触发处理,无需手动调用 - **错误处理** - 完善的异常处理和重试机制 - **扩展性强** - 支持自定义设备类型和处理逻辑 - **易于调试** - 详细的日志记录和调试功能 ### 使用建议 1. 根据实际设备类型选择合适的device_type 2. 合理设置listen_topics和forward_topics 3. 在处理函数中添加充分的错误处理 4. 使用VWED.log记录关键操作日志 5. 利用VWED.data缓存必要的状态信息 通过这些示例,您可以快速掌握VWED设备处理器的使用方法,实现复杂的设备逻辑处理和MQTT消息转发。