68 lines
1.7 KiB
Python
68 lines
1.7 KiB
Python
"""REST endpoints backing the 3D motor-temperature dashboard (N1).
|
|
|
|
Serves the motor name/mesh mapping + thresholds, and a one-shot temperature
|
|
snapshot (the front-end's initial fetch fallback). The live stream is over
|
|
/ws/motor-temps (dashboard/websockets/motor_temps.py). The 3D view itself is
|
|
the static page at /static/temp3d/index.html.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from Project.Sanad.dashboard.temp_motor_map import (
|
|
MOTOR_NAMES,
|
|
MOTOR_TO_MESH,
|
|
TEMP_HOT_THRESHOLD,
|
|
TEMP_MAX,
|
|
TEMP_MIN,
|
|
TEMP_WARM_THRESHOLD,
|
|
build_payload,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _get_arm():
|
|
"""Lazy import — avoids a circular import on dashboard load."""
|
|
try:
|
|
from Project.Sanad.main import arm # type: ignore
|
|
return arm
|
|
except Exception:
|
|
return None
|
|
|
|
|
|
@router.get("/mapping")
|
|
async def motor_mapping():
|
|
"""Motor id → name / mesh map + the temperature gradient thresholds."""
|
|
return {
|
|
"motor_names": MOTOR_NAMES,
|
|
"motor_to_mesh": MOTOR_TO_MESH,
|
|
"thresholds": {
|
|
"min": TEMP_MIN,
|
|
"max": TEMP_MAX,
|
|
"warm": TEMP_WARM_THRESHOLD,
|
|
"hot": TEMP_HOT_THRESHOLD,
|
|
},
|
|
}
|
|
|
|
|
|
@router.get("/motors")
|
|
async def motors_snapshot():
|
|
"""One-shot motor temperature + position snapshot (Marcus payload shape)."""
|
|
arm = _get_arm()
|
|
temps: list = []
|
|
positions: list = []
|
|
if arm is not None:
|
|
try:
|
|
temps = arm.get_motor_temps()
|
|
except Exception:
|
|
temps = []
|
|
try:
|
|
positions = arm.get_current_q()
|
|
except Exception:
|
|
positions = []
|
|
return build_payload(temps, positions, time.time())
|