simo 2.0.5__py3-none-any.whl → 2.0.7__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/__pycache__/settings.cpython-38.pyc +0 -0
- simo/__pycache__/urls.cpython-38.pyc +0 -0
- simo/core/__pycache__/admin.cpython-38.pyc +0 -0
- simo/core/__pycache__/api.cpython-38.pyc +0 -0
- simo/core/__pycache__/api_auth.cpython-38.pyc +0 -0
- simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
- simo/core/__pycache__/auto_urls.cpython-38.pyc +0 -0
- simo/core/__pycache__/autocomplete_views.cpython-38.pyc +0 -0
- simo/core/__pycache__/base_types.cpython-38.pyc +0 -0
- simo/core/__pycache__/context.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__/gateways.cpython-38.pyc +0 -0
- simo/core/__pycache__/managers.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__/permissions.cpython-38.pyc +0 -0
- simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/core/__pycache__/socket_consumers.cpython-38.pyc +0 -0
- simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
- simo/core/__pycache__/views.cpython-38.pyc +0 -0
- simo/core/admin.py +10 -10
- simo/core/api.py +7 -6
- simo/core/controllers.py +1 -0
- simo/core/db_backend/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/db_backend/__pycache__/base.cpython-38.pyc +0 -0
- simo/core/drf_braces/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/drf_braces/__pycache__/utils.cpython-38.pyc +0 -0
- simo/core/drf_braces/fields/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/drf_braces/fields/__pycache__/_fields.cpython-38.pyc +0 -0
- simo/core/drf_braces/fields/__pycache__/custom.cpython-38.pyc +0 -0
- simo/core/drf_braces/fields/__pycache__/mixins.cpython-38.pyc +0 -0
- simo/core/drf_braces/fields/__pycache__/modified.cpython-38.pyc +0 -0
- simo/core/drf_braces/serializers/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/drf_braces/serializers/__pycache__/form_serializer.cpython-38.pyc +0 -0
- simo/core/forms.py +8 -6
- simo/core/migrations/0030_alter_instance_timezone.py +18 -0
- simo/core/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0002_load_icons.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0003_create_default_zones_and_categories.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0004_create_generic.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0005_component_subcomponents.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0006_alter_component_subcomponents.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0007_component_change_init_to.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0008_alter_component_change_init_to.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0009_auto_20220707_1404.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0010_historyaggregate.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0011_component_last_change.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0012_instance.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0013_auto_20231003_0754.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0014_zone_instance.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0015_auto_20231004_1113.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0016_auto_20231004_1113.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0017_auto_20231004_1313.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0018_auto_20231005_0622.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0019_alter_gateway_type.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0020_component_meta.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0021_auto_20231020_1041.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0026_category_instance.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0027_remove_component_tags.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0028_rename_subcomponents_component_slaves.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0029_auto_20240229_1331.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0030_alter_instance_timezone.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/models.py +31 -46
- simo/core/serializers.py +3 -4
- simo/core/templatetags/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/templatetags/__pycache__/components_list.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/admin.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/config_values.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/easing.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/form_fields.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/form_widgets.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/formsets.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/helpers.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/logs.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/mixins.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/model_helpers.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/relay.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/serialization.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/type_constants.cpython-38.pyc +0 -0
- simo/core/utils/__pycache__/validators.cpython-38.pyc +0 -0
- simo/core/utils/serialization.py +4 -2
- simo/core/utils/type_constants.py +32 -11
- simo/fleet/__pycache__/admin.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/api.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/auto_urls.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/managers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/utils.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
- simo/fleet/admin.py +6 -6
- simo/fleet/auto_urls.py +4 -4
- simo/fleet/controllers.py +75 -2
- simo/fleet/forms.py +68 -33
- simo/fleet/gateways.py +7 -3
- simo/fleet/managers.py +4 -2
- simo/fleet/migrations/0032_auto_20240415_0736.py +33 -0
- simo/fleet/migrations/0033_auto_20240415_0736.py +28 -0
- simo/fleet/migrations/__pycache__/0025_auto_20240130_1334.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0026_rename_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0027_auto_20240306_0802.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0028_remove_i2cinterface_scl_pin_no_and_more.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0029_alter_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0030_colonelpin_label_alter_colonel_type.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0031_alter_colonel_type.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0032_auto_20240415_0736.cpython-38.pyc +0 -0
- simo/fleet/migrations/__pycache__/0033_auto_20240415_0736.cpython-38.pyc +0 -0
- simo/fleet/models.py +82 -14
- simo/fleet/socket_consumers.py +19 -12
- simo/fleet/utils.py +6 -1
- simo/fleet/views.py +10 -9
- simo/generic/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/generic/__pycache__/app_widgets.cpython-38.pyc +0 -0
- simo/generic/__pycache__/base_types.cpython-38.pyc +0 -0
- 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/__pycache__/routing.cpython-38.pyc +0 -0
- simo/generic/__pycache__/socket_consumers.cpython-38.pyc +0 -0
- simo/generic/controllers.py +0 -7
- simo/generic/forms.py +0 -3
- simo/generic/gateways.py +0 -8
- simo/multimedia/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/admin.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/api.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/app_widgets.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/base_types.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/forms.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/models.cpython-38.pyc +0 -0
- simo/multimedia/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/multimedia/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
- simo/multimedia/migrations/__pycache__/0002_sound_length.cpython-38.pyc +0 -0
- simo/multimedia/migrations/__pycache__/0003_alter_sound_length.cpython-38.pyc +0 -0
- simo/multimedia/migrations/__pycache__/0004_auto_20231023_1055.cpython-38.pyc +0 -0
- simo/multimedia/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/admin.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/api.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/models.cpython-38.pyc +0 -0
- simo/notifications/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/notifications/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
- simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.pyc +0 -0
- simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
- simo/users/__pycache__/admin.cpython-38.pyc +0 -0
- simo/users/__pycache__/api.cpython-38.pyc +0 -0
- simo/users/__pycache__/auto_urls.cpython-38.pyc +0 -0
- simo/users/__pycache__/middleware.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__/sso_urls.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0002_componentpermission.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0003_create_roles_and_system_user.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0004_user_secret_key.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0005_permissionsrole_instance.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0006_auto_20231003_0850.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0007_auto_20231003_1228.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0008_auto_20231003_1229.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0009_remove_user_role.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0010_auto_20231004_1313.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0011_auto_20231004_1313.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0012_alter_userinstancerole_unique_together.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0013_remove_user_roles.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0014_user_roles.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0015_remove_user_at_home.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0016_auto_20231005_1050.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0025_rename_name_fingerprint_type_and_more.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
- {simo-2.0.5.dist-info → simo-2.0.7.dist-info}/METADATA +1 -1
- {simo-2.0.5.dist-info → simo-2.0.7.dist-info}/RECORD +183 -89
- {simo-2.0.5.dist-info → simo-2.0.7.dist-info}/LICENSE.md +0 -0
- {simo-2.0.5.dist-info → simo-2.0.7.dist-info}/WHEEL +0 -0
- {simo-2.0.5.dist-info → simo-2.0.7.dist-info}/top_level.txt +0 -0
simo/fleet/models.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
import time
|
|
3
|
+
from django.core.exceptions import ValidationError
|
|
3
4
|
from django.db import transaction
|
|
4
5
|
from django.db import models
|
|
5
6
|
from django.db.models.signals import post_save, pre_delete, post_delete
|
|
@@ -11,8 +12,8 @@ from simo.core.models import Instance, Gateway, Component
|
|
|
11
12
|
from simo.core.utils.helpers import get_random_string
|
|
12
13
|
from simo.core.events import GatewayObjectCommand
|
|
13
14
|
from .gateways import FleetGatewayHandler
|
|
14
|
-
from .managers import ColonelsManager, ColonelPinsManager,
|
|
15
|
-
from .utils import GPIO_PINS
|
|
15
|
+
from .managers import ColonelsManager, ColonelPinsManager, InterfacesManager
|
|
16
|
+
from .utils import GPIO_PINS, INTERFACES_PINS_MAP
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
|
|
@@ -181,10 +182,12 @@ class Colonel(DirtyFieldsMixin, models.Model):
|
|
|
181
182
|
pin.save()
|
|
182
183
|
|
|
183
184
|
for interface in self.i2c_interfaces.all():
|
|
184
|
-
interface.sda_pin
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
interface.scl_pin
|
|
185
|
+
if interface.sda_pin:
|
|
186
|
+
interface.sda_pin.occupied_by = interface
|
|
187
|
+
interface.sda_pin.save()
|
|
188
|
+
if interface.scl_pin:
|
|
189
|
+
interface.scl_pin.occupied_by = interface
|
|
190
|
+
interface.scl_pin.save()
|
|
188
191
|
|
|
189
192
|
|
|
190
193
|
def move_to(self, other_colonel):
|
|
@@ -256,12 +259,6 @@ def after_colonel_save(sender, instance, created, *args, **kwargs):
|
|
|
256
259
|
capacitive=data.get('capacitive'), adc=data.get('adc'),
|
|
257
260
|
native=data.get('native'), note=data.get('note')
|
|
258
261
|
)
|
|
259
|
-
if instance.type in ('ample-wall', 'game-changer'):
|
|
260
|
-
I2CInterface.objects.create(
|
|
261
|
-
colonel=instance, name='Main', no=0,
|
|
262
|
-
scl_pin=ColonelPin.objects.get(colonel=instance, no=4),
|
|
263
|
-
sda_pin=ColonelPin.objects.get(colonel=instance, no=15),
|
|
264
|
-
)
|
|
265
262
|
|
|
266
263
|
|
|
267
264
|
@receiver(pre_delete, sender=Component)
|
|
@@ -310,7 +307,7 @@ class I2CInterface(models.Model):
|
|
|
310
307
|
default=100000, help_text="100000 - is a good middle point!"
|
|
311
308
|
)
|
|
312
309
|
|
|
313
|
-
objects =
|
|
310
|
+
objects = InterfacesManager()
|
|
314
311
|
|
|
315
312
|
class Meta:
|
|
316
313
|
unique_together = 'colonel', 'no'
|
|
@@ -319,7 +316,7 @@ class I2CInterface(models.Model):
|
|
|
319
316
|
return self.name
|
|
320
317
|
|
|
321
318
|
|
|
322
|
-
@receiver(
|
|
319
|
+
@receiver(post_delete, sender=I2CInterface)
|
|
323
320
|
def post_i2c_interface_delete(sender, instance, *args, **kwargs):
|
|
324
321
|
with transaction.atomic():
|
|
325
322
|
ct = ContentType.objects.get_for_model(instance)
|
|
@@ -334,3 +331,74 @@ def post_i2c_interface_delete(sender, instance, *args, **kwargs):
|
|
|
334
331
|
instance.scl_pin.save()
|
|
335
332
|
instance.sda_pin.occupied_by = instance
|
|
336
333
|
instance.sda_pin.save()
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class Interface(models.Model):
|
|
337
|
+
colonel = models.ForeignKey(
|
|
338
|
+
Colonel, on_delete=models.CASCADE, related_name='interfaces'
|
|
339
|
+
)
|
|
340
|
+
no = models.PositiveIntegerField(choices=((1, "1"), (2, "2")))
|
|
341
|
+
type = models.CharField(
|
|
342
|
+
max_length=20, choices=(('i2c', "I2C"), ('dali', "DALI"))
|
|
343
|
+
)
|
|
344
|
+
pin_a = models.ForeignKey(
|
|
345
|
+
ColonelPin, on_delete=models.CASCADE, limit_choices_to={
|
|
346
|
+
'native': True, 'output': True,
|
|
347
|
+
}, verbose_name="Pin A (scl)", null=True, related_name='interface_a',
|
|
348
|
+
editable=False
|
|
349
|
+
)
|
|
350
|
+
pin_b = models.ForeignKey(
|
|
351
|
+
ColonelPin, on_delete=models.CASCADE, limit_choices_to={
|
|
352
|
+
'native': True, 'output': True,
|
|
353
|
+
}, verbose_name="Pin B (sda)", null=True, related_name='interface_b',
|
|
354
|
+
editable=False
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
objects = InterfacesManager()
|
|
358
|
+
|
|
359
|
+
class Meta:
|
|
360
|
+
unique_together = 'colonel', 'no'
|
|
361
|
+
|
|
362
|
+
def __str__(self):
|
|
363
|
+
return f"{self.no} - {self.get_type_display()}"
|
|
364
|
+
|
|
365
|
+
def save(self, *args, **kwargs):
|
|
366
|
+
if not self.pk:
|
|
367
|
+
for pin_no in INTERFACES_PINS_MAP[self.no]:
|
|
368
|
+
cpin = ColonelPin.objects.get(colonel=self.colonel, no=pin_no)
|
|
369
|
+
if cpin.occupied_by:
|
|
370
|
+
raise ValidationError(
|
|
371
|
+
f"Interface can not be created, because "
|
|
372
|
+
f"GPIO{cpin} is already occupied by {cpin.occupied_by}."
|
|
373
|
+
)
|
|
374
|
+
return super().save(*args, **kwargs)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
@receiver(post_save, sender=Interface)
|
|
378
|
+
def post_interface_save(sender, instance, created, *args, **kwargs):
|
|
379
|
+
if created:
|
|
380
|
+
instance.pin_a = ColonelPin.objects.get(
|
|
381
|
+
colonel=instance.colonel, no=INTERFACES_PINS_MAP[instance.no][0]
|
|
382
|
+
)
|
|
383
|
+
instance.pin_a.occupied_by = instance
|
|
384
|
+
instance.pin_a.save()
|
|
385
|
+
instance.pin_b = ColonelPin.objects.get(
|
|
386
|
+
colonel=instance.colonel, no=INTERFACES_PINS_MAP[instance.no][1]
|
|
387
|
+
)
|
|
388
|
+
instance.pin_b.occupied_by = instance
|
|
389
|
+
instance.pin_b.save()
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@receiver(post_delete, sender=Interface)
|
|
393
|
+
def post_interface_delete(sender, instance, *args, **kwargs):
|
|
394
|
+
with transaction.atomic():
|
|
395
|
+
ct = ContentType.objects.get_for_model(instance)
|
|
396
|
+
for pin in ColonelPin.objects.filter(
|
|
397
|
+
occupied_by_content_type=ct,
|
|
398
|
+
occupied_by_id=instance.id
|
|
399
|
+
):
|
|
400
|
+
pin.occupied_by_content_type = None
|
|
401
|
+
pin.occupied_by_content_id = None
|
|
402
|
+
pin.save()
|
|
403
|
+
|
|
404
|
+
|
simo/fleet/socket_consumers.py
CHANGED
|
@@ -218,15 +218,14 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
config_data['settings'].update(instance_options)
|
|
221
|
-
|
|
222
|
-
self.colonel.
|
|
223
|
-
'
|
|
221
|
+
interfaces = await sync_to_async(list, thread_sensitive=True)(
|
|
222
|
+
self.colonel.interfaces.all().select_related(
|
|
223
|
+
'pin_a', 'pin_b'
|
|
224
224
|
)
|
|
225
225
|
)
|
|
226
|
-
for
|
|
227
|
-
config_data['interfaces']['
|
|
228
|
-
'
|
|
229
|
-
'freq': i2c_interface.freq
|
|
226
|
+
for interface in interfaces:
|
|
227
|
+
config_data['interfaces'][f'{interface.type}-{interface.no}'] = {
|
|
228
|
+
'pin_a': interface.pin_a.no, 'pin_b': interface.pin_b.no,
|
|
230
229
|
}
|
|
231
230
|
components = await sync_to_async(
|
|
232
231
|
list, thread_sensitive=True
|
|
@@ -319,6 +318,11 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
319
318
|
asyncio.run(self.send_data({
|
|
320
319
|
'command': 'discover-ttlock'
|
|
321
320
|
}))
|
|
321
|
+
elif payload.get('command') == 'discover-dali':
|
|
322
|
+
print("SEND discover-dali command!")
|
|
323
|
+
asyncio.run(self.send_data({
|
|
324
|
+
'command': 'discover-dali', 'i': payload['interface']
|
|
325
|
+
}))
|
|
322
326
|
elif payload.get('command') == 'finalize':
|
|
323
327
|
asyncio.run(self.send_data({
|
|
324
328
|
'command': 'finalize',
|
|
@@ -420,18 +424,21 @@ class FleetConsumer(AsyncWebsocketConsumer):
|
|
|
420
424
|
except Exception as e:
|
|
421
425
|
print(traceback.format_exc(), file=sys.stderr)
|
|
422
426
|
|
|
423
|
-
elif '
|
|
427
|
+
elif 'discovery-result' in data:
|
|
424
428
|
def process_discovery_result():
|
|
425
|
-
|
|
426
|
-
if
|
|
427
|
-
|
|
429
|
+
# check if component is already created
|
|
430
|
+
if data['discovery-result'] == 'success':
|
|
431
|
+
comp = Component.objects.filter(
|
|
428
432
|
meta__finalization_data__temp_id=data['result']['id']
|
|
429
433
|
).first()
|
|
434
|
+
if comp:
|
|
435
|
+
return comp
|
|
436
|
+
|
|
437
|
+
self.gateway.refresh_from_db()
|
|
430
438
|
try:
|
|
431
439
|
self.gateway.process_discovery(data)
|
|
432
440
|
except Exception as e:
|
|
433
441
|
print(traceback.format_exc(), file=sys.stderr)
|
|
434
|
-
self.gateway.finish_discovery()
|
|
435
442
|
|
|
436
443
|
finished_comp = await sync_to_async(
|
|
437
444
|
process_discovery_result, thread_sensitive=True
|
simo/fleet/utils.py
CHANGED
|
@@ -58,7 +58,7 @@ for no, data in BASE_ESP32_GPIO_PINS.items():
|
|
|
58
58
|
|
|
59
59
|
# ample-wall
|
|
60
60
|
for no, data in BASE_ESP32_GPIO_PINS.items():
|
|
61
|
-
if no in (
|
|
61
|
+
if no in (12, 13, 14, 23, 32, 33, 34, 36, 39):
|
|
62
62
|
GPIO_PINS['ample-wall'][no] = GPIO_PIN_DEFAULTS.copy()
|
|
63
63
|
GPIO_PINS['ample-wall'][no].update(data)
|
|
64
64
|
|
|
@@ -114,3 +114,8 @@ for no, data in BASE_ESP32_GPIO_PINS.items():
|
|
|
114
114
|
GPIO_PINS['4-relays'][no]['note'] = 'Relay4'
|
|
115
115
|
else:
|
|
116
116
|
GPIO_PINS['4-relays'][no].update(data)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
INTERFACES_PINS_MAP = {
|
|
120
|
+
1: [13, 23], 2: [32, 33]
|
|
121
|
+
}
|
simo/fleet/views.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
from django.contrib.contenttypes.models import ContentType
|
|
2
1
|
from django.http import HttpResponse, Http404
|
|
3
2
|
from django.db.models import Q
|
|
4
3
|
from dal import autocomplete
|
|
5
4
|
from simo.core.utils.helpers import search_queryset
|
|
6
|
-
from .models import Colonel, ColonelPin,
|
|
5
|
+
from .models import Colonel, ColonelPin, Interface
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
def colonels_ping(request):
|
|
@@ -43,20 +42,22 @@ class PinsSelectAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
43
42
|
return qs
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
class
|
|
45
|
+
class InterfaceSelectAutocomplete(autocomplete.Select2ListView):
|
|
47
46
|
|
|
48
47
|
def get_list(self):
|
|
49
48
|
if not self.request.user.is_staff:
|
|
50
|
-
return
|
|
49
|
+
return Interface.objects.none()
|
|
51
50
|
|
|
52
51
|
try:
|
|
53
52
|
colonel = Colonel.objects.get(
|
|
54
53
|
pk=self.forwarded.get("colonel")
|
|
55
54
|
)
|
|
56
55
|
except:
|
|
57
|
-
return
|
|
56
|
+
return Interface.objects.none()
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
qs = Interface.objects.filter(colonel=colonel)
|
|
59
|
+
|
|
60
|
+
if self.forwarded.get('filters'):
|
|
61
|
+
qs = qs.filter(**self.forwarded.get('filters'))
|
|
62
|
+
|
|
63
|
+
return qs
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/generic/controllers.py
CHANGED
|
@@ -208,13 +208,9 @@ class Thermostat(ControllerBase):
|
|
|
208
208
|
heater = Component.objects.filter(
|
|
209
209
|
pk=self.component.config.get('heater')
|
|
210
210
|
).first()
|
|
211
|
-
if heater:
|
|
212
|
-
heater.prepare_controller()
|
|
213
211
|
cooler = Component.objects.filter(
|
|
214
212
|
pk=self.component.config.get('cooler')
|
|
215
213
|
).first()
|
|
216
|
-
if cooler:
|
|
217
|
-
cooler.prepare_controller()
|
|
218
214
|
|
|
219
215
|
if not temperature_sensor or not temperature_sensor.alive:
|
|
220
216
|
print(f"No temperature sensor on {self.component}!")
|
|
@@ -720,7 +716,6 @@ class Watering(ControllerBase):
|
|
|
720
716
|
switch = Component.objects.get(pk=contour_data['switch'])
|
|
721
717
|
except Component.DoesNotExist:
|
|
722
718
|
continue
|
|
723
|
-
switch.prepare_controller()
|
|
724
719
|
if run:
|
|
725
720
|
if switch.timer_engaged():
|
|
726
721
|
switch.stop_timer()
|
|
@@ -845,7 +840,6 @@ class Watering(ControllerBase):
|
|
|
845
840
|
switch = Component.objects.get(pk=contour_data['switch'])
|
|
846
841
|
except Component.DoesNotExist:
|
|
847
842
|
continue
|
|
848
|
-
switch.prepare_controller()
|
|
849
843
|
if switch.timer_engaged():
|
|
850
844
|
switch.stop_timer()
|
|
851
845
|
switch.turn_off()
|
|
@@ -1077,7 +1071,6 @@ class AlarmClock(ControllerBase):
|
|
|
1077
1071
|
print(f"Reverse event {event['uid']}!")
|
|
1078
1072
|
comp = Component.objects.filter(id=event['component']).first()
|
|
1079
1073
|
if comp:
|
|
1080
|
-
comp.prepare_controller()
|
|
1081
1074
|
if forward:
|
|
1082
1075
|
action_name = 'play_action'
|
|
1083
1076
|
else:
|
simo/generic/forms.py
CHANGED
|
@@ -202,7 +202,6 @@ class AlarmGroupConfigForm(BaseComponentForm):
|
|
|
202
202
|
"Can not cover self. Please remove - [%s]" % str(check_cmp)
|
|
203
203
|
)
|
|
204
204
|
if comp.base_type == 'alarm-group':
|
|
205
|
-
comp.prepare_controller()
|
|
206
205
|
self.recurse_check_alarm_groups(
|
|
207
206
|
comp.get_children(), check_cmp
|
|
208
207
|
)
|
|
@@ -227,7 +226,6 @@ class AlarmGroupConfigForm(BaseComponentForm):
|
|
|
227
226
|
c.save(update_fields=('config',))
|
|
228
227
|
if obj.id:
|
|
229
228
|
comp = Component.objects.get(id=obj.id)
|
|
230
|
-
comp.prepare_controller()
|
|
231
229
|
comp.refresh_status()
|
|
232
230
|
return obj
|
|
233
231
|
|
|
@@ -512,7 +510,6 @@ class AlarmClockEventForm(forms.Form):
|
|
|
512
510
|
if not self.cleaned_data.get('play_action'):
|
|
513
511
|
return self.cleaned_data
|
|
514
512
|
component = self.cleaned_data.get('component')
|
|
515
|
-
component.prepare_controller()
|
|
516
513
|
if not hasattr(component, self.cleaned_data['play_action']):
|
|
517
514
|
self.add_error(
|
|
518
515
|
'play_action',
|
simo/generic/gateways.py
CHANGED
|
@@ -175,7 +175,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
175
175
|
):
|
|
176
176
|
tz = pytz.timezone(thermostat.zone.instance.timezone)
|
|
177
177
|
timezone.activate(tz)
|
|
178
|
-
thermostat.prepare_controller()
|
|
179
178
|
thermostat.evaluate()
|
|
180
179
|
|
|
181
180
|
def watch_alarm_clocks(self):
|
|
@@ -185,7 +184,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
185
184
|
):
|
|
186
185
|
tz = pytz.timezone(alarm_clock.zone.instance.timezone)
|
|
187
186
|
timezone.activate(tz)
|
|
188
|
-
alarm_clock.prepare_controller()
|
|
189
187
|
alarm_clock.tick()
|
|
190
188
|
|
|
191
189
|
def watch_scripts(self):
|
|
@@ -194,7 +192,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
194
192
|
controller_uid=Script.uid,
|
|
195
193
|
config__autostart=True
|
|
196
194
|
).exclude(value='running'):
|
|
197
|
-
script.prepare_controller()
|
|
198
195
|
self.start_script(script)
|
|
199
196
|
|
|
200
197
|
def watch_watering(self):
|
|
@@ -202,7 +199,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
202
199
|
for watering in Component.objects.filter(controller_uid=Watering.uid):
|
|
203
200
|
tz = pytz.timezone(watering.zone.instance.timezone)
|
|
204
201
|
timezone.activate(tz)
|
|
205
|
-
watering.prepare_controller()
|
|
206
202
|
if watering.value['status'] == 'running_program':
|
|
207
203
|
watering.set_program_progress(
|
|
208
204
|
watering.value['program_progress'] + 1
|
|
@@ -333,11 +329,9 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
333
329
|
open_switch = Component.objects.get(
|
|
334
330
|
pk=blinds.config['open_switch']
|
|
335
331
|
)
|
|
336
|
-
open_switch.prepare_controller()
|
|
337
332
|
close_switch = Component.objects.get(
|
|
338
333
|
pk=blinds.config['close_switch']
|
|
339
334
|
)
|
|
340
|
-
close_switch.prepare_controller()
|
|
341
335
|
except:
|
|
342
336
|
return
|
|
343
337
|
|
|
@@ -406,7 +400,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
406
400
|
alarm_group.save()
|
|
407
401
|
|
|
408
402
|
for pk, other_group in other_alarm_groups.items():
|
|
409
|
-
other_group.prepare_controller()
|
|
410
403
|
other_group.refresh_status()
|
|
411
404
|
|
|
412
405
|
|
|
@@ -416,7 +409,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
416
409
|
).first()
|
|
417
410
|
if not switch:
|
|
418
411
|
return
|
|
419
|
-
switch.prepare_controller()
|
|
420
412
|
|
|
421
413
|
if gate.config.get('action_method') == 'click':
|
|
422
414
|
switch.click()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|