Initial commit: SIBU 2.0 MISSION
This commit is contained in:
84
backend/app/api/telemetry.py
Normal file
84
backend/app/api/telemetry.py
Normal file
@ -0,0 +1,84 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlmodel import Session, select
|
||||
from typing import List
|
||||
from datetime import datetime, timedelta
|
||||
from app.core.database import get_session
|
||||
from app.models.telemetry import Telemetry, TelemetryCreate, VehicleStatus
|
||||
from app.models.user import User
|
||||
from app.api.deps import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/api/telemetry", tags=["telemetry"])
|
||||
|
||||
@router.post("", response_model=Telemetry)
|
||||
async def create_telemetry_record(
|
||||
*,
|
||||
session: Session = Depends(get_session),
|
||||
telemetry_in: TelemetryCreate,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
Create a new telemetry record for the current driver.
|
||||
"""
|
||||
if current_user.role != "driver":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Only drivers can send telemetry data"
|
||||
)
|
||||
|
||||
db_telemetry = Telemetry(
|
||||
user_id=current_user.id,
|
||||
latitude=telemetry_in.latitude,
|
||||
longitude=telemetry_in.longitude,
|
||||
speed=telemetry_in.speed,
|
||||
heading=telemetry_in.heading,
|
||||
status=telemetry_in.status
|
||||
)
|
||||
|
||||
session.add(db_telemetry)
|
||||
session.commit()
|
||||
session.refresh(db_telemetry)
|
||||
return db_telemetry
|
||||
|
||||
@router.get("/active", response_model=List[dict])
|
||||
async def get_active_units(
|
||||
*,
|
||||
session: Session = Depends(get_session)
|
||||
):
|
||||
"""
|
||||
Get the latest location of all active units (last 5 minutes).
|
||||
"""
|
||||
# Subquery to get the latest timestamp per user
|
||||
five_minutes_ago = datetime.utcnow() - timedelta(minutes=5)
|
||||
|
||||
# This is a bit complex in SQLModel/SQLAlchemy for "latest record per group"
|
||||
# We'll use a simpler approach: get all records from last 5 mins and filter in python
|
||||
# or use a more efficient distinct on if supported.
|
||||
|
||||
statement = (
|
||||
select(Telemetry)
|
||||
.where(Telemetry.timestamp >= five_minutes_ago)
|
||||
.where(Telemetry.status == VehicleStatus.ACTIVE)
|
||||
.order_by(Telemetry.user_id, Telemetry.timestamp.desc())
|
||||
)
|
||||
|
||||
results = session.exec(statement).all()
|
||||
|
||||
# Filter to get only the latest unique user_id
|
||||
latest_units = {}
|
||||
for t in results:
|
||||
if t.user_id not in latest_units:
|
||||
# We also want the driver name and vehicle info
|
||||
user = session.get(User, t.user_id)
|
||||
latest_units[t.user_id] = {
|
||||
"user_id": t.user_id,
|
||||
"full_name": user.full_name if user else "Unknown",
|
||||
"latitude": t.latitude,
|
||||
"longitude": t.longitude,
|
||||
"speed": t.speed,
|
||||
"heading": t.heading,
|
||||
"timestamp": t.timestamp,
|
||||
"vehicle_type": user.driver_profile.vehicle_type if user and user.driver_profile else "unknown",
|
||||
"license_plate": user.driver_profile.license_plate if user and user.driver_profile else "unknown"
|
||||
}
|
||||
|
||||
return list(latest_units.values())
|
||||
Reference in New Issue
Block a user