simo 2.1.5__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 +45 -2
- simo/core/apps.py +3 -0
- simo/core/serializers.py +5 -6
- simo/core/signal_receivers.py +2 -2
- simo/core/tasks.py +76 -75
- simo/management/install.py +1 -1
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/METADATA +2 -1
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/RECORD +12 -12
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/WHEEL +1 -1
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/LICENSE.md +0 -0
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/entry_points.txt +0 -0
- {simo-2.1.5.dist-info → simo-2.1.6.dist-info}/top_level.txt +0 -0
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/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.
|
|
395
|
-
return self.
|
|
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.
|
|
418
|
+
self.context['forms'][form_key] = form
|
|
420
419
|
|
|
421
420
|
return form
|
|
422
421
|
|
simo/core/signal_receivers.py
CHANGED
|
@@ -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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
simo/management/install.py
CHANGED
|
@@ -222,7 +222,7 @@ def install():
|
|
|
222
222
|
with open('/etc/ssh/sshd_config', 'r') as ssh_conf:
|
|
223
223
|
line = ssh_conf.readline()
|
|
224
224
|
while line:
|
|
225
|
-
if line.
|
|
225
|
+
if line.startswith('PasswordAuthentication'):
|
|
226
226
|
line.replace(' yes', ' no')
|
|
227
227
|
new_ssh_conf += line
|
|
228
228
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: simo
|
|
3
|
-
Version: 2.1.
|
|
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=
|
|
17
|
+
simo/core/api.py,sha256=qx2hwBTeDmuVFL__gRS4ySZkl8aoHM_8R6F47tzME7w,27581
|
|
18
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=
|
|
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=
|
|
40
|
-
simo/core/signal_receivers.py,sha256=
|
|
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=
|
|
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
|
|
@@ -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=
|
|
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.
|
|
10498
|
-
simo-2.1.
|
|
10499
|
-
simo-2.1.
|
|
10500
|
-
simo-2.1.
|
|
10501
|
-
simo-2.1.
|
|
10502
|
-
simo-2.1.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|