simo 1.6.2__tar.gz → 1.6.4__tar.gz

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 (167) hide show
  1. {simo-1.6.2/src/simo.egg-info → simo-1.6.4}/PKG-INFO +1 -1
  2. {simo-1.6.2 → simo-1.6.4}/pyproject.toml +1 -1
  3. {simo-1.6.2 → simo-1.6.4}/src/simo/core/api.py +0 -1
  4. {simo-1.6.2 → simo-1.6.4}/src/simo/core/apps.py +1 -1
  5. {simo-1.6.2 → simo-1.6.4}/src/simo/core/autocomplete_views.py +4 -5
  6. {simo-1.6.2 → simo-1.6.4}/src/simo/core/events.py +56 -0
  7. {simo-1.6.2 → simo-1.6.4}/src/simo/core/middleware.py +1 -7
  8. simo-1.6.4/src/simo/core/migrations/0022_auto_20231221_0735.py +23 -0
  9. {simo-1.6.2 → simo-1.6.4}/src/simo/core/models.py +3 -49
  10. {simo-1.6.2 → simo-1.6.4}/src/simo/core/socket_consumers.py +1 -1
  11. {simo-1.6.2 → simo-1.6.4}/src/simo/core/widgets.py +9 -0
  12. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/controllers.py +1 -0
  13. {simo-1.6.2 → simo-1.6.4}/src/simo/users/admin.py +6 -6
  14. {simo-1.6.2 → simo-1.6.4}/src/simo/users/api.py +13 -17
  15. {simo-1.6.2 → simo-1.6.4}/src/simo/users/auth_backends.py +2 -2
  16. simo-1.6.4/src/simo/users/migrations/0017_auto_20231221_0735.py +22 -0
  17. {simo-1.6.2 → simo-1.6.4}/src/simo/users/models.py +23 -4
  18. {simo-1.6.2 → simo-1.6.4}/src/simo/users/serializers.py +2 -2
  19. {simo-1.6.2 → simo-1.6.4/src/simo.egg-info}/PKG-INFO +1 -1
  20. {simo-1.6.2 → simo-1.6.4}/src/simo.egg-info/SOURCES.txt +2 -0
  21. {simo-1.6.2 → simo-1.6.4}/LICENSE.md +0 -0
  22. {simo-1.6.2 → simo-1.6.4}/README.rst +0 -0
  23. {simo-1.6.2 → simo-1.6.4}/requirements.txt +0 -0
  24. {simo-1.6.2 → simo-1.6.4}/setup.cfg +0 -0
  25. {simo-1.6.2 → simo-1.6.4}/src/simo/__init__.py +0 -0
  26. {simo-1.6.2 → simo-1.6.4}/src/simo/_hub_template/hub/asgi.py +0 -0
  27. {simo-1.6.2 → simo-1.6.4}/src/simo/_hub_template/hub/celeryc.py +0 -0
  28. {simo-1.6.2 → simo-1.6.4}/src/simo/_hub_template/hub/manage.py +0 -0
  29. {simo-1.6.2 → simo-1.6.4}/src/simo/_hub_template/hub/settings.py +0 -0
  30. {simo-1.6.2 → simo-1.6.4}/src/simo/_hub_template/hub/urls.py +0 -0
  31. {simo-1.6.2 → simo-1.6.4}/src/simo/asgi.py +0 -0
  32. {simo-1.6.2 → simo-1.6.4}/src/simo/auto_update.py +0 -0
  33. {simo-1.6.2 → simo-1.6.4}/src/simo/celeryc.py +0 -0
  34. {simo-1.6.2 → simo-1.6.4}/src/simo/cli.py +0 -0
  35. {simo-1.6.2 → simo-1.6.4}/src/simo/conf.py +0 -0
  36. {simo-1.6.2 → simo-1.6.4}/src/simo/core/__init__.py +0 -0
  37. {simo-1.6.2 → simo-1.6.4}/src/simo/core/admin.py +0 -0
  38. {simo-1.6.2 → simo-1.6.4}/src/simo/core/api_auth.py +0 -0
  39. {simo-1.6.2 → simo-1.6.4}/src/simo/core/app_widgets.py +0 -0
  40. {simo-1.6.2 → simo-1.6.4}/src/simo/core/auto_urls.py +0 -0
  41. {simo-1.6.2 → simo-1.6.4}/src/simo/core/base_types.py +0 -0
  42. {simo-1.6.2 → simo-1.6.4}/src/simo/core/context.py +0 -0
  43. {simo-1.6.2 → simo-1.6.4}/src/simo/core/controllers.py +0 -0
  44. {simo-1.6.2 → simo-1.6.4}/src/simo/core/db_backend/__init__.py +0 -0
  45. {simo-1.6.2 → simo-1.6.4}/src/simo/core/db_backend/base.py +0 -0
  46. {simo-1.6.2 → simo-1.6.4}/src/simo/core/dynamic_settings.py +0 -0
  47. {simo-1.6.2 → simo-1.6.4}/src/simo/core/filters.py +0 -0
  48. {simo-1.6.2 → simo-1.6.4}/src/simo/core/forms.py +0 -0
  49. {simo-1.6.2 → simo-1.6.4}/src/simo/core/gateways.py +0 -0
  50. {simo-1.6.2 → simo-1.6.4}/src/simo/core/loggers.py +0 -0
  51. {simo-1.6.2 → simo-1.6.4}/src/simo/core/management/__init__.py +0 -0
  52. {simo-1.6.2 → simo-1.6.4}/src/simo/core/management/commands/__init__.py +0 -0
  53. {simo-1.6.2 → simo-1.6.4}/src/simo/core/management/commands/gateways_manager.py +0 -0
  54. {simo-1.6.2 → simo-1.6.4}/src/simo/core/management/commands/run_gateway.py +0 -0
  55. {simo-1.6.2 → simo-1.6.4}/src/simo/core/management/commands/update.py +0 -0
  56. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0001_initial.py +0 -0
  57. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0002_load_icons.py +0 -0
  58. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0003_create_default_zones_and_categories.py +0 -0
  59. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0004_create_generic.py +0 -0
  60. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0005_component_subcomponents.py +0 -0
  61. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0006_alter_component_subcomponents.py +0 -0
  62. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0007_component_change_init_to.py +0 -0
  63. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0008_alter_component_change_init_to.py +0 -0
  64. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0009_auto_20220707_1404.py +0 -0
  65. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0010_historyaggregate.py +0 -0
  66. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0011_component_last_change.py +0 -0
  67. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0012_instance.py +0 -0
  68. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0013_auto_20231003_0754.py +0 -0
  69. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0014_zone_instance.py +0 -0
  70. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0015_auto_20231004_1113.py +0 -0
  71. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0016_auto_20231004_1113.py +0 -0
  72. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0017_auto_20231004_1313.py +0 -0
  73. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0018_auto_20231005_0622.py +0 -0
  74. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0019_alter_gateway_type.py +0 -0
  75. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0020_component_meta.py +0 -0
  76. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/0021_auto_20231020_1041.py +0 -0
  77. {simo-1.6.2 → simo-1.6.4}/src/simo/core/migrations/__init__.py +0 -0
  78. {simo-1.6.2 → simo-1.6.4}/src/simo/core/permissions.py +0 -0
  79. {simo-1.6.2 → simo-1.6.4}/src/simo/core/routing.py +0 -0
  80. {simo-1.6.2 → simo-1.6.4}/src/simo/core/serializers.py +0 -0
  81. {simo-1.6.2 → simo-1.6.4}/src/simo/core/signal_receivers.py +0 -0
  82. {simo-1.6.2 → simo-1.6.4}/src/simo/core/storage.py +0 -0
  83. {simo-1.6.2 → simo-1.6.4}/src/simo/core/tasks.py +0 -0
  84. {simo-1.6.2 → simo-1.6.4}/src/simo/core/templatetags/__init__.py +0 -0
  85. {simo-1.6.2 → simo-1.6.4}/src/simo/core/templatetags/components_list.py +0 -0
  86. {simo-1.6.2 → simo-1.6.4}/src/simo/core/todos.py +0 -0
  87. {simo-1.6.2 → simo-1.6.4}/src/simo/core/types.py +0 -0
  88. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/__init__.py +0 -0
  89. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/admin.py +0 -0
  90. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/config_values.py +0 -0
  91. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/easing.py +0 -0
  92. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/form_fields.py +0 -0
  93. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/form_widgets.py +0 -0
  94. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/formsets.py +0 -0
  95. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/helpers.py +0 -0
  96. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/logs.py +0 -0
  97. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/mixins.py +0 -0
  98. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/model_helpers.py +0 -0
  99. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/relay.py +0 -0
  100. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/type_constants.py +0 -0
  101. {simo-1.6.2 → simo-1.6.4}/src/simo/core/utils/validators.py +0 -0
  102. {simo-1.6.2 → simo-1.6.4}/src/simo/core/views.py +0 -0
  103. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/__init__.py +0 -0
  104. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/app_widgets.py +0 -0
  105. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/base_types.py +0 -0
  106. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/forms.py +0 -0
  107. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/gateways.py +0 -0
  108. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/models.py +0 -0
  109. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/routing.py +0 -0
  110. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/socket_consumers.py +0 -0
  111. {simo-1.6.2 → simo-1.6.4}/src/simo/generic/tasks.py +0 -0
  112. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/__init__.py +0 -0
  113. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/admin.py +0 -0
  114. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/api.py +0 -0
  115. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/app_widgets.py +0 -0
  116. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/base_types.py +0 -0
  117. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/controllers.py +0 -0
  118. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/forms.py +0 -0
  119. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/migrations/0001_initial.py +0 -0
  120. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/migrations/0002_sound_length.py +0 -0
  121. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/migrations/0003_alter_sound_length.py +0 -0
  122. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/migrations/0004_auto_20231023_1055.py +0 -0
  123. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/migrations/__init__.py +0 -0
  124. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/models.py +0 -0
  125. {simo-1.6.2 → simo-1.6.4}/src/simo/multimedia/serializers.py +0 -0
  126. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/__init__.py +0 -0
  127. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/admin.py +0 -0
  128. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/api.py +0 -0
  129. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/migrations/0001_initial.py +0 -0
  130. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/migrations/0002_notification_instance.py +0 -0
  131. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/migrations/__init__.py +0 -0
  132. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/models.py +0 -0
  133. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/serializers.py +0 -0
  134. {simo-1.6.2 → simo-1.6.4}/src/simo/notifications/utils.py +0 -0
  135. {simo-1.6.2 → simo-1.6.4}/src/simo/scripting.py +0 -0
  136. {simo-1.6.2 → simo-1.6.4}/src/simo/settings.py +0 -0
  137. {simo-1.6.2 → simo-1.6.4}/src/simo/urls.py +0 -0
  138. {simo-1.6.2 → simo-1.6.4}/src/simo/users/__init__.py +0 -0
  139. {simo-1.6.2 → simo-1.6.4}/src/simo/users/auto_urls.py +0 -0
  140. {simo-1.6.2 → simo-1.6.4}/src/simo/users/dynamic_settings.py +0 -0
  141. {simo-1.6.2 → simo-1.6.4}/src/simo/users/middleware.py +0 -0
  142. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0001_initial.py +0 -0
  143. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0002_componentpermission.py +0 -0
  144. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0003_create_roles_and_system_user.py +0 -0
  145. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0004_user_secret_key.py +0 -0
  146. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0005_permissionsrole_instance.py +0 -0
  147. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0006_auto_20231003_0850.py +0 -0
  148. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0007_auto_20231003_1228.py +0 -0
  149. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0008_auto_20231003_1229.py +0 -0
  150. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0009_remove_user_role.py +0 -0
  151. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0010_auto_20231004_1313.py +0 -0
  152. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0011_auto_20231004_1313.py +0 -0
  153. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0012_alter_userinstancerole_unique_together.py +0 -0
  154. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0013_remove_user_roles.py +0 -0
  155. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0014_user_roles.py +0 -0
  156. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0015_remove_user_at_home.py +0 -0
  157. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/0016_auto_20231005_1050.py +0 -0
  158. {simo-1.6.2 → simo-1.6.4}/src/simo/users/migrations/__init__.py +0 -0
  159. {simo-1.6.2 → simo-1.6.4}/src/simo/users/permissions.py +0 -0
  160. {simo-1.6.2 → simo-1.6.4}/src/simo/users/sso_urls.py +0 -0
  161. {simo-1.6.2 → simo-1.6.4}/src/simo/users/sso_views.py +0 -0
  162. {simo-1.6.2 → simo-1.6.4}/src/simo/users/tasks.py +0 -0
  163. {simo-1.6.2 → simo-1.6.4}/src/simo/users/utils.py +0 -0
  164. {simo-1.6.2 → simo-1.6.4}/src/simo/users/views.py +0 -0
  165. {simo-1.6.2 → simo-1.6.4}/src/simo.egg-info/dependency_links.txt +0 -0
  166. {simo-1.6.2 → simo-1.6.4}/src/simo.egg-info/requires.txt +0 -0
  167. {simo-1.6.2 → simo-1.6.4}/src/simo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 1.6.2
