finalize quest for finding ranging beacon bssids

This commit is contained in:
Laura Klünder 2024-12-27 01:14:52 +01:00
parent e177554c5c
commit 0db0ae5cd6
4 changed files with 96 additions and 11 deletions

View file

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-26 22:26+0100\n" "POT-Creation-Date: 2024-12-27 01:14+0100\n"
"PO-Revision-Date: 2024-12-26 22:25+0100\n" "PO-Revision-Date: 2024-12-27 01:14+0100\n"
"Last-Translator: Laura Klünder <laura@codingcatgirl.de>\n" "Last-Translator: Laura Klünder <laura@codingcatgirl.de>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
@ -2137,10 +2137,8 @@ msgid "Node Number"
msgstr "Node Nummer" msgstr "Node Nummer"
#: c3nav/mapdata/models/geometry/space.py #: c3nav/mapdata/models/geometry/space.py
#, fuzzy
#| msgid "WiFi BSSID"
msgid "WiFi BSSIDs" msgid "WiFi BSSIDs"
msgstr "WLAN BSSID" msgstr "WLAN BSSIDs"
#: c3nav/mapdata/models/geometry/space.py #: c3nav/mapdata/models/geometry/space.py
msgid "uses node's value if not set" msgid "uses node's value if not set"
@ -2643,8 +2641,8 @@ msgid "default fill color"
msgstr "Standardfüllfarbe" msgstr "Standardfüllfarbe"
#: c3nav/mapdata/models/overlay.py #: c3nav/mapdata/models/overlay.py
msgid "fill opacity" msgid "default fill opacity"
msgstr "Füllopacity" msgstr "Standard-Füllopacity"
#: c3nav/mapdata/models/overlay.py #: c3nav/mapdata/models/overlay.py
msgid "cluster points together when zoomed out" msgid "cluster points together when zoomed out"
@ -2666,6 +2664,18 @@ msgstr "Header für pull http request (JSON objekt)"
msgid "pull interval" msgid "pull interval"
msgstr "Pullintervall" msgstr "Pullintervall"
#: c3nav/mapdata/models/overlay.py
msgid "frontend update interval"
msgstr "Frontend Updateintervall"
#: c3nav/mapdata/models/overlay.py
msgid "in seconds"
msgstr "in Sekunden"
#: c3nav/mapdata/models/overlay.py
msgid "Editor Access Restriction"
msgstr "Editor Zugangs­beschränkung"
#: c3nav/mapdata/models/overlay.py #: c3nav/mapdata/models/overlay.py
msgid "Data Overlay" msgid "Data Overlay"
msgstr "Datenoverlay" msgstr "Datenoverlay"
@ -2686,6 +2696,10 @@ msgstr "randdicke"
msgid "fill color" msgid "fill color"
msgstr "Füllfarbe" msgstr "Füllfarbe"
#: c3nav/mapdata/models/overlay.py
msgid "fill opacity"
msgstr "Füllopacity"
#: c3nav/mapdata/models/overlay.py #: c3nav/mapdata/models/overlay.py
msgid "show label" msgid "show label"
msgstr "Label anzeigen" msgstr "Label anzeigen"
@ -2973,6 +2987,33 @@ msgstr "Der AP sollte sich nicht 0m über dem Boden befinden."
msgid "Ranging Beacon Altitude" msgid "Ranging Beacon Altitude"
msgstr "Höhe des Ranging Beacons" msgstr "Höhe des Ranging Beacons"
#: c3nav/mapdata/quests/positioning.py
msgid "Need at least one bssid."
msgstr "Mindestens eine BSSID wird benötigt."
#: c3nav/mapdata/quests/positioning.py
msgid "Ranging Beacon Identifier"
msgstr "Ranging Beacons Indentifizierung"
#: c3nav/mapdata/quests/positioning.py
msgid "This quest only works in the app. It works fully automatically."
msgstr ""
"Dieser Quest funktioniert nur in der App. Er funktioniert vollautomatisch."
#: c3nav/mapdata/quests/positioning.py
#, python-format
msgid "We are trying to find the BSSIDs broadcast by “%s”."
msgstr "Wir versuchen die BSSIDs von „%s“ zu finden."
#: c3nav/mapdata/quests/positioning.py
#, python-format
msgid "Please stand near “%s” and wait for the submit button to appear."
msgstr "Bitte stell dich zu „%s“ und warte bis der Absendebutton erscheint."
#: c3nav/mapdata/quests/positioning.py
msgid "This should happen within less than a minute."
msgstr "Dies sollte weniger als eine Minute dauern."
#: c3nav/mapdata/quests/route_descriptions.py #: c3nav/mapdata/quests/route_descriptions.py
msgid "Does this space qualify as “easily identifyable/findable”?" msgid "Does this space qualify as “easily identifyable/findable”?"
msgstr "Ist dieser Raum „einfach zu identifizieren/finden“?" msgstr "Ist dieser Raum „einfach zu identifizieren/finden“?"

View file

@ -1,6 +1,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms import CharField, HiddenInput
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from shapely import Point from shapely import Point
from shapely.geometry import mapping from shapely.geometry import mapping
@ -55,6 +56,12 @@ class RangingBeaconAltitudeQuest(Quest):
class RangingBeaconBSSIDsQuestForm(ChangeSetModelForm): class RangingBeaconBSSIDsQuestForm(ChangeSetModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["look_for_ap"] = CharField(disabled=True, initial=self.instance.import_tag[4:],
widget=HiddenInput())
self.fields["wifi_bssids"].widget = HiddenInput()
def clean_bssids(self): def clean_bssids(self):
data = self.cleaned_data["wifi_bssids"] data = self.cleaned_data["wifi_bssids"]
if not data: if not data:
@ -82,8 +89,9 @@ class RangingBeaconBSSIDsQuest(Quest):
@property @property
def quest_description(self) -> list[str]: def quest_description(self) -> list[str]:
return [ return [
_("This quest is only available in the app. It works fully automatically."), _("This quest only works in the app. It works fully automatically."),
_("Please stand near this access point and wait for the submit button to appear."), _("We are trying to find the BSSIDs broadcast by “%s”."),
_("Please stand near “%s” and wait for the submit button to appear.") % self.obj.title,
_("This should happen within less than a minute."), _("This should happen within less than a minute."),
] ]
@ -93,4 +101,4 @@ class RangingBeaconBSSIDsQuest(Quest):
@classmethod @classmethod
def _qs_for_request(cls, request): def _qs_for_request(cls, request):
return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", bssids=[]) return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", wifi_bssids=[])

View file

@ -9,6 +9,7 @@ from pydantic.types import NonNegativeInt, NonNegativeFloat
from pydantic_extra_types.mac_address import MacAddress from pydantic_extra_types.mac_address import MacAddress
from c3nav.api.schema import BaseSchema from c3nav.api.schema import BaseSchema
from c3nav.api.utils import NonEmptyStr
class WifiPeerInformationElement(BaseSchema): class WifiPeerInformationElement(BaseSchema):
@ -69,6 +70,15 @@ class LocateWifiPeerSchema(BaseSchema):
description="standard deviation of measurements in meters", description="standard deviation of measurements in meters",
example=1.23 example=1.23
) )
ap_name: Union[
NonEmptyStr,
Annotated[None, APIField(title="null", description="AP name not available")]
] = APIField(
default=None,
title="AP name",
description="as broadcasted, for example, by aruba APs",
example="AP042"
)
info_elems: list[WifiPeerInformationElement] = APIField( info_elems: list[WifiPeerInformationElement] = APIField(
default=[], default=[],
title="information elements / vendor data", title="information elements / vendor data",

View file

@ -1459,10 +1459,14 @@ c3nav = {
} }
}, },
_set_modal_content: function (content, no_close) { _set_modal_content: function (content, no_close) {
$('#modal').toggleClass('loading', !content) const $modal = $('#modal');
$modal.toggleClass('loading', !content)
.find('#modal-content') .find('#modal-content')
.html((!no_close) ? '<button class="button-clear material-symbols" id="close-modal">clear</button>' : '') .html((!no_close) ? '<button class="button-clear material-symbols" id="close-modal">clear</button>' : '')
.append(content || '<div class="loader"></div>'); .append(content || '<div class="loader"></div>');
if ($modal.find('[name=look_for_ap]').length) {
$modal.find('button').hide();
}
}, },
_modal_click: function (e) { _modal_click: function (e) {
if (!c3nav.modal_noclose && (e.target.id === 'modal' || e.target.id === 'close-modal')) { if (!c3nav.modal_noclose && (e.target.id === 'modal' || e.target.id === 'close-modal')) {
@ -2120,6 +2124,9 @@ c3nav = {
if (c3nav.ssids) { if (c3nav.ssids) {
peers = peers.filter(peer => c3nav.ssids.includes(peer.ssid)); peers = peers.filter(peer => c3nav.ssids.includes(peer.ssid));
} }
let match_ap = $('[name=look_for_ap]').val(),
found_bssids = [];
for (const peer of peers) { for (const peer of peers) {
if (peer.level !== undefined) { if (peer.level !== undefined) {
peer.rssi = peer.level; peer.rssi = peer.level;
@ -2130,6 +2137,25 @@ c3nav = {
peer.distance_sd = peer.rtt.distance_std_dev_mm / 1000; peer.distance_sd = peer.rtt.distance_std_dev_mm / 1000;
delete peer.rtt; delete peer.rtt;
} }
if (match_ap && peer.ap_name === match_ap) {
found_bssids.push(peer.bssid);
}
}
if (found_bssids.length) {
let $wifi_bssids = $('[name=wifi_bssids]'),
val = JSON.parse($wifi_bssids.val()),
added = 0;
for (let bssid of found_bssids) {
if (!val.includes(bssid)) {
val.push(bssid);
added++;
}
}
if (added) {
$wifi_bssids.val(JSON.stringify(val));
} else {
$('#modal button[type=submit]').show();
}
} }
c3nav._last_wifi_peers = peers; c3nav._last_wifi_peers = peers;
c3nav._after_scan_results(); c3nav._after_scan_results();