2023-12-02 00:00:23 +01:00
|
|
|
from typing import Annotated, Optional
|
2023-11-27 22:59:59 +01:00
|
|
|
|
|
|
|
from ninja import Field as APIField
|
2023-12-03 16:37:05 +01:00
|
|
|
from ninja import Router as APIRouter
|
|
|
|
from ninja import Schema
|
2023-12-02 00:00:23 +01:00
|
|
|
from pydantic import NegativeInt
|
2023-11-24 16:15:19 +01:00
|
|
|
|
|
|
|
from c3nav.api.newauth import auth_responses
|
2023-12-02 00:00:23 +01:00
|
|
|
from c3nav.api.utils import NonEmptyStr
|
2023-11-24 16:15:19 +01:00
|
|
|
from c3nav.mapdata.models import Source
|
2023-12-02 00:00:23 +01:00
|
|
|
from c3nav.mapdata.schemas.models import CustomLocationSchema
|
2023-11-24 16:15:19 +01:00
|
|
|
from c3nav.mapdata.schemas.responses import BoundsSchema
|
2023-11-27 22:59:59 +01:00
|
|
|
from c3nav.routing.rangelocator import RangeLocator
|
2023-11-24 16:15:19 +01:00
|
|
|
|
2023-12-02 00:00:23 +01:00
|
|
|
BSSIDSchema = Annotated[str, APIField(pattern=r"^[a-z0-9]{2}(:[a-z0-9]{2}){5}$", title="BSSID")]
|
|
|
|
|
2023-11-24 16:15:19 +01:00
|
|
|
positioning_api_router = APIRouter(tags=["positioning"])
|
|
|
|
|
|
|
|
|
2023-12-02 00:00:23 +01:00
|
|
|
class LocateRequestItemSchema(Schema):
|
|
|
|
ssid: NonEmptyStr
|
|
|
|
bssid: BSSIDSchema
|
|
|
|
rssi: NegativeInt
|
|
|
|
distance: Optional[float] = None
|
|
|
|
|
|
|
|
|
|
|
|
class LocateRequestSchema(Schema):
|
|
|
|
items: list[LocateRequestItemSchema]
|
|
|
|
|
|
|
|
|
|
|
|
class PositioningResult(Schema):
|
|
|
|
location: Optional[CustomLocationSchema]
|
|
|
|
|
|
|
|
|
2023-11-24 16:15:19 +01:00
|
|
|
@positioning_api_router.post('/locate/', summary="locate based on wifi scans",
|
2023-12-02 00:00:23 +01:00
|
|
|
response={200: PositioningResult, **auth_responses})
|
|
|
|
def locate(locate_data: LocateRequestSchema):
|
2023-11-24 16:15:19 +01:00
|
|
|
# todo: implement
|
2023-12-02 00:00:23 +01:00
|
|
|
raise NotImplementedError
|
2023-11-24 16:15:19 +01:00
|
|
|
|
2023-11-26 17:55:23 +01:00
|
|
|
|
2023-11-24 16:15:19 +01:00
|
|
|
@positioning_api_router.get('/locate-test/', summary="get dummy location for debugging",
|
2023-12-02 00:00:23 +01:00
|
|
|
response={200: PositioningResult, **auth_responses})
|
2023-11-30 22:02:40 +01:00
|
|
|
def locate_test():
|
2023-12-02 00:00:23 +01:00
|
|
|
raise NotImplementedError
|
2023-11-27 22:59:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
BeaconsXYZ = dict[
|
2023-12-02 00:00:23 +01:00
|
|
|
BSSIDSchema,
|
2023-11-27 22:59:59 +01:00
|
|
|
Annotated[
|
|
|
|
tuple[
|
|
|
|
Annotated[int, APIField(title="X (in cm)")],
|
|
|
|
Annotated[int, APIField(title="Y (in cm)")],
|
|
|
|
Annotated[int, APIField(title="Z (in cm)")],
|
|
|
|
],
|
|
|
|
APIField(title="global XYZ coordinates")
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
@positioning_api_router.get('/beacons-xyz/', summary="get calculated x y z for all beacons",
|
|
|
|
response={200: BeaconsXYZ, **auth_responses})
|
2023-11-30 22:02:40 +01:00
|
|
|
def beacons_xyz():
|
2023-11-27 22:59:59 +01:00
|
|
|
return RangeLocator.load().get_all_xyz()
|