3
+ Version: 1.6.4
4
4
  Summary: Smart Home on Steroids!
5
5
  Author-email: Simanas Venčkauskas <simanas@simo.io>
6
6
  Project-URL: Homepage, https://simo.io
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simo"
7
- version = "1.6.2"
7
+ version = "1.6.4"
8
8
  authors = [
9
9
  { name="Simanas Venčkauskas", email="simanas@simo.io" },
10
10
  ]
@@ -3,7 +3,6 @@ from calendar import monthrange
3
3
  import pytz
4
4
  import logging
5
5
  from django.db.models import Q, Prefetch
6
- from django.urls import get_script_prefix
7
6
  from django.utils.translation import gettext_lazy as _
8
7
  from django.utils import timezone
9
8
  from django.shortcuts import get_object_or_404
@@ -19,6 +19,6 @@ class CoreAppConfig(AppConfig):
19
19
  # We are running as root and there is no symbolic link yet made
20
20
  # for auto updates.
21
21
  os.symlink(auto_update_file_path, executable_path)
22
- auto_update_cron = f'*/10 * * * * {executable_path} \n'
22
+ auto_update_cron = f'0 * * * * {executable_path} \n'
23
23
  cron_out = subprocess.Popen(['crontab', '-'], stdin=subprocess.PIPE)
24
24
  cron_out.communicate(input=str.encode(auto_update_cron))
@@ -1,5 +1,4 @@
1
1
  from dal import autocomplete
2
- from django.urls import get_script_prefix
3
2
  from django.db.models import Q
4
3
  from django.template.loader import render_to_string
5
4
  from simo.core.utils.helpers import search_queryset
@@ -24,7 +23,7 @@ class IconModelAutocomplete(autocomplete.Select2QuerySetView):
24
23
  def get_result_label(self, item):
25
24
  return render_to_string(
26
25
  'core/icon_acutocomplete_select_item.html', {
27
- 'icon': item, 'prefix': get_script_prefix()[:-1]
26
+ 'icon': item,
28
27
  }
29
28
  )
30
29
 
@@ -70,7 +69,7 @@ class CategoryAutocomplete(autocomplete.Select2QuerySetView):
70
69
  def get_result_label(self, item):
71
70
  return render_to_string(
72
71
  'core/object_acutocomplete_select_item.html', {
73
- 'object': item, 'prefix': get_script_prefix()[:-1]
72
+ 'object': item
74
73
  }
75
74
  )
76
75
 
@@ -96,7 +95,7 @@ class ZoneAutocomplete(autocomplete.Select2QuerySetView):
96
95
  def get_result_label(self, item):
97
96
  return render_to_string(
98
97
  'core/object_acutocomplete_select_item.html', {
99
- 'object': item, 'prefix': get_script_prefix()[:-1]
98
+ 'object': item
100
99
  }
101
100
  )
102
101
 
@@ -133,7 +132,7 @@ class ComponentAutocomplete(autocomplete.Select2QuerySetView):
133
132
  def get_result_label(self, item):
134
133
  return render_to_string(
135
134
  'core/object_acutocomplete_select_item.html', {
136
- 'object': item, 'prefix': get_script_prefix()[:-1]
135
+ 'object': item
137
136
  }
138
137
  )
139
138
 
@@ -2,9 +2,14 @@ import json
2
2
  import time
3
3
  import logging
4
4
  import threading
5
+ import sys
6
+ import json
7
+ import traceback
8
+ import pytz
5
9
  from django.contrib.contenttypes.models import ContentType
6
10
  from django.conf import settings
7
11
  import paho.mqtt.client as mqtt
12
+ from django.utils import timezone
8
13
  from django.utils.translation import gettext_lazy as _
9
14
  import paho.mqtt.publish as mqtt_publish
10
15
 
@@ -130,3 +135,54 @@ class EventsStream:
130
135
  def on_tick(self):
131
136
  """Override me to do something every second"""
132
137
  pass
138
+
139
+
140
+ class OnChangeMixin:
141
+
142
+ on_change_fields = ('value', )
143
+
144
+ def get_instance(self):
145
+ # default for component
146
+ return self.zone.instance.timezone
147
+
148
+ def on_mqtt_connect(self, mqtt_client, userdata, flags, rc):
149
+ mqtt_client.subscribe(ObjectManagementEvent.TOPIC)
150
+
151
+ def on_mqtt_message(self, client, userdata, msg):
152
+ payload = json.loads(msg.payload)
153
+ if not self._on_change_function:
154
+ return
155
+ if payload['obj_pk'] != self.id:
156
+ return
157
+ if payload['obj_ct_pk'] != self._obj_ct_id:
158
+ return
159
+ if payload['event'] != 'changed':
160
+ return
161
+ if 'value' not in payload.get('dirty_fields', {}):
162
+ return
163
+
164
+ tz = pytz.timezone(self.gget_instance().timezone)
165
+ timezone.activate(tz)
166
+
167
+ self.refresh_from_db()
168
+
169
+ try:
170
+ self._on_change_function(self)
171
+ except Exception:
172
+ print(traceback.format_exc(), file=sys.stderr)
173
+
174
+ def on_change(self, function):
175
+ if function:
176
+ self._mqtt_client = mqtt.Client()
177
+ self._mqtt_client.on_connect = self.on_mqtt_connect
178
+ self._mqtt_client.on_message = self.on_mqtt_message
179
+ self._mqtt_client.connect(host=settings.MQTT_HOST,
180
+ port=settings.MQTT_PORT)
181
+ self._mqtt_client.loop_start()
182
+ self._on_change_function = function
183
+ self._obj_ct_id = ContentType.objects.get_for_model(self).pk
184
+ elif self._mqtt_client:
185
+ self._mqtt_client.disconnect()
186
+ self._mqtt_client.loop_stop()
187
+ self._mqtt_client = None
188
+ self._on_change_function = None
@@ -1,14 +1,9 @@
1
1
  import pytz
2
2
  import threading
3
- from django.urls import set_script_prefix, get_script_prefix
4
- from django.shortcuts import redirect, render
3
+ from django.urls import set_script_prefix
5
4
  from django.utils import timezone
6
- from django.conf import settings
7
- from simo.users.models import User
8
5
  from simo.conf import dynamic_settings
9
6
 
10
-
11
-
12
7
  _thread_locals = threading.local()
13
8
 
14
9
 
@@ -25,7 +20,6 @@ def simo_router_middleware(get_response):
25
20
  _thread_locals.request = request
26
21
 
27
22
  request.relay = None
28
- router_prefix = '/'
29
23
 
30
24
  if request.META.get('HTTP_HOST', '').endswith('.simo.io'):
31
25
  router_prefix = dynamic_settings['core__remote_http']
@@ -0,0 +1,23 @@
1
+ # Generated by Django 3.2.9 on 2023-12-21 07:35
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0021_auto_20231020_1041'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='gateway',
15
+ name='type',
16
+ field=models.CharField(choices=[('simo.generic.gateways.DummyGatewayHandler', 'Dummy'), ('simo_esphome.gateways.ESPHomeGatewayHandler', 'ESPHome'), ('simo.generic.gateways.GenericGatewayHandler', 'Generic'), ('NukiDevices', 'Nuki'), ('simo_fleet.gateways.FleetGatewayHandler', 'SIMO.io Fleet'), ('simo_sonos.gateways.SONOSGatewayHandler', 'SONOS'), ('simo_zwave.gateways.ZwaveGatewayHandler', 'Zwave')], db_index=True, max_length=200, unique=True),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='instance',
20
+ name='timezone',
21
+ field=models.CharField(choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ('Africa/Algiers', 'Africa/Algiers'), ('Africa/Asmara', 'Africa/Asmara'), ('Africa/Asmera', 'Africa/Asmera'), ('Africa/Bamako', 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), ('Africa/Banjul', 'Africa/Banjul'), ('Africa/Bissau', 'Africa/Bissau'), ('Africa/Blantyre', 'Africa/Blantyre'), ('Africa/Brazzaville', 'Africa/Brazzaville'), ('Africa/Bujumbura', 'Africa/Bujumbura'), ('Africa/Cairo', 'Africa/Cairo'), ('Africa/Casablanca', 'Africa/Casablanca'), ('Africa/Ceuta', 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), ('Africa/Dakar', 'Africa/Dakar'), ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), ('Africa/Djibouti', 'Africa/Djibouti'), ('Africa/Douala', 'Africa/Douala'), ('Africa/El_Aaiun', 'Africa/El_Aaiun'), ('Africa/Freetown', 'Africa/Freetown'), ('Africa/Gaborone', 'Africa/Gaborone'), ('Africa/Harare', 'Africa/Harare'), ('Africa/Johannesburg', 'Africa/Johannesburg'), ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), ('Africa/Khartoum', 'Africa/Khartoum'), ('Africa/Kigali', 'Africa/Kigali'), ('Africa/Kinshasa', 'Africa/Kinshasa'), ('Africa/Lagos', 'Africa/Lagos'), ('Africa/Libreville', 'Africa/Libreville'), ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), ('Africa/Lubumbashi', 'Africa/Lubumbashi'), ('Africa/Lusaka', 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), ('Africa/Maputo', 'Africa/Maputo'), ('Africa/Maseru', 'Africa/Maseru'), ('Africa/Mbabane', 'Africa/Mbabane'), ('Africa/Mogadishu', 'Africa/Mogadishu'), ('Africa/Monrovia', 'Africa/Monrovia'), ('Africa/Nairobi', 'Africa/Nairobi'), ('Africa/Ndjamena', 'Africa/Ndjamena'), ('Africa/Niamey', 'Africa/Niamey'), ('Africa/Nouakchott', 'Africa/Nouakchott'), ('Africa/Ouagadougou', 'Africa/Ouagadougou'), ('Africa/Porto-Novo', 'Africa/Porto-Novo'), ('Africa/Sao_Tome', 'Africa/Sao_Tome'), ('Africa/Timbuktu', 'Africa/Timbuktu'), ('Africa/Tripoli', 'Africa/Tripoli'), ('Africa/Tunis', 'Africa/Tunis'), ('Africa/Windhoek', 'Africa/Windhoek'), ('America/Adak', 'America/Adak'), ('America/Anchorage', 'America/Anchorage'), ('America/Anguilla', 'America/Anguilla'), ('America/Antigua', 'America/Antigua'), ('America/Araguaina', 'America/Araguaina'), ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), ('America/Argentina/ComodRivadavia', 'America/Argentina/ComodRivadavia'), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'America/Argentina/Salta'), ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), ('America/Aruba', 'America/Aruba'), ('America/Asuncion', 'America/Asuncion'), ('America/Atikokan', 'America/Atikokan'), ('America/Atka', 'America/Atka'), ('America/Bahia', 'America/Bahia'), ('America/Bahia_Banderas', 'America/Bahia_Banderas'), ('America/Barbados', 'America/Barbados'), ('America/Belem', 'America/Belem'), ('America/Belize', 'America/Belize'), ('America/Blanc-Sablon', 'America/Blanc-Sablon'), ('America/Boa_Vista', 'America/Boa_Vista'), ('America/Bogota', 'America/Bogota'), ('America/Boise', 'America/Boise'), ('America/Buenos_Aires', 'America/Buenos_Aires'), ('America/Cambridge_Bay', 'America/Cambridge_Bay'), ('America/Campo_Grande', 'America/Campo_Grande'), ('America/Cancun', 'America/Cancun'), ('America/Caracas', 'America/Caracas'), ('America/Catamarca', 'America/Catamarca'), ('America/Cayenne', 'America/Cayenne'), ('America/Cayman', 'America/Cayman'), ('America/Chicago', 'America/Chicago'), ('America/Chihuahua', 'America/Chihuahua'), ('America/Ciudad_Juarez', 'America/Ciudad_Juarez'), ('America/Coral_Harbour', 'America/Coral_Harbour'), ('America/Cordoba', 'America/Cordoba'), ('America/Costa_Rica', 'America/Costa_Rica'), ('America/Creston', 'America/Creston'), ('America/Cuiaba', 'America/Cuiaba'), ('America/Curacao', 'America/Curacao'), ('America/Danmarkshavn', 'America/Danmarkshavn'), ('America/Dawson', 'America/Dawson'), ('America/Dawson_Creek', 'America/Dawson_Creek'), ('America/Denver', 'America/Denver'), ('America/Detroit', 'America/Detroit'), ('America/Dominica', 'America/Dominica'), ('America/Edmonton', 'America/Edmonton'), ('America/Eirunepe', 'America/Eirunepe'), ('America/El_Salvador', 'America/El_Salvador'), ('America/Ensenada', 'America/Ensenada'), ('America/Fort_Nelson', 'America/Fort_Nelson'), ('America/Fort_Wayne', 'America/Fort_Wayne'), ('America/Fortaleza', 'America/Fortaleza'), ('America/Glace_Bay', 'America/Glace_Bay'), ('America/Godthab', 'America/Godthab'), ('America/Goose_Bay', 'America/Goose_Bay'), ('America/Grand_Turk', 'America/Grand_Turk'), ('America/Grenada', 'America/Grenada'), ('America/Guadeloupe', 'America/Guadeloupe'), ('America/Guatemala', 'America/Guatemala'), ('America/Guayaquil', 'America/Guayaquil'), ('America/Guyana', 'America/Guyana'), ('America/Halifax', 'America/Halifax'), ('America/Havana', 'America/Havana'), ('America/Hermosillo', 'America/Hermosillo'), ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), ('America/Indiana/Knox', 'America/Indiana/Knox'), ('America/Indiana/Marengo', 'America/Indiana/Marengo'), ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), ('America/Indiana/Vevay', 'America/Indiana/Vevay'), ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), ('America/Indiana/Winamac', 'America/Indiana/Winamac'), ('America/Indianapolis', 'America/Indianapolis'), ('America/Inuvik', 'America/Inuvik'), ('America/Iqaluit', 'America/Iqaluit'), ('America/Jamaica', 'America/Jamaica'), ('America/Jujuy', 'America/Jujuy'), ('America/Juneau', 'America/Juneau'), ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), ('America/Knox_IN', 'America/Knox_IN'), ('America/Kralendijk', 'America/Kralendijk'), ('America/La_Paz', 'America/La_Paz'), ('America/Lima', 'America/Lima'), ('America/Los_Angeles', 'America/Los_Angeles'), ('America/Louisville', 'America/Louisville'), ('America/Lower_Princes', 'America/Lower_Princes'), ('America/Maceio', 'America/Maceio'), ('America/Managua', 'America/Managua'), ('America/Manaus', 'America/Manaus'), ('America/Marigot', 'America/Marigot'), ('America/Martinique', 'America/Martinique'), ('America/Matamoros', 'America/Matamoros'), ('America/Mazatlan', 'America/Mazatlan'), ('America/Mendoza', 'America/Mendoza'), ('America/Menominee', 'America/Menominee'), ('America/Merida', 'America/Merida'), ('America/Metlakatla', 'America/Metlakatla'), ('America/Mexico_City', 'America/Mexico_City'), ('America/Miquelon', 'America/Miquelon'), ('America/Moncton', 'America/Moncton'), ('America/Monterrey', 'America/Monterrey'), ('America/Montevideo', 'America/Montevideo'), ('America/Montreal', 'America/Montreal'), ('America/Montserrat', 'America/Montserrat'), ('America/Nassau', 'America/Nassau'), ('America/New_York', 'America/New_York'), ('America/Nipigon', 'America/Nipigon'), ('America/Nome', 'America/Nome'), ('America/Noronha', 'America/Noronha'), ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), ('America/North_Dakota/Center', 'America/North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), ('America/Nuuk', 'America/Nuuk'), ('America/Ojinaga', 'America/Ojinaga'), ('America/Panama', 'America/Panama'), ('America/Pangnirtung', 'America/Pangnirtung'), ('America/Paramaribo', 'America/Paramaribo'), ('America/Phoenix', 'America/Phoenix'), ('America/Port-au-Prince', 'America/Port-au-Prince'), ('America/Port_of_Spain', 'America/Port_of_Spain'), ('America/Porto_Acre', 'America/Porto_Acre'), ('America/Porto_Velho', 'America/Porto_Velho'), ('America/Puerto_Rico', 'America/Puerto_Rico'), ('America/Punta_Arenas', 'America/Punta_Arenas'), ('America/Rainy_River', 'America/Rainy_River'), ('America/Rankin_Inlet', 'America/Rankin_Inlet'), ('America/Recife', 'America/Recife'), ('America/Regina', 'America/Regina'), ('America/Resolute', 'America/Resolute'), ('America/Rio_Branco', 'America/Rio_Branco'), ('America/Rosario', 'America/Rosario'), ('America/Santa_Isabel', 'America/Santa_Isabel'), ('America/Santarem', 'America/Santarem'), ('America/Santiago', 'America/Santiago'), ('America/Santo_Domingo', 'America/Santo_Domingo'), ('America/Sao_Paulo', 'America/Sao_Paulo'), ('America/Scoresbysund', 'America/Scoresbysund'), ('America/Shiprock', 'America/Shiprock'), ('America/Sitka', 'America/Sitka'), ('America/St_Barthelemy', 'America/St_Barthelemy'), ('America/St_Johns', 'America/St_Johns'), ('America/St_Kitts', 'America/St_Kitts'), ('America/St_Lucia', 'America/St_Lucia'), ('America/St_Thomas', 'America/St_Thomas'), ('America/St_Vincent', 'America/St_Vincent'), ('America/Swift_Current', 'America/Swift_Current'), ('America/Tegucigalpa', 'America/Tegucigalpa'), ('America/Thule', 'America/Thule'), ('America/Thunder_Bay', 'America/Thunder_Bay'), ('America/Tijuana', 'America/Tijuana'), ('America/Toronto', 'America/Toronto'), ('America/Tortola', 'America/Tortola'), ('America/Vancouver', 'America/Vancouver'), ('America/Virgin', 'America/Virgin'), ('America/Whitehorse', 'America/Whitehorse'), ('America/Winnipeg', 'America/Winnipeg'), ('America/Yakutat', 'America/Yakutat'), ('America/Yellowknife', 'America/Yellowknife'), ('Antarctica/Casey', 'Antarctica/Casey'), ('Antarctica/Davis', 'Antarctica/Davis'), ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), ('Antarctica/Macquarie', 'Antarctica/Macquarie'), ('Antarctica/Mawson', 'Antarctica/Mawson'), ('Antarctica/McMurdo', 'Antarctica/McMurdo'), ('Antarctica/Palmer', 'Antarctica/Palmer'), ('Antarctica/Rothera', 'Antarctica/Rothera'), ('Antarctica/South_Pole', 'Antarctica/South_Pole'), ('Antarctica/Syowa', 'Antarctica/Syowa'), ('Antarctica/Troll', 'Antarctica/Troll'), ('Antarctica/Vostok', 'Antarctica/Vostok'), ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), ('Asia/Ashgabat', 'Asia/Ashgabat'), ('Asia/Ashkhabad', 'Asia/Ashkhabad'), ('Asia/Atyrau', 'Asia/Atyrau'), ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), ('Asia/Calcutta', 'Asia/Calcutta'), ('Asia/Chita', 'Asia/Chita'), ('Asia/Choibalsan', 'Asia/Choibalsan'), ('Asia/Chongqing', 'Asia/Chongqing'), ('Asia/Chungking', 'Asia/Chungking'), ('Asia/Colombo', 'Asia/Colombo'), ('Asia/Dacca', 'Asia/Dacca'), ('Asia/Damascus', 'Asia/Damascus'), ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), ('Asia/Famagusta', 'Asia/Famagusta'), ('Asia/Gaza', 'Asia/Gaza'), ('Asia/Harbin', 'Asia/Harbin'), ('Asia/Hebron', 'Asia/Hebron'), ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Istanbul', 'Asia/Istanbul'), ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), ('Asia/Kamchatka', 'Asia/Kamchatka'), ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kashgar', 'Asia/Kashgar'), ('Asia/Kathmandu', 'Asia/Kathmandu'), ('Asia/Katmandu', 'Asia/Katmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), ('Asia/Kolkata', 'Asia/Kolkata'), ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), ('Asia/Macao', 'Asia/Macao'), ('Asia/Macau', 'Asia/Macau'), ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), ('Asia/Nicosia', 'Asia/Nicosia'), ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), ('Asia/Pontianak', 'Asia/Pontianak'), ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), ('Asia/Qostanay', 'Asia/Qostanay'), ('Asia/Qyzylorda', 'Asia/Qyzylorda'), ('Asia/Rangoon', 'Asia/Rangoon'), ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Saigon', 'Asia/Saigon'), ('Asia/Sakhalin', 'Asia/Sakhalin'), ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), ('Asia/Shanghai', 'Asia/Shanghai'), ('Asia/Singapore', 'Asia/Singapore'), ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), ('Asia/Tel_Aviv', 'Asia/Tel_Aviv'), ('Asia/Thimbu', 'Asia/Thimbu'), ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), ('Asia/Tomsk', 'Asia/Tomsk'), ('Asia/Ujung_Pandang', 'Asia/Ujung_Pandang'), ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), ('Asia/Ulan_Bator', 'Asia/Ulan_Bator'), ('Asia/Urumqi', 'Asia/Urumqi'), ('Asia/Ust-Nera', 'Asia/Ust-Nera'), ('Asia/Vientiane', 'Asia/Vientiane'), ('Asia/Vladivostok', 'Asia/Vladivostok'), ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yangon', 'Asia/Yangon'), ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), ('Asia/Yerevan', 'Asia/Yerevan'), ('Atlantic/Azores', 'Atlantic/Azores'), ('Atlantic/Bermuda', 'Atlantic/Bermuda'), ('Atlantic/Canary', 'Atlantic/Canary'), ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), ('Atlantic/Faeroe', 'Atlantic/Faeroe'), ('Atlantic/Faroe', 'Atlantic/Faroe'), ('Atlantic/Jan_Mayen', 'Atlantic/Jan_Mayen'), ('Atlantic/Madeira', 'Atlantic/Madeira'), ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), ('Atlantic/St_Helena', 'Atlantic/St_Helena'), ('Atlantic/Stanley', 'Atlantic/Stanley'), ('Australia/ACT', 'Australia/ACT'), ('Australia/Adelaide', 'Australia/Adelaide'), ('Australia/Brisbane', 'Australia/Brisbane'), ('Australia/Broken_Hill', 'Australia/Broken_Hill'), ('Australia/Canberra', 'Australia/Canberra'), ('Australia/Currie', 'Australia/Currie'), ('Australia/Darwin', 'Australia/Darwin'), ('Australia/Eucla', 'Australia/Eucla'), ('Australia/Hobart', 'Australia/Hobart'), ('Australia/LHI', 'Australia/LHI'), ('Australia/Lindeman', 'Australia/Lindeman'), ('Australia/Lord_Howe', 'Australia/Lord_Howe'), ('Australia/Melbourne', 'Australia/Melbourne'), ('Australia/NSW', 'Australia/NSW'), ('Australia/North', 'Australia/North'), ('Australia/Perth', 'Australia/Perth'), ('Australia/Queensland', 'Australia/Queensland'), ('Australia/South', 'Australia/South'), ('Australia/Sydney', 'Australia/Sydney'), ('Australia/Tasmania', 'Australia/Tasmania'), ('Australia/Victoria', 'Australia/Victoria'), ('Australia/West', 'Australia/West'), ('Australia/Yancowinna', 'Australia/Yancowinna'), ('Brazil/Acre', 'Brazil/Acre'), ('Brazil/DeNoronha', 'Brazil/DeNoronha'), ('Brazil/East', 'Brazil/East'), ('Brazil/West', 'Brazil/West'), ('CET', 'CET'), ('CST6CDT', 'CST6CDT'), ('Canada/Atlantic', 'Canada/Atlantic'), ('Canada/Central', 'Canada/Central'), ('Canada/Eastern', 'Canada/Eastern'), ('Canada/Mountain', 'Canada/Mountain'), ('Canada/Newfoundland', 'Canada/Newfoundland'), ('Canada/Pacific', 'Canada/Pacific'), ('Canada/Saskatchewan', 'Canada/Saskatchewan'), ('Canada/Yukon', 'Canada/Yukon'), ('Chile/Continental', 'Chile/Continental'), ('Chile/EasterIsland', 'Chile/EasterIsland'), ('Cuba', 'Cuba'), ('EET', 'EET'), ('EST', 'EST'), ('EST5EDT', 'EST5EDT'), ('Egypt', 'Egypt'), ('Eire', 'Eire'), ('Etc/GMT', 'Etc/GMT'), ('Etc/GMT+0', 'Etc/GMT+0'), ('Etc/GMT+1', 'Etc/GMT+1'), ('Etc/GMT+10', 'Etc/GMT+10'), ('Etc/GMT+11', 'Etc/GMT+11'), ('Etc/GMT+12', 'Etc/GMT+12'), ('Etc/GMT+2', 'Etc/GMT+2'), ('Etc/GMT+3', 'Etc/GMT+3'), ('Etc/GMT+4', 'Etc/GMT+4'), ('Etc/GMT+5', 'Etc/GMT+5'), ('Etc/GMT+6', 'Etc/GMT+6'), ('Etc/GMT+7', 'Etc/GMT+7'), ('Etc/GMT+8', 'Etc/GMT+8'), ('Etc/GMT+9', 'Etc/GMT+9'), ('Etc/GMT-0', 'Etc/GMT-0'), ('Etc/GMT-1', 'Etc/GMT-1'), ('Etc/GMT-10', 'Etc/GMT-10'), ('Etc/GMT-11', 'Etc/GMT-11'), ('Etc/GMT-12', 'Etc/GMT-12'), ('Etc/GMT-13', 'Etc/GMT-13'), ('Etc/GMT-14', 'Etc/GMT-14'), ('Etc/GMT-2', 'Etc/GMT-2'), ('Etc/GMT-3', 'Etc/GMT-3'), ('Etc/GMT-4', 'Etc/GMT-4'), ('Etc/GMT-5', 'Etc/GMT-5'), ('Etc/GMT-6', 'Etc/GMT-6'), ('Etc/GMT-7', 'Etc/GMT-7'), ('Etc/GMT-8', 'Etc/GMT-8'), ('Etc/GMT-9', 'Etc/GMT-9'), ('Etc/GMT0', 'Etc/GMT0'), ('Etc/Greenwich', 'Etc/Greenwich'), ('Etc/UCT', 'Etc/UCT'), ('Etc/UTC', 'Etc/UTC'), ('Etc/Universal', 'Etc/Universal'), ('Etc/Zulu', 'Etc/Zulu'), ('Europe/Amsterdam', 'Europe/Amsterdam'), ('Europe/Andorra', 'Europe/Andorra'), ('Europe/Astrakhan', 'Europe/Astrakhan'), ('Europe/Athens', 'Europe/Athens'), ('Europe/Belfast', 'Europe/Belfast'), ('Europe/Belgrade', 'Europe/Belgrade'), ('Europe/Berlin', 'Europe/Berlin'), ('Europe/Bratislava', 'Europe/Bratislava'), ('Europe/Brussels', 'Europe/Brussels'), ('Europe/Bucharest', 'Europe/Bucharest'), ('Europe/Budapest', 'Europe/Budapest'), ('Europe/Busingen', 'Europe/Busingen'), ('Europe/Chisinau', 'Europe/Chisinau'), ('Europe/Copenhagen', 'Europe/Copenhagen'), ('Europe/Dublin', 'Europe/Dublin'), ('Europe/Gibraltar', 'Europe/Gibraltar'), ('Europe/Guernsey', 'Europe/Guernsey'), ('Europe/Helsinki', 'Europe/Helsinki'), ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), ('Europe/Istanbul', 'Europe/Istanbul'), ('Europe/Jersey', 'Europe/Jersey'), ('Europe/Kaliningrad', 'Europe/Kaliningrad'), ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), ('Europe/Kyiv', 'Europe/Kyiv'), ('Europe/Lisbon', 'Europe/Lisbon'), ('Europe/Ljubljana', 'Europe/Ljubljana'), ('Europe/London', 'Europe/London'), ('Europe/Luxembourg', 'Europe/Luxembourg'), ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), ('Europe/Mariehamn', 'Europe/Mariehamn'), ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), ('Europe/Moscow', 'Europe/Moscow'), ('Europe/Nicosia', 'Europe/Nicosia'), ('Europe/Oslo', 'Europe/Oslo'), ('Europe/Paris', 'Europe/Paris'), ('Europe/Podgorica', 'Europe/Podgorica'), ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), ('Europe/San_Marino', 'Europe/San_Marino'), ('Europe/Sarajevo', 'Europe/Sarajevo'), ('Europe/Saratov', 'Europe/Saratov'), ('Europe/Simferopol', 'Europe/Simferopol'), ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), ('Europe/Stockholm', 'Europe/Stockholm'), ('Europe/Tallinn', 'Europe/Tallinn'), ('Europe/Tirane', 'Europe/Tirane'), ('Europe/Tiraspol', 'Europe/Tiraspol'), ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), ('Europe/Uzhgorod', 'Europe/Uzhgorod'), ('Europe/Vaduz', 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), ('Europe/Vienna', 'Europe/Vienna'), ('Europe/Vilnius', 'Europe/Vilnius'), ('Europe/Volgograd', 'Europe/Volgograd'), ('Europe/Warsaw', 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), ('Europe/Zaporozhye', 'Europe/Zaporozhye'), ('Europe/Zurich', 'Europe/Zurich'), ('GB', 'GB'), ('GB-Eire', 'GB-Eire'), ('GMT', 'GMT'), ('GMT+0', 'GMT+0'), ('GMT-0', 'GMT-0'), ('GMT0', 'GMT0'), ('Greenwich', 'Greenwich'), ('HST', 'HST'), ('Hongkong', 'Hongkong'), ('Iceland', 'Iceland'), ('Indian/Antananarivo', 'Indian/Antananarivo'), ('Indian/Chagos', 'Indian/Chagos'), ('Indian/Christmas', 'Indian/Christmas'), ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), ('Indian/Kerguelen', 'Indian/Kerguelen'), ('Indian/Mahe', 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), ('Indian/Mauritius', 'Indian/Mauritius'), ('Indian/Mayotte', 'Indian/Mayotte'), ('Indian/Reunion', 'Indian/Reunion'), ('Iran', 'Iran'), ('Israel', 'Israel'), ('Jamaica', 'Jamaica'), ('Japan', 'Japan'), ('Kwajalein', 'Kwajalein'), ('Libya', 'Libya'), ('MET', 'MET'), ('MST', 'MST'), ('MST7MDT', 'MST7MDT'), ('Mexico/BajaNorte', 'Mexico/BajaNorte'), ('Mexico/BajaSur', 'Mexico/BajaSur'), ('Mexico/General', 'Mexico/General'), ('NZ', 'NZ'), ('NZ-CHAT', 'NZ-CHAT'), ('Navajo', 'Navajo'), ('PRC', 'PRC'), ('PST8PDT', 'PST8PDT'), ('Pacific/Apia', 'Pacific/Apia'), ('Pacific/Auckland', 'Pacific/Auckland'), ('Pacific/Bougainville', 'Pacific/Bougainville'), ('Pacific/Chatham', 'Pacific/Chatham'), ('Pacific/Chuuk', 'Pacific/Chuuk'), ('Pacific/Easter', 'Pacific/Easter'), ('Pacific/Efate', 'Pacific/Efate'), ('Pacific/Enderbury', 'Pacific/Enderbury'), ('Pacific/Fakaofo', 'Pacific/Fakaofo'), ('Pacific/Fiji', 'Pacific/Fiji'), ('Pacific/Funafuti', 'Pacific/Funafuti'), ('Pacific/Galapagos', 'Pacific/Galapagos'), ('Pacific/Gambier', 'Pacific/Gambier'), ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), ('Pacific/Guam', 'Pacific/Guam'), ('Pacific/Honolulu', 'Pacific/Honolulu'), ('Pacific/Johnston', 'Pacific/Johnston'), ('Pacific/Kanton', 'Pacific/Kanton'), ('Pacific/Kiritimati', 'Pacific/Kiritimati'), ('Pacific/Kosrae', 'Pacific/Kosrae'), ('Pacific/Kwajalein', 'Pacific/Kwajalein'), ('Pacific/Majuro', 'Pacific/Majuro'), ('Pacific/Marquesas', 'Pacific/Marquesas'), ('Pacific/Midway', 'Pacific/Midway'), ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), ('Pacific/Norfolk', 'Pacific/Norfolk'), ('Pacific/Noumea', 'Pacific/Noumea'), ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), ('Pacific/Palau', 'Pacific/Palau'), ('Pacific/Pitcairn', 'Pacific/Pitcairn'), ('Pacific/Pohnpei', 'Pacific/Pohnpei'), ('Pacific/Ponape', 'Pacific/Ponape'), ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), ('Pacific/Rarotonga', 'Pacific/Rarotonga'), ('Pacific/Saipan', 'Pacific/Saipan'), ('Pacific/Samoa', 'Pacific/Samoa'), ('Pacific/Tahiti', 'Pacific/Tahiti'), ('Pacific/Tarawa', 'Pacific/Tarawa'), ('Pacific/Tongatapu', 'Pacific/Tongatapu'), ('Pacific/Truk', 'Pacific/Truk'), ('Pacific/Wake', 'Pacific/Wake'), ('Pacific/Wallis', 'Pacific/Wallis'), ('Pacific/Yap', 'Pacific/Yap'), ('Poland', 'Poland'), ('Portugal', 'Portugal'), ('ROC', 'ROC'), ('ROK', 'ROK'), ('Singapore', 'Singapore'), ('Turkey', 'Turkey'), ('UCT', 'UCT'), ('US/Alaska', 'US/Alaska'), ('US/Aleutian', 'US/Aleutian'), ('US/Arizona', 'US/Arizona'), ('US/Central', 'US/Central'), ('US/East-Indiana', 'US/East-Indiana'), ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), ('US/Indiana-Starke', 'US/Indiana-Starke'), ('US/Michigan', 'US/Michigan'), ('US/Mountain', 'US/Mountain'), ('US/Pacific', 'US/Pacific'), ('US/Samoa', 'US/Samoa'), ('UTC', 'UTC'), ('Universal', 'Universal'), ('W-SU', 'W-SU'), ('WET', 'WET'), ('Zulu', 'Zulu')], db_index=True, max_length=50),
22
+ ),
23
+ ]
@@ -1,9 +1,7 @@
1
1
  import os
2
2
  import sys
3
3
  import inspect
4
- import json
5
- import traceback
6
- import pytz
4
+
7
5
  from django.utils.text import slugify
8
6
  from django.core.cache import cache
9
7
  from django.urls import reverse_lazy
@@ -25,10 +23,7 @@ from django.contrib.contenttypes.models import ContentType
25
23
  from simo.core.utils.mixins import SimoAdminMixin
26
24
  from simo.core.storage import OverwriteStorage
27
25
  from simo.core.utils.validators import validate_svg
28
- from .events import ObjectCommand, ObjectManagementEvent
29
-
30
-
31
-
26
+ from .events import ObjectCommand, ObjectManagementEvent, OnChangeMixin
32
27
 
33
28
 
34
29
  User = get_user_model()
@@ -239,7 +234,7 @@ class Gateway(DirtyFieldsMixin, models.Model, SimoAdminMixin):
239
234
  )
240
235
 
241
236
 
242
- class Component(DirtyFieldsMixin, models.Model, SimoAdminMixin):
237
+ class Component(DirtyFieldsMixin, models.Model, SimoAdminMixin, OnChangeMixin):
243
238
  name = models.CharField(
244
239
  _('name'), max_length=100, db_index=True
245
240
  )
@@ -403,47 +398,6 @@ def translate_before_set(self, value):
403
398
  return '%s | %s' % (self.zone.name, self.name)
404
399
  return self.name
405
400
 
406
- def on_mqtt_connect(self, mqtt_client, userdata, flags, rc):
407
- mqtt_client.subscribe(ObjectManagementEvent.TOPIC)
408
-
409
- def on_mqtt_message(self, client, userdata, msg):
410
- payload = json.loads(msg.payload)
411
- if not self._on_change_function:
412
- return
413
- if payload['obj_pk'] != self.id:
414
- return
415
- if payload['obj_ct_pk'] != self._obj_ct_id:
416
- return
417
- if payload['event'] != 'changed':
418
- return
419
- if 'value' not in payload.get('dirty_fields', {}):
420
- return
421
-
422
- tz = pytz.timezone(self.zone.instance.timezone)
423
- timezone.activate(tz)
424
-
425
- self.refresh_from_db()
426
-
427
- try:
428
- self._on_change_function(self)
429
- except Exception:
430
- print(traceback.format_exc(), file=sys.stderr)
431
-
432
- def on_change(self, function):
433
- if function:
434
- self._mqtt_client = mqtt.Client()
435
- self._mqtt_client.on_connect = self.on_mqtt_connect
436
- self._mqtt_client.on_message = self.on_mqtt_message
437
- self._mqtt_client.connect(host=settings.MQTT_HOST,
438
- port=settings.MQTT_PORT)
439
- self._mqtt_client.loop_start()
440
- self._on_change_function = function
441
- self._obj_ct_id = ContentType.objects.get_for_model(self).pk
442
- elif self._mqtt_client:
443
- self._mqtt_client.disconnect()
444
- self._mqtt_client.loop_stop()
445
- self._mqtt_client = None
446
- self._on_change_function = None
447
401
 
448
402
  def get_socket_url(self):
449
403
  return reverse_lazy(
@@ -6,7 +6,7 @@ import os
6
6
  import logging
7
7
  from ansi2html import Ansi2HTMLConverter
8
8
  from asgiref.sync import sync_to_async
9
- from django.urls import set_script_prefix, get_script_prefix
9
+ from django.urls import set_script_prefix
10
10
  from django.core.exceptions import ValidationError
11
11
  from django.template.loader import render_to_string
12
12
  from django.conf import settings
@@ -1,5 +1,6 @@
1
1
  from django import forms
2
2
  from django.conf import settings
3
+ from django.templatetags.static import static
3
4
  from django.utils.safestring import mark_safe
4
5
  from location_field.widgets import LocationWidget as OrgLocationWidget
5
6
 
@@ -12,6 +13,14 @@ class LocationWidget(OrgLocationWidget):
12
13
  if zoom:
13
14
  self.options['map.zoom'] = zoom
14
15
 
16
+ @property
17
+ def media(self):
18
+ return forms.Media({
19
+ 'js': [
20
+ static('location_field') + '/js/form.js',
21
+ ],
22
+ })
23
+
15
24
 
16
25
  class SVGFileWidget(forms.ClearableFileInput):
17
26
  template_name = 'admin/svg_file_widget.html'
@@ -1123,6 +1123,7 @@ class AlarmClock(ControllerBase):
1123
1123
  week_days.sort()
1124
1124
  week_days = week_days + [d + 7 for d in week_days]
1125
1125
  for wd in week_days:
1126
+ alarm = json.loads(json.dumps(alarm))
1126
1127
  if wd < weekday:
1127
1128
  continue
1128
1129
  days_diff = wd - weekday
@@ -6,7 +6,7 @@ from django.contrib.auth.admin import UserAdmin as OrgUserAdmin
6
6
  from django.contrib import admin
7
7
  from .models import (
8
8
  PermissionsRole, ComponentPermission, User, UserDevice, UserDeviceReportLog,
9
- InstanceInvitation, UserInstanceRole
9
+ InstanceInvitation, InstanceUser
10
10
  )
11
11
 
12
12
 
@@ -67,8 +67,8 @@ class UserDeviceInline(admin.TabularInline):
67
67
  return mark_safe('<a href="%s">more >></a>' % obj.get_admin_url())
68
68
 
69
69
 
70
- class UserInstanceRoleInline(admin.TabularInline):
71
- model = UserInstanceRole
70
+ class InstanceUserInline(admin.TabularInline):
71
+ model = InstanceUser
72
72
  extra = 0
73
73
  readonly_fields = 'instance', 'at_home'
74
74
 
@@ -90,7 +90,7 @@ class UserAdmin(OrgUserAdmin):
90
90
  'name', 'email', 'avatar',
91
91
  'last_action', 'ssh_key',
92
92
  )
93
- inlines = UserDeviceInline, UserInstanceRoleInline
93
+ inlines = UserDeviceInline, InstanceUserInline
94
94
 
95
95
  def name_display(self, obj=None):
96
96
  if not obj:
@@ -132,8 +132,8 @@ admin.site.unregister(Group)
132
132
  @admin.register(UserDeviceReportLog)
133
133
  class UserDeviceLogInline(admin.ModelAdmin):
134
134
  model = UserDeviceReportLog
135
- readonly_fields = 'datetime', 'app_open', 'location', 'relay', 'at_home'
136
- list_display = 'datetime', 'app_open', 'location', 'relay', 'at_home'
135
+ readonly_fields = 'datetime', 'app_open', 'location', 'relay'
136
+ list_display = 'datetime', 'app_open', 'location', 'relay'
137
137
  fields = readonly_fields
138
138
  list_filter = 'user_device__user',
139
139
 
@@ -11,7 +11,7 @@ from simo.core.api import InstanceMixin
11
11
  from simo.core.models import Instance
12
12
  from .models import (
13
13
  User, UserDevice, UserDeviceReportLog, PermissionsRole, InstanceInvitation,
14
- UserInstanceRole
14
+ InstanceUser
15
15
  )
16
16
  from .serializers import (
17
17
  UserSerializer, PermissionsRoleSerializer, InstanceInvitationSerializer
@@ -169,12 +169,6 @@ class UserDeviceReport(viewsets.GenericViewSet):
169
169
  if request.META.get('HTTP_HOST', '').endswith('.simo.io'):
170
170
  relay = request.META.get('HTTP_HOST')
171
171
 
172
- at_home = False
173
- if not relay:
174
- at_home = True
175
- elif location:
176
- pass
177
-
178
172
 
179
173
  # TODO: fire at home event:
180
174
  # from simo.core.events import Event
@@ -185,9 +179,9 @@ class UserDeviceReport(viewsets.GenericViewSet):
185
179
  # ).publish()
186
180
 
187
181
  if not relay:
188
- UserInstanceRole.objects.filter(
189
- user=request.user
190
- ).update(at_home=True)
182
+ for item in InstanceUser.objects.filter(user=request.user):
183
+ item.at_home = True
184
+ item.save()
191
185
  elif location:
192
186
  for instance in Instance.objects.all():
193
187
  cords = instance.location
@@ -201,19 +195,21 @@ class UserDeviceReport(viewsets.GenericViewSet):
201
195
  else:
202
196
  if distance(instance_location, location).meters < \
203
197
  dynamic_settings['users__at_home_radius']:
204
- UserInstanceRole.objects.filter(
205
- user=request.user, instance=instance
206
- ).update(at_home=True)
198
+ at_home = True
207
199
  else:
208
- UserInstanceRole.objects.filter(
209
- user=request.user, instance=instance
210
- ).update(at_home=False)
200
+ at_home = False
201
+
202
+ for item in InstanceUser.objects.filter(
203
+ user=request.user, instance=instance
204
+ ):
205
+ item.at_home = at_home
206
+ item.save()
211
207
 
212
208
  log_entry = UserDeviceReportLog.objects.create(
213
209
  user_device=user_device,
214
210
  app_open=request.data.get('app_open', False),
215
211
  location=','.join([str(i) for i in location]) if location else None,
216
- relay=relay, at_home=at_home
212
+ relay=relay
217
213
  )
218
214
  # Do not keep more than 1000 entries for every device.
219
215
  for log in UserDeviceReportLog.objects.filter(
@@ -4,7 +4,7 @@ import requests
4
4
  from django.core.files import File
5
5
  from django.contrib.auth.backends import ModelBackend
6
6
  from django.utils import timezone
7
- from .models import User, InstanceInvitation, UserInstanceRole
7
+ from .models import User, InstanceInvitation, InstanceUser
8
8
  from .utils import get_superuser_role
9
9
 
10
10
 
@@ -52,7 +52,7 @@ class SSOBackend(ModelBackend):
52
52
  if invitation:
53
53
  invitation.taken_by = user
54
54
  invitation.save()
55
- UserInstanceRole.objects.create(
55
+ InstanceUser.objects.create(
56
56
  user=user, role=invitation.role,
57
57
  instance=invitation.instance
58
58
  )
@@ -0,0 +1,22 @@
1
+ # Generated by Django 3.2.9 on 2023-12-21 07:35
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0022_auto_20231221_0735'),
10
+ ('users', '0016_auto_20231005_1050'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.RenameModel(
15
+ old_name='UserInstanceRole',
16
+ new_name='InstanceUser',
17
+ ),
18
+ migrations.RemoveField(
19
+ model_name='userdevicereportlog',
20
+ name='at_home',
21
+ ),
22
+ ]
@@ -7,6 +7,8 @@ from django.db.models import Q
7
7
  from django.db import transaction
8
8
  from django.db.models.signals import post_save, post_delete, m2m_changed
9
9
  from django.dispatch import receiver
10
+ from model_utils import FieldTracker
11
+ from dirtyfields import DirtyFieldsMixin
10
12
  from django.core.exceptions import ValidationError
11
13
  from django.contrib.auth.models import (
12
14
  AbstractBaseUser, PermissionsMixin, UserManager as DefaultUserManager
@@ -17,6 +19,7 @@ from location_field.models.plain import PlainLocationField
17
19
  from simo.conf import dynamic_settings
18
20
  from simo.core.utils.mixins import SimoAdminMixin
19
21
  from simo.core.utils.helpers import get_random_string
22
+ from simo.core.events import OnChangeMixin
20
23
  from .middleware import get_current_user
21
24
  from .utils import rebuild_authorized_keys
22
25
 
@@ -69,7 +72,7 @@ class UserManager(DefaultUserManager):
69
72
  return user
70
73
 
71
74
 
72
- class UserInstanceRole(models.Model):
75
+ class InstanceUser(DirtyFieldsMixin, models.Model, OnChangeMixin):
73
76
  user = models.ForeignKey(
74
77
  'User', on_delete=models.CASCADE, related_name='instance_roles'
75
78
  )
@@ -91,6 +94,23 @@ class UserInstanceRole(models.Model):
91
94
  self.instance = self.role.instance
92
95
  return super().save(*args, **kwargs)
93
96
 
97
+ def get_instance(self):
98
+ return self.instance
99
+
100
+
101
+ @receiver(post_save, sender=InstanceUser)
102
+ def post_instance_user_save(sender, instance, created, **kwargs):
103
+ if created:
104
+ return
105
+ from simo.core.events import ObjectManagementEvent
106
+ dirty_fields = instance.get_dirty_fields()
107
+ if 'at_home' in dirty_fields:
108
+ def post_update():
109
+ ObjectManagementEvent(
110
+ instance, 'changed', dirty_fields=dirty_fields
111
+ ).publish()
112
+ transaction.on_commit(post_update)
113
+
94
114
 
95
115
  class User(AbstractBaseUser, SimoAdminMixin):
96
116
  name = models.CharField(_('name'), max_length=150)
@@ -101,7 +121,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
101
121
  )
102
122
  avatar_url = models.URLField(null=True, blank=True)
103
123
  avatar_last_change = models.DateTimeField(auto_now_add=True)
104
- roles = models.ManyToManyField(PermissionsRole, through=UserInstanceRole)
124
+ roles = models.ManyToManyField(PermissionsRole, through=InstanceUser)
105
125
  is_active = models.BooleanField(
106
126
  _('active'),
107
127
  default=True,
@@ -205,7 +225,7 @@ class User(AbstractBaseUser, SimoAdminMixin):
205
225
  if not role:
206
226
  raise ValueError("There is no such a role on this instance")
207
227
 
208
- UserInstanceRole.objects.update_or_create(
228
+ InstanceUser.objects.update_or_create(
209
229
  user=self, instance=self._instance, defaults={
210
230
  'role': role
211
231
  }
@@ -324,7 +344,6 @@ class UserDeviceReportLog(models.Model):
324
344
  help_text="Sent via remote relay if specified, otherwise it's from LAN."
325
345
  )
326
346
  location = PlainLocationField(zoom=7, null=True, blank=True)
327
- at_home = models.BooleanField(default=False)
328
347
 
329
348
  class Meta:
330
349
  ordering = '-datetime',
@@ -3,7 +3,7 @@ from collections.abc import Iterable
3
3
  from simo.core.middleware import get_current_request
4
4
  from simo.core.serializers import TimestampField
5
5
  from easy_thumbnails.files import get_thumbnailer
6
- from .models import User, PermissionsRole, InstanceInvitation, UserInstanceRole
6
+ from .models import User, PermissionsRole, InstanceInvitation, InstanceUser
7
7
 
8
8
 
9
9
  class UserSerializer(serializers.ModelSerializer):
@@ -42,7 +42,7 @@ class UserSerializer(serializers.ModelSerializer):
42
42
  return None
43
43
 
44
44
  def get_at_home(self, obj):
45
- return UserInstanceRole.objects.filter(
45
+ return InstanceUser.objects.filter(
46
46
  user=obj
47
47
  ).first().at_home
48
48
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 1.6.2
3
+ Version: 1.6.4
4
4
  Summary: Smart Home on Steroids!
5
5
  Author-email: Simanas Venčkauskas <simanas@simo.io>
6
6
  Project-URL: Homepage, https://simo.io