base_agent/uas/event/handlers/device_handlers.py

115 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
设备/装备事件处理器集合
演示两种注册方式:类继承 + @on_event 装饰器
"""
import asyncio
import logging
from uas.event.event_handler import BaseEventHandler, on_event
from uas.event.event_model import Event
from uas.event.event_type import EventType
logger = logging.getLogger(__name__)
# ─────────────────────────────────────────────────────────────────
# 方式1继承 BaseEventHandler面向对象
# ─────────────────────────────────────────────────────────────────
class DeviceErrorHandler(BaseEventHandler):
"""设备错误处理器:记录日志 + 触发告警"""
event_types = [EventType.DEVICE_ERROR]
priority = 0 # 最高优先执行
def handle(self, event: Event):
code = event.params.get("code", "UNKNOWN")
device = event.source
message = event.message or "设备发生未知错误"
self.logger.error(
f"🔴 设备错误 | device={device} code={code} | {message}"
)
# 模拟:错误码 E999 触发紧急停机
if code == "E999":
self.logger.critical(f"⚠️ 紧急停机指令已发送 -> {device}")
return {"action": "emergency_stop", "device": device}
return {"action": "log", "code": code}
class DeviceTimeoutHandler(BaseEventHandler):
"""设备超时处理器:尝试重连"""
event_types = [EventType.DEVICE_TIMEOUT]
priority = 0
def handle(self, event: Event):
retry = event.params.get("retry_count", 0)
self.logger.warning(
f"⏱️ 设备超时 | device={event.source} retry={retry}"
)
if retry >= 3:
self.logger.error(f"设备 {event.source} 超时重试超限,标记离线")
return {"action": "mark_offline"}
return {"action": "reconnect", "retry": retry + 1}
class EquipmentFaultHandler(BaseEventHandler):
"""装备故障处理器:故障分级响应"""
event_types = [EventType.EQUIPMENT_FAULT, EventType.EQUIPMENT_ALARM]
priority = 0
LEVEL_ACTIONS = {
"critical": "立即停机并通知维修人员",
"major": "降级运行并记录故障",
"minor": "记录故障,继续运行",
}
def handle(self, event: Event):
level = event.params.get("level", "minor")
action = self.LEVEL_ACTIONS.get(level, "记录故障")
self.logger.warning(
f"⚙️ 装备故障 | src={event.source} level={level} | {action}"
)
return {"level": level, "action": action}
# ─────────────────────────────────────────────────────────────────
# 方式2@on_event 装饰器(函数式)
# ─────────────────────────────────────────────────────────────────
@on_event(EventType.DEVICE_CONNECTED, EventType.DEVICE_DISCONNECTED)
def handle_device_connection(event: Event):
"""设备连接/断开日志记录"""
icon = "🟢" if event.event_type == EventType.DEVICE_CONNECTED else "🔴"
logger.info(f"{icon} 设备连接状态变更 | {event.source} | {event.message}")
@on_event(EventType.DEVICE_WARNING,
condition=lambda e: e.params.get("temp", 0) > 80)
def handle_high_temp_warning(event: Event):
"""仅处理温度超过80°C的设备警告"""
temp = event.params.get("temp", 0)
logger.warning(f"🌡️ 高温警告 | device={event.source} temp={temp}°C")
return {"alert": "high_temp", "temp": temp}
@on_event(EventType.EQUIPMENT_RECOVERED)
def handle_equipment_recovered(event: Event):
"""装备恢复正常"""
logger.info(f"✅ 装备已恢复 | {event.source} | {event.message}")
@on_event(EventType.SYSTEM_HEARTBEAT, priority=100) # 低优先级
async def async_heartbeat_handler(event: Event):
"""异步心跳处理器(演示 async 支持)"""
await asyncio.sleep(0.01) # 模拟异步IO
logger.debug(f"💓 心跳 | {event.source} | ts={event.timestamp:.3f}")
@on_event("*", priority=999) # 通配符:捕获所有事件
def global_audit_handler(event: Event):
"""全局审计处理器(最低优先级,记录所有事件)"""
logger.debug(
f"📋 审计 | {event.type_key} | src={event.source} "
f"| id={event.event_id[:8]}"
)