simo 1.7.19__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 (289) hide show
  1. simo/__pycache__/asgi.cpython-38.pyc +0 -0
  2. simo/__pycache__/on_http_start.cpython-38.pyc +0 -0
  3. simo/__pycache__/settings.cpython-38.pyc +0 -0
  4. simo/__pycache__/urls.cpython-38.pyc +0 -0
  5. simo/__pycache__/wsgi.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/__init__.cpython-38.pyc +0 -0
  7. simo/core/__pycache__/admin.cpython-38.pyc +0 -0
  8. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  9. simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
  10. simo/core/__pycache__/auto_urls.cpython-38.pyc +0 -0
  11. simo/core/__pycache__/autocomplete_views.cpython-38.pyc +0 -0
  12. simo/core/__pycache__/base_types.cpython-38.pyc +0 -0
  13. simo/core/__pycache__/context.cpython-38.pyc +0 -0
  14. simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
  15. simo/core/__pycache__/events.cpython-38.pyc +0 -0
  16. simo/core/__pycache__/filters.cpython-38.pyc +0 -0
  17. simo/core/__pycache__/forms.cpython-38.pyc +0 -0
  18. simo/core/__pycache__/gateways.cpython-38.pyc +0 -0
  19. simo/core/__pycache__/managers.cpython-38.pyc +0 -0
  20. simo/core/__pycache__/middleware.cpython-38.pyc +0 -0
  21. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  22. simo/core/__pycache__/permissions.cpython-38.pyc +0 -0
  23. simo/core/__pycache__/routing.cpython-38.pyc +0 -0
  24. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  25. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  26. simo/core/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  27. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  28. simo/core/__pycache__/todos.cpython-38.pyc +0 -0
  29. simo/core/__pycache__/views.cpython-38.pyc +0 -0
  30. simo/core/admin.py +28 -18
  31. simo/core/api.py +157 -16
  32. simo/core/api_meta.py +87 -0
  33. simo/core/auto_urls.py +4 -1
  34. simo/core/autocomplete_views.py +8 -4
  35. simo/core/base_types.py +1 -0
  36. simo/core/context.py +3 -1
  37. simo/core/controllers.py +112 -32
  38. simo/core/db_backend/base.py +7 -22
  39. simo/core/drf_braces/README +3 -0
  40. simo/core/drf_braces/__init__.py +7 -0
  41. simo/core/drf_braces/__pycache__/__init__.cpython-38.pyc +0 -0
  42. simo/core/drf_braces/__pycache__/utils.cpython-38.pyc +0 -0
  43. simo/core/drf_braces/fields/__init__.py +5 -0
  44. simo/core/drf_braces/fields/__pycache__/__init__.cpython-38.pyc +0 -0
  45. simo/core/drf_braces/fields/__pycache__/_fields.cpython-38.pyc +0 -0
  46. simo/core/drf_braces/fields/__pycache__/custom.cpython-38.pyc +0 -0
  47. simo/core/drf_braces/fields/__pycache__/mixins.cpython-38.pyc +0 -0
  48. simo/core/drf_braces/fields/__pycache__/modified.cpython-38.pyc +0 -0
  49. simo/core/drf_braces/fields/_fields.py +48 -0
  50. simo/core/drf_braces/fields/custom.py +107 -0
  51. simo/core/drf_braces/fields/mixins.py +58 -0
  52. simo/core/drf_braces/fields/modified.py +41 -0
  53. simo/core/drf_braces/forms/__init__.py +0 -0
  54. simo/core/drf_braces/forms/fields.py +20 -0
  55. simo/core/drf_braces/forms/serializer_form.py +156 -0
  56. simo/core/drf_braces/mixins.py +52 -0
  57. simo/core/drf_braces/models.py +0 -0
  58. simo/core/drf_braces/parsers.py +72 -0
  59. simo/core/drf_braces/renderers.py +37 -0
  60. simo/core/drf_braces/serializers/__init__.py +0 -0
  61. simo/core/drf_braces/serializers/__pycache__/__init__.cpython-38.pyc +0 -0
  62. simo/core/drf_braces/serializers/__pycache__/form_serializer.cpython-38.pyc +0 -0
  63. simo/core/drf_braces/serializers/enforce_validation_serializer.py +214 -0
  64. simo/core/drf_braces/serializers/form_serializer.py +391 -0
  65. simo/core/drf_braces/serializers/swapping.py +48 -0
  66. simo/core/drf_braces/tests/__init__.py +0 -0
  67. simo/core/drf_braces/tests/fields/__init__.py +0 -0
  68. simo/core/drf_braces/tests/fields/test_custom.py +94 -0
  69. simo/core/drf_braces/tests/fields/test_fields.py +13 -0
  70. simo/core/drf_braces/tests/fields/test_mixins.py +96 -0
  71. simo/core/drf_braces/tests/fields/test_modified.py +40 -0
  72. simo/core/drf_braces/tests/forms/__init__.py +0 -0
  73. simo/core/drf_braces/tests/forms/test_fields.py +46 -0
  74. simo/core/drf_braces/tests/forms/test_serializer_form.py +256 -0
  75. simo/core/drf_braces/tests/serializers/__init__.py +0 -0
  76. simo/core/drf_braces/tests/serializers/test_enforce_validation_serializer.py +169 -0
  77. simo/core/drf_braces/tests/serializers/test_form_serializer.py +387 -0
  78. simo/core/drf_braces/tests/serializers/test_swapping.py +40 -0
  79. simo/core/drf_braces/tests/test_mixins.py +111 -0
  80. simo/core/drf_braces/tests/test_parsers.py +73 -0
  81. simo/core/drf_braces/tests/test_renderers.py +23 -0
  82. simo/core/drf_braces/tests/test_utils.py +73 -0
  83. simo/core/drf_braces/utils.py +209 -0
  84. simo/core/events.py +3 -3
  85. simo/core/forms.py +79 -37
  86. simo/core/gateways.py +31 -14
  87. simo/core/management/__pycache__/__init__.cpython-38.pyc +0 -0
  88. simo/core/management/commands/__pycache__/__init__.cpython-38.pyc +0 -0
  89. simo/core/management/commands/gateways_manager.py +0 -1
  90. simo/core/managers.py +81 -0
  91. simo/core/middleware.py +25 -0
  92. simo/core/migrations/0026_category_instance.py +20 -0
  93. simo/core/migrations/0027_remove_component_tags.py +17 -0
  94. simo/core/migrations/0028_rename_subcomponents_component_slaves.py +18 -0
  95. simo/core/migrations/0029_auto_20240229_1331.py +33 -0
  96. simo/core/migrations/__pycache__/0026_category_instance.cpython-38.pyc +0 -0
  97. simo/core/migrations/__pycache__/0027_remove_component_tags.cpython-38.pyc +0 -0
  98. simo/core/migrations/__pycache__/0028_rename_subcomponents_component_slaves.cpython-38.pyc +0 -0
  99. simo/core/migrations/__pycache__/0029_auto_20240229_1331.cpython-38.pyc +0 -0
  100. simo/core/models.py +103 -66
  101. simo/core/permissions.py +28 -2
  102. simo/core/serializers.py +330 -26
  103. simo/core/socket_consumers.py +5 -14
  104. simo/core/tasks.py +11 -1
  105. simo/core/templates/admin/base.html +37 -10
  106. simo/core/templates/admin/wizard/discovery.html +188 -0
  107. simo/core/templates/admin/wizard/wizard_add.html +5 -5
  108. simo/core/utils/__pycache__/serialization.cpython-38.pyc +0 -0
  109. simo/core/utils/admin.py +9 -2
  110. simo/core/utils/formsets.py +17 -16
  111. simo/core/utils/helpers.py +1 -0
  112. simo/core/utils/serialization.py +56 -0
  113. simo/core/utils/type_constants.py +1 -1
  114. simo/core/utils/validators.py +14 -1
  115. simo/core/views.py +13 -0
  116. simo/fleet/__pycache__/admin.cpython-38.pyc +0 -0
  117. simo/fleet/__pycache__/api.cpython-38.pyc +0 -0
  118. simo/fleet/__pycache__/auto_urls.cpython-38.pyc +0 -0
  119. simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
  120. simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
  121. simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
  122. simo/fleet/__pycache__/managers.cpython-38.pyc +0 -0
  123. simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
  124. simo/fleet/__pycache__/serializers.cpython-38.pyc +0 -0
  125. simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  126. simo/fleet/__pycache__/utils.cpython-38.pyc +0 -0
  127. simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
  128. simo/fleet/admin.py +54 -25
  129. simo/fleet/api.py +59 -3
  130. simo/fleet/auto_urls.py +2 -3
  131. simo/fleet/controllers.py +199 -16
  132. simo/fleet/forms.py +325 -483
  133. simo/fleet/gateways.py +44 -2
  134. simo/fleet/managers.py +32 -0
  135. simo/fleet/migrations/0025_auto_20240130_1334.py +27 -0
  136. simo/fleet/migrations/0026_rename_i2cinterface_scl_pin_and_more.py +64 -0
  137. simo/fleet/migrations/0027_auto_20240306_0802.py +170 -0
  138. simo/fleet/migrations/0028_remove_i2cinterface_scl_pin_no_and_more.py +21 -0
  139. simo/fleet/migrations/0029_alter_i2cinterface_scl_pin_and_more.py +24 -0
  140. simo/fleet/migrations/0030_colonelpin_label_alter_colonel_type.py +24 -0
  141. simo/fleet/migrations/0031_alter_colonel_type.py +18 -0
  142. simo/fleet/migrations/__pycache__/0025_auto_20240130_1334.cpython-38.pyc +0 -0
  143. simo/fleet/migrations/__pycache__/0026_rename_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
  144. simo/fleet/migrations/__pycache__/0027_auto_20240306_0802.cpython-38.pyc +0 -0
  145. simo/fleet/migrations/__pycache__/0028_remove_i2cinterface_scl_pin_no_and_more.cpython-38.pyc +0 -0
  146. simo/fleet/migrations/__pycache__/0029_alter_i2cinterface_scl_pin_and_more.cpython-38.pyc +0 -0
  147. simo/fleet/migrations/__pycache__/0030_colonelpin_label_alter_colonel_type.cpython-38.pyc +0 -0
  148. simo/fleet/migrations/__pycache__/0031_alter_colonel_type.cpython-38.pyc +0 -0
  149. simo/fleet/models.py +134 -82
  150. simo/fleet/serializers.py +35 -1
  151. simo/fleet/socket_consumers.py +239 -76
  152. simo/fleet/utils.py +15 -53
  153. simo/fleet/views.py +28 -14
  154. simo/generic/controllers.py +13 -89
  155. simo/generic/forms.py +30 -23
  156. simo/generic/gateways.py +98 -10
  157. simo/generic/models.py +3 -3
  158. simo/multimedia/controllers.py +9 -8
  159. simo/settings.py +7 -4
  160. simo/urls.py +4 -8
  161. simo/users/__pycache__/admin.cpython-38.pyc +0 -0
  162. simo/users/__pycache__/api.cpython-38.pyc +0 -0
  163. simo/users/__pycache__/auto_urls.cpython-38.pyc +0 -0
  164. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  165. simo/users/__pycache__/serializers.cpython-38.pyc +0 -0
  166. simo/users/__pycache__/sso_urls.cpython-38.pyc +0 -0
  167. simo/users/admin.py +8 -1
  168. simo/users/api.py +38 -2
  169. simo/users/auto_urls.py +2 -2
  170. simo/users/migrations/0025_rename_name_fingerprint_type_and_more.py +22 -0
  171. simo/users/migrations/__pycache__/0025_rename_name_fingerprint_type_and_more.cpython-38.pyc +0 -0
  172. simo/users/models.py +2 -3
  173. simo/users/serializers.py +15 -1
  174. simo/users/sso_urls.py +3 -3
  175. simo/wsgi.py +7 -0
  176. {simo-1.7.19.dist-info → simo-2.0.0.dist-info}/METADATA +8 -9
  177. {simo-1.7.19.dist-info → simo-2.0.0.dist-info}/RECORD +180 -210
  178. {simo-1.7.19.dist-info → simo-2.0.0.dist-info}/WHEEL +1 -1
  179. simo/core/__pycache__/__init__.cpython-37.pyc +0 -0
  180. simo/core/__pycache__/admin.cpython-37.pyc +0 -0
  181. simo/core/__pycache__/api.cpython-37.pyc +0 -0
  182. simo/core/__pycache__/apps.cpython-38.pyc +0 -0
  183. simo/core/__pycache__/controllers.cpython-37.pyc +0 -0
  184. simo/core/__pycache__/events.cpython-37.pyc +0 -0
  185. simo/core/__pycache__/forms.cpython-37.pyc +0 -0
  186. simo/core/__pycache__/gateways.cpython-37.pyc +0 -0
  187. simo/core/__pycache__/models.cpython-37.pyc +0 -0
  188. simo/core/__pycache__/scripts.cpython-37.pyc +0 -0
  189. simo/core/__pycache__/serializers.cpython-37.pyc +0 -0
  190. simo/core/__pycache__/widgets.cpython-37.pyc +0 -0
  191. simo/core/db_backend/__pycache__/__init__.cpython-38.pyc +0 -0
  192. simo/core/db_backend/__pycache__/base.cpython-38.pyc +0 -0
  193. simo/core/management/commands/__pycache__/gateways_manager.cpython-38.pyc +0 -0
  194. simo/core/management/commands/__pycache__/run_gateway.cpython-38.pyc +0 -0
  195. simo/core/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  196. simo/core/migrations/__pycache__/0002_load_icons.cpython-38.pyc +0 -0
  197. simo/core/migrations/__pycache__/0003_create_default_zones_and_categories.cpython-38.pyc +0 -0
  198. simo/core/migrations/__pycache__/0004_create_generic.cpython-38.pyc +0 -0
  199. simo/core/migrations/__pycache__/0005_component_subcomponents.cpython-38.pyc +0 -0
  200. simo/core/migrations/__pycache__/0006_alter_component_subcomponents.cpython-38.pyc +0 -0
  201. simo/core/migrations/__pycache__/0007_component_change_init_to.cpython-38.pyc +0 -0
  202. simo/core/migrations/__pycache__/0008_alter_component_change_init_to.cpython-38.pyc +0 -0
  203. simo/core/migrations/__pycache__/0009_auto_20220707_1404.cpython-38.pyc +0 -0
  204. simo/core/migrations/__pycache__/0010_historyaggregate.cpython-38.pyc +0 -0
  205. simo/core/migrations/__pycache__/0011_component_last_change.cpython-38.pyc +0 -0
  206. simo/core/migrations/__pycache__/0012_instance.cpython-38.pyc +0 -0
  207. simo/core/migrations/__pycache__/0013_auto_20231003_0754.cpython-38.pyc +0 -0
  208. simo/core/migrations/__pycache__/0014_zone_instance.cpython-38.pyc +0 -0
  209. simo/core/migrations/__pycache__/0015_auto_20231004_1113.cpython-38.pyc +0 -0
  210. simo/core/migrations/__pycache__/0016_auto_20231004_1113.cpython-38.pyc +0 -0
  211. simo/core/migrations/__pycache__/0017_auto_20231004_1313.cpython-38.pyc +0 -0
  212. simo/core/migrations/__pycache__/0018_auto_20231005_0622.cpython-38.pyc +0 -0
  213. simo/core/migrations/__pycache__/0019_alter_gateway_type.cpython-38.pyc +0 -0
  214. simo/core/migrations/__pycache__/0020_component_meta.cpython-38.pyc +0 -0
  215. simo/core/migrations/__pycache__/0021_auto_20231020_1041.cpython-38.pyc +0 -0
  216. simo/core/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  217. simo/core/templatetags/__pycache__/__init__.cpython-38.pyc +0 -0
  218. simo/core/templatetags/__pycache__/components_list.cpython-38.pyc +0 -0
  219. simo/core/utils/__pycache__/__init__.cpython-38.pyc +0 -0
  220. simo/core/utils/__pycache__/admin.cpython-38.pyc +0 -0
  221. simo/core/utils/__pycache__/config_values.cpython-38.pyc +0 -0
  222. simo/core/utils/__pycache__/easing.cpython-38.pyc +0 -0
  223. simo/core/utils/__pycache__/form_fields.cpython-38.pyc +0 -0
  224. simo/core/utils/__pycache__/form_widgets.cpython-38.pyc +0 -0
  225. simo/core/utils/__pycache__/formsets.cpython-38.pyc +0 -0
  226. simo/core/utils/__pycache__/helpers.cpython-38.pyc +0 -0
  227. simo/core/utils/__pycache__/logs.cpython-38.pyc +0 -0
  228. simo/core/utils/__pycache__/mixins.cpython-38.pyc +0 -0
  229. simo/core/utils/__pycache__/model_helpers.cpython-38.pyc +0 -0
  230. simo/core/utils/__pycache__/relay.cpython-38.pyc +0 -0
  231. simo/core/utils/__pycache__/type_constants.cpython-38.pyc +0 -0
  232. simo/core/utils/__pycache__/validators.cpython-38.pyc +0 -0
  233. simo/fleet/tasks.py +0 -25
  234. simo/generic/__pycache__/__init__.cpython-37.pyc +0 -0
  235. simo/generic/__pycache__/__init__.cpython-38.pyc +0 -0
  236. simo/generic/__pycache__/app_widgets.cpython-38.pyc +0 -0
  237. simo/generic/__pycache__/base_types.cpython-38.pyc +0 -0
  238. simo/generic/__pycache__/controllers.cpython-37.pyc +0 -0
  239. simo/generic/__pycache__/controllers.cpython-38.pyc +0 -0
  240. simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
  241. simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
  242. simo/generic/__pycache__/models.cpython-38.pyc +0 -0
  243. simo/generic/__pycache__/routing.cpython-38.pyc +0 -0
  244. simo/generic/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  245. simo/generic/__pycache__/tasks.cpython-38.pyc +0 -0
  246. simo/generic/__pycache__/widgets.cpython-37.pyc +0 -0
  247. simo/generic/tasks.py +0 -41
  248. simo/multimedia/__pycache__/__init__.cpython-38.pyc +0 -0
  249. simo/multimedia/__pycache__/admin.cpython-38.pyc +0 -0
  250. simo/multimedia/__pycache__/api.cpython-38.pyc +0 -0
  251. simo/multimedia/__pycache__/app_widgets.cpython-38.pyc +0 -0
  252. simo/multimedia/__pycache__/base_types.cpython-38.pyc +0 -0
  253. simo/multimedia/__pycache__/controllers.cpython-38.pyc +0 -0
  254. simo/multimedia/__pycache__/forms.cpython-38.pyc +0 -0
  255. simo/multimedia/__pycache__/models.cpython-38.pyc +0 -0
  256. simo/multimedia/__pycache__/serializers.cpython-38.pyc +0 -0
  257. simo/multimedia/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  258. simo/multimedia/migrations/__pycache__/0002_sound_length.cpython-38.pyc +0 -0
  259. simo/multimedia/migrations/__pycache__/0003_alter_sound_length.cpython-38.pyc +0 -0
  260. simo/multimedia/migrations/__pycache__/0004_auto_20231023_1055.cpython-38.pyc +0 -0
  261. simo/multimedia/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  262. simo/notifications/__pycache__/__init__.cpython-38.pyc +0 -0
  263. simo/notifications/__pycache__/admin.cpython-38.pyc +0 -0
  264. simo/notifications/__pycache__/api.cpython-38.pyc +0 -0
  265. simo/notifications/__pycache__/models.cpython-38.pyc +0 -0
  266. simo/notifications/__pycache__/serializers.cpython-38.pyc +0 -0
  267. simo/notifications/__pycache__/utils.cpython-38.pyc +0 -0
  268. simo/notifications/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  269. simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.pyc +0 -0
  270. simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  271. simo/users/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  272. simo/users/migrations/__pycache__/0002_componentpermission.cpython-38.pyc +0 -0
  273. simo/users/migrations/__pycache__/0003_create_roles_and_system_user.cpython-38.pyc +0 -0
  274. simo/users/migrations/__pycache__/0004_user_secret_key.cpython-38.pyc +0 -0
  275. simo/users/migrations/__pycache__/0005_permissionsrole_instance.cpython-38.pyc +0 -0
  276. simo/users/migrations/__pycache__/0006_auto_20231003_0850.cpython-38.pyc +0 -0
  277. simo/users/migrations/__pycache__/0007_auto_20231003_1228.cpython-38.pyc +0 -0
  278. simo/users/migrations/__pycache__/0008_auto_20231003_1229.cpython-38.pyc +0 -0
  279. simo/users/migrations/__pycache__/0009_remove_user_role.cpython-38.pyc +0 -0
  280. simo/users/migrations/__pycache__/0010_auto_20231004_1313.cpython-38.pyc +0 -0
  281. simo/users/migrations/__pycache__/0011_auto_20231004_1313.cpython-38.pyc +0 -0
  282. simo/users/migrations/__pycache__/0012_alter_userinstancerole_unique_together.cpython-38.pyc +0 -0
  283. simo/users/migrations/__pycache__/0013_remove_user_roles.cpython-38.pyc +0 -0
  284. simo/users/migrations/__pycache__/0014_user_roles.cpython-38.pyc +0 -0
  285. simo/users/migrations/__pycache__/0015_remove_user_at_home.cpython-38.pyc +0 -0
  286. simo/users/migrations/__pycache__/0016_auto_20231005_1050.cpython-38.pyc +0 -0
  287. simo/users/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  288. {simo-1.7.19.dist-info → simo-2.0.0.dist-info}/LICENSE.md +0 -0
  289. {simo-1.7.19.dist-info → simo-2.0.0.dist-info}/top_level.txt +0 -0
simo/fleet/gateways.py CHANGED
@@ -1,7 +1,49 @@
1
- from simo.core.gateways import BaseGatewayHandler
1
+ import datetime
2
+ from django.utils import timezone
3
+ from simo.core.gateways import BaseObjectCommandsGatewayHandler
2
4
  from simo.core.forms import BaseGatewayForm
5
+ from simo.core.models import Gateway
6
+ from simo.core.events import GatewayObjectCommand
3
7
 
4
8
 
5
- class FleetGatewayHandler(BaseGatewayHandler):
9
+
10
+ class FleetGatewayHandler(BaseObjectCommandsGatewayHandler):
6
11
  name = "SIMO.io Fleet"
7
12
  config_form = BaseGatewayForm
13
+
14
+ periodic_tasks = (
15
+ ('look_for_updates', 600),
16
+ ('watch_colonels_connection', 30),
17
+ ('push_discoveries', 3),
18
+ )
19
+
20
+ def _on_mqtt_message(self, client, userdata, msg):
21
+ pass
22
+
23
+ def look_for_updates(self):
24
+ from .models import Colonel
25
+ for colonel in Colonel.objects.all():
26
+ colonel.check_for_upgrade()
27
+
28
+ def watch_colonels_connection(self):
29
+ from .models import Colonel
30
+ for colonel in Colonel.objects.filter(
31
+ socket_connected=True,
32
+ last_seen__lt=timezone.now() - datetime.timedelta(minutes=2)
33
+ ):
34
+ colonel.socket_connected = False
35
+ colonel.save()
36
+
37
+ def push_discoveries(self):
38
+ from .models import Colonel
39
+ for gw in Gateway.objects.filter(
40
+ type=self.uid,
41
+ discovery__has_key='start',
42
+ ).exclude(discovery__has_key='finished'):
43
+ colonel = Colonel.objects.get(
44
+ id=gw.discovery['init_data']['colonel']['val'][0]['pk']
45
+ )
46
+ print("Publish discover-ttlock command!")
47
+ GatewayObjectCommand(
48
+ gw, colonel, command='discover-ttlock',
49
+ ).publish()
simo/fleet/managers.py ADDED
@@ -0,0 +1,32 @@
1
+ from django.db import models
2
+ from simo.core.middleware import get_current_instance
3
+
4
+
5
+ class ColonelsManager(models.Manager):
6
+
7
+ def get_queryset(self):
8
+ qs = super().get_queryset()
9
+ instance = get_current_instance()
10
+ if instance:
11
+ qs = qs.filter(instance=instance)
12
+ return qs
13
+
14
+
15
+ class ColonelPinsManager(models.Manager):
16
+
17
+ def get_queryset(self):
18
+ qs = super().get_queryset()
19
+ instance = get_current_instance()
20
+ if instance:
21
+ qs = qs.filter(colonel__instance=instance)
22
+ return qs
23
+
24
+
25
+ class I2CInterfacesManager(models.Manager):
26
+
27
+ def get_queryset(self):
28
+ qs = super().get_queryset()
29
+ instance = get_current_instance()
30
+ if instance:
31
+ qs = qs.filter(colonel__instance=instance)
32
+ return qs
@@ -0,0 +1,27 @@
1
+ # Generated by Django 3.2.9 on 2024-01-30 13:34
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('fleet', '0024_colonel_pwm_frequency'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RemoveField(
14
+ model_name='colonel',
15
+ name='is_authorized',
16
+ ),
17
+ migrations.AlterField(
18
+ model_name='colonel',
19
+ name='pwm_frequency',
20
+ field=models.IntegerField(choices=[(0, '3kHz'), (1, '22kHz')], default=1, help_text='Affects Ample Wall dimmer PWM output (dimmer) frequency'),
21
+ ),
22
+ migrations.AlterField(
23
+ model_name='colonel',
24
+ name='type',
25
+ field=models.CharField(choices=[('ample-wall', 'Ample Wall')], default='ample-wall', max_length=20),
26
+ ),
27
+ ]
@@ -0,0 +1,64 @@
1
+ # Generated by Django 4.2.10 on 2024-03-06 08:00
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('contenttypes', '0002_remove_content_type_name'),
11
+ ('fleet', '0025_auto_20240130_1334'),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.RenameField(
16
+ model_name='i2cinterface',
17
+ old_name='scl_pin',
18
+ new_name='scl_pin_no',
19
+ ),
20
+ migrations.RenameField(
21
+ model_name='i2cinterface',
22
+ old_name='sda_pin',
23
+ new_name='sda_pin_no',
24
+ ),
25
+ migrations.CreateModel(
26
+ name='ColonelPin',
27
+ fields=[
28
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
29
+ ('no', models.PositiveIntegerField()),
30
+ ('input', models.BooleanField(db_index=True, default=False)),
31
+ ('output', models.BooleanField(db_index=True, default=False)),
32
+ ('capacitive', models.BooleanField(db_index=True, default=False)),
33
+ ('adc', models.BooleanField(default=False)),
34
+ ('native', models.BooleanField(db_index=True, default=True)),
35
+ ('default_pull', models.CharField(blank=True, choices=[('LOW', 'LOW'), ('HIGH', 'HIGH')], db_index=True, max_length=50, null=True)),
36
+ ('note', models.CharField(max_length=100)),
37
+ ('occupied_by_id', models.PositiveIntegerField(null=True)),
38
+ ('colonel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pins', to='fleet.colonel')),
39
+ ('occupied_by_content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, null=True, to='contenttypes.contenttype')),
40
+ ],
41
+ options={
42
+ 'indexes': [models.Index(fields=['occupied_by_content_type', 'occupied_by_id'], name='fleet_colon_occupie_f2bfd0_idx')],
43
+ 'unique_together': {('colonel', 'no')},
44
+ },
45
+ ),
46
+ migrations.AddField(
47
+ model_name='i2cinterface',
48
+ name='scl_pin',
49
+ field=models.ForeignKey(
50
+ to='fleet.ColonelPin', on_delete=django.db.models.CASCADE,
51
+ limit_choices_to={'native': True},
52
+ null=True, related_name='i2c_scl'
53
+ ),
54
+ ),
55
+ migrations.AddField(
56
+ model_name='i2cinterface',
57
+ name='sda_pin',
58
+ field=models.ForeignKey(
59
+ to='fleet.ColonelPin', on_delete=django.db.models.CASCADE,
60
+ limit_choices_to={'native': True},
61
+ null=True, related_name='i2c_sda'
62
+ ),
63
+ ),
64
+ ]
@@ -0,0 +1,170 @@
1
+ # Generated by Django 4.2.10 on 2024-03-06 08:02
2
+ import traceback
3
+ import json
4
+ import sys
5
+ from django.db import migrations
6
+
7
+
8
+ def forwards_func(apps, schema_editor):
9
+ from simo.fleet.utils import GPIO_PINS
10
+ from django.contrib.contenttypes.models import ContentType
11
+
12
+ Colonel = apps.get_model('fleet', "Colonel")
13
+ ColonelPin = apps.get_model("fleet", "ColonelPin")
14
+ Component = apps.get_model('core', "Component")
15
+
16
+ new_pins = {}
17
+
18
+ for colonel in Colonel.objects.all():
19
+ new_pins[colonel.id] = {}
20
+ for no, data in GPIO_PINS.get(colonel.type).items():
21
+ new_pins[colonel.id][no] = ColonelPin.objects.create(
22
+ colonel=colonel, no=no,
23
+ input=data.get('input'), output=data.get('output'),
24
+ capacitive=data.get('capacitive'), adc=data.get('adc'),
25
+ native=data.get('native'), note=data.get('note')
26
+ )
27
+
28
+ for i2c in colonel.i2c_interfaces.all():
29
+ ct = ContentType.objects.get_for_model(i2c)
30
+
31
+ scl_pin = new_pins[colonel.id][i2c.scl_pin_no]
32
+ scl_pin.occupied_by_content_type = ct
33
+ scl_pin.occupied_by_id = i2c.id
34
+ scl_pin.save()
35
+ i2c.scl_pin = scl_pin
36
+ i2c.scl_pin.save()
37
+
38
+ sda_pin = new_pins[colonel.id][i2c.sda_pin_no]
39
+ sda_pin.occupied_by_content_type = ct
40
+ sda_pin.occupied_by_id = i2c.id
41
+ sda_pin.save()
42
+
43
+ i2c.sda_pin = sda_pin
44
+ i2c.sda_pin.save()
45
+
46
+ print("NEW pins: ", new_pins)
47
+
48
+ for comp in Component.objects.filter(
49
+ controller_uid__startswith='simo.fleet.'
50
+ ):
51
+ ct = ContentType.objects.get_for_model(comp)
52
+ try:
53
+ colonel = Colonel.objects.get(id=comp.config['colonel'])
54
+ except Exception as e:
55
+ print(traceback.format_exc(), file=sys.stderr)
56
+ continue
57
+ if 'pin' in comp.config:
58
+ comp.config['pin_no'] = comp.config.pop('pin')
59
+
60
+ if comp.config['pin_no'] not in new_pins[colonel.id]:
61
+ print("BAD COMPONENT CONFIG!")
62
+ comp.delete()
63
+ continue
64
+
65
+ pin = new_pins[colonel.id][comp.config['pin_no']]
66
+ comp.config['pin'] = pin.pk
67
+ pin.occupied_by_content_type = ct
68
+ pin.occupied_by_id = comp.id
69
+ pin.save()
70
+ if 'power_pin' in comp.config:
71
+ comp.config['power_pin_no'] = comp.config.pop('power_pin')
72
+
73
+ if comp.config['power_pin_no'] not in new_pins[colonel.id]:
74
+ print("BAD COMPONENT CONFIG!")
75
+ comp.delete()
76
+ continue
77
+
78
+ pin = new_pins[colonel.id][comp.config['power_pin_no']]
79
+ comp.config['power_pin'] = pin.pk
80
+ pin.occupied_by_content_type = ct
81
+ pin.occupied_by_id = comp.id
82
+ pin.save()
83
+ if 'sensor_pin' in comp.config:
84
+ comp.config['sensor_pin_no'] = comp.config.pop('sensor_pin')
85
+
86
+ if comp.config['sensor_pin_no'] not in new_pins[colonel.id]:
87
+ print("BAD COMPONENT CONFIG!")
88
+ comp.delete()
89
+ continue
90
+
91
+ pin = new_pins[colonel.id][comp.config['sensor_pin_no']]
92
+ comp.config['sensor_pin'] = pin.pk
93
+ pin.occupied_by_content_type = ct
94
+ pin.occupied_by_id = comp.id
95
+ pin.save()
96
+ if 'output_pin' in comp.config:
97
+ comp.config['output_pin_no'] = comp.config.pop('output_pin')
98
+
99
+ if comp.config['output_pin_no'] not in new_pins[colonel.id]:
100
+ print("BAD COMPONENT CONFIG!")
101
+ comp.delete()
102
+ continue
103
+
104
+ pin = new_pins[colonel.id][comp.config['output_pin_no']]
105
+ comp.config['output_pin'] = pin.pk
106
+ pin.occupied_by_content_type = ct
107
+ pin.occupied_by_id = comp.id
108
+ pin.save()
109
+ if 'open_pin' in comp.config:
110
+ comp.config['open_pin_no'] = comp.config.pop('open_pin')
111
+
112
+ if comp.config['open_pin_no'] not in new_pins[colonel.id]:
113
+ print("BAD COMPONENT CONFIG!")
114
+ comp.delete()
115
+ continue
116
+
117
+ pin = new_pins[colonel.id][comp.config['open_pin_no']]
118
+ comp.config['open_pin'] = pin.pk
119
+ pin.occupied_by_content_type = ct
120
+ pin.occupied_by_id = comp.id
121
+ pin.save()
122
+ if 'close_pin' in comp.config:
123
+ comp.config['close_pin_no'] = comp.config.pop('close_pin')
124
+
125
+ if comp.config['close_pin_no'] not in new_pins[colonel.id]:
126
+ print("BAD COMPONENT CONFIG!")
127
+ comp.delete()
128
+ continue
129
+
130
+ pin = new_pins[colonel.id][comp.config['close_pin_no']]
131
+ comp.config['close_pin'] = pin.pk
132
+ pin.occupied_by_content_type = ct
133
+ pin.occupied_by_id = comp.id
134
+ pin.save()
135
+
136
+ if 'controls' in comp.config:
137
+ for i, control in enumerate(comp.config['controls']):
138
+ updated_controls = json.loads(json.dumps(control))
139
+ updated_controls['pin_no'] = control['pin']
140
+
141
+ if updated_controls['pin_no'] not in new_pins[colonel.id]:
142
+ print("BAD COMPONENT CONFIG!")
143
+ comp.delete()
144
+ continue
145
+
146
+ pin = new_pins[colonel.id][updated_controls['pin_no']]
147
+ updated_controls['pin'] = pin.pk
148
+
149
+ pin.occupied_by_content_type = ct
150
+ pin.occupied_by_id = comp.id
151
+ pin.save()
152
+
153
+ comp.config['controls'][i] = updated_controls
154
+
155
+ comp.save()
156
+
157
+
158
+ def reverse_func(apps, schema_editor):
159
+ pass
160
+
161
+
162
+ class Migration(migrations.Migration):
163
+
164
+ dependencies = [
165
+ ('fleet', '0026_rename_i2cinterface_scl_pin_and_more'),
166
+ ]
167
+
168
+ operations = [
169
+ migrations.RunPython(forwards_func, reverse_func, elidable=True),
170
+ ]
@@ -0,0 +1,21 @@
1
+ # Generated by Django 4.2.10 on 2024-03-06 08:13
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('fleet', '0027_auto_20240306_0802'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RemoveField(
14
+ model_name='i2cinterface',
15
+ name='scl_pin_no',
16
+ ),
17
+ migrations.RemoveField(
18
+ model_name='i2cinterface',
19
+ name='sda_pin_no',
20
+ ),
21
+ ]
@@ -0,0 +1,24 @@
1
+ # Generated by Django 4.2.10 on 2024-03-06 10:19
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('fleet', '0028_remove_i2cinterface_scl_pin_no_and_more'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name='i2cinterface',
16
+ name='scl_pin',
17
+ field=models.ForeignKey(limit_choices_to={'native': True, 'output': True}, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='i2c_scl', to='fleet.colonelpin'),
18
+ ),
19
+ migrations.AlterField(
20
+ model_name='i2cinterface',
21
+ name='sda_pin',
22
+ field=models.ForeignKey(limit_choices_to={'native': True, 'output': True}, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='i2c_sda', to='fleet.colonelpin'),
23
+ ),
24
+ ]
@@ -0,0 +1,24 @@
1
+ # Generated by Django 4.2.10 on 2024-03-06 11:30
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('fleet', '0029_alter_i2cinterface_scl_pin_and_more'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='colonelpin',
15
+ name='label',
16
+ field=models.CharField(db_index=True, default='', max_length=200),
17
+ preserve_default=False,
18
+ ),
19
+ migrations.AlterField(
20
+ model_name='colonel',
21
+ name='type',
22
+ field=models.CharField(choices=[('4-relays', '4 Relay'), ('ample-wall', 'Ample Wall')], default='ample-wall', max_length=20),
23
+ ),
24
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 4.2.10 on 2024-03-22 11:30
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('fleet', '0030_colonelpin_label_alter_colonel_type'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='colonel',
15
+ name='type',
16
+ field=models.CharField(choices=[('4-relays', '4 Relay'), ('ample-wall', 'Ample Wall'), ('game-changer', 'Game Changer')], default='ample-wall', max_length=20),
17
+ ),
18
+ ]