simo 2.5.25__py3-none-any.whl → 2.5.26__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/middleware.py +6 -0
- simo/fleet/forms.py +9 -0
- simo/fleet/models.py +1 -1
- simo/generic/gateways.py +12 -1
- simo/users/auth_backends.py +6 -4
- simo/users/models.py +4 -1
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/METADATA +1 -1
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/RECORD +12 -12
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/LICENSE.md +0 -0
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/WHEEL +0 -0
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/entry_points.txt +0 -0
- {simo-2.5.25.dist-info → simo-2.5.26.dist-info}/top_level.txt +0 -0
simo/core/middleware.py
CHANGED
|
@@ -25,6 +25,12 @@ def introduce_instance(instance, request=None):
|
|
|
25
25
|
request.instance = instance
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
def drop_current_instance(request=None):
|
|
29
|
+
if request and 'instance_id' in request.session:
|
|
30
|
+
request.session.pop('instance_id')
|
|
31
|
+
_thread_locals.instance = None
|
|
32
|
+
|
|
33
|
+
|
|
28
34
|
def get_current_instance(request=None):
|
|
29
35
|
from simo.core.models import Instance
|
|
30
36
|
if request and request.session.get('instance_id'):
|
simo/fleet/forms.py
CHANGED
|
@@ -1175,6 +1175,11 @@ class BlindsConfigForm(ColonelComponentForm):
|
|
|
1175
1175
|
"to go from fully closed to the start of open movement. <br>"
|
|
1176
1176
|
"Usually it's in between of 1 - 3 seconds."
|
|
1177
1177
|
)
|
|
1178
|
+
retain_angle = forms.BooleanField(
|
|
1179
|
+
required=False, initial=True,
|
|
1180
|
+
help_text="Retain blinds angle after adjusting it's "
|
|
1181
|
+
"position using physical buttons."
|
|
1182
|
+
)
|
|
1178
1183
|
control_mode = forms.ChoiceField(
|
|
1179
1184
|
label="App control mode", required=True, choices=(
|
|
1180
1185
|
('click', "Click"), ('hold', "Hold"), ('slide', "Slide")
|
|
@@ -1186,6 +1191,10 @@ class BlindsConfigForm(ColonelComponentForm):
|
|
|
1186
1191
|
)
|
|
1187
1192
|
)
|
|
1188
1193
|
|
|
1194
|
+
def __init__(self, *args, **kwargs):
|
|
1195
|
+
self.basic_fields.append('retain_angle')
|
|
1196
|
+
return super().__init__(*args, **kwargs)
|
|
1197
|
+
|
|
1189
1198
|
def clean(self):
|
|
1190
1199
|
super().clean()
|
|
1191
1200
|
|
simo/fleet/models.py
CHANGED
|
@@ -275,7 +275,7 @@ def after_colonel_save(sender, instance, created, *args, **kwargs):
|
|
|
275
275
|
if instance.type == 'game-changer':
|
|
276
276
|
# occupy ports immediately
|
|
277
277
|
Interface.objects.create(colonel=instance, no=1, type='i2c')
|
|
278
|
-
Interface.objects.create(colonel=instance, no=2
|
|
278
|
+
Interface.objects.create(colonel=instance, no=2)
|
|
279
279
|
elif instance.type == 'game-changer-mini':
|
|
280
280
|
# only create interfaces, but do not ocuupy ports
|
|
281
281
|
Interface.objects.create(colonel=instance, no=1)
|
simo/generic/gateways.py
CHANGED
|
@@ -12,7 +12,7 @@ from django.db import connection as db_connection
|
|
|
12
12
|
from django.db.models import Q
|
|
13
13
|
import paho.mqtt.client as mqtt
|
|
14
14
|
from simo.core.models import Component
|
|
15
|
-
from simo.core.middleware import introduce_instance
|
|
15
|
+
from simo.core.middleware import introduce_instance, drop_current_instance
|
|
16
16
|
from simo.core.gateways import BaseObjectCommandsGatewayHandler
|
|
17
17
|
from simo.core.forms import BaseGatewayForm
|
|
18
18
|
from simo.core.utils.logs import StreamToLogger
|
|
@@ -132,6 +132,7 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
132
132
|
|
|
133
133
|
def watch_thermostats(self):
|
|
134
134
|
from .controllers import Thermostat
|
|
135
|
+
drop_current_instance()
|
|
135
136
|
for thermostat in Component.objects.filter(
|
|
136
137
|
controller_uid=Thermostat.uid
|
|
137
138
|
):
|
|
@@ -141,15 +142,18 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
141
142
|
|
|
142
143
|
def watch_alarm_clocks(self):
|
|
143
144
|
from .controllers import AlarmClock
|
|
145
|
+
drop_current_instance()
|
|
144
146
|
for alarm_clock in Component.objects.filter(
|
|
145
147
|
controller_uid=AlarmClock.uid
|
|
146
148
|
):
|
|
149
|
+
introduce_instance(alarm_clock.zone.instance)
|
|
147
150
|
tz = pytz.timezone(alarm_clock.zone.instance.timezone)
|
|
148
151
|
timezone.activate(tz)
|
|
149
152
|
alarm_clock.tick()
|
|
150
153
|
|
|
151
154
|
def watch_scripts(self):
|
|
152
155
|
# observe running scripts and drop the ones that are no longer alive
|
|
156
|
+
drop_current_instance()
|
|
153
157
|
dead_processes = []
|
|
154
158
|
for id, process in self.running_scripts.items():
|
|
155
159
|
if process.is_alive():
|
|
@@ -183,8 +187,10 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
183
187
|
self.start_script(script)
|
|
184
188
|
|
|
185
189
|
def watch_watering(self):
|
|
190
|
+
drop_current_instance()
|
|
186
191
|
from .controllers import Watering
|
|
187
192
|
for watering in Component.objects.filter(controller_uid=Watering.uid):
|
|
193
|
+
introduce_instance(watering.zone.instance)
|
|
188
194
|
tz = pytz.timezone(watering.zone.instance.timezone)
|
|
189
195
|
timezone.activate(tz)
|
|
190
196
|
if watering.value['status'] == 'running_program':
|
|
@@ -195,6 +201,7 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
195
201
|
watering.controller._perform_schedule()
|
|
196
202
|
|
|
197
203
|
def run(self, exit):
|
|
204
|
+
drop_current_instance()
|
|
198
205
|
self.exit = exit
|
|
199
206
|
self.logger = get_gw_logger(self.gateway_instance.id)
|
|
200
207
|
for task, period in self.periodic_tasks:
|
|
@@ -261,9 +268,11 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
261
268
|
Script, AlarmGroup
|
|
262
269
|
)
|
|
263
270
|
payload = json.loads(msg.payload)
|
|
271
|
+
drop_current_instance()
|
|
264
272
|
component = get_event_obj(payload, Component)
|
|
265
273
|
if not component:
|
|
266
274
|
return
|
|
275
|
+
introduce_instance(component.zone.instance)
|
|
267
276
|
try:
|
|
268
277
|
if isinstance(component.controller, Script):
|
|
269
278
|
if payload.get('set_val') == 'start':
|
|
@@ -373,6 +382,7 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
373
382
|
|
|
374
383
|
def watch_alarm_events(self):
|
|
375
384
|
from .controllers import AlarmGroup
|
|
385
|
+
drop_current_instance()
|
|
376
386
|
for alarm in Component.objects.filter(
|
|
377
387
|
controller_uid=AlarmGroup.uid, value='breached',
|
|
378
388
|
meta__breach_start__gt=0
|
|
@@ -393,6 +403,7 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
393
403
|
alarm.save(update_fields=['meta'])
|
|
394
404
|
|
|
395
405
|
def watch_timers(self):
|
|
406
|
+
drop_current_instance()
|
|
396
407
|
for component in Component.objects.filter(
|
|
397
408
|
meta__timer_to__gt=0
|
|
398
409
|
).filter(meta__timer_to__lt=time.time()):
|
simo/users/auth_backends.py
CHANGED
|
@@ -99,13 +99,17 @@ class SSOBackend(ModelBackend):
|
|
|
99
99
|
user=user, instance=invitation.instance,
|
|
100
100
|
defaults={'role': invitation.role}
|
|
101
101
|
)
|
|
102
|
-
user.is_active
|
|
102
|
+
if not user.is_active:
|
|
103
|
+
user.is_active = True
|
|
104
|
+
user.save()
|
|
103
105
|
|
|
104
106
|
if not user.is_active:
|
|
105
107
|
return
|
|
106
108
|
|
|
107
109
|
if user_data.get('name'):
|
|
108
|
-
|
|
110
|
+
if user_data['name'] != user.name:
|
|
111
|
+
user.name = user_data['name']
|
|
112
|
+
user.save()
|
|
109
113
|
if user_data.get('avatar_url') \
|
|
110
114
|
and user.avatar_url != user_data.get('avatar_url'):
|
|
111
115
|
user.avatar_url = user_data.get('avatar_url')
|
|
@@ -113,7 +117,5 @@ class SSOBackend(ModelBackend):
|
|
|
113
117
|
user.avatar.save(
|
|
114
118
|
os.path.basename(user.avatar_url), io.BytesIO(resp.content)
|
|
115
119
|
)
|
|
116
|
-
if user.get_dirty_fields():
|
|
117
|
-
user.save()
|
|
118
120
|
|
|
119
121
|
return user
|
simo/users/models.py
CHANGED
|
@@ -154,7 +154,10 @@ def post_instance_user_save(sender, instance, created, **kwargs):
|
|
|
154
154
|
dynamic_settings['core__needs_mqtt_acls_rebuild'] = True
|
|
155
155
|
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
# DirtyFieldsMixin does not work with AbstractBaseUser model!!!
|
|
158
|
+
# goes in to RecursionError: maximum recursion depth exceeded
|
|
159
|
+
# when saving, so do not ever use it!!!!
|
|
160
|
+
class User(AbstractBaseUser, SimoAdminMixin):
|
|
158
161
|
name = models.CharField(_('name'), max_length=150)
|
|
159
162
|
email = models.EmailField(_('email address'), unique=True)
|
|
160
163
|
avatar = ThumbnailerImageField(
|
|
@@ -51,7 +51,7 @@ simo/core/forms.py,sha256=O40apPH7a4qX4WdCc10A1aoAaGWOpKqmjB8d-OhEKCo,21523
|
|
|
51
51
|
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
|
-
simo/core/middleware.py,sha256=
|
|
54
|
+
simo/core/middleware.py,sha256=j_nZQPwT21xuVP2glNTbLm4LE-dvqxroeEcl8Oy3DzA,3367
|
|
55
55
|
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
|
|
@@ -10224,10 +10224,10 @@ simo/fleet/auto_urls.py,sha256=UX66eR2ykMqFgfIllW-RTdjup5-FieCWl_BVm3CcXKg,702
|
|
|
10224
10224
|
simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
|
|
10225
10225
|
simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
|
|
10226
10226
|
simo/fleet/controllers.py,sha256=fjri1GtCnflkkDpNqhTwy6i9CK6RDEB0Q_BtADzcG8E,29156
|
|
10227
|
-
simo/fleet/forms.py,sha256=
|
|
10227
|
+
simo/fleet/forms.py,sha256=dNyM0hAKR93DPeKs6NJnE42prAeCR4MoXjkv5mGeQ4g,62952
|
|
10228
10228
|
simo/fleet/gateways.py,sha256=lKEJW0MgaOEiNnijH50DNSVChvaUT3TA3UurcI57P8k,5677
|
|
10229
10229
|
simo/fleet/managers.py,sha256=ZNeHFSkF5kzsl9E1DCBevOW6kXJlD6kw0LU4B-JMOG8,828
|
|
10230
|
-
simo/fleet/models.py,sha256=
|
|
10230
|
+
simo/fleet/models.py,sha256=zPplx_v64nfKBmb-nCb74aCVtEeY3m3SjEy-VhbnydU,17511
|
|
10231
10231
|
simo/fleet/routing.py,sha256=cofGsVWXMfPDwsJ6HM88xxtRxHwERhJ48Xyxc8mxg5o,149
|
|
10232
10232
|
simo/fleet/serializers.py,sha256=X2M0DFKVaxM6JFGDsdg3S2nJlLIcBvbujidZdfxD88w,2169
|
|
10233
10233
|
simo/fleet/socket_consumers.py,sha256=nfwMAzHHDWrvmwOIfPJqYHgr2fF-OJ_l6gWOnljyFWI,18434
|
|
@@ -10342,7 +10342,7 @@ simo/generic/app_widgets.py,sha256=TPRLj4hri2hBuY6mrdwBiv-01z2hDxZmsup-GDD9LrM,9
|
|
|
10342
10342
|
simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
|
|
10343
10343
|
simo/generic/controllers.py,sha256=i-xKQ5PrNKwCuO0dFaHHUaD5rF9lDnq18ziVSNBENao,50134
|
|
10344
10344
|
simo/generic/forms.py,sha256=H841-wbWltnZ2-RXQEM1G8H4kfOcl88Qhg7bxE4VCiQ,28993
|
|
10345
|
-
simo/generic/gateways.py,sha256=
|
|
10345
|
+
simo/generic/gateways.py,sha256=MxPQzgEnnXSG-t6rErHZQJACFWegCWGaME640UIGrA8,15783
|
|
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
|
|
@@ -10445,12 +10445,12 @@ simo/users/__init__.py,sha256=6a7uBpCWB_DR7p54rbHusc0xvi1qfT1ZCCQGb6TiBh8,52
|
|
|
10445
10445
|
simo/users/admin.py,sha256=9P0iIGAep2R1AUvZnROsRULbxwCYK9pCfSJ2X4aLLBg,6965
|
|
10446
10446
|
simo/users/api.py,sha256=xe__HFxzOaKgrh75PFpP4nkSs5DvmJp8QvMDNhP5kLU,12127
|
|
10447
10447
|
simo/users/apps.py,sha256=cq0A8-U1HALEwev0TicgFhr4CAu7Icz8rwq0HfOaL4E,207
|
|
10448
|
-
simo/users/auth_backends.py,sha256=
|
|
10448
|
+
simo/users/auth_backends.py,sha256=KIw2AdjCUKfm_7Lql6aC4qdE6JznP0ECIMA5MVMLeiM,4251
|
|
10449
10449
|
simo/users/auto_urls.py,sha256=lcJvteBsbHQMJieZpDz-63tDYejLApqsW3CUnDakd7k,272
|
|
10450
10450
|
simo/users/dynamic_settings.py,sha256=sEIsi4yJw3kH46Jq_aOkSuK7QTfQACGUE-lkyBogCaM,570
|
|
10451
10451
|
simo/users/managers.py,sha256=OHgEP85MBtdkdYxdstBd8RavTBT8F_2WyDxUJ9aCqqM,246
|
|
10452
10452
|
simo/users/middleware.py,sha256=GMCrnWSc_2qCleyQIkfQGdL-pU-UTEcSg1wPvIKZ9uk,1210
|
|
10453
|
-
simo/users/models.py,sha256=
|
|
10453
|
+
simo/users/models.py,sha256=Ms5YiU_N1rDSxWMYErO1RnBiK7Jo8Ww_raYJZ5p4yL0,19551
|
|
10454
10454
|
simo/users/permissions.py,sha256=IwtYS8yQdupWbYKR9VimSRDV3qCJ2jXP57Lyjpb2EQM,242
|
|
10455
10455
|
simo/users/serializers.py,sha256=zzw1KONTnaTNBaU0r4rNVxJ827KzD6Z5LuQt27ZsQ98,2516
|
|
10456
10456
|
simo/users/sso_urls.py,sha256=gQOaPvGMYFD0NCVSwyoWO-mTEHe5j9sbzV_RK7kdvp0,251
|
|
@@ -10561,9 +10561,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
10561
10561
|
simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10562
10562
|
simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10563
10563
|
simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10564
|
-
simo-2.5.
|
|
10565
|
-
simo-2.5.
|
|
10566
|
-
simo-2.5.
|
|
10567
|
-
simo-2.5.
|
|
10568
|
-
simo-2.5.
|
|
10569
|
-
simo-2.5.
|
|
10564
|
+
simo-2.5.26.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
10565
|
+
simo-2.5.26.dist-info/METADATA,sha256=CE-CKVFUAiMRRc6FxPMUlSdJqpVyGbVc4L1Y6rB7Mx4,1924
|
|
10566
|
+
simo-2.5.26.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
10567
|
+
simo-2.5.26.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
|
|
10568
|
+
simo-2.5.26.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
10569
|
+
simo-2.5.26.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|