diff --git a/src/c3nav/mesh/consumers.py b/src/c3nav/mesh/consumers.py index 5f2fb352..e4ab58fa 100644 --- a/src/c3nav/mesh/consumers.py +++ b/src/c3nav/mesh/consumers.py @@ -269,6 +269,22 @@ class MeshConsumer(AsyncWebsocketConsumer): }) print("MESH %s: [%s] %s" % (self.uplink.node, address, text)) + async def check_ota(self, addresses): + recipients = await self.get_nodes_with_ota(addresses) + for address, recipient in recipients.items(): + if not recipient: + continue + await self.check_ota_recipient(address, recipient) + + @database_sync_to_async + def get_nodes_with_ota(self, addresses) -> dict: + return {node.address: node.current_ota + for node in MeshNode.objects.filter(address__in=addresses).prefetch_ota()} + + async def check_ota_recipient(self, address, update): + print('checking OTA recipient', address, update) + pass + async def add_dst_nodes(self, nodes=None, addresses=None): nodes = list(nodes) if nodes else [] addresses = set(addresses) if addresses else set() @@ -299,6 +315,8 @@ class MeshConsumer(AsyncWebsocketConsumer): ) ) + await self.check_ota([address]) + @database_sync_to_async def _add_destination(self, address): with transaction.atomic(): @@ -406,8 +424,24 @@ class MeshUIConsumer(AsyncJsonWebsocketConsumer): else: if value != filter_value: return + if data["msg"]["msg_type"] == MeshMessageType.LOCATE_RANGE_RESULTS.name: + data = data.copy() + location = await self.locator(data["msg"]) + data["position"] = None if not location else (int(location.x*100), int(location.y*100), int(location.z*100)) await self.send_json(data) + @database_sync_to_async + def locator(self, msg): + locator = RangeLocator.load() + return locator.locate( + { + r["peer"]: r["distance"] + for r in msg["ranges"] + if r["distance"] != 0xFFFF + }, + None + ) + async def disconnect(self, code): await self.channel_layer.group_discard("mesh_log", self.channel_name) await self.channel_layer.group_discard("mesh_msg_sent", self.channel_name) diff --git a/src/c3nav/mesh/templates/mesh/fragment_mesh_websocket.html b/src/c3nav/mesh/templates/mesh/fragment_mesh_websocket.html index 30771ed0..bd92dbff 100644 --- a/src/c3nav/mesh/templates/mesh/fragment_mesh_websocket.html +++ b/src/c3nav/mesh/templates/mesh/fragment_mesh_websocket.html @@ -105,6 +105,27 @@ function connect() { for (cell of document.querySelectorAll(`[data-range-from="${src_node}"]:not([data-range-to="${src_node}"])`)) { cell.innerText = "-"; } + cell = document.querySelector(`[data-range-location="${src_node}"]`); + if (!cell) break; + if (data.position) { + cell.innerHTML = `Location (${data.position[0]}, ${data.position[1]}, ${data.position[2]})`; + if (src_node in nodes_xyz) { + cell.innerHTML += `
Actual: (${nodes_xyz[src_node][0]}, ${nodes_xyz[src_node][1]}, ${nodes_xyz[src_node][2]})`; + cell.innerHTML += `
Diff: (${data.position[0]-nodes_xyz[src_node][0]}, ${data.position[1]-nodes_xyz[src_node][1]}, ${data.position[2]-nodes_xyz[src_node][2]})`; + + cell.innerHTML += '
XY: '+String(Math.round(Math.sqrt( + Math.pow(nodes_xyz[src_node][0]-data.position[0], 2) + + Math.pow(nodes_xyz[src_node][1]-data.position[1], 2) + )))+' // XYZ: '+String(Math.round(Math.sqrt( + Math.pow(nodes_xyz[src_node][0]-data.position[0], 2) + + Math.pow(nodes_xyz[src_node][1]-data.position[1], 2) + + Math.pow(nodes_xyz[src_node][2]-data.position[2], 2) + ))); + + } + } else { + cell.innerHTML = ''; + } for (var i=0;i {% endfor %} + + + + {% for range_from in ranging_form.cleaned_data.range_from %} + + {% endfor %} + {% endif %} diff --git a/src/c3nav/routing/rangelocator.py b/src/c3nav/routing/rangelocator.py index 6dd195ce..e4129045 100644 --- a/src/c3nav/routing/rangelocator.py +++ b/src/c3nav/routing/rangelocator.py @@ -126,7 +126,8 @@ class RangeLocator: y=results.x[1]/100, permissions=(), icon='my_location' - ) + )# + location.z = results.x[2] pprint(relevant_ranges) print("measured ranges:", ", ".join(("%.2f" % i) for i in tuple(np_ranges[:, 3])))