Files
AareCommon/src/aarecommon/models/aerotech.py
T
perl_d 5dc939a5ab
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / lint (pull_request) Failing after 28s
CI / test (3.11) (pull_request) Skipped
CI / test (3.12) (pull_request) Skipped
CI / test (3.13) (pull_request) Skipped
ci: add more linting steps
2026-08-06 17:41:17 +02:00

155 lines
4.0 KiB
Python

from enum import Enum
from pydantic import BaseModel, ConfigDict, Field
from aarecommon.models.rotation_scan import RotationScanRequest
class TaskEnum(Enum):
TASK_0 = 0
TASK_1 = 1
TASK_2 = 2
TASK_3 = 3
TASK_4 = 4
TASK_5 = 5
TASK_6 = 6
TASK_7 = 7
TASK_8 = 8
TASK_9 = 9
class AxisEnum(Enum):
X = "x"
Y = "y"
Z = "z"
OMEGA = "u"
class AerotechRunEnum(Enum):
STOP = 0
START = 1
RUN = 2
LOAD = 3
PAUSE = 4
RESET = 5
class VariableTypeEnum(Enum):
INT = 0
REAL = 1
STRING = 2
class AerotechAxisStatus(BaseModel):
enabled: bool
fault: int
homed: bool
is_fault: bool
moving: bool
position: float
status: int
velocity: float
class AerotechStatus(BaseModel):
state: str
x: AerotechAxisStatus | None = None
y: AerotechAxisStatus | None = None
z: AerotechAxisStatus | None = None
u: AerotechAxisStatus | None = None
model_config = ConfigDict(extra="allow")
def __str__(self) -> str:
return self.to_pretty_string()
def to_pretty_string(self) -> str:
def axis_line(name: str, axis: AerotechAxisStatus | None) -> str:
if axis is None:
return f"{name.upper()}: unavailable"
return (
f"{name.upper():>2} | pos={axis.position:>12.6f} | "
f"homed={axis.homed!s:<5} | moving={axis.moving!s:<5} | "
f"enabled={axis.enabled!s:<5} | fault={axis.fault} | "
f"faulted={axis.is_fault!s:<5} | vel={axis.velocity:>10.6f}"
)
return "\n".join(
[
f"STATE: {self.state}",
axis_line("x", self.x),
axis_line("y", self.y),
axis_line("z", self.z),
axis_line("u", self.u),
]
)
def to_compact_string(self) -> str:
axes = []
for name in ("x", "y", "z", "u"):
axis = getattr(self, name)
if axis is not None:
axes.append(
f"{name}={axis.position:.4f} "
f"({'H' if axis.homed else 'NH'}, {'M' if axis.moving else '-'})"
)
return f"state={self.state} | " + " | ".join(axes)
def to_colored_string(self) -> str:
# ANSI colors for terminal use
RESET = "\033[0m"
BOLD = "\033[1m"
CYAN = "\033[36m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
RED = "\033[31m"
def color_bool(value: bool) -> str:
return f"{GREEN}True{RESET}" if value else f"{RED}False{RESET}"
def axis_line(name: str, axis: AerotechAxisStatus | None) -> str:
if axis is None:
return f"{YELLOW}{name.upper()}: unavailable{RESET}"
return (
f"{BOLD}{name.upper()}{RESET} | "
f"pos={CYAN}{axis.position:>12.6f}{RESET} | "
f"homed={color_bool(axis.homed)} | "
f"moving={color_bool(axis.moving)} | "
f"enabled={color_bool(axis.enabled)} | "
f"fault={axis.fault} | "
f"faulted={color_bool(axis.is_fault)} | "
f"vel={axis.velocity:>10.6f}"
)
return "\n".join(
[
f"{BOLD}STATE:{RESET} {CYAN}{self.state}{RESET}",
axis_line("x", self.x),
axis_line("y", self.y),
axis_line("z", self.z),
axis_line("u", self.u),
]
)
class AerotechTarget(BaseModel):
x: float | None = None
y: float | None = None
z: float | None = None
u: float | None = None
def to_payload(self) -> dict:
return self.model_dump(exclude_none=True)
class AerotechRotationScanRequest(RotationScanRequest):
rotation_deg: float
time_sec: float
start_pos_deg: float
async_move: bool = Field(default=False, alias="async")
model_config = ConfigDict(populate_by_name=True)
def to_payload(self) -> dict:
return self.model_dump(by_alias=True, exclude_none=True)