simo 2.6.7__py3-none-any.whl → 2.6.9__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 +12 -5
- 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__/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 +37 -0
- simo/core/api_meta.py +3 -20
- simo/core/controllers.py +25 -9
- simo/core/gateways.py +7 -1
- simo/core/serializers.py +13 -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/controllers.py +8 -30
- simo/fleet/forms.py +1 -1
- simo/fleet/gateways.py +2 -0
- simo/fleet/migrations/0043_auto_20241203_0930.py +28 -0
- simo/fleet/migrations/__pycache__/0043_auto_20241203_0930.cpython-38.pyc +0 -0
- simo/generic/__pycache__/gateways.cpython-38.pyc +0 -0
- simo/generic/gateways.py +5 -0
- simo/users/migrations/0039_auto_20241117_1039.py +25 -24
- simo/users/migrations/__pycache__/0039_auto_20241117_1039.cpython-38.pyc +0 -0
- {simo-2.6.7.dist-info → simo-2.6.9.dist-info}/METADATA +1 -1
- {simo-2.6.7.dist-info → simo-2.6.9.dist-info}/RECORD +34 -32
- {simo-2.6.7.dist-info → simo-2.6.9.dist-info}/LICENSE.md +0 -0
- {simo-2.6.7.dist-info → simo-2.6.9.dist-info}/WHEEL +0 -0
- {simo-2.6.7.dist-info → simo-2.6.9.dist-info}/entry_points.txt +0 -0
- {simo-2.6.7.dist-info → simo-2.6.9.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
|
|
@@ -193,6 +198,9 @@ class PresenceLighting(Script):
|
|
|
193
198
|
if must_on and on_sensor:
|
|
194
199
|
print("Presence detected!")
|
|
195
200
|
|
|
201
|
+
if must_on:
|
|
202
|
+
self.last_presence = 0
|
|
203
|
+
|
|
196
204
|
additional_conditions_met = True
|
|
197
205
|
for condition in self.conditions:
|
|
198
206
|
|
|
@@ -203,25 +211,24 @@ class PresenceLighting(Script):
|
|
|
203
211
|
continue
|
|
204
212
|
|
|
205
213
|
if condition['op'] == 'in':
|
|
206
|
-
if comp.value not in
|
|
214
|
+
if comp.value not in condition['condition_value']:
|
|
207
215
|
if must_on and on_sensor:
|
|
208
216
|
print(
|
|
209
217
|
f"Condition not met: [{comp} value:{comp.value} "
|
|
210
|
-
f"{condition['op']} {condition['
|
|
218
|
+
f"{condition['op']} {condition['condition_value']}]"
|
|
211
219
|
)
|
|
212
220
|
additional_conditions_met = False
|
|
213
221
|
break
|
|
214
222
|
|
|
215
|
-
if not op(comp.value, condition['
|
|
223
|
+
if not op(comp.value, condition['condition_value']):
|
|
216
224
|
if must_on and on_sensor:
|
|
217
225
|
print(
|
|
218
226
|
f"Condition not met: [{comp} value:{comp.value} "
|
|
219
|
-
f"{condition['op']} {condition['
|
|
227
|
+
f"{condition['op']} {condition['condition_value']}]"
|
|
220
228
|
)
|
|
221
229
|
additional_conditions_met = False
|
|
222
230
|
break
|
|
223
231
|
|
|
224
|
-
|
|
225
232
|
if not self.is_on:
|
|
226
233
|
if not must_on:
|
|
227
234
|
return
|
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
|
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'
|
|
@@ -733,7 +734,43 @@ class ControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
|
733
734
|
for uid, cls in get_controller_types_map(user=request.user).items():
|
|
734
735
|
if cls.gateway_class.name not in data:
|
|
735
736
|
data[cls.gateway_class.name] = []
|
|
737
|
+
if not cls.manual_add:
|
|
738
|
+
continue
|
|
736
739
|
data[cls.gateway_class.name].append({
|
|
740
|
+
'uid': uid,
|
|
741
|
+
'name': cls.name,
|
|
742
|
+
'is_discoverable': cls.is_discoverable,
|
|
743
|
+
'discovery_msg': cls.discovery_msg,
|
|
744
|
+
'info': cls.info(cls)
|
|
745
|
+
})
|
|
746
|
+
|
|
747
|
+
return RESTResponse(data)
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
class GWControllerTypes(InstanceMixin, viewsets.GenericViewSet):
|
|
751
|
+
url = 'core/gw-controller-types'
|
|
752
|
+
basename = 'gw-controller-types'
|
|
753
|
+
queryset = []
|
|
754
|
+
|
|
755
|
+
def get_permissions(self):
|
|
756
|
+
permissions = super().get_permissions()
|
|
757
|
+
permissions.append(IsInstanceSuperuser())
|
|
758
|
+
return permissions
|
|
759
|
+
|
|
760
|
+
def list(self, request, *args, **kwargs):
|
|
761
|
+
from .utils.type_constants import get_controller_types_map
|
|
762
|
+
data = {}
|
|
763
|
+
|
|
764
|
+
for uid, cls in get_controller_types_map(user=request.user).items():
|
|
765
|
+
if cls.gateway_class.uid not in data:
|
|
766
|
+
data[cls.gateway_class.uid] = {
|
|
767
|
+
'name': cls.gateway_class.name,
|
|
768
|
+
'info': cls.gateway_class.info,
|
|
769
|
+
'controllers': []
|
|
770
|
+
}
|
|
771
|
+
if not cls.manual_add:
|
|
772
|
+
continue
|
|
773
|
+
data[cls.gateway_class.uid]['controllers'].append({
|
|
737
774
|
'uid': uid,
|
|
738
775
|
'name': cls.name,
|
|
739
776
|
'is_discoverable': cls.is_discoverable,
|
simo/core/api_meta.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from collections import OrderedDict
|
|
2
2
|
from django.urls import reverse
|
|
3
3
|
from django.utils.encoding import force_str
|
|
4
|
-
from django.forms.utils import pretty_name
|
|
5
4
|
from rest_framework.metadata import SimpleMetadata
|
|
6
5
|
from rest_framework import serializers
|
|
7
6
|
from rest_framework.utils.field_mapping import ClassLookupDict
|
|
@@ -97,7 +96,7 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
97
96
|
field_info['child'] = self.get_field_info(field.child)
|
|
98
97
|
elif getattr(field, 'fields', None):
|
|
99
98
|
field.Meta.form = form_field.formset_cls.form
|
|
100
|
-
field_info['children'] = self.
|
|
99
|
+
field_info['children'] = self.get_serializer_info(field)
|
|
101
100
|
|
|
102
101
|
if form_field and hasattr(form_field, 'queryset'):
|
|
103
102
|
if form_field.queryset.model == Icon:
|
|
@@ -116,7 +115,7 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
116
115
|
zone__instance=self.instance
|
|
117
116
|
)
|
|
118
117
|
|
|
119
|
-
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'):
|
|
120
119
|
field_info['choices'] = [
|
|
121
120
|
{
|
|
122
121
|
'value': choice_value,
|
|
@@ -125,20 +124,4 @@ class SIMOAPIMetadata(SimpleMetadata):
|
|
|
125
124
|
for choice_value, choice_name in field.choices.items()
|
|
126
125
|
]
|
|
127
126
|
|
|
128
|
-
return field_info
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def get_formset_serializer_info(self, serializer):
|
|
132
|
-
"""
|
|
133
|
-
Given an instance of a serializer, return a dictionary of metadata
|
|
134
|
-
about its fields.
|
|
135
|
-
"""
|
|
136
|
-
if hasattr(serializer, 'child'):
|
|
137
|
-
# If this is a `ListSerializer` then we want to examine the
|
|
138
|
-
# underlying child serializer instance instead.
|
|
139
|
-
serializer = serializer.child
|
|
140
|
-
return OrderedDict([
|
|
141
|
-
(field_name, self.get_field_info(field))
|
|
142
|
-
for field_name, field in serializer.get_fields().items()
|
|
143
|
-
if not isinstance(field, serializers.HiddenField)
|
|
144
|
-
])
|
|
127
|
+
return field_info
|
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
|
@@ -131,7 +131,6 @@ class ComponentManyToManyRelatedField(serializers.Field):
|
|
|
131
131
|
return self.queryset.filter(pk__in=data)
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
|
|
135
134
|
class ComponentFormsetField(FormSerializer):
|
|
136
135
|
|
|
137
136
|
class Meta:
|
|
@@ -152,9 +151,20 @@ class ComponentFormsetField(FormSerializer):
|
|
|
152
151
|
}
|
|
153
152
|
|
|
154
153
|
def __init__(self, formset_field, *args, **kwargs):
|
|
155
|
-
self.
|
|
154
|
+
self.form = formset_field.formset_cls.form
|
|
156
155
|
super().__init__(*args, **kwargs)
|
|
157
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
|
+
|
|
158
168
|
def get_fields(self):
|
|
159
169
|
ret = super(FormSerializerBase, self).get_fields()
|
|
160
170
|
|
|
@@ -164,7 +174,7 @@ class ComponentFormsetField(FormSerializer):
|
|
|
164
174
|
FORM_SERIALIZER_FIELD_MAPPING
|
|
165
175
|
)
|
|
166
176
|
|
|
167
|
-
form = self.
|
|
177
|
+
form = self.form
|
|
168
178
|
for field_name, form_field in getattr(form, 'all_base_fields', form.base_fields).items():
|
|
169
179
|
|
|
170
180
|
if field_name in getattr(self.Meta, 'exclude', []):
|
|
@@ -249,11 +259,6 @@ class ComponentFormsetField(FormSerializer):
|
|
|
249
259
|
|
|
250
260
|
return ret
|
|
251
261
|
|
|
252
|
-
def get_form(self, data=None, **kwargs):
|
|
253
|
-
form = super().get_form(data=data, **kwargs)
|
|
254
|
-
form.prefix = ''
|
|
255
|
-
return form
|
|
256
|
-
|
|
257
262
|
def create(self, validated_data):
|
|
258
263
|
return validated_data
|
|
259
264
|
|
|
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,
|
|
@@ -100,36 +100,21 @@ class BurglarSmokeDetector(BinarySensor):
|
|
|
100
100
|
]
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
# class AnalogSensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
104
|
-
# config_form = ColonelNumericSensorConfigForm
|
|
105
|
-
# name = "Analog sensor"
|
|
106
|
-
#
|
|
107
|
-
# def _get_occupied_pins(self):
|
|
108
|
-
# return [
|
|
109
|
-
# self.component.config['pin_no'],
|
|
110
|
-
# ]
|
|
111
|
-
|
|
112
|
-
|
|
113
103
|
class DS18B20Sensor(FleeDeviceMixin, BasicSensorMixin, BaseNumericSensor):
|
|
114
104
|
config_form = DS18B20SensorConfigForm
|
|
115
105
|
name = "DS18B20 Temperature sensor"
|
|
116
106
|
|
|
117
107
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
# 'pressure': self.sensor.pressure, 'gas': self.sensor.gas
|
|
122
|
-
# }
|
|
123
|
-
# which is used by BME680Sensor
|
|
124
|
-
|
|
125
|
-
class BaseClimateSensor(FleeDeviceMixin, BasicSensorMixin, BaseMultiSensor):
|
|
108
|
+
class DHTSensor(FleeDeviceMixin, BasicSensorMixin, BaseMultiSensor):
|
|
109
|
+
config_form = ColonelDHTSensorConfigForm
|
|
110
|
+
name = "DHT climate sensor"
|
|
126
111
|
app_widget = NumericSensorWidget
|
|
127
112
|
|
|
128
113
|
def __init__(self, *args, **kwargs):
|
|
129
114
|
super().__init__(*args, **kwargs)
|
|
130
115
|
self.sys_temp_units = 'C'
|
|
131
116
|
if hasattr(self.component, 'zone') \
|
|
132
|
-
|
|
117
|
+
and self.component.zone.instance.units_of_measure == 'imperial':
|
|
133
118
|
self.sys_temp_units = 'F'
|
|
134
119
|
|
|
135
120
|
@property
|
|
@@ -164,23 +149,16 @@ class BaseClimateSensor(FleeDeviceMixin, BasicSensorMixin, BaseMultiSensor):
|
|
|
164
149
|
return new_val
|
|
165
150
|
|
|
166
151
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
class DHTSensor(BaseClimateSensor):
|
|
170
|
-
config_form = ColonelDHTSensorConfigForm
|
|
171
|
-
name = "DHT climate sensor"
|
|
172
|
-
|
|
173
|
-
|
|
174
152
|
class BME680Sensor(FleeDeviceMixin, BaseMultiSensor):
|
|
175
153
|
gateway_class = FleetGatewayHandler
|
|
176
154
|
config_form = BME680SensorConfigForm
|
|
177
155
|
name = "BME680 Climate Sensor (I2C)"
|
|
178
156
|
|
|
179
157
|
|
|
180
|
-
class
|
|
158
|
+
class MCP9808TempSensor(FleeDeviceMixin, BaseNumericSensor):
|
|
181
159
|
gateway_class = FleetGatewayHandler
|
|
182
|
-
config_form =
|
|
183
|
-
name = "
|
|
160
|
+
config_form = MCP9808SensorConfigForm
|
|
161
|
+
name = "MCP9808 Temperature Sensor (I2C)"
|
|
184
162
|
|
|
185
163
|
@property
|
|
186
164
|
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
|
+
]
|
|
Binary file
|
|
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)
|
|
@@ -4,30 +4,31 @@ from django.db import migrations
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def forwards_func(apps, schema_editor):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
7
|
+
pass
|
|
8
|
+
# from simo.automation.helpers import haversine_distance
|
|
9
|
+
# UserDeviceReportLog = apps.get_model("users", "UserDeviceReportLog")
|
|
10
|
+
#
|
|
11
|
+
# logs = UserDeviceReportLog.objects.filter(
|
|
12
|
+
# instance__isnull=False
|
|
13
|
+
# ).select_related('instance')
|
|
14
|
+
#
|
|
15
|
+
# print("Calculate at_home on UserDeviceReportLog's!")
|
|
16
|
+
#
|
|
17
|
+
# bulk_update = []
|
|
18
|
+
# for log in tqdm(logs, total=logs.count()):
|
|
19
|
+
# log.at_home = False
|
|
20
|
+
# if not log.relay:
|
|
21
|
+
# log.at_home = True
|
|
22
|
+
# elif log.location:
|
|
23
|
+
# log.at_home = haversine_distance(
|
|
24
|
+
# log.instance.location, log.location
|
|
25
|
+
# ) < 250
|
|
26
|
+
# if log.at_home:
|
|
27
|
+
# bulk_update.append(log)
|
|
28
|
+
# if len(bulk_update) > 1000:
|
|
29
|
+
# UserDeviceReportLog.objects.bulk_update(bulk_update, ["at_home"])
|
|
30
|
+
# bulk_update = []
|
|
31
|
+
# UserDeviceReportLog.objects.bulk_update(bulk_update, ["at_home"])
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def reverse_func(apps, schema_editor):
|
|
Binary file
|
|
@@ -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=cgTuS9Gwi9R94FTi4kbN9VG74HhddHxEqlCZEbvE-jY,10553
|
|
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=K0cTMm42Ia4k0p2ZLQOU8aiJjZh32Ku965QfqSR7Vsw,8038
|
|
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=eJCV5kScDWfVUa7RprMWvu8PQlGX2T3vCGIhIl4Z6Jw,30306
|
|
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
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=uSPeR38cxPN2H875ky5tDlF_tkkuInzB92qaK4lQWUA,23249
|
|
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
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=PezfOT-1N_UONSsbyTXEIyGO6Po57KdEBRv4yzk_sw0,28605
|
|
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
|
|
@@ -10270,9 +10270,9 @@ simo/fleet/__pycache__/api.cpython-38.pyc,sha256=rZ1mkfkaMBEXhi9sw_jTKdk2CPJhBNx
|
|
|
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=UtuihR455FLsHFAtMBh6haJzypp_HTyo3o8kPH02gnI,24739
|
|
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
|
|
@@ -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
|
|
@@ -10366,6 +10367,7 @@ simo/fleet/migrations/__pycache__/0039_auto_20241016_1047.cpython-38.pyc,sha256=
|
|
|
10366
10367
|
simo/fleet/migrations/__pycache__/0040_alter_colonel_pwm_frequency.cpython-38.pyc,sha256=o_trHQUyQfYzWO_iWmZpvzc-uVJlBjK-GfyKhPOVSjc,736
|
|
10367
10368
|
simo/fleet/migrations/__pycache__/0041_alter_colonel_instance_and_more.cpython-38.pyc,sha256=76yu9gz3pcAq5IYbNeZIoOSgdi0HVqTvc3EdXLGriQI,1178
|
|
10368
10369
|
simo/fleet/migrations/__pycache__/0042_auto_20241120_1028.cpython-38.pyc,sha256=yK2HRc7MYMc4i9ev7FaguBdnXUnUmpFn8E8JOP_yluA,1030
|
|
10370
|
+
simo/fleet/migrations/__pycache__/0043_auto_20241203_0930.cpython-38.pyc,sha256=0QWVIvorcCuhfuGFu0fMdu5vkxcQSosxjt8KT6Ld07E,980
|
|
10369
10371
|
simo/fleet/migrations/__pycache__/__init__.cpython-38.pyc,sha256=5k1KW0jeSDzw6RnVPRq4CaO13Lg7M0F-pxA_gqqZ6Mg,170
|
|
10370
10372
|
simo/fleet/templates/fleet/controllers_info/Button.md,sha256=GIuxqG617174NEtpPeCGVocxO4YMe7-CacgVSu_L5-E,739
|
|
10371
10373
|
simo/fleet/templates/fleet/controllers_info/ENS160AirQualitySensor.md,sha256=3LSTY9YPFuVPIbVsYCAifcotrXJcOXl2k774_vo6nAE,770
|
|
@@ -10374,7 +10376,7 @@ simo/generic/app_widgets.py,sha256=y8W3jR76Hh26O9pPQyg2SophMbYIOtAWD33MPKbB8Mg,8
|
|
|
10374
10376
|
simo/generic/base_types.py,sha256=u3SlfpNYaCwkVBwomWgso4ODzL71ay9MhiAW-bxgnDU,341
|
|
10375
10377
|
simo/generic/controllers.py,sha256=9u6Z_69t1Pkfmbsepx4AOj3cJKrZhik2elVuZjuBYGA,41722
|
|
10376
10378
|
simo/generic/forms.py,sha256=i1TDb8pvFBws2COlmLCH12dTY4MKElFlQoSu5pwdw_w,18967
|
|
10377
|
-
simo/generic/gateways.py,sha256=
|
|
10379
|
+
simo/generic/gateways.py,sha256=3gvBoT4a5NuzdOX1GyzG8M462I1ScbhL8LmShcK-Vcc,9122
|
|
10378
10380
|
simo/generic/models.py,sha256=Adq7ipWK-renxJlNW-SZnAq2oGEOwKx8EdUWaKnfcVQ,7597
|
|
10379
10381
|
simo/generic/routing.py,sha256=elQVZmgnPiieEuti4sJ7zITk1hlRxpgbotcutJJgC60,228
|
|
10380
10382
|
simo/generic/socket_consumers.py,sha256=K2OjphIhKJH48BvfFfoCOyCQZ1NmXb_phs6y1IP-qaQ,1757
|
|
@@ -10383,7 +10385,7 @@ simo/generic/__pycache__/app_widgets.cpython-38.pyc,sha256=D9b13pbMlirgHmjDnQhfL
|
|
|
10383
10385
|
simo/generic/__pycache__/base_types.cpython-38.pyc,sha256=aV5NdIuvXR-ItKpI__MwcyPZHD6Z882TFdgYkPCkr1I,493
|
|
10384
10386
|
simo/generic/__pycache__/controllers.cpython-38.pyc,sha256=_JsNQrL8iR-SY3MlrGJqguoAYaDGg2KGL7IwA0jl3w4,27025
|
|
10385
10387
|
simo/generic/__pycache__/forms.cpython-38.pyc,sha256=fm8tOkr4t0VUiwAOjibvRdh7FPPL2VNH2w78DZsMYW4,14380
|
|
10386
|
-
simo/generic/__pycache__/gateways.cpython-38.pyc,sha256
|
|
10388
|
+
simo/generic/__pycache__/gateways.cpython-38.pyc,sha256=-sdbyRuRpngSIORp3Y94hoLzIL4nrj52HGbcDy4heSA,7507
|
|
10387
10389
|
simo/generic/__pycache__/models.cpython-38.pyc,sha256=MZpum7syAFxuulf47K7gtUlJJ7xRD-IBUBAwUM1ZRnw,5825
|
|
10388
10390
|
simo/generic/__pycache__/routing.cpython-38.pyc,sha256=xtxTUTBTdivzFyA5Wh7k-hUj1WDO_FiRq6HYXdbr9Ks,382
|
|
10389
10391
|
simo/generic/__pycache__/socket_consumers.cpython-38.pyc,sha256=qJO5kvQLWhsQDOr1AtAtsAybuRWioxSkQei3Pc7rdP0,1737
|
|
@@ -10539,7 +10541,7 @@ simo/users/migrations/0035_instanceuser_last_seen_speed_kmh_and_more.py,sha256=l
|
|
|
10539
10541
|
simo/users/migrations/0036_instanceuser_phone_on_charge_user_phone_on_charge.py,sha256=uHXLRmFAASdB9sPivYkRu7WV4rxZDI3RaEwl2i7U_xg,615
|
|
10540
10542
|
simo/users/migrations/0037_rename_last_seen_location_datetime_instanceuser_last_seen_and_more.py,sha256=8f_7fC7k0Dm-0gGVHMI9_490BbEC_SfuAPrAADrZ7BA,1543
|
|
10541
10543
|
simo/users/migrations/0038_userdevicereportlog_at_home_and_more.py,sha256=qL1ZjUJDiSrJat59ToqpNBwnMMPb3Q5mwHq-qd1eFcI,691
|
|
10542
|
-
simo/users/migrations/0039_auto_20241117_1039.py,sha256=
|
|
10544
|
+
simo/users/migrations/0039_auto_20241117_1039.py,sha256=BCIIDfvRzIHaP3SM-Df1XYjWzVLugFqAYGcFofaQepE,1369
|
|
10543
10545
|
simo/users/migrations/0040_userdevicereportlog_location_smoothed_and_more.py,sha256=umGDjQGpCrQocNxaCvwdTsOmSxcRC61NcUdHGUczoc4,855
|
|
10544
10546
|
simo/users/migrations/0041_userdevicereportlog_speed_kmh_received.py,sha256=WoJ-ImX1lNIl7CKO_HMt3jbFjoenFGBUm9HZWidb-eA,433
|
|
10545
10547
|
simo/users/migrations/0042_remove_userdevicereportlog_location_smoothed_and_more.py,sha256=p-GFu6qjkxqeA0TI8aaIum0k6fQfc39RIKbfGPSf0Yk,499
|
|
@@ -10585,7 +10587,7 @@ simo/users/migrations/__pycache__/0035_instanceuser_last_seen_speed_kmh_and_more
|
|
|
10585
10587
|
simo/users/migrations/__pycache__/0036_instanceuser_phone_on_charge_user_phone_on_charge.cpython-38.pyc,sha256=y1ZDJ8VM5_vJOxTPRERjwukiGXJ89UhDc4bHiHZwQ_w,723
|
|
10586
10588
|
simo/users/migrations/__pycache__/0037_rename_last_seen_location_datetime_instanceuser_last_seen_and_more.cpython-38.pyc,sha256=W4Rc6SRNNJ_yAYrEyoklD5LFmQPAL9mTDrXHMfP8R4I,1162
|
|
10587
10589
|
simo/users/migrations/__pycache__/0038_userdevicereportlog_at_home_and_more.cpython-38.pyc,sha256=khDSeTH3-jJ4yO1D6-i3Pm_NekJkVwBSUJ-rAxu0cr4,836
|
|
10588
|
-
simo/users/migrations/__pycache__/0039_auto_20241117_1039.cpython-38.pyc,sha256=
|
|
10590
|
+
simo/users/migrations/__pycache__/0039_auto_20241117_1039.cpython-38.pyc,sha256=2Qi46pncWXhcy6EaqXdLuynw3nCxqDC_KtS_3MToH1g,798
|
|
10589
10591
|
simo/users/migrations/__pycache__/0040_userdevicereportlog_location_smoothed_and_more.cpython-38.pyc,sha256=I0W00mt73gjKunnwAyf3kz1FKfgm2HRwCJY_ogATSS0,918
|
|
10590
10592
|
simo/users/migrations/__pycache__/0041_userdevicereportlog_speed_kmh_received.cpython-38.pyc,sha256=XWC9Emcc1Bm498UZ-6Lo7-i2Vq77vndjMA9xRdJbdfU,676
|
|
10591
10593
|
simo/users/migrations/__pycache__/0042_remove_userdevicereportlog_location_smoothed_and_more.cpython-38.pyc,sha256=sSnWjU7rg5LXlRCxUFb_m2lUIcB4EHgtAnl-C9MMJvE,656
|
|
@@ -10599,9 +10601,9 @@ simo/users/templates/invitations/expired_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
10599
10601
|
simo/users/templates/invitations/expired_suggestion.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10600
10602
|
simo/users/templates/invitations/taken_msg.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10601
10603
|
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.
|
|
10604
|
+
simo-2.6.9.dist-info/LICENSE.md,sha256=M7wm1EmMGDtwPRdg7kW4d00h1uAXjKOT3HFScYQMeiE,34916
|
|
10605
|
+
simo-2.6.9.dist-info/METADATA,sha256=cCWJSmJj43zsbyPzT4tUyfvv4mU2nbkwzh0nTHzyJdk,1952
|
|
10606
|
+
simo-2.6.9.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
10607
|
+
simo-2.6.9.dist-info/entry_points.txt,sha256=S9PwnUYmTSW7681GKDCxUbL0leRJIaRk6fDQIKgbZBA,135
|
|
10608
|
+
simo-2.6.9.dist-info/top_level.txt,sha256=GmS1hrAbpVqn9OWZh6UX82eIOdRLgYA82RG9fe8v4Rs,5
|
|
10609
|
+
simo-2.6.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|