store multiple wifi bssids per beacon

This commit is contained in:
Laura Klünder 2024-12-26 22:17:27 +01:00
parent b27aed1343
commit 7c7b73f488
7 changed files with 17 additions and 20 deletions

View file

@ -170,8 +170,8 @@ def beacons_lookup(request):
"name": node.name if node else ("Beacon #%d" % beacon.pk),
"point": mapping(beacon.geometry),
}
if beacon.wifi_bssid:
wifi_beacons[beacon.wifi_bssid] = beacon_data
for bssid in beacon.wifi_bssids:
wifi_beacons[bssid] = beacon_data
if beacon.ibeacon_uuid and beacon.ibeacon_major is not None and beacon.ibeacon_minor is not None:
ibeacons.setdefault(
str(beacon.ibeacon_uuid), {}

View file

@ -382,7 +382,7 @@ def create_editor_form(editor_model):
'base_altitude', 'intermediate', 'waytype', 'access_restriction', 'default_height', 'door_height', 'outside',
"identifyable", 'can_search', 'can_describe', 'geometry', 'single', 'altitude', 'level_index', 'short_label',
'origin_space', 'target_space', 'data',
'comment', 'slow_down_factor', 'groundaltitude', 'node_number', 'wifi_bssid', 'bluetooth_address', "group",
'comment', 'slow_down_factor', 'groundaltitude', 'node_number', 'wifi_bssids', 'bluetooth_address', "group",
'ibeacon_uuid', 'ibeacon_major', 'ibeacon_minor', 'uwb_address', 'extra_seconds', 'speed', 'can_report_missing',
"can_report_mistake", 'description', 'speed_up', 'description_up', 'avoid_by_default', 'report_help_text',
'enter_description', 'level_change_description', 'base_mapdata_accessible', 'label_settings', 'label_override',

View file

@ -1,3 +1,5 @@
from itertools import chain
import numpy as np
from django.core.management.base import BaseCommand
@ -17,7 +19,7 @@ class Command(BaseCommand):
found_beacons.setdefault(measurement["bssid"], []).append((beacon_measurement, measurement))
# put in the ones we know
known = {r.wifi_bssid: r for r in RangingBeacon.objects.all()}
known = dict(chain(*(((bssid, r) for bssid in r.wifi_bssids) for r in RangingBeacon.objects.all())))
# lets go through them
for bssid, measurements in found_beacons.items():

View file

@ -10,6 +10,7 @@ from django.utils.functional import cached_property
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from django_pydantic_field.fields import SchemaField
from pydantic_extra_types.mac_address import MacAddress
from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
from c3nav.mapdata.fields import GeometryField, I18nField
@ -468,13 +469,7 @@ class RangingBeacon(SpaceGeometryMixin, models.Model):
node_number = models.PositiveSmallIntegerField(_('Node Number'), unique=True, null=True, blank=True)
wifi_bssid = models.CharField(_('WiFi BSSID'), unique=True, null=True, blank=True,
max_length=17,
validators=[RegexValidator(
regex='^([a-f0-9]{2}:){5}[a-f0-9]{2}$',
message='Must be a lower-case bssid',
code='invalid_bssid'
)],
wifi_bssids: list[MacAddress] = SchemaField(list[MacAddress], verbose_name=_('WiFi BSSIDs'), default=list,
help_text=_("uses node's value if not set"))
bluetooth_address = models.CharField(_('Bluetooth Address'), unique=True, null=True, blank=True,
max_length=17,
@ -520,10 +515,10 @@ class RangingBeacon(SpaceGeometryMixin, models.Model):
@property
def title(self):
if self.node_number is not None or self.wifi_bssid is not None:
if self.node_number is not None or self.wifi_bssids:
if self.comment:
return f'{self.node_number or ''} {self.wifi_bssid or ''} ({self.comment})'.strip()
return f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])} ({self.comment})'.strip()
else:
return f'{self.node_number or ''} {self.wifi_bssid or ''}'.strip()
return f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])}'.strip()
else:
return self.comment

View file

@ -272,7 +272,7 @@ def mesh_map(request, level_id: int):
"geometry": mapping(beacon.geometry),
"properties": {
"node_number": beacon.node_number,
"wifi_bssid": beacon.wifi_bssid,
"wifi_bssid": (beacon.wifi_bssids + [None])[0],
"comment": beacon.comment,
"mesh_node": None if node is None else {
"address": node.address,

View file

@ -60,8 +60,8 @@ def get_nodes_and_ranging_beacons():
ranging_beacon = beacons[ranging_beacon_id]
ranging_beacon.save = None
if not ranging_beacon.wifi_bssid:
ranging_beacon.wifi_bssid = node.address
if not ranging_beacon.wifi_bssids:
ranging_beacon.wifi_bssids = [node.address]
if not ranging_beacon.bluetooth_address:
ranging_beacon.bluetooth_address = node.address[:-2] + hex(int(node.address[-2:], 16)+1)[2:]

View file

@ -80,8 +80,8 @@ class Locator:
calculated = get_nodes_and_ranging_beacons()
for beacon in calculated.beacons.values():
identifiers = []
if beacon.wifi_bssid:
identifiers.append(beacon.wifi_bssid)
for bssid in beacon.wifi_bssids:
identifiers.append(bssid)
if beacon.ibeacon_uuid and beacon.ibeacon_major is not None and beacon.ibeacon_minor is not None:
identifiers.append((beacon.ibeacon_uuid, beacon.ibeacon_major, beacon.ibeacon_minor))
for identifier in identifiers: