use shcmea for beaconmeasurement data and fix some related things

This commit is contained in:
Laura Klünder 2024-12-23 16:26:15 +01:00
parent b45fd961c0
commit 8feac6bf43
6 changed files with 67 additions and 44 deletions

View file

@ -12,16 +12,16 @@ from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.schemas.models import CustomLocationSchema
from c3nav.mapdata.utils.cache.stats import increment_cache_key
from c3nav.routing.locator import Locator
from c3nav.routing.schemas import LocateRequestWifiPeerSchema, LocateRequestIBeaconPeerSchema
from c3nav.routing.schemas import LocateWifiPeerSchema, LocateIBeaconPeerSchema
positioning_api_router = APIRouter(tags=["positioning"])
class LocateRequestSchema(BaseSchema):
wifi_peers: list[LocateRequestWifiPeerSchema] = APIField(
wifi_peers: list[LocateWifiPeerSchema] = APIField(
title="list of visible/measured wifi location beacons",
)
ibeacon_peers: list[LocateRequestIBeaconPeerSchema] = APIField(
ibeacon_peers: list[LocateIBeaconPeerSchema] = APIField(
title="list of visible/measured location iBeacons",
)

View file

@ -17,7 +17,7 @@ from c3nav.mapdata.models import MapUpdate, Space
from c3nav.mapdata.utils.locations import CustomLocation
from c3nav.mesh.utils import get_nodes_and_ranging_beacons
from c3nav.routing.router import Router
from c3nav.routing.schemas import LocateRequestWifiPeerSchema
from c3nav.routing.schemas import LocateWifiPeerSchema, BeaconMeasurementDataSchema, LocateIBeaconPeerSchema
try:
from asgiref.local import Local as LocalContext
@ -117,33 +117,33 @@ class Locator:
self.peers.append(peer)
return peer_id
def convert_wifi_scan(self, scan_data, create_peers=False) -> ScanData:
def convert_wifi_scan(self, scan_data: list[LocateWifiPeerSchema], create_peers=False) -> ScanData:
result = {}
for scan_value in scan_data:
if settings.WIFI_SSIDS and scan_value['ssid'] not in settings.WIFI_SSIDS:
if settings.WIFI_SSIDS and scan_value.ssid not in settings.WIFI_SSIDS:
continue
peer_id = self.get_peer_id(scan_value['bssid'], create=create_peers)
peer_id = self.get_peer_id(scan_value.bssid, create=create_peers)
if peer_id is not None:
result[peer_id] = ScanDataValue(rssi=scan_value["rssi"], distance=scan_value.get("distance", None))
result[peer_id] = ScanDataValue(rssi=scan_value.rssi, distance=scan_value.get("distance", None))
return result
def convert_ibeacon_scan(self, scan_data, create_peers=False) -> ScanData:
def convert_ibeacon_scan(self, scan_data: list[LocateIBeaconPeerSchema], create_peers=False) -> ScanData:
result = {}
for scan_value in scan_data:
peer_id = self.get_peer_id(
(scan_value['uuid'], scan_value['major'], scan_value['minor']),
(scan_value.uuid, scan_value.major, scan_value.minor),
create=create_peers
)
if peer_id is not None:
result[peer_id] = ScanDataValue(ibeacon_range=scan_value["distance"])
result[peer_id] = ScanDataValue(ibeacon_range=scan_value.distance)
return result
def convert_scans(self, scans_data, create_peers=False) -> ScanData:
def convert_scans(self, scans_data: BeaconMeasurementDataSchema, create_peers=False) -> ScanData:
converted = []
for scan in scans_data.get("wifi", []):
for scan in scans_data.wifi:
converted.append(self.convert_wifi_scan(scan, create_peers=create_peers))
for scan in scans_data.get("ibeacon", []):
for scan in scans_data.ibeacon:
converted.append(self.convert_ibeacon_scan(scan, create_peers=create_peers))
peer_ids = reduce(operator.or_, (frozenset(values.keys()) for values in converted), frozenset())
@ -176,7 +176,7 @@ class Locator:
cls.cached.data = cls.load_nocache(update)
return cls.cached.data
def convert_raw_scan_data(self, raw_scan_data: list[LocateRequestWifiPeerSchema]) -> ScanData:
def convert_raw_scan_data(self, raw_scan_data: list[LocateWifiPeerSchema]) -> ScanData:
return self.convert_wifi_scan(raw_scan_data, create_peers=False)
def get_xyz(self, identifier: LocatorPeerIdentifier) -> tuple[int, int, int] | None:
@ -191,7 +191,7 @@ class Locator:
if isinstance(peer.identifier, MacAddress)
}
def locate(self, raw_scan_data: list[LocateRequestWifiPeerSchema], permissions=None):
def locate(self, raw_scan_data: list[LocateWifiPeerSchema], permissions=None):
# todo: support for ibeacons
scan_data = self.convert_raw_scan_data(raw_scan_data)
if not scan_data:

View file

@ -10,7 +10,7 @@ from pydantic_extra_types.mac_address import MacAddress
from c3nav.api.schema import BaseSchema
class LocateRequestWifiPeerSchema(BaseSchema):
class LocateWifiPeerSchema(BaseSchema):
bssid: MacAddress = APIField(
title="BSSID",
description="BSSID of the peer",
@ -25,6 +25,7 @@ class LocateRequestWifiPeerSchema(BaseSchema):
title="RSSI",
description="RSSI in dBm",
example=-42,
validation_alias="level", # App version < 4.2.4 use level instead fo rssi
)
frequency: Union[
PositiveInt,
@ -64,7 +65,7 @@ class LocateRequestWifiPeerSchema(BaseSchema):
)
class LocateRequestIBeaconPeerSchema(BaseSchema):
class LocateIBeaconPeerSchema(BaseSchema):
uuid: UUID = APIField(
title="UUID",
description="UUID of the iBeacon",
@ -82,3 +83,8 @@ class LocateRequestIBeaconPeerSchema(BaseSchema):
last_seen_ago: NonNegativeInt = APIField(
title="how many milliseconds ago this beacon was last seen"
)
class BeaconMeasurementDataSchema(BaseSchema):
wifi: list[list[LocateWifiPeerSchema]] = []
ibeacon: list[list[LocateIBeaconPeerSchema]] = []