simo 2.7.6__py3-none-any.whl → 2.7.8__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.

@@ -33,6 +33,7 @@ class Script(ControllerBase, TimerMixin):
33
33
  admin_widget_template = 'admin/controller_widgets/script.html'
34
34
  default_config = {'autostart': True, 'autorestart': True}
35
35
  default_value = 'stopped'
36
+ masters_only = True
36
37
 
37
38
  def _validate_val(self, value, occasion=None):
38
39
  if occasion == BEFORE_SEND:
Binary file
simo/core/api_meta.py CHANGED
@@ -119,7 +119,8 @@ class SIMOAPIMetadata(SimpleMetadata):
119
119
  if form_field and hasattr(form_field, 'zoom'):
120
120
  field_info['zoom'] = form_field.zoom
121
121
 
122
- if not field_info.get('read_only') and hasattr(field, 'choices'):# and not hasattr(form_field, 'forward'):
122
+ if not field_info.get('read_only') and hasattr(field, 'choices')\
123
+ and not hasattr(form_field, 'forward'):
123
124
  field_info['choices'] = [
124
125
  {
125
126
  'value': choice_value,
@@ -217,8 +217,6 @@ class ComponentController(SIMOWebsocketConsumer):
217
217
  if not self.scope['user'].is_active:
218
218
  return self.close()
219
219
 
220
- introduce_instance(self.component.zone.instance)
221
-
222
220
  self._mqtt_client = mqtt.Client()
223
221
  self._mqtt_client.username_pw_set('root', settings.SECRET_KEY)
224
222
  self._mqtt_client.on_connect = self._on_mqtt_connect
@@ -236,7 +234,6 @@ class ComponentController(SIMOWebsocketConsumer):
236
234
  payload = json.loads(msg.payload)
237
235
  component = get_event_obj(payload, Component)
238
236
  if component == self.component:
239
- introduce_instance(self.component.zone.instance)
240
237
  # print("Object changed [%s], %s" % (str(component), payload))
241
238
  self.component = component
242
239
  if self.send_value:
@@ -253,7 +250,6 @@ class ComponentController(SIMOWebsocketConsumer):
253
250
 
254
251
  def receive(self, text_data=None, bytes_data=None, **kwargs):
255
252
  introduce(self.scope['user'])
256
- introduce_instance(self.component.zone.instance)
257
253
  json_data = json.loads(text_data)
258
254
  self.send_value = json_data.pop('send_value', False)
259
255
  for method, param in json_data.items():
simo/core/tasks.py CHANGED
@@ -436,7 +436,7 @@ def restart_postgresql():
436
436
  @celery_app.task
437
437
  def low_battery_notifications():
438
438
  from simo.notifications.utils import notify_users
439
- from simo.generic.scripting.helpers import be_or_not_to_be
439
+ from simo.automation.helpers import be_or_not_to_be
440
440
  for instance in Instance.objects.filter(is_active=True):
441
441
  timezone.activate(instance.timezone)
442
442
  hour = timezone.localtime().hour
Binary file
simo/fleet/forms.py CHANGED
@@ -782,8 +782,9 @@ class ColonelPWMOutputConfigForm(ColonelComponentForm):
782
782
  help_text="easeOutSine - offers most naturally looking effect."
783
783
  )
784
784
  on_value = forms.FloatField(
785
- required=True, initial=100,
786
- help_text="ON value when used with toggle switch"
785
+ required=False,
786
+ help_text="Static ON value used to turn the light on with physical controls. <br>"
787
+ "Leaving this field empty turns the light on to the last used value."
787
788
  )
788
789
 
789
790
  slaves = Select2ModelMultipleChoiceField(
@@ -0,0 +1,31 @@
1
+ # Generated by Django 4.2.10 on 2024-12-03 09:30
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ def forwards_func(apps, schema_editor):
7
+ Component = apps.get_model("core", "Component")
8
+
9
+ for comp in Component.objects.filter(
10
+ controller_uid='simo.fleet.controllers.PWMOutput'
11
+ ):
12
+ for ctrl in comp.config.get('controls'):
13
+ if ctrl.get('method') == 'momentary':
14
+ comp.config['on_value'] = None
15
+ comp.save()
16
+ break
17
+
18
+
19
+ def reverse_func(apps, schema_editor):
20
+ pass
21
+
22
+
23
+ class Migration(migrations.Migration):
24
+
25
+ dependencies = [
26
+ ('fleet', '0043_auto_20241203_0930'),
27
+ ]
28
+
29
+ operations = [
30
+ migrations.RunPython(forwards_func, reverse_func, elidable=True),
31
+ ]
@@ -13,7 +13,7 @@ import paho.mqtt.client as mqtt
13
13
  from channels.generic.websocket import AsyncWebsocketConsumer
14
14
  from asgiref.sync import sync_to_async
15
15
  from simo.core.utils.model_helpers import get_log_file_path
16
- from simo.core.middleware import introduce_instance, drop_current_instance
16
+ from simo.core.middleware import drop_current_instance
17
17
  from simo.core.utils.logs import capture_socket_errors
18
18
  from simo.core.events import GatewayObjectCommand, get_event_obj
19
19
  from simo.core.models import Gateway, Instance, Component
simo/fleet/views.py CHANGED
@@ -41,6 +41,12 @@ class PinsSelectAutocomplete(autocomplete.Select2QuerySetView):
41
41
  if not instance:
42
42
  return ColonelPin.objects.none()
43
43
 
44
+ if self.request.GET.get('value'):
45
+ return ColonelPin.objects.filter(
46
+ pk__in=self.request.GET['value'].split(','),
47
+ colonel__instance=instance
48
+ )
49
+
44
50
  try:
45
51
  colonel = Colonel.objects.get(
46
52
  pk=self.forwarded.get("colonel"), instance=instance
@@ -62,11 +68,7 @@ class PinsSelectAutocomplete(autocomplete.Select2QuerySetView):
62
68
  if self.forwarded.get('filters'):
63
69
  qs = qs.filter(**self.forwarded.get('filters'))
64
70
 
65
-
66
- if self.request.GET.get('value'):
67
- qs = qs.filter(pk__in=self.request.GET['value'].split(','))
68
- elif self.q:
69
- qs = search_queryset(qs, self.q, ('label', ))
71
+ qs = search_queryset(qs, self.q, ('label', ))
70
72
 
71
73
  return qs
72
74
 
@@ -1161,9 +1161,9 @@ class MainState(StateSelect):
1161
1161
  return False
1162
1162
 
1163
1163
 
1164
- def owner_phones_on_sleep(self):
1164
+ def owner_phones_on_sleep(self, all_phones=False):
1165
1165
  sleeping_phones_hour = self.component.config.get('sleeping_phones_hour')
1166
- if sleeping_phones_hour is not None:
1166
+ if sleeping_phones_hour is None:
1167
1167
  return False
1168
1168
 
1169
1169
  if not self.is_sleep_time():
@@ -1171,6 +1171,7 @@ class MainState(StateSelect):
1171
1171
 
1172
1172
  from simo.users.models import InstanceUser
1173
1173
 
1174
+ phones_on_charge = []
1174
1175
  for iuser in InstanceUser.objects.filter(
1175
1176
  is_active=True, role__is_owner=True,
1176
1177
  instance=self.component.zone.instance
@@ -1178,11 +1179,13 @@ class MainState(StateSelect):
1178
1179
  # skipping users that are not at home
1179
1180
  if not iuser.at_home:
1180
1181
  continue
1181
- if not iuser.phone_on_charge:
1182
- # at least one user's phone is not yet on charge
1183
- return False
1182
+ phones_on_charge.append(iuser.phone_on_charge)
1184
1183
 
1185
- return True
1184
+
1185
+ if all:
1186
+ return all(phones_on_charge)
1187
+ else:
1188
+ return any(phones_on_charge)
1186
1189
 
1187
1190
 
1188
1191
  # ----------- Dummy controllers -----------------------------
simo/generic/forms.py CHANGED
@@ -29,7 +29,8 @@ ACTION_METHODS = (
29
29
  class ControlForm(forms.Form):
30
30
  button = Select2ModelChoiceField(
31
31
  queryset=Component.objects.filter(base_type='button'),
32
- url='autocomplete-component'
32
+ url='autocomplete-component',
33
+ forward=(forward.Const(['button',], 'base_type'),)
33
34
  )
34
35
  prefix = 'controls'
35
36
 
simo/generic/gateways.py CHANGED
@@ -157,6 +157,7 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
157
157
  self.last_sensor_actions = {}
158
158
  self.sensors_on_watch = {}
159
159
  self.sleep_is_on = {}
160
+ self.last_set_state = None
160
161
 
161
162
 
162
163
 
@@ -176,7 +177,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
176
177
  for alarm_clock in Component.objects.filter(
177
178
  controller_uid=AlarmClock.uid
178
179
  ):
179
- introduce_instance(alarm_clock.zone.instance)
180
180
  tz = pytz.timezone(alarm_clock.zone.instance.timezone)
181
181
  timezone.activate(tz)
182
182
  alarm_clock.tick()
@@ -185,7 +185,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
185
185
  drop_current_instance()
186
186
  from .controllers import Watering
187
187
  for watering in Component.objects.filter(controller_uid=Watering.uid):
188
- introduce_instance(watering.zone.instance)
189
188
  tz = pytz.timezone(watering.zone.instance.timezone)
190
189
  timezone.activate(tz)
191
190
  if watering.value['status'] == 'running_program':
@@ -237,7 +236,6 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
237
236
  component = get_event_obj(payload, Component)
238
237
  if not component:
239
238
  return
240
- introduce_instance(component.zone.instance)
241
239
  try:
242
240
  if component.controller_uid == AlarmGroup.uid:
243
241
  self.control_alarm_group(component, payload.get('set_val'))
@@ -325,13 +323,32 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
325
323
  print(traceback.format_exc(), file=sys.stderr)
326
324
 
327
325
 
326
+ def set_get_day_evening_night_morning(self, state):
327
+ if state.value not in ('day', 'night', 'evening', 'morning'):
328
+ return
329
+ new_state = state.get_day_evening_night_morning()
330
+ if new_state == state.value:
331
+ self.last_set_state = state.value
332
+ return
333
+ if self.last_set_state:
334
+ # check if user maybe changed the state manually.
335
+ # If that's the case, we should not intervene
336
+ if new_state == 'day' and self.last_set_state not in ('night', 'morning'):
337
+ return
338
+ if new_state == 'evening' and self.last_set_state != 'day':
339
+ return
340
+ if new_state == 'night' and self.last_set_state != 'evening':
341
+ return
342
+ if new_state == 'morning' and self.last_set_state != 'night':
343
+ return
344
+
345
+ print(f"New main state of {state.zone.instance} - {new_state}")
346
+ state.send(new_state)
347
+
348
+
328
349
  def watch_main_state(self, state):
329
350
  i_id = state.zone.instance.id
330
- if state.value in ('day', 'night', 'evening', 'morning'):
331
- new_state = state.get_day_evening_night_morning()
332
- if new_state != state.value:
333
- print(f"New main state of {state.zone.instance} - {new_state}")
334
- state.send(new_state)
351
+ self.set_get_day_evening_night_morning(state)
335
352
 
336
353
  if state.config.get('away_on_no_action'):
337
354
  if i_id not in self.last_sensor_actions:
@@ -362,18 +379,19 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
362
379
  state.send(new_state)
363
380
 
364
381
  if state.config.get('sleeping_phones_hour') is not None:
365
- sleep_time = state.owner_phones_on_sleep()
366
- if sleep_time and state.value != 'sleep':
367
- print(f"New main state of {state.zone.instance} - sleep")
368
- state.send('sleep')
369
- elif state.value == 'sleep':
370
- try:
371
- new_state = state.get_day_evening_night_morning()
372
- except:
373
- new_state = 'day'
374
- print(f"New main state of "
375
- f"{state.zone.instance} - {new_state}")
376
- state.send(new_state)
382
+ if state.value != 'sleep':
383
+ if state.owner_phones_on_sleep(True):
384
+ print(f"New main state of {state.zone.instance} - sleep")
385
+ state.send('sleep')
386
+ else:
387
+ if not state.owner_phones_on_sleep(False):
388
+ try:
389
+ new_state = state.get_day_evening_night_morning()
390
+ except:
391
+ new_state = 'day'
392
+ print(f"New main state of "
393
+ f"{state.zone.instance} - {new_state}")
394
+ state.send(new_state)
377
395
 
378
396
 
379
397
  def watch_main_states(self):
@@ -66,9 +66,9 @@ class BasePlayer(Switch):
66
66
 
67
67
  def toggle(self):
68
68
  if self.component.value == 'playing':
69
- self.turn_off()
69
+ self.pause()
70
70
  else:
71
- self.turn_on()
71
+ self.play()
72
72
 
73
73
 
74
74
  class BaseAudioPlayer(BasePlayer):
@@ -1,4 +1,6 @@
1
- from simo.core.middleware import get_current_instance
1
+ from simo.core.middleware import (
2
+ get_current_instance, drop_current_instance, introduce_instance
3
+ )
2
4
  from .models import Notification, UserNotification
3
5
 
4
6
 
@@ -12,6 +14,7 @@ def notify_users(severity, title, body=None, component=None, instance_users=None
12
14
  :param instance_users: List of instance users to receive this notification. All active instance users will receive the message if not specified.
13
15
  :return:
14
16
  '''
17
+ current_instance = get_current_instance()
15
18
  if not instance:
16
19
  if component:
17
20
  instance = component.zone.instance
@@ -19,6 +22,7 @@ def notify_users(severity, title, body=None, component=None, instance_users=None
19
22
  instance = get_current_instance()
20
23
  if not instance:
21
24
  return
25
+ drop_current_instance()
22
26
  if component and component.zone.instance != instance:
23
27
  # something is completely wrong!
24
28
  return
@@ -45,3 +49,6 @@ def notify_users(severity, title, body=None, component=None, instance_users=None
45
49
  user=iuser.user, notification=notification,
46
50
  )
47
51
  notification.dispatch()
52
+ if current_instance:
53
+ introduce_instance(current_instance)
54
+
simo/users/tasks.py CHANGED
@@ -9,7 +9,6 @@ def clear_device_report_logs():
9
9
  from simo.core.models import Instance
10
10
  from .models import UserDeviceReportLog
11
11
  for instance in Instance.objects.all():
12
- introduce_instance(instance)
13
12
  # keeping at least 1 hour of logs so that we could evaluate
14
13
  # user's current location using Kalman filter
15
14
  UserDeviceReportLog.objects.filter(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.7.6
3
+ Version: 2.7.8
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
@@ -13,7 +13,7 @@ simo/__pycache__/urls.cpython-38.pyc,sha256=u0x6EqT8S1YfDOSPgbI8Kf-RDlveY9OV-EDX
13
13
  simo/__pycache__/wsgi.cpython-38.pyc,sha256=TpRxO7VM_ql31hbKphVdanydC5RI1nHB4l0QA2pdWxo,322
14
14
  simo/automation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  simo/automation/app_widgets.py,sha256=gaqImMZjuMHm7nIb9a4D-Y3qipz_WhSPAHXcwGx4Uzs,199
16
- simo/automation/controllers.py,sha256=kST668ljPAxp4HSWgPJuBDeTDKeQTr83fZxkZmLVRLg,11468
16
+ simo/automation/controllers.py,sha256=Ow8xG9hkdyMRZbrNPX5uZloYM9jZqa9mgCh4k6FeoJw,11492
17
17
  simo/automation/forms.py,sha256=UWnkxw8pILPK0smRPTo4SLgsZl78zOySx7JIc30Bgtk,10228
18
18
  simo/automation/gateways.py,sha256=nWiWaDcNFpOumtTEE1xbhuYLt4Qvs8K0-zVEupdRPRU,14563
19
19
  simo/automation/helpers.py,sha256=iP-fxxB8HsFQy3k2CjFubu86aMqvWgmh-p24DiyOrek,4330
@@ -22,7 +22,7 @@ simo/automation/serializers.py,sha256=PjyFrjdPK1mBsgbNhyqMi9SWzcymqTa742ipy0LhAN
22
22
  simo/automation/state.py,sha256=aZZvNBae7unnux_zGHCIWCV2z47hVJc-DIL72Hqfkeo,600
23
23
  simo/automation/__pycache__/__init__.cpython-38.pyc,sha256=YmP0xAD-mxpQHgdTZeC64sXChA8TriMZD1jckNYi3xg,164
24
24
  simo/automation/__pycache__/app_widgets.cpython-38.pyc,sha256=7DfUA9V_1MiwrOe_ta-ts8dYY8xXb9UMg2_9A3XoRcs,523
25
- simo/automation/__pycache__/controllers.cpython-38.pyc,sha256=jOeue93TpWhmbmbrvL8ORwGX-1aYsjaqHzCo0Zwt4WU,8380
25
+ simo/automation/__pycache__/controllers.cpython-38.pyc,sha256=CL-0Tq9B4-E36fYfWT1XEBTq1dkq1W8003f6MrBnQU0,8391
26
26
  simo/automation/__pycache__/forms.cpython-38.pyc,sha256=cpA5hA2Iz3JsPC0Dq01ki1I7S9c5DKRcXveHApI1dJo,7772
27
27
  simo/automation/__pycache__/gateways.cpython-38.pyc,sha256=K8y3DNQFfcEQiLTgHl5p0Uk58R5QCuqFCluvbQ6I_9g,10652
28
28
  simo/automation/__pycache__/helpers.cpython-38.pyc,sha256=4VSSarOFnUk_KExWwvDlx5dEhv8aHUCHMZDtGG--pUY,3627
@@ -63,7 +63,7 @@ simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
63
63
  simo/core/admin.py,sha256=j07Dy3IsW7SRRsAJ2XXGzE0MTxmfY87CEEbT22kLlS4,18550
64
64
  simo/core/api.py,sha256=D5FBWvhYpQeM9wVfapzRvBi_ypOtXBt9tmmCaUxpGjI,29992
65
65
  simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
66
- simo/core/api_meta.py,sha256=dBIpQNDSMO4yum4Xa6acHkWwEDItooZC4QLV_EZfwIc,5221
66
+ simo/core/api_meta.py,sha256=DuX6BmUC2uY_mXb8NC_UMq6T3FcMSQoD2Rv0Pp0NdQo,5228
67
67
  simo/core/app_widgets.py,sha256=VxZzapuc-a29wBH7JzpvNF2SK1ECrgNUySId5ke1ffc,2509
68
68
  simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
69
69
  simo/core/auto_urls.py,sha256=FBDclIeRp5UVWomIUbRzUgY-AoMk-r2qC2htlwKD4Lo,1106
@@ -85,9 +85,9 @@ simo/core/permissions.py,sha256=2YNRot2qoHjHKWPGOpO4PBseecctPbTlUQpepnFkCRs,3027
85
85
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
86
86
  simo/core/serializers.py,sha256=pa4F5fSvIxgGJWBEcXdzpmemRWl6QbUoUDMqQ_RdA2o,22514
87
87
  simo/core/signal_receivers.py,sha256=y8p0BG3PzhHI3w2WXS8QXyxXc7YKUE_mmO2-QElvrP4,6276
88
- simo/core/socket_consumers.py,sha256=trRZvBGTJ7xIbfdmVvn7zoiWp_qssSkMZykDrI5YQyE,9783
88
+ simo/core/socket_consumers.py,sha256=Es_NmacQGZjsncBXDTEXR2yZbRs7mf2FKOBJjbZRGac,9607
89
89
  simo/core/storage.py,sha256=_5igjaoWZAiExGWFEJMElxUw55DzJG1jqFty33xe8BE,342
90
- simo/core/tasks.py,sha256=ridh-22XWY3v9DCWrGYaXrOM0w4XOebkjkkZT9NtnP4,16911
90
+ simo/core/tasks.py,sha256=LMTkZQDGFus5L2Q8AGzYegjpnZKf9Klgo3V9BT5L2ng,16904
91
91
  simo/core/todos.py,sha256=eYVXfLGiapkxKK57XuviSNe3WsUYyIWZ0hgQJk7ThKo,665
92
92
  simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
93
93
  simo/core/views.py,sha256=yx9I0byeVUa-LAOnklpWIYwpNNOf5m9fyjKBvj4YCh4,2475
@@ -96,7 +96,7 @@ simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEt
96
96
  simo/core/__pycache__/admin.cpython-38.pyc,sha256=oDG9Kem_VbiRDB6ednmvPS9asBDb3iki7OyLzzNRYCQ,14155
97
97
  simo/core/__pycache__/api.cpython-38.pyc,sha256=JXCs5U9MPyZTdO4_j-ytpH1_Fo9-w36zs1eHXZ-czwo,22925
98
98
  simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=mi3mu5qEKio_PvfQEvr3Q6AhdPLAHxzxAxrMbAz_pKU,1712
99
- simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=0IkX6_e09XSsHuA4NDhmyXtegiXo0bpiAeJvEl8LFoc,3837
99
+ simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=km2IBFS1ot6CTYuIAnCwQToQLVQqRasAvfQ6UC8-1ts,3853
100
100
  simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=oN657XMMZ6GYN9nblv7fX3kdnTEzSP9XV6PXM6Z0wl4,4358
101
101
  simo/core/__pycache__/apps.cpython-38.pyc,sha256=JL0BEqgXcSQvMlcK48PBpPfyDEkPMdO1Y0teqMRGirs,713
102
102
  simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=ib_ns5Ko8ybfrdJJWYVV1jevihxOFs39aBF4bez6Lzs,874
@@ -120,7 +120,7 @@ simo/core/__pycache__/serializers.cpython-38.pyc,sha256=xegjaPbTp71RK9pfle_vgbHi
120
120
  simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=v-qSKC9KX--aw9-vSNX8z8HXNFr0yOII0Aw8JxrYM0U,4920
121
121
  simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=KqbO1cOewodVPcy0-htVefyUjCuELKV0o7fOfYqfgPc,8490
122
122
  simo/core/__pycache__/storage.cpython-38.pyc,sha256=9R1Xu0FJDflfRXUPsqEgt0SpwiP7FGk7HaR8s8XRyI8,721
123
- simo/core/__pycache__/tasks.cpython-38.pyc,sha256=GFIC8IsQ_bK4rgNRl_oGbMCQHhbcgGS7dx-rjPcLy08,11220
123
+ simo/core/__pycache__/tasks.cpython-38.pyc,sha256=-J2is-l5XsfhamreN2TPQDTK-Jw6XGYL81bcVfjXsU8,11213
124
124
  simo/core/__pycache__/todos.cpython-38.pyc,sha256=lOqGZ58siHM3isoJV4r7sg8igrfE9fFd-jSfeBa0AQI,253
125
125
  simo/core/__pycache__/views.cpython-38.pyc,sha256=IRjbX3MwKkAb10sMIJ3esKZH8W-tHwnuzm-mLIT_NWc,2584
126
126
  simo/core/__pycache__/widgets.cpython-38.pyc,sha256=sR0ZeHCHrhnNDBJuRrxp3zUsfBp0xrtF0xrK2TkQv1o,3520
@@ -10259,16 +10259,16 @@ simo/fleet/auto_urls.py,sha256=vrfrooPyY4pDuQjya-eLxCgZldfhwbEeEiXa7diO_CY,847
10259
10259
  simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
10260
10260
  simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
10261
10261
  simo/fleet/controllers.py,sha256=PezfOT-1N_UONSsbyTXEIyGO6Po57KdEBRv4yzk_sw0,28605
10262
- simo/fleet/forms.py,sha256=cA0iqixII5k9LUqbMPWzTyvfu9SNH23ChH_Mt6C6Ggk,66913
10262
+ simo/fleet/forms.py,sha256=CHSmIz9bsdyukyTQnU5t554ggriWJjjwoBQe68l4FKI,67022
10263
10263
  simo/fleet/gateways.py,sha256=C7dyapWDlJ5erYPNLkSoH50I8kj0lIXicSno0_CrdXc,5783
10264
10264
  simo/fleet/managers.py,sha256=ZNeHFSkF5kzsl9E1DCBevOW6kXJlD6kw0LU4B-JMOG8,828
10265
10265
  simo/fleet/models.py,sha256=zPplx_v64nfKBmb-nCb74aCVtEeY3m3SjEy-VhbnydU,17511
10266
10266
  simo/fleet/routing.py,sha256=cofGsVWXMfPDwsJ6HM88xxtRxHwERhJ48Xyxc8mxg5o,149
10267
10267
  simo/fleet/serializers.py,sha256=PQnjp7LaEpMts-om2OPV5XOU9ut6KFWiePPDCXK0M98,2679
10268
- simo/fleet/socket_consumers.py,sha256=4hVSvFNq9Hi44R7JmaujFoEtgmH5YBST2cFYtIiMDRA,18840
10268
+ simo/fleet/socket_consumers.py,sha256=3Ayry0PJgP5K2V7c-4a11QFOxfM8lOSXfIVhaBB8wTM,18820
10269
10269
  simo/fleet/tasks.py,sha256=NX_opj-rbkK9eeQMeRNwHj_ZJ0LC4rYOZovMg9_r0kA,904
10270
10270
  simo/fleet/utils.py,sha256=wNJvURzLP3-aho3D3rfg07N9kWCaMIw5gOsmeeO9Nlg,4740
10271
- simo/fleet/views.py,sha256=ao1e5ZAkQDZ2AuGiPYTbfgxgH_9efRwnTkk-ZjwnpPc,5122
10271
+ simo/fleet/views.py,sha256=3F8im6BsSOaK3KEuBNESE4sDbS_dWHYaOdhTR4cCLjE,5189
10272
10272
  simo/fleet/__pycache__/__init__.cpython-38.pyc,sha256=pIZE7EL6-cuJ3pQtaSwjKLrKLsTYelp1k9sRhXKLh6s,159
10273
10273
  simo/fleet/__pycache__/admin.cpython-38.pyc,sha256=iweeu5AkaggBhQntP6-VF_eEodkNc6E7zKy0VjfwC2o,6652
10274
10274
  simo/fleet/__pycache__/api.cpython-38.pyc,sha256=rZ1mkfkaMBEXhi9sw_jTKdk2CPJhBNxoImtjQ3Rf1VY,4016
@@ -10276,7 +10276,7 @@ simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=jHsvfwAumiBusr91QK1-qC-nm
10276
10276
  simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
10277
10277
  simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
10278
10278
  simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=vH7mK1K4JBcLU9eKtqTJwbgB0SFMJ-s7WvO0qOsWjrg,24739
10279
- simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=lNb_jc66-aO1NkYIJs4TWOX7uS8H2a8oCP-HCLJZoNY,45169
10279
+ simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=NkchZIvx79WswYepd8IgWwI7Pu3hd4sPkhsWt79YOII,45304
10280
10280
  simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=MIpXuGWitGNdsxJ99fWvMXJ6sVE96ac7iR4K4aM4Sds,5148
10281
10281
  simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=Vmm23zoQnS3-uS5_WJt2n3wtjhLiEhLWaYxXJCU6Gts,1339
10282
10282
  simo/fleet/__pycache__/models.cpython-38.pyc,sha256=AXk1Q_nnHDXirHYgM3EW5pLsrR2CaPWk4EuvGCuDUpI,14131
@@ -10329,6 +10329,7 @@ simo/fleet/migrations/0040_alter_colonel_pwm_frequency.py,sha256=AiiYeLXEmBAFj1O
10329
10329
  simo/fleet/migrations/0041_alter_colonel_instance_and_more.py,sha256=r3PzZERt4kM0ul_TFl-i7qS7n0ht0G8jS83nucMxZfQ,1181
10330
10330
  simo/fleet/migrations/0042_auto_20241120_1028.py,sha256=nXyOXyTqhYfR2IDpIX0E3oIhKI7ShI7TGZ0Uf1CzR1U,715
10331
10331
  simo/fleet/migrations/0043_auto_20241203_0930.py,sha256=wYfYEBurHB5pGOgL6M-z9EoOZGhW9glhT3BpNiMDoH4,651
10332
+ simo/fleet/migrations/0044_auto_20241210_0707.py,sha256=HJDLZWX84rlCN5vO3VGr8-TQLFIDT3pWmWwc-2BG67Q,746
10332
10333
  simo/fleet/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10333
10334
  simo/fleet/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=9kc1UyMEYkRNVnZ7iwZbiW1t3qWXROvWrI2G1BdzIaA,1250
10334
10335
  simo/fleet/migrations/__pycache__/0002_auto_20220422_0743.cpython-38.pyc,sha256=8oxhGb7rL8QYKlBLU3pOYcd8aHeQWDB9I8awkK04mXg,841
@@ -10379,18 +10380,18 @@ simo/fleet/templates/fleet/controllers_info/ENS160AirQualitySensor.md,sha256=3LS
10379
10380
  simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10380
10381
  simo/generic/app_widgets.py,sha256=y8W3jR76Hh26O9pPQyg2SophMbYIOtAWD33MPKbB8Mg,856
10381
10382
  simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
10382
- simo/generic/controllers.py,sha256=ksn_8LvBn3RM-OegI32h4fp7te_Koq-rQy7DtHCiOI4,46063
10383
- simo/generic/forms.py,sha256=kQL8NdK_9-PxFcoPK6fMMCmtroY2Nbx_MqERgBoRg6g,22933
10384
- simo/generic/gateways.py,sha256=om0KdIPOQVyNbxUQuD7Angf4o0Jg8OblMFsWjOfRGXw,15210
10383
+ simo/generic/controllers.py,sha256=Y-juxa7OSz24XYysFe785DCHPlbGeEurGTkK471S3iI,46123
10384
+ simo/generic/forms.py,sha256=ikSwn6hg6m4XoaWyZNydw9e5aoFRHxbeM8tWsyYlen4,22993
10385
+ simo/generic/gateways.py,sha256=SBQPlcU2oNCWzRQ1H1XWQ11O2E3zWDNImXlWNDzKg-Y,15865
10385
10386
  simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
10386
10387
  simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
10387
10388
  simo/generic/socket_consumers.py,sha256=K2OjphIhKJH48BvfFfoCOyCQZ1NmXb_phs6y1IP-qaQ,1757
10388
10389
  simo/generic/__pycache__/__init__.cpython-38.pyc,sha256=mLu54WS9KIl-pHwVCBKpsDFIlOqml--JsOVzAUHg6cU,161
10389
10390
  simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=D9b13pbMlirgHmjDnQhfLIDGSVINoSouHb4SWOeCRrs,1642
10390
10391
  simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
10391
- simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=ccYZ7AknZbPK_fTHO5lUO-steSeZeudQIynMkh1Gm7M,30116
10392
- simo/generic/__pycache__/forms.cpython-38.pyc,sha256=2rmamwhD9wdrW2zO73oAAbeAMZiJqGKB1lizwTRuGZs,17258
10393
- simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=QtQhcRm_UNBEyLyGfb_bxmS6JZ9S0aeOhEVzAAAWXds,11356
10392
+ simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=tRYKQsZuWBBKXbfd32BGz3AsV4Jz4y-KsEkumoRP_T4,30195
10393
+ simo/generic/__pycache__/forms.cpython-38.pyc,sha256=at1PQBgwr11YzSiTP92v3nyz1G59oKhu7vTa0sK0zUE,17289
10394
+ simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=7Y190Iylo2X2AykcKrKzVllfDmW02B5suRMlcS0y6KQ,11712
10394
10395
  simo/generic/__pycache__/models.cpython-38.pyc,sha256=MZpum7syAFxuulf47K7gtUlJJ7xRD-IBUBAwUM1ZRnw,5825
10395
10396
  simo/generic/__pycache__/routing.cpython-38.pyc,sha256=xtxTUTBTdivzFyA5Wh7k-hUj1WDO_FiRq6HYXdbr9Ks,382
10396
10397
  simo/generic/__pycache__/socket_consumers.cpython-38.pyc,sha256=qJO5kvQLWhsQDOr1AtAtsAybuRWioxSkQei3Pc7rdP0,1737
@@ -10430,7 +10431,7 @@ simo/multimedia/admin.py,sha256=GgXiKTLfi3omjBurU-bKgneJRK-tAeiR8o2jo3zD7zs,1002
10430
10431
  simo/multimedia/api.py,sha256=mZ5BTggWdc_kL8P70JGC3rTCiZKPnxWYoyNcAQkFnX4,285
10431
10432
  simo/multimedia/app_widgets.py,sha256=g_IPx5bNmIS6JbaXXDCzYZYV2KVKAiYvWjH4oI30lWM,331
10432
10433
  simo/multimedia/base_types.py,sha256=dAP7_uh_b3A03yXBJZyQdRFucKIro4_RkIZ5yOaWXVE,151
10433
- simo/multimedia/controllers.py,sha256=lwBWzy_hFFHV7dZQgNwHNAWogOnfLzNwkZ2S38_vu48,1999
10434
+ simo/multimedia/controllers.py,sha256=kaoi-nv9b6O87k1eijgk-6ub0-E2KdTN1lL99OPGpo8,1993
10434
10435
  simo/multimedia/forms.py,sha256=oMCVUXRNiESrY3w_uBLRRgjMjx8BrmNeVglzorA9QtY,239
10435
10436
  simo/multimedia/models.py,sha256=5aWGLWDdCkekGAOGZIdanvX1l6ULnhgJN4JAvDZT4nQ,734
10436
10437
  simo/multimedia/requirements.txt,sha256=QeIhjf1RfNGCYn_WZm3VuinPI2wK31WEJPbCxRWxssY,28
@@ -10440,7 +10441,7 @@ simo/multimedia/__pycache__/admin.cpython-38.pyc,sha256=kIVA9sfSgBYNMC64CaSDXLl4
10440
10441
  simo/multimedia/__pycache__/api.cpython-38.pyc,sha256=lFGEB74vgyEM98B42wwcN9WvH8FAupIiSY0SwEBd5Dw,605
10441
10442
  simo/multimedia/__pycache__/app_widgets.cpython-38.pyc,sha256=6pr3fz21tQ5ReC9SJ8VzheUZ0hpxDIClB0SA8YCwcPk,730
10442
10443
  simo/multimedia/__pycache__/base_types.cpython-38.pyc,sha256=c4nmNziLs4RB3MAnxltn3W5XNW6PM5_vK_mm3Yvy42Y,324
10443
- simo/multimedia/__pycache__/controllers.cpython-38.pyc,sha256=aDFKmyduOm4hMf-CqVhQKQ8r8ERBNFkVgsOGg8J6DOg,3473
10444
+ simo/multimedia/__pycache__/controllers.cpython-38.pyc,sha256=C9stIL6FgGiFOxMy76QemVvc7wshVEsPxfa0wCtG4PQ,3464
10444
10445
  simo/multimedia/__pycache__/forms.cpython-38.pyc,sha256=99h7Yj2jim3QOrqej00wiPufrCF3F--RoYvwa6lzhPI,697
10445
10446
  simo/multimedia/__pycache__/models.cpython-38.pyc,sha256=2LViRCOULb9g_k3wZvrODVIuj-iFgfwoWXyg-mAx8Ys,1195
10446
10447
  simo/multimedia/__pycache__/serializers.cpython-38.pyc,sha256=n86txYSrkmN0Xlrr8dMwKSY7rEzMc1iovepCZi_Fcw8,886
@@ -10459,7 +10460,7 @@ simo/notifications/admin.py,sha256=WQbN_bd2KRxVjbOajeworNrV9QlDNSadQT58La0Nn2M,1
10459
10460
  simo/notifications/api.py,sha256=QrfFn5kBU0vlqi8X368w1-0iTmDGu_hmMxLW2R0OTTg,1765
10460
10461
  simo/notifications/models.py,sha256=QGDLGAi5gk8OTcvd7ho5WNdctDymWGmGF1ZqN4-G_ZA,2443
10461
10462
  simo/notifications/serializers.py,sha256=altDEAPWwOhxRcEzE9-34jL8EFpyf3vPoEdAPoVLfGc,523
10462
- simo/notifications/utils.py,sha256=uBl-Y7WGu00iaGM5rrdogcq0OMRVtyVfJF39-mdB3_k,1853
10463
+ simo/notifications/utils.py,sha256=RnvwKFGZ6e34ishUWHfZq4m3H6XFxFbRF4NQCi2LT-E,2049
10463
10464
  simo/notifications/__pycache__/__init__.cpython-38.pyc,sha256=YvucUfu98XFvEEg1LYFMlOZJpo_jSGxTVrM-ylAFLOg,167
10464
10465
  simo/notifications/__pycache__/admin.cpython-38.pyc,sha256=MScNrtVM1wavefsPfxy0A7LVyXKcbvEkLH9GJkgNOl8,1945
10465
10466
  simo/notifications/__pycache__/api.cpython-38.pyc,sha256=eQmCHwTnr4zQ3ZY_SKZVCryiSEnzmyIjHQM13pZ5LT0,2071
@@ -10488,7 +10489,7 @@ simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
10488
10489
  simo/users/serializers.py,sha256=zzw1KONTnaTNBaU0r4rNVxJ827KzD6Z5LuQt27ZsQ98,2516
10489
10490
  simo/users/sso_urls.py,sha256=gQOaPvGMYFD0NCVSwyoWO-mTEHe5j9sbzV_RK7kdvp0,251
10490
10491
  simo/users/sso_views.py,sha256=5J0D4qUFQDvd-Fcqx_xLJWLJgPdqtVD5DDiPJyPsT2Q,4336
10491
- simo/users/tasks.py,sha256=M8MDQ1oR6WXWoOP5SQYui-CsCIV0jUmfI84TbRgGKo8,1199
10492
+ simo/users/tasks.py,sha256=FhbczWFHRFI6To4xqkx4gUX4p0vCwwTT297GWBPAoIg,1162
10492
10493
  simo/users/utils.py,sha256=-Lu7C_sz8JJauLaIwgEa6umArqzNL7JJTY-ZcuF4irA,2004
10493
10494
  simo/users/views.py,sha256=CVhNczY7FjtpFxzQSwRZj39HIBTHsA_2wtkTFUfzKRA,4134
10494
10495
  simo/users/__pycache__/__init__.cpython-38.pyc,sha256=VFoDJE_SKKaPqqYaaBYd1Ndb1hjakkTo_u0EG_XJ1GM,211
@@ -10606,9 +10607,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10606
10607
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10607
10608
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10608
10609
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10609
- simo-2.7.6.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10610
- simo-2.7.6.dist-info/METADATA,sha256=84AzLEVR7S7jKZ7N1R77sFabXq9v8phZ4y_eopUzqCI,1952
10611
- simo-2.7.6.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10612
- simo-2.7.6.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10613
- simo-2.7.6.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10614
- simo-2.7.6.dist-info/RECORD,,
10610
+ simo-2.7.8.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10611
+ simo-2.7.8.dist-info/METADATA,sha256=N8l_soYBEp5Ohuwp2gwQwgd2ScThohJQUa7cfGSkVVk,1952
10612
+ simo-2.7.8.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10613
+ simo-2.7.8.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10614
+ simo-2.7.8.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10615
+ simo-2.7.8.dist-info/RECORD,,
File without changes