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.

Files changed (62) hide show
  1. simo/cli.py +2 -17
  2. simo/core/__pycache__/admin.cpython-38.pyc +0 -0
  3. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  4. simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/forms.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/managers.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  10. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  11. simo/core/admin.py +2 -2
  12. simo/core/api.py +46 -4
  13. simo/core/controllers.py +14 -7
  14. simo/core/forms.py +2 -2
  15. simo/core/managers.py +1 -5
  16. simo/core/migrations/0003_create_default_zones_and_categories.py +2 -39
  17. simo/core/migrations/0004_create_generic.py +22 -21
  18. simo/core/migrations/0013_auto_20231003_0754.py +45 -43
  19. simo/core/migrations/0018_auto_20231005_0622.py +18 -16
  20. simo/core/migrations/0033_auto_20240509_0821.py +25 -0
  21. simo/core/migrations/0034_component_error_msg.py +18 -0
  22. simo/core/migrations/0035_remove_instance_share_location.py +17 -0
  23. simo/core/migrations/0036_auto_20240521_0823.py +22 -0
  24. simo/core/migrations/__pycache__/0003_create_default_zones_and_categories.cpython-38.pyc +0 -0
  25. simo/core/migrations/__pycache__/0004_create_generic.cpython-38.pyc +0 -0
  26. simo/core/migrations/__pycache__/0013_auto_20231003_0754.cpython-38.pyc +0 -0
  27. simo/core/migrations/__pycache__/0018_auto_20231005_0622.cpython-38.pyc +0 -0
  28. simo/core/migrations/__pycache__/0033_auto_20240509_0821.cpython-38.pyc +0 -0
  29. simo/core/migrations/__pycache__/0034_component_error_msg.cpython-38.pyc +0 -0
  30. simo/core/migrations/__pycache__/0035_remove_instance_share_location.cpython-38.pyc +0 -0
  31. simo/core/migrations/__pycache__/0036_auto_20240521_0823.cpython-38.pyc +0 -0
  32. simo/core/models.py +26 -26
  33. simo/core/serializers.py +12 -9
  34. simo/core/signal_receivers.py +82 -1
  35. simo/core/tasks.py +7 -4
  36. simo/fleet/__pycache__/admin.cpython-38.pyc +0 -0
  37. simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
  38. simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
  39. simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
  40. simo/fleet/__pycache__/serializers.cpython-38.pyc +0 -0
  41. simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  42. simo/fleet/admin.py +25 -6
  43. simo/fleet/controllers.py +97 -36
  44. simo/fleet/forms.py +162 -9
  45. simo/fleet/migrations/0035_auto_20240514_0855.py +32 -0
  46. simo/fleet/migrations/__pycache__/0035_auto_20240514_0855.cpython-38.pyc +0 -0
  47. simo/fleet/models.py +97 -82
  48. simo/fleet/serializers.py +8 -1
  49. simo/fleet/socket_consumers.py +3 -15
  50. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  51. simo/users/__pycache__/utils.cpython-38.pyc +0 -0
  52. simo/users/migrations/0003_create_roles_and_system_user.py +24 -23
  53. simo/users/migrations/0019_auto_20231221_1155.py +9 -8
  54. simo/users/migrations/__pycache__/0003_create_roles_and_system_user.cpython-38.pyc +0 -0
  55. simo/users/migrations/__pycache__/0019_auto_20231221_1155.cpython-38.pyc +0 -0
  56. simo/users/models.py +6 -7
  57. simo/users/utils.py +0 -4
  58. {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/METADATA +1 -1
  59. {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/RECORD +62 -52
  60. {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/LICENSE.md +0 -0
  61. {simo-2.0.32.dist-info → simo-2.0.34.dist-info}/WHEEL +0 -0
  62. {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
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', 'alive',
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', 'arm_status', 'battery_level',
556
- 'alive', 'meta'
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(self, value, is_alive=True, battery_level=None):
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(self, value, is_alive=True, battery_level=None):
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, is_alive=is_alive, battery_level=battery_level
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
- core_dir_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
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
- Icon = apps.get_model("core", "Icon")
9
- Zone = apps.get_model("core", "Zone")
10
- Category = apps.get_model("core", "Category")
11
- Gateway = apps.get_model("core", "Gateway")
12
- Component = apps.get_model("core", "Component")
13
-
14
- generic, new = Gateway.objects.get_or_create(
15
- type='simo.generic.gateways.GenericGatewayHandler'
16
- )
17
- weather_icon = Icon.objects.get(slug='cloud-bolt-sun')
18
- other_zone = Zone.objects.get(name='Other')
19
- climate_category = Category.objects.get(name='Climate')
20
- Component.objects.create(
21
- name='Weather', icon=weather_icon,
22
- zone=other_zone,
23
- category=climate_category,
24
- gateway=generic, base_type='weather-forecast',
25
- controller_uid='simo.generic.controllers.WeatherForecast',
26
- config={'is_main': True}
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
- Instance = apps.get_model("core", "Instance")
7
- Component = apps.get_model("core", "Component")
8
- GlobalPreferenceModel = apps.get_model(
9
- 'dynamic_preferences', "GlobalPreferenceModel"
10
- )
11
-
12
- Instance.objects.create(
13
- uid=GlobalPreferenceModel.objects.get(
14
- section='core', name='hub_uid'
15
- ).raw_value,
16
- name=GlobalPreferenceModel.objects.get(
17
- section='core', name='hub_name'
18
- ).raw_value,
19
- cover_image=GlobalPreferenceModel.objects.get(
20
- section='core', name='cover_image'
21
- ).raw_value,
22
- cover_image_synced=True,
23
- secret_key=GlobalPreferenceModel.objects.get(
24
- section='core', name='hub_secret'
25
- ).raw_value,
26
- location=GlobalPreferenceModel.objects.get(
27
- section='core', name='location_coordinates'
28
- ).raw_value,
29
- timezone=GlobalPreferenceModel.objects.get(
30
- section='core', name='time_zone'
31
- ).raw_value,
32
- units_of_measure=GlobalPreferenceModel.objects.get(
33
- section='core', name='units_of_measure'
34
- ).raw_value,
35
- share_location=True,
36
- remote_http=GlobalPreferenceModel.objects.get(
37
- section='core', name='remote_http'
38
- ).raw_value,
39
- remote_connection_version=int(GlobalPreferenceModel.objects.get(
40
- section='core', name='remote_conn_version'
41
- ).raw_value),
42
- indoor_climate_sensor=Component(id=int(GlobalPreferenceModel.objects.get(
43
- section='core', name='indoor_climate_sensor'
44
- ).raw_value)),
45
- history_days=int(GlobalPreferenceModel.objects.get(
46
- section='core', name='history_days'
47
- ).raw_value)
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
- Instance = apps.get_model("core", "Instance")
8
- GlobalPreferenceModel = apps.get_model(
9
- 'dynamic_preferences', "GlobalPreferenceModel"
10
- )
11
-
12
- instance = Instance.objects.all().first()
13
- GlobalPreferenceModel.objects.update_or_create(
14
- section='core', name='hub_uid', defaults={
15
- 'raw_value': instance.uid
16
- }
17
- )
18
- GlobalPreferenceModel.objects.update_or_create(
19
- section='core', name='hub_secret', defaults={
20
- 'raw_value': instance.secret_key
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
+ ]