Ekaropolus a271b43318
All checks were successful
continuous-integration/drone/push Build is passing
Simulation MVP and Waste management
2026-01-03 03:10:53 -06:00

97 lines
3.1 KiB
Python

from __future__ import annotations
from django.shortcuts import render
from django.conf import settings
from rest_framework.decorators import api_view, throttle_classes
from rest_framework.response import Response
from rest_framework import status
from .services.sim_engine import create_run, get_run
from .services.waste_sim import build_waste_cesium_payload
CESIUM_ION_FALLBACK = (
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
"eyJqdGkiOiJkZmM5ZmE1MS0yNWFlLTQ1YjEtOGZiNy1lMmFlOGYyYTI0MjYiLCJpZCI6Mzc0NDg3LCJpYXQiOjE3Njc0MTAxNzN9."
"tFBLet8CEmvfCivzZM5ExfHL752iPQIShw6Pqa49Gkw"
)
CESIUM_ION_TOKEN = getattr(settings, "CESIUM_ION_TOKEN", "") or CESIUM_ION_FALLBACK
def simulation_mvp(request):
return render(request, "pxy_simulations/simulation_mvp.html", {"ion_token": CESIUM_ION_TOKEN})
def _err(code: str, message: str, http_status: int = 400):
return Response({"ok": False, "code": code, "message": message}, status=http_status)
def simulation_waste_cesium(request, subdivision, vehicle):
context = {
"subdivision": subdivision,
"vehicle": vehicle,
"ion_token": CESIUM_ION_TOKEN,
}
return render(request, "pxy_simulations/waste_cesium.html", context)
@api_view(["GET"])
@throttle_classes([])
def simulations_health(request):
return Response({"ok": True, "service": "simulations"})
@api_view(["POST"])
@throttle_classes([])
def simulations_new(request):
run = create_run(request.data or {})
return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=True)})
@api_view(["POST"])
@throttle_classes([])
def simulations_step(request):
payload = request.data or {}
run_id = (payload.get("run_id") or "").strip()
if not run_id:
return _err("missing_run_id", "run_id is required")
run = get_run(run_id)
if run is None:
return _err("not_found", "run not found", http_status=status.HTTP_404_NOT_FOUND)
try:
steps = int(payload.get("steps", 1))
except (TypeError, ValueError):
steps = 1
steps = max(1, min(steps, 200))
run.step(steps=steps)
return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=False)})
@api_view(["GET"])
@throttle_classes([])
def simulations_state(request):
run_id = (request.query_params.get("run_id") or "").strip()
if not run_id:
return _err("missing_run_id", "run_id is required")
run = get_run(run_id)
if run is None:
return _err("not_found", "run not found", http_status=status.HTTP_404_NOT_FOUND)
return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=False)})
@api_view(["GET"])
@throttle_classes([])
def simulations_waste_cesium_data(request, subdivision, vehicle):
try:
payload = build_waste_cesium_payload(subdivision, vehicle, request.query_params.dict())
except ValueError as exc:
return _err("not_found", str(exc), http_status=status.HTTP_404_NOT_FOUND)
except Exception as exc:
return _err("error", str(exc), http_status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response({"ok": True, **payload})