simo 2.6.6__py3-none-any.whl → 2.6.8__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/automation/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/automation/__pycache__/forms.cpython-38.pyc +0 -0
- simo/automation/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/automation/controllers.py +9 -4
- simo/automation/forms.py +7 -1
- simo/automation/gateways.py +1 -0
- simo/core/__pycache__/api.cpython-38.pyc +0 -0
- simo/core/__pycache__/api_meta.cpython-38.pyc +0 -0
- simo/core/__pycache__/autocomplete_views.cpython-38.pyc +0 -0
- simo/core/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/core/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/core/__pycache__/serializers.cpython-38.pyc +0 -0
- simo/core/api.py +34 -0
- simo/core/api_meta.py +3 -1
- simo/core/autocomplete_views.py +13 -4
- simo/core/controllers.py +25 -9
- simo/core/gateways.py +7 -1
- simo/core/serializers.py +19 -8
- simo/fleet/__pycache__/controllers.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/forms.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/fleet/__pycache__/views.cpython-38.pyc +0 -0
- simo/fleet/controllers.py +4 -4
- simo/fleet/forms.py +1 -1
- simo/fleet/gateways.py +2 -0
- simo/fleet/migrations/0043_auto_20241203_0930.py +28 -0
- simo/fleet/views.py +27 -7
- simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/generic/gateways.py +5 -0
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/METADATA +1 -1
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/RECORD +35 -34
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/LICENSE.md +0 -0
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/WHEEL +0 -0
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/entry_points.txt +0 -0
- {simo-2.6.6.dist-info → simo-2.6.8.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/automation/controllers.py
CHANGED
|
@@ -156,6 +156,11 @@ class PresenceLighting(Script):
|
|
|
156
156
|
).first()
|
|
157
157
|
if comp:
|
|
158
158
|
condition['component'] = comp
|
|
159
|
+
condition['condition_value'] = \
|
|
160
|
+
comp.controller._string_to_vals(condition['value'])
|
|
161
|
+
if condition['op'] != 'in':
|
|
162
|
+
condition['condition_value'] = \
|
|
163
|
+
condition['condition_value'][0]
|
|
159
164
|
self.conditions.append(condition)
|
|
160
165
|
comp.on_change(self._on_condition)
|
|
161
166
|
self.condition_comps[comp.id] = comp
|
|
@@ -203,20 +208,20 @@ class PresenceLighting(Script):
|
|
|
203
208
|
continue
|
|
204
209
|
|
|
205
210
|
if condition['op'] == 'in':
|
|
206
|
-
if comp.value not in
|
|
211
|
+
if comp.value not in condition['condition_value']:
|
|
207
212
|
if must_on and on_sensor:
|
|
208
213
|
print(
|
|
209
214
|
f"Condition not met: [{comp} value:{comp.value} "
|
|
210
|
-
f"{condition['op']} {condition['
|
|
215
|
+
f"{condition['op']} {condition['condition_value']}]"
|
|
211
216
|
)
|
|
212
217
|
additional_conditions_met = False
|
|
213
218
|
break
|
|
214
219
|
|
|
215
|
-
if not op(comp.value, condition['
|
|
220
|
+
if not op(comp.value, condition['condition_value']):
|
|
216
221
|
if must_on and on_sensor:
|
|
217
222
|
print(
|
|
218
223
|
f"Condition not met: [{comp} value:{comp.value} "
|
|
219
|
-
f"{condition['op']} {condition['
|
|
224
|
+
f"{condition['op']} {condition['condition_value']}]"
|
|
220
225
|
)
|
|
221
226
|
additional_conditions_met = False
|
|
222
227
|
break
|
simo/automation/forms.py
CHANGED
|
@@ -150,7 +150,7 @@ class ConditionForm(forms.Form):
|
|
|
150
150
|
for val in values:
|
|
151
151
|
val = val.strip()
|
|
152
152
|
if controller_val_type == bool:
|
|
153
|
-
if val.lower() in ('0', 'false', 'none', 'null'):
|
|
153
|
+
if val.lower() in ('0', 'false', 'none', 'null', 'off'):
|
|
154
154
|
final_val = False
|
|
155
155
|
else:
|
|
156
156
|
final_val = True
|
|
@@ -169,6 +169,12 @@ class ConditionForm(forms.Form):
|
|
|
169
169
|
'value', f"{val} is not compatible with selected component."
|
|
170
170
|
)
|
|
171
171
|
continue
|
|
172
|
+
|
|
173
|
+
if final_val == True:
|
|
174
|
+
final_val = 'ON'
|
|
175
|
+
elif final_val == False:
|
|
176
|
+
final_val = 'OFF'
|
|
177
|
+
|
|
172
178
|
final_values.append(final_val)
|
|
173
179
|
|
|
174
180
|
if self.cleaned_data['op'] == 'in':
|
simo/automation/gateways.py
CHANGED
|
@@ -80,6 +80,7 @@ class ScriptRunHandler(multiprocessing.Process):
|
|
|
80
80
|
class AutomationsGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
81
81
|
name = "Automation"
|
|
82
82
|
config_form = BaseGatewayForm
|
|
83
|
+
info = "Provides various types of automation capabilities"
|
|
83
84
|
|
|
84
85
|
running_scripts = {}
|
|
85
86
|
periodic_tasks = (
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/core/api.py
CHANGED
|
@@ -716,6 +716,7 @@ class StatesViewSet(InstanceMixin, viewsets.GenericViewSet):
|
|
|
716
716
|
})
|
|
717
717
|
|
|
718
718
|
|
|
719
|
+
# Legacy.
|
|
719
720
|
class ControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
720
721
|
url = 'core/controller-types'
|
|
721
722
|
basename = 'controller-types'
|
|
@@ -745,6 +746,39 @@ class ControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
|
745
746
|
return RESTResponse(data)
|
|
746
747
|
|
|
747
748
|
|
|
749
|
+
class GWControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
750
|
+
url = 'core/gw-controller-types'
|
|
751
|
+
basename = 'gw-controller-types'
|
|
752
|
+
queryset = []
|
|
753
|
+
|
|
754
|
+
def get_permissions(self):
|
|
755
|
+
permissions = super().get_permissions()
|
|
756
|
+
permissions.append(IsInstanceSuperuser())
|
|
757
|
+
return permissions
|
|
758
|
+
|
|
759
|
+
def list(self, request, *args, **kwargs):
|
|
760
|
+
from .utils.type_constants import get_controller_types_map
|
|
761
|
+
data = {}
|
|
762
|
+
|
|
763
|
+
for uid, cls in get_controller_types_map(user=request.user).items():
|
|
764
|
+
if cls.gateway_class.uid not in data:
|
|
765
|
+
data[cls.gateway_class.uid] = {
|
|
766
|
+
'name': cls.gateway_class.name,
|
|
767
|
+
'info': cls.gateway_class.info,
|
|
768
|
+
'controllers': []
|
|
769
|
+
}
|
|
770
|
+
data[cls.gateway_class.uid]['controllers'].append({
|
|
771
|
+
'uid': uid,
|
|
772
|
+
'name': cls.name,
|
|
773
|
+
'is_discoverable': cls.is_discoverable,
|
|
774
|
+
'manual_add': cls.manual_add,
|
|
775
|
+
'discovery_msg': cls.discovery_msg,
|
|
776
|
+
'info': cls.info(cls)
|
|
777
|
+
})
|
|
778
|
+
|
|
779
|
+
return RESTResponse(data)
|
|
780
|
+
|
|
781
|
+
|
|
748
782
|
class RunningDiscoveries(InstanceMixin, viewsets.GenericViewSet):
|
|
749
783
|
url = 'core/discoveries'
|
|
750
784
|
basename = 'discoveries'
|
simo/core/api_meta.py
CHANGED
|
@@ -79,6 +79,7 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
79
79
|
field_info['autocomplete_url'] = reverse(form_field.url)
|
|
80
80
|
field_info['forward'] = form_field.forward
|
|
81
81
|
|
|
82
|
+
|
|
82
83
|
attrs = [
|
|
83
84
|
'read_only', 'label', 'help_text',
|
|
84
85
|
'min_length', 'max_length',
|
|
@@ -94,6 +95,7 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
94
95
|
if getattr(field, 'child', None):
|
|
95
96
|
field_info['child'] = self.get_field_info(field.child)
|
|
96
97
|
elif getattr(field, 'fields', None):
|
|
98
|
+
field.Meta.form = form_field.formset_cls.form
|
|
97
99
|
field_info['children'] = self.get_serializer_info(field)
|
|
98
100
|
|
|
99
101
|
if form_field and hasattr(form_field, 'queryset'):
|
|
@@ -113,7 +115,7 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
113
115
|
zone__instance=self.instance
|
|
114
116
|
)
|
|
115
117
|
|
|
116
|
-
if not field_info.get('read_only') and hasattr(field, 'choices'):
|
|
118
|
+
if not field_info.get('read_only') and hasattr(field, 'choices'):# and not hasattr(form_field, 'forward'):
|
|
117
119
|
field_info['choices'] = [
|
|
118
120
|
{
|
|
119
121
|
'value': choice_value,
|
simo/core/autocomplete_views.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from dal import autocomplete
|
|
2
|
+
from dal.views import BaseQuerySetView
|
|
2
3
|
from django.db.models import Q
|
|
3
4
|
from django.template.loader import render_to_string
|
|
4
5
|
from simo.core.utils.helpers import search_queryset
|
|
@@ -13,7 +14,9 @@ class IconModelAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
13
14
|
if self.forwarded.get("id"):
|
|
14
15
|
return qs.filter(pk=self.forwarded.get("id"))
|
|
15
16
|
|
|
16
|
-
if self.
|
|
17
|
+
if self.request.GET.get('value'):
|
|
18
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
19
|
+
elif self.q:
|
|
17
20
|
qs = search_queryset(qs, self.q, ('slug', 'keywords'))
|
|
18
21
|
return qs.distinct()
|
|
19
22
|
|
|
@@ -56,7 +59,9 @@ class CategoryAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
56
59
|
return qs.filter(pk=self.forwarded.get("id"))
|
|
57
60
|
|
|
58
61
|
qs = qs.filter(all=False)
|
|
59
|
-
if self.
|
|
62
|
+
if self.request.GET.get('value'):
|
|
63
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
64
|
+
elif self.q:
|
|
60
65
|
qs = search_queryset(qs, self.q, ('name'))
|
|
61
66
|
return qs.distinct()
|
|
62
67
|
|
|
@@ -79,7 +84,9 @@ class ZoneAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
79
84
|
if self.forwarded.get("id"):
|
|
80
85
|
return qs.filter(pk=self.forwarded.get("id"))
|
|
81
86
|
|
|
82
|
-
if self.
|
|
87
|
+
if self.request.GET.get('value'):
|
|
88
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
89
|
+
elif self.q:
|
|
83
90
|
qs = search_queryset(qs, self.q, ('name',))
|
|
84
91
|
return qs.distinct()
|
|
85
92
|
|
|
@@ -116,7 +123,9 @@ class ComponentAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
116
123
|
Q(alarm_category__in=self.forwarded['alarm_category'])
|
|
117
124
|
)
|
|
118
125
|
|
|
119
|
-
if self.
|
|
126
|
+
if self.request.GET.get('value'):
|
|
127
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
128
|
+
elif self.q:
|
|
120
129
|
qs = search_queryset(qs, self.q, ('zone__name', 'name',))
|
|
121
130
|
return qs.distinct()
|
|
122
131
|
|
simo/core/controllers.py
CHANGED
|
@@ -40,6 +40,7 @@ class ControllerBase(ABC):
|
|
|
40
40
|
manual_add = True # Can be added manually
|
|
41
41
|
family = None
|
|
42
42
|
masters_only = False # component can be created/modified by hub masters only
|
|
43
|
+
info_template_path = None
|
|
43
44
|
|
|
44
45
|
@property
|
|
45
46
|
@abstractmethod
|
|
@@ -76,11 +77,6 @@ class ControllerBase(ABC):
|
|
|
76
77
|
:return: Default value of this base component type
|
|
77
78
|
"""
|
|
78
79
|
|
|
79
|
-
@property
|
|
80
|
-
def info_template_path(self) -> str:
|
|
81
|
-
return f"{self.__class__.__module__.split('.')[-2]}/" \
|
|
82
|
-
f"controllers_info/{self.__class__.__name__}.md"
|
|
83
|
-
|
|
84
80
|
@abstractmethod
|
|
85
81
|
def _validate_val(self, value, occasion=None):
|
|
86
82
|
"""
|
|
@@ -121,7 +117,8 @@ class ControllerBase(ABC):
|
|
|
121
117
|
cls, '_process_discovery'
|
|
122
118
|
)
|
|
123
119
|
|
|
124
|
-
|
|
120
|
+
@classmethod
|
|
121
|
+
def info(cls, component=None):
|
|
125
122
|
'''
|
|
126
123
|
Override this to give users help on how to use this component type,
|
|
127
124
|
after you do that, include any component instance specific information
|
|
@@ -130,10 +127,13 @@ class ControllerBase(ABC):
|
|
|
130
127
|
along with any other relative information,
|
|
131
128
|
regarding this particular component instance
|
|
132
129
|
'''
|
|
130
|
+
if not cls.info_template_path:
|
|
131
|
+
cls.info_template_path = f"{cls.__module__.split('.')[-2]}/" \
|
|
132
|
+
f"controllers_info/{cls.__name__}.md"
|
|
133
133
|
try:
|
|
134
134
|
return render_to_string(
|
|
135
|
-
|
|
136
|
-
'component':
|
|
135
|
+
cls.info_template_path, {
|
|
136
|
+
'component': component
|
|
137
137
|
}
|
|
138
138
|
)
|
|
139
139
|
except:
|
|
@@ -214,7 +214,23 @@ class ControllerBase(ABC):
|
|
|
214
214
|
'''
|
|
215
215
|
val_type = type(self.default_value)
|
|
216
216
|
v = str(v).strip('(').strip('[').rstrip(')').rstrip(']')
|
|
217
|
-
|
|
217
|
+
vals = []
|
|
218
|
+
for val in v.split(','):
|
|
219
|
+
val = val.strip()
|
|
220
|
+
if val.lower() in ('none', 'null'):
|
|
221
|
+
val = None
|
|
222
|
+
elif val_type == bool:
|
|
223
|
+
if val.lower() in ('0', 'false', 'off'):
|
|
224
|
+
val = False
|
|
225
|
+
else:
|
|
226
|
+
val = True
|
|
227
|
+
else:
|
|
228
|
+
try:
|
|
229
|
+
val = val_type(val)
|
|
230
|
+
except:
|
|
231
|
+
continue
|
|
232
|
+
vals.append(val)
|
|
233
|
+
return vals
|
|
218
234
|
|
|
219
235
|
def send(self, value):
|
|
220
236
|
self.component.refresh_from_db()
|
simo/core/gateways.py
CHANGED
|
@@ -3,7 +3,7 @@ import time
|
|
|
3
3
|
import json
|
|
4
4
|
import paho.mqtt.client as mqtt
|
|
5
5
|
from django.conf import settings
|
|
6
|
-
from django.
|
|
6
|
+
from django.template.loader import render_to_string
|
|
7
7
|
from abc import ABC, abstractmethod
|
|
8
8
|
from simo.core.utils.helpers import classproperty
|
|
9
9
|
from simo.core.events import GatewayObjectCommand, get_event_obj
|
|
@@ -33,6 +33,12 @@ class BaseGatewayHandler(ABC):
|
|
|
33
33
|
def uid(cls):
|
|
34
34
|
return ".".join([cls.__module__, cls.__name__])
|
|
35
35
|
|
|
36
|
+
|
|
37
|
+
@classproperty
|
|
38
|
+
@classmethod
|
|
39
|
+
def info(cls):
|
|
40
|
+
return
|
|
41
|
+
|
|
36
42
|
def __init__(self, gateway_instance):
|
|
37
43
|
self.gateway_instance = gateway_instance
|
|
38
44
|
super().__init__()
|
simo/core/serializers.py
CHANGED
|
@@ -4,6 +4,7 @@ import re
|
|
|
4
4
|
from django import forms
|
|
5
5
|
from collections import OrderedDict
|
|
6
6
|
from django.conf import settings
|
|
7
|
+
from django.forms.utils import pretty_name
|
|
7
8
|
from collections.abc import Iterable
|
|
8
9
|
from easy_thumbnails.files import get_thumbnailer
|
|
9
10
|
from simo.core.middleware import get_current_request
|
|
@@ -130,7 +131,6 @@ class ComponentManyToManyRelatedField(serializers.Field):
|
|
|
130
131
|
return self.queryset.filter(pk__in=data)
|
|
131
132
|
|
|
132
133
|
|
|
133
|
-
|
|
134
134
|
class ComponentFormsetField(FormSerializer):
|
|
135
135
|
|
|
136
136
|
class Meta:
|
|
@@ -151,9 +151,20 @@ class ComponentFormsetField(FormSerializer):
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
def __init__(self, formset_field, *args, **kwargs):
|
|
154
|
-
self.
|
|
154
|
+
self.form = formset_field.formset_cls.form
|
|
155
155
|
super().__init__(*args, **kwargs)
|
|
156
156
|
|
|
157
|
+
def get_form(self, data=None, **kwargs):
|
|
158
|
+
form_cls = self.form
|
|
159
|
+
instance = form_cls(data=data, **kwargs)
|
|
160
|
+
# Handle partial validation on the form side
|
|
161
|
+
if self.partial:
|
|
162
|
+
set_form_partial_validation(
|
|
163
|
+
instance, self.Meta.minimum_required
|
|
164
|
+
)
|
|
165
|
+
instance.prefix = ''
|
|
166
|
+
return instance
|
|
167
|
+
|
|
157
168
|
def get_fields(self):
|
|
158
169
|
ret = super(FormSerializerBase, self).get_fields()
|
|
159
170
|
|
|
@@ -163,7 +174,7 @@ class ComponentFormsetField(FormSerializer):
|
|
|
163
174
|
FORM_SERIALIZER_FIELD_MAPPING
|
|
164
175
|
)
|
|
165
176
|
|
|
166
|
-
form = self.
|
|
177
|
+
form = self.form
|
|
167
178
|
for field_name, form_field in getattr(form, 'all_base_fields', form.base_fields).items():
|
|
168
179
|
|
|
169
180
|
if field_name in getattr(self.Meta, 'exclude', []):
|
|
@@ -193,6 +204,9 @@ class ComponentFormsetField(FormSerializer):
|
|
|
193
204
|
ret[field_name] = self._get_field(form_field, serializer_field_class)
|
|
194
205
|
ret[field_name].initial = form_field.initial
|
|
195
206
|
ret[field_name].default = form_field.initial
|
|
207
|
+
ret[field_name].label = form_field.label
|
|
208
|
+
if not ret[field_name].label:
|
|
209
|
+
ret[field_name].label = pretty_name(field_name)
|
|
196
210
|
|
|
197
211
|
return ret
|
|
198
212
|
|
|
@@ -245,11 +259,6 @@ class ComponentFormsetField(FormSerializer):
|
|
|
245
259
|
|
|
246
260
|
return ret
|
|
247
261
|
|
|
248
|
-
def get_form(self, data=None, **kwargs):
|
|
249
|
-
form = super().get_form(data=data, **kwargs)
|
|
250
|
-
form.prefix = ''
|
|
251
|
-
return form
|
|
252
|
-
|
|
253
262
|
def create(self, validated_data):
|
|
254
263
|
return validated_data
|
|
255
264
|
|
|
@@ -360,6 +369,8 @@ class ComponentSerializer(FormSerializer):
|
|
|
360
369
|
)
|
|
361
370
|
ret[field_name].initial = form_field.initial
|
|
362
371
|
ret[field_name].default = form_field.initial
|
|
372
|
+
if not ret[field_name].label:
|
|
373
|
+
ret[field_name].label = pretty_name(field_name)
|
|
363
374
|
|
|
364
375
|
for name, field in super(FormSerializerBase, self).get_fields().items():
|
|
365
376
|
if name in ret:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
simo/fleet/controllers.py
CHANGED
|
@@ -25,7 +25,7 @@ from .forms import (
|
|
|
25
25
|
ColonelSwitchConfigForm, ColonelPWMOutputConfigForm, DCDriverConfigForm,
|
|
26
26
|
ColonelNumericSensorConfigForm, ColonelRGBLightConfigForm,
|
|
27
27
|
ColonelDHTSensorConfigForm, DS18B20SensorConfigForm,
|
|
28
|
-
BME680SensorConfigForm,
|
|
28
|
+
BME680SensorConfigForm, MCP9808SensorConfigForm, ENS160SensorConfigForm,
|
|
29
29
|
DualMotorValveForm, BlindsConfigForm, GateConfigForm,
|
|
30
30
|
BurglarSmokeDetectorConfigForm,
|
|
31
31
|
TTLockConfigForm, DALIDeviceConfigForm, DaliLampForm, DaliGearGroupForm,
|
|
@@ -177,10 +177,10 @@ class BME680Sensor(FleeDeviceMixin, BaseMultiSensor):
|
|
|
177
177
|
name = "BME680 Climate Sensor (I2C)"
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
class
|
|
180
|
+
class MCP9808TempSensor(FleeDeviceMixin, BaseNumericSensor):
|
|
181
181
|
gateway_class = FleetGatewayHandler
|
|
182
|
-
config_form =
|
|
183
|
-
name = "
|
|
182
|
+
config_form = MCP9808SensorConfigForm
|
|
183
|
+
name = "MCP9808 Temperature Sensor (I2C)"
|
|
184
184
|
|
|
185
185
|
@property
|
|
186
186
|
def default_value_units(self):
|
simo/fleet/forms.py
CHANGED
|
@@ -501,7 +501,7 @@ class BME680SensorConfigForm(ColonelComponentForm):
|
|
|
501
501
|
return super().save(commit=commit)
|
|
502
502
|
|
|
503
503
|
|
|
504
|
-
class
|
|
504
|
+
class MCP9808SensorConfigForm(ColonelComponentForm):
|
|
505
505
|
interface = Select2ModelChoiceField(
|
|
506
506
|
queryset=Interface.objects.filter(type='i2c'),
|
|
507
507
|
url='autocomplete-interfaces',
|
simo/fleet/gateways.py
CHANGED
|
@@ -14,6 +14,8 @@ from simo.core.utils.serialization import deserialize_form_data
|
|
|
14
14
|
class FleetGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
15
15
|
name = "SIMO.io Fleet"
|
|
16
16
|
config_form = BaseGatewayForm
|
|
17
|
+
info = "Provides components that run on SIMO.io colonel boards " \
|
|
18
|
+
"like The Game Changer"
|
|
17
19
|
|
|
18
20
|
periodic_tasks = (
|
|
19
21
|
('look_for_updates', 600),
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Generated by Django 4.2.10 on 2024-12-03 09:30
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def forwards_func(apps, schema_editor):
|
|
7
|
+
Component = apps.get_model("core", "Component")
|
|
8
|
+
|
|
9
|
+
for comp in Component.objects.filter(
|
|
10
|
+
controller_uid='simo.fleet.controllers.MPC9808TempSensor'
|
|
11
|
+
):
|
|
12
|
+
comp.controller_uid = 'simo.fleet.controllers.MCP9808TempSensor'
|
|
13
|
+
comp.save()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def reverse_func(apps, schema_editor):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Migration(migrations.Migration):
|
|
21
|
+
|
|
22
|
+
dependencies = [
|
|
23
|
+
('fleet', '0042_auto_20241120_1028'),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
operations = [
|
|
27
|
+
migrations.RunPython(forwards_func, reverse_func, elidable=True),
|
|
28
|
+
]
|
simo/fleet/views.py
CHANGED
|
@@ -40,7 +40,10 @@ class PinsSelectAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
40
40
|
if self.forwarded.get('filters'):
|
|
41
41
|
qs = qs.filter(**self.forwarded.get('filters'))
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
|
|
44
|
+
if self.request.GET.get('value'):
|
|
45
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
46
|
+
elif self.q:
|
|
44
47
|
qs = search_queryset(qs, self.q, ('label', ))
|
|
45
48
|
|
|
46
49
|
return qs
|
|
@@ -59,7 +62,9 @@ class InterfaceSelectAutocomplete(autocomplete.Select2QuerySetView):
|
|
|
59
62
|
|
|
60
63
|
qs = Interface.objects.filter(colonel=colonel)
|
|
61
64
|
|
|
62
|
-
if self.
|
|
65
|
+
if self.request.GET.get('value'):
|
|
66
|
+
qs = qs.filter(pk__in=self.request.GET['value'].split(','))
|
|
67
|
+
elif self.forwarded.get('filters'):
|
|
63
68
|
qs = qs.filter(**self.forwarded.get('filters'))
|
|
64
69
|
|
|
65
70
|
return qs
|
|
@@ -81,15 +86,12 @@ class ControlInputSelectAutocomplete(autocomplete.Select2ListView):
|
|
|
81
86
|
pins_qs = pins_qs.filter(
|
|
82
87
|
Q(occupied_by_id=None) | Q(id=int(self.forwarded['self'][4:]))
|
|
83
88
|
)
|
|
84
|
-
|
|
89
|
+
elif 'value' not in self.request.GET:
|
|
85
90
|
pins_qs = pins_qs.filter(occupied_by_id=None)
|
|
86
91
|
|
|
87
92
|
if self.forwarded.get('pin_filters'):
|
|
88
93
|
pins_qs = pins_qs.filter(**self.forwarded.get('pin_filters'))
|
|
89
94
|
|
|
90
|
-
if self.q:
|
|
91
|
-
pins_qs = search_queryset(pins_qs, self.q, ('label',))
|
|
92
|
-
|
|
93
95
|
buttons_qs = Component.objects.filter(
|
|
94
96
|
base_type='button'
|
|
95
97
|
).select_related('zone')
|
|
@@ -97,10 +99,28 @@ class ControlInputSelectAutocomplete(autocomplete.Select2ListView):
|
|
|
97
99
|
if self.forwarded.get('button_filters'):
|
|
98
100
|
buttons_qs = buttons_qs.filter(**self.forwarded.get('button_filters'))
|
|
99
101
|
|
|
100
|
-
if self.
|
|
102
|
+
if self.request.GET.get('value'):
|
|
103
|
+
pin_ids = []
|
|
104
|
+
button_ids = []
|
|
105
|
+
for v in self.request.GET['value'].split(','):
|
|
106
|
+
try:
|
|
107
|
+
t, id = v.split('-')
|
|
108
|
+
id = int(id)
|
|
109
|
+
except:
|
|
110
|
+
continue
|
|
111
|
+
if t == 'pin':
|
|
112
|
+
pin_ids.append(id)
|
|
113
|
+
elif t == 'button':
|
|
114
|
+
button_ids.append(id)
|
|
115
|
+
buttons_qs = buttons_qs.filter(id__in=button_ids)
|
|
116
|
+
pins_qs = pins_qs.filter(id__in=pin_ids)
|
|
117
|
+
|
|
118
|
+
elif self.q:
|
|
101
119
|
buttons_qs = search_queryset(
|
|
102
120
|
buttons_qs, self.q, ('name', 'zone__name', 'category__name')
|
|
103
121
|
)
|
|
122
|
+
pins_qs = search_queryset(pins_qs, self.q, ('label',))
|
|
123
|
+
|
|
104
124
|
|
|
105
125
|
return [(f'pin-{pin.id}', str(pin)) for pin in pins_qs] + \
|
|
106
126
|
[(f'button-{button.id}',
|
|
Binary file
|
simo/generic/gateways.py
CHANGED
|
@@ -62,6 +62,9 @@ class CameraWatcher(threading.Thread):
|
|
|
62
62
|
class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
63
63
|
name = "Generic"
|
|
64
64
|
config_form = BaseGatewayForm
|
|
65
|
+
info = "Provides generic type components which use other components to operate like " \
|
|
66
|
+
"thermostats, alarm groups, watering programs, alarm clocks," \
|
|
67
|
+
"etc. "
|
|
65
68
|
|
|
66
69
|
running_scripts = {}
|
|
67
70
|
periodic_tasks = (
|
|
@@ -242,6 +245,8 @@ class GenericGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
|
242
245
|
class DummyGatewayHandler(BaseObjectCommandsGatewayHandler):
|
|
243
246
|
name = "Dummy"
|
|
244
247
|
config_form = BaseGatewayForm
|
|
248
|
+
info = "Provides dummy components that do absolutely anything, " \
|
|
249
|
+
"but comes in super handy when configuring custom automations."
|
|
245
250
|
|
|
246
251
|
def perform_value_send(self, component, value):
|
|
247
252
|
component.controller.set(value)
|
|
@@ -13,18 +13,18 @@ simo/__pycache__/urls.cpython-38.pyc,sha256=u0x6EqT8S1YfDOSPgbI8Kf-RDlveY9OV-EDX
|
|
|
13
13
|
simo/__pycache__/wsgi.cpython-38.pyc,sha256=TpRxO7VM_ql31hbKphVdanydC5RI1nHB4l0QA2pdWxo,322
|
|
14
14
|
simo/automation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
simo/automation/app_widgets.py,sha256=gaqImMZjuMHm7nIb9a4D-Y3qipz_WhSPAHXcwGx4Uzs,199
|
|
16
|
-
simo/automation/controllers.py,sha256=
|
|
17
|
-
simo/automation/forms.py,sha256=
|
|
18
|
-
simo/automation/gateways.py,sha256=
|
|
16
|
+
simo/automation/controllers.py,sha256=kk_gssVoxfkn268gAhmmSpTWnW4UnEQAVyxLHwyZYPc,10498
|
|
17
|
+
simo/automation/forms.py,sha256=UWnkxw8pILPK0smRPTo4SLgsZl78zOySx7JIc30Bgtk,10228
|
|
18
|
+
simo/automation/gateways.py,sha256=wElqHHyNd2jdpWuhO9DQ0yORIrObSzJsgZ-4dlKCLo4,9471
|
|
19
19
|
simo/automation/helpers.py,sha256=iP-fxxB8HsFQy3k2CjFubu86aMqvWgmh-p24DiyOrek,4330
|
|
20
20
|
simo/automation/models.py,sha256=l45FHgeKGsfpLtd1X1PVFpIjB5JI4BlvKkodpcxm6aE,927
|
|
21
21
|
simo/automation/serializers.py,sha256=PjyFrjdPK1mBsgbNhyqMi9SWzcymqTa742ipy0LhAN4,1996
|
|
22
22
|
simo/automation/state.py,sha256=aZZvNBae7unnux_zGHCIWCV2z47hVJc-DIL72Hqfkeo,600
|
|
23
23
|
simo/automation/__pycache__/__init__.cpython-38.pyc,sha256=YmP0xAD-mxpQHgdTZeC64sXChA8TriMZD1jckNYi3xg,164
|
|
24
24
|
simo/automation/__pycache__/app_widgets.cpython-38.pyc,sha256=7DfUA9V_1MiwrOe_ta-ts8dYY8xXb9UMg2_9A3XoRcs,523
|
|
25
|
-
simo/automation/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
26
|
-
simo/automation/__pycache__/forms.cpython-38.pyc,sha256=
|
|
27
|
-
simo/automation/__pycache__/gateways.cpython-38.pyc,sha256=
|
|
25
|
+
simo/automation/__pycache__/controllers.cpython-38.pyc,sha256=YTL0-xu1CjO57mz1HKX1DIDrZeSGiGtl9-uKlokbF1Y,8024
|
|
26
|
+
simo/automation/__pycache__/forms.cpython-38.pyc,sha256=cpA5hA2Iz3JsPC0Dq01ki1I7S9c5DKRcXveHApI1dJo,7772
|
|
27
|
+
simo/automation/__pycache__/gateways.cpython-38.pyc,sha256=4gDB7AeKwumAty-1x1Uyh1dEckw-kntBafMNvayH-PA,7621
|
|
28
28
|
simo/automation/__pycache__/helpers.cpython-38.pyc,sha256=4VSSarOFnUk_KExWwvDlx5dEhv8aHUCHMZDtGG--pUY,3627
|
|
29
29
|
simo/automation/__pycache__/models.cpython-38.pyc,sha256=6gXdIMcrWaGACal2omj-b2if5JW8QvLIrtRfYVpDRQU,1230
|
|
30
30
|
simo/automation/__pycache__/serializers.cpython-38.pyc,sha256=gWgcuPE8aY-TmuRLXCuSR74mvtKerpZ04m0MfPfw0AI,3405
|
|
@@ -61,29 +61,29 @@ simo/backups/migrations/__pycache__/0004_alter_backup_options_alter_backuplog_op
|
|
|
61
61
|
simo/backups/migrations/__pycache__/__init__.cpython-38.pyc,sha256=Lz1fs6V05h2AoxTOLNye0do9bEMnyuaXB_hHOjG5-HU,172
|
|
62
62
|
simo/core/__init__.py,sha256=_s2TjJfQImsMrTIxqLAx9AZie1Ojmm6sCHASdl3WLGU,50
|
|
63
63
|
simo/core/admin.py,sha256=nmFDO57D5hXHDfl0wjJ9J5jBxyCqW4Gp_uqHhpS2uuw,18564
|
|
64
|
-
simo/core/api.py,sha256=
|
|
64
|
+
simo/core/api.py,sha256=iipxmn7rWnK_c2JaHJ8PQ7BVAsA19VlFIM7RkU0HxNM,30232
|
|
65
65
|
simo/core/api_auth.py,sha256=vCxvczA8aWNcW0VyKs5WlC_ytlqeGP_H_hkKUNVkCwM,1247
|
|
66
|
-
simo/core/api_meta.py,sha256=
|
|
66
|
+
simo/core/api_meta.py,sha256=e9iqVv-3d651lMvZY-ILG4F35Puh2XunnwykiBUbl5E,5055
|
|
67
67
|
simo/core/app_widgets.py,sha256=VxZzapuc-a29wBH7JzpvNF2SK1ECrgNUySId5ke1ffc,2509
|
|
68
68
|
simo/core/apps.py,sha256=CsqpiQerhmrMsH-wGiG-gQgXd9qEkIi-LUaA9cXpKSw,425
|
|
69
69
|
simo/core/auto_urls.py,sha256=FBDclIeRp5UVWomIUbRzUgY-AoMk-r2qC2htlwKD4Lo,1106
|
|
70
|
-
simo/core/autocomplete_views.py,sha256=
|
|
70
|
+
simo/core/autocomplete_views.py,sha256=sQbT2g1Y9HGLLKazKaNfnZmwa6RJlTek9XzkGQcx4P8,4363
|
|
71
71
|
simo/core/base_types.py,sha256=WypW8hTfzveuTQtruGjLYAGQZIuczxTlW-SdRk3iQug,666
|
|
72
72
|
simo/core/context.py,sha256=LKw1I4iIRnlnzoTCuSLLqDX7crHdBnMo3hjqYvVmzFc,1557
|
|
73
|
-
simo/core/controllers.py,sha256=
|
|
73
|
+
simo/core/controllers.py,sha256=xqEtTWkIJSpgez2OmsLoYImR4ZPSzY20xR-qe8eMQpo,36129
|
|
74
74
|
simo/core/dynamic_settings.py,sha256=bUs58XEZOCIEhg1TigR3LmYggli13KMryBZ9pC7ugAQ,1872
|
|
75
75
|
simo/core/events.py,sha256=1_KIk5pJqdLPRQlCQ9xSyALst2Cn0b2lAEAJ3QjwIjE,4801
|
|
76
76
|
simo/core/filters.py,sha256=6wbn8C2WvKTTjtfMwwLBp2Fib1V0-DMpS4iqJd6jJQo,2540
|
|
77
77
|
simo/core/form_fields.py,sha256=wowWocYgxkKBr0WYzpKn4UvH4ScnImus56Tg2G8OPBc,2274
|
|
78
78
|
simo/core/forms.py,sha256=CCKypzX32-Mp8LpyO0ffiPcwIitaw0F03e8A9ZL0Mhw,21586
|
|
79
|
-
simo/core/gateways.py,sha256=
|
|
79
|
+
simo/core/gateways.py,sha256=7SvBKuVwdYYLRoAP8FXT2qz63FBpns21vlSMW1bCDFg,3795
|
|
80
80
|
simo/core/loggers.py,sha256=EBdq23gTQScVfQVH-xeP90-wII2DQFDjoROAW6ggUP4,1645
|
|
81
81
|
simo/core/managers.py,sha256=n-b3I4uXzfHKTeB1VMjSaMsDUxp8FegFJwnbV1IsWQ4,3019
|
|
82
82
|
simo/core/middleware.py,sha256=eUFf6iP-Snx_0TE3MoXsSwqrd5IjlukqZk2GQGStRCo,3385
|
|
83
83
|
simo/core/models.py,sha256=QNVTnWeHAW6LVrs3eaR7WNMhwjICuQpXZ8vyH_2qCBo,22834
|
|
84
84
|
simo/core/permissions.py,sha256=2YNRot2qoHjHKWPGOpO4PBseecctPbTlUQpepnFkCRs,3027
|
|
85
85
|
simo/core/routing.py,sha256=X1_IHxyA-_Q7hw1udDoviVP4_FSBDl8GYETTC2zWTbY,499
|
|
86
|
-
simo/core/serializers.py,sha256=
|
|
86
|
+
simo/core/serializers.py,sha256=OvwFIIKHJtBuAJPhILPLx-9ENADBSz5T6dHOuKKtC3g,22326
|
|
87
87
|
simo/core/signal_receivers.py,sha256=xUnQrWFBMF0Uasj6PzpERPr6h6BR-ZjUb1NSakRSzQo,9458
|
|
88
88
|
simo/core/socket_consumers.py,sha256=trRZvBGTJ7xIbfdmVvn7zoiWp_qssSkMZykDrI5YQyE,9783
|
|
89
89
|
simo/core/storage.py,sha256=_5igjaoWZAiExGWFEJMElxUw55DzJG1jqFty33xe8BE,342
|
|
@@ -94,29 +94,29 @@ simo/core/views.py,sha256=yx9I0byeVUa-LAOnklpWIYwpNNOf5m9fyjKBvj4YCh4,2475
|
|
|
94
94
|
simo/core/widgets.py,sha256=J9e06C6I22F6xKic3VMgG7WeX07glAcl-4bF2Mg180A,2827
|
|
95
95
|
simo/core/__pycache__/__init__.cpython-38.pyc,sha256=ZJFM_XN0RmJMULQulgA_wFiOnEtsMoedcOWnXjH-Y8o,208
|
|
96
96
|
simo/core/__pycache__/admin.cpython-38.pyc,sha256=WAfdq_hAdkW-_QwJ0E7NSd25yxnPRi_HjJ-uKFMJzcg,14146
|
|
97
|
-
simo/core/__pycache__/api.cpython-38.pyc,sha256=
|
|
97
|
+
simo/core/__pycache__/api.cpython-38.pyc,sha256=88Btwy435_Jb5bYnkuBfsrNILpdfhMTCYHuNdo1pu-8,23209
|
|
98
98
|
simo/core/__pycache__/api_auth.cpython-38.pyc,sha256=mi3mu5qEKio_PvfQEvr3Q6AhdPLAHxzxAxrMbAz_pKU,1712
|
|
99
|
-
simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=
|
|
99
|
+
simo/core/__pycache__/api_meta.cpython-38.pyc,sha256=PrJrXcjbhXQkYrvEVG9jpRzkB8XYBMRQuKjXrgU9POA,3742
|
|
100
100
|
simo/core/__pycache__/app_widgets.cpython-38.pyc,sha256=oN657XMMZ6GYN9nblv7fX3kdnTEzSP9XV6PXM6Z0wl4,4358
|
|
101
101
|
simo/core/__pycache__/apps.cpython-38.pyc,sha256=JL0BEqgXcSQvMlcK48PBpPfyDEkPMdO1Y0teqMRGirs,713
|
|
102
102
|
simo/core/__pycache__/auto_urls.cpython-38.pyc,sha256=ib_ns5Ko8ybfrdJJWYVV1jevihxOFs39aBF4bez6Lzs,874
|
|
103
|
-
simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=
|
|
103
|
+
simo/core/__pycache__/autocomplete_views.cpython-38.pyc,sha256=Er4fS5KhE2FB9g7-ckjS_RIWOv7qysuzdt1Ab7HUL5Q,4318
|
|
104
104
|
simo/core/__pycache__/base_types.cpython-38.pyc,sha256=CX-qlF7CefRi_mCE954wYa9rUFR88mOl6g7fybDRu7g,803
|
|
105
105
|
simo/core/__pycache__/context.cpython-38.pyc,sha256=NlTHt2GvXxA21AhBkeyOLfRFUuXw7wmwqyNhhcDl2cw,1373
|
|
106
|
-
simo/core/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
106
|
+
simo/core/__pycache__/controllers.cpython-38.pyc,sha256=X9Dd2zKebwG_I93H63uYyS1WtqZRrjX8z7dqngtbSlM,30610
|
|
107
107
|
simo/core/__pycache__/dynamic_settings.cpython-38.pyc,sha256=wGpnscX1DxFpRl54MQURhjz2aD3NJohSzw9JCFnzh2Y,2384
|
|
108
108
|
simo/core/__pycache__/events.cpython-38.pyc,sha256=1y8YaZsiDkBOeIWzH7SQz4holmMG_RLlMWi8kuSZcoE,5280
|
|
109
109
|
simo/core/__pycache__/filters.cpython-38.pyc,sha256=WBBDwcDQwOmgbrRhyUxenSN80rU4Eq9jQ6RcrRGCP_o,2440
|
|
110
110
|
simo/core/__pycache__/form_fields.cpython-38.pyc,sha256=phMdhDFRmaFDhJSnasAg8VKNP6PxkPjFqkLwEuWicIs,3465
|
|
111
111
|
simo/core/__pycache__/forms.cpython-38.pyc,sha256=9ogrGIBTmPWXUD3qgICo2oA-pBlgO2Bqg9hRv_-IUdE,17571
|
|
112
|
-
simo/core/__pycache__/gateways.cpython-38.pyc,sha256=
|
|
112
|
+
simo/core/__pycache__/gateways.cpython-38.pyc,sha256=MG7VHsx0DcfjTqi9efDEomnp_oz7eOC0rLdyzUw4-Wk,4694
|
|
113
113
|
simo/core/__pycache__/loggers.cpython-38.pyc,sha256=Z-cdQnC6XlIonPV4Sl4E52tP4NMEdPAiHK0cFaIL7I8,1623
|
|
114
114
|
simo/core/__pycache__/managers.cpython-38.pyc,sha256=6RTIxyjOgpQGtAqcUyE2vFPS09w1V5Wmd_vOV7rHRRI,3370
|
|
115
115
|
simo/core/__pycache__/middleware.cpython-38.pyc,sha256=g3d4L2PwxFyRKIPMP9Hkdjk1PL9NarQd4hSHS55I8n8,2649
|
|
116
116
|
simo/core/__pycache__/models.cpython-38.pyc,sha256=po4B4bMyA-KDBu8qbVwGjrpUZJQPVBB6dkfncEBKYnM,18554
|
|
117
117
|
simo/core/__pycache__/permissions.cpython-38.pyc,sha256=UdtxCTXPEbe99vgZOfRz9wfKSYvUn9hSRbpIV9CJSyI,2988
|
|
118
118
|
simo/core/__pycache__/routing.cpython-38.pyc,sha256=3T3FPJ8Cn99xZCGvMyg2xjl7al-Shm9CelbSpkJtNP8,599
|
|
119
|
-
simo/core/__pycache__/serializers.cpython-38.pyc,sha256=
|
|
119
|
+
simo/core/__pycache__/serializers.cpython-38.pyc,sha256=SK8uPWorFZujwL4vBeLarwS5hPknoqREmDSGhX5bWO8,19616
|
|
120
120
|
simo/core/__pycache__/signal_receivers.cpython-38.pyc,sha256=h0AsNC33oLoADJlwUVfPB1suUYovfzjfc0SE41-3MjY,6778
|
|
121
121
|
simo/core/__pycache__/socket_consumers.cpython-38.pyc,sha256=KqbO1cOewodVPcy0-htVefyUjCuELKV0o7fOfYqfgPc,8490
|
|
122
122
|
simo/core/__pycache__/storage.cpython-38.pyc,sha256=9R1Xu0FJDflfRXUPsqEgt0SpwiP7FGk7HaR8s8XRyI8,721
|
|
@@ -10253,9 +10253,9 @@ simo/fleet/api.py,sha256=rJwAYJvp0uslW7O6Q4XOpOa8hfCdy3keUD7b3UNL43E,3424
|
|
|
10253
10253
|
simo/fleet/auto_urls.py,sha256=UX66eR2ykMqFgfIllW-RTdjup5-FieCWl_BVm3CcXKg,702
|
|
10254
10254
|
simo/fleet/base_types.py,sha256=wL9RVkHr0gA7HI1wZq0pruGEIgvQqpfnCL4cC3ywsvw,102
|
|
10255
10255
|
simo/fleet/ble.py,sha256=eHA_9ABjbmH1vUVCv9hiPXQL2GZZSEVwfO0xyI1S0nI,1081
|
|
10256
|
-
simo/fleet/controllers.py,sha256=
|
|
10257
|
-
simo/fleet/forms.py,sha256=
|
|
10258
|
-
simo/fleet/gateways.py,sha256=
|
|
10256
|
+
simo/fleet/controllers.py,sha256=jz-DyWP1F-eLUl8UkbCAqiAqRUm4d_TXVuepTIe9akU,29157
|
|
10257
|
+
simo/fleet/forms.py,sha256=2pbX1otTb1HqJ3aksRWz-FbsJ3YIyx6weV_tMFonecY,64772
|
|
10258
|
+
simo/fleet/gateways.py,sha256=C7dyapWDlJ5erYPNLkSoH50I8kj0lIXicSno0_CrdXc,5783
|
|
10259
10259
|
simo/fleet/managers.py,sha256=ZNeHFSkF5kzsl9E1DCBevOW6kXJlD6kw0LU4B-JMOG8,828
|
|
10260
10260
|
simo/fleet/models.py,sha256=zPplx_v64nfKBmb-nCb74aCVtEeY3m3SjEy-VhbnydU,17511
|
|
10261
10261
|
simo/fleet/routing.py,sha256=cofGsVWXMfPDwsJ6HM88xxtRxHwERhJ48Xyxc8mxg5o,149
|
|
@@ -10263,16 +10263,16 @@ simo/fleet/serializers.py,sha256=PQnjp7LaEpMts-om2OPV5XOU9ut6KFWiePPDCXK0M98,267
|
|
|
10263
10263
|
simo/fleet/socket_consumers.py,sha256=4hVSvFNq9Hi44R7JmaujFoEtgmH5YBST2cFYtIiMDRA,18840
|
|
10264
10264
|
simo/fleet/tasks.py,sha256=NX_opj-rbkK9eeQMeRNwHj_ZJ0LC4rYOZovMg9_r0kA,904
|
|
10265
10265
|
simo/fleet/utils.py,sha256=wNJvURzLP3-aho3D3rfg07N9kWCaMIw5gOsmeeO9Nlg,4740
|
|
10266
|
-
simo/fleet/views.py,sha256=
|
|
10266
|
+
simo/fleet/views.py,sha256=jK5ajYTIPhz8ODgeHxHgZ9aWicWOD2D6PFJ_iq9B_ug,4051
|
|
10267
10267
|
simo/fleet/__pycache__/__init__.cpython-38.pyc,sha256=pIZE7EL6-cuJ3pQtaSwjKLrKLsTYelp1k9sRhXKLh6s,159
|
|
10268
10268
|
simo/fleet/__pycache__/admin.cpython-38.pyc,sha256=iweeu5AkaggBhQntP6-VF_eEodkNc6E7zKy0VjfwC2o,6652
|
|
10269
10269
|
simo/fleet/__pycache__/api.cpython-38.pyc,sha256=rZ1mkfkaMBEXhi9sw_jTKdk2CPJhBNxoImtjQ3Rf1VY,4016
|
|
10270
10270
|
simo/fleet/__pycache__/auto_urls.cpython-38.pyc,sha256=Tc6a6BCXHjijP8U2jE2ghlJwnSNrGm59-hW5t-80wF0,689
|
|
10271
10271
|
simo/fleet/__pycache__/base_types.cpython-38.pyc,sha256=deyPwjpT6xZiFxBGFnj5b7R-lbdOTh2krgpJhrcGVhc,274
|
|
10272
10272
|
simo/fleet/__pycache__/ble.cpython-38.pyc,sha256=Nrof9w7cm4OlpFWHeVnmvvanh2_oF9oQ3TknJiV93-0,1267
|
|
10273
|
-
simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=
|
|
10274
|
-
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=
|
|
10275
|
-
simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=
|
|
10273
|
+
simo/fleet/__pycache__/controllers.cpython-38.pyc,sha256=C8pGEX-J8aaXsq9tNIMNAcd4Ip37--nT1V7eqXd6aQg,24906
|
|
10274
|
+
simo/fleet/__pycache__/forms.cpython-38.pyc,sha256=VQqXDYGpTMMOrV3PGXFbWD_49XjglqJO2LWIHidMom0,43550
|
|
10275
|
+
simo/fleet/__pycache__/gateways.cpython-38.pyc,sha256=MIpXuGWitGNdsxJ99fWvMXJ6sVE96ac7iR4K4aM4Sds,5148
|
|
10276
10276
|
simo/fleet/__pycache__/managers.cpython-38.pyc,sha256=Vmm23zoQnS3-uS5_WJt2n3wtjhLiEhLWaYxXJCU6Gts,1339
|
|
10277
10277
|
simo/fleet/__pycache__/models.cpython-38.pyc,sha256=WUahZgETWlem5rVXlJ_vINFRM7OZWp5xpWXGMoeBXsM,14131
|
|
10278
10278
|
simo/fleet/__pycache__/routing.cpython-38.pyc,sha256=aPrCmxFKVyB8R8ZbJDwdPdFfvT7CvobovvZeq_mqRgY,314
|
|
@@ -10280,7 +10280,7 @@ simo/fleet/__pycache__/serializers.cpython-38.pyc,sha256=l_FzORWCM1hcSZV0AaGRO-p
|
|
|
10280
10280
|
simo/fleet/__pycache__/socket_consumers.cpython-38.pyc,sha256=m8sJWln-uyjeTD-alyoNikEJcHCxZGTe2vXnMGVNZog,14170
|
|
10281
10281
|
simo/fleet/__pycache__/tasks.cpython-38.pyc,sha256=RoNxL2WUiW67s9O9DjaYVVjCBSZu2nje0Qn9FJkWVS0,1116
|
|
10282
10282
|
simo/fleet/__pycache__/utils.cpython-38.pyc,sha256=obUd-X2Y-ybx4icqUWq_qwIxrP9yyarJjexWAfO4MTI,3344
|
|
10283
|
-
simo/fleet/__pycache__/views.cpython-38.pyc,sha256=
|
|
10283
|
+
simo/fleet/__pycache__/views.cpython-38.pyc,sha256=jffuwjfsNGY8EJchA6lnSBUXkDQkIqoov6DhWAO4yCA,3623
|
|
10284
10284
|
simo/fleet/migrations/0001_initial.py,sha256=lce8nkD8Sz6pYr-XJSpDm4CMDuB6TA__WtnHpIp-eA4,1326
|
|
10285
10285
|
simo/fleet/migrations/0002_auto_20220422_0743.py,sha256=sFOfAjnQOzcJjE8lHrrHgTaGilJNYswMdXphgVzUZqY,825
|
|
10286
10286
|
simo/fleet/migrations/0003_auto_20220422_0752.py,sha256=VcH7DyMAniEwT76hDVofS8FTNpM3nxz_J9AC2zKHDSA,543
|
|
@@ -10323,6 +10323,7 @@ simo/fleet/migrations/0039_auto_20241016_1047.py,sha256=c75iDlPH9NPQohkNBt58NPl3
|
|
|
10323
10323
|
simo/fleet/migrations/0040_alter_colonel_pwm_frequency.py,sha256=AiiYeLXEmBAFj1O3WdJB0xQy1KqfiErYR8yPpL8W7e4,498
|
|
10324
10324
|
simo/fleet/migrations/0041_alter_colonel_instance_and_more.py,sha256=r3PzZERt4kM0ul_TFl-i7qS7n0ht0G8jS83nucMxZfQ,1181
|
|
10325
10325
|
simo/fleet/migrations/0042_auto_20241120_1028.py,sha256=nXyOXyTqhYfR2IDpIX0E3oIhKI7ShI7TGZ0Uf1CzR1U,715
|
|
10326
|
+
simo/fleet/migrations/0043_auto_20241203_0930.py,sha256=wYfYEBurHB5pGOgL6M-z9EoOZGhW9glhT3BpNiMDoH4,651
|
|
10326
10327
|
simo/fleet/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10327
10328
|
simo/fleet/migrations/__pycache__/0001_initial.cpython-38.pyc,sha256=9kc1UyMEYkRNVnZ7iwZbiW1t3qWXROvWrI2G1BdzIaA,1250
|
|
10328
10329
|
simo/fleet/migrations/__pycache__/0002_auto_20220422_0743.cpython-38.pyc,sha256=8oxhGb7rL8QYKlBLU3pOYcd8aHeQWDB9I8awkK04mXg,841
|
|
@@ -10374,7 +10375,7 @@ simo/generic/app_widgets.py,sha256=y8W3jR76Hh26O9pPQyg2SophMbYIOtAWD33MPKbB8Mg,8
|
|
|
10374
10375
|
simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
|
|
10375
10376
|
simo/generic/controllers.py,sha256=9u6Z_69t1Pkfmbsepx4AOj3cJKrZhik2elVuZjuBYGA,41722
|
|
10376
10377
|
simo/generic/forms.py,sha256=i1TDb8pvFBws2COlmLCH12dTY4MKElFlQoSu5pwdw_w,18967
|
|
10377
|
-
simo/generic/gateways.py,sha256=
|
|
10378
|
+
simo/generic/gateways.py,sha256=3gvBoT4a5NuzdOX1GyzG8M462I1ScbhL8LmShcK-Vcc,9122
|
|
10378
10379
|
simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
|
|
10379
10380
|
simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
|
|
10380
10381
|
simo/generic/socket_consumers.py,sha256=K2OjphIhKJH48BvfFfoCOyCQZ1NmXb_phs6y1IP-qaQ,1757
|
|
@@ -10383,7 +10384,7 @@ simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=D9b13pbMlirgHmjDnQhfL
|
|
|
10383
10384
|
simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
|
|
10384
10385
|
simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=_JsNQrL8iR-SY3MlrGJqguoAYaDGg2KGL7IwA0jl3w4,27025
|
|
10385
10386
|
simo/generic/__pycache__/forms.cpython-38.pyc,sha256=fm8tOkr4t0VUiwAOjibvRdh7FPPL2VNH2w78DZsMYW4,14380
|
|
10386
|
-
simo/generic/__pycache__/gateways.cpython-38.pyc,sha256
|
|
10387
|
+
simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=-sdbyRuRpngSIORp3Y94hoLzIL4nrj52HGbcDy4heSA,7507
|
|
10387
10388
|
simo/generic/__pycache__/models.cpython-38.pyc,sha256=MZpum7syAFxuulf47K7gtUlJJ7xRD-IBUBAwUM1ZRnw,5825
|
|
10388
10389
|
simo/generic/__pycache__/routing.cpython-38.pyc,sha256=xtxTUTBTdivzFyA5Wh7k-hUj1WDO_FiRq6HYXdbr9Ks,382
|
|
10389
10390
|
simo/generic/__pycache__/socket_consumers.cpython-38.pyc,sha256=qJO5kvQLWhsQDOr1AtAtsAybuRWioxSkQei3Pc7rdP0,1737
|
|
@@ -10599,9 +10600,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
10599
10600
|
simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10600
10601
|
simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10601
10602
|
simo/users/templates/invitations/taken_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10602
|
-
simo-2.6.
|
|
10603
|
-
simo-2.6.
|
|
10604
|
-
simo-2.6.
|
|
10605
|
-
simo-2.6.
|
|
10606
|
-
simo-2.6.
|
|
10607
|
-
simo-2.6.
|
|
10603
|
+
simo-2.6.8.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
10604
|
+
simo-2.6.8.dist-info/METADATA,sha256=oLE9PcdmNJtUr78LOvEltMytRMStMXtcPoWCS7O4Y-E,1952
|
|
10605
|
+
simo-2.6.8.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
10606
|
+
simo-2.6.8.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
|
|
10607
|
+
simo-2.6.8.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
10608
|
+
simo-2.6.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|