simo 1.7.20__py3-none-any.whl → 2.0.0__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 (267) hide show
  1. simo/__pycache__/asgi.cpython-38.pyc +0 -0
  2. simo/__pycache__/settings.cpython-38.pyc +0 -0
  3. simo/__pycache__/urls.cpython-38.pyc +0 -0
  4. simo/__pycache__/wsgi.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/admin.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/auto_urls.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/autocomplete_views.cpython-38.pyc +0 -0
  10. simo/core/__pycache__/base_types.cpython-38.pyc +0 -0
  11. simo/core/__pycache__/context.cpython-38.pyc +0 -0
  12. simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
  13. simo/core/__pycache__/events.cpython-38.pyc +0 -0
  14. simo/core/__pycache__/forms.cpython-38.pyc +0 -0
  15. simo/core/__pycache__/gateways.cpython-38.pyc +0 -0
  16. simo/core/__pycache__/managers.cpython-38.pyc +0 -0
  17. simo/core/__pycache__/middleware.cpython-38.pyc +0 -0
  18. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  19. simo/core/__pycache__/permissions.cpython-38.pyc +0 -0
  20. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  21. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  22. simo/core/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  23. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  24. simo/core/__pycache__/views.cpython-38.pyc +0 -0
  25. simo/core/admin.py +28 -18
  26. simo/core/api.py +157 -16
  27. simo/core/api_meta.py +87 -0
  28. simo/core/auto_urls.py +4 -1
  29. simo/core/autocomplete_views.py +8 -4
  30. simo/core/base_types.py +1 -0
  31. simo/core/context.py +3 -1
  32. simo/core/controllers.py +112 -32
  33. simo/core/db_backend/base.py +7 -22
  34. simo/core/drf_braces/README +3 -0
  35. simo/core/drf_braces/__init__.py +7 -0
  36. simo/core/drf_braces/__pycache__/__init__.cpython-38.pyc +0 -0
  37. simo/core/drf_braces/__pycache__/utils.cpython-38.pyc +0 -0
  38. simo/core/drf_braces/fields/__init__.py +5 -0
  39. simo/core/drf_braces/fields/__pycache__/__init__.cpython-38.pyc +0 -0
  40. simo/core/drf_braces/fields/__pycache__/_fields.cpython-38.pyc +0 -0
  41. simo/core/drf_braces/fields/__pycache__/custom.cpython-38.pyc +0 -0
  42. simo/core/drf_braces/fields/__pycache__/mixins.cpython-38.pyc +0 -0
  43. simo/core/drf_braces/fields/__pycache__/modified.cpython-38.pyc +0 -0
  44. simo/core/drf_braces/fields/_fields.py +48 -0
  45. simo/core/drf_braces/fields/custom.py +107 -0
  46. simo/core/drf_braces/fields/mixins.py +58 -0
  47. simo/core/drf_braces/fields/modified.py +41 -0
  48. simo/core/drf_braces/forms/__init__.py +0 -0
  49. simo/core/drf_braces/forms/fields.py +20 -0
  50. simo/core/drf_braces/forms/serializer_form.py +156 -0
  51. simo/core/drf_braces/mixins.py +52 -0
  52. simo/core/drf_braces/models.py +0 -0
  53. simo/core/drf_braces/parsers.py +72 -0
  54. simo/core/drf_braces/renderers.py +37 -0
  55. simo/core/drf_braces/serializers/__init__.py +0 -0
  56. simo/core/drf_braces/serializers/__pycache__/__init__.cpython-38.pyc +0 -0
  57. simo/core/drf_braces/serializers/__pycache__/form_serializer.cpython-38.pyc +0 -0
  58. simo/core/drf_braces/serializers/enforce_validation_serializer.py +214 -0
  59. simo/core/drf_braces/serializers/form_serializer.py +391 -0
  60. simo/core/drf_braces/serializers/swapping.py +48 -0
  61. simo/core/drf_braces/tests/__init__.py +0 -0
  62. simo/core/drf_braces/tests/fields/__init__.py +0 -0
  63. simo/core/drf_braces/tests/fields/test_custom.py +94 -0
  64. simo/core/drf_braces/tests/fields/test_fields.py +13 -0
  65. simo/core/drf_braces/tests/fields/test_mixins.py +96 -0
  66. simo/core/drf_braces/tests/fields/test_modified.py +40 -0
  67. simo/core/drf_braces/tests/forms/__init__.py +0 -0
  68. simo/core/drf_braces/tests/forms/test_fields.py +46 -0
  69. simo/core/drf_braces/tests/forms/test_serializer_form.py +256 -0
  70. simo/core/drf_braces/tests/serializers/__init__.py +0 -0
  71. simo/core/drf_braces/tests/serializers/test_enforce_validation_serializer.py +169 -0
  72. simo/core/drf_braces/tests/serializers/test_form_serializer.py +387 -0
  73. simo/core/drf_braces/tests/serializers/test_swapping.py +40 -0
  74. simo/core/drf_braces/tests/test_mixins.py +111 -0
  75. simo/core/drf_braces/tests/test_parsers.py +73 -0
  76. simo/core/drf_braces/tests/test_renderers.py +23 -0
  77. simo/core/drf_braces/tests/test_utils.py +73 -0
  78. simo/core/drf_braces/utils.py +209 -0
  79. simo/core/events.py +3 -3
  80. simo/core/forms.py +79 -37
  81. simo/core/gateways.py +31 -14
  82. simo/core/management/commands/gateways_manager.py +0 -1
  83. simo/core/managers.py +81 -0
  84. simo/core/middleware.py +25 -0
  85. simo/core/migrations/0026_category_instance.py +20 -0
  86. simo/core/migrations/0027_remove_component_tags.py +17 -0
  87. simo/core/migrations/0028_rename_subcomponents_component_slaves.py +18 -0
  88. simo/core/migrations/0029_auto_20240229_1331.py +33 -0
  89. simo/core/migrations/__pycache__/0026_category_instance.cpython-38.pyc +0 -0
  90. simo/core/migrations/__pycache__/0027_remove_component_tags.cpython-38.pyc +0 -0
  91. simo/core/migrations/__pycache__/0028_rename_subcomponents_component_slaves.cpython-38.pyc +0 -0
  92. simo/core/migrations/__pycache__/0029_auto_20240229_1331.cpython-38.pyc +0 -0
  93. simo/core/models.py +103 -66
  94. simo/core/permissions.py +28 -2
  95. simo/core/serializers.py +330 -26
  96. simo/core/socket_consumers.py +5 -14
  97. simo/core/tasks.py +11 -1
  98. simo/core/templates/admin/base.html +37 -10
  99. simo/core/templates/admin/wizard/discovery.html +188 -0
  100. simo/core/templates/admin/wizard/wizard_add.html +5 -5
  101. simo/core/utils/__pycache__/serialization.cpython-38.pyc +0 -0
  102. simo/core/utils/admin.py +9 -2
  103. simo/core/utils/formsets.py +17 -16
  104. simo/core/utils/helpers.py +1 -0
  105. simo/core/utils/serialization.py +56 -0
  106. simo/core/utils/type_constants.py +1 -1
  107. simo/core/utils/validators.py +14 -1
  108. simo/core/views.py +13 -0
  109. simo/fleet/__pycache__/admin.cpython-38.pyc +0 -0
  110. simo/fleet/__pycache__/api.cpython-38.pyc +0 -0
  111. simo/fleet/__pycache__/auto_urls.cpython-38.pyc +0 -0
  112. simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
  113. simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
  114. simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
  115. simo/fleet/__pycache__/managers.cpython-38.pyc +0 -0
  116. simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
  117. simo/fleet/__pycache__/serializers.cpython-38.pyc +0 -0
  118. simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  119. simo/fleet/__pycache__/utils.cpython-38.pyc +0 -0
  120. simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
  121. simo/fleet/admin.py +54 -25
  122. simo/fleet/api.py +59 -3
  123. simo/fleet/auto_urls.py +2 -3
  124. simo/fleet/controllers.py +199 -16
  125. simo/fleet/forms.py +325 -483
  126. simo/fleet/gateways.py +44 -2
  127. simo/fleet/managers.py +32 -0
  128. simo/fleet/migrations/0025_auto_20240130_1334.py +27 -0
  129. simo/fleet/migrations/0026_rename_i2cinterface_scl_pin_and_more.py +64 -0
  130. simo/fleet/migrations/0027_auto_20240306_0802.py +170 -0
  131. simo/fleet/migrations/0028_remove_i2cinterface_scl_pin_no_and_more.py +21 -0
  132. simo/fleet/migrations/0029_alter_i2cinterface_scl_pin_and_more.py +24 -0
  133. simo/fleet/migrations/0030_colonelpin_label_alter_colonel_type.py +24 -0
  134. simo/fleet/migrations/0031_alter_colonel_type.py +18 -0
  135. simo/fleet/migrations/__pycache__/0025_auto_20240130_1334.cpython-38.pyc +0 -0
  136. simo/fleet/migrations/__pycache__/0026_rename_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
  137. simo/fleet/migrations/__pycache__/0027_auto_20240306_0802.cpython-38.pyc +0 -0
  138. simo/fleet/migrations/__pycache__/0028_remove_i2cinterface_scl_pin_no_and_more.cpython-38.pyc +0 -0
  139. simo/fleet/migrations/__pycache__/0029_alter_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
  140. simo/fleet/migrations/__pycache__/0030_colonelpin_label_alter_colonel_type.cpython-38.pyc +0 -0
  141. simo/fleet/migrations/__pycache__/0031_alter_colonel_type.cpython-38.pyc +0 -0
  142. simo/fleet/models.py +134 -82
  143. simo/fleet/serializers.py +35 -1
  144. simo/fleet/socket_consumers.py +239 -76
  145. simo/fleet/utils.py +15 -53
  146. simo/fleet/views.py +28 -14
  147. simo/generic/controllers.py +13 -89
  148. simo/generic/forms.py +29 -18
  149. simo/generic/gateways.py +73 -2
  150. simo/generic/models.py +3 -3
  151. simo/multimedia/controllers.py +9 -8
  152. simo/settings.py +7 -4
  153. simo/urls.py +4 -8
  154. simo/users/__pycache__/admin.cpython-38.pyc +0 -0
  155. simo/users/__pycache__/api.cpython-38.pyc +0 -0
  156. simo/users/__pycache__/auto_urls.cpython-38.pyc +0 -0
  157. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  158. simo/users/__pycache__/serializers.cpython-38.pyc +0 -0
  159. simo/users/__pycache__/sso_urls.cpython-38.pyc +0 -0
  160. simo/users/admin.py +8 -1
  161. simo/users/api.py +38 -2
  162. simo/users/auto_urls.py +2 -2
  163. simo/users/migrations/0025_rename_name_fingerprint_type_and_more.py +22 -0
  164. simo/users/migrations/__pycache__/0025_rename_name_fingerprint_type_and_more.cpython-38.pyc +0 -0
  165. simo/users/models.py +2 -3
  166. simo/users/serializers.py +15 -1
  167. simo/users/sso_urls.py +3 -3
  168. simo/wsgi.py +7 -0
  169. {simo-1.7.20.dist-info → simo-2.0.0.dist-info}/METADATA +8 -9
  170. {simo-1.7.20.dist-info → simo-2.0.0.dist-info}/RECORD +173 -189
  171. {simo-1.7.20.dist-info → simo-2.0.0.dist-info}/WHEEL +1 -1
  172. simo/core/db_backend/__pycache__/__init__.cpython-38.pyc +0 -0
  173. simo/core/db_backend/__pycache__/base.cpython-38.pyc +0 -0
  174. simo/core/management/commands/__pycache__/gateways_manager.cpython-38.pyc +0 -0
  175. simo/core/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  176. simo/core/migrations/__pycache__/0002_load_icons.cpython-38.pyc +0 -0
  177. simo/core/migrations/__pycache__/0003_create_default_zones_and_categories.cpython-38.pyc +0 -0
  178. simo/core/migrations/__pycache__/0004_create_generic.cpython-38.pyc +0 -0
  179. simo/core/migrations/__pycache__/0005_component_subcomponents.cpython-38.pyc +0 -0
  180. simo/core/migrations/__pycache__/0006_alter_component_subcomponents.cpython-38.pyc +0 -0
  181. simo/core/migrations/__pycache__/0007_component_change_init_to.cpython-38.pyc +0 -0
  182. simo/core/migrations/__pycache__/0008_alter_component_change_init_to.cpython-38.pyc +0 -0
  183. simo/core/migrations/__pycache__/0009_auto_20220707_1404.cpython-38.pyc +0 -0
  184. simo/core/migrations/__pycache__/0010_historyaggregate.cpython-38.pyc +0 -0
  185. simo/core/migrations/__pycache__/0011_component_last_change.cpython-38.pyc +0 -0
  186. simo/core/migrations/__pycache__/0012_instance.cpython-38.pyc +0 -0
  187. simo/core/migrations/__pycache__/0013_auto_20231003_0754.cpython-38.pyc +0 -0
  188. simo/core/migrations/__pycache__/0014_zone_instance.cpython-38.pyc +0 -0
  189. simo/core/migrations/__pycache__/0015_auto_20231004_1113.cpython-38.pyc +0 -0
  190. simo/core/migrations/__pycache__/0016_auto_20231004_1113.cpython-38.pyc +0 -0
  191. simo/core/migrations/__pycache__/0017_auto_20231004_1313.cpython-38.pyc +0 -0
  192. simo/core/migrations/__pycache__/0018_auto_20231005_0622.cpython-38.pyc +0 -0
  193. simo/core/migrations/__pycache__/0019_alter_gateway_type.cpython-38.pyc +0 -0
  194. simo/core/migrations/__pycache__/0020_component_meta.cpython-38.pyc +0 -0
  195. simo/core/migrations/__pycache__/0021_auto_20231020_1041.cpython-38.pyc +0 -0
  196. simo/core/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  197. simo/core/templatetags/__pycache__/__init__.cpython-38.pyc +0 -0
  198. simo/core/templatetags/__pycache__/components_list.cpython-38.pyc +0 -0
  199. simo/core/utils/__pycache__/__init__.cpython-38.pyc +0 -0
  200. simo/core/utils/__pycache__/admin.cpython-38.pyc +0 -0
  201. simo/core/utils/__pycache__/config_values.cpython-38.pyc +0 -0
  202. simo/core/utils/__pycache__/easing.cpython-38.pyc +0 -0
  203. simo/core/utils/__pycache__/form_fields.cpython-38.pyc +0 -0
  204. simo/core/utils/__pycache__/form_widgets.cpython-38.pyc +0 -0
  205. simo/core/utils/__pycache__/formsets.cpython-38.pyc +0 -0
  206. simo/core/utils/__pycache__/helpers.cpython-38.pyc +0 -0
  207. simo/core/utils/__pycache__/logs.cpython-38.pyc +0 -0
  208. simo/core/utils/__pycache__/mixins.cpython-38.pyc +0 -0
  209. simo/core/utils/__pycache__/model_helpers.cpython-38.pyc +0 -0
  210. simo/core/utils/__pycache__/relay.cpython-38.pyc +0 -0
  211. simo/core/utils/__pycache__/type_constants.cpython-38.pyc +0 -0
  212. simo/core/utils/__pycache__/validators.cpython-38.pyc +0 -0
  213. simo/fleet/tasks.py +0 -25
  214. simo/generic/__pycache__/__init__.cpython-37.pyc +0 -0
  215. simo/generic/__pycache__/__init__.cpython-38.pyc +0 -0
  216. simo/generic/__pycache__/app_widgets.cpython-38.pyc +0 -0
  217. simo/generic/__pycache__/base_types.cpython-38.pyc +0 -0
  218. simo/generic/__pycache__/controllers.cpython-37.pyc +0 -0
  219. simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
  220. simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
  221. simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
  222. simo/generic/__pycache__/models.cpython-38.pyc +0 -0
  223. simo/generic/__pycache__/routing.cpython-38.pyc +0 -0
  224. simo/generic/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  225. simo/generic/__pycache__/widgets.cpython-37.pyc +0 -0
  226. simo/multimedia/__pycache__/__init__.cpython-38.pyc +0 -0
  227. simo/multimedia/__pycache__/admin.cpython-38.pyc +0 -0
  228. simo/multimedia/__pycache__/api.cpython-38.pyc +0 -0
  229. simo/multimedia/__pycache__/app_widgets.cpython-38.pyc +0 -0
  230. simo/multimedia/__pycache__/base_types.cpython-38.pyc +0 -0
  231. simo/multimedia/__pycache__/controllers.cpython-38.pyc +0 -0
  232. simo/multimedia/__pycache__/forms.cpython-38.pyc +0 -0
  233. simo/multimedia/__pycache__/models.cpython-38.pyc +0 -0
  234. simo/multimedia/__pycache__/serializers.cpython-38.pyc +0 -0
  235. simo/multimedia/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  236. simo/multimedia/migrations/__pycache__/0002_sound_length.cpython-38.pyc +0 -0
  237. simo/multimedia/migrations/__pycache__/0003_alter_sound_length.cpython-38.pyc +0 -0
  238. simo/multimedia/migrations/__pycache__/0004_auto_20231023_1055.cpython-38.pyc +0 -0
  239. simo/multimedia/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  240. simo/notifications/__pycache__/__init__.cpython-38.pyc +0 -0
  241. simo/notifications/__pycache__/admin.cpython-38.pyc +0 -0
  242. simo/notifications/__pycache__/api.cpython-38.pyc +0 -0
  243. simo/notifications/__pycache__/models.cpython-38.pyc +0 -0
  244. simo/notifications/__pycache__/serializers.cpython-38.pyc +0 -0
  245. simo/notifications/__pycache__/utils.cpython-38.pyc +0 -0
  246. simo/notifications/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  247. simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.pyc +0 -0
  248. simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  249. simo/users/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  250. simo/users/migrations/__pycache__/0002_componentpermission.cpython-38.pyc +0 -0
  251. simo/users/migrations/__pycache__/0003_create_roles_and_system_user.cpython-38.pyc +0 -0
  252. simo/users/migrations/__pycache__/0004_user_secret_key.cpython-38.pyc +0 -0
  253. simo/users/migrations/__pycache__/0005_permissionsrole_instance.cpython-38.pyc +0 -0
  254. simo/users/migrations/__pycache__/0006_auto_20231003_0850.cpython-38.pyc +0 -0
  255. simo/users/migrations/__pycache__/0007_auto_20231003_1228.cpython-38.pyc +0 -0
  256. simo/users/migrations/__pycache__/0008_auto_20231003_1229.cpython-38.pyc +0 -0
  257. simo/users/migrations/__pycache__/0009_remove_user_role.cpython-38.pyc +0 -0
  258. simo/users/migrations/__pycache__/0010_auto_20231004_1313.cpython-38.pyc +0 -0
  259. simo/users/migrations/__pycache__/0011_auto_20231004_1313.cpython-38.pyc +0 -0
  260. simo/users/migrations/__pycache__/0012_alter_userinstancerole_unique_together.cpython-38.pyc +0 -0
  261. simo/users/migrations/__pycache__/0013_remove_user_roles.cpython-38.pyc +0 -0
  262. simo/users/migrations/__pycache__/0014_user_roles.cpython-38.pyc +0 -0
  263. simo/users/migrations/__pycache__/0015_remove_user_at_home.cpython-38.pyc +0 -0
  264. simo/users/migrations/__pycache__/0016_auto_20231005_1050.cpython-38.pyc +0 -0
  265. simo/users/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  266. {simo-1.7.20.dist-info → simo-2.0.0.dist-info}/LICENSE.md +0 -0
  267. {simo-1.7.20.dist-info → simo-2.0.0.dist-info}/top_level.txt +0 -0
simo/fleet/auto_urls.py CHANGED
@@ -1,5 +1,4 @@
1
- from django.conf.urls import include, url
2
- from django.urls import path
1
+ from django.urls import path, re_path
3
2
  from django.views.generic import TemplateView
4
3
  from .views import (
5
4
  colonels_ping,
@@ -8,7 +7,7 @@ from .views import (
8
7
  )
9
8
 
10
9
  urlpatterns = [
11
- url(
10
+ re_path(
12
11
  r"^colonels-ping/$", colonels_ping, name='colonels-ping'
13
12
  ),
14
13
  path(
simo/fleet/controllers.py CHANGED
@@ -1,4 +1,4 @@
1
- from django.core.exceptions import ValidationError
1
+ from django.utils.translation import gettext_lazy as _
2
2
  from simo.core.events import GatewayObjectCommand
3
3
  from simo.core.controllers import (
4
4
  BinarySensor as BaseBinarySensor,
@@ -8,19 +8,23 @@ from simo.core.controllers import (
8
8
  )
9
9
  from simo.conf import dynamic_settings
10
10
  from simo.core.app_widgets import NumericSensorWidget
11
- from simo.core.controllers import BEFORE_SEND, BEFORE_SET, ControllerBase
12
- from simo.core.utils import easing
11
+ from simo.core.controllers import Lock
13
12
  from simo.core.utils.helpers import heat_index
13
+ from simo.core.utils.serialization import (
14
+ serialize_form_data, deserialize_form_data
15
+ )
14
16
  from simo.generic.controllers import Blinds as GenericBlinds
15
17
  from .models import Colonel
16
18
  from .gateways import FleetGatewayHandler
17
19
  from .forms import (
20
+ ColonelPinChoiceField,
18
21
  ColonelBinarySensorConfigForm, ColonelTouchSensorConfigForm,
19
22
  ColonelSwitchConfigForm, ColonelPWMOutputConfigForm,
20
23
  ColonelNumericSensorConfigForm, ColonelRGBLightConfigForm,
21
24
  ColonelDHTSensorConfigForm, DS18B20SensorConfigForm,
22
- BME680SensorConfigForm,
23
- DualMotorValveForm, BlindsConfigForm, BurglarSmokeDetectorConfigForm
25
+ BME680SensorConfigForm, MPC9808SensorConfigForm,
26
+ DualMotorValveForm, BlindsConfigForm, BurglarSmokeDetectorConfigForm,
27
+ TTLockConfigForm
24
28
  )
25
29
 
26
30
 
@@ -47,17 +51,34 @@ class FleeDeviceMixin:
47
51
  options['controls_enabled'] = True
48
52
  self.update_options(options)
49
53
 
54
+ def _get_colonel_config(self):
55
+ declared_fields = self.config_form.declared_fields
56
+ config = {}
57
+ for key, val in self.component.config.items():
58
+ if key == 'colonel':
59
+ continue
60
+ if val in ({}, [], None):
61
+ continue
62
+ if isinstance(declared_fields.get(key), ColonelPinChoiceField):
63
+ config[f'{key}_no'] = self.component.config[f'{key}_no']
64
+ else:
65
+ config[key] = val
66
+ return config
67
+
50
68
 
51
69
  class BasicSensorMixin:
52
70
  gateway_class = FleetGatewayHandler
53
71
 
54
- def _get_occupied_pins(self):
55
- return [self.component.config['pin']]
56
72
 
57
73
 
58
74
  class BinarySensor(FleeDeviceMixin, BasicSensorMixin, BaseBinarySensor):
59
75
  config_form = ColonelBinarySensorConfigForm
60
76
 
77
+ def _get_occupied_pins(self):
78
+ return [
79
+ self.component.config['pin_no'],
80
+ ]
81
+
61
82
 
62
83
  class BurglarSmokeDetector(BinarySensor):
63
84
  config_form = BurglarSmokeDetectorConfigForm
@@ -65,8 +86,8 @@ class BurglarSmokeDetector(BinarySensor):
65
86
 
66
87
  def _get_occupied_pins(self):
67
88
  return [
68
- self.component.config['power_pin'],
69
- self.component.config['sensor_pin']
89
+ self.component.config['power_pin_no'],
90
+ self.component.config['sensor_pin_no']
70
91
  ]
71
92
 
72
93
 
@@ -74,11 +95,21 @@ class AnalogSensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
74
95
  config_form = ColonelNumericSensorConfigForm
75
96
  name = "Analog sensor"
76
97
 
98
+ def _get_occupied_pins(self):
99
+ return [
100
+ self.component.config['pin_no'],
101
+ ]
102
+
77
103
 
78
104
  class DS18B20Sensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
79
105
  config_form = DS18B20SensorConfigForm
80
106
  name = "DS18B20 Temperature sensor"
81
107
 
108
+ def _get_occupied_pins(self):
109
+ return [
110
+ self.component.config['pin_no'],
111
+ ]
112
+
82
113
 
83
114
  class BaseClimateSensor(FleeDeviceMixin, BasicSensorMixin, BaseMultiSensor):
84
115
  app_widget = NumericSensorWidget
@@ -125,19 +156,30 @@ class DHTSensor(BaseClimateSensor):
125
156
  config_form = ColonelDHTSensorConfigForm
126
157
  name = "DHT climate sensor"
127
158
 
159
+ def _get_occupied_pins(self):
160
+ return [
161
+ self.component.config['pin_no'],
162
+ ]
163
+
128
164
 
129
165
  class BME680Sensor(BaseClimateSensor):
130
166
  config_form = BME680SensorConfigForm
131
167
  name = "BME680 Climate Sensor (I2C)"
132
168
 
133
169
 
170
+ class MPC9808TempSensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
171
+ config_form = MPC9808SensorConfigForm
172
+ name = "MPC9808 Temperature Sensor (I2C)"
173
+
174
+
175
+
134
176
  class BasicOutputMixin:
135
177
  gateway_class = FleetGatewayHandler
136
178
 
137
179
  def _get_occupied_pins(self):
138
- pins = [self.component.config['output_pin']]
180
+ pins = [self.component.config['output_pin_no']]
139
181
  for control_unit in self.component.config.get('controls', []):
140
- pins.append(control_unit['pin'])
182
+ pins.append(control_unit['pin_no'])
141
183
  return pins
142
184
 
143
185
  def _send_to_device(self, value):
@@ -216,8 +258,8 @@ class DualMotorValve(FleeDeviceMixin, BasicOutputMixin, BaseSwitch):
216
258
 
217
259
  def _get_occupied_pins(self):
218
260
  return [
219
- self.component.config['open_pin'],
220
- self.component.config['close_pin']
261
+ self.component.config['open_pin_no'],
262
+ self.component.config['close_pin_no']
221
263
  ]
222
264
 
223
265
 
@@ -227,9 +269,150 @@ class Blinds(FleeDeviceMixin, BasicOutputMixin, GenericBlinds):
227
269
 
228
270
  def _get_occupied_pins(self):
229
271
  pins = [
230
- self.component.config['open_pin'],
231
- self.component.config['close_pin']
272
+ self.component.config['open_pin_no'],
273
+ self.component.config['close_pin_no']
232
274
  ]
233
275
  for p in self.component.config.get('controls', []):
234
276
  pins.append(p['pin'])
235
- return pins
277
+ return pins
278
+
279
+
280
+ class TTLock(FleeDeviceMixin, Lock):
281
+ gateway_class = FleetGatewayHandler
282
+ config_form = TTLockConfigForm
283
+ name = 'TTLock'
284
+ discovery_msg = _("Please activate your TTLock so it can be discovered.")
285
+
286
+ def _send_to_device(self, value):
287
+ GatewayObjectCommand(
288
+ self.component.gateway,
289
+ Colonel(id=self.component.config['colonel']),
290
+ set_val=value,
291
+ component_id=self.component.id,
292
+ ).publish()
293
+
294
+ @classmethod
295
+ def init_discovery(self, form_cleaned_data):
296
+ from simo.core.models import Gateway
297
+ print("Serialized form: ", serialize_form_data(form_cleaned_data))
298
+ gateway = Gateway.objects.filter(type=self.gateway_class.uid).first()
299
+ gateway.start_discovery(
300
+ self.uid, serialize_form_data(form_cleaned_data),
301
+ timeout=60
302
+ )
303
+ GatewayObjectCommand(
304
+ gateway, form_cleaned_data['colonel'],
305
+ command='discover-ttlock',
306
+ ).publish()
307
+
308
+ @classmethod
309
+ def _process_discovery(cls, started_with, data):
310
+ if data['discover-ttlock'] == 'fail':
311
+ if data['result'] == 1:
312
+ return {'error': 'TTLock not found.'}
313
+ elif data['result'] == 2:
314
+ return {'error': 'Error connecting to your TTLock.'}
315
+ elif data['result'] == 3:
316
+ return {
317
+ 'error': 'Unable to initialize your TTLock. '
318
+ 'Perform full reset. '
319
+ 'Allow the lock to rest for at least 2 min. '
320
+ 'Move your lock as close as possible to your SIMO.io Colonel. '
321
+ 'Retry!'
322
+ }
323
+ elif data['result'] == 4:
324
+ return {
325
+ 'error': 'BLE is available only on LAN connected colonels.'
326
+ }
327
+ elif data['result'] == 5:
328
+ return {
329
+ 'error': 'Single TTLock is alowed per Colonel.'
330
+ }
331
+ else:
332
+ return {'error': data['result']}
333
+
334
+ started_with = deserialize_form_data(started_with)
335
+ form = TTLockConfigForm(controller_uid=cls.uid, data=started_with)
336
+ if form.is_valid():
337
+ new_component = form.save()
338
+ new_component.config.update(data.get('result', {}).get('config'))
339
+ new_component.meta['finalization_data'] = {
340
+ 'temp_id': data['result']['id'],
341
+ 'permanent_id': new_component.id,
342
+ 'config': {
343
+ 'type': cls.uid.split('.')[-1],
344
+ 'config': new_component.config,
345
+ 'val': False,
346
+ },
347
+ }
348
+ new_component.save()
349
+ GatewayObjectCommand(
350
+ new_component.gateway, Colonel(
351
+ id=new_component.config['colonel']
352
+ ), command='finalize',
353
+ data=new_component.meta['finalization_data'],
354
+ ).publish()
355
+ return [new_component]
356
+
357
+ # Literally impossible, but just in case...
358
+ return {'error': 'INVALID INITIAL DISCOVERY FORM!'}
359
+
360
+
361
+ def add_code(self, code):
362
+ code = str(code)
363
+ assert 4 <= len(code) <= 8
364
+ for no in code:
365
+ try:
366
+ int(no)
367
+ except:
368
+ raise AssertionError("Digits only please!")
369
+ GatewayObjectCommand(
370
+ self.component.gateway,
371
+ Colonel(id=self.component.config['colonel']),
372
+ id=self.component.id,
373
+ command='call', method='add_code', args=[str(code)]
374
+ ).publish()
375
+
376
+ def delete_code(self, code):
377
+ GatewayObjectCommand(
378
+ self.component.gateway,
379
+ Colonel(id=self.component.config['colonel']),
380
+ id=self.component.id,
381
+ command='call', method='delete_code', args=[str(code)]
382
+ ).publish()
383
+
384
+ def get_codes(self):
385
+ GatewayObjectCommand(
386
+ self.component.gateway,
387
+ Colonel(id=self.component.config['colonel']),
388
+ id=self.component.id,
389
+ command='call', method='get_codes'
390
+ ).publish()
391
+
392
+
393
+ def add_fingerprint(self):
394
+ GatewayObjectCommand(
395
+ self.component.gateway,
396
+ Colonel(id=self.component.config['colonel']),
397
+ id=self.component.id,
398
+ command='call', method='add_fingerprint'
399
+ ).publish()
400
+
401
+ def delete_fingerprint(self, code):
402
+ GatewayObjectCommand(
403
+ self.component.gateway,
404
+ Colonel(id=self.component.config['colonel']),
405
+ id=self.component.id,
406
+ command='call', method='delete_fingerprint', args=[str(code)]
407
+ ).publish()
408
+
409
+ def get_fingerprints(self):
410
+ GatewayObjectCommand(
411
+ self.component.gateway,
412
+ Colonel(id=self.component.config['colonel']),
413
+ id=self.component.id,
414
+ command='call', method='get_fingerprints'
415
+ ).publish()
416
+
417
+
418
+