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])))