+
General
+
+ Address: {{ node.address }}
+ Name: {% if node.name %}{{ node.name }}{% else %}{% trans '(no name)' %}{% endif %}
+
+
+
+ {% trans 'Edit' %}
+
+
+ {% trans 'View messages' %}
+
+
+
Firmware
-
Chip: {{ node.last_messages.CONFIG_FIRMWARE.parsed.get_chip_display }} rev{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision|join:"." }}
-
-
Firmware: {{ node.last_messages.CONFIG_FIRMWARE.parsed.project_name }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.version }} (IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.idf_version }})
-
-
Compile Date: {{ node.last_messages.CONFIG_FIRMWARE.parsed.compile_date }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.compile_time }}
-
-
SHA256: {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_elf_sha256 }}
+
+ Chip: {{ node.last_messages.CONFIG_FIRMWARE.parsed.get_chip_display }} rev{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision|join:"." }}
+
+ Firmware: {{ node.last_messages.CONFIG_FIRMWARE.parsed.project_name }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.version }} (IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.idf_version }})
+
+ Compile Date: {{ node.last_messages.CONFIG_FIRMWARE.parsed.compile_date }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.compile_time }}
+
+ SHA256: {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_elf_sha256 }}
+
Uplink
@@ -32,7 +48,6 @@
-
Position
X={{ node.last_messages.CONFIG_POSITION.parsed.x_pos }}, Y={{ node.last_messages.CONFIG_POSITION.parsed.y_pos }}, Z={{ node.last_messages.CONFIG_POSITION.parsed.z_pos }}
diff --git a/src/c3nav/control/urls.py b/src/c3nav/control/urls.py
index 626b533f..9c027ff2 100644
--- a/src/c3nav/control/urls.py
+++ b/src/c3nav/control/urls.py
@@ -1,6 +1,7 @@
from django.urls import path
-from c3nav.control.views.mesh import MeshNodeListView, MeshMessageListView, MeshNodeDetailView, MeshMessageSendView
+from c3nav.control.views.mesh import MeshNodeListView, MeshMessageListView, MeshNodeDetailView, MeshMessageSendView, \
+ MeshNodeEditView
from c3nav.control.views.mapupdates import map_updates
from c3nav.control.views.announcements import announcement_list, announcement_detail
from c3nav.control.views.access import grant_access, grant_access_qr
@@ -18,6 +19,7 @@ urlpatterns = [
path('mesh/', MeshNodeListView.as_view(), name='control.mesh_nodes'),
path('mesh/messages/', MeshMessageListView.as_view(), name='control.mesh_messages'),
path('mesh//', MeshNodeDetailView.as_view(), name='control.mesh_node.detail'),
+ path('mesh//edit/', MeshNodeEditView.as_view(), name='control.mesh_node.edit'),
path('mesh//message//', MeshMessageSendView.as_view(), name='control.mesh_message.send'),
path('', ControlPanelIndexView.as_view(), name='control.index'),
]
diff --git a/src/c3nav/control/views/mesh.py b/src/c3nav/control/views/mesh.py
index 967f55ed..b6da40bf 100644
--- a/src/c3nav/control/views/mesh.py
+++ b/src/c3nav/control/views/mesh.py
@@ -1,13 +1,14 @@
from django.contrib import messages
+from django.contrib.messages.views import SuccessMessageMixin
from django.db.models import Max
from django.http import Http404
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
-from django.views.generic import ListView, DetailView, FormView
+from django.views.generic import ListView, DetailView, FormView, UpdateView
from c3nav.control.forms import MeshMessageFilterForm
from c3nav.control.views.base import ControlPanelMixin
-from c3nav.mesh.forms import MeshMessageForm
+from c3nav.mesh.forms import MeshMessageForm, MeshNodeForm
from c3nav.mesh.messages import MeshMessageType
from c3nav.mesh.models import MeshNode, NodeMessage
@@ -32,6 +33,22 @@ class MeshNodeDetailView(ControlPanelMixin, DetailView):
return super().get_queryset().annotate(last_msg=Max('received_messages__datetime')).prefetch_last_messages()
+class MeshNodeEditView(ControlPanelMixin, SuccessMessageMixin, UpdateView):
+ model = MeshNode
+ form_class = MeshNodeForm
+ template_name = "control/form.html"
+ success_message = _('Name updated successfully')
+
+ def get_context_data(self, **kwargs):
+ return {
+ **super().get_context_data(),
+ 'title': _('Editing mesh node: %s') % self.get_object(),
+ }
+
+ def get_success_url(self):
+ return reverse('control.mesh_node.detail', kwargs={'pk': self.get_object().pk})
+
+
class MeshMessageListView(ControlPanelMixin, ListView):
model = NodeMessage
template_name = "control/mesh_messages.html"
diff --git a/src/c3nav/mesh/forms.py b/src/c3nav/mesh/forms.py
index dc62d826..15839462 100644
--- a/src/c3nav/mesh/forms.py
+++ b/src/c3nav/mesh/forms.py
@@ -166,3 +166,9 @@ class ConfigPositionMessageForm(MeshMessageForm):
x_pos = forms.IntegerField(min_value=0, max_value=2**16-1, label=_('X'))
y_pos = forms.IntegerField(min_value=0, max_value=2 ** 16 - 1, label=_('Y'))
z_pos = forms.IntegerField(min_value=0, max_value=2 ** 16 - 1, label=_('Z'))
+
+
+class MeshNodeForm(forms.ModelForm):
+ class Meta:
+ model = MeshNode
+ fields = ["name"]
\ No newline at end of file
diff --git a/src/c3nav/mesh/messages.py b/src/c3nav/mesh/messages.py
index 24b7f597..401d1478 100644
--- a/src/c3nav/mesh/messages.py
+++ b/src/c3nav/mesh/messages.py
@@ -90,11 +90,17 @@ class MeshMessage:
def fromjson(cls, data) -> M:
kwargs = data.copy()
klass = cls.msg_types[kwargs.pop('msg_id')]
+ kwargs = klass.upgrade_json(kwargs)
+ names = set(field.name for field in fields(klass))
for field_ in fields(klass):
if is_dataclass(field_.type):
kwargs[field_.name] = field_.type.fromjson(kwargs[field_.name])
return klass(**kwargs)
+ @classmethod
+ def upgrade_json(cls, data):
+ return data
+
def send(self):
async_to_sync(channels.layers.get_channel_layer().group_send)(get_mesh_comm_group(self.dst), {
"type": "mesh.send",
@@ -256,14 +262,14 @@ class ConfigFirmwareMessage(MeshMessage, msg_id=MeshMessageType.CONFIG_FIRMWARE)
app_elf_sha256: str = field(metadata={"format": HexFormat(32)})
reserv2: list[int] = field(metadata={"format": SimpleFormat('20I')}, repr=False)
- def to_model_data(self):
- return {
- 'chip': self.chip,
- 'project_name': self.project_name,
- 'version': self.version,
- 'idf_version': self.idf_version,
- 'sha256_hash': self.app_elf_sha256,
- }
+ @classmethod
+ def upgrade_json(cls, data):
+ data = data.copy() # todo: deepcopy?
+ print(data)
+ if 'revision' in data:
+ data['revision_major'], data['revision_minor'] = data.pop('revision')
+ print(data)
+ return data
def get_chip_display(self):
return ChipType(self.chip).name.replace('_', '-')