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

simo/core/api.py CHANGED
@@ -544,6 +544,46 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
544
544
  if main_alarm_group:
545
545
  main_alarm_group_id = main_alarm_group.id
546
546
 
547
+ if request.method == 'POST':
548
+ data = request.data
549
+ if not isinstance(request.data, dict):
550
+ data = data.dict()
551
+ request_data = restore_json(data)
552
+ if 'history_days' in request_data:
553
+ try:
554
+ history_days = int(request_data['history_days'])
555
+ except:
556
+ raise APIValidationError(
557
+ _('Bad value for history days!'), code=400
558
+ )
559
+ if history_days < 0 or history_days > 365:
560
+ raise APIValidationError(
561
+ _('History days must be 0 - 365!'), code=400
562
+ )
563
+ self.instance.history_days = history_days
564
+ if 'device_report_history_days' in request_data:
565
+ try:
566
+ device_report_history_days = int(
567
+ request_data['device_report_history_days']
568
+ )
569
+ except:
570
+ raise APIValidationError(
571
+ _('Bad value for device_report_history_days days!'),
572
+ code=400
573
+ )
574
+ if device_report_history_days < 0 \
575
+ or device_report_history_days > 365:
576
+ raise APIValidationError(
577
+ _('History days must be 0 - 365!'), code=400
578
+ )
579
+ self.instance.device_report_history_days = device_report_history_days
580
+
581
+ self.instance.indoor_climate_sensor = Component.objects.filter(
582
+ id=request_data.get('indoor_climate_sensor', 0)
583
+ ).first()
584
+
585
+ self.instance.save()
586
+
547
587
  return RESTResponse({
548
588
  'hub_uid': dynamic_settings['core__hub_uid'],
549
589
  'instance_name': self.instance.name,
@@ -551,12 +591,15 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
551
591
  'timezone': self.instance.timezone,
552
592
  'location': self.instance.location,
553
593
  'last_event': last_event,
554
- 'indoor_climate_sensor': self.instance.indoor_climate_sensor_id,
555
594
  'weather_forecast': wf_comp_id,
556
595
  'main_alarm_group': main_alarm_group_id,
557
596
  'remote_http': dynamic_settings['core__remote_http'],
558
597
  'local_http': 'https://%s' % get_self_ip(),
559
- 'units_of_measure': self.instance.units_of_measure
598
+ 'units_of_measure': self.instance.units_of_measure,
599
+ # editable fields
600
+ 'history_days': self.instance.history_days,
601
+ 'device_report_history_days': self.instance.device_report_history_days,
602
+ 'indoor_climate_sensor': self.instance.indoor_climate_sensor_id,
560
603
  })
561
604
 
562
605
 
simo/core/api_auth.py CHANGED
@@ -41,7 +41,3 @@ class IsAuthenticated(SessionAuthentication):
41
41
 
42
42
  def authenticate_header(self, request):
43
43
  return "None"
44
-
45
-
46
-
47
-
simo/core/apps.py CHANGED
@@ -9,5 +9,8 @@ class SIMOCoreAppConfig(AppConfig):
9
9
  from actstream import registry
10
10
  registry.register(self.get_model('Component'))
11
11
  registry.register(self.get_model('Gateway'))
12
+ registry.register(self.get_model('Instance'))
13
+ registry.register(self.get_model('Zone'))
14
+ registry.register(self.get_model('Category'))
12
15
 
13
16
 
simo/core/serializers.py CHANGED
@@ -257,8 +257,6 @@ class ComponentSerializer(FormSerializer):
257
257
  controller_methods = serializers.SerializerMethodField()
258
258
  info = serializers.SerializerMethodField()
259
259
 
260
- _forms = {}
261
-
262
260
  class Meta:
263
261
  form = ComponentAdminForm
264
262
  field_mapping = {
@@ -386,13 +384,15 @@ class ComponentSerializer(FormSerializer):
386
384
  self.Meta.form = controller.config_form
387
385
 
388
386
  def get_form(self, data=None, instance=None, **kwargs):
387
+ if 'forms' not in self.context:
388
+ self.context['forms'] = {}
389
389
  form_key = None
390
390
  if not data:
391
391
  form_key = 0
392
392
  if instance:
393
393
  form_key = instance.id
394
- if form_key in self._forms:
395
- return self._forms[form_key]
394
+ if form_key in self.context['forms']:
395
+ return self.context['forms'][form_key]
396
396
 
397
397
  self.set_form_cls()
398
398
  if not self.instance or isinstance(self.instance, Iterable):
@@ -412,11 +412,10 @@ class ComponentSerializer(FormSerializer):
412
412
  if not user_role.is_superuser and user_role.is_owner:
413
413
  for field_name in list(form.fields.keys()):
414
414
  if field_name not in form.basic_fields:
415
- print("DELETE FIELD: ", field_name)
416
415
  del form.fields[field_name]
417
416
 
418
417
  if form_key is not None:
419
- self._forms[form_key] = form
418
+ self.context['forms'][form_key] = form
420
419
 
421
420
  return form
422
421
 
@@ -71,8 +71,8 @@ def create_instance_defaults(sender, instance, created, **kwargs):
71
71
  )
72
72
  dummy.start()
73
73
  weather_icon = Icon.objects.get(slug='cloud-bolt-sun')
74
- other_zone = Zone.objects.get(name='Other')
75
- climate_category = Category.objects.get(name='Climate')
74
+ other_zone = Zone.objects.get(name='Other', instance=instance)
75
+ climate_category = Category.objects.get(name='Climate', instance=instance)
76
76
  Component.objects.create(
77
77
  name='Weather', icon=weather_icon,
78
78
  zone=other_zone,
simo/core/tasks.py CHANGED
@@ -167,82 +167,83 @@ def sync_with_remote():
167
167
 
168
168
  print("Responded with: ", json.dumps(r_json))
169
169
 
170
- if 'hub_uid' in r_json:
171
- dynamic_settings['core__hub_uid'] = r_json['hub_uid']
172
-
173
- dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
174
- if 'new_secret' in r_json:
175
- dynamic_settings['core__hub_secret'] = r_json['new_secret']
176
-
177
- if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
178
- save_config(r_json)
179
- dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
180
-
181
- for data in r_json['instances']:
182
- users_data = data.pop('users', {})
183
- instance_uid = data.pop('uid')
184
- weather_forecast = data.pop('weather_forecast', None)
185
- instance, new_instance = Instance.objects.update_or_create(
186
- uid=instance_uid, defaults=data
187
- )
170
+ with transaction.atomic():
171
+ if 'hub_uid' in r_json:
172
+ dynamic_settings['core__hub_uid'] = r_json['hub_uid']
173
+
174
+ dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
175
+ if 'new_secret' in r_json:
176
+ dynamic_settings['core__hub_secret'] = r_json['new_secret']
177
+
178
+ if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
179
+ save_config(r_json)
180
+ dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
181
+
182
+ for data in r_json['instances']:
183
+ users_data = data.pop('users', {})
184
+ instance_uid = data.pop('uid')
185
+ weather_forecast = data.pop('weather_forecast', None)
186
+ instance, new_instance = Instance.objects.update_or_create(
187
+ uid=instance_uid, defaults=data
188
+ )
188
189
 
189
- if weather_forecast:
190
- from simo.generic.controllers import WeatherForecast
191
- weather_component = Component.objects.filter(
192
- zone__instance=instance,
193
- controller_uid=WeatherForecast.uid
194
- ).first()
195
- if weather_component:
196
- weather_component.track_history = False
197
- weather_component.controller.set(weather_forecast)
198
-
199
-
200
- for email, options in users_data.items():
201
- with transaction.atomic():
202
- if new_instance:
203
- # Create users for new instance!
204
- user, new_user = User.objects.update_or_create(
205
- email=email, defaults={
206
- 'name': options.get('name'),
207
- 'is_master': options.get('is_hub_master', False),
208
- 'ssh_key': options.get('ssh_key')
209
- })
210
- role = None
211
- if options.get('is_superuser'):
212
- role = PermissionsRole.objects.filter(
213
- instance=new_instance, is_superuser=True
214
- ).first()
215
- elif options.get('is_owner'):
216
- role = PermissionsRole.objects.filter(
217
- instance=new_instance, is_owner=True
218
- ).first()
219
- InstanceUser.objects.update_or_create(
220
- user=user, instance=new_instance, defaults={
221
- 'is_active': True, 'role': role
222
- }
223
- )
224
- else:
225
- user = User.objects.filter(email=email).first()
226
-
227
- if not user:
228
- continue
229
-
230
- if user.name != options.get('name'):
231
- user.name = options['name']
232
- user.save()
233
- if user.ssh_key != options.get('ssh_key'):
234
- user.ssh_key = options['ssh_key']
235
- user.save()
236
-
237
- avatar_url = options.get('avatar_url')
238
- if avatar_url and user.avatar_url != avatar_url:
239
- resp = requests.get(avatar_url)
240
- user.avatar.save(
241
- os.path.basename(avatar_url), io.BytesIO(resp.content)
242
- )
243
- user.avatar_url = avatar_url
244
- user.avatar_last_change = timezone.now()
245
- user.save()
190
+ if weather_forecast:
191
+ from simo.generic.controllers import WeatherForecast
192
+ weather_component = Component.objects.filter(
193
+ zone__instance=instance,
194
+ controller_uid=WeatherForecast.uid
195
+ ).first()
196
+ if weather_component:
197
+ weather_component.track_history = False
198
+ weather_component.controller.set(weather_forecast)
199
+
200
+
201
+ for email, options in users_data.items():
202
+ with transaction.atomic():
203
+ if new_instance:
204
+ # Create users for new instance!
205
+ user, new_user = User.objects.update_or_create(
206
+ email=email, defaults={
207
+ 'name': options.get('name'),
208
+ 'is_master': options.get('is_hub_master', False),
209
+ 'ssh_key': options.get('ssh_key')
210
+ })
211
+ role = None
212
+ if options.get('is_superuser'):
213
+ role = PermissionsRole.objects.filter(
214
+ instance=new_instance, is_superuser=True
215
+ ).first()
216
+ elif options.get('is_owner'):
217
+ role = PermissionsRole.objects.filter(
218
+ instance=new_instance, is_owner=True
219
+ ).first()
220
+ InstanceUser.objects.update_or_create(
221
+ user=user, instance=new_instance, defaults={
222
+ 'is_active': True, 'role': role
223
+ }
224
+ )
225
+ else:
226
+ user = User.objects.filter(email=email).first()
227
+
228
+ if not user:
229
+ continue
230
+
231
+ if user.name != options.get('name'):
232
+ user.name = options['name']
233
+ user.save()
234
+ if user.ssh_key != options.get('ssh_key'):
235
+ user.ssh_key = options['ssh_key']
236
+ user.save()
237
+
238
+ avatar_url = options.get('avatar_url')
239
+ if avatar_url and user.avatar_url != avatar_url:
240
+ resp = requests.get(avatar_url)
241
+ user.avatar.save(
242
+ os.path.basename(avatar_url), io.BytesIO(resp.content)
243
+ )
244
+ user.avatar_url = avatar_url
245
+ user.avatar_last_change = timezone.now()
246
+ user.save()
246
247
 
247
248
 
248
249
  @celery_app.task
Binary file
simo/fleet/forms.py CHANGED
@@ -146,7 +146,7 @@ class ColonelComponentForm(BaseComponentForm):
146
146
  continue
147
147
  if pin_instances[i].colonel != self.cleaned_data['colonel']:
148
148
  formset_errors[i] = {
149
- 'pin': f"{pin_instances[i]} must be from the same Colonel!"
149
+ 'input': f"{pin_instances[i]} must be from the same Colonel!"
150
150
  }
151
151
  elif pin_instances[i].occupied_by \
152
152
  and pin_instances[i].occupied_by != self.instance:
@@ -51,7 +51,7 @@ def copy_template(to_directory='/etc/SIMO'):
51
51
  'base_dir': to_directory
52
52
  }, autoescape=False)
53
53
  template_dir = os.path.join(
54
- os.path.dirname(simo.__file__), '_hub_template'
54
+ os.path.dirname(simo.__file__), 'management', '_hub_template'
55
55
  )
56
56
  prefix_length = len(template_dir) + 1
57
57
  for root, dirs, files in os.walk(template_dir):
@@ -82,8 +82,16 @@ def copy_template(to_directory='/etc/SIMO'):
82
82
  else:
83
83
  os.makedirs(os.path.join(root, dirname), exist_ok=True)
84
84
 
85
+ manage_py_path = os.path.join(to_directory, 'hub', 'manage.py')
86
+ st = os.stat(manage_py_path)
87
+ os.chmod(manage_py_path, st.st_mode | 0o111)
88
+
85
89
 
86
90
  def install():
91
+ # this must be performed on a host machine before simo could be installed.
92
+ #
93
+ # apt install python3-pip libpq-dev python3-dev -y
94
+
87
95
  simo_directory = '/etc/SIMO'
88
96
  installed_flag_file_path = os.path.join(simo_directory, 'is_installed.json')
89
97
  HUB_DIR = os.path.join(simo_directory, 'hub')
@@ -166,6 +174,7 @@ def install():
166
174
  f'{simo_directory}/hub/supervisor.conf',
167
175
  '/etc/supervisor/conf.d/SIMO.conf'
168
176
  )
177
+ os.makedirs('/var/log/simo')
169
178
  status = subprocess.call(['supervisorctl', 'update', 'all'])
170
179
  if status != 0:
171
180
  sys.exit("INSTALLATION FAILED! Unable to start supervisord")
@@ -213,10 +222,10 @@ def install():
213
222
  with open('/etc/ssh/sshd_config', 'r') as ssh_conf:
214
223
  line = ssh_conf.readline()
215
224
  while line:
216
- if 'PasswordAuthentication' in line:
217
- new_ssh_conf += 'PasswordAuthentication no'
218
- else:
219
- new_ssh_conf += line
225
+ if line.startswith('PasswordAuthentication'):
226
+ line.replace(' yes', ' no')
227
+ new_ssh_conf += line
228
+
220
229
  line = ssh_conf.readline()
221
230
  with open('/etc/ssh/sshd_config', 'w') as ssh_conf:
222
231
  ssh_conf.write(new_ssh_conf)
@@ -263,17 +272,22 @@ def install():
263
272
  timeshift_conf['schedule_monthly'] = "true"
264
273
  timeshift_conf['schedule_weekly'] = "true"
265
274
  timeshift_conf['schedule_daily'] = "true"
275
+ timeshift_conf['exclude'] = []
266
276
 
267
- # Must be copied to /etc/timeshift.json to work
268
- with open('/etc/timeshift.json', 'w') as conf_f:
277
+ # Must be copied to /etc/timeshift/timeshift.json to work
278
+ with open('/etc/timeshift/timeshift.json', 'w') as conf_f:
269
279
  conf_f.write(json.dumps(timeshift_conf))
270
280
 
271
- status = subprocess.call([
272
- '/usr/bin/timeshift', '--create',
273
- '--comments', '"Initial backup"', '--tags', 'M'
274
- ])
275
- if status != 0:
276
- print("Unable to start TimeShift")
281
+ # status = subprocess.call([
282
+ # '/usr/bin/timeshift', '--create',
283
+ # '--comments', '"Initial backup"', '--tags', 'M'
284
+ # ])
285
+ # if status != 0:
286
+ # print("Unable to start TimeShift")
287
+
288
+
289
+ step += 1
290
+ print("%d.__________ PUT UP INSTALL COMPLETE FLAG! _____________________" % step)
277
291
 
278
292
  with open(installed_flag_file_path, 'w') as f:
279
293
  f.write(json.dumps(True))
@@ -284,4 +298,4 @@ def install():
284
298
 
285
299
 
286
300
  if __name__ == "__main__":
287
- sys.exit(init())
301
+ sys.exit(install())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.1.4
3
+ Version: 2.1.6
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
@@ -33,6 +33,7 @@ Requires-Dist: itsdangerous ==2.0.1
33
33
  Requires-Dist: redis ==3.5.3
34
34
  Requires-Dist: django-redis ==4.12.1
35
35
  Requires-Dist: webservices ==0.7
36
+ Requires-Dist: numpy ==1.24.4
36
37
  Requires-Dist: opencv-python ==4.5.4.60
37
38
  Requires-Dist: geopy ==2.2.0
38
39
  Requires-Dist: requests ==2.26.0
@@ -14,11 +14,11 @@ simo/__pycache__/urls.cpython-38.pyc,sha256=sqfstQthcjXtv31Tad0RAlWWI2A0HH6HN0fW
14
14
  simo/__pycache__/wsgi.cpython-38.pyc,sha256=TpRxO7VM_ql31hbKphVdanydC5RI1nHB4l0QA2pdWxo,322
15
15
  simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
16
16
  simo/core/admin.py,sha256=Gb1lSyvFtYj2oC5lA7j3VqU6zlqlncx5R-_XJbb8Wdk,17927
17
- simo/core/api.py,sha256=HSokv9CZCCr0WHSzo5TBXe2BF5-EnTZHPnShlzN86ms,25706
18
- simo/core/api_auth.py,sha256=_3hG4e1eLKrcRnSAOB_xTL6cwtOJ2_7JS7GZU_iqTgA,1251
17
+ simo/core/api.py,sha256=qx2hwBTeDmuVFL__gRS4ySZkl8aoHM_8R6F47tzME7w,27581
18
+ simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
19
19
  simo/core/api_meta.py,sha256=0leq4qdAELwACL7-9V_LCkuzu1VSEexys1b3iz0bsYM,3848
20
20
  simo/core/app_widgets.py,sha256=4Lh9FDzdkfh_mccJMe09dyRTT3Uqf9VXwbkurJ9E9oQ,2115
21
- simo/core/apps.py,sha256=CL4-BX6lYYGwq6hcXL-ozT7RTvy9hyfuiPCC_RfGIY0,267
21
+ simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
22
22
  simo/core/auto_urls.py,sha256=nNXEgLAAAQAhRWQDA9AbDtw-zcPKmu_pufJaSa8g818,1102
23
23
  simo/core/autocomplete_views.py,sha256=JT5LA2_Wtr60XYSAIqaXFKFYPjrmkEf6yunXD9y2zco,4022
24
24
  simo/core/base_types.py,sha256=qVh6MrXZEfN7bFOyFftC7u0yyz0PkvpsjllLBc6SCp4,616
@@ -36,11 +36,11 @@ simo/core/middleware.py,sha256=pO52hQOJV_JRmNyUe7zfufSnJFlRITOWX6jwkoPWJhk,2052
36
36
  simo/core/models.py,sha256=MaE6BUIJdXwrrlsGZRkrPSaOLY1OTWRCyjEoYArdAl8,20739
37
37
  simo/core/permissions.py,sha256=u89OubeV_NPMX87Mcireg6FhCs-XTuyYLIiL2HDaxg4,2815
38
38
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
39
- simo/core/serializers.py,sha256=M3r2P1-Eb5eObOqcI9dttedh4UxgPwWwGYmOfXe3BDk,20303
40
- simo/core/signal_receivers.py,sha256=ZhHg1mLn_Yhin-23Af1WNPfE5hnGYhhVDZDTEjRtO-A,6190
39
+ simo/core/serializers.py,sha256=wrOSMN1P3iBSLpHKB8EUyrK-TqRKltXM-tks_84hrNw,20335
40
+ simo/core/signal_receivers.py,sha256=9-qFCCeSLcMFEMg6QUtKOVgUsoNoqhzGoI98nuNSTEo,6228
41
41
  simo/core/socket_consumers.py,sha256=n7VE2Fvqt4iEAYLTRbTPOcI-7tszMAADu7gimBxB-Fg,9635
42
42
  simo/core/storage.py,sha256=YlxmdRs-zhShWtFKgpJ0qp2NDBuIkJGYC1OJzqkbttQ,572
43
- simo/core/tasks.py,sha256=VTr83_8avke6UwFZ9VQ8c2qROpVOqAWqc0RbMxNPd08,14005
43
+ simo/core/tasks.py,sha256=wlhesYdCKMm2rOvgXglmMB2WfEnH7m4uNsNHNVy6H0k,14304
44
44
  simo/core/todos.py,sha256=eYVXfLGiapkxKK57XuviSNe3WsUYyIWZ0hgQJk7ThKo,665
45
45
  simo/core/types.py,sha256=WJEq48mIbFi_5Alt4wxWMGXxNxUTXqfQU5koH7wqHHI,1108
46
46
  simo/core/views.py,sha256=ze8yX0PBLN-DH8B8jol6NKj0hLOAE4WA1rTXf07G-MU,2129
@@ -48,7 +48,7 @@ simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
48
48
  simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEtsMoedcOWnXjH-Y8o,208
49
49
  simo/core/__pycache__/admin.cpython-38.pyc,sha256=Lqs-wHz-vxGEo7ApOk6nkpNwfxselcFHqAUozotdZU4,13231
50
50
  simo/core/__pycache__/api.cpython-38.pyc,sha256=hoCs0HvJFULzhDG4mwhTMMJt3hSDnMXJU_05FPK6dB4,20516
51
- simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=5UTBr3rDMERAfc0OuOVDwGeQkt6Q7GLBtZJAMBse1sg,1712
51
+ simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=6M9Cl_ha4y_Vf8Rv4GMYL8dcBCmp0KzYi6jn3SQTgys,1712
52
52
  simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=Y59fGaKkyo_DJhhcDeRUUguy2OUb6f7_F6RbQRRp0vY,3023
53
53
  simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=vUCEAYqppjgRZYMs6pTuSxWWuZxreLygPuPBGw044dQ,3643
54
54
  simo/core/__pycache__/apps.cpython-38.pyc,sha256=S12d7zdc2m_93FeQ4gE6I3l_lh3GAe2Icf1Ra869Kzs,633
@@ -10186,7 +10186,7 @@ simo/fleet/auto_urls.py,sha256=UX66eR2ykMqFgfIllW-RTdjup5-FieCWl_BVm3CcXKg,702
10186
10186
  simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
10187
10187
  simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
10188
10188
  simo/fleet/controllers.py,sha256=ounEUw51X6EYA8xDcGNIik1bDbw4JR3DOGr1FKo4hHs,28829
10189
- simo/fleet/forms.py,sha256=fdq30tA4mx-34eLQnHV1O0XFe3offN-BKcXmltww01k,54423
10189
+ simo/fleet/forms.py,sha256=CbrLN_gMCTo8u6fg0ovztkhdYEjHZmSr_3gzsDRMP84,54425
10190
10190
  simo/fleet/gateways.py,sha256=lKEJW0MgaOEiNnijH50DNSVChvaUT3TA3UurcI57P8k,5677
10191
10191
  simo/fleet/managers.py,sha256=XOpDOA9L-f_550TNSyXnJbun2EmtGz1TenVTMlUSb8E,807
10192
10192
  simo/fleet/models.py,sha256=U4q813VZmYUpgu7Iw4-z80LfHlkZziIqBKqkQzBA9WI,16304
@@ -10203,7 +10203,7 @@ simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=Tc6a6BCXHjijP8U2jE2ghlJwn
10203
10203
  simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
10204
10204
  simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
10205
10205
  simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=61dvQDl2nIuB4iaCzdBMwQnly_m0OvI7zteRS6sIm5U,23831
10206
- simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=iC11rfQVEUhjqxIewYX5CoR4cqBXyNzbcmgzRk-TiKc,37436
10206
+ simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=7B6NZnY6yS8qrmv5zlTa07iUYmdv4nW7PTpOVfRn3OY,37436
10207
10207
  simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=0RKVn0ndreVKhsrukqeLPSdMnRrsQ_W7yeVeBkRLfIk,5058
10208
10208
  simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=8uz-xpUiqbGDgXIZ_XRZtFb-Tju6NGxflGg-Ee4Yo6k,1310
10209
10209
  simo/fleet/__pycache__/models.cpython-38.pyc,sha256=yudhmE7zhXN5t3b63N6TwAtBLC4OXiAZiNBzki3SuHI,13664
@@ -10337,7 +10337,7 @@ simo/generic/templates/generic/controllers_info/stateselect.md,sha256=T0w3vJg02W
10337
10337
  simo/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10338
10338
  simo/management/auto_update.py,sha256=4MDrJHdtC5LxEJM258Y0kc5yI4yloeKhDjh-S2BN-ZQ,2115
10339
10339
  simo/management/copy_template.py,sha256=Iehq57FYMzdHNp3LU4ue6rr6AkRiGeOthG7PoGWd88Q,2002
10340
- simo/management/install.py,sha256=IwSeullwXxATsL4cpLNmOgmVJASwLehopohp9Ua-064,9640
10340
+ simo/management/install.py,sha256=hy2LB0sPNpaFHv2Wvp6CeiItvKJb3sFVU0lJuz02VDM,10127
10341
10341
  simo/management/on_http_start.py,sha256=ZDotfMQaCjksD5FFf3eZYgJS-gd_-7eZhYTHLaD-448,3312
10342
10342
  simo/management/__pycache__/__init__.cpython-38.pyc,sha256=ey9k5mPsmvAHRVf5Du6QUqy40LgBCAPN_B5EaR6h9Eg,164
10343
10343
  simo/management/__pycache__/on_http_start.cpython-38.pyc,sha256=ERfcMNz3QnqDJTJ4PwbmDfLgPCh5hrEcaedejARFkUQ,2864
@@ -10494,9 +10494,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10494
10494
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10495
10495
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10496
10496
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10497
- simo-2.1.4.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10498
- simo-2.1.4.dist-info/METADATA,sha256=BV3GcDw-Fy6Wx4aVwZIwJ6vS_Qwea0cVZbGor3xjYiE,1817
10499
- simo-2.1.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
10500
- simo-2.1.4.dist-info/entry_points.txt,sha256=SJBxiDpH7noO0STxVI_eRIsGR-nLgdXXeqCDe8cXlbM,65
10501
- simo-2.1.4.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10502
- simo-2.1.4.dist-info/RECORD,,
10497
+ simo-2.1.6.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10498
+ simo-2.1.6.dist-info/METADATA,sha256=0v_e39Aa9o7fBTvk4ee7urOjd86tTljt6QQxgIhOLdA,1847
10499
+ simo-2.1.6.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
10500
+ simo-2.1.6.dist-info/entry_points.txt,sha256=SJBxiDpH7noO0STxVI_eRIsGR-nLgdXXeqCDe8cXlbM,65
10501
+ simo-2.1.6.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10502
+ simo-2.1.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5