simo 2.0.32__py3-none-any.whl → 2.0.34__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/cli.py +2 -17
- simo/core/__pycache__/admin.cpython-38.pyc +0 -0
- simo/core/__pycache__/api.cpython-38.pyc +0 -0
- simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/core/__pycache__/forms.cpython-38.pyc +0 -0
- simo/core/__pycache__/managers.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__/signal_receivers.cpython-38.pyc +0 -0
- simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
- simo/core/admin.py +2 -2
- simo/core/api.py +46 -4
- simo/core/controllers.py +14 -7
- simo/core/forms.py +2 -2
- simo/core/managers.py +1 -5
- simo/core/migrations/0003_create_default_zones_and_categories.py +2 -39
- simo/core/migrations/0004_create_generic.py +22 -21
- simo/core/migrations/0013_auto_20231003_0754.py +45 -43
- simo/core/migrations/0018_auto_20231005_0622.py +18 -16
- simo/core/migrations/0033_auto_20240509_0821.py +25 -0
- simo/core/migrations/0034_component_error_msg.py +18 -0
- simo/core/migrations/0035_remove_instance_share_location.py +17 -0
- simo/core/migrations/0036_auto_20240521_0823.py +22 -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__/0013_auto_20231003_0754.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0018_auto_20231005_0622.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0033_auto_20240509_0821.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0034_component_error_msg.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0035_remove_instance_share_location.cpython-38.pyc +0 -0
- simo/core/migrations/__pycache__/0036_auto_20240521_0823.cpython-38.pyc +0 -0
- simo/core/models.py +26 -26
- simo/core/serializers.py +12 -9
- simo/core/signal_receivers.py +82 -1
- simo/core/tasks.py +7 -4
- simo/fleet/__pycache__/admin.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__/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/admin.py +25 -6
- simo/fleet/controllers.py +97 -36
- simo/fleet/forms.py +162 -9
- simo/fleet/migrations/0035_auto_20240514_0855.py +32 -0
- simo/fleet/migrations/__pycache__/0035_auto_20240514_0855.cpython-38.pyc +0 -0
- simo/fleet/models.py +97 -82
- simo/fleet/serializers.py +8 -1
- simo/fleet/socket_consumers.py +3 -15
- simo/users/__pycache__/models.cpython-38.pyc +0 -0
- simo/users/__pycache__/utils.cpython-38.pyc +0 -0
- simo/users/migrations/0003_create_roles_and_system_user.py +24 -23
- simo/users/migrations/0019_auto_20231221_1155.py +9 -8
- simo/users/migrations/__pycache__/0003_create_roles_and_system_user.cpython-38.pyc +0 -0
- simo/users/migrations/__pycache__/0019_auto_20231221_1155.cpython-38.pyc +0 -0
- simo/users/models.py +6 -7
- simo/users/utils.py +0 -4
- {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/METADATA +1 -1
- {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/RECORD +62 -52
- {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/LICENSE.md +0 -0
- {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/WHEEL +0 -0
- {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/top_level.txt +0 -0
simo/cli.py
CHANGED
|
@@ -3,48 +3,35 @@ import sys
|
|
|
3
3
|
import click
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
|
-
import requests
|
|
7
|
-
from subprocess import Popen, PIPE
|
|
8
6
|
import simo
|
|
9
7
|
from django.template import Context, Engine
|
|
10
8
|
from django.core.management.utils import get_random_secret_key
|
|
11
9
|
|
|
12
10
|
|
|
13
|
-
template_file_extensions = ['.py', '.conf']
|
|
14
|
-
|
|
15
|
-
|
|
16
11
|
def copy_default_template(to_directory='/etc/SIMO'):
|
|
12
|
+
template_file_extensions = ['.py', '.conf']
|
|
13
|
+
|
|
17
14
|
context = Context({
|
|
18
15
|
'secret_key': get_random_secret_key(),
|
|
19
16
|
'project_dir': to_directory,
|
|
20
17
|
'base_dir': to_directory
|
|
21
18
|
}, autoescape=False)
|
|
22
|
-
|
|
23
|
-
|
|
24
19
|
template_dir = os.path.join(
|
|
25
20
|
os.path.dirname(simo.__file__), '_hub_template'
|
|
26
21
|
)
|
|
27
|
-
|
|
28
22
|
prefix_length = len(template_dir) + 1
|
|
29
|
-
|
|
30
23
|
for root, dirs, files in os.walk(template_dir):
|
|
31
|
-
|
|
32
24
|
relative_dir = root[prefix_length:]
|
|
33
25
|
target_dir = os.path.join(to_directory, relative_dir)
|
|
34
26
|
os.makedirs(target_dir, exist_ok=True)
|
|
35
|
-
|
|
36
27
|
for filename in files:
|
|
37
28
|
if filename.endswith(('.pyo', '.pyc', '.py.class')):
|
|
38
29
|
# Ignore some files as they cause various breakages.
|
|
39
30
|
continue
|
|
40
|
-
|
|
41
31
|
old_path = os.path.join(root, filename)
|
|
42
32
|
new_path = os.path.join(target_dir, filename)
|
|
43
|
-
|
|
44
33
|
os.makedirs(target_dir, exist_ok=True)
|
|
45
|
-
|
|
46
34
|
fn, file_extension = os.path.splitext(new_path)
|
|
47
|
-
|
|
48
35
|
if file_extension in template_file_extensions:
|
|
49
36
|
with open(old_path, encoding='utf-8') as template_file:
|
|
50
37
|
content = template_file.read()
|
|
@@ -54,9 +41,7 @@ def copy_default_template(to_directory='/etc/SIMO'):
|
|
|
54
41
|
new_file.write(content)
|
|
55
42
|
else:
|
|
56
43
|
shutil.copyfile(old_path, new_path)
|
|
57
|
-
|
|
58
44
|
shutil.copymode(old_path, new_path)
|
|
59
|
-
|
|
60
45
|
for dirname in dirs[:]:
|
|
61
46
|
if dirname.startswith('.') or dirname == '__pycache__':
|
|
62
47
|
dirs.remove(dirname)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/core/admin.py
CHANGED
|
@@ -261,8 +261,8 @@ class ComponentAdmin(admin.ModelAdmin):
|
|
|
261
261
|
'alarm_category', 'show_in_app',
|
|
262
262
|
)
|
|
263
263
|
readonly_fields = (
|
|
264
|
-
'id', 'controller_uid', 'base_type', 'gateway', 'config',
|
|
265
|
-
'battery_level',
|
|
264
|
+
'id', 'controller_uid', 'base_type', 'gateway', 'config',
|
|
265
|
+
'alive', 'error_msg', 'battery_level',
|
|
266
266
|
'control', 'value', 'arm_status', 'history', 'meta'
|
|
267
267
|
)
|
|
268
268
|
list_filter = (
|
simo/core/api.py
CHANGED
|
@@ -125,6 +125,22 @@ class ZoneViewSet(InstanceMixin, viewsets.ModelViewSet):
|
|
|
125
125
|
serializer.validated_data['instance'] = self.instance
|
|
126
126
|
serializer.save()
|
|
127
127
|
|
|
128
|
+
@action(detail=False, methods=['post'])
|
|
129
|
+
def reorder(self, request, pk=None, *args, **kwargs):
|
|
130
|
+
data = request.data
|
|
131
|
+
if not isinstance(request.data, dict):
|
|
132
|
+
data = data.dict()
|
|
133
|
+
request_data = restore_json(data)
|
|
134
|
+
zones = {str(z.id): z for z in Zone.objects.filter(instance=self.instance)}
|
|
135
|
+
if len(request_data.get('zones', [])) != len(zones):
|
|
136
|
+
raise APIValidationError(
|
|
137
|
+
_('All zones must be provided to perform reorder.'), code=400
|
|
138
|
+
)
|
|
139
|
+
for i, id in enumerate(request_data.get('zones')):
|
|
140
|
+
zones[str(id)].order = i
|
|
141
|
+
Zone.objects.bulk_update([z for id, z in zones.items()], fields=['order'])
|
|
142
|
+
return RESTResponse({'status': 'success'})
|
|
143
|
+
|
|
128
144
|
|
|
129
145
|
def get_components_queryset(instance, user):
|
|
130
146
|
qs = Component.objects.filter(zone__instance=instance)
|
|
@@ -552,15 +568,32 @@ class StatesViewSet(InstanceMixin, viewsets.GenericViewSet):
|
|
|
552
568
|
component_values = get_components_queryset(
|
|
553
569
|
self.instance, request.user
|
|
554
570
|
).filter(zone__instance=self.instance).values(
|
|
555
|
-
'id', 'value', 'last_change', '
|
|
556
|
-
'alive', '
|
|
571
|
+
'id', 'value', 'last_change', 'last_modified',
|
|
572
|
+
'arm_status', 'battery_level', 'alive', 'error_msg',
|
|
573
|
+
'meta'
|
|
557
574
|
)
|
|
558
575
|
for vals in component_values:
|
|
559
576
|
vals['last_change'] = datetime.datetime.timestamp(
|
|
560
577
|
vals['last_change']
|
|
561
578
|
)
|
|
579
|
+
vals['last_modified'] = datetime.datetime.timestamp(
|
|
580
|
+
vals['last_modified']
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
categories = Category.objects.filter(instance=self.instance).values(
|
|
584
|
+
'id', 'last_modified'
|
|
585
|
+
)
|
|
586
|
+
for cat in categories:
|
|
587
|
+
cat['last_modified'] = datetime.datetime.timestamp(
|
|
588
|
+
cat['last_modified']
|
|
589
|
+
)
|
|
590
|
+
|
|
562
591
|
|
|
563
592
|
return RESTResponse({
|
|
593
|
+
'zones': Zone.objects.filter(instance=self.instance).values(
|
|
594
|
+
'id', 'name'
|
|
595
|
+
),
|
|
596
|
+
'categories': categories,
|
|
564
597
|
'component_values': component_values,
|
|
565
598
|
'users': UserSerializer(
|
|
566
599
|
users_qs, many=True, context={
|
|
@@ -591,7 +624,8 @@ class ControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
|
591
624
|
'uid': uid,
|
|
592
625
|
'name': cls.name,
|
|
593
626
|
'is_discoverable': cls.is_discoverable,
|
|
594
|
-
'manual_add': cls.manual_add
|
|
627
|
+
'manual_add': cls.manual_add,
|
|
628
|
+
'discovery_msg': cls.discovery_msg
|
|
595
629
|
})
|
|
596
630
|
|
|
597
631
|
return RESTResponse(data)
|
|
@@ -634,10 +668,18 @@ class RunningDiscoveries(InstanceMixin, viewsets.GenericViewSet):
|
|
|
634
668
|
def list(self, request, *args, **kwargs):
|
|
635
669
|
return RESTResponse(self.get_data(self.get_gateways(request)))
|
|
636
670
|
|
|
637
|
-
@action(detail=False, methods=['get'])
|
|
671
|
+
@action(detail=False, methods=['get', 'post'])
|
|
638
672
|
def retry(self, request, *args, **kwargs):
|
|
639
673
|
gateways = self.get_gateways(request)
|
|
640
674
|
if 'controller_uid' in request.GET:
|
|
641
675
|
for gateway in gateways:
|
|
642
676
|
gateway.retry_discovery()
|
|
677
|
+
return RESTResponse(self.get_data(gateways))
|
|
678
|
+
|
|
679
|
+
@action(detail=False, methods=['get', 'post'])
|
|
680
|
+
def finish(self, request, *args, **kwargs):
|
|
681
|
+
gateways = self.get_gateways(request)
|
|
682
|
+
if 'controller_uid' in request.GET:
|
|
683
|
+
for gateway in gateways:
|
|
684
|
+
gateway.finish_discovery()
|
|
643
685
|
return RESTResponse(self.get_data(gateways))
|
simo/core/controllers.py
CHANGED
|
@@ -33,8 +33,10 @@ class ControllerBase(ABC):
|
|
|
33
33
|
admin_widget_template = 'admin/controller_widgets/generic.html'
|
|
34
34
|
default_config = {}
|
|
35
35
|
default_meta = {}
|
|
36
|
+
default_value_units = None
|
|
36
37
|
discovery_msg = None
|
|
37
38
|
manual_add = True # Can be added manually
|
|
39
|
+
family = None
|
|
38
40
|
|
|
39
41
|
@property
|
|
40
42
|
@abstractmethod
|
|
@@ -187,8 +189,6 @@ class ControllerBase(ABC):
|
|
|
187
189
|
bulk_send_map = {self.component: value}
|
|
188
190
|
for slave in self.component.slaves.all():
|
|
189
191
|
bulk_send_map[slave] = value
|
|
190
|
-
|
|
191
|
-
print("BULK SEND MAP: ", bulk_send_map)
|
|
192
192
|
from .models import Component
|
|
193
193
|
Component.objects.bulk_send(bulk_send_map)
|
|
194
194
|
return
|
|
@@ -232,7 +232,9 @@ class ControllerBase(ABC):
|
|
|
232
232
|
self.component.change_init_fingerprint = None
|
|
233
233
|
self.component.save()
|
|
234
234
|
|
|
235
|
-
def _receive_from_device(
|
|
235
|
+
def _receive_from_device(
|
|
236
|
+
self, value, is_alive=True, battery_level=None, error_msg=None
|
|
237
|
+
):
|
|
236
238
|
value = self._prepare_for_set(value)
|
|
237
239
|
actor = self._get_actor(value)
|
|
238
240
|
|
|
@@ -245,9 +247,11 @@ class ControllerBase(ABC):
|
|
|
245
247
|
# in relation to the change of this component
|
|
246
248
|
introduce(actor)
|
|
247
249
|
self.component.alive = is_alive
|
|
250
|
+
if error_msg != None:
|
|
251
|
+
self.component.error_msg = error_msg if error_msg.strip() else None
|
|
248
252
|
if battery_level:
|
|
249
253
|
self.component.battery_level = battery_level
|
|
250
|
-
self.component.save(update_fields=['alive', 'battery_level'])
|
|
254
|
+
self.component.save(update_fields=['alive', 'battery_level', 'error_msg'])
|
|
251
255
|
self.set(value, actor)
|
|
252
256
|
|
|
253
257
|
if init_by_device and self.component.slaves.count():
|
|
@@ -465,7 +469,7 @@ class Dimmer(ControllerBase, TimerMixin, OnOffPokerMixin):
|
|
|
465
469
|
admin_widget_template = 'admin/controller_widgets/knob.html'
|
|
466
470
|
default_config = {'min': 0.0, 'max': 100.0, 'inverse': False}
|
|
467
471
|
default_value = 0
|
|
468
|
-
|
|
472
|
+
default_value_units = '%'
|
|
469
473
|
|
|
470
474
|
def _prepare_for_send(self, value):
|
|
471
475
|
if isinstance(value, bool):
|
|
@@ -759,6 +763,7 @@ class Lock(Switch):
|
|
|
759
763
|
base_type = 'lock'
|
|
760
764
|
app_widget = LockWidget
|
|
761
765
|
admin_widget_template = 'admin/controller_widgets/lock.html'
|
|
766
|
+
default_value = 'unlocked'
|
|
762
767
|
|
|
763
768
|
UNLOCKED = 0
|
|
764
769
|
LOCKED = 1
|
|
@@ -772,7 +777,9 @@ class Lock(Switch):
|
|
|
772
777
|
def unlock(self):
|
|
773
778
|
self.turn_off()
|
|
774
779
|
|
|
775
|
-
def _receive_from_device(
|
|
780
|
+
def _receive_from_device(
|
|
781
|
+
self, value, *args, **kwargs
|
|
782
|
+
):
|
|
776
783
|
if type(value) == bool:
|
|
777
784
|
if value:
|
|
778
785
|
value = 'locked'
|
|
@@ -788,7 +795,7 @@ class Lock(Switch):
|
|
|
788
795
|
}
|
|
789
796
|
value = values_map.get(value, 'fault')
|
|
790
797
|
return super()._receive_from_device(
|
|
791
|
-
value,
|
|
798
|
+
value, *args, **kwargs
|
|
792
799
|
)
|
|
793
800
|
|
|
794
801
|
def _validate_val(self, value, occasion=None):
|
simo/core/forms.py
CHANGED
|
@@ -323,6 +323,7 @@ class ComponentAdminForm(forms.ModelForm):
|
|
|
323
323
|
self.instance.controller_uid = ControllerClass.uid
|
|
324
324
|
self.instance.base_type = self.controller.base_type
|
|
325
325
|
self.instance.value = self.controller.default_value
|
|
326
|
+
self.instance.value_units = self.controller.default_value_units
|
|
326
327
|
self.instance.value_previous = self.controller.default_value
|
|
327
328
|
self.instance.config = self.controller.default_config
|
|
328
329
|
self.instance.meta = self.controller.default_meta
|
|
@@ -393,7 +394,7 @@ class ComponentAdminForm(forms.ModelForm):
|
|
|
393
394
|
fieldsets.extend([
|
|
394
395
|
(_("Meta"), {
|
|
395
396
|
'fields': (
|
|
396
|
-
'alive', 'battery_level',
|
|
397
|
+
'alive', 'error_msg', 'battery_level',
|
|
397
398
|
'config', 'meta',
|
|
398
399
|
'value', 'value_units',
|
|
399
400
|
'history'
|
|
@@ -684,7 +685,6 @@ class DimmerConfigForm(BaseComponentForm):
|
|
|
684
685
|
return validate_slaves(self.cleaned_data['slaves'], self.instance)
|
|
685
686
|
|
|
686
687
|
def save(self, commit=True):
|
|
687
|
-
self.instance.config['output_pin_no'] = self.cleaned_data['output_pin'].no
|
|
688
688
|
obj = super().save(commit=commit)
|
|
689
689
|
if commit:
|
|
690
690
|
obj.slaves.set(self.cleaned_data['slaves'])
|
simo/core/managers.py
CHANGED
|
@@ -71,11 +71,7 @@ class ComponentsManager(models.Manager):
|
|
|
71
71
|
gateway_components[comp.gateway] = {}
|
|
72
72
|
gateway_components[comp.gateway][comp.id] = value
|
|
73
73
|
|
|
74
|
-
print("BULK SEND: ", gateway_components)
|
|
75
74
|
for gateway, send_vals in gateway_components.items():
|
|
76
75
|
GatewayObjectCommand(gateway, bulk_send=send_vals).publish(
|
|
77
76
|
retain=False
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
)
|
|
@@ -1,47 +1,10 @@
|
|
|
1
1
|
# Generated by Django 2.2.12 on 2021-11-04 14:10
|
|
2
|
-
import os
|
|
3
|
-
import shutil
|
|
4
2
|
from django.db import migrations
|
|
5
|
-
from django.conf import settings
|
|
6
3
|
|
|
7
4
|
|
|
8
5
|
def create_objects(apps, schema_editor):
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
imgs_folder = os.path.join(
|
|
12
|
-
core_dir_path, 'static/defaults/category_headers'
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
Icon = apps.get_model("core", "Icon")
|
|
16
|
-
Zone = apps.get_model("core", "Zone")
|
|
17
|
-
Category = apps.get_model("core", "Category")
|
|
18
|
-
|
|
19
|
-
for zone_name in (
|
|
20
|
-
'Living Room', 'Kitchen', 'Bathroom', 'Porch', 'Garage', 'Yard', 'Other'
|
|
21
|
-
):
|
|
22
|
-
Zone.objects.create(name=zone_name)
|
|
23
|
-
|
|
24
|
-
categories_media_dir = os.path.join(settings.MEDIA_ROOT, 'categories')
|
|
25
|
-
if not os.path.exists(categories_media_dir):
|
|
26
|
-
os.makedirs(categories_media_dir)
|
|
27
|
-
|
|
28
|
-
for i, data in enumerate([
|
|
29
|
-
("All", 'star'), ("Climate", 'temperature-half'),
|
|
30
|
-
("Lights", 'lightbulb'), ("Security", 'eye'),
|
|
31
|
-
("Watering", 'faucet'), ("Other", 'flag-pennant')
|
|
32
|
-
]):
|
|
33
|
-
shutil.copy(
|
|
34
|
-
os.path.join(imgs_folder, "%s.jpg" % data[0].lower()),
|
|
35
|
-
os.path.join(
|
|
36
|
-
settings.MEDIA_ROOT, 'categories', "%s.jpg" % data[0].lower()
|
|
37
|
-
)
|
|
38
|
-
)
|
|
39
|
-
Category.objects.create(
|
|
40
|
-
name=data[0], icon=Icon.objects.get(slug=data[1]),
|
|
41
|
-
all=i==0, header_image=os.path.join(
|
|
42
|
-
'categories', "%s.jpg" % data[0].lower()
|
|
43
|
-
), order=i+10
|
|
44
|
-
)
|
|
6
|
+
# legacy..
|
|
7
|
+
pass
|
|
45
8
|
|
|
46
9
|
|
|
47
10
|
def delete_objects(apps, schema_editor):
|
|
@@ -4,27 +4,28 @@ from django.db import migrations
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def create_objects(apps, schema_editor):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
pass
|
|
8
|
+
# legacy
|
|
9
|
+
# Icon = apps.get_model("core", "Icon")
|
|
10
|
+
# Zone = apps.get_model("core", "Zone")
|
|
11
|
+
# Category = apps.get_model("core", "Category")
|
|
12
|
+
# Gateway = apps.get_model("core", "Gateway")
|
|
13
|
+
# Component = apps.get_model("core", "Component")
|
|
14
|
+
#
|
|
15
|
+
# generic, new = Gateway.objects.get_or_create(
|
|
16
|
+
# type='simo.generic.gateways.GenericGatewayHandler'
|
|
17
|
+
# )
|
|
18
|
+
# weather_icon = Icon.objects.get(slug='cloud-bolt-sun')
|
|
19
|
+
# other_zone = Zone.objects.get(name='Other')
|
|
20
|
+
# climate_category = Category.objects.get(name='Climate')
|
|
21
|
+
# Component.objects.create(
|
|
22
|
+
# name='Weather', icon=weather_icon,
|
|
23
|
+
# zone=other_zone,
|
|
24
|
+
# category=climate_category,
|
|
25
|
+
# gateway=generic, base_type='weather-forecast',
|
|
26
|
+
# controller_uid='simo.generic.controllers.WeatherForecast',
|
|
27
|
+
# config={'is_main': True}
|
|
28
|
+
# )
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
def delete_objects(apps, schema_editor):
|
|
@@ -3,49 +3,51 @@ from django.db import migrations
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def forwards_func(apps, schema_editor):
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
6
|
+
pass
|
|
7
|
+
# legacy
|
|
8
|
+
# Instance = apps.get_model("core", "Instance")
|
|
9
|
+
# Component = apps.get_model("core", "Component")
|
|
10
|
+
# GlobalPreferenceModel = apps.get_model(
|
|
11
|
+
# 'dynamic_preferences', "GlobalPreferenceModel"
|
|
12
|
+
# )
|
|
13
|
+
#
|
|
14
|
+
# Instance.objects.create(
|
|
15
|
+
# uid=GlobalPreferenceModel.objects.get(
|
|
16
|
+
# section='core', name='hub_uid'
|
|
17
|
+
# ).raw_value,
|
|
18
|
+
# name=GlobalPreferenceModel.objects.get(
|
|
19
|
+
# section='core', name='hub_name'
|
|
20
|
+
# ).raw_value,
|
|
21
|
+
# cover_image=GlobalPreferenceModel.objects.get(
|
|
22
|
+
# section='core', name='cover_image'
|
|
23
|
+
# ).raw_value,
|
|
24
|
+
# cover_image_synced=True,
|
|
25
|
+
# secret_key=GlobalPreferenceModel.objects.get(
|
|
26
|
+
# section='core', name='hub_secret'
|
|
27
|
+
# ).raw_value,
|
|
28
|
+
# location=GlobalPreferenceModel.objects.get(
|
|
29
|
+
# section='core', name='location_coordinates'
|
|
30
|
+
# ).raw_value,
|
|
31
|
+
# timezone=GlobalPreferenceModel.objects.get(
|
|
32
|
+
# section='core', name='time_zone'
|
|
33
|
+
# ).raw_value,
|
|
34
|
+
# units_of_measure=GlobalPreferenceModel.objects.get(
|
|
35
|
+
# section='core', name='units_of_measure'
|
|
36
|
+
# ).raw_value,
|
|
37
|
+
# share_location=True,
|
|
38
|
+
# remote_http=GlobalPreferenceModel.objects.get(
|
|
39
|
+
# section='core', name='remote_http'
|
|
40
|
+
# ).raw_value,
|
|
41
|
+
# remote_connection_version=int(GlobalPreferenceModel.objects.get(
|
|
42
|
+
# section='core', name='remote_conn_version'
|
|
43
|
+
# ).raw_value),
|
|
44
|
+
# indoor_climate_sensor=Component(id=int(GlobalPreferenceModel.objects.get(
|
|
45
|
+
# section='core', name='indoor_climate_sensor'
|
|
46
|
+
# ).raw_value)),
|
|
47
|
+
# history_days=int(GlobalPreferenceModel.objects.get(
|
|
48
|
+
# section='core', name='history_days'
|
|
49
|
+
# ).raw_value)
|
|
50
|
+
# )
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
def reverse_func(apps, schema_editor):
|
|
@@ -4,22 +4,24 @@ from django.db import migrations
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def forwards_func(apps, schema_editor):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
pass
|
|
8
|
+
# legacy
|
|
9
|
+
# Instance = apps.get_model("core", "Instance")
|
|
10
|
+
# GlobalPreferenceModel = apps.get_model(
|
|
11
|
+
# 'dynamic_preferences', "GlobalPreferenceModel"
|
|
12
|
+
# )
|
|
13
|
+
#
|
|
14
|
+
# instance = Instance.objects.all().first()
|
|
15
|
+
# GlobalPreferenceModel.objects.update_or_create(
|
|
16
|
+
# section='core', name='hub_uid', defaults={
|
|
17
|
+
# 'raw_value': instance.uid
|
|
18
|
+
# }
|
|
19
|
+
# )
|
|
20
|
+
# GlobalPreferenceModel.objects.update_or_create(
|
|
21
|
+
# section='core', name='hub_secret', defaults={
|
|
22
|
+
# 'raw_value': instance.secret_key
|
|
23
|
+
# }
|
|
24
|
+
# )
|
|
23
25
|
|
|
24
26
|
def reverse_func(apps, schema_editor):
|
|
25
27
|
pass
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2024-05-09 08:21
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
import django.utils.timezone
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('core', '0032_auto_20240506_0834'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name='component',
|
|
16
|
+
name='last_modified',
|
|
17
|
+
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Last time component was modified.'),
|
|
18
|
+
preserve_default=False,
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name='component',
|
|
22
|
+
name='last_change',
|
|
23
|
+
field=models.DateTimeField(auto_now_add=True, help_text='Last time component state was changed.', null=True),
|
|
24
|
+
),
|
|
25
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2024-05-09 10:25
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('core', '0033_auto_20240509_0821'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name='component',
|
|
15
|
+
name='error_msg',
|
|
16
|
+
field=models.TextField(blank=True, editable=False, null=True),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2024-05-20 11:46
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('core', '0034_component_error_msg'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name='instance',
|
|
15
|
+
name='share_location',
|
|
16
|
+
),
|
|
17
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated by Django 3.2.9 on 2024-05-21 08:23
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('core', '0035_remove_instance_share_location'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name='category',
|
|
15
|
+
name='header_image_last_change',
|
|
16
|
+
),
|
|
17
|
+
migrations.AddField(
|
|
18
|
+
model_name='category',
|
|
19
|
+
name='last_modified',
|
|
20
|
+
field=models.DateTimeField(auto_now=True),
|
|
21
|
+
),
|
|
22
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|