File size: 1,585 Bytes
2edb151 676f5d4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | from __future__ import annotations
from pathlib import Path
import httpx
from app.config import Settings
class CameraError(RuntimeError):
pass
def snapshot(settings: Settings, *, client: httpx.Client | None = None) -> Path:
"""HAL snapshot used by Autonomous Lamp. Returns the saved JPEG path."""
url = (
f"{settings.camera_url.rstrip('/')}/camera/snapshot"
f"?save=true&width={settings.snapshot_width}&quality={settings.snapshot_quality}"
)
own = client is None
http = client or httpx.Client(timeout=30.0)
try:
response = http.get(url)
response.raise_for_status()
payload = response.json()
except httpx.HTTPError as exc:
raise CameraError(f"Lamp camera snapshot failed: {exc}") from exc
finally:
if own:
http.close()
path = payload.get("path") if isinstance(payload, dict) else None
if not path:
raise CameraError(f"snapshot JSON missing path: {payload!r}")
return Path(path)
def aim(settings: Settings, direction: str = "down", *, client: httpx.Client | None = None) -> None:
"""HAL servo aim. Call before snapshot when the paper is on the desk."""
url = f"{settings.camera_url.rstrip('/')}/servo/aim"
own = client is None
http = client or httpx.Client(timeout=15.0)
try:
response = http.post(url, json={"direction": direction})
response.raise_for_status()
except httpx.HTTPError as exc:
raise CameraError(f"Lamp servo aim failed: {exc}") from exc
finally:
if own:
http.close()
|