add possibility to set LED_CONFIG message
This commit is contained in:
parent
c5ac3ceb76
commit
e0961c16c1
5 changed files with 137 additions and 36 deletions
|
@ -17,19 +17,41 @@
|
|||
</div>
|
||||
<div>
|
||||
<h4>Uplink</h4>
|
||||
<strong>Enabled:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.enabled }},
|
||||
<strong>SSID:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.ssid }},
|
||||
<strong>Channel:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.channel }}<br>
|
||||
<strong>Host:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.host }},
|
||||
<strong>Port:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.port }},
|
||||
<strong>UDP:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.udp }},
|
||||
<strong>SSL:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.ssl }}
|
||||
<p>
|
||||
<strong>Enabled:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.enabled }},
|
||||
<strong>SSID:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.ssid }},
|
||||
<strong>Channel:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.channel }}<br>
|
||||
<strong>Host:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.host }},
|
||||
<strong>Port:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.port }},
|
||||
<strong>UDP:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.udp }},
|
||||
<strong>SSL:</strong> {{ node.last_messages.CONFIG_UPLINK.parsed.ssl }}<br>
|
||||
</p>
|
||||
<p>
|
||||
<a class="button" href="{% url "control.mesh_message.send" recipient=node.address msg_type="CONFIG_UPLINK" %}">
|
||||
{% trans 'Change' %}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
<h4>Position</h4>
|
||||
<strong>X=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.x_pos }}, <strong>Y=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.y_pos }}, <strong>Z=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.z_pos }}
|
||||
<p>
|
||||
<strong>X=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.x_pos }}, <strong>Y=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.y_pos }}, <strong>Z=</strong>{{ node.last_messages.CONFIG_POSITION.parsed.z_pos }}
|
||||
</p>
|
||||
<p>
|
||||
<a class="button" href="{% url "control.mesh_message.send" recipient=node.address msg_type="CONFIG_POSITION" %}">
|
||||
{% trans 'Change' %}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h4>LED config</h4>
|
||||
{{ node.last_messages.CONFIG_LED.parsed.led_config }}
|
||||
<p>
|
||||
{{ node.last_messages.CONFIG_LED.parsed.led_config }}
|
||||
</p>
|
||||
<p>
|
||||
<a class="button" href="{% url "control.mesh_message.send" recipient=node.address msg_type="CONFIG_LED" %}">
|
||||
{% trans 'Change' %}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -109,7 +109,7 @@ class MeshConsumer(WebsocketConsumer):
|
|||
def add_dst_nodes(self, addresses):
|
||||
for address in addresses:
|
||||
# create group name for this address
|
||||
group = self.comm_address_group(address)
|
||||
group = get_mesh_comm_group(address)
|
||||
|
||||
# if we aren't handling this address yet, join the group
|
||||
if address not in self.dst_nodes:
|
||||
|
@ -140,7 +140,7 @@ class MeshConsumer(WebsocketConsumer):
|
|||
def remove_dst_nodes(self, addresses):
|
||||
for address in tuple(addresses):
|
||||
# create group name for this address
|
||||
group = self.comm_address_group(address)
|
||||
group = get_mesh_comm_group(address)
|
||||
|
||||
# leave the group
|
||||
if address in self.dst_nodes:
|
||||
|
|
|
@ -138,14 +138,3 @@ class LedConfigFormat:
|
|||
else:
|
||||
raise ValueError
|
||||
return value, data[4:]
|
||||
|
||||
def from_json(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
type_ = value.pop('type')
|
||||
if type_ == 'serial':
|
||||
return SerialLedConfig(**value)
|
||||
elif type_ == 'multipin':
|
||||
return MultipinLedConfig(**value)
|
||||
raise ValueError
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
from dataclasses import fields as dataclass_fields
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import Http404
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from c3nav.mesh.dataformats import LedConfig
|
||||
from c3nav.mesh.messages import MeshMessageType, MeshMessage, ROOT_ADDRESS
|
||||
from c3nav.mesh.models import MeshNode
|
||||
|
||||
|
@ -54,6 +58,29 @@ class MeshMessageForm(forms.Form):
|
|||
def get_recipient_display(self):
|
||||
return self.recipient_choices[self.recipient]
|
||||
|
||||
def get_cleaned_msg_data(self):
|
||||
msg_data = self.cleaned_data.copy()
|
||||
msg_data.pop('recipients', None)
|
||||
return msg_data
|
||||
|
||||
def send(self):
|
||||
if not self.is_valid():
|
||||
raise Exception('nope')
|
||||
|
||||
msg_data = {
|
||||
'msg_id': self.msg_type,
|
||||
'src': ROOT_ADDRESS,
|
||||
**self.get_cleaned_msg_data(),
|
||||
}
|
||||
|
||||
recipients = [self.recipient] if self.recipient else self.cleaned_data['recipients']
|
||||
for recipient in recipients:
|
||||
print('sending to ', recipient)
|
||||
MeshMessage.fromjson({
|
||||
'dst': recipient,
|
||||
**msg_data,
|
||||
}).send()
|
||||
|
||||
|
||||
class ConfigUplinkMessageForm(MeshMessageForm):
|
||||
msg_type = MeshMessageType.CONFIG_UPLINK
|
||||
|
@ -67,20 +94,76 @@ class ConfigUplinkMessageForm(MeshMessageForm):
|
|||
host = forms.CharField(required=False, label=_('host'), max_length=63)
|
||||
port = forms.IntegerField(min_value=1, max_value=65535, label=_('port'))
|
||||
|
||||
def send(self):
|
||||
if not self.is_valid():
|
||||
raise Exception('nope')
|
||||
|
||||
msg_data = {
|
||||
'msg_id': self.msg_type,
|
||||
'src': ROOT_ADDRESS,
|
||||
**self.cleaned_data,
|
||||
class ConfigLedMessageForm(MeshMessageForm):
|
||||
msg_type = MeshMessageType.CONFIG_LED
|
||||
|
||||
led_type = forms.ChoiceField(choices=(
|
||||
('', _('no LED')),
|
||||
(1, _('serial LED')),
|
||||
(2, _('multipin LED'))
|
||||
))
|
||||
gpio = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||
label=_('gpio pin'), help_text=_('serial only'))
|
||||
rmt = forms.IntegerField(min_value=0, max_value=7, required=False,
|
||||
label=_('rmt'), help_text=_('serial only'))
|
||||
gpio_r = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||
label=_('gpio red'), help_text=_('multipin only'))
|
||||
gpio_g = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||
label=_('gpio green'), help_text=_('multipin only'))
|
||||
gpio_b = forms.IntegerField(min_value=0, max_value=48, required=False,
|
||||
label=_('gpio blue'), help_text=_('multipin only'))
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
led_type = int(cleaned_data["led_type"])
|
||||
if led_type:
|
||||
required_fields = set(field.name for field in dataclass_fields(LedConfig.ledconfig_types[led_type]))
|
||||
else:
|
||||
required_fields = set()
|
||||
|
||||
errors = {}
|
||||
led_config = {
|
||||
"led_type": led_type
|
||||
}
|
||||
|
||||
recipients = [self.recipient] if self.recipient else self.cleaned_data['recipients']
|
||||
for recipient in recipients:
|
||||
print('sending to ', recipient)
|
||||
MeshMessage.fromjson({
|
||||
'dst': recipient,
|
||||
**msg_data,
|
||||
}).send()
|
||||
for key, value in cleaned_data.items():
|
||||
if key == "recipients":
|
||||
continue
|
||||
if value and key not in required_fields:
|
||||
errors[key] = _("this field is not allowed for this LED type")
|
||||
|
||||
for key in required_fields:
|
||||
value = cleaned_data.pop(key, "")
|
||||
if value == "":
|
||||
errors[key] = _("this field is required for this LED type")
|
||||
led_config[key] = value
|
||||
|
||||
cleaned_data["led_config"] = led_config
|
||||
|
||||
if errors:
|
||||
raise ValidationError(errors)
|
||||
|
||||
return cleaned_data
|
||||
|
||||
def get_cleaned_msg_data(self):
|
||||
msg_data = super().get_cleaned_msg_data().copy()
|
||||
msg_data = {
|
||||
"led_config": msg_data["led_config"],
|
||||
}
|
||||
return msg_data
|
||||
|
||||
def __init__(self, *args, initial=None, **kwargs):
|
||||
if initial:
|
||||
initial.update(initial.pop('led_config'))
|
||||
super().__init__(*args, initial=initial, **kwargs)
|
||||
|
||||
|
||||
class ConfigPositionMessageForm(MeshMessageForm):
|
||||
msg_type = MeshMessageType.CONFIG_POSITION
|
||||
|
||||
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'))
|
||||
|
||||
|
|
|
@ -1351,3 +1351,10 @@ button + button {
|
|||
.material-icons {
|
||||
text-transform: none !important;
|
||||
}
|
||||
|
||||
.helptext {
|
||||
display: block;
|
||||
margin-top: -1.5rem;
|
||||
font-style: italic;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue