release: bump version to 0.50.0
This commit is contained in:
96
motion_agent/events.py
Normal file
96
motion_agent/events.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Stable event models emitted by the local motion capture agent."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from typing import Any, Literal
|
||||
|
||||
GestureName = Literal["rotate_left", "rotate_right", "zoom_in", "zoom_out", "confirm"]
|
||||
GesturePhase = Literal["start", "active", "end", "discrete"]
|
||||
|
||||
|
||||
def now_ms() -> int:
|
||||
return int(time.time() * 1000)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class GestureEvent:
|
||||
gesture: GestureName
|
||||
phase: GesturePhase = "discrete"
|
||||
confidence: float = 1.0
|
||||
intensity: float = 1.0
|
||||
timestamp_ms: int = field(default_factory=now_ms)
|
||||
seq: int = 0
|
||||
source: str = "motion-agent"
|
||||
mode: str = "single"
|
||||
payload: dict[str, Any] = field(default_factory=dict)
|
||||
type: Literal["gesture"] = "gesture"
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return json.dumps(self.to_dict(), ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class StatusEvent:
|
||||
connected: bool
|
||||
camera_count: int
|
||||
active_camera_ids: tuple[str, ...] = ()
|
||||
mode: str = "single"
|
||||
recognizer: str = "mediapipe-opencv"
|
||||
fps: float = 0.0
|
||||
last_gesture: str | None = None
|
||||
error: str | None = None
|
||||
timestamp_ms: int = field(default_factory=now_ms)
|
||||
source: str = "motion-agent"
|
||||
type: Literal["status"] = "status"
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return json.dumps(self.to_dict(), ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class HeartbeatEvent:
|
||||
timestamp_ms: int = field(default_factory=now_ms)
|
||||
source: str = "motion-agent"
|
||||
type: Literal["heartbeat"] = "heartbeat"
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return json.dumps(self.to_dict(), ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SkeletonJoint:
|
||||
id: str
|
||||
x: float
|
||||
y: float
|
||||
confidence: float = 1.0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SkeletonEvent:
|
||||
joints: list[SkeletonJoint]
|
||||
bones: list[tuple[str, str]]
|
||||
matched_gesture: GestureName | None = None
|
||||
confidence: float = 0.0
|
||||
camera_id: str = "unknown"
|
||||
timestamp_ms: int = field(default_factory=now_ms)
|
||||
source: str = "motion-agent"
|
||||
mode: str = "single"
|
||||
type: Literal["skeleton"] = "skeleton"
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return json.dumps(self.to_dict(), ensure_ascii=False, separators=(",", ":"))
|
||||
Reference in New Issue
Block a user