better location? lets see it fail!
This commit is contained in:
parent
0b8b2cad67
commit
88d9051f1c
1 changed files with 59 additions and 4 deletions
|
@ -24,7 +24,8 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from threading import local as LocalContext
|
from threading import local as LocalContext
|
||||||
|
|
||||||
LocatorPeerIdentifier: TypeAlias = MacAddress | tuple[UUID, Annotated[NonNegativeInt, Lt(2 ** 16)], Annotated[NonNegativeInt, Lt(2 ** 16)]]
|
LocatorPeerIdentifier: TypeAlias = MacAddress | str | tuple[
|
||||||
|
UUID, Annotated[NonNegativeInt, Lt(2 ** 16)], Annotated[NonNegativeInt, Lt(2 ** 16)]]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -32,6 +33,7 @@ class LocatorPeer:
|
||||||
identifier: LocatorPeerIdentifier
|
identifier: LocatorPeerIdentifier
|
||||||
frequencies: set[int] = field(default_factory=set)
|
frequencies: set[int] = field(default_factory=set)
|
||||||
xyz: Optional[tuple[int, int, int]] = None
|
xyz: Optional[tuple[int, int, int]] = None
|
||||||
|
space_id: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -91,6 +93,7 @@ class Locator:
|
||||||
int(beacon.geometry.y * 100),
|
int(beacon.geometry.y * 100),
|
||||||
int((router.altitude_for_point(beacon.space_id, beacon.geometry) + float(beacon.altitude)) * 100),
|
int((router.altitude_for_point(beacon.space_id, beacon.geometry) + float(beacon.altitude)) * 100),
|
||||||
)
|
)
|
||||||
|
self.peers[peer_id].space_id = beacon.space_id
|
||||||
self.xyz = np.array(tuple(peer.xyz for peer in self.peers))
|
self.xyz = np.array(tuple(peer.xyz for peer in self.peers))
|
||||||
|
|
||||||
for space in Space.objects.prefetch_related('beacon_measurements'):
|
for space in Space.objects.prefetch_related('beacon_measurements'):
|
||||||
|
@ -122,8 +125,11 @@ class Locator:
|
||||||
for scan_value in scan_data:
|
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
|
continue
|
||||||
peer_id = self.get_peer_id(scan_value.bssid, create=create_peers)
|
peer_ids = {
|
||||||
if peer_id is not None:
|
self.get_peer_id(scan_value.bssid, create=create_peers),
|
||||||
|
self.get_peer_id(scan_value.ap_name, create=create_peers),
|
||||||
|
} - {None, ""}
|
||||||
|
for peer_id in peer_ids:
|
||||||
result[peer_id] = ScanDataValue(rssi=scan_value.rssi, distance=scan_value.distance)
|
result[peer_id] = ScanDataValue(rssi=scan_value.rssi, distance=scan_value.distance)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -201,8 +207,54 @@ class Locator:
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
result = self.locate_by_beacon_positions(scan_data, permissions)
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
|
||||||
return self.locate_rssi(scan_data, permissions)
|
return self.locate_rssi(scan_data, permissions)
|
||||||
|
|
||||||
|
def locate_by_beacon_positions(self, scan_data: ScanData, permissions=None):
|
||||||
|
scan_data_we_can_use = [
|
||||||
|
(peer_id, value) for peer_id, value in scan_data.items() if self.peers[peer_id].space_id
|
||||||
|
]
|
||||||
|
|
||||||
|
if not scan_data_we_can_use:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# get visible spaces
|
||||||
|
best_ap_id = min(scan_data_we_can_use, key=lambda item: item[1].rssi)[0]
|
||||||
|
space_id = self.peers[best_ap_id].space_id
|
||||||
|
space = self.spaces[space_id]
|
||||||
|
|
||||||
|
scan_data_in_the_same_room = sorted([
|
||||||
|
(peer_id, value) for peer_id, value in scan_data_we_can_use if self.peers[peer_id].space_id == space_id
|
||||||
|
], key=lambda a: a[1].rssi)
|
||||||
|
|
||||||
|
if len(scan_data_in_the_same_room) == 1:
|
||||||
|
point = space.point
|
||||||
|
return CustomLocation(
|
||||||
|
level=space.level_id,
|
||||||
|
x=point.x,
|
||||||
|
y=point.y,
|
||||||
|
permissions=permissions,
|
||||||
|
icon='my_location'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
the_sum = sum(a[1].rssi for a in scan_data_in_the_same_room[:3])
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
for peer_id, value in scan_data_in_the_same_room[:3]:
|
||||||
|
x = self.peers[peer_id].xyz[0] * value.rssi / the_sum
|
||||||
|
y = self.peers[peer_id].xyz[1] * value.rssi / the_sum
|
||||||
|
return CustomLocation(
|
||||||
|
level=space.level_id,
|
||||||
|
x=x,
|
||||||
|
y=y,
|
||||||
|
permissions=permissions,
|
||||||
|
icon='my_location'
|
||||||
|
)
|
||||||
|
|
||||||
def locate_rssi(self, scan_data: ScanData, permissions=None):
|
def locate_rssi(self, scan_data: ScanData, permissions=None):
|
||||||
router = Router.load()
|
router = Router.load()
|
||||||
restrictions = router.get_restrictions(permissions)
|
restrictions = router.get_restrictions(permissions)
|
||||||
|
@ -227,6 +279,9 @@ class Locator:
|
||||||
if best_location is not None:
|
if best_location is not None:
|
||||||
best_location.score = best_score
|
best_location.score = best_score
|
||||||
|
|
||||||
|
if best_location is not None:
|
||||||
|
return None
|
||||||
|
|
||||||
return best_location
|
return best_location
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
@ -312,7 +367,7 @@ class Locator:
|
||||||
)],
|
)],
|
||||||
x=result_pos[0]/100,
|
x=result_pos[0]/100,
|
||||||
y=result_pos[1]/100,
|
y=result_pos[1]/100,
|
||||||
permissions=(),
|
permissions=permissions,
|
||||||
icon='my_location'
|
icon='my_location'
|
||||||
)
|
)
|
||||||
location.z = result_pos[2]/100
|
location.z = result_pos[2]/100
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue