simo 2.5.12__py3-none-any.whl → 2.5.14__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 (33) hide show
  1. simo/core/__pycache__/api.cpython-38.pyc +0 -0
  2. simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
  3. simo/core/__pycache__/models.cpython-38.pyc +0 -0
  4. simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
  5. simo/core/__pycache__/signal_receivers.cpython-38.pyc +0 -0
  6. simo/core/__pycache__/tasks.cpython-38.pyc +0 -0
  7. simo/core/api.py +5 -5
  8. simo/core/management/_hub_template/hub/supervisor.conf +1 -0
  9. simo/core/models.py +4 -2
  10. simo/core/serializers.py +3 -2
  11. simo/core/signal_receivers.py +4 -4
  12. simo/core/tasks.py +79 -81
  13. simo/generic/__pycache__/app_widgets.cpython-38.pyc +0 -0
  14. simo/generic/__pycache__/base_types.cpython-38.pyc +0 -0
  15. simo/generic/__pycache__/controllers.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/app_widgets.py +3 -3
  19. simo/generic/base_types.py +1 -1
  20. simo/generic/controllers.py +9 -9
  21. simo/generic/forms.py +9 -9
  22. simo/generic/gateways.py +4 -2
  23. simo/generic/migrations/0001_initial.py +29 -0
  24. simo/generic/migrations/__init__.py +0 -0
  25. simo/generic/migrations/__pycache__/0001_initial.cpython-38.pyc +0 -0
  26. simo/generic/migrations/__pycache__/__init__.cpython-38.pyc +0 -0
  27. simo/generic/templates/admin/controller_widgets/{weather_forecast.html → weather.html} +1 -1
  28. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/METADATA +1 -1
  29. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/RECORD +33 -29
  30. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/LICENSE.md +0 -0
  31. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/WHEEL +0 -0
  32. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/entry_points.txt +0 -0
  33. {simo-2.5.12.dist-info → simo-2.5.14.dist-info}/top_level.txt +0 -0
Binary file
Binary file
Binary file
simo/core/api.py CHANGED
@@ -151,13 +151,13 @@ def get_components_queryset(instance, user):
151
151
 
152
152
  c_ids = set()
153
153
 
154
- from simo.generic.controllers import WeatherForecast
154
+ from simo.generic.controllers import Weather
155
155
 
156
156
  if instance.indoor_climate_sensor:
157
157
  c_ids.add(instance.indoor_climate_sensor.id)
158
158
  wf_c = Component.objects.filter(
159
159
  zone__instance=instance,
160
- controller_uid=WeatherForecast.uid, config__is_main=True
160
+ controller_uid=Weather.uid, config__is_main=True
161
161
  ).values('id').first()
162
162
  if wf_c:
163
163
  c_ids.add(wf_c['id'])
@@ -532,12 +532,12 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
532
532
  if last_history_event:
533
533
  last_event = last_history_event.date.timestamp()
534
534
 
535
- from simo.generic.controllers import WeatherForecast
535
+ from simo.generic.controllers import Weather
536
536
 
537
537
  wf_comp_id = None
538
538
  wf_c = Component.objects.filter(
539
539
  zone__instance=self.instance,
540
- controller_uid=WeatherForecast.uid, config__is_main=True
540
+ controller_uid=Weather.uid, config__is_main=True
541
541
  ).first()
542
542
  if wf_c:
543
543
  wf_comp_id = wf_c.id
@@ -566,7 +566,7 @@ class SettingsViewSet(InstanceMixin, viewsets.GenericViewSet):
566
566
  'timezone': self.instance.timezone,
567
567
  'location': self.instance.location,
568
568
  'last_event': last_event,
569
- 'weather_forecast': wf_comp_id,
569
+ 'weather': wf_comp_id,
570
570
  'main_alarm_group': main_alarm_group_id,
571
571
  'main_state': main_state,
572
572
  # TODO: Remove these two when the app is updated for everybody.
@@ -60,6 +60,7 @@ autostart=true
60
60
  autorestart=true
61
61
  stopwaitsecs=15
62
62
  killasgroup=true
63
+ stopsignal=INT
63
64
 
64
65
 
65
66
  [program:simo-celery-beat]
simo/core/models.py CHANGED
@@ -530,7 +530,6 @@ def is_in_alarm(self):
530
530
  and 'last_change' not in kwargs['update_fields']:
531
531
  kwargs['update_fields'].append('last_change')
532
532
 
533
-
534
533
  modifying_fields = (
535
534
  'name', 'icon', 'zone', 'category', 'config', 'meta',
536
535
  'value_units', 'slaves', 'show_in_app', 'alarm_category'
@@ -539,7 +538,10 @@ def is_in_alarm(self):
539
538
  self.last_modified = timezone.now()
540
539
  if 'update_fields' in kwargs \
541
540
  and 'last_modified' not in kwargs['update_fields']:
542
- kwargs['update_fields'].append('last_modified')
541
+ if isinstance(kwargs['update_fields'], tuple):
542
+ kwargs['update_fields'] += ('last_modified', )
543
+ else:
544
+ kwargs['update_fields'].append('last_modified')
543
545
 
544
546
  obj = super().save(*args, **kwargs)
545
547
 
simo/core/serializers.py CHANGED
@@ -106,7 +106,6 @@ class TextAreaSerializerField(serializers.CharField):
106
106
  class ComponentPrimaryKeyRelatedField(PrimaryKeyRelatedField):
107
107
 
108
108
  def get_attribute(self, instance):
109
- print(f"{instance} SOURCE ATTRIBUTES: ", self.source_attrs)
110
109
  if self.queryset.model in (Icon, Zone, Category):
111
110
  return super().get_attribute(instance)
112
111
  return self.queryset.model.objects.filter(
@@ -445,7 +444,9 @@ class ComponentSerializer(FormSerializer):
445
444
  continue
446
445
  if field_name in form.basic_fields:
447
446
  continue
448
- if self.context['request'].user.is_master or user_role.is_superuser:
447
+ if self.context['request'].user.is_master:
448
+ continue
449
+ if user_role and user_role.is_superuser:
449
450
  continue
450
451
  del form.fields[field_name]
451
452
 
@@ -82,8 +82,8 @@ def create_instance_defaults(sender, instance, created, **kwargs):
82
82
  name='Weather', icon=weather_icon,
83
83
  zone=other_zone,
84
84
  category=climate_category,
85
- gateway=generic, base_type='weather-forecast',
86
- controller_uid='simo.generic.controllers.WeatherForecast',
85
+ gateway=generic, base_type='weather',
86
+ controller_uid='simo.generic.controllers.Weather',
87
87
  config={'is_main': True}
88
88
  )
89
89
 
@@ -147,13 +147,13 @@ Sets State component to "day" state as soon as none of the home owners phones ar
147
147
  # Create default User permission roles
148
148
 
149
149
  PermissionsRole.objects.create(
150
- instance=instance, name="Admin", is_superuser=True
150
+ instance=instance, name="Admin", is_owner=True, is_superuser=True
151
151
  )
152
152
  PermissionsRole.objects.create(
153
153
  instance=instance, name="Owner", is_owner=True, is_default=True
154
154
  )
155
155
  PermissionsRole.objects.create(
156
- instance=instance, name="Guest", is_owner=True
156
+ instance=instance, name="Guest", is_owner=False
157
157
  )
158
158
  generic.start()
159
159
  dummy.start()
simo/core/tasks.py CHANGED
@@ -178,88 +178,86 @@ def sync_with_remote():
178
178
 
179
179
  print("Responded with: ", json.dumps(r_json))
180
180
 
181
- with transaction.atomic():
182
- if 'hub_uid' in r_json:
183
- dynamic_settings['core__hub_uid'] = r_json['hub_uid']
184
-
185
- dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
186
- if 'new_secret' in r_json:
187
- dynamic_settings['core__hub_secret'] = r_json['new_secret']
188
-
189
- if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
190
- save_config(r_json)
191
- dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
192
-
193
- instance_uids = []
194
- for data in r_json['instances']:
195
- users_data = data.pop('users', {})
196
- instance_uid = data.pop('uid')
197
- instance_uids.append(instance_uid)
198
- weather_forecast = data.pop('weather_forecast', None)
199
- instance, new_instance = Instance.objects.update_or_create(
200
- uid=instance_uid, defaults=data
201
- )
202
- if not instance.is_active:
203
- instance.is_active = True
204
- instance.save()
205
-
206
- if weather_forecast:
207
- from simo.generic.controllers import WeatherForecast
208
- weather_component = Component.objects.filter(
209
- zone__instance=instance,
210
- controller_uid=WeatherForecast.uid
211
- ).first()
212
- if weather_component:
213
- weather_component.track_history = False
214
- weather_component.controller.set(
215
- weather_forecast.pop('current', None)
216
- )
217
- weather_component.meta['forecast'] = weather_forecast
218
- weather_component.save()
219
-
220
- for email, options in users_data.items():
221
-
222
- if new_instance or not instance.instance_users.count():
223
- # Create user for new instance!
224
- user, new_user = User.objects.update_or_create(
225
- email=email, defaults={
226
- 'name': options.get('name'),
227
- 'is_master': options.get('is_hub_master', False),
228
- })
229
- role = None
230
- if options.get('is_hub_master') or options.get('is_superuser'):
231
- role = PermissionsRole.objects.filter(
232
- instance=instance, is_superuser=True
233
- ).first()
234
- elif options.get('is_owner'):
235
- role = PermissionsRole.objects.filter(
236
- instance=instance, is_owner=True
237
- ).first()
238
- if role:
239
- InstanceUser.objects.update_or_create(
240
- user=user, instance=instance, defaults={
241
- 'is_active': True, 'role': role
242
- }
243
- )
244
- else:
245
- user = User.objects.filter(email=email).first()
246
-
247
- if not user:
248
- continue
249
-
250
- if user.name != options.get('name'):
251
- user.name = options['name']
252
- user.save()
253
-
254
- avatar_url = options.get('avatar_url')
255
- if avatar_url and user.avatar_url != avatar_url:
256
- resp = requests.get(avatar_url)
257
- user.avatar.save(
258
- os.path.basename(avatar_url), io.BytesIO(resp.content)
181
+
182
+ if 'hub_uid' in r_json:
183
+ dynamic_settings['core__hub_uid'] = r_json['hub_uid']
184
+
185
+ dynamic_settings['core__remote_http'] = r_json.get('hub_remote_http', '')
186
+ if 'new_secret' in r_json:
187
+ dynamic_settings['core__hub_secret'] = r_json['new_secret']
188
+
189
+ if dynamic_settings['core__remote_conn_version'] < r_json['remote_conn_version']:
190
+ save_config(r_json)
191
+ dynamic_settings['core__remote_conn_version'] = r_json['remote_conn_version']
192
+
193
+ instance_uids = []
194
+ for data in r_json['instances']:
195
+ users_data = data.pop('users', {})
196
+ instance_uid = data.pop('uid')
197
+ instance_uids.append(instance_uid)
198
+ weather = data.pop('weather', None)
199
+ instance, new_instance = Instance.objects.update_or_create(
200
+ uid=instance_uid, defaults=data
201
+ )
202
+ if not instance.is_active:
203
+ instance.is_active = True
204
+ instance.save()
205
+
206
+ if weather:
207
+ from simo.generic.controllers import Weather
208
+ weather_component = Component.objects.filter(
209
+ zone__instance=instance,
210
+ controller_uid=Weather.uid
211
+ ).first()
212
+ if weather_component:
213
+ weather_component.track_history = False
214
+ weather_component.controller.set(weather)
215
+ weather_component.save()
216
+
217
+ for email, options in users_data.items():
218
+
219
+ if new_instance or not instance.instance_users.count():
220
+ # Create user for new instance!
221
+ user, new_user = User.objects.get_or_create(
222
+ email=email, defaults={
223
+ 'name': options.get('name'),
224
+ 'is_master': options.get('is_hub_master', False),
225
+ })
226
+ role = None
227
+ if options.get('is_hub_master') or options.get('is_superuser'):
228
+ role = PermissionsRole.objects.filter(
229
+ instance=instance, is_superuser=True
230
+ ).first()
231
+ elif options.get('is_owner'):
232
+ role = PermissionsRole.objects.filter(
233
+ instance=instance, is_owner=True
234
+ ).first()
235
+
236
+ if role:
237
+ InstanceUser.objects.update_or_create(
238
+ user=user, instance=instance, defaults={
239
+ 'is_active': True, 'role': role
240
+ }
259
241
  )
260
- user.avatar_url = avatar_url
261
- user.avatar_last_change = timezone.now()
262
- user.save()
242
+ else:
243
+ user = User.objects.filter(email=email).first()
244
+
245
+ if not user:
246
+ continue
247
+
248
+ if user.name != options.get('name'):
249
+ user.name = options['name']
250
+ user.save()
251
+
252
+ avatar_url = options.get('avatar_url')
253
+ if avatar_url and user.avatar_url != avatar_url:
254
+ resp = requests.get(avatar_url)
255
+ user.avatar.save(
256
+ os.path.basename(avatar_url), io.BytesIO(resp.content)
257
+ )
258
+ user.avatar_url = avatar_url
259
+ user.avatar_last_change = timezone.now()
260
+ user.save()
263
261
 
264
262
  Instance.objects.all().exclude(
265
263
  uid__in=instance_uids
@@ -32,9 +32,9 @@ class IPCameraWidget(BaseAppWidget):
32
32
  size = [2, 2]
33
33
 
34
34
 
35
- class WeatherForecastWidget(BaseAppWidget):
36
- uid = 'weather-forecast'
37
- name = _("Weather Forecast")
35
+ class WeatherWidget(BaseAppWidget):
36
+ uid = 'weather'
37
+ name = _("Weather")
38
38
  size = [4, 2]
39
39
 
40
40
 
@@ -5,7 +5,7 @@ BASE_TYPES = {
5
5
  'thermostat': _("Thermostat"),
6
6
  'alarm-group': _("Alarm Group"),
7
7
  'ip-camera': _("IP Camera"),
8
- 'weather-forecast': _("Weather Forecast"),
8
+ 'weather': _("Weather"),
9
9
  'watering': _("Watering"),
10
10
  'state-select': _("State Select"),
11
11
  'alarm-clock': _("Alarm Clock"),
@@ -38,13 +38,13 @@ from simo.core.utils.config_values import (
38
38
  from .gateways import GenericGatewayHandler, DummyGatewayHandler
39
39
  from .app_widgets import (
40
40
  ScriptWidget, ThermostatWidget, AlarmGroupWidget, IPCameraWidget,
41
- WeatherForecastWidget,
42
- WateringWidget, StateSelectWidget, AlarmClockWidget
41
+ WateringWidget, StateSelectWidget, AlarmClockWidget,
42
+ WeatherWidget
43
43
  )
44
44
  from .forms import (
45
45
  ScriptConfigForm, PresenceLightingConfigForm,
46
46
  ThermostatConfigForm, AlarmGroupConfigForm,
47
- IPCameraConfigForm, WeatherForecastForm,
47
+ IPCameraConfigForm, WeatherForm,
48
48
  WateringConfigForm, StateSelectForm,
49
49
  AlarmClockConfigForm
50
50
  )
@@ -527,13 +527,13 @@ class AlarmGroup(ControllerBase):
527
527
  return map
528
528
 
529
529
 
530
- class WeatherForecast(ControllerBase):
531
- name = _("Weather Forecast")
532
- base_type = 'weather-forecast'
530
+ class Weather(ControllerBase):
531
+ name = _("Weather")
532
+ base_type = 'weather'
533
533
  gateway_class = GenericGatewayHandler
534
- config_form = WeatherForecastForm
535
- app_widget = WeatherForecastWidget
536
- admin_widget_template = 'admin/controller_widgets/weather_forecast.html'
534
+ config_form = WeatherForm
535
+ app_widget = WeatherWidget
536
+ admin_widget_template = 'admin/controller_widgets/weather.html'
537
537
  default_config = {}
538
538
  default_value = {}
539
539
 
simo/generic/forms.py CHANGED
@@ -544,24 +544,24 @@ class IPCameraConfigForm(BaseComponentForm):
544
544
 
545
545
  )
546
546
 
547
- class WeatherForecastForm(BaseComponentForm):
547
+ class WeatherForm(BaseComponentForm):
548
548
  is_main = forms.BooleanField(
549
549
  required=False,
550
- help_text="Defines if this is your main/top global weather forecast."
550
+ help_text="Defines if this is your main/top global weather."
551
551
  )
552
552
 
553
553
  def __init__(self, *args, **kwargs):
554
554
  super().__init__(*args, **kwargs)
555
- from .controllers import WeatherForecast
555
+ from .controllers import Weather
556
556
  if not self.instance.pk:
557
- first_weather_forecast = bool(
557
+ first_weather = bool(
558
558
  not Component.objects.filter(
559
- controller_uid=WeatherForecast.uid,
559
+ controller_uid=Weather.uid,
560
560
  config__is_main=True
561
561
  ).count()
562
562
  )
563
- self.fields['is_main'].initial = first_weather_forecast
564
- if first_weather_forecast:
563
+ self.fields['is_main'].initial = first_weather
564
+ if first_weather:
565
565
  self.fields['is_main'].widget.attrs['disabled'] = 'disabled'
566
566
  else:
567
567
  if self.instance.config.get('is_main'):
@@ -570,14 +570,14 @@ class WeatherForecastForm(BaseComponentForm):
570
570
 
571
571
  def save(self, *args, **kwargs):
572
572
  self.instance.value_units = 'status'
573
- from .controllers import WeatherForecast
573
+ from .controllers import Weather
574
574
  if 'is_main' in self.fields and 'is_main' in self.cleaned_data:
575
575
  if self.fields['is_main'].widget.attrs.get('disabled'):
576
576
  self.cleaned_data['is_main'] = self.fields['is_main'].initial
577
577
  obj = super().save(*args, **kwargs)
578
578
  if obj.config.get('is_main'):
579
579
  for c in Component.objects.filter(
580
- controller_uid=WeatherForecast.uid,
580
+ controller_uid=Weather.uid,
581
581
  config__is_main=True
582
582
  ).exclude(pk=obj.pk):
583
583
  c.config['is_main'] = False
simo/generic/gateways.py CHANGED
@@ -246,8 +246,10 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
246
246
  Component.objects.get(id=id), 'error'
247
247
  )
248
248
 
249
- while len(script_ids):
250
- time.sleep(0.1)
249
+ time.sleep(0.5)
250
+ while len(self.running_scripts.keys()):
251
+ print("Still running scripts: ", self.running_scripts.keys())
252
+ time.sleep(0.5)
251
253
 
252
254
  def on_mqtt_connect(self, mqtt_client, userdata, flags, rc):
253
255
  command = GatewayObjectCommand(self.gateway_instance)
@@ -0,0 +1,29 @@
1
+ # Generated by Django 4.2.10 on 2024-11-05 07:52
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ def forwards_func(apps, schema_editor):
7
+
8
+ Component = apps.get_model("core", "Component")
9
+
10
+ Component.objects.filter(
11
+ controller_uid='simo.generic.controllers.WeatherForecast'
12
+ ).update(
13
+ controller_uid='simo.generic.controllers.Weather', base_type='weather'
14
+ )
15
+
16
+
17
+ def reverse_func(apps, schema_editor):
18
+ pass
19
+
20
+
21
+ class Migration(migrations.Migration):
22
+
23
+ dependencies = [
24
+ ('core', '0043_alter_category_instance_alter_instance_timezone_and_more'),
25
+ ]
26
+
27
+ operations = [
28
+ migrations.RunPython(forwards_func, reverse_func, elidable=True),
29
+ ]
File without changes
@@ -9,5 +9,5 @@
9
9
  position: relative;
10
10
  bottom: -4px;
11
11
  "></span>
12
- {{ obj.value.temp }}ᴼ {% if obj.zone.instance.units_of_measure == 'metric' %}C{% else %}F{% endif %}
12
+ {{ obj.value.main.temp }}ᴼ {% if obj.zone.instance.units_of_measure == 'metric' %}C{% else %}F{% endif %}
13
13
  </div>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simo
3
- Version: 2.5.12
3
+ Version: 2.5.14
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,7 +33,7 @@ simo/backups/migrations/__pycache__/0004_alter_backup_options_alter_backuplog_op
33
33
  simo/backups/migrations/__pycache__/__init__.cpython-38.pyc,sha256=Lz1fs6V05h2AoxTOLNye0do9bEMnyuaXB_hHOjG5-HU,172
34
34
  simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
35
35
  simo/core/admin.py,sha256=5mi0Qe9TM-OILCxbcRfGJvq397QCPxjYX30K3CIZrPs,18133
36
- simo/core/api.py,sha256=KIy7mpNbMWKtNPrcnbzeHXmPRboF5RPxmi_NssJXkQk,28317
36
+ simo/core/api.py,sha256=id8RCZ7r9IKqpcV6ajqF87k9yKqcFmSc8YfWIP99tQE,28276
37
37
  simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
38
38
  simo/core/api_meta.py,sha256=EaiY-dCADP__9MvLpoHvhjytFT92IrxPZDv95xgqasU,4955
39
39
  simo/core/app_widgets.py,sha256=VxZzapuc-a29wBH7JzpvNF2SK1ECrgNUySId5ke1ffc,2509
@@ -52,21 +52,21 @@ simo/core/gateways.py,sha256=m0eS3XjVe34Dge6xtoCq16kFWCKJcdQrT0JW0REqoq8,3715
52
52
  simo/core/loggers.py,sha256=EBdq23gTQScVfQVH-xeP90-wII2DQFDjoROAW6ggUP4,1645
53
53
  simo/core/managers.py,sha256=n-b3I4uXzfHKTeB1VMjSaMsDUxp8FegFJwnbV1IsWQ4,3019
54
54
  simo/core/middleware.py,sha256=hExD7Vmw7eitk0vAjOwKzkwrtuw8YxpflF92j_CA2YY,3193
55
- simo/core/models.py,sha256=Z6WLvU4K-LWIXghCBwTyZAOW5n2hCFNU-pteiPnpOAQ,22617
55
+ simo/core/models.py,sha256=DXJXTtNdpn9yC4VArHp0yrhpRb7vGpwH2c-JvqLE56M,22784
56
56
  simo/core/permissions.py,sha256=v0iJM4LOeYoEfMiw3OLPYio272G1aUEAg_z9Wd1q5m0,2993
57
57
  simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
58
- simo/core/serializers.py,sha256=HaX5F_wxg_7nX0XMVnfbTsnocFaRTXUPDAkShaTxP4s,21843
59
- simo/core/signal_receivers.py,sha256=qCpzEUv5Bl9--K8fe08GVDmE6EBOj292YBia1TYDdSE,9267
58
+ simo/core/serializers.py,sha256=aoPeHcUi8v0YgEYkTFQr2Nu2lW0Gk3sG8RC2sDPNR00,21827
59
+ simo/core/signal_receivers.py,sha256=-Lw2Jzvgiznw3wj44ntL9nv3DtT8RCEpz6Tap9ZHEQk,9266
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=8n0zw6p2P2dJhR2SovIYsP8HMd1jjs_bgXOOkYqRvNI,15642
62
+ simo/core/tasks.py,sha256=EF_wDWeCZDA68xtexPURqJaBwbCP48bxdURWgcOLWjE,15141
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
66
66
  simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
67
67
  simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEtsMoedcOWnXjH-Y8o,208
68
68
  simo/core/__pycache__/admin.cpython-38.pyc,sha256=uM58xiBAbbstmKZ0CoxLSk_RRu5TDVuHJNOveXUhFqM,13723
69
- simo/core/__pycache__/api.cpython-38.pyc,sha256=8vfLeuJIPaWeQXIghIEGbNwKJtK_0ZTcPexKlEbig0A,21868
69
+ simo/core/__pycache__/api.cpython-38.pyc,sha256=z5IT2AoH_Y7iXJELeGlgaxJ2RNe-Wwk8YIt_rJcOGMw,21851
70
70
  simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=6M9Cl_ha4y_Vf8Rv4GMYL8dcBCmp0KzYi6jn3SQTgys,1712
71
71
  simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=VYx5ZeDyNBI4B_CBEIhV5B3GnLsMOx9s3rNZTSMODco,3703
72
72
  simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=oN657XMMZ6GYN9nblv7fX3kdnTEzSP9XV6PXM6Z0wl4,4358
@@ -75,7 +75,7 @@ simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=Tyf8PYHq5YqSwTp25Joy-eura_
75
75
  simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=wDak1gJYUF5oXSlDz1Dtn-Rhy5CxYEY-v1sPkJhQDpk,4128
76
76
  simo/core/__pycache__/base_types.cpython-38.pyc,sha256=CX-qlF7CefRi_mCE954wYa9rUFR88mOl6g7fybDRu7g,803
77
77
  simo/core/__pycache__/context.cpython-38.pyc,sha256=ck1FcBljLB4__5F6poS2tEEn8IDDgK7pU3FcXDPc_mI,1329
78
- simo/core/__pycache__/controllers.cpython-38.pyc,sha256=s7onEMtWmHjvTGvWXIbpvWMWb7aAfOVhFhWuu49kLSg,30701
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
80
  simo/core/__pycache__/events.cpython-38.pyc,sha256=yip7WSyX4pUy2wJE820W4fD7iwoIWGhdHfloFb_N0R8,5257
81
81
  simo/core/__pycache__/filters.cpython-38.pyc,sha256=VIMADCBiYhziIyRmxAyUDJluZvuZmiC4bNYWTRsGSao,721
@@ -85,14 +85,14 @@ simo/core/__pycache__/gateways.cpython-38.pyc,sha256=D1ooHL-iSpQrxnD8uAl4xWFJmm-
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
87
  simo/core/__pycache__/middleware.cpython-38.pyc,sha256=iOSTXSQl3sEsa-9kx_6w5zbEByRtfzJHT6XkUIYMGdE,2469
88
- simo/core/__pycache__/models.cpython-38.pyc,sha256=Nw2Fb11EwBdMVTHCpzkY6x0hRNCqRo0RtLNlRxS1VZE,18534
88
+ simo/core/__pycache__/models.cpython-38.pyc,sha256=HGL3TiaMy-0oobgCGGxH2nvDhh4RnOBeD00rwQsuklU,18591
89
89
  simo/core/__pycache__/permissions.cpython-38.pyc,sha256=fH4iyqd9DdzRLEu2b621-FeM-napR0M7hzBUTHo9Q3g,2972
90
90
  simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
91
- simo/core/__pycache__/serializers.cpython-38.pyc,sha256=o8vSdZC2mqKRAMJRpKXade-Jp0g4X6PmilOulvZ92Rk,19625
92
- simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=lBVca6zNPVn3Ev98ekjPGzBR1MJk4xI19CyMcm4lf6A,7056
91
+ simo/core/__pycache__/serializers.cpython-38.pyc,sha256=AX-5qAXYDjny1-ZHf3Ow7Ri20pmGV2dwo6n1g_Nzb30,19592
92
+ simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=h6MWIU7U2tNCIp0NiKSEDuFeaxLHYz1OXehzBxAYrYA,7048
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=5Nc_A5eOn3X_ZeC1OyZP1PFzXDgaV4ihmqz9eQbirpQ,10479
95
+ simo/core/__pycache__/tasks.cpython-38.pyc,sha256=DKhn-7oFN4EINROUgsXj4ihlaS93O1xDGqgxZ7PkFuo,10391
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
@@ -153,7 +153,7 @@ simo/core/management/_hub_template/hub/celeryc.py,sha256=3ksDXftIZKJ4Cq9WNKJERdZ
153
153
  simo/core/management/_hub_template/hub/manage.py,sha256=PNNlw3EVeIJDgkG0l-klqoxsKWfTYWG9jzRG0upmAaI,620
154
154
  simo/core/management/_hub_template/hub/nginx.conf,sha256=40hvXL42MeiqqkLURNcDQsRudv1dNFLJnvb2-Y3RCkk,2394
155
155
  simo/core/management/_hub_template/hub/settings.py,sha256=4QhvhbtLRxHvAntwqG_qeAAtpDUqKvN4jzw9u3vqff8,361
156
- simo/core/management/_hub_template/hub/supervisor.conf,sha256=7oqtr3p8rUervmwdfMNdscpPPCTLCFgrn2W_ak7g0yk,2362
156
+ simo/core/management/_hub_template/hub/supervisor.conf,sha256=sfeitUI6V4MgPDtfj-6AEQSTS_VNvLUdwNYNdSI1zRI,2377
157
157
  simo/core/management/_hub_template/hub/urls.py,sha256=Ydm-1BkYAzWeEF-MKSDIFf-7aE4qNLPm48-SA51XgJQ,25
158
158
  simo/core/management/_hub_template/hub/wsgi.py,sha256=Lo-huLHnMDTxSmMBOodVFMWBls9poddrV2KRzXU0xGo,280
159
159
  simo/core/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -10338,23 +10338,27 @@ simo/fleet/migrations/__pycache__/__init__.cpython-38.pyc,sha256=5k1KW0jeSDzw6Rn
10338
10338
  simo/fleet/templates/fleet/controllers_info/Button.md,sha256=GIuxqG617174NEtpPeCGVocxO4YMe7-CacgVSu_L5-E,739
10339
10339
  simo/fleet/templates/fleet/controllers_info/ENS160AirQualitySensor.md,sha256=3LSTY9YPFuVPIbVsYCAifcotrXJcOXl2k774_vo6nAE,770
10340
10340
  simo/generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10341
- simo/generic/app_widgets.py,sha256=vwYYVRKzKZ9XTvWTfEbaH4zpoHiDIHP6qFTNgZI-xvY,979
10342
- simo/generic/base_types.py,sha256=Bvf3lv6PXx_SwtwBH7qpkwysWuloNcKNRh3LiuZf-Dc,359
10343
- simo/generic/controllers.py,sha256=kGYdcuU7kpbhb6QeuOo4l-W82Zldh8vpdMnJRMKCkgU,49378
10344
- simo/generic/forms.py,sha256=vXQ7bQV4SmYx5hbCIZFvCYZ3rJJfx4SpDJgNy8sCioE,29069
10345
- simo/generic/gateways.py,sha256=dUzRBxVDdsx70mrCvxSQwhJr0ydQ5NtoLHoYeVLJmtA,15224
10341
+ simo/generic/app_widgets.py,sha256=TPRLj4hri2hBuY6mrdwBiv-01z2hDxZmsup-GDD9LrM,953
10342
+ simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
10343
+ simo/generic/controllers.py,sha256=Qf54CAeD8DviMV_S19E-7f-w-94Vr90-8xasy-IfG_A,49311
10344
+ simo/generic/forms.py,sha256=H841-wbWltnZ2-RXQEM1G8H4kfOcl88Qhg7bxE4VCiQ,28993
10345
+ simo/generic/gateways.py,sha256=sMedpxIfpxqTx746DdhsIu-pzTrqduOSIb7i7XDX9GU,15339
10346
10346
  simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
10347
10347
  simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
10348
10348
  simo/generic/socket_consumers.py,sha256=K2OjphIhKJH48BvfFfoCOyCQZ1NmXb_phs6y1IP-qaQ,1757
10349
10349
  simo/generic/__pycache__/__init__.cpython-38.pyc,sha256=mLu54WS9KIl-pHwVCBKpsDFIlOqml--JsOVzAUHg6cU,161
10350
- simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=dt7fSf38eDA5hVUvVfpytOKoAFLQJuFffoAfqhJUKNc,1846
10351
- simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=8YDxrsRFGqaeBfSF3Y1WmIGDRHGH1Ww7dSBkxRxkKyc,511
10352
- simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=DsxStuB6A2NhZOqx2tcgMisR4Y2Tkkr30PAU45DHiok,32819
10353
- simo/generic/__pycache__/forms.cpython-38.pyc,sha256=OtzGDat6Zg7SlVVub0RIsR-vJTonL8pJqxzI1TrBXcs,21278
10354
- simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=IazhRBe-YZ9t7_wq1fULoyLnxn3frR967lAN9D7MbKY,11583
10350
+ simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=YZ5db6-FPynBi6ooPW5crK9lZ6ymRh2DlGN6FwxfX4M,1820
10351
+ simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
10352
+ simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=EwtavDlVJX0b6taQ0moYk11oL9nZL5_esoCXGdtcNNo,32751
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
10355
  simo/generic/__pycache__/models.cpython-38.pyc,sha256=MZpum7syAFxuulf47K7gtUlJJ7xRD-IBUBAwUM1ZRnw,5825
10356
10356
  simo/generic/__pycache__/routing.cpython-38.pyc,sha256=xtxTUTBTdivzFyA5Wh7k-hUj1WDO_FiRq6HYXdbr9Ks,382
10357
10357
  simo/generic/__pycache__/socket_consumers.cpython-38.pyc,sha256=qJO5kvQLWhsQDOr1AtAtsAybuRWioxSkQei3Pc7rdP0,1737
10358
+ simo/generic/migrations/0001_initial.py,sha256=7FpPcfpRU5ya0b8s2KbxR5a3npf92YruvZltUybjzys,676
10359
+ simo/generic/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10360
+ simo/generic/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=xy_fN8vnebC_X8hArqHAOLYHLm3puD_stzJ-LvUOhgk,1009
10361
+ simo/generic/migrations/__pycache__/__init__.cpython-38.pyc,sha256=nJV0NkIT8MuONj1hUX-V6aCU2lX3BXHyPjisapnBsPA,172
10358
10362
  simo/generic/scripting/__init__.py,sha256=aZZvNBae7unnux_zGHCIWCV2z47hVJc-DIL72Hqfkeo,600
10359
10363
  simo/generic/scripting/example.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10360
10364
  simo/generic/scripting/helpers.py,sha256=Zt8Mx5AXIggzYk0e7jn-xQNR_NOqzolAReLkrmDJzVQ,3042
@@ -10385,7 +10389,7 @@ simo/generic/templates/admin/controller_widgets/gate.html,sha256=rqtgEQTmyK8Q66o
10385
10389
  simo/generic/templates/admin/controller_widgets/ip_camera.html,sha256=ZmWm21EswkgT6XR9x1GgzDIkSU2j_GpdOTfbPINg6jY,657
10386
10390
  simo/generic/templates/admin/controller_widgets/script.html,sha256=biUEMo5V35wqSrM97d5WqNDi47GNaDpi53I3YBfDLOs,1484
10387
10391
  simo/generic/templates/admin/controller_widgets/thermostat.html,sha256=iH7j631AY6ahsI7dTMyMYHL_EuX6Q_aRxQgQcPIVxvI,288
10388
- simo/generic/templates/admin/controller_widgets/weather_forecast.html,sha256=QXR2rIXu-qF6L9bkPKN8CNvT_YVHv-V63ABEnLBwaUY,484
10392
+ simo/generic/templates/admin/controller_widgets/weather.html,sha256=84SESQBhhzNUay8-6l8XtrC_GNZqI5HWJrgk0Mi6qbM,489
10389
10393
  simo/generic/templates/generic/controllers_info/dummy.md,sha256=DcdkpYXpK7sroINukZZPUQs9uekN9kkE7p5hfnArgFo,147
10390
10394
  simo/generic/templates/generic/controllers_info/stateselect.md,sha256=T0w3vJg02W3RMSsljN1EPRnkVaeRW5acSZaSq9FYvZw,135
10391
10395
  simo/multimedia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -10557,9 +10561,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
10557
10561
  simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10558
10562
  simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10559
10563
  simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10560
- simo-2.5.12.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10561
- simo-2.5.12.dist-info/METADATA,sha256=PxKmTOUs81ncFdpPiAcL2KrrVlTtwuHmGgPIqBQbtdo,1924
10562
- simo-2.5.12.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10563
- simo-2.5.12.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10564
- simo-2.5.12.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10565
- simo-2.5.12.dist-info/RECORD,,
10564
+ simo-2.5.14.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
10565
+ simo-2.5.14.dist-info/METADATA,sha256=5BwYzfoplEKYlQTBYh4sf6Vy7Iig41b4lG9cgx6lj0I,1924
10566
+ simo-2.5.14.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
10567
+ simo-2.5.14.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
10568
+ simo-2.5.14.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
10569
+ simo-2.5.14.dist-info/RECORD,,
File without changes