base_agent/uas/event/event_model.py

207 lines
8.8 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
# -*- coding: utf-8 -*-
"""
事件数据模型
Event 核心事件对象贯穿整个生命周期
EventResult 处理器返回结果
EventState 事件处理状态机
"""
from __future__ import annotations
import time
import uuid
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional, Union
from uas.event.event_type import EventType, EventPriority, event_registry
# ─────────────────────────────────────────────────────────────────
# 事件状态
# ─────────────────────────────────────────────────────────────────
class EventState(Enum):
CREATED = "created" # 已创建,未提交
PENDING = "pending" # 已提交,等待处理
PROCESSING = "processing" # 处理中
HANDLED = "handled" # 已处理完成
CANCELLED = "cancelled" # 已取消
FAILED = "failed" # 处理失败
IGNORED = "ignored" # 无处理器,已忽略
# ─────────────────────────────────────────────────────────────────
# 事件处理结果
# ─────────────────────────────────────────────────────────────────
@dataclass
class EventResult:
"""单个处理器的执行结果"""
handler_name: str
success: bool
data: Any = None
error: str = ""
elapsed_ms: float = 0.0
def __repr__(self):
status = "" if self.success else ""
return f"EventResult({status} {self.handler_name} {self.elapsed_ms:.1f}ms)"
# ─────────────────────────────────────────────────────────────────
# 核心事件对象
# ─────────────────────────────────────────────────────────────────
@dataclass
class Event:
"""
核心事件对象
字段说明
event_type 事件类型EventType 枚举 自定义字符串
source 事件来源设备ID模块名等
params 事件携带参数任意字典
priority 优先级默认从注册表读取
timestamp 发生时间Unix 时间戳自动填充
event_id 唯一标识UUID自动生成
"""
event_type: Union[EventType, str]
source: str = "unknown"
params: Dict[str, Any] = field(default_factory=dict)
priority: Optional[EventPriority] = None
message: str = ""
# 自动填充字段
event_id: str = field(default_factory=lambda: str(uuid.uuid4()))
timestamp: float = field(default_factory=time.time)
state: EventState = field(default=EventState.CREATED)
# 运行时字段(不参与构造)
results: List[EventResult] = field(default_factory=list)
_cancelled: bool = field(default=False, repr=False)
_submit_time: Optional[float] = field(default=None, repr=False)
_done_time: Optional[float] = field(default=None, repr=False)
def __post_init__(self):
# 若未指定优先级,从注册表读取
if self.priority is None:
self.priority = event_registry.get_priority(self.type_key)
# ── 属性 ──────────────────────────────────────────────────────
@property
def type_key(self) -> str:
"""统一返回字符串 key"""
return (self.event_type.value
if isinstance(self.event_type, EventType)
else str(self.event_type))
@property
def datetime(self) -> datetime:
return datetime.fromtimestamp(self.timestamp)
@property
def datetime_str(self) -> str:
return self.datetime.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
@property
def is_cancelled(self) -> bool:
return self._cancelled
@property
def elapsed_ms(self) -> float:
"""从提交到完成的总耗时ms"""
if self._submit_time and self._done_time:
return (self._done_time - self._submit_time) * 1000
return 0.0
@property
def success_count(self) -> int:
return sum(1 for r in self.results if r.success)
@property
def failed_count(self) -> int:
return sum(1 for r in self.results if not r.success)
# ── 状态操作 ──────────────────────────────────────────────────
def cancel(self) -> bool:
"""取消事件(仅 cancellable 类型可取消)"""
if event_registry.is_cancellable(self.type_key):
self._cancelled = True
self.state = EventState.CANCELLED
return True
return False
def mark_pending(self):
self.state = EventState.PENDING
self._submit_time = time.time()
def mark_processing(self):
self.state = EventState.PROCESSING
def mark_done(self):
self._done_time = time.time()
if self._cancelled:
self.state = EventState.CANCELLED
elif any(not r.success for r in self.results):
self.state = EventState.FAILED
elif not self.results:
self.state = EventState.IGNORED
else:
self.state = EventState.HANDLED
def add_result(self, result: EventResult):
self.results.append(result)
# ── 序列化 ────────────────────────────────────────────────────
def to_dict(self) -> dict:
return {
"event_id": self.event_id,
"event_type": self.type_key,
"source": self.source,
"message": self.message,
"params": self.params,
"priority": self.priority.name if self.priority else "NORMAL",
"timestamp": self.timestamp,
"datetime": self.datetime_str,
"state": self.state.value,
"elapsed_ms": self.elapsed_ms,
"results": [str(r) for r in self.results],
}
def __repr__(self):
return (f"Event(id={self.event_id[:8]}, type={self.type_key!r}, "
f"src={self.source!r}, state={self.state.value}, "
f"priority={self.priority.name if self.priority else 'N/A'})")
# ─────────────────────────────────────────────────────────────────
# 便捷工厂函数
# ─────────────────────────────────────────────────────────────────
def make_event(
event_type: Union[EventType, str],
source: str = "system",
message: str = "",
**params
) -> Event:
"""
快速创建事件
示例
e = make_event(EventType.DEVICE_ERROR, source="sensor-01",
message="温度传感器异常", code="E001", temp=98.5)
"""
return Event(
event_type = event_type,
source = source,
message = message,
params = params,
)