more features for tracing and everything
This commit is contained in:
parent
0343030980
commit
0c9b253d87
6 changed files with 97 additions and 30 deletions
|
@ -65,11 +65,26 @@ function connect() {
|
||||||
break
|
break
|
||||||
case 'mesh.msg_sent':
|
case 'mesh.msg_sent':
|
||||||
{% if send_uuid %}
|
{% if send_uuid %}
|
||||||
line = document.createElement("p");
|
line = document.createElement("span");
|
||||||
line.innerText = "sent via uplink ["+data.channel+"] "+data.uplink;
|
|
||||||
|
text = document.createElement("span")
|
||||||
|
text.innerText = "sent via uplink "
|
||||||
|
line.appendChild(text)
|
||||||
|
|
||||||
|
text = document.createElement("small")
|
||||||
|
text.innerText = "["+data.channel+"] "
|
||||||
|
line.appendChild(text)
|
||||||
|
|
||||||
|
link_tag = document.createElement("a");
|
||||||
|
link_tag.href = "/control/mesh/" + data.uplink;
|
||||||
|
link_tag.innerText = data.uplink;
|
||||||
if (node_names[data.uplink]) {
|
if (node_names[data.uplink]) {
|
||||||
line.innerText += " ("+node_names[data.uplink]+")";
|
link_tag.innerText += "("+node_names[data.uplink]+")";
|
||||||
}
|
}
|
||||||
|
line.appendChild(link_tag);
|
||||||
|
|
||||||
|
line.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
document.getElementById("sending-status-"+data.recipient).appendChild(line);
|
document.getElementById("sending-status-"+data.recipient).appendChild(line);
|
||||||
{% endif %}
|
{% endif %}
|
||||||
break;
|
break;
|
||||||
|
@ -77,23 +92,21 @@ function connect() {
|
||||||
case 'mesh.msg_received':
|
case 'mesh.msg_received':
|
||||||
{% if send_uuid and msg_type == "MESH_ROUTE_REQUEST" %}
|
{% if send_uuid and msg_type == "MESH_ROUTE_REQUEST" %}
|
||||||
if (data.msg.route) {
|
if (data.msg.route) {
|
||||||
|
line = document.createElement('tr');
|
||||||
|
|
||||||
|
cell = document.createElement("td");
|
||||||
link_tag = document.createElement("a");
|
link_tag = document.createElement("a");
|
||||||
link_tag.href = "/control/mesh/" + data.msg.src;
|
link_tag.href = "/control/mesh/" + data.msg.src;
|
||||||
link_tag.innerText = data.msg.src;
|
link_tag.innerText = data.msg.src;
|
||||||
if (node_names[data.msg.src]) {
|
if (node_names[data.msg.src]) {
|
||||||
link_tag.innerText += " ("+node_names[data.msg.src]+")";
|
link_tag.innerText += " ("+node_names[data.msg.src]+")";
|
||||||
}
|
}
|
||||||
|
cell.appendChild(link_tag);
|
||||||
|
line.appendChild(cell);
|
||||||
|
|
||||||
if (data.msg.route === "00:00:00:00:00:00") {
|
if (data.msg.route === "00:00:00:00:00:00") {
|
||||||
line = document.createElement("li");
|
|
||||||
line.appendChild(link_tag);
|
|
||||||
document.getElementById("no-routes").appendChild(line);
|
document.getElementById("no-routes").appendChild(line);
|
||||||
} else {
|
} else {
|
||||||
line = document.createElement("tr");
|
|
||||||
|
|
||||||
cell = document.createElement("td");
|
|
||||||
cell.appendChild(link_tag);
|
|
||||||
line.appendChild(cell);
|
|
||||||
|
|
||||||
cell = document.createElement("td");
|
cell = document.createElement("td");
|
||||||
link_tag = document.createElement("a");
|
link_tag = document.createElement("a");
|
||||||
link_tag.href = "/control/mesh/" + data.msg.route;
|
link_tag.href = "/control/mesh/" + data.msg.route;
|
||||||
|
@ -108,14 +121,17 @@ function connect() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (var i=0;i<data.msg.trace.length;i++) {
|
for (var i=0;i<data.msg.trace.length;i++) {
|
||||||
line = document.createElement("li");
|
line = document.createElement('tr');
|
||||||
|
|
||||||
|
cell = document.createElement("td");
|
||||||
link_tag = document.createElement("a");
|
link_tag = document.createElement("a");
|
||||||
link_tag.href = "/control/mesh/" + data.msg.trace[i];
|
link_tag.href = "/control/mesh/" + data.msg.trace[i];
|
||||||
link_tag.innerText = data.msg.trace[i];
|
link_tag.innerText = data.msg.trace[i];
|
||||||
if (node_names[data.msg.trace[i]]) {
|
if (node_names[data.msg.trace[i]]) {
|
||||||
link_tag.innerText += " ("+node_names[data.msg.trace[i]]+")";
|
link_tag.innerText += " ("+node_names[data.msg.trace[i]]+")";
|
||||||
}
|
}
|
||||||
line.appendChild(link_tag);
|
cell.appendChild(link_tag);
|
||||||
|
line.appendChild(cell);
|
||||||
document.getElementById("route-trace").appendChild(line);
|
document.getElementById("route-trace").appendChild(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,18 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% for address, name in recipients %}
|
{% for address, name in recipients %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ address }}{% if name %} ({{ name }}){% endif %}</td>
|
<td>
|
||||||
|
{% if address != "ff:ff:ff:ff:ff:ff" %}<a href="{% url "control.mesh_node.detail" pk=address %}">{% endif %}
|
||||||
|
{{ address }}{% if name %} ({{ name }}){% endif %}
|
||||||
|
{% if address != "ff:ff:ff:ff:ff:ff" %}</a>{% endif %}
|
||||||
|
</td>
|
||||||
<td id="sending-status-{{ address }}"></td>
|
<td id="sending-status-{{ address }}"></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% if msg_type == "MESH_ROUTE_REQUEST" %}
|
{% if msg_type == "MESH_ROUTE_REQUEST" %}
|
||||||
<div>
|
<div style="min-width: 12vw;">
|
||||||
<h4>Routes</h4>
|
<h4>Routes</h4>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -38,13 +42,27 @@
|
||||||
<tbody id="route-responses"></tbody>
|
<tbody id="route-responses"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div style="min-width: 12vw;">
|
||||||
<h4>No Route</h4>
|
<h4 class="white-space: nowrap;">No Route</h4>
|
||||||
<ul id="no-routes"></ul>
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans 'Node' %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="no-routes"></tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div style="min-width: 12vw;">
|
||||||
<h4>Trace</h4>
|
<h4>Trace</h4>
|
||||||
<ul id="route-trace"></ul>
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans 'Hop' %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="route-trace"></tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,9 +4,34 @@
|
||||||
{% block heading %}{% trans 'Mesh' %}{% endblock %}
|
{% block heading %}{% trans 'Mesh' %}{% endblock %}
|
||||||
|
|
||||||
{% block subcontent %}
|
{% block subcontent %}
|
||||||
<a class="button" href="{% url "control.mesh_messages" %}">
|
<div class="columns">
|
||||||
{% trans 'View messages' %}
|
<div>
|
||||||
</a>
|
<h4>View messages</h4>
|
||||||
|
<a class="button" href="{% url "control.mesh_messages" %}">
|
||||||
|
{% trans 'View received messages' %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Send messages</h4>
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
<select name="send_msg_type" style="display: inline-block; width: auto;" required>
|
||||||
|
<option value="">select type</option>
|
||||||
|
{% for msg_type in send_msg_types %}
|
||||||
|
<option value="{{ msg_type }}">{{ msg_type }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<button type="submit">{% trans 'Send message' %}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Logs</h4>
|
||||||
|
<a class="button" href="{% url "control.mesh_log" %}">
|
||||||
|
{% trans 'View log' %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4>Nodes</h4>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans 'Node' %}</th>
|
<th>{% trans 'Node' %}</th>
|
||||||
|
@ -21,11 +46,11 @@
|
||||||
<td><a href="{% url "control.mesh_node.detail" pk=node.address %}">{{ node }}</a></td>
|
<td><a href="{% url "control.mesh_node.detail" pk=node.address %}">{{ node }}</a></td>
|
||||||
<td>
|
<td>
|
||||||
{{ node.last_messages.CONFIG_FIRMWARE.parsed.get_chip_display }}
|
{{ node.last_messages.CONFIG_FIRMWARE.parsed.get_chip_display }}
|
||||||
rev{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_minor }}
|
<small>rev{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_minor }}</small>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ node.last_messages.CONFIG_FIRMWARE.parsed.version }}
|
{{ node.last_messages.CONFIG_FIRMWARE.parsed.version }}
|
||||||
(IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.idf_version }})
|
<small>(IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.idf_version }})</small>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% blocktrans trimmed with timesince=node.last_msg|timesince %}
|
{% blocktrans trimmed with timesince=node.last_msg|timesince %}
|
||||||
|
|
|
@ -26,6 +26,17 @@ class MeshNodeListView(ControlPanelMixin, ListView):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().annotate(last_msg=Max('received_messages__datetime')).prefetch_last_messages()
|
return super().get_queryset().annotate(last_msg=Max('received_messages__datetime')).prefetch_last_messages()
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
return {
|
||||||
|
**super().get_context_data(*args, **kwargs),
|
||||||
|
"send_msg_types": [msg_type.name for msg_type in MeshMessageForm.msg_types.keys()],
|
||||||
|
}
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
return redirect(
|
||||||
|
reverse("control.mesh_message.send", kwargs={"msg_type": request.POST.get("send_msg_type", "")})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MeshNodeDetailView(ControlPanelMixin, DetailView):
|
class MeshNodeDetailView(ControlPanelMixin, DetailView):
|
||||||
model = MeshNode
|
model = MeshNode
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import time
|
import time
|
||||||
from dataclasses import fields as dataclass_fields
|
from dataclasses import fields as dataclass_fields
|
||||||
from functools import cached_property
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
@ -99,7 +98,7 @@ class MeshRouteRequestForm(MeshMessageForm):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields["address"].choices = self.node_choices
|
self.fields["address"].choices = (('', '------'), )+self.node_choices
|
||||||
|
|
||||||
def get_msg_data(self):
|
def get_msg_data(self):
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -10,9 +10,7 @@ class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
done_struct_names = set()
|
done_struct_names = set()
|
||||||
nodata = set()
|
nodata = set()
|
||||||
struct_lines = {
|
struct_lines = {}
|
||||||
"num": "uint8_t num; /** defined here for convenience. subtypes that use it will define it themselves */"
|
|
||||||
}
|
|
||||||
|
|
||||||
for msg_type in MeshMessage.msg_types.values():
|
for msg_type in MeshMessage.msg_types.values():
|
||||||
if msg_type.c_struct_name:
|
if msg_type.c_struct_name:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue