some work on creating the CONFIG_BOARD form
This commit is contained in:
parent
330a32adf8
commit
e70bd7e0e2
7 changed files with 125 additions and 30 deletions
|
@ -16,8 +16,42 @@
|
||||||
{% block subcontent %}
|
{% block subcontent %}
|
||||||
<form method="POST" style="max-width:400px;">
|
<form method="POST" style="max-width:400px;">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form.as_div }}
|
||||||
<noscript><input type="hidden" name="noscript" value"1"></noscript>
|
{{ form.conditionals | json_script:"form-conditionals" }}
|
||||||
|
<noscript><input type="hidden" name="noscript" value="1"></noscript>
|
||||||
|
<script>
|
||||||
|
var form_conditionals = JSON.parse(document.getElementById('form-conditionals').innerHTML)
|
||||||
|
function update_form() {
|
||||||
|
var field, other_field, value, show;
|
||||||
|
for (field of document.querySelectorAll("select, input[name]")) {
|
||||||
|
show = true;
|
||||||
|
for (elem of form_conditionals) {
|
||||||
|
if (field.name.startsWith(elem.prefix)) {
|
||||||
|
other_field = document.getElementsByName(elem.field)[0];
|
||||||
|
value = (other_field.type == "checkbox") ? other_field.checked : other_field.value;
|
||||||
|
|
||||||
|
console.log({"field": field.name, "filter": elem, "value": value});
|
||||||
|
if (!elem.values.includes(value)) {
|
||||||
|
console.log('no show');
|
||||||
|
show = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
field.parentNode.style.display = show ? "" : "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var done_fields = [];
|
||||||
|
for (elem of form_conditionals) {
|
||||||
|
if (done_fields.includes(elem.field)) continue;
|
||||||
|
done_fields.push(elem.field);
|
||||||
|
field = document.getElementsByName(elem.field)[0];
|
||||||
|
field.addEventListener("input", update_form);
|
||||||
|
field.addEventListener("change", update_form);
|
||||||
|
|
||||||
|
}
|
||||||
|
update_form();
|
||||||
|
</script>
|
||||||
<button type="submit">{% trans 'Send' %}</button>
|
<button type="submit">{% trans 'Send' %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,10 @@
|
||||||
<td><a href="{% url "control.mesh.node.detail" pk=msg.src_node.address %}">{{ msg.src_node }}</a></td>
|
<td><a href="{% url "control.mesh.node.detail" pk=msg.src_node.address %}">{{ msg.src_node }}</a></td>
|
||||||
<td>{{ msg.get_message_type_display }}</td>
|
<td>{{ msg.get_message_type_display }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if msg.get_message_type_display == "CONFIG_FIRMWARE" %}
|
{% if msg.get_message_type_display == "CONFIG_HARDWARE" %}
|
||||||
<strong>Chip:</strong> {{ msg.parsed.get_chip_display }} rev{{ msg.parsed.revision_major }}.{{ msg.parsed.revision_minor }}
|
<strong>Chip:</strong> {{ msg.parsed.get_chip_display }} rev{{ msg.parsed.revision_major }}.{{ msg.parsed.revision_minor }}
|
||||||
<br>
|
|
||||||
|
{% elif msg.get_message_type_display == "CONFIG_FIRMWARE" %}
|
||||||
<strong>Firmware:</strong> {{ msg.parsed.app_desc.project_name }} {{ msg.parsed.app_desc.version }} (IDF {{ msg.parsed.app_desc.idf_version }})
|
<strong>Firmware:</strong> {{ msg.parsed.app_desc.project_name }} {{ msg.parsed.app_desc.version }} (IDF {{ msg.parsed.app_desc.idf_version }})
|
||||||
<br>
|
<br>
|
||||||
<strong>Compile Date:</strong> {{ msg.parsed.app_desc.compile_date }} {{ msg.parsed.app_desc.compile_time }}
|
<strong>Compile Date:</strong> {{ msg.parsed.app_desc.compile_date }} {{ msg.parsed.app_desc.compile_time }}
|
||||||
|
|
|
@ -40,11 +40,13 @@
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h4>Hardware</h4>
|
||||||
|
<p>
|
||||||
|
<strong>Chip:</strong> {{ node.last_messages.CONFIG_HARDWARE.parsed.get_chip_display }}
|
||||||
|
rev{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_minor }}
|
||||||
|
</p>
|
||||||
<h4>Firmware</h4>
|
<h4>Firmware</h4>
|
||||||
<p>
|
<p>
|
||||||
<strong>Chip:</strong> {{ 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 }}
|
|
||||||
<br>
|
|
||||||
<strong>Firmware:</strong> {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.project_name }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.version }} (IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.idf_version }})
|
<strong>Firmware:</strong> {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.project_name }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.version }} (IDF {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.idf_version }})
|
||||||
<br>
|
<br>
|
||||||
<strong>Compile Date:</strong> {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.compile_date }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.compile_time }}
|
<strong>Compile Date:</strong> {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.compile_date }} {{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.compile_time }}
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<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_HARDWARE.parsed.get_chip_display }}
|
||||||
<small>rev{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_FIRMWARE.parsed.revision_minor }}</small>
|
<small>rev{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_minor }}</small>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.version }}
|
{{ node.last_messages.CONFIG_FIRMWARE.parsed.app_desc.version }}
|
||||||
|
|
|
@ -145,6 +145,10 @@ class MeshMessageSendView(ControlPanelMixin, FormView):
|
||||||
messages.success(self.request, _('Message sent successfully(?)'))
|
messages.success(self.request, _('Message sent successfully(?)'))
|
||||||
super().form_valid(form)
|
super().form_valid(form)
|
||||||
uuid = uuid4()
|
uuid = uuid4()
|
||||||
|
from pprint import pprint
|
||||||
|
pprint(form.get_msg_data())
|
||||||
|
pprint(MeshMessage.fromjson(form.get_msg_data()))
|
||||||
|
1/0
|
||||||
self.request.session["mesh_msg_%s" % uuid] = {
|
self.request.session["mesh_msg_%s" % uuid] = {
|
||||||
"success_url": self.get_success_url(),
|
"success_url": self.get_success_url(),
|
||||||
"recipients": form.get_recipients(),
|
"recipients": form.get_recipients(),
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from c3nav.mesh.dataformats import LedConfig
|
from c3nav.mesh.dataformats import LedConfig, LedType, SerialLedType, BoardType, BoardConfig
|
||||||
from c3nav.mesh.messages import MESH_BROADCAST_ADDRESS, MESH_ROOT_ADDRESS, MeshMessage, MeshMessageType
|
from c3nav.mesh.messages import MESH_BROADCAST_ADDRESS, MESH_ROOT_ADDRESS, MeshMessage, MeshMessageType
|
||||||
from c3nav.mesh.models import MeshNode
|
from c3nav.mesh.models import MeshNode
|
||||||
|
|
||||||
|
@ -121,29 +121,83 @@ class ConfigUplinkMessageForm(MeshMessageForm):
|
||||||
port = forms.IntegerField(min_value=1, max_value=65535, label=_('port'))
|
port = forms.IntegerField(min_value=1, max_value=65535, label=_('port'))
|
||||||
|
|
||||||
|
|
||||||
class ConfigLedMessageForm(MeshMessageForm):
|
class ConfigBoardMessageForm(MeshMessageForm):
|
||||||
msg_type = MeshMessageType.CONFIG_LED
|
msg_type = MeshMessageType.CONFIG_BOARD
|
||||||
|
|
||||||
led_type = forms.ChoiceField(choices=(
|
# todo: don't use numerical values
|
||||||
('', _('no LED')),
|
board = forms.ChoiceField(choices=((item.value, item.name) for item in BoardType),
|
||||||
(1, _('serial LED')),
|
label=_('board'))
|
||||||
(2, _('multipin LED'))
|
led_type = forms.ChoiceField(choices=((item.value, item.name) for item in LedType),
|
||||||
))
|
label=_('LED type'))
|
||||||
gpio = forms.IntegerField(min_value=0, max_value=48, required=False,
|
led_serial_type = forms.ChoiceField(choices=((item.value or '', item.name) for item in SerialLedType),
|
||||||
label=_('gpio pin'), help_text=_('serial only'))
|
label=_('serial LED type'), help_text=_('serial LED only'))
|
||||||
rmt = forms.IntegerField(min_value=0, max_value=7, required=False,
|
# todo: make this use the modern messages
|
||||||
label=_('rmt'), help_text=_('serial only'))
|
led_serial_gpio = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||||
gpio_r = forms.IntegerField(min_value=0, max_value=48, required=False,
|
label=_('serial LED GPIO pin'), help_text=_('serial LED only'))
|
||||||
label=_('gpio red'), help_text=_('multipin only'))
|
led_multipin_gpio_r = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||||
gpio_g = forms.IntegerField(min_value=0, max_value=48, required=False,
|
label=_('multpin LED GPIO red'), help_text=_('multipin LED only'))
|
||||||
label=_('gpio green'), help_text=_('multipin only'))
|
led_multipin_gpio_g = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||||
gpio_b = forms.IntegerField(min_value=0, max_value=48, required=False,
|
label=_('multpin LED GPIO green'), help_text=_('multipin LED only'))
|
||||||
label=_('gpio blue'), help_text=_('multipin only'))
|
led_multipin_gpio_b = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||||
|
label=_('multpin LED GPIO blue'), help_text=_('multipin LED only'))
|
||||||
|
|
||||||
|
uwb_enable = forms.BooleanField(required=False, label=_('UWB enable'))
|
||||||
|
uwb_gpio_miso = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO MISO'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_mosi = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO MOSI'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_clk = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO CLK'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_cs = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO CS'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_irq = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO IRQ'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_rst = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO RST'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_wakeup = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO WAKEUP'), help_text=_('UWB only'))
|
||||||
|
uwb_gpio_exton = forms.IntegerField(min_value=-1, max_value=48, required=False,
|
||||||
|
label=_('UWB GPIO EXTON'), help_text=_('UWB only'))
|
||||||
|
|
||||||
|
conditionals = (
|
||||||
|
{
|
||||||
|
"prefix": "led_",
|
||||||
|
"field": "board",
|
||||||
|
"values": tuple(
|
||||||
|
str(cfg.board.value) for cfg in BoardConfig._union_options["board"].values()
|
||||||
|
if "led" in cfg.__dataclass_fields__
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": "led_serial_",
|
||||||
|
"field": "led_type",
|
||||||
|
"values": (str(LedType.SERIAL.value),),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": "led_multipin_",
|
||||||
|
"field": "led_type",
|
||||||
|
"values": (str(LedType.MULTIPIN.value),),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": "uwb_",
|
||||||
|
"field": "board",
|
||||||
|
"values": tuple(
|
||||||
|
str(cfg.board.value) for cfg in BoardConfig._union_options["board"].values()
|
||||||
|
if "uwb" in cfg.__dataclass_fields__
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prefix": "uwb_gpio_",
|
||||||
|
"field": "uwb_enable",
|
||||||
|
"values": (True,)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
|
|
||||||
led_type = int(cleaned_data["led_type"])
|
led_type = int(cleaned_data["led_type"])
|
||||||
|
|
||||||
if led_type:
|
if led_type:
|
||||||
required_fields = set(field.name for field in dataclass_fields(LedConfig.ledconfig_types[led_type]))
|
required_fields = set(field.name for field in dataclass_fields(LedConfig.ledconfig_types[led_type]))
|
||||||
else:
|
else:
|
||||||
|
@ -154,7 +208,7 @@ class ConfigLedMessageForm(MeshMessageForm):
|
||||||
"led_type": led_type
|
"led_type": led_type
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, value in cleaned_data.items():
|
"""for key, value in cleaned_data.items():
|
||||||
if key == "recipients":
|
if key == "recipients":
|
||||||
continue
|
continue
|
||||||
if value and key not in required_fields:
|
if value and key not in required_fields:
|
||||||
|
@ -164,7 +218,7 @@ class ConfigLedMessageForm(MeshMessageForm):
|
||||||
value = cleaned_data.pop(key, "")
|
value = cleaned_data.pop(key, "")
|
||||||
if value == "":
|
if value == "":
|
||||||
errors[key] = _("this field is required for this LED type")
|
errors[key] = _("this field is required for this LED type")
|
||||||
led_config[key] = value
|
led_config[key] = value"""
|
||||||
|
|
||||||
cleaned_data["led_config"] = led_config
|
cleaned_data["led_config"] = led_config
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ class BoardType(IntEnum):
|
||||||
@dataclass
|
@dataclass
|
||||||
class ConfigBoardMessage(MeshMessage, msg_id=MeshMessageType.CONFIG_BOARD):
|
class ConfigBoardMessage(MeshMessage, msg_id=MeshMessageType.CONFIG_BOARD):
|
||||||
""" set/respond board config """
|
""" set/respond board config """
|
||||||
board_config: BoardConfig = field(metadata={"c_embed": True})
|
board_config: BoardConfig = field(metadata={"c_embed": True, "json_embed": True})
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue