simo 2.5.27__py3-none-any.whl → 2.5.30__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 (35) hide show
  1. simo/core/__pycache__/context.cpython-38.pyc +0 -0
  2. simo/core/__pycache__/events.cpython-38.pyc +0 -0
  3. simo/core/__pycache__/middleware.cpython-38.pyc +0 -0
  4. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  6. simo/core/context.py +1 -1
  7. simo/core/events.py +3 -2
  8. simo/core/management/update.py +3 -2
  9. simo/core/migrations/0044_alter_gateway_type.py +18 -0
  10. simo/core/migrations/__pycache__/0044_alter_gateway_type.cpython-38.pyc +0 -0
  11. simo/core/signal_receivers.py +0 -3
  12. simo/core/tasks.py +1 -1
  13. simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
  14. simo/fleet/__pycache__/models.cpython-38.pyc +0 -0
  15. simo/fleet/__pycache__/socket_consumers.cpython-38.pyc +0 -0
  16. simo/generic/__pycache__/forms.cpython-38.pyc +0 -0
  17. simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
  18. simo/generic/gateways.py +65 -53
  19. simo/users/__pycache__/admin.cpython-38.pyc +0 -0
  20. simo/users/__pycache__/api.cpython-38.pyc +0 -0
  21. simo/users/__pycache__/auth_backends.cpython-38.pyc +0 -0
  22. simo/users/__pycache__/models.cpython-38.pyc +0 -0
  23. simo/users/admin.py +2 -2
  24. simo/users/api.py +16 -5
  25. simo/users/migrations/0038_userdevicereportlog_at_home_and_more.py +23 -0
  26. simo/users/migrations/0039_auto_20241117_1039.py +45 -0
  27. simo/users/migrations/__pycache__/0038_userdevicereportlog_at_home_and_more.cpython-38.pyc +0 -0
  28. simo/users/migrations/__pycache__/0039_auto_20241117_1039.cpython-38.pyc +0 -0
  29. simo/users/models.py +5 -2
  30. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/METADATA +2 -1
  31. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/RECORD +35 -29
  32. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/LICENSE.md +0 -0
  33. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/WHEEL +0 -0
  34. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/entry_points.txt +0 -0
  35. {simo-2.5.27.dist-info → simo-2.5.30.dist-info}/top_level.txt +0 -0
Binary file
Binary file
simo/core/context.py CHANGED
@@ -15,7 +15,7 @@ def additional_templates_context(request):
15
15
  else:
16
16
  instances = request.user.instances
17
17
  try:
18
- version = pkg_resources.get_distribution('simo')
18
+ version = pkg_resources.get_distribution('simo').version
19
19
  except:
20
20
  version = 'dev'
21
21
  ctx = {
simo/core/events.py CHANGED
@@ -29,6 +29,7 @@ class ObjMqttAnnouncement:
29
29
  def publish(self, retain=False):
30
30
  assert isinstance(self.TOPIC, str)
31
31
  assert self.data is not None
32
+ self.data['timestamp'] = timezone.now().timestamp()
32
33
  mqtt_publish.single(
33
34
  self.get_topic(), json.dumps(self.data, default=str),
34
35
  retain=retain,
@@ -48,8 +49,7 @@ class ObjectChangeEvent(ObjMqttAnnouncement):
48
49
  self.instance = instance
49
50
  self.obj = obj
50
51
  super().__init__(obj)
51
- for key, val in kwargs.items():
52
- self.data[key] = val
52
+ self.data.update(**kwargs)
53
53
 
54
54
  def get_topic(self):
55
55
  return f"{self.TOPIC}/{self.instance.id if self.instance else 'global'}/" \
@@ -118,6 +118,7 @@ class OnChangeMixin:
118
118
  for key, val in payload.get('dirty_fields', {}).items():
119
119
  if key in self.on_change_fields:
120
120
  has_changed = True
121
+ break
121
122
 
122
123
  if not has_changed:
123
124
  return
@@ -55,12 +55,13 @@ def maybe_update():
55
55
  print("Auto updates are disabled")
56
56
  else:
57
57
  try:
58
- current = pkg_resources.get_distribution('simo')
58
+ current = pkg_resources.get_distribution('simo').version
59
59
  except:
60
- current = 'dev'
60
+ return
61
61
  resp = requests.get("https://pypi.org/pypi/simo/json")
62
62
  if resp.status_code != 200:
63
63
  sys.exit("Bad response from PyPi")
64
+ return
64
65
  latest = resp.json()['info']['version']
65
66
  if current != latest:
66
67
  print(f"Need to update! We are on {current} but {latest} is available!")
@@ -0,0 +1,18 @@
1
+ # Generated by Django 4.2.10 on 2024-11-17 10:38
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('core', '0043_alter_category_instance_alter_instance_timezone_and_more'),
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.generic.gateways.GenericGatewayHandler', 'Generic'), ('simo_komfovent.gateways.KomfoventGatewayHandler', 'Komfovent'), ('simo.fleet.gateways.FleetGatewayHandler', 'SIMO.io Fleet'), ('simo_zwave.gateways.ZwaveGatewayHandler', 'Zwave')], db_index=True, max_length=200, unique=True),
17
+ ),
18
+ ]
@@ -194,7 +194,6 @@ def post_save_change_events(sender, instance, created, **kwargs):
194
194
  ObjectChangeEvent(
195
195
  None, target,
196
196
  dirty_fields=dirty_fields,
197
- timestamp=timezone.now().timestamp()
198
197
  ).publish()
199
198
  elif type(target) == Component:
200
199
  data = {}
@@ -206,7 +205,6 @@ def post_save_change_events(sender, instance, created, **kwargs):
206
205
  ObjectChangeEvent(
207
206
  target.zone.instance, target,
208
207
  dirty_fields=dirty_fields,
209
- timestamp=timezone.now().timestamp(),
210
208
  **data
211
209
  ).publish()
212
210
  for master in target.masters.all():
@@ -219,7 +217,6 @@ def post_save_change_events(sender, instance, created, **kwargs):
219
217
  ObjectChangeEvent(
220
218
  master.zone.instance,
221
219
  master, slave_id=target.id,
222
- timestamp=timezone.now().timestamp(),
223
220
  **data
224
221
  ).publish()
225
222
 
simo/core/tasks.py CHANGED
@@ -120,7 +120,7 @@ def sync_with_remote():
120
120
  mac = ''
121
121
 
122
122
  try:
123
- version = pkg_resources.get_distribution('simo').version,
123
+ version = pkg_resources.get_distribution('simo').version
124
124
  except:
125
125
  version = 'dev'
126
126
 
Binary file
simo/generic/gateways.py CHANGED
@@ -130,6 +130,8 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
130
130
  ('watch_timers', 1)
131
131
  )
132
132
 
133
+ terminating_scripts = set()
134
+
133
135
  def watch_thermostats(self):
134
136
  from .controllers import Thermostat
135
137
  drop_current_instance()
@@ -152,31 +154,25 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
152
154
  alarm_clock.tick()
153
155
 
154
156
  def watch_scripts(self):
155
- # observe running scripts and drop the ones that are no longer alive
156
157
  drop_current_instance()
157
- dead_processes = []
158
- for id, process in self.running_scripts.items():
158
+ # observe running scripts and drop the ones that are no longer alive
159
+ dead_scripts = False
160
+ for id, process in list(self.running_scripts.items()):
161
+ comp = Component.objects.filter(id=id).first()
159
162
  if process.is_alive():
160
- if not Component.objects.filter(id=id).count():
163
+ if not comp and id not in self.terminating_scripts:
161
164
  # script is deleted, or instance deactivated
162
- process.terminate()
165
+ process.kill()
163
166
  continue
164
- component = Component.objects.filter(id=id).exclude(
165
- value__in=('error', 'finished')
166
- ).first()
167
- if component:
168
- logger = get_component_logger(component)
169
- logger.log(logging.INFO, "-------DEAD!-------")
170
- component.value = 'error'
171
- component.save()
172
- dead_processes.append(id)
173
-
174
- for id in dead_processes:
175
- self.running_scripts.pop(id)
176
-
177
- if dead_processes:
178
- # give 10s of air before we restart the scripts what were
179
- # detected to be dead.
167
+ else:
168
+ if id not in self.terminating_scripts:
169
+ dead_scripts = True
170
+ logger = get_component_logger(comp)
171
+ logger.log(logging.INFO, "-------DEAD!-------")
172
+ self.stop_script(comp, 'error')
173
+
174
+ if dead_scripts:
175
+ # give 10s air before we wake these dead scripts up!
180
176
  return
181
177
 
182
178
  from simo.generic.controllers import Script
@@ -291,52 +287,68 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
291
287
  def start_script(self, component):
292
288
  print("START SCRIPT %s" % str(component))
293
289
  if component.id in self.running_scripts:
294
- if self.running_scripts[component.id].is_alive():
295
- self.running_scripts[component.id].kill()
296
- component.value = 'error'
297
- component.save(update_fields=['value'])
290
+ if component.id not in self.terminating_scripts:
291
+ if component.value != 'running':
292
+ component.value = 'running'
293
+ component.save()
294
+ return
295
+ else:
296
+ good_to_go = False
297
+ for i in range(12): # wait for 3s
298
+ time.sleep(0.2)
299
+ component.refresh_from_db()
300
+ if component.id not in self.running_scripts:
301
+ good_to_go = True
302
+ break
303
+ if not good_to_go:
304
+ return self.stop_script(component, 'error')
305
+
298
306
  self.running_scripts[component.id] = ScriptRunHandler(
299
307
  component.id, daemon=True
300
308
  )
301
309
  self.running_scripts[component.id].start()
302
310
 
303
311
  def stop_script(self, component, stop_status='stopped'):
312
+ self.terminating_scripts.add(component.id)
304
313
  if component.id not in self.running_scripts:
305
314
  if component.value == 'running':
306
315
  component.value = stop_status
307
316
  component.save(update_fields=['value'])
308
317
  return
309
- if self.running_scripts[component.id].is_alive():
310
- tz = pytz.timezone(component.zone.instance.timezone)
311
- timezone.activate(tz)
312
- logger = get_component_logger(component)
313
- if stop_status == 'error':
314
- logger.log(logging.INFO, "-------GATEWAY STOP-------")
315
- else:
316
- logger.log(logging.INFO, "-------STOP-------")
317
- self.running_scripts[component.id].terminate()
318
318
 
319
- def kill():
320
- start = time.time()
321
- terminated = False
322
- while start > time.time() - 2:
323
- if not self.running_scripts[component.id].is_alive():
324
- terminated = True
325
- break
326
- time.sleep(0.1)
327
- if not terminated:
328
- if stop_status == 'error':
329
- logger.log(logging.INFO, "-------GATEWAY KILL-------")
330
- else:
331
- logger.log(logging.INFO, "-------KILL!-------")
332
- self.running_scripts[component.id].kill()
319
+ tz = pytz.timezone(component.zone.instance.timezone)
320
+ timezone.activate(tz)
321
+ logger = get_component_logger(component)
322
+ if stop_status == 'error':
323
+ logger.log(logging.INFO, "-------GATEWAY STOP-------")
324
+ else:
325
+ logger.log(logging.INFO, "-------STOP-------")
326
+ self.running_scripts[component.id].terminate()
327
+
328
+ def kill():
329
+ start = time.time()
330
+ terminated = False
331
+ while start > time.time() - 2:
332
+ if not self.running_scripts[component.id].is_alive():
333
+ terminated = True
334
+ break
335
+ time.sleep(0.1)
336
+ if not terminated:
337
+ if stop_status == 'error':
338
+ logger.log(logging.INFO, "-------GATEWAY KILL-------")
339
+ else:
340
+ logger.log(logging.INFO, "-------KILL!-------")
341
+ self.running_scripts[component.id].kill()
333
342
 
334
- component.value = stop_status
335
- component.save(update_fields=['value'])
336
- self.running_scripts.pop(component.id)
337
- logger.handlers = []
343
+ component.value = stop_status
344
+ component.save(update_fields=['value'])
345
+ self.terminating_scripts.remove(component.id)
346
+ # making sure it's fully killed along with it's child processes
347
+ self.running_scripts[component.id].kill()
348
+ self.running_scripts.pop(component.id, None)
349
+ logger.handlers = []
338
350
 
339
- threading.Thread(target=kill, daemon=True).start()
351
+ threading.Thread(target=kill, daemon=True).start()
340
352
 
341
353
  def control_alarm_group(self, alarm_group, value):
342
354
  from simo.generic.controllers import AlarmGroup
Binary file
Binary file
simo/users/admin.py CHANGED
@@ -130,11 +130,11 @@ admin.site.unregister(Group)
130
130
  class UserDeviceLog(admin.ModelAdmin):
131
131
  model = UserDeviceReportLog
132
132
  readonly_fields = (
133
- 'datetime', 'app_open', 'location', 'relay', 'users',
133
+ 'datetime', 'app_open', 'at_home', 'location', 'relay', 'users',
134
134
  'speed_kmh', 'phone_on_charge'
135
135
  )
136
136
  list_display = (
137
- 'datetime', 'app_open', 'location', 'relay', 'speed_kmh',
137
+ 'datetime', 'at_home', 'app_open', 'location', 'relay', 'speed_kmh',
138
138
  'phone_on_charge', 'users'
139
139
  )
140
140
  fields = readonly_fields
simo/users/api.py CHANGED
@@ -222,13 +222,24 @@ class UserDeviceReport(InstanceMixin, viewsets.GenericViewSet):
222
222
  if request.data.get('is_charging'):
223
223
  phone_on_charge = True
224
224
  speed_kmh = request.data.get('speed', 0) * 3.6
225
+
226
+ at_home = False
227
+ if not relay:
228
+ at_home = True
229
+ elif last_seen_location:
230
+ at_home = haversine_distance(
231
+ self.instance.location, last_seen_location
232
+ ) < dynamic_settings['users__at_home_radius']
233
+
234
+
225
235
  for iu in request.user.instance_roles.filter(is_active=True):
226
- if location:
236
+ if not relay:
237
+ iu.at_home = True
238
+ elif location:
227
239
  iu.at_home = haversine_distance(
228
240
  iu.instance.location, last_seen_location
229
241
  ) < dynamic_settings['users__at_home_radius']
230
- elif not relay:
231
- iu.at_home = True
242
+
232
243
 
233
244
  iu.last_seen = user_device.last_seen
234
245
  iu.last_seen_location = last_seen_location
@@ -239,9 +250,9 @@ class UserDeviceReport(InstanceMixin, viewsets.GenericViewSet):
239
250
  UserDeviceReportLog.objects.create(
240
251
  user_device=user_device, instance=self.instance,
241
252
  app_open=request.data.get('app_open', False),
242
- location=','.join([str(i) for i in location]) if location else None,
253
+ location=last_seen_location,
243
254
  relay=relay, speed_kmh=speed_kmh,
244
- phone_on_charge=phone_on_charge
255
+ phone_on_charge=phone_on_charge, at_home=at_home
245
256
  )
246
257
 
247
258
  return RESTResponse({'status': 'success'})
@@ -0,0 +1,23 @@
1
+ # Generated by Django 4.2.10 on 2024-11-17 10:38
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('users', '0037_rename_last_seen_location_datetime_instanceuser_last_seen_and_more'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='userdevicereportlog',
15
+ name='at_home',
16
+ field=models.BooleanField(default=False),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='permissionsrole',
20
+ name='is_superuser',
21
+ field=models.BooleanField(default=False, help_text='Has 100% management control of an instance via mobile app.'),
22
+ ),
23
+ ]
@@ -0,0 +1,45 @@
1
+ # Generated by Django 4.2.10 on 2024-11-17 10:39
2
+ from tqdm import tqdm
3
+ from django.db import migrations
4
+
5
+
6
+ def forwards_func(apps, schema_editor):
7
+ from simo.generic.scripting.helpers import haversine_distance
8
+ UserDeviceReportLog = apps.get_model("users", "UserDeviceReportLog")
9
+
10
+ logs = UserDeviceReportLog.objects.filter(
11
+ instance__isnull=False
12
+ ).select_related('instance')
13
+
14
+ print("Calculate at_home on UserDeviceReportLog's!")
15
+
16
+ bulk_update = []
17
+ for log in tqdm(logs, total=logs.count()):
18
+ log.at_home = False
19
+ if not log.relay:
20
+ log.at_home = True
21
+ elif log.location:
22
+ log.at_home = haversine_distance(
23
+ log.instance.location, log.location
24
+ ) < 250
25
+ if log.at_home:
26
+ bulk_update.append(log)
27
+ if len(bulk_update) > 1000:
28
+ UserDeviceReportLog.objects.bulk_update(bulk_update, ["at_home"])
29
+ bulk_update = []
30
+ UserDeviceReportLog.objects.bulk_update(bulk_update, ["at_home"])
31
+
32
+
33
+ def reverse_func(apps, schema_editor):
34
+ pass
35
+
36
+
37
+ class Migration(migrations.Migration):
38
+
39
+ dependencies = [
40
+ ('users', '0038_userdevicereportlog_at_home_and_more'),
41
+ ]
42
+
43
+ operations = [
44
+ migrations.RunPython(forwards_func, reverse_func, elidable=True),
45
+ ]
simo/users/models.py CHANGED
@@ -110,7 +110,9 @@ class InstanceUser(DirtyFieldsMixin, models.Model, OnChangeMixin):
110
110
 
111
111
  objects = ActiveInstanceManager()
112
112
 
113
- on_change_fields = ('last_seen',)
113
+ on_change_fields = (
114
+ 'is_active', 'last_seen', 'last_seen_location', 'phone_on_charge'
115
+ )
114
116
 
115
117
  class Meta:
116
118
  unique_together = 'user', 'instance'
@@ -134,7 +136,7 @@ def post_instance_user_save(sender, instance, created, **kwargs):
134
136
  return
135
137
  from simo.core.events import ObjectChangeEvent
136
138
  dirty_fields = instance.get_dirty_fields()
137
- if 'at_home' in dirty_fields or 'last_seen_location' in dirty_fields:
139
+ if any([f in dirty_fields.keys() for f in InstanceUser.on_change_fields]):
138
140
  def post_update():
139
141
  if 'at_home' in dirty_fields:
140
142
  if instance.at_home:
@@ -447,6 +449,7 @@ class UserDeviceReportLog(models.Model):
447
449
  location = PlainLocationField(zoom=7, null=True, blank=True)
448
450
  speed_kmh = models.FloatField(default=0)
449
451
  phone_on_charge = models.BooleanField(default=False, db_index=True)
452
+ at_home = models.BooleanField(default=True)
450
453
 
451
454
  class Meta:
452
455
  ordering = '-datetime',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.5.27
3
+ Version: 2.5.30
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
@@ -50,4 +50,5 @@ Requires-Dist: django-activity-stream ==2.0.0
50
50
  Requires-Dist: gunicorn ==23.0.0
51
51
  Requires-Dist: python-crontab ==3.2.0
52
52
  Requires-Dist: django-object-actions ==4.3.0
53
+ Requires-Dist: tqdm ==4.67.0
53
54
 
@@ -41,10 +41,10 @@ simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
41
41
  simo/core/auto_urls.py,sha256=nNXEgLAAAQAhRWQDA9AbDtw-zcPKmu_pufJaSa8g818,1102
42
42
  simo/core/autocomplete_views.py,sha256=l7DmpoeXcwjmBda--tT6zFQTNcyfYpgTaryWP-ghETU,3846
43
43
  simo/core/base_types.py,sha256=WypW8hTfzveuTQtruGjLYAGQZIuczxTlW-SdRk3iQug,666
44
- simo/core/context.py,sha256=xH7Fdd2uO7CMm3a1QHnYJTZfEfPfBDFSScKxAx6q69o,1549
44
+ simo/core/context.py,sha256=LKw1I4iIRnlnzoTCuSLLqDX7crHdBnMo3hjqYvVmzFc,1557
45
45
  simo/core/controllers.py,sha256=JvXdwXD7iotA7fIjZmBVshKLQGSt9Na48FMAyHRDh84,35615
46
46
  simo/core/dynamic_settings.py,sha256=bUs58XEZOCIEhg1TigR3LmYggli13KMryBZ9pC7ugAQ,1872
47
- simo/core/events.py,sha256=fH6d5HcPdDqT3R7CZPdo69qTszJ23j3GJt3IFOso3WA,4757
47
+ simo/core/events.py,sha256=1_KIk5pJqdLPRQlCQ9xSyALst2Cn0b2lAEAJ3QjwIjE,4801
48
48
  simo/core/filters.py,sha256=ghtOZcrwNAkIyF5_G9Sn73NkiI71mXv0NhwCk4IyMIM,411
49
49
  simo/core/form_fields.py,sha256=wowWocYgxkKBr0WYzpKn4UvH4ScnImus56Tg2G8OPBc,2274
50
50
  simo/core/forms.py,sha256=O40apPH7a4qX4WdCc10A1aoAaGWOpKqmjB8d-OhEKCo,21523
@@ -56,10 +56,10 @@ simo/core/models.py,sha256=DXJXTtNdpn9yC4VArHp0yrhpRb7vGpwH2c-JvqLE56M,22784
56
56
  simo/core/permissions.py,sha256=INQPrUAIM3WXCvd7e6cmYytKaak8fMEn7VooX-fIds0,3002
57
57
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
58
58
  simo/core/serializers.py,sha256=WgksN1Ombv240nfQR_UtmKslTWM9vz9Y0yTdN5usiHU,21892
59
- simo/core/signal_receivers.py,sha256=WYBRCFJhP83Ukd-Ipc1HlNyTXdTHD1rl0tV3uOKnYWY,8861
59
+ simo/core/signal_receivers.py,sha256=2WfF3FI5ZmJM1S-oT_1w3TdnBUX6fjbI4Rpg-DKsuYA,8696
60
60
  simo/core/socket_consumers.py,sha256=trRZvBGTJ7xIbfdmVvn7zoiWp_qssSkMZykDrI5YQyE,9783
61
61
  simo/core/storage.py,sha256=_5igjaoWZAiExGWFEJMElxUw55DzJG1jqFty33xe8BE,342
62
- simo/core/tasks.py,sha256=N0E9ps1n1d8xayYElGlm7GDudVEwpWfFjC8Aq9fP7TA,16407
62
+ simo/core/tasks.py,sha256=yrZORvMv7imfsyLIPn8TGDwo7oN7SDY1Uxv4C67Unfo,16406
63
63
  simo/core/todos.py,sha256=eYVXfLGiapkxKK57XuviSNe3WsUYyIWZ0hgQJk7ThKo,665
64
64
  simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
65
65
  simo/core/views.py,sha256=3SRZr00fyLQf8ja3U-9eekKt-ld5TvU1WQqUWprXfQ4,2390
@@ -74,25 +74,25 @@ simo/core/__pycache__/apps.cpython-38.pyc,sha256=JL0BEqgXcSQvMlcK48PBpPfyDEkPMdO
74
74
  simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=Tyf8PYHq5YqSwTp25Joy-eura_Fm86fpX9zKLSklhvo,872
75
75
  simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=YoF9mTXfQtZ0ZC4wIVvYe4RUUnfV8OlCkIDTVT0LwBw,3953
76
76
  simo/core/__pycache__/base_types.cpython-38.pyc,sha256=CX-qlF7CefRi_mCE954wYa9rUFR88mOl6g7fybDRu7g,803
77
- simo/core/__pycache__/context.cpython-38.pyc,sha256=ck1FcBljLB4__5F6poS2tEEn8IDDgK7pU3FcXDPc_mI,1329
77
+ simo/core/__pycache__/context.cpython-38.pyc,sha256=NlTHt2GvXxA21AhBkeyOLfRFUuXw7wmwqyNhhcDl2cw,1373
78
78
  simo/core/__pycache__/controllers.cpython-38.pyc,sha256=6Ts1BeGND9Uy5eeqC5dNeme1yYilEV_emRnjTjJ9WNw,30701
79
79
  simo/core/__pycache__/dynamic_settings.cpython-38.pyc,sha256=wGpnscX1DxFpRl54MQURhjz2aD3NJohSzw9JCFnzh2Y,2384
80
- simo/core/__pycache__/events.cpython-38.pyc,sha256=yip7WSyX4pUy2wJE820W4fD7iwoIWGhdHfloFb_N0R8,5257
80
+ simo/core/__pycache__/events.cpython-38.pyc,sha256=1y8YaZsiDkBOeIWzH7SQz4holmMG_RLlMWi8kuSZcoE,5280
81
81
  simo/core/__pycache__/filters.cpython-38.pyc,sha256=VIMADCBiYhziIyRmxAyUDJluZvuZmiC4bNYWTRsGSao,721
82
82
  simo/core/__pycache__/form_fields.cpython-38.pyc,sha256=phMdhDFRmaFDhJSnasAg8VKNP6PxkPjFqkLwEuWicIs,3465
83
83
  simo/core/__pycache__/forms.cpython-38.pyc,sha256=vqU3No0S56V1q1RrY7y5otT-o0p-5qAiffvqECG2Gg8,17525
84
84
  simo/core/__pycache__/gateways.cpython-38.pyc,sha256=D1ooHL-iSpQrxnD8uAl4xWFJmm-QWZfbkLiLlFOMtdU,4553
85
85
  simo/core/__pycache__/loggers.cpython-38.pyc,sha256=Z-cdQnC6XlIonPV4Sl4E52tP4NMEdPAiHK0cFaIL7I8,1623
86
86
  simo/core/__pycache__/managers.cpython-38.pyc,sha256=6RTIxyjOgpQGtAqcUyE2vFPS09w1V5Wmd_vOV7rHRRI,3370
87
- simo/core/__pycache__/middleware.cpython-38.pyc,sha256=iOSTXSQl3sEsa-9kx_6w5zbEByRtfzJHT6XkUIYMGdE,2469
87
+ simo/core/__pycache__/middleware.cpython-38.pyc,sha256=g3d4L2PwxFyRKIPMP9Hkdjk1PL9NarQd4hSHS55I8n8,2649
88
88
  simo/core/__pycache__/models.cpython-38.pyc,sha256=HGL3TiaMy-0oobgCGGxH2nvDhh4RnOBeD00rwQsuklU,18591
89
89
  simo/core/__pycache__/permissions.cpython-38.pyc,sha256=bO13B8uGCv4AiWNBoU2Gxt3mNuQ3gCxb7eKFihwFb5o,2974
90
90
  simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
91
91
  simo/core/__pycache__/serializers.cpython-38.pyc,sha256=d4wpUjFuo8GxaNWbin9GdHKik06IZN32uZL1SnXiL_s,19616
92
- simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=ZxsQUC_bijcKs2A9BifeqdI5JVS0RCsZpdcBTRoT8o8,6733
92
+ simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=Od1ejof2nHAFzTAG5vGGVjMA8WUJNVJ9o_KWGqRSR34,6669
93
93
  simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=KqbO1cOewodVPcy0-htVefyUjCuELKV0o7fOfYqfgPc,8490
94
94
  simo/core/__pycache__/storage.cpython-38.pyc,sha256=9R1Xu0FJDflfRXUPsqEgt0SpwiP7FGk7HaR8s8XRyI8,721
95
- simo/core/__pycache__/tasks.cpython-38.pyc,sha256=PN2_K7yt2lDRYqbkKIozcENhq0gkW5muE0GVKevLM6o,10951
95
+ simo/core/__pycache__/tasks.cpython-38.pyc,sha256=0cdIMWxwx8qkeseOvZcgIZ_BXrGbkhfijRUfpIa3s8s,10896
96
96
  simo/core/__pycache__/todos.cpython-38.pyc,sha256=lOqGZ58siHM3isoJV4r7sg8igrfE9fFd-jSfeBa0AQI,253
97
97
  simo/core/__pycache__/views.cpython-38.pyc,sha256=K_QM967bIJeU02DJu0Dm7j8RiFDKn_TLzX77YzNkA7c,2495
98
98
  simo/core/__pycache__/widgets.cpython-38.pyc,sha256=sR0ZeHCHrhnNDBJuRrxp3zUsfBp0xrtF0xrK2TkQv1o,3520
@@ -146,7 +146,7 @@ simo/core/drf_braces/tests/serializers/test_enforce_validation_serializer.py,sha
146
146
  simo/core/drf_braces/tests/serializers/test_form_serializer.py,sha256=IE2xQ1SzhSsOy2BFsBYw_Po-ujKBgIuNoTRxCzhyilE,12995
147
147
  simo/core/drf_braces/tests/serializers/test_swapping.py,sha256=o-B5YV5HDxHCVrXYGODeF7lB3rPDGtafNgClx97d6w4,1220
148
148
  simo/core/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
- simo/core/management/update.py,sha256=CDve2OAKBLJpnuhIgOp7riqBm_gl9D0oNKmNOFXGq2E,1964
149
+ simo/core/management/update.py,sha256=XHkacZcwotUMJ6f1PEpVs3iIZr6wNZ4l_P6Kg_EF4IM,1982
150
150
  simo/core/management/__pycache__/__init__.cpython-38.pyc,sha256=Ptf1WzljXMt3wP1tzOy6q3JfLERYDs66wSHBVdrzjHg,169
151
151
  simo/core/management/_hub_template/hub/asgi.py,sha256=ElN_fdeSkf0Ysa7pS9rJVmZ1HmLhFxb8jFaMLqe1220,126
152
152
  simo/core/management/_hub_template/hub/celeryc.py,sha256=3ksDXftIZKJ4Cq9WNKJERdZdQlDEnjTQXycweRFmsSQ,27
@@ -206,6 +206,7 @@ simo/core/migrations/0040_alter_instance_name.py,sha256=FqUq-NnO_eqMy3lg5Yl0uG3C
206
206
  simo/core/migrations/0041_alter_instance_slug.py,sha256=MmuW0n5CCpF7NyKYINDcqChOU1DynSqQu_3wAYQypCo,401
207
207
  simo/core/migrations/0042_alter_instance_timezone.py,sha256=5fLprOmoV06y37rh3uJWq8Fy4SjNmu86Imky6t7j13g,23334
208
208
  simo/core/migrations/0043_alter_category_instance_alter_instance_timezone_and_more.py,sha256=TpJRZjwJu1iDYt1cCQr62jLOz14yy7yjrfbyHYgu9pM,23896
209
+ simo/core/migrations/0044_alter_gateway_type.py,sha256=xoQvOSz_JrWHECAAII83518tmhEEfLUHqxpIjoo4oLY,758
209
210
  simo/core/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
210
211
  simo/core/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=w6GiBXVxWj30Bg4Sn_pFVeA041d-pCrkaq8mR3KuF70,5381
211
212
  simo/core/migrations/__pycache__/0002_load_icons.cpython-38.pyc,sha256=Nb9RrPjVYo_RpZ5PmzoaEIWGCeVt4kicpmGiKlBrpIw,2123
@@ -250,6 +251,7 @@ simo/core/migrations/__pycache__/0040_alter_instance_name.cpython-38.pyc,sha256=
250
251
  simo/core/migrations/__pycache__/0041_alter_instance_slug.cpython-38.pyc,sha256=tVBd5-92gJPHR-I2yjUhsbtxwcykBMzxA6W3mvs8giE,620
251
252
  simo/core/migrations/__pycache__/0042_alter_instance_timezone.cpython-38.pyc,sha256=_IdEOLCC0xgeVcKfCk7x0kKxVPu0iWuCxCg8aqkzeSI,16392
252
253
  simo/core/migrations/__pycache__/0043_alter_category_instance_alter_instance_timezone_and_more.cpython-38.pyc,sha256=97_eFPQ_Iy-M1712Nad1w8t3ITBV4BF0eY1e8N-oOE4,16759
254
+ simo/core/migrations/__pycache__/0044_alter_gateway_type.cpython-38.pyc,sha256=KwqGKoo8C1wH9ZUhagpC3plTwheSMcWtwlCGcSPd5WQ,964
253
255
  simo/core/migrations/__pycache__/__init__.cpython-38.pyc,sha256=VZmDQ57BTcebuM0KMhjiTOabgWZCBxQmSJzWZos9SO8,169
254
256
  simo/core/static/ansi_styles.css,sha256=4ieJGrjZPKyPSago9FdB_gflHoGE1vxCHi8qVn5tY-Y,37352
255
257
  simo/core/static/admin/Img/plus.svg,sha256=2NpSFPWqGIjpAQGFI7LDQHPKagEhYkJiJX95ufCoZaI,741
@@ -10241,13 +10243,13 @@ simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=Tc6a6BCXHjijP8U2jE2ghlJwn
10241
10243
  simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
10242
10244
  simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
10243
10245
  simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=jtFHr_uyjCCeuidL-o-hGaf21u0fnxK_O6hTRdY6lpc,24906
10244
- simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=tvoi9np3Empg1GYBFTChznEy09M0v6UBRaGz9FZCJxc,42300
10246
+ simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=09TcBfKorvkokHkLRua0gg8sVBamwjEhvCpoANRhPyg,42595
10245
10247
  simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=0RKVn0ndreVKhsrukqeLPSdMnRrsQ_W7yeVeBkRLfIk,5058
10246
10248
  simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=Vmm23zoQnS3-uS5_WJt2n3wtjhLiEhLWaYxXJCU6Gts,1339
10247
- simo/fleet/__pycache__/models.cpython-38.pyc,sha256=d1Reu7cAryqGuA_Z0eqVsX7SFUo4_jNnyi1JbK7mWuI,14138
10249
+ simo/fleet/__pycache__/models.cpython-38.pyc,sha256=WUahZgETWlem5rVXlJ_vINFRM7OZWp5xpWXGMoeBXsM,14131
10248
10250
  simo/fleet/__pycache__/routing.cpython-38.pyc,sha256=aPrCmxFKVyB8R8ZbJDwdPdFfvT7CvobovvZeq_mqRgY,314
10249
10251
  simo/fleet/__pycache__/serializers.cpython-38.pyc,sha256=gIWHJaSUbTe9H_xerD29Fz7BxIqXNzBI60GsIVXbNdY,3134
10250
- simo/fleet/__pycache__/socket_consumers.cpython-38.pyc,sha256=YUu6CroTABvoZGRHnE-bVno1-5pUWLSA0wOQkbrHfuo,14032
10252
+ simo/fleet/__pycache__/socket_consumers.cpython-38.pyc,sha256=Dmy99vvfoB-k-lLvr_BHit6JzbCAXiUUxTSCpdDrElU,14012
10251
10253
  simo/fleet/__pycache__/tasks.cpython-38.pyc,sha256=RoNxL2WUiW67s9O9DjaYVVjCBSZu2nje0Qn9FJkWVS0,1116
10252
10254
  simo/fleet/__pycache__/utils.cpython-38.pyc,sha256=obUd-X2Y-ybx4icqUWq_qwIxrP9yyarJjexWAfO4MTI,3344
10253
10255
  simo/fleet/__pycache__/views.cpython-38.pyc,sha256=wilxSvZliSKQ5qC7JjWneYBSdbeZeTsF5uDrOQVmvms,3181
@@ -10342,7 +10344,7 @@ simo/generic/app_widgets.py,sha256=TPRLj4hri2hBuY6mrdwBiv-01z2hDxZmsup-GDD9LrM,9
10342
10344
  simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
10343
10345
  simo/generic/controllers.py,sha256=i-xKQ5PrNKwCuO0dFaHHUaD5rF9lDnq18ziVSNBENao,50134
10344
10346
  simo/generic/forms.py,sha256=tCbIZtbruBHjZRzulGXJQOjmxaGJ2uoKqjT1scScdDQ,29004
10345
- simo/generic/gateways.py,sha256=MxPQzgEnnXSG-t6rErHZQJACFWegCWGaME640UIGrA8,15783
10347
+ simo/generic/gateways.py,sha256=0gDjWSCAt6MABR6k8xV7N1zXutDLCileGtAm6pSl4Q4,16165
10346
10348
  simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
10347
10349
  simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
10348
10350
  simo/generic/socket_consumers.py,sha256=K2OjphIhKJH48BvfFfoCOyCQZ1NmXb_phs6y1IP-qaQ,1757
@@ -10350,8 +10352,8 @@ simo/generic/__pycache__/__init__.cpython-38.pyc,sha256=mLu54WS9KIl-pHwVCBKpsDFI
10350
10352
  simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=YZ5db6-FPynBi6ooPW5crK9lZ6ymRh2DlGN6FwxfX4M,1820
10351
10353
  simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
10352
10354
  simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=-Y3fV0gbkye9WgWpdNY7qG9VvMWpFUT7Spl1eukztgQ,33352
10353
- simo/generic/__pycache__/forms.cpython-38.pyc,sha256=w7p-dFYvxtNMlrKVnM2zWa1Jp0zXygP6Lbo6kKg-Ox4,21228
10354
- simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=QGj0mIWyqrVpn9AeGeYzdu6PxcF5SdQOHNzEqcHCy_E,11648
10355
+ simo/generic/__pycache__/forms.cpython-38.pyc,sha256=Dd-hgbRNdIFzUDjSZ4yQp7wwR-ILBYQFI8MCob_ZYwQ,21232
10356
+ simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=uubZtp-UgEmKU4vG9ophnCZFEDqmKkeY1yyWUXzdmdY,12015
10355
10357
  simo/generic/__pycache__/models.cpython-38.pyc,sha256=MZpum7syAFxuulf47K7gtUlJJ7xRD-IBUBAwUM1ZRnw,5825
10356
10358
  simo/generic/__pycache__/routing.cpython-38.pyc,sha256=xtxTUTBTdivzFyA5Wh7k-hUj1WDO_FiRq6HYXdbr9Ks,382
10357
10359
  simo/generic/__pycache__/socket_consumers.cpython-38.pyc,sha256=qJO5kvQLWhsQDOr1AtAtsAybuRWioxSkQei3Pc7rdP0,1737
@@ -10442,15 +10444,15 @@ simo/notifications/migrations/__pycache__/0002_notification_instance.cpython-38.
10442
10444
  simo/notifications/migrations/__pycache__/0003_alter_notification_instance.cpython-38.pyc,sha256=awhD1F9RyK_706zVNM5io3WT_konFkKQgL7D5MkONwk,851
10443
10445
  simo/notifications/migrations/__pycache__/__init__.cpython-38.pyc,sha256=YMBRHVon2nWDtIUbghckjnC12sIg_ykPWhV5aM0tto4,178
10444
10446
  simo/users/__init__.py,sha256=6a7uBpCWB_DR7p54rbHusc0xvi1qfT1ZCCQGb6TiBh8,52
10445
- simo/users/admin.py,sha256=9P0iIGAep2R1AUvZnROsRULbxwCYK9pCfSJ2X4aLLBg,6965
10446
- simo/users/api.py,sha256=xe__HFxzOaKgrh75PFpP4nkSs5DvmJp8QvMDNhP5kLU,12127
10447
+ simo/users/admin.py,sha256=2Ay47b1NWBfdUpMZ8qUFAbwiu7-P3JNxNpM7FKVwrLw,6987
10448
+ simo/users/api.py,sha256=pWmP201jyz7_KCC_c8Fsrnh1R0HoCkcHfwu4LYCIRfg,12373
10447
10449
  simo/users/apps.py,sha256=cq0A8-U1HALEwev0TicgFhr4CAu7Icz8rwq0HfOaL4E,207
10448
10450
  simo/users/auth_backends.py,sha256=KIw2AdjCUKfm_7Lql6aC4qdE6JznP0ECIMA5MVMLeiM,4251
10449
10451
  simo/users/auto_urls.py,sha256=lcJvteBsbHQMJieZpDz-63tDYejLApqsW3CUnDakd7k,272
10450
10452
  simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
10451
10453
  simo/users/managers.py,sha256=OHgEP85MBtdkdYxdstBd8RavTBT8F_2WyDxUJ9aCqqM,246
10452
10454
  simo/users/middleware.py,sha256=GMCrnWSc_2qCleyQIkfQGdL-pU-UTEcSg1wPvIKZ9uk,1210
10453
- simo/users/models.py,sha256=Ms5YiU_N1rDSxWMYErO1RnBiK7Jo8Ww_raYJZ5p4yL0,19551
10455
+ simo/users/models.py,sha256=EeIiEPJMS5wibbdYOvNzxTT1eGihFYERlNwERli5Uo8,19671
10454
10456
  simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
10455
10457
  simo/users/serializers.py,sha256=zzw1KONTnaTNBaU0r4rNVxJ827KzD6Z5LuQt27ZsQ98,2516
10456
10458
  simo/users/sso_urls.py,sha256=gQOaPvGMYFD0NCVSwyoWO-mTEHe5j9sbzV_RK7kdvp0,251
@@ -10459,15 +10461,15 @@ simo/users/tasks.py,sha256=HJAqiyWGsaN3wSfquU0UyQ20jL-njXeaaTOdDT3TQ3s,979
10459
10461
  simo/users/utils.py,sha256=1HGSZyHRqQvdJ4RtAiZDg1juvgG8aOlrGXR7CcvsyQc,1886
10460
10462
  simo/users/views.py,sha256=dOQVvmlHG7ihWKJLFUBcqKOA0UDctlMKR0pTc36JZqg,3487
10461
10463
  simo/users/__pycache__/__init__.cpython-38.pyc,sha256=VFoDJE_SKKaPqqYaaBYd1Ndb1hjakkTo_u0EG_XJ1GM,211
10462
- simo/users/__pycache__/admin.cpython-38.pyc,sha256=xZ_PgvobRrbqSuNgR2z2ZNm1Ec7MlvswLp7wiUxw5KQ,7937
10463
- simo/users/__pycache__/api.cpython-38.pyc,sha256=laiJ17ZN-Bj8fL-AjKpcjPm0hOVEd83vYkOqxfmHa7c,10218
10464
+ simo/users/__pycache__/admin.cpython-38.pyc,sha256=-TXB5LGoAvCfgNhsqaB-1pgyyfW8lbuGcgD8F4HZojk,7947
10465
+ simo/users/__pycache__/api.cpython-38.pyc,sha256=4JQ61L-i0GXtnqlGgZfoHHQX9bd8xJc9kkEmvjHC_-Q,10172
10464
10466
  simo/users/__pycache__/apps.cpython-38.pyc,sha256=dgbWL8CxzzISJQTmq_4IztPJ2UzykNVdqA2Ae1PmeGk,605
10465
- simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=n5nx2QSXNj2idzRcGE6bAagMN-8qxoCs580H1EFZXls,3105
10467
+ simo/users/__pycache__/auth_backends.cpython-38.pyc,sha256=jYS2hlbTZh_ZtPeWcN50pc0IpyfCSO7_MvIbuVwEp8M,3144
10466
10468
  simo/users/__pycache__/auto_urls.cpython-38.pyc,sha256=K-3sz2h-cEitoflSmZk1t0eUg5mQMMGLNZFREVwG7_o,430
10467
10469
  simo/users/__pycache__/dynamic_settings.cpython-38.pyc,sha256=6F8JBjZkHykySnmZjNEzjS0ijbmPdcp9yUAZ5kqq_Fo,864
10468
10470
  simo/users/__pycache__/managers.cpython-38.pyc,sha256=O0Y8ABp42RAosrbODmYsPMaj9AyOPyJ-aqzuO0Qpi2s,679
10469
10471
  simo/users/__pycache__/middleware.cpython-38.pyc,sha256=Tj4nVEAvxEW3xA63fBRiJWRJpz_M848ZOqbHioc_IPE,1149
10470
- simo/users/__pycache__/models.cpython-38.pyc,sha256=RDZ7bjfjTQV0rJxEVM8dfaxD5oKmoOWViAtIPpQmNQg,17472
10472
+ simo/users/__pycache__/models.cpython-38.pyc,sha256=aFOdFfAu0XLxg4BOSE_Kj3e-Qr3b8dMH8mWiyM9Egew,17672
10471
10473
  simo/users/__pycache__/permissions.cpython-38.pyc,sha256=ez5NxoL_JUeeH6GsKhvFreuA3FCBgGf9floSypdXUtM,633
10472
10474
  simo/users/__pycache__/serializers.cpython-38.pyc,sha256=Dy8RAcwNkNSXoJHvLp8fozURyHCtucqpSPyqZtbnMZc,3732
10473
10475
  simo/users/__pycache__/sso_urls.cpython-38.pyc,sha256=uAwDozpOmrhUald-8tOHANILXkH7-TI8fNYXOtPkSY8,402
@@ -10512,6 +10514,8 @@ simo/users/migrations/0034_instanceuser_last_seen_location_and_more.py,sha256=_W
10512
10514
  simo/users/migrations/0035_instanceuser_last_seen_speed_kmh_and_more.py,sha256=lAtNHugmvm-ssNL3R82o2mKayxBU5K_wLXoWaxyr1XI,580
10513
10515
  simo/users/migrations/0036_instanceuser_phone_on_charge_user_phone_on_charge.py,sha256=uHXLRmFAASdB9sPivYkRu7WV4rxZDI3RaEwl2i7U_xg,615
10514
10516
  simo/users/migrations/0037_rename_last_seen_location_datetime_instanceuser_last_seen_and_more.py,sha256=8f_7fC7k0Dm-0gGVHMI9_490BbEC_SfuAPrAADrZ7BA,1543
10517
+ simo/users/migrations/0038_userdevicereportlog_at_home_and_more.py,sha256=qL1ZjUJDiSrJat59ToqpNBwnMMPb3Q5mwHq-qd1eFcI,691
10518
+ simo/users/migrations/0039_auto_20241117_1039.py,sha256=e64AJM2ZId516Px-gmAxkp2NmSC5Vjo_BBTGbYrFuKY,1310
10515
10519
  simo/users/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10516
10520
  simo/users/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=e4XOKaYRb7l0P7cBnHHi5FQQJMlwjK0g7iqgM-xKmNI,4215
10517
10521
  simo/users/migrations/__pycache__/0002_componentpermission.cpython-38.pyc,sha256=pknJnpic8p6Vdx9DX41FfODXNnvexDswJtUCmC5w1tg,995
@@ -10552,6 +10556,8 @@ simo/users/migrations/__pycache__/0034_instanceuser_last_seen_location_and_more.
10552
10556
  simo/users/migrations/__pycache__/0035_instanceuser_last_seen_speed_kmh_and_more.cpython-38.pyc,sha256=EOQ0J-t-CMgyVCAl6NHBXyScx6D83MO-zISO9Z1aE-U,705
10553
10557
  simo/users/migrations/__pycache__/0036_instanceuser_phone_on_charge_user_phone_on_charge.cpython-38.pyc,sha256=y1ZDJ8VM5_vJOxTPRERjwukiGXJ89UhDc4bHiHZwQ_w,723
10554
10558
  simo/users/migrations/__pycache__/0037_rename_last_seen_location_datetime_instanceuser_last_seen_and_more.cpython-38.pyc,sha256=W4Rc6SRNNJ_yAYrEyoklD5LFmQPAL9mTDrXHMfP8R4I,1162
10559
+ simo/users/migrations/__pycache__/0038_userdevicereportlog_at_home_and_more.cpython-38.pyc,sha256=khDSeTH3-jJ4yO1D6-i3Pm_NekJkVwBSUJ-rAxu0cr4,836
10560
+ simo/users/migrations/__pycache__/0039_auto_20241117_1039.cpython-38.pyc,sha256=IEOIfvnUiV-GX9VI4W2UKJugC3nfwKfy7QdmS3pW6Ss,1377
10555
10561
  simo/users/migrations/__pycache__/__init__.cpython-38.pyc,sha256=NKq7WLgktK8WV1oOqCPbAbdkrPV5GRGhYx4VxxI4dcs,170
10556
10562
  simo/users/templates/conf/mosquitto.conf,sha256=1eIGNuRu4Y3hfAU6qiWix648eCRrw0oOT24PnyFI4ys,189
10557
10563
  simo/users/templates/conf/mosquitto_acls.conf,sha256=ga44caTDNQE0CBKw55iM2jOuna6-9fKGwAhjyERZdRE,500
@@ -10561,9 +10567,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10561
10567
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10562
10568
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10563
10569
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10564
- simo-2.5.27.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10565
- simo-2.5.27.dist-info/METADATA,sha256=iYNcZpbiLgJERBKWPk9fk0ZMXQqO7-pT2h-9B6N9YbE,1924
10566
- simo-2.5.27.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10567
- simo-2.5.27.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10568
- simo-2.5.27.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10569
- simo-2.5.27.dist-info/RECORD,,
10570
+ simo-2.5.30.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10571
+ simo-2.5.30.dist-info/METADATA,sha256=rnYLYWnVpPGB86Gmr15dmR9wmv--Q42fKSUK_3Uu6iI,1953
10572
+ simo-2.5.30.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10573
+ simo-2.5.30.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10574
+ simo-2.5.30.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10575
+ simo-2.5.30.dist-info/RECORD,,
File without changes