introduce ap_name and implement bssid_from_scans_to_beacons
This commit is contained in:
parent
f7bf30bd7e
commit
da4cc419ca
5 changed files with 74 additions and 8 deletions
|
@ -384,7 +384,7 @@ def create_editor_form(editor_model):
|
|||
'ordering', 'category', 'width', 'groups', 'height', 'color', 'in_legend', 'priority', 'hierarchy', 'icon_name',
|
||||
'base_altitude', 'intermediate', 'waytype', 'access_restriction', 'edit_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',
|
||||
'level_index', 'short_label', 'origin_space', 'target_space', 'data', "ap_name", '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',
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
from django.db import transaction
|
||||
|
||||
from c3nav.mapdata.models.geometry.space import BeaconMeasurement
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'collect BSSIDS for AP names from measurements'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
with transaction.atomic():
|
||||
BeaconMeasurement.contribute_bssid_to_beacons(BeaconMeasurement.objects.all())
|
36
src/c3nav/mapdata/migrations/0134_rangingbeacon_ap_name.py
Normal file
36
src/c3nav/mapdata/migrations/0134_rangingbeacon_ap_name.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Generated by Django 5.0.8 on 2024-12-27 20:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def fill_ap_name(apps, schema_editor):
|
||||
RangingBeacon = apps.get_model('mapdata', 'rangingbeacon')
|
||||
for ranging_beacon in RangingBeacon.objects.filter(import_tag__startswith='noc:'):
|
||||
ranging_beacon.ap_name = ranging_beacon.import_tag[4:]
|
||||
if ranging_beacon.comment == ranging_beacon.import_tag[4:]:
|
||||
ranging_beacon.comment = None
|
||||
ranging_beacon.save()
|
||||
|
||||
|
||||
def unfill_ap_name(apps, schema_editor):
|
||||
RangingBeacon = apps.get_model('mapdata', 'rangingbeacon')
|
||||
for ranging_beacon in RangingBeacon.objects.filter(ap_name__isnull=False, import_tag__startswith='noc:'):
|
||||
if ranging_beacon.ap_name == ranging_beacon.import_tag[4:]:
|
||||
ranging_beacon.comment = ' '.join(((ranging_beacon.comment or ''), ranging_beacon.ap_name)).strip()
|
||||
ranging_beacon.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mapdata', '0133_beaconmeasurement_fill_quest'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rangingbeacon',
|
||||
name='ap_name',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='AP name'),
|
||||
),
|
||||
migrations.RunPython(fill_ap_name, unfill_ap_name),
|
||||
]
|
|
@ -444,7 +444,7 @@ class BeaconMeasurement(SpaceGeometryMixin, models.Model):
|
|||
verbose_name=_('author'))
|
||||
comment = models.TextField(null=True, blank=True, verbose_name=_('comment'))
|
||||
data: BeaconMeasurementDataSchema = SchemaField(BeaconMeasurementDataSchema,
|
||||
verbose_name=_('Measurement list'),
|
||||
verbose_name=_('Measurement list'),
|
||||
default=BeaconMeasurementDataSchema())
|
||||
|
||||
fill_quest = models.BooleanField(_('create a quest to fill this'), default=False)
|
||||
|
@ -462,6 +462,22 @@ class BeaconMeasurement(SpaceGeometryMixin, models.Model):
|
|||
def geometry_changed(self):
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def contribute_bssid_to_beacons(items: list["BeaconMeasurement"]):
|
||||
map_name = {}
|
||||
for item in items:
|
||||
for scan in item.data.wifi:
|
||||
for peer in scan:
|
||||
if peer.ap_name:
|
||||
map_name.setdefault(peer.ap_name, []).append(peer.bssid)
|
||||
for beacon in RangingBeacon.objects.filter(ap_name__in=map_name.keys()):
|
||||
beacon.wifi_bssids = list(set(beacon.wifi_bssids) | set(map_name[beacon.ap_name]))
|
||||
beacon.save()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.contribute_bssid_to_beacons([self])
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class RangingBeacon(SpaceGeometryMixin, models.Model):
|
||||
"""
|
||||
|
@ -498,6 +514,7 @@ class RangingBeacon(SpaceGeometryMixin, models.Model):
|
|||
|
||||
altitude = models.DecimalField(_('altitude above ground'), max_digits=6, decimal_places=2, default=0,
|
||||
validators=[MinValueValidator(Decimal('0'))])
|
||||
ap_name = models.TextField(null=True, blank=True, verbose_name=_('AP name'))
|
||||
comment = models.TextField(null=True, blank=True, verbose_name=_('comment'))
|
||||
|
||||
altitude_quest = models.BooleanField(_('altitude quest'), default=True)
|
||||
|
@ -517,10 +534,11 @@ class RangingBeacon(SpaceGeometryMixin, models.Model):
|
|||
|
||||
@property
|
||||
def title(self):
|
||||
if self.node_number is not None or self.wifi_bssids:
|
||||
if self.node_number is not None or self.wifi_bssids or self.ap_name:
|
||||
if self.comment:
|
||||
return f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])} ({self.comment})'.strip()
|
||||
return (f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])} {self.ap_name or ''} '
|
||||
f' ({self.comment})').strip()
|
||||
else:
|
||||
return f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])}'.strip()
|
||||
return f'{self.node_number or ''} {''.join(self.wifi_bssids[:1])} {self.ap_name or ''}'.strip()
|
||||
else:
|
||||
return self.comment
|
||||
|
|
|
@ -91,8 +91,8 @@ class RangingBeaconBSSIDsQuest(Quest):
|
|||
def quest_description(self) -> list[str]:
|
||||
return [
|
||||
_("This quest only works in the app. It works fully automatically."),
|
||||
_("We are trying to find the BSSIDs broadcast by “%s”.") % self.obj.title,
|
||||
_("Please stand near “%s” and wait for the submit button to appear.") % self.obj.title,
|
||||
_("We are trying to find the BSSIDs broadcast by “%s”.") % self.obj.ap_name,
|
||||
_("Please stand near “%s” and wait for the submit button to appear.") % self.obj.ap_name,
|
||||
_("Do not close this popup until then."),
|
||||
_("This should happen within less than a minute."),
|
||||
]
|
||||
|
@ -103,7 +103,7 @@ class RangingBeaconBSSIDsQuest(Quest):
|
|||
|
||||
@classmethod
|
||||
def _qs_for_request(cls, request):
|
||||
return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", wifi_bssids=[])
|
||||
return RangingBeacon.qs_for_request(request).filter(ap_name__isnull=False, wifi_bssids=[])
|
||||
|
||||
|
||||
class BeaconMeasurementQuestForm(ChangeSetModelForm):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue