wifimeasurement → beaconmeasurement… and editor scancollector implementation

This commit is contained in:
Laura Klünder 2024-03-31 16:23:15 +02:00
parent 35d030a6fd
commit 20fbcc9139
13 changed files with 169 additions and 85 deletions

View file

@ -48,7 +48,7 @@ def geometrystyles(request):
'graphnode': '#009900',
'graphedge': '#00CC00',
'altitudemarker': '#0000FF',
'wifimeasurement': '#DDDD00',
'beaconmeasurement': '#DDDD00',
'rangingbeacon': '#CC00CC',
}

View file

@ -119,7 +119,7 @@ def get_level_geometries_result(request, level_id: int, update_cache_key: str, u
Building = request.changeset.wrap_model('Building')
Door = request.changeset.wrap_model('Door')
LocationGroup = request.changeset.wrap_model('LocationGroup')
WifiMeasurement = request.changeset.wrap_model('WifiMeasurement')
BeaconMeasurement = request.changeset.wrap_model('BeaconMeasurement')
RangingBeacon = request.changeset.wrap_model('RangingBeacon')
try:
@ -149,7 +149,7 @@ def get_level_geometries_result(request, level_id: int, update_cache_key: str, u
Prefetch('buildings', Building.objects.only('geometry', 'level')),
Prefetch('spaces__holes', Hole.objects.only('geometry', 'space')),
Prefetch('spaces__altitudemarkers', AltitudeMarker.objects.only('geometry', 'space')),
Prefetch('spaces__wifi_measurements', WifiMeasurement.objects.only('geometry', 'space')),
Prefetch('spaces__beacon_measurements', BeaconMeasurement.objects.only('geometry', 'space')),
Prefetch('spaces__ranging_beacons', RangingBeacon.objects.only('geometry', 'space')),
Prefetch('spaces__graphnodes', graphnodes_qs)
)
@ -184,7 +184,7 @@ def get_level_geometries_result(request, level_id: int, update_cache_key: str, u
_get_geometries_for_one_level(level),
*(_get_geometries_for_one_level(level) for level in levels_on_top),
*(space.altitudemarkers.all() for space in level.spaces.all()),
*(space.wifi_measurements.all() for space in level.spaces.all()),
*(space.beacon_measurements.all() for space in level.spaces.all()),
*(space.ranging_beacons.all() for space in level.spaces.all()),
graphedges,
graphnodes,
@ -309,7 +309,7 @@ def get_space_geometries_result(request, space_id: int, update_cache_key: str, u
space.lineobstacles.all().only('geometry', 'width', 'space').prefetch_related('group'),
space.columns.all().only('geometry', 'space'),
space.altitudemarkers.all().only('geometry', 'space'),
space.wifi_measurements.all().only('geometry', 'space'),
space.beacon_measurements.all().only('geometry', 'space'),
space.ranging_beacons.all().only('geometry', 'space'),
space.pois.filter(POI.q_for_request(request)).only('geometry', 'space').prefetch_related(
Prefetch('groups', LocationGroup.objects.only(

View file

@ -396,38 +396,41 @@ textarea.form-control {
height: 75px;
}
.wificollector {
.scancollector {
padding: 10px;
height: auto;
}
body > .wificollector {
body > .scancollector {
display: none;
}
.wificollector:not(.empty) .btn.start,
.wificollector:not(.running) .btn.stop,
.wificollector:not(.done) .btn.reset,
.wificollector.empty .count-line,
body:not(.mobileclient) .wificollector .btn {
.scancollector:not(.empty) .btn.start,
.scancollector:not(.running) .btn.stop,
.scancollector:not(.done) .btn.reset,
.scancollector.empty .count-line,
body:not(.mobileclient) .scancollector .btn {
display: none;
}
.wificollector .btn {
.scancollector .btn {
margin: 0 5px 0 0;
}
.wificollector p:first-child {
.scancollector p:first-child {
height: 26px;
margin: 0;
}
.wificollector table {
.scancollector table {
width: 100%;
border-style: solid;
border-width: 0 0 1px;
border-color: #666666;
}
.wificollector table td {
.scancollector table td {
padding: 5px 5px 0 0;
}
.wificollector table td:last-child {
.scancollector table td:last-child {
padding-right: 0;
text-align: right;
}
.wificollector table tr td {
.scancollectorŝ table tr td {
color: #666666;
}

View file

@ -71,7 +71,7 @@ editor = {
editor._sublevel_control_container = $(editor._sublevel_control._container);
editor.init_geometries();
editor.init_wificollector();
editor.init_scancollector();
editor.sidebar_content_loaded();
},
_inform_mobile_client: function(elem) {
@ -175,7 +175,7 @@ editor = {
editor._fixed_point_layer = null;
}
if (window.mobileclient && mobileclient.wificollectorStop && $('#sidebar').find('.wificollector.running').length) {
if (window.mobileclient && mobileclient.wificollectorStop && $('#sidebar').find('.scancollector.running').length) {
mobileclient.wificollectorStop();
}
@ -413,13 +413,13 @@ editor = {
var data_field = $('form [name=data]');
if (data_field.length) {
data_field.hide();
var collector = $($('body .wificollector')[0].outerHTML);
var collector = $($('body .scancollector')[0].outerHTML);
var existing_data = [];
if (data_field.val()) {
existing_data = JSON.parse(data_field.val());
}
if (existing_data.length > 0) {
collector.removeClass('empty').addClass('done').find('.count').text(existing_data.length);
collector.removeClass('empty').addClass('done').find('.wifi-count').text(existing_data.length);
} else {
data_field.closest('form').addClass('scan-lock');
}
@ -1304,50 +1304,58 @@ editor = {
}
},
init_wificollector: function () {
init_scancollector: function () {
// init geometries and edit listeners
editor._highlight_layer = L.layerGroup().addTo(editor.map);
$('#sidebar').on('click', '.wificollector .start', editor._wificollector_start)
.on('click', '.wificollector .stop', editor._wificollector_stop)
.on('click', '.wificollector .reset', editor._wificollector_reset);
window.setInterval(editor._wificollector_scan_perhaps, 1000);
$('#sidebar').on('click', '.scancollector .start', editor._scancollector_start)
.on('click', '.scancollector .stop', editor._scancollector_stop)
.on('click', '.scancollector .reset', editor._scancollector_reset);
window.setInterval(editor._scancollector_wifi_scan_perhaps, 1000);
},
_wificollector_data: [],
_wificollector_start: function () {
var $collector = $('#sidebar').find('.wificollector');
_scancollector_data: {
wifi: [],
ibeacon: [],
},
_scancollector_start: function () {
var $collector = $('#sidebar').find('.scancollector');
$collector.removeClass('empty').addClass('running');
editor._wificollector_data = [];
$collector.find('.count').text(0);
editor._scancollector_data.wifi = [];
editor._scancollector_data.ibeacon = [];
$collector.find('.wifi-count').text(0);
$collector.find('.ibeacon-count').text(0);
if (mobileclient.wificollectorStart) mobileclient.wificollectorStart();
if (mobileclient.registerBeaconUuid) mobileclient.registerBeaconUuid("a142621a-2f42-09b3-245b-e1ac6356e9b0");
},
_wificollector_stop: function () {
_scancollector_stop: function () {
if (mobileclient.wificollectorStop) mobileclient.wificollectorStop();
if (!editor._wificollector_data.length) return editor._wificollector_reset();
var $collector = $('#sidebar').find('.wificollector');
if (mobileclient.unregisterBeaconUuid) mobileclient.unregisterBeaconUuid("a142621a-2f42-09b3-245b-e1ac6356e9b0");
// todo: maybe reset if either is empty?
if (!editor._scancollector_data.wifi.length && editor._scancollector_data.ibeacon.length) return editor._scancollector_reset();
var $collector = $('#sidebar').find('.scancollector');
$collector.removeClass('running').delay(1000).queue(function(n) {
$(this).addClass('done');
n();
});
$collector.closest('form').removeClass('scan-lock');
},
_wificollector_reset: function () {
var $collector = $('#sidebar').find('.wificollector');
$collector.removeClass('done').removeClass('running').addClass('empty').find('table').html('');
_scancollector_reset: function () {
var $collector = $('#sidebar').find('.scancollector');
$collector.removeClass('done').removeClass('running').addClass('empty').find('table').forEach(function(elem) {elem.html('');});
$collector.siblings('[name=data]').val('');
$collector.closest('form').addClass('scan-lock');
},
_wificollector_last_max_last: 0,
_wificollector_last_result: 0,
_wificollector_result: function(data) {
var $collector = $('#sidebar').find('.wificollector.running'),
$table = $collector.find('table'),
_scancollector_wifi_last_max_last: 0,
_scancollector_wifi_last_result: 0,
_scancollector_wifi_result: function(data) {
var $collector = $('#sidebar').find('.scancollector.running'),
$table = $collector.find('.wifi-table'),
item, i, line, apid, color, max_last = 0, now = Date.now();
editor._scan_waits = false;
editor._wifi_scan_waits = false;
if (!data.length) return;
if (now-2000 < editor._wificollector_last_result) return;
editor._wificollector_last_result = now;
if (now-2000 < editor._scancollector_wifi_last_result) return;
editor._scancollector_wifi_last_result = now;
// ignore this scan?
for (i=0; i < data.length; i++) {
@ -1356,8 +1364,8 @@ editor = {
max_last = Math.max(max_last, item.last);
}
}
if (max_last && editor._wificollector_last_max_last && max_last === editor._max_last_max) return;
editor._wificollector_last_max_last = max_last;
if (max_last && editor._scancollector_wifi_last_max_last && max_last === editor._max_last_max) return;
editor._scancollector_wifi_last_max_last = max_last;
$table.find('tr').addClass('old');
for (i=0; i < data.length; i++) {
@ -1388,23 +1396,55 @@ editor = {
$table.append(line);
}
}
editor._wificollector_data.push(data);
$collector.find('.count').text(editor._wificollector_data.length);
$collector.siblings('[name=data]').val(JSON.stringify(editor._wificollector_data));
editor._scancollector_data.wifi.push(data);
$collector.find('.wifi-count').text(editor._scancollector_data.wifi.length);
$collector.siblings('[name=data]').val(JSON.stringify(editor._scancollector_data));
},
_scan_waits: false,
_wificollector_scan_perhaps: function() {
if (!editor._scan_waits && $('#sidebar').find('.wificollector.running').length) {
editor._scan_waits = true;
_scancollector_ibeacon_result: function(data) {
var $collector = $('#sidebar').find('.scancollector.running'),
$table = $collector.find('.ibeacon-table'),
item, i, line, beaconid, color = Date.now();
if (!data.length) return;
$table.find('tr').addClass('old');
for (i=0; i < data.length; i++) {
item = data[i];
beaconid = 'beacon-'+item.uuid+'-'+item.major+'-'+item-minor;
line = $table.find('tr.'+beaconid);
color = Math.max(0, Math.min(50, item.distance));
color = 'rgb('+String(color*5)+', '+String(200-color*4)+', 0)';
if (line.length) {
line.removeClass('old').find(':last-child').text(item.distance).css('color', color);
} else {
line = $('<tr>').addClass(beaconid);
line.append($('<td>').text(item.major));
line.append($('<td>').text(item.minor));
line.append($('<td>').text(item.distance).css('color', color));
$table.append(line);
}
}
editor._scancollector_data.ibeacon.push(data);
$collector.find('.ibeacon-count').text(editor._scancollector_data.ibeacon.length);
$collector.siblings('[name=data]').val(JSON.stringify(editor._scancollector_data));
},
_wifi_scan_waits: false,
_scancollector_wifi_scan_perhaps: function() {
if (!editor._wifi_scan_waits && $('#sidebar').find('.scancollector.running').length) {
editor._wifi_scan_waits = true;
mobileclient.scanNow();
}
}
};
function nearby_stations_available() {
editor._wificollector_result(JSON.parse(mobileclient.getNearbyStations()));
editor._scancollector_wifi_result(JSON.parse(mobileclient.getNearbyStations()));
}
function ibeacon_results_available() {
c3nav._scancollector_ibeacon_result(mobileclient.getNearbyBeacons());
}
LevelControl = L.Control.extend({
options: {

View file

@ -69,17 +69,19 @@
{% endblock %}
</div>
<div class="wificollector form-control empty">
<div class="scancollector form-control empty">
<p>
<a class="btn btn-xs btn-primary start">{% trans 'Start scanning' %}</a>
<a class="btn btn-xs btn-default stop">{% trans 'Stop scanning' %}</a>
<a class="btn btn-xs btn-danger reset">{% trans 'Reset scan results' %}</a>
<span class="count-line"><span class="count">0</span> scans</span>
</p>
<p class="nomobileclient"><em>
{% trans 'mobileclient not found. Please install the c3nav app for wifi scanning support.' %}
</em></p>
<table></table>
<p><span class="count-line"><span class="wifi-count">0</span> WiFi scans</span></p>
<table class="wifi-table"></table>
<p><span class="count-line"><span class="ibeacon-count">0</span> iBeacon scans</span></p>
<table class="ibeacon-table"></table>
</div>
<div class="theme-editor-filter">

View file

@ -80,5 +80,5 @@ urlpatterns.extend(add_editor_urls('POI', 'Space'))
urlpatterns.extend(add_editor_urls('AltitudeMarker', 'Space'))
urlpatterns.extend(add_editor_urls('LeaveDescription', 'Space'))
urlpatterns.extend(add_editor_urls('CrossDescription', 'Space'))
urlpatterns.extend(add_editor_urls('WifiMeasurement', 'Space'))
urlpatterns.extend(add_editor_urls('BeaconMeasurement', 'Space'))
urlpatterns.extend(add_editor_urls('RangingBeacon', 'Space'))

View file

@ -108,7 +108,7 @@ def space_detail(request, level, pk):
if edit_utils.can_access_child_base_mapdata:
submodels = ('POI', 'Area', 'Obstacle', 'LineObstacle', 'Stair', 'Ramp', 'Column',
'Hole', 'AltitudeMarker', 'LeaveDescription', 'CrossDescription',
'WifiMeasurement', 'RangingBeacon')
'BeaconMeasurement', 'RangingBeacon')
else:
submodels = ('POI', 'Area', 'AltitudeMarker', 'LeaveDescription', 'CrossDescription')
@ -281,9 +281,9 @@ def edit(request, pk=None, model=None, level=None, space=None, on_top_of=None, e
'nozoom': True
})
if new and model.__name__ == 'WifiMeasurement' and not request.user.is_authenticated:
if new and model.__name__ == 'BeaconMeasurement' and not request.user.is_authenticated:
return APIHybridLoginRequiredResponse(next=request.path_info, login_url='editor.login', level='info',
message=_('You need to log in to create Wifi Measurements.'))
message=_('You need to log in to create Beacon Measurements.'))
error = None
delete = getattr(request, 'is_delete', None)