simo 2.10.9__py3-none-any.whl → 2.10.11__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/fleet/controllers.py CHANGED
@@ -23,7 +23,7 @@ from .gateways import FleetGatewayHandler
23
23
  from .forms import (
24
24
  ColonelPinChoiceField,
25
25
  ColonelBinarySensorConfigForm, ColonelButtonConfigForm,
26
- ColonelSwitchConfigForm, ColonelPWMOutputConfigForm, DCDriverConfigForm,
26
+ ColonelSwitchConfigForm, ColonelPWMOutputConfigForm, DC10VConfigForm,
27
27
  ColonelNumericSensorConfigForm, ColonelRGBLightConfigForm,
28
28
  ColonelDHTSensorConfigForm, DS18B20SensorConfigForm,
29
29
  BME680SensorConfigForm, MCP9808SensorConfigForm, ENS160SensorConfigForm,
@@ -314,7 +314,7 @@ class FadeMixin:
314
314
 
315
315
 
316
316
  class PWMOutput(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
317
- name = "Dimmer"
317
+ name = "AC/DC Dimmer | PWM Driver"
318
318
  config_form = ColonelPWMOutputConfigForm
319
319
 
320
320
  def _prepare_for_send(self, value):
@@ -344,7 +344,7 @@ class PWMOutput(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
344
344
 
345
345
  def _prepare_for_set(self, pwm_value):
346
346
  conf = self.component.config
347
- duty_max = 1023 - (conf.get('device_min', 0) * 0.01 * 1023)
347
+ duty_max = 1023 - conf.get('device_min', 0) * 0.01 * 1023
348
348
  duty_min = 1023 - conf.get('device_max', 100) * 0.01 * 1023
349
349
 
350
350
  if pwm_value > duty_max:
@@ -352,7 +352,7 @@ class PWMOutput(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
352
352
  elif pwm_value < duty_min:
353
353
  value = conf.get('min', 0)
354
354
  else:
355
- pwm_amplitude =duty_max - duty_min
355
+ pwm_amplitude = duty_max - duty_min
356
356
  relative_value = (pwm_value - duty_min) / pwm_amplitude
357
357
  val_amplitude = conf.get('max', 100) - conf.get('min', 0)
358
358
  value = conf.get('min', 0) + val_amplitude * relative_value
@@ -362,47 +362,61 @@ class PWMOutput(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
362
362
  return round(value, 3)
363
363
 
364
364
 
365
- class DCDriver(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
366
- name = "0 - 24V DC Driver"
367
- config_form = DCDriverConfigForm
368
- default_value_units = 'V'
365
+ class DC10VDriver(FadeMixin, FleeDeviceMixin, BasicOutputMixin, BaseDimmer):
366
+ name = "0 - 10V Driver"
367
+ config_form = DC10VConfigForm
368
+ default_value_units = '%'
369
369
 
370
370
  def _prepare_for_send(self, value):
371
371
  conf = self.component.config
372
- if value >= conf.get('max', 24):
373
- value = conf.get('max', 24)
372
+ if value >= conf.get('max', 100):
373
+ value = conf.get('max', 100)
374
374
  elif value < conf.get('min', 0):
375
375
  value = conf.get('min', 0)
376
376
 
377
- if value >= conf.get('max', 24):
378
- pwm_value = 1023
379
- elif value <= conf.get('min', 100):
380
- pwm_value = 0
377
+ if value >= conf.get('max', 100):
378
+ if conf.get('inverse') == True:
379
+ pwm_value = 0
380
+ else:
381
+ pwm_value = 1023
382
+ elif value <= conf.get('min', 0):
383
+ if conf.get('inverse') == True:
384
+ pwm_value = 1023
385
+ else:
386
+ pwm_value = 0
381
387
  else:
382
- val_amplitude = conf.get('max', 24) - conf.get('min', 0)
388
+ val_amplitude = conf.get('max', 100) - conf.get('min', 0)
383
389
  val_relative = value / val_amplitude
384
390
 
385
- duty_max = conf.get('device_max', 24) / 24 * 1023
386
- duty_min = conf.get('device_min', 0) / 24 * 1023
387
-
388
- pwm_amplitude = duty_max - duty_min
389
- pwm_value = duty_min + pwm_amplitude * val_relative
391
+ if conf.get('inverse') == True:
392
+ duty_max = 1023 - conf.get('device_min', 0) / 10 * 1023
393
+ duty_min = 1023 - conf.get('device_max', 10) / 10 * 1023
394
+ pwm_amplitude = duty_max - duty_min
395
+ pwm_value = duty_min + pwm_amplitude * val_relative
396
+ pwm_value = duty_max - pwm_value + duty_min
397
+ else:
398
+ duty_max = conf.get('device_max', 10) / 10 * 1023
399
+ duty_min = conf.get('device_min', 0) / 10 * 1023
400
+ pwm_amplitude = duty_max - duty_min
401
+ pwm_value = duty_min + pwm_amplitude * val_relative
390
402
 
391
403
  return pwm_value
392
404
 
393
405
  def _prepare_for_set(self, pwm_value):
394
406
  conf = self.component.config
395
- duty_max = conf.get('device_max', 24) / 24 * 1023
396
- duty_min = conf.get('device_min', 0) / 24 * 1023
407
+ if conf.get('inverse') == True:
408
+ pwm_value = 1023 - pwm_value
409
+ duty_max = conf.get('device_max', 10) / 10 * 1023
410
+ duty_min = conf.get('device_min', 0) / 10 * 1023
397
411
 
398
412
  if pwm_value > duty_max:
399
- value = conf.get('max', 24)
413
+ value = conf.get('max', 100)
400
414
  elif pwm_value < duty_min:
401
415
  value = conf.get('min', 0)
402
416
  else:
403
417
  pwm_amplitude = duty_max - duty_min
404
418
  relative_value = (pwm_value - duty_min) / pwm_amplitude
405
- val_amplitude = conf.get('max', 24) - conf.get('min', 0)
419
+ val_amplitude = conf.get('max', 100) - conf.get('min', 0)
406
420
  value = conf.get('min', 0) + val_amplitude * relative_value
407
421
 
408
422
  return round(value, 3)
simo/fleet/forms.py CHANGED
@@ -689,7 +689,75 @@ class ColonelSwitchConfigForm(ColonelComponentForm):
689
689
  return obj
690
690
 
691
691
 
692
- class ColonelPWMOutputConfigForm(ColonelComponentForm):
692
+ class PWMOutputBaseConfig(ColonelComponentForm):
693
+
694
+ def __init__(self, *args, **kwargs):
695
+ super().__init__(*args, **kwargs)
696
+ if 'value_units' in self.fields:
697
+ self.fields['value_units'].initial = self.controller.default_value_units
698
+ self.basic_fields.extend(
699
+ ['value_units', 'turn_on_time', 'turn_off_time', 'skew']
700
+ )
701
+ if self.instance.pk and 'slaves' in self.fields:
702
+ self.fields['slaves'].initial = self.instance.slaves.all()
703
+
704
+ def clean_slaves(self):
705
+ if not self.cleaned_data['slaves'] or not self.instance:
706
+ return self.cleaned_data['slaves']
707
+ return validate_slaves(self.cleaned_data['slaves'], self.instance)
708
+
709
+ def clean(self):
710
+ super().clean()
711
+ if 'output_pin' in self.cleaned_data:
712
+ self._clean_pin('output_pin')
713
+ if 'controls' in self.cleaned_data:
714
+ self._clean_controls()
715
+
716
+ if self.cleaned_data.get('output_pin') and self.cleaned_data.get('controls'):
717
+ for ctrl in self.cleaned_data['controls']:
718
+ if not ctrl['input'].startswith('pin'):
719
+ continue
720
+ if int(ctrl['input'][4:]) == self.cleaned_data['output_pin'].id:
721
+ self.add_error(
722
+ "output_pin",
723
+ "Can't be used as control pin at the same time!"
724
+ )
725
+ return self.cleaned_data
726
+
727
+
728
+ def save(self, commit=True):
729
+ if 'output_pin' in self.cleaned_data:
730
+ self.instance.config['output_pin_no'] = self.cleaned_data['output_pin'].no
731
+
732
+ update_colonel = False
733
+ if not self.instance.pk:
734
+ update_colonel = True
735
+ elif 'output_pin' in self.changed_data:
736
+ update_colonel = True
737
+ elif 'slaves' in self.changed_data:
738
+ update_colonel = True
739
+ if not update_colonel:
740
+ old = Component.objects.get(id=self.instance.id)
741
+ if old.config.get('controls') != self.cleaned_data.get('controls'):
742
+ update_colonel = True
743
+
744
+ obj = super().save(commit=commit)
745
+ if commit and 'slaves' in self.cleaned_data:
746
+ obj.slaves.set(self.cleaned_data['slaves'])
747
+ if not update_colonel:
748
+ GatewayObjectCommand(
749
+ obj.gateway, self.cleaned_data['colonel'], id=obj.id,
750
+ command='call', method='update_config', args=[
751
+ obj.controller._get_colonel_config()
752
+ ]
753
+ ).publish()
754
+ if commit and self.cleaned_data.get('controls'):
755
+ GatewayObjectCommand(
756
+ self.instance.gateway, obj, command='watch_buttons'
757
+ ).publish()
758
+ return obj
759
+
760
+ class ColonelPWMOutputConfigForm(PWMOutputBaseConfig):
693
761
  output_pin = Select2ModelChoiceField(
694
762
  label="Port",
695
763
  queryset=ColonelPin.objects.filter(output=True),
@@ -758,74 +826,8 @@ class ColonelPWMOutputConfigForm(ColonelComponentForm):
758
826
  )
759
827
  )
760
828
 
761
- def __init__(self, *args, **kwargs):
762
- super().__init__(*args, **kwargs)
763
- if 'value_units' in self.fields:
764
- self.fields['value_units'].initial = self.controller.default_value_units
765
- self.basic_fields.extend(
766
- ['value_units', 'turn_on_time', 'turn_off_time', 'skew']
767
- )
768
- if self.instance.pk and 'slaves' in self.fields:
769
- self.fields['slaves'].initial = self.instance.slaves.all()
770
-
771
- def clean_slaves(self):
772
- if not self.cleaned_data['slaves'] or not self.instance:
773
- return self.cleaned_data['slaves']
774
- return validate_slaves(self.cleaned_data['slaves'], self.instance)
775
-
776
- def clean(self):
777
- super().clean()
778
- if 'output_pin' in self.cleaned_data:
779
- self._clean_pin('output_pin')
780
- if 'controls' in self.cleaned_data:
781
- self._clean_controls()
782
-
783
- if self.cleaned_data.get('output_pin') and self.cleaned_data.get('controls'):
784
- for ctrl in self.cleaned_data['controls']:
785
- if not ctrl['input'].startswith('pin'):
786
- continue
787
- if int(ctrl['input'][4:]) == self.cleaned_data['output_pin'].id:
788
- self.add_error(
789
- "output_pin",
790
- "Can't be used as control pin at the same time!"
791
- )
792
- return self.cleaned_data
793
-
794
-
795
- def save(self, commit=True):
796
- if 'output_pin' in self.cleaned_data:
797
- self.instance.config['output_pin_no'] = self.cleaned_data['output_pin'].no
798
-
799
- update_colonel = False
800
- if not self.instance.pk:
801
- update_colonel = True
802
- elif 'output_pin' in self.changed_data:
803
- update_colonel = True
804
- elif 'slaves' in self.changed_data:
805
- update_colonel = True
806
- if not update_colonel:
807
- old = Component.objects.get(id=self.instance.id)
808
- if old.config.get('controls') != self.cleaned_data.get('controls'):
809
- update_colonel = True
810
829
 
811
- obj = super().save(commit=commit)
812
- if commit and 'slaves' in self.cleaned_data:
813
- obj.slaves.set(self.cleaned_data['slaves'])
814
- if not update_colonel:
815
- GatewayObjectCommand(
816
- obj.gateway, self.cleaned_data['colonel'], id=obj.id,
817
- command='call', method='update_config', args=[
818
- obj.controller._get_colonel_config()
819
- ]
820
- ).publish()
821
- if commit and self.cleaned_data.get('controls'):
822
- GatewayObjectCommand(
823
- self.instance.gateway, obj, command='watch_buttons'
824
- ).publish()
825
- return obj
826
-
827
-
828
- class DCDriverConfigForm(ColonelComponentForm):
830
+ class DC10VConfigForm(PWMOutputBaseConfig):
829
831
  output_pin = Select2ModelChoiceField(
830
832
  label="Port",
831
833
  queryset=ColonelPin.objects.filter(output=True),
@@ -841,53 +843,60 @@ class DCDriverConfigForm(ColonelComponentForm):
841
843
  help_text="Minimum component value displayed to the user."
842
844
  )
843
845
  max = forms.FloatField(
844
- required=True, initial=24,
846
+ required=True, initial=100,
845
847
  help_text="Maximum component value displayed to the user."
846
848
  )
847
- value_units = forms.CharField(required=False)
849
+ value_units = forms.CharField(required=False, initial='%')
848
850
 
849
851
  device_min = forms.FloatField(
850
852
  label="Device minimum Voltage.",
851
853
  help_text="This will be the lowest possible voltage value of a device.\n"
852
854
  "Don't forget to adjust your component min value accordingly "
853
855
  "if you change this.",
854
- initial=0, min_value=0, max_value=24,
856
+ initial=0, min_value=0, max_value=10,
855
857
  )
856
- device_max = forms.IntegerField(
858
+ device_max = forms.FloatField(
857
859
  label="Device maximum Voltage.",
858
- help_text="Can be set lower than it's natural maximum of 24V. \n"
860
+ help_text="Can be set lower than it's natural maximum of 10V. \n"
859
861
  "Don't forget to adjust your component max value accordingly "
860
862
  "if you change this.",
861
- initial=24, min_value=0, max_value=24,
863
+ initial=10, min_value=0, max_value=10,
862
864
  )
865
+ inverse = forms.BooleanField(required=False, initial=False)
863
866
 
864
- def clean(self):
865
- super().clean()
866
- if 'output_pin' in self.cleaned_data:
867
- self._clean_pin('output_pin')
868
- return self.cleaned_data
869
-
870
-
871
- def save(self, commit=True):
872
- if 'output_pin' in self.cleaned_data:
873
- self.instance.config['output_pin_no'] = self.cleaned_data['output_pin'].no
874
-
875
- update_colonel = False
876
- if not self.instance.pk:
877
- update_colonel = True
878
- elif 'output_pin' in self.changed_data:
879
- update_colonel = True
880
-
881
- obj = super().save(commit=commit)
867
+ turn_on_time = forms.IntegerField(
868
+ min_value=0, max_value=60000, initial=0,
869
+ help_text="Turn on speed in ms. 1500 is a great quick default for controlling lights. "
870
+ "10000 - great slow default."
871
+ )
872
+ turn_off_time = forms.IntegerField(
873
+ min_value=0, max_value=60000, initial=0,
874
+ help_text="Turn off speed in ms. 3000 is a great quick default when controlling lights. "
875
+ "20000 - great slow default"
876
+ )
877
+ skew = forms.ChoiceField(
878
+ initial='linear', choices=EASING_CHOICES,
879
+ help_text="easeOutSine - offers most naturally looking effect for lights."
880
+ )
881
+ on_value = forms.FloatField(
882
+ required=False,
883
+ help_text="Static ON value used to turn on the device with physical controls. <br>"
884
+ "Leaving this field empty turns the device on to the last used value."
885
+ )
882
886
 
883
- if not update_colonel:
884
- GatewayObjectCommand(
885
- obj.gateway, self.cleaned_data['colonel'], id=obj.id,
886
- command='call', method='update_config', args=[
887
- obj.controller._get_colonel_config()
888
- ]
889
- ).publish()
890
- return obj
887
+ slaves = Select2ModelMultipleChoiceField(
888
+ queryset=Component.objects.filter(
889
+ base_type__in=('dimmer',),
890
+ ),
891
+ url='autocomplete-component',
892
+ forward=(forward.Const(['dimmer', ], 'base_type'),),
893
+ required=False
894
+ )
895
+ controls = FormsetField(
896
+ formset_factory(
897
+ ControlForm, can_delete=True, can_order=True, extra=0, max_num=10
898
+ )
899
+ )
891
900
 
892
901
 
893
902
  class ColonelRGBLightConfigForm(ColonelComponentForm):
@@ -1814,6 +1823,7 @@ class CustomDaliDeviceForm(BaseComponentForm):
1814
1823
 
1815
1824
  class RoomSensorDeviceConfigForm(CustomDaliDeviceForm):
1816
1825
 
1826
+
1817
1827
  def save(self, commit=True):
1818
1828
  from simo.core.models import Icon
1819
1829
  colonel = None
@@ -0,0 +1,36 @@
1
+ # Generated by Django 4.2.10 on 2025-05-07 12:56
2
+
3
+ from django.db import migrations
4
+
5
+ def forwards_func(apps, schema_editor):
6
+ Component = apps.get_model("core", "Component")
7
+ ColonelPin = apps.get_model('fleet', "ColonelPin")
8
+
9
+ for comp in Component.objects.filter(controller_uid__in=(
10
+ 'simo.fleet.controllers.BME680Sensor',
11
+ 'simo.fleet.controllers.MCP9808TempSensor',
12
+ 'simo.fleet.controllers.ENS160AirQualitySensor'
13
+ )):
14
+ cp = ColonelPin.objects.filter(
15
+ colonel__id=comp.config['colonel'],
16
+ interface=comp.config['i2c_interface']
17
+ ).first()
18
+ if cp:
19
+ comp.config['interface_port'] = cp.id
20
+ comp.save()
21
+
22
+
23
+
24
+ def reverse_func(apps, schema_editor):
25
+ pass
26
+
27
+
28
+ class Migration(migrations.Migration):
29
+
30
+ dependencies = [
31
+ ('fleet', '0053_auto_20250507_0713'),
32
+ ]
33
+
34
+ operations = [
35
+ migrations.RunPython(forwards_func, reverse_func, elidable=True),
36
+ ]
simo/fleet/models.py CHANGED
@@ -255,7 +255,7 @@ class ColonelPin(models.Model):
255
255
  interface = Interface.objects.filter(
256
256
  colonel=self.colonel, no=self.interface
257
257
  ).first()
258
- if interface:
258
+ if interface and interface.type:
259
259
  return f"{self.label} - {interface.get_type_display()}"
260
260
  return self.label
261
261
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simo
3
- Version: 2.10.9
3
+ Version: 2.10.11
4
4
  Summary: Smart Home Supremacy
5
5
  Author-email: Simanas Venčkauskas <simanas@simo.io>
6
6
  Project-URL: Homepage, https://simo.io
@@ -10452,12 +10452,12 @@ simo/fleet/apps.py,sha256=je8mRXMcRq4lABQZlyF2G2hOCkBUicR9I2jvrLDA8eI,238
10452
10452
  simo/fleet/auto_urls.py,sha256=vrfrooPyY4pDuQjya-eLxCgZldfhwbEeEiXa7diO_CY,847
10453
10453
  simo/fleet/base_types.py,sha256=0F8r7eNpi0qdm7DtVHyQN3fst8sFOFjq61twFO2WeZQ,139
10454
10454
  simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
10455
- simo/fleet/controllers.py,sha256=wi1UVL2Xrnj-V49VOgQS4t_br46QhB7rf6HvoPUy--c,40110
10455
+ simo/fleet/controllers.py,sha256=UNxQ4zDnZ_jZaIsnwHuGOPA5qz14mfPBeYIu6OQyUcY,40804
10456
10456
  simo/fleet/custom_dali_operations.py,sha256=LASObOxRymL-f0AEm9wdt4YFnNsz5z385wQE9qJhOZY,9948
10457
- simo/fleet/forms.py,sha256=xp_aGG9e2QcTVY790lSAdRUMJAF84Siq2fi2SCbZmDc,69183
10457
+ simo/fleet/forms.py,sha256=7s-DXQ3eYHnqztaWQaYMfu6eFQy5fSYODr-v4kvuDIc,69737
10458
10458
  simo/fleet/gateways.py,sha256=GMaZt1w0yZu-mpt2lnWODBt7qRtXjVmaNmQWPk4zxVk,7144
10459
10459
  simo/fleet/managers.py,sha256=DKU9kv5S6dAqAHWq4OgfEOeK5IJaQW7qdCednA0NpUA,858
10460
- simo/fleet/models.py,sha256=pKZ1reGYN3IGym7QP6VEDGRbGcEsceIQF3lauqBPygo,22583
10460
+ simo/fleet/models.py,sha256=TGpYkX8bni1fwiMN61KYBile9ev_EgfZ4pdZHdWlbu0,22602
10461
10461
  simo/fleet/routing.py,sha256=cofGsVWXMfPDwsJ6HM88xxtRxHwERhJ48Xyxc8mxg5o,149
10462
10462
  simo/fleet/serializers.py,sha256=VrY7pNCOS720QoukeA8YFkwVRcYDlT9ZrOWKfZF0zOs,4271
10463
10463
  simo/fleet/socket_consumers.py,sha256=SPrhbcMY50QD1QKXBPUwBZi_Jmw7FwRZdHGUybkAQlU,19460
@@ -10480,13 +10480,13 @@ simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9o
10480
10480
  simo/fleet/__pycache__/controllers.cpython-312.pyc,sha256=zX0h22tqYC6qDIfKzkUUU3Qp6ZnAsI7SXJTR-ru1bh8,54500
10481
10481
  simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=vH7mK1K4JBcLU9eKtqTJwbgB0SFMJ-s7WvO0qOsWjrg,24739
10482
10482
  simo/fleet/__pycache__/custom_dali_operations.cpython-312.pyc,sha256=MwA_oC32S-j5nTfnJhTE3mSTlyxn1xvgif73KWQqaX0,13702
10483
- simo/fleet/__pycache__/forms.cpython-312.pyc,sha256=6n77IgzxYxs0_S9-crWXLqrUradoxo5xZQ10EGVfisc,84713
10483
+ simo/fleet/__pycache__/forms.cpython-312.pyc,sha256=GIWBBKlvXEqHuU9WS4RopyIRnNWkJCCZ_QQSr9QMCww,84764
10484
10484
  simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=hrNfyGm2NfoNG1II-OqeHzR2TkkAWp3igvHGs6X0iIM,45252
10485
10485
  simo/fleet/__pycache__/gateways.cpython-312.pyc,sha256=5tOEiBbleeZUbnbCV6kt5la4YfYuKOKMvRxoNc3112M,10039
10486
10486
  simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=MIpXuGWitGNdsxJ99fWvMXJ6sVE96ac7iR4K4aM4Sds,5148
10487
10487
  simo/fleet/__pycache__/managers.cpython-312.pyc,sha256=LwTKNnkBhSj5FtpdmBZMpXYgNSnXEY8Zaz6NRPVxIS0,1703
10488
10488
  simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=Vmm23zoQnS3-uS5_WJt2n3wtjhLiEhLWaYxXJCU6Gts,1339
10489
- simo/fleet/__pycache__/models.cpython-312.pyc,sha256=ZVWAB-mP1177o4Uffdt1ey1e7Obl7dQh0NdK1gh_BRo,30836
10489
+ simo/fleet/__pycache__/models.cpython-312.pyc,sha256=7Wco3hDFizVOsnT1FnhWeyDaDsgUDmF2NCMa4UkcoZM,30922
10490
10490
  simo/fleet/__pycache__/models.cpython-38.pyc,sha256=AXk1Q_nnHDXirHYgM3EW5pLsrR2CaPWk4EuvGCuDUpI,14131
10491
10491
  simo/fleet/__pycache__/routing.cpython-312.pyc,sha256=SXX0YgnGxVZIDCRGE46PzkDgPgF-Xg7ahNI_rfHBPN0,334
10492
10492
  simo/fleet/__pycache__/routing.cpython-38.pyc,sha256=aPrCmxFKVyB8R8ZbJDwdPdFfvT7CvobovvZeq_mqRgY,314
@@ -10553,6 +10553,7 @@ simo/fleet/migrations/0050_customdalidevice_uid.py,sha256=iO_vpbNnEDLWo8p0S81Mou
10553
10553
  simo/fleet/migrations/0051_customdalidevice_components.py,sha256=-tTMCuBQnAFf3W5aHCn1qWa447e1XdghVK8nNA7J7bo,456
10554
10554
  simo/fleet/migrations/0052_colonelpin_interface.py,sha256=lODzYseGKZv_P-LTWCKor2kXvt_GprCIrcqibXjdGu4,418
10555
10555
  simo/fleet/migrations/0053_auto_20250507_0713.py,sha256=u18ulpyMflNql3-bTsJRj_dYTXVJhzq7iyxtF9gglO0,563
10556
+ simo/fleet/migrations/0054_auto_20250507_1256.py,sha256=A2bLRfcLnasbjOzLUam5yaHw_l9T9RfMMTn0MSU3Dgs,969
10556
10557
  simo/fleet/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10557
10558
  simo/fleet/migrations/__pycache__/0001_initial.cpython-312.pyc,sha256=pmAucXHKCx4FZRIRVrX9l63-GrVozZEi1kVqT_tPQz4,1940
10558
10559
  simo/fleet/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=9kc1UyMEYkRNVnZ7iwZbiW1t3qWXROvWrI2G1BdzIaA,1250
@@ -10651,6 +10652,7 @@ simo/fleet/migrations/__pycache__/0050_customdalidevice_uid.cpython-312.pyc,sha2
10651
10652
  simo/fleet/migrations/__pycache__/0051_customdalidevice_components.cpython-312.pyc,sha256=o76mJd3d_lDeFbNHgKFW5JNDSWsQTMhmRU9G7cVoURk,776
10652
10653
  simo/fleet/migrations/__pycache__/0052_colonelpin_interface.cpython-312.pyc,sha256=Una715IYH-a39D-IxiImAYrbg6oyVfftw_xWirJ_VIo,733
10653
10654
  simo/fleet/migrations/__pycache__/0053_auto_20250507_0713.cpython-312.pyc,sha256=eyvZZZd-DmoxjlK30jwj9iWCE-EmCLNzBWjk2iB7BsY,1220
10655
+ simo/fleet/migrations/__pycache__/0054_auto_20250507_1256.cpython-312.pyc,sha256=67MZoSNgxEhWmAI8nRUyS7qHSfjRuUqDJywklYWFW-I,1730
10654
10656
  simo/fleet/migrations/__pycache__/__init__.cpython-312.pyc,sha256=NhvncgZjeTfbQ3W00bDahlhD8YZzlX8xHqlherT7FmQ,125
10655
10657
  simo/fleet/migrations/__pycache__/__init__.cpython-38.pyc,sha256=5k1KW0jeSDzw6RnVPRq4CaO13Lg7M0F-pxA_gqqZ6Mg,170
10656
10658
  simo/fleet/templates/admin/colonel_history.html,sha256=YfA6LDVExk1sAWhBuiCLA6vb3XcBNN7_fpJNZzGFtB0,169
@@ -11001,9 +11003,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
11001
11003
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11002
11004
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11003
11005
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11004
- simo-2.10.9.dist-info/licenses/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
11005
- simo-2.10.9.dist-info/METADATA,sha256=jA-ZFxYqm6R8hES46SuRYFEl6lnWhmiR6NqNGCY_zRE,2028
11006
- simo-2.10.9.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
11007
- simo-2.10.9.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
11008
- simo-2.10.9.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
11009
- simo-2.10.9.dist-info/RECORD,,
11006
+ simo-2.10.11.dist-info/licenses/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
11007
+ simo-2.10.11.dist-info/METADATA,sha256=jF8Jc9GHCm8dV1kbfIuRIKeaAjhU6c7ukEHo-27FIZM,2029
11008
+ simo-2.10.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11009
+ simo-2.10.11.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
11010
+ simo-2.10.11.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
11011
+ simo-2.10.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5