simo 2.4.1__py3-none-any.whl → 2.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simo might be problematic. Click here for more details.
- simo/backups/__pycache__/admin.cpython-38.pyc +0 -0
- simo/backups/__pycache__/models.cpython-38.pyc +0 -0
- simo/backups/__pycache__/tasks.cpython-38.pyc +0 -0
- simo/backups/admin.py +10 -13
- simo/backups/migrations/0003_alter_backuplog_options_alter_backup_size.py +22 -0
- simo/backups/migrations/0004_alter_backup_options_alter_backuplog_options_and_more.py +29 -0
- simo/backups/migrations/__pycache__/0003_alter_backuplog_options_alter_backup_size.cpython-38.pyc +0 -0
- simo/backups/migrations/__pycache__/0004_alter_backup_options_alter_backuplog_options_and_more.cpython-38.pyc +0 -0
- simo/backups/models.py +1 -7
- simo/backups/tasks.py +221 -145
- simo/core/__pycache__/admin.cpython-38.pyc +0 -0
- simo/core/__pycache__/api.cpython-38.pyc +0 -0
- simo/core/__pycache__/app_widgets.cpython-38.pyc +0 -0
- simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/core/__pycache__/events.cpython-38.pyc +0 -0
- simo/core/__pycache__/forms.cpython-38.pyc +0 -0
- simo/core/__pycache__/middleware.cpython-38.pyc +0 -0
- simo/core/__pycache__/models.cpython-38.pyc +0 -0
- simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
- simo/core/admin.py +4 -4
- simo/core/api.py +20 -4
- simo/core/app_widgets.py +5 -0
- simo/core/controllers.py +2 -2
- simo/core/events.py +2 -0
- simo/core/forms.py +2 -0
- simo/core/management/commands/gateways_manager.py +0 -3
- simo/core/middleware.py +7 -1
- simo/core/migrations/0042_alter_instance_timezone.py +18 -0
- simo/core/migrations/__pycache__/0042_alter_instance_timezone.cpython-38.pyc +0 -0
- simo/core/models.py +26 -6
- simo/core/serializers.py +17 -17
- simo/core/tasks.py +10 -7
- simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
- simo/fleet/controllers.py +86 -22
- simo/fleet/forms.py +224 -185
- simo/fleet/migrations/0038_alter_colonel_type.py +18 -0
- simo/fleet/migrations/0039_auto_20241016_1047.py +28 -0
- simo/fleet/migrations/0040_alter_colonel_pwm_frequency.py +18 -0
- simo/fleet/migrations/__pycache__/0038_alter_colonel_type.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0039_auto_20241016_1047.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0040_alter_colonel_pwm_frequency.cpython-38.pyc +0 -0
- simo/fleet/models.py +2 -2
- simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
- simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/generic/__pycache__/models.cpython-38.pyc +0 -0
- simo/generic/controllers.py +41 -2
- simo/generic/forms.py +71 -7
- simo/generic/models.py +0 -1
- simo/generic/scripting/__init__.py +16 -0
- simo/generic/scripting/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/generic/scripting/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/generic/scripting/helpers.py +35 -0
- simo/generic/scripting/serializers.py +77 -0
- simo/generic/templates/admin/controller_widgets/weather_forecast.html +2 -2
- simo/notifications/__pycache__/models.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/utils.cpython-38.pyc +0 -0
- simo/notifications/utils.py +30 -12
- simo/scripting.py +2 -2
- simo/users/__pycache__/api.cpython-38.pyc +0 -0
- simo/users/__pycache__/managers.cpython-38.pyc +0 -0
- simo/users/__pycache__/models.cpython-38.pyc +0 -0
- simo/users/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/users/__pycache__/utils.cpython-38.pyc +0 -0
- simo/users/api.py +36 -7
- simo/users/managers.py +5 -1
- simo/users/migrations/0033_alter_user_ssh_key.py +18 -0
- simo/users/migrations/0034_instanceuser_last_seen_location_and_more.py +24 -0
- simo/users/migrations/__pycache__/0033_alter_user_ssh_key.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0034_instanceuser_last_seen_location_and_more.cpython-38.pyc +0 -0
- simo/users/models.py +37 -32
- simo/users/serializers.py +11 -8
- simo/users/utils.py +14 -3
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/METADATA +1 -1
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/RECORD +82 -59
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/WHEEL +1 -1
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/LICENSE.md +0 -0
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/entry_points.txt +0 -0
- {simo-2.4.1.dist-info → simo-2.5.1.dist-info}/top_level.txt +0 -0
simo/fleet/forms.py
CHANGED
|
@@ -195,17 +195,15 @@ class ControlForm(forms.Form):
|
|
|
195
195
|
|
|
196
196
|
|
|
197
197
|
class ColonelBinarySensorConfigForm(ColonelComponentForm):
|
|
198
|
-
pin =
|
|
198
|
+
pin = Select2ModelChoiceField(
|
|
199
199
|
label='Port',
|
|
200
200
|
queryset=ColonelPin.objects.filter(input=True),
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
forward
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
]
|
|
208
|
-
)
|
|
201
|
+
url='autocomplete-colonel-pins',
|
|
202
|
+
forward=[
|
|
203
|
+
forward.Self(),
|
|
204
|
+
forward.Field('colonel'),
|
|
205
|
+
forward.Const({'input': True}, 'filters')
|
|
206
|
+
]
|
|
209
207
|
)
|
|
210
208
|
inverse = forms.TypedChoiceField(
|
|
211
209
|
choices=((1, "Yes"), (0, "No")), coerce=int, initial=1,
|
|
@@ -283,17 +281,15 @@ class ColonelBinarySensorConfigForm(ColonelComponentForm):
|
|
|
283
281
|
|
|
284
282
|
|
|
285
283
|
class ColonelButtonConfigForm(ColonelComponentForm):
|
|
286
|
-
pin =
|
|
284
|
+
pin = Select2ModelChoiceField(
|
|
287
285
|
label="Port",
|
|
288
286
|
queryset=ColonelPin.objects.filter(input=True),
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
forward
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
]
|
|
296
|
-
)
|
|
287
|
+
url='autocomplete-colonel-pins',
|
|
288
|
+
forward=[
|
|
289
|
+
forward.Self(),
|
|
290
|
+
forward.Field('colonel'),
|
|
291
|
+
forward.Const({'input': True}, 'filters')
|
|
292
|
+
]
|
|
297
293
|
)
|
|
298
294
|
action_method = forms.ChoiceField(
|
|
299
295
|
label="Action method", initial='down',
|
|
@@ -322,19 +318,17 @@ class ColonelButtonConfigForm(ColonelComponentForm):
|
|
|
322
318
|
|
|
323
319
|
|
|
324
320
|
class ColonelNumericSensorConfigForm(ColonelComponentForm, NumericSensorForm):
|
|
325
|
-
pin =
|
|
321
|
+
pin = Select2ModelChoiceField(
|
|
326
322
|
label="Port",
|
|
327
323
|
queryset=ColonelPin.objects.filter(adc=True, input=True, native=True),
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
forward
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
]
|
|
337
|
-
)
|
|
324
|
+
url='autocomplete-colonel-pins',
|
|
325
|
+
forward=[
|
|
326
|
+
forward.Self(),
|
|
327
|
+
forward.Field('colonel'),
|
|
328
|
+
forward.Const(
|
|
329
|
+
{'adc': True, 'native': True, 'input': True}, 'filters'
|
|
330
|
+
)
|
|
331
|
+
]
|
|
338
332
|
)
|
|
339
333
|
attenuation = forms.TypedChoiceField(
|
|
340
334
|
initial=0, coerce=int, choices=(
|
|
@@ -375,19 +369,17 @@ class ColonelNumericSensorConfigForm(ColonelComponentForm, NumericSensorForm):
|
|
|
375
369
|
|
|
376
370
|
|
|
377
371
|
class DS18B20SensorConfigForm(ColonelComponentForm, NumericSensorForm):
|
|
378
|
-
pin =
|
|
372
|
+
pin = Select2ModelChoiceField(
|
|
379
373
|
label="Port",
|
|
380
374
|
queryset=ColonelPin.objects.filter(input=True, native=True),
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
forward
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
]
|
|
390
|
-
)
|
|
375
|
+
url='autocomplete-colonel-pins',
|
|
376
|
+
forward=[
|
|
377
|
+
forward.Self(),
|
|
378
|
+
forward.Field('colonel'),
|
|
379
|
+
forward.Const(
|
|
380
|
+
{'native': True, 'input': True}, 'filters'
|
|
381
|
+
)
|
|
382
|
+
]
|
|
391
383
|
)
|
|
392
384
|
read_frequency_s = forms.IntegerField(
|
|
393
385
|
initial=60, min_value=1, max_value=60*60*24,
|
|
@@ -415,19 +407,17 @@ class DS18B20SensorConfigForm(ColonelComponentForm, NumericSensorForm):
|
|
|
415
407
|
|
|
416
408
|
|
|
417
409
|
class ColonelDHTSensorConfigForm(ColonelComponentForm):
|
|
418
|
-
pin =
|
|
410
|
+
pin = Select2ModelChoiceField(
|
|
419
411
|
label="Port",
|
|
420
412
|
queryset=ColonelPin.objects.filter(input=True, native=True),
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
forward
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
]
|
|
430
|
-
)
|
|
413
|
+
url='autocomplete-colonel-pins',
|
|
414
|
+
forward=[
|
|
415
|
+
forward.Self(),
|
|
416
|
+
forward.Field('colonel'),
|
|
417
|
+
forward.Const(
|
|
418
|
+
{'native': True, 'input': True}, 'filters'
|
|
419
|
+
)
|
|
420
|
+
]
|
|
431
421
|
)
|
|
432
422
|
sensor_type = forms.TypedChoiceField(
|
|
433
423
|
initial=11, coerce=int, choices=(
|
|
@@ -462,18 +452,16 @@ class ColonelDHTSensorConfigForm(ColonelComponentForm):
|
|
|
462
452
|
|
|
463
453
|
|
|
464
454
|
class BME680SensorConfigForm(ColonelComponentForm):
|
|
465
|
-
interface =
|
|
455
|
+
interface = Select2ModelChoiceField(
|
|
466
456
|
queryset=Interface.objects.filter(type='i2c'),
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
forward
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
]
|
|
476
|
-
)
|
|
457
|
+
url='autocomplete-interfaces',
|
|
458
|
+
forward=[
|
|
459
|
+
forward.Self(),
|
|
460
|
+
forward.Field('colonel'),
|
|
461
|
+
forward.Const(
|
|
462
|
+
{'type': 'i2c'}, 'filters'
|
|
463
|
+
)
|
|
464
|
+
]
|
|
477
465
|
)
|
|
478
466
|
i2c_address = forms.TypedChoiceField(
|
|
479
467
|
coerce=int, initial=118,
|
|
@@ -511,18 +499,16 @@ class BME680SensorConfigForm(ColonelComponentForm):
|
|
|
511
499
|
|
|
512
500
|
|
|
513
501
|
class MPC9808SensorConfigForm(ColonelComponentForm):
|
|
514
|
-
interface =
|
|
502
|
+
interface = Select2ModelChoiceField(
|
|
515
503
|
queryset=Interface.objects.filter(type='i2c'),
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
forward
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
]
|
|
525
|
-
)
|
|
504
|
+
url='autocomplete-interfaces',
|
|
505
|
+
forward=[
|
|
506
|
+
forward.Self(),
|
|
507
|
+
forward.Field('colonel'),
|
|
508
|
+
forward.Const(
|
|
509
|
+
{'type': 'i2c'}, 'filters'
|
|
510
|
+
)
|
|
511
|
+
]
|
|
526
512
|
)
|
|
527
513
|
i2c_address = forms.TypedChoiceField(
|
|
528
514
|
coerce=int, initial=24,
|
|
@@ -566,18 +552,16 @@ class MPC9808SensorConfigForm(ColonelComponentForm):
|
|
|
566
552
|
|
|
567
553
|
|
|
568
554
|
class ENS160SensorConfigForm(ColonelComponentForm):
|
|
569
|
-
interface =
|
|
555
|
+
interface = Select2ModelChoiceField(
|
|
570
556
|
queryset=Interface.objects.filter(type='i2c'),
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
forward
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
]
|
|
580
|
-
)
|
|
557
|
+
url='autocomplete-interfaces',
|
|
558
|
+
forward=[
|
|
559
|
+
forward.Self(),
|
|
560
|
+
forward.Field('colonel'),
|
|
561
|
+
forward.Const(
|
|
562
|
+
{'type': 'i2c'}, 'filters'
|
|
563
|
+
)
|
|
564
|
+
]
|
|
581
565
|
)
|
|
582
566
|
i2c_address = forms.TypedChoiceField(
|
|
583
567
|
coerce=int, initial=83,
|
|
@@ -616,17 +600,15 @@ class ENS160SensorConfigForm(ColonelComponentForm):
|
|
|
616
600
|
|
|
617
601
|
|
|
618
602
|
class ColonelTouchSensorConfigForm(ColonelComponentForm):
|
|
619
|
-
pin =
|
|
603
|
+
pin = Select2ModelChoiceField(
|
|
620
604
|
label="Port",
|
|
621
605
|
queryset=ColonelPin.objects.filter(input=True, capacitive=True),
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
forward
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
]
|
|
629
|
-
)
|
|
606
|
+
url='autocomplete-colonel-pins',
|
|
607
|
+
forward=[
|
|
608
|
+
forward.Self(),
|
|
609
|
+
forward.Field('colonel'),
|
|
610
|
+
forward.Const({'input': True, 'capacitive': True}, 'filters')
|
|
611
|
+
]
|
|
630
612
|
)
|
|
631
613
|
threshold = forms.IntegerField(
|
|
632
614
|
min_value=0, max_value=999999999, required=False, initial=1000,
|
|
@@ -740,17 +722,15 @@ class ColonelSwitchConfigForm(ColonelComponentForm):
|
|
|
740
722
|
|
|
741
723
|
|
|
742
724
|
class ColonelPWMOutputConfigForm(ColonelComponentForm):
|
|
743
|
-
output_pin =
|
|
725
|
+
output_pin = Select2ModelChoiceField(
|
|
744
726
|
label="Port",
|
|
745
727
|
queryset=ColonelPin.objects.filter(output=True),
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
forward
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
]
|
|
753
|
-
)
|
|
728
|
+
url='autocomplete-colonel-pins',
|
|
729
|
+
forward=[
|
|
730
|
+
forward.Self(),
|
|
731
|
+
forward.Field('colonel'),
|
|
732
|
+
forward.Const({'output': True}, 'filters')
|
|
733
|
+
]
|
|
754
734
|
)
|
|
755
735
|
min = forms.FloatField(
|
|
756
736
|
required=True, initial=0,
|
|
@@ -761,14 +741,21 @@ class ColonelPWMOutputConfigForm(ColonelComponentForm):
|
|
|
761
741
|
help_text="Maximum component value"
|
|
762
742
|
)
|
|
763
743
|
value_units = forms.CharField(required=False)
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
744
|
+
|
|
745
|
+
device_min = forms.IntegerField(
|
|
746
|
+
label="Device minimum (%).",
|
|
747
|
+
help_text="Device will turn off once it reaches this internal value. "
|
|
748
|
+
"Usually it is a good idea to "
|
|
749
|
+
"set this somewhere in between of 5 - 15 %. ",
|
|
750
|
+
initial=10, min_value=0, max_value=100,
|
|
767
751
|
)
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
help_text="
|
|
752
|
+
device_max = forms.IntegerField(
|
|
753
|
+
label="Device maximum (%).",
|
|
754
|
+
help_text="Can be used to prevent reaching maximum values. "
|
|
755
|
+
"Default is 100%",
|
|
756
|
+
initial=100, min_value=0, max_value=100,
|
|
771
757
|
)
|
|
758
|
+
|
|
772
759
|
turn_on_time = forms.IntegerField(
|
|
773
760
|
min_value=0, max_value=60000, initial=1000,
|
|
774
761
|
help_text="Turn on speed in ms. 1500 is a great quick default. "
|
|
@@ -783,9 +770,6 @@ class ColonelPWMOutputConfigForm(ColonelComponentForm):
|
|
|
783
770
|
initial='easeOutSine', choices=EASING_CHOICES,
|
|
784
771
|
help_text="easeOutSine - offers most naturally looking effect."
|
|
785
772
|
)
|
|
786
|
-
inverse = forms.BooleanField(
|
|
787
|
-
label=_("Inverse dimmer signal"), required=False, initial=True
|
|
788
|
-
)
|
|
789
773
|
on_value = forms.FloatField(
|
|
790
774
|
required=True, initial=100,
|
|
791
775
|
help_text="ON value when used with toggle switch"
|
|
@@ -874,18 +858,81 @@ class ColonelPWMOutputConfigForm(ColonelComponentForm):
|
|
|
874
858
|
return obj
|
|
875
859
|
|
|
876
860
|
|
|
861
|
+
class DCDriverConfigForm(ColonelComponentForm):
|
|
862
|
+
output_pin = Select2ModelChoiceField(
|
|
863
|
+
label="Port",
|
|
864
|
+
queryset=ColonelPin.objects.filter(output=True),
|
|
865
|
+
url='autocomplete-colonel-pins',
|
|
866
|
+
forward=[
|
|
867
|
+
forward.Self(),
|
|
868
|
+
forward.Field('colonel'),
|
|
869
|
+
forward.Const({'output': True}, 'filters')
|
|
870
|
+
]
|
|
871
|
+
)
|
|
872
|
+
min = forms.FloatField(
|
|
873
|
+
required=True, initial=0,
|
|
874
|
+
help_text="Minimum component value displayed to the user."
|
|
875
|
+
)
|
|
876
|
+
max = forms.FloatField(
|
|
877
|
+
required=True, initial=24,
|
|
878
|
+
help_text="Maximum component value displayed to the user."
|
|
879
|
+
)
|
|
880
|
+
value_units = forms.CharField(required=False)
|
|
881
|
+
|
|
882
|
+
device_min = forms.FloatField(
|
|
883
|
+
label="Device minimum Voltage.",
|
|
884
|
+
help_text="This will be the lowest possible voltage value of a device.\n"
|
|
885
|
+
"Don't forget to adjust your component min value accordingly "
|
|
886
|
+
"if you change this.",
|
|
887
|
+
initial=0, min_value=0, max_value=24,
|
|
888
|
+
)
|
|
889
|
+
device_max = forms.IntegerField(
|
|
890
|
+
label="Device maximum Voltage.",
|
|
891
|
+
help_text="Can be set lower than it's natural maximum of 24V. \n"
|
|
892
|
+
"Don't forget to adjust your component max value accordingly "
|
|
893
|
+
"if you change this.",
|
|
894
|
+
initial=24, min_value=0, max_value=24,
|
|
895
|
+
)
|
|
896
|
+
|
|
897
|
+
def clean(self):
|
|
898
|
+
super().clean()
|
|
899
|
+
if 'output_pin' in self.cleaned_data:
|
|
900
|
+
self._clean_pin('output_pin')
|
|
901
|
+
return self.cleaned_data
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
def save(self, commit=True):
|
|
905
|
+
if 'output_pin' in self.cleaned_data:
|
|
906
|
+
self.instance.config['output_pin_no'] = self.cleaned_data['output_pin'].no
|
|
907
|
+
|
|
908
|
+
update_colonel = False
|
|
909
|
+
if not self.instance.pk:
|
|
910
|
+
update_colonel = True
|
|
911
|
+
elif 'output_pin' in self.changed_data:
|
|
912
|
+
update_colonel = True
|
|
913
|
+
|
|
914
|
+
obj = super().save(commit=commit)
|
|
915
|
+
|
|
916
|
+
if not update_colonel:
|
|
917
|
+
GatewayObjectCommand(
|
|
918
|
+
obj.gateway, self.cleaned_data['colonel'], id=obj.id,
|
|
919
|
+
command='call', method='update_config', args=[
|
|
920
|
+
obj.controller._get_colonel_config()
|
|
921
|
+
]
|
|
922
|
+
).publish()
|
|
923
|
+
return obj
|
|
924
|
+
|
|
925
|
+
|
|
877
926
|
class ColonelRGBLightConfigForm(ColonelComponentForm):
|
|
878
|
-
output_pin =
|
|
927
|
+
output_pin = Select2ModelChoiceField(
|
|
879
928
|
label="Port",
|
|
880
929
|
queryset=ColonelPin.objects.filter(output=True, native=True),
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
forward
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
]
|
|
888
|
-
)
|
|
930
|
+
url='autocomplete-colonel-pins',
|
|
931
|
+
forward=[
|
|
932
|
+
forward.Self(),
|
|
933
|
+
forward.Field('colonel'),
|
|
934
|
+
forward.Const({'output': True, 'native': True}, 'filters')
|
|
935
|
+
]
|
|
889
936
|
)
|
|
890
937
|
num_leds = forms.IntegerField(
|
|
891
938
|
label=_("Number of leds"), min_value=1, max_value=2000
|
|
@@ -998,17 +1045,15 @@ class ColonelRGBLightConfigForm(ColonelComponentForm):
|
|
|
998
1045
|
|
|
999
1046
|
|
|
1000
1047
|
class DualMotorValveForm(ColonelComponentForm):
|
|
1001
|
-
open_pin =
|
|
1048
|
+
open_pin = Select2ModelChoiceField(
|
|
1002
1049
|
label="Open Relay Port",
|
|
1003
1050
|
queryset=ColonelPin.objects.filter(output=True),
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
forward
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
]
|
|
1011
|
-
)
|
|
1051
|
+
url='autocomplete-colonel-pins',
|
|
1052
|
+
forward=[
|
|
1053
|
+
forward.Self(),
|
|
1054
|
+
forward.Field('colonel'),
|
|
1055
|
+
forward.Const({'output': True}, 'filters')
|
|
1056
|
+
]
|
|
1012
1057
|
)
|
|
1013
1058
|
open_action = forms.ChoiceField(
|
|
1014
1059
|
choices=(('HIGH', "HIGH"), ('LOW', "LOW")),
|
|
@@ -1017,17 +1062,15 @@ class DualMotorValveForm(ColonelComponentForm):
|
|
|
1017
1062
|
required=True, min_value=0.01, max_value=1000000000,
|
|
1018
1063
|
initial=2, help_text="Time in seconds to open."
|
|
1019
1064
|
)
|
|
1020
|
-
close_pin =
|
|
1065
|
+
close_pin = Select2ModelChoiceField(
|
|
1021
1066
|
label="Close Relay Port",
|
|
1022
1067
|
queryset=ColonelPin.objects.filter(output=True),
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
forward
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
]
|
|
1030
|
-
)
|
|
1068
|
+
url='autocomplete-colonel-pins',
|
|
1069
|
+
forward=[
|
|
1070
|
+
forward.Self(),
|
|
1071
|
+
forward.Field('colonel'),
|
|
1072
|
+
forward.Const({'output': True}, 'filters')
|
|
1073
|
+
]
|
|
1031
1074
|
)
|
|
1032
1075
|
close_action = forms.ChoiceField(
|
|
1033
1076
|
choices=(('HIGH', "HIGH"), ('LOW', "LOW")),
|
|
@@ -1036,6 +1079,12 @@ class DualMotorValveForm(ColonelComponentForm):
|
|
|
1036
1079
|
required=True, min_value=0.01, max_value=1000000000,
|
|
1037
1080
|
initial=10, help_text="Time in seconds to close."
|
|
1038
1081
|
)
|
|
1082
|
+
min = forms.FloatField(
|
|
1083
|
+
label="Minimum displayed value", required=True, initial=0
|
|
1084
|
+
)
|
|
1085
|
+
max = forms.FloatField(
|
|
1086
|
+
label="Maximum displayed value", required=True, initial=100
|
|
1087
|
+
)
|
|
1039
1088
|
|
|
1040
1089
|
|
|
1041
1090
|
def clean(self):
|
|
@@ -1064,32 +1113,28 @@ class DualMotorValveForm(ColonelComponentForm):
|
|
|
1064
1113
|
|
|
1065
1114
|
|
|
1066
1115
|
class BlindsConfigForm(ColonelComponentForm):
|
|
1067
|
-
open_pin =
|
|
1116
|
+
open_pin = Select2ModelChoiceField(
|
|
1068
1117
|
label="Open Relay Port",
|
|
1069
1118
|
queryset=ColonelPin.objects.filter(output=True),
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
forward
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
]
|
|
1077
|
-
)
|
|
1119
|
+
url='autocomplete-colonel-pins',
|
|
1120
|
+
forward=[
|
|
1121
|
+
forward.Self(),
|
|
1122
|
+
forward.Field('colonel'),
|
|
1123
|
+
forward.Const({'output': True}, 'filters')
|
|
1124
|
+
]
|
|
1078
1125
|
)
|
|
1079
1126
|
open_action = forms.ChoiceField(
|
|
1080
1127
|
choices=(('HIGH', "HIGH"), ('LOW', "LOW")),
|
|
1081
1128
|
)
|
|
1082
|
-
close_pin =
|
|
1129
|
+
close_pin = Select2ModelChoiceField(
|
|
1083
1130
|
label="Close Relay Port",
|
|
1084
1131
|
queryset=ColonelPin.objects.filter(output=True),
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
forward
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
]
|
|
1092
|
-
)
|
|
1132
|
+
url='autocomplete-colonel-pins',
|
|
1133
|
+
forward=[
|
|
1134
|
+
forward.Self(),
|
|
1135
|
+
forward.Field('colonel'),
|
|
1136
|
+
forward.Const({'output': True}, 'filters')
|
|
1137
|
+
]
|
|
1093
1138
|
)
|
|
1094
1139
|
close_action = forms.ChoiceField(
|
|
1095
1140
|
choices=(('HIGH', "HIGH"), ('LOW', "LOW")),
|
|
@@ -1212,29 +1257,25 @@ class BlindsConfigForm(ColonelComponentForm):
|
|
|
1212
1257
|
|
|
1213
1258
|
|
|
1214
1259
|
class BurglarSmokeDetectorConfigForm(ColonelComponentForm):
|
|
1215
|
-
power_pin =
|
|
1260
|
+
power_pin = Select2ModelChoiceField(
|
|
1216
1261
|
label="Power port",
|
|
1217
1262
|
queryset=ColonelPin.objects.filter(output=True),
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
forward
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
]
|
|
1225
|
-
)
|
|
1263
|
+
url='autocomplete-colonel-pins',
|
|
1264
|
+
forward=[
|
|
1265
|
+
forward.Self(),
|
|
1266
|
+
forward.Field('colonel'),
|
|
1267
|
+
forward.Const({'output': True}, 'filters')
|
|
1268
|
+
]
|
|
1226
1269
|
)
|
|
1227
|
-
sensor_pin =
|
|
1270
|
+
sensor_pin = Select2ModelChoiceField(
|
|
1228
1271
|
label="Sensor port",
|
|
1229
1272
|
queryset=ColonelPin.objects.filter(input=True),
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
forward
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
]
|
|
1237
|
-
)
|
|
1273
|
+
url='autocomplete-colonel-pins',
|
|
1274
|
+
forward=[
|
|
1275
|
+
forward.Self(),
|
|
1276
|
+
forward.Field('colonel'),
|
|
1277
|
+
forward.Const({'input': True}, 'filters')
|
|
1278
|
+
]
|
|
1238
1279
|
)
|
|
1239
1280
|
sensor_inverse = forms.TypedChoiceField(
|
|
1240
1281
|
choices=((0, "No"), (1, "Yes")), coerce=int, initial=0,
|
|
@@ -1306,18 +1347,16 @@ class TTLockConfigForm(ColonelComponentForm):
|
|
|
1306
1347
|
|
|
1307
1348
|
|
|
1308
1349
|
class DALIDeviceConfigForm(ColonelComponentForm):
|
|
1309
|
-
interface =
|
|
1350
|
+
interface = Select2ModelChoiceField(
|
|
1310
1351
|
queryset=Interface.objects.filter(type='dali'),
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
forward
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
]
|
|
1320
|
-
)
|
|
1352
|
+
url='autocomplete-interfaces',
|
|
1353
|
+
forward=[
|
|
1354
|
+
forward.Self(),
|
|
1355
|
+
forward.Field('colonel'),
|
|
1356
|
+
forward.Const(
|
|
1357
|
+
{'type': 'dali'}, 'filters'
|
|
1358
|
+
)
|
|
1359
|
+
]
|
|
1321
1360
|
)
|
|
1322
1361
|
|
|
1323
1362
|
def clean_interface(self):
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 4.2.10 on 2024-10-09 09:16
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('fleet', '0037_alter_colonelpin_options_alter_colonelpin_no_and_more'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='colonel',
|
|
15
|
+
name='type',
|
|
16
|
+
field=models.CharField(choices=[('4-relays', '4 Relay'), ('ample-wall', 'Ample Wall'), ('game-changer', 'Game Changer'), ('game-changer-mini', 'Game Changer Mini')], default='ample-wall', max_length=20),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Generated by Django 4.2.10 on 2024-10-16 10:47
|
|
2
|
+
from django.db import migrations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def forwards_func(apps, schema_editor):
|
|
6
|
+
Component = apps.get_model("core", "Component")
|
|
7
|
+
|
|
8
|
+
for comp in Component.objects.filter(controller_uid='simo.fleet.controllers.PWMOutput'):
|
|
9
|
+
duty_min = comp.config.get('duty_min', 0)
|
|
10
|
+
duty_max = comp.config.get('duty_max', 1023)
|
|
11
|
+
comp.config['device_min'] = int((1023 - duty_max) / 1023 * 100)
|
|
12
|
+
comp.config['device_max'] = int(100 - (duty_min / 1023 * 100))
|
|
13
|
+
comp.save()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def reverse_func(apps, schema_editor):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Migration(migrations.Migration):
|
|
21
|
+
|
|
22
|
+
dependencies = [
|
|
23
|
+
('fleet', '0038_alter_colonel_type'),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
operations = [
|
|
27
|
+
migrations.RunPython(forwards_func, reverse_func, elidable=True),
|
|
28
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 4.2.10 on 2024-10-18 08:00
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('fleet', '0039_auto_20241016_1047'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='colonel',
|
|
15
|
+
name='pwm_frequency',
|
|
16
|
+
field=models.IntegerField(choices=[(0, '3kHz'), (1, '22kHz')], default=0, help_text='Affects Ample Wall dimmer PWM output (dimmer) frequency'),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
Binary file
|
|
Binary file
|