sensor-sdk 0.0.1__tar.gz → 0.0.3__tar.gz
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 sensor-sdk might be problematic. Click here for more details.
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/PKG-INFO +104 -59
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/README.md +103 -58
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/sensor_controller.py +3 -3
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/sensor_data_context.py +2 -2
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/sensor_profile.py +2 -2
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/PKG-INFO +104 -59
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/setup.py +1 -1
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/LICENSE.txt +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/__init__.py +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/gforce.py +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/sensor_data.py +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/sensor_device.py +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor/utils.py +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/SOURCES.txt +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/dependency_links.txt +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/requires.txt +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/top_level.txt +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/sensor_sdk.egg-info/zip-safe +0 -0
- {sensor-sdk-0.0.1 → sensor-sdk-0.0.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sensor-sdk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Python sdk for Synchroni
|
|
5
5
|
Home-page: https://github.com/oymotion/SynchroniSDKPython
|
|
6
6
|
Author: Martin Ye
|
|
@@ -9,7 +9,7 @@ Requires-Python: >=3.8.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.txt
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# sensor-sdk
|
|
13
13
|
|
|
14
14
|
Synchroni sdk for Python
|
|
15
15
|
|
|
@@ -17,7 +17,6 @@ Synchroni sdk for Python
|
|
|
17
17
|
|
|
18
18
|
Synchroni SDK is the software development kit for developers to access Synchroni products.
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
## Contributing
|
|
22
21
|
|
|
23
22
|
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
@@ -31,10 +30,10 @@ MIT
|
|
|
31
30
|
## Installation
|
|
32
31
|
|
|
33
32
|
```sh
|
|
34
|
-
pip install
|
|
33
|
+
pip install sensor-sdk
|
|
35
34
|
```
|
|
36
35
|
|
|
37
|
-
## 1. Permission
|
|
36
|
+
## 1. Permission
|
|
38
37
|
|
|
39
38
|
Application will obtain bluetooth permission by itself.
|
|
40
39
|
|
|
@@ -44,58 +43,66 @@ Application will obtain bluetooth permission by itself.
|
|
|
44
43
|
from sensor import *
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
## SensorController methods
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
### 1. Initalize
|
|
50
49
|
|
|
51
50
|
```python
|
|
52
|
-
|
|
51
|
+
SensorControllerInstance = SensorController()
|
|
53
52
|
|
|
54
53
|
# register scan listener
|
|
55
|
-
if not
|
|
56
|
-
def on_device_callback(
|
|
54
|
+
if not SensorControllerInstance.hasDeviceFoundCallback:
|
|
55
|
+
def on_device_callback(deviceList: List[BLEDevice]):
|
|
57
56
|
# return all devices doesn't connected
|
|
58
57
|
pass
|
|
59
|
-
|
|
58
|
+
SensorControllerInstance.onDeviceFoundCallback = on_device_callback
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
### 2. Start scan
|
|
62
|
+
|
|
63
|
+
Use `def startScan(period_in_ms: int) -> bool` to start scan
|
|
64
|
+
|
|
64
65
|
```python
|
|
65
|
-
success =
|
|
66
|
+
success = SensorControllerInstance.startScan(6000)
|
|
66
67
|
```
|
|
68
|
+
|
|
67
69
|
returns true if start scan success, periodInMS means onDeviceCallback will be called every periodInMS
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
### 3. Stop scan
|
|
72
|
+
|
|
73
|
+
Use `def stopScan() -> None` to stop scan
|
|
70
74
|
|
|
71
|
-
Use `async def stop_scan() -> None` to stop scan
|
|
72
75
|
```python
|
|
73
|
-
|
|
76
|
+
SensorControllerInstance.stopScan()
|
|
74
77
|
```
|
|
75
|
-
|
|
78
|
+
|
|
79
|
+
### 4. Check scaning
|
|
76
80
|
|
|
77
81
|
Use `property isScanning: bool` to check scanning status
|
|
82
|
+
|
|
78
83
|
```python
|
|
79
|
-
isScanning =
|
|
84
|
+
isScanning = SensorControllerInstance.isScanning
|
|
80
85
|
```
|
|
81
86
|
|
|
82
|
-
|
|
87
|
+
### 5. Check if bluetooth is enabled
|
|
83
88
|
|
|
84
89
|
Use `property isEnabled: bool` to check if bluetooth is enabled
|
|
90
|
+
|
|
85
91
|
```python
|
|
86
|
-
isEnabled =
|
|
92
|
+
isEnabled = SensorControllerInstance.isEnabled
|
|
87
93
|
```
|
|
88
|
-
|
|
94
|
+
|
|
95
|
+
### 6. Create SensorProfile
|
|
89
96
|
|
|
90
97
|
Use `def requireSensor(device: BLEDevice) -> SensorProfile | None` to create SensorProfile.
|
|
91
98
|
|
|
92
99
|
If bleDevice is invalid, result is None.
|
|
93
100
|
|
|
94
101
|
```python
|
|
95
|
-
sensorProfile =
|
|
102
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
96
103
|
```
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
### 7. Get SensorProfile
|
|
99
106
|
|
|
100
107
|
Use `def getSensor(device: BLEDevice) -> SensorProfile | None` to get SensorProfile.
|
|
101
108
|
|
|
@@ -105,26 +112,48 @@ If SensorProfile didn't created, result is None.
|
|
|
105
112
|
sensorProfile = SensorControllerInstance.getSensor(bleDevice)
|
|
106
113
|
```
|
|
107
114
|
|
|
108
|
-
|
|
115
|
+
### 8. Get Connected SensorProfiles
|
|
109
116
|
|
|
110
117
|
Use `def getConnectedSensors() -> list[SensorProfile]` to get connected SensorProfiles.
|
|
118
|
+
|
|
111
119
|
```python
|
|
112
120
|
sensorProfiles = SensorControllerInstance.getConnectedSensors()
|
|
113
121
|
```
|
|
114
122
|
|
|
115
|
-
|
|
123
|
+
### 9. Get Connected BLE Devices
|
|
116
124
|
|
|
117
125
|
Use `def getConnectedDevices() -> list[SensorProfile]` to get connected BLE Devices.
|
|
126
|
+
|
|
118
127
|
```python
|
|
119
128
|
bleDevices = SensorControllerInstance.getConnectedDevices()
|
|
120
129
|
```
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
### 10. Terminate
|
|
132
|
+
|
|
133
|
+
Use `def terminate()` to terminate sdk
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
|
|
137
|
+
def terminate():
|
|
138
|
+
SensorControllerInstance.terminate()
|
|
139
|
+
exit()
|
|
140
|
+
|
|
141
|
+
def main():
|
|
142
|
+
signal.signal(signal.SIGINT, lambda signal, frame: terminate())
|
|
143
|
+
time.sleep(30)
|
|
144
|
+
SensorControllerInstance.terminate()
|
|
145
|
+
|
|
146
|
+
Please MAKE SURE to call terminate when exit main() or press Ctrl+C
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## SensorProfile methods
|
|
150
|
+
|
|
151
|
+
### 11. Initalize
|
|
123
152
|
|
|
124
|
-
## 1. Initalize
|
|
125
153
|
Please register callbacks for SensorProfile
|
|
154
|
+
|
|
126
155
|
```python
|
|
127
|
-
sensorProfile =
|
|
156
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
128
157
|
|
|
129
158
|
# register callbacks
|
|
130
159
|
def on_state_changed(sensor, newState):
|
|
@@ -149,26 +178,30 @@ sensorProfile.onPowerChanged = on_power_changed
|
|
|
149
178
|
sensorProfile.onDataCallback = on_data_callback
|
|
150
179
|
```
|
|
151
180
|
|
|
152
|
-
|
|
153
|
-
|
|
181
|
+
### 12. Connect device
|
|
182
|
+
|
|
183
|
+
Use `def connect() -> bool` to connect.
|
|
184
|
+
|
|
154
185
|
```python
|
|
155
|
-
success =
|
|
186
|
+
success = sensorProfile.connect()
|
|
156
187
|
```
|
|
157
188
|
|
|
158
|
-
|
|
159
|
-
|
|
189
|
+
### 13. Disconnect
|
|
190
|
+
|
|
191
|
+
Use `def disconnect() -> bool` to disconnect.
|
|
192
|
+
|
|
160
193
|
```python
|
|
161
|
-
success =
|
|
194
|
+
success = sensorProfile.disconnect()
|
|
162
195
|
```
|
|
163
196
|
|
|
197
|
+
### 14. Get device status
|
|
164
198
|
|
|
165
|
-
|
|
166
|
-
Use `property connectionState: DeviceStateEx` to get device status.
|
|
199
|
+
Use `property deviceState: DeviceStateEx` to get device status.
|
|
167
200
|
|
|
168
201
|
Please send command in 'Ready' state, should be after connect() return True.
|
|
169
202
|
|
|
170
203
|
```python
|
|
171
|
-
deviceStateEx = sensorProfile.
|
|
204
|
+
deviceStateEx = sensorProfile.deviceState
|
|
172
205
|
|
|
173
206
|
# deviceStateEx has define:
|
|
174
207
|
# class DeviceStateEx(Enum):
|
|
@@ -180,21 +213,22 @@ deviceStateEx = sensorProfile.connectionState
|
|
|
180
213
|
# Invalid = 5
|
|
181
214
|
```
|
|
182
215
|
|
|
216
|
+
### 15. Get BLE device of SensorProfile
|
|
183
217
|
|
|
184
|
-
|
|
185
|
-
## 5. Get BLE device of SensorProfile
|
|
186
218
|
Use `property BLEDevice: BLEDevice` to get BLE device of SensorProfile.
|
|
219
|
+
|
|
187
220
|
```python
|
|
188
221
|
bleDevice = sensorProfile.BLEDevice
|
|
189
222
|
```
|
|
190
223
|
|
|
191
|
-
|
|
192
|
-
|
|
224
|
+
### 16. Get device info of SensorProfile
|
|
225
|
+
|
|
226
|
+
Use `def getDeviceInfo() -> dict | None` to get device info of SensorProfile.
|
|
193
227
|
|
|
194
228
|
Please call after device in 'Ready' state, return None if it's not connected.
|
|
195
229
|
|
|
196
230
|
```python
|
|
197
|
-
deviceInfo =
|
|
231
|
+
deviceInfo = sensorProfile.getDeviceInfo()
|
|
198
232
|
|
|
199
233
|
# deviceInfo has defines:
|
|
200
234
|
# deviceInfo = {
|
|
@@ -212,31 +246,37 @@ Please call after device in 'Ready' state, return None if it's not connected.
|
|
|
212
246
|
# }
|
|
213
247
|
```
|
|
214
248
|
|
|
249
|
+
### 17. Init data transfer
|
|
215
250
|
|
|
216
|
-
|
|
217
|
-
Use `async def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
251
|
+
Use `def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
218
252
|
|
|
219
253
|
Please call after device in 'Ready' state, return True if init succeed.
|
|
254
|
+
|
|
220
255
|
```python
|
|
221
|
-
success =
|
|
256
|
+
success = sensorProfile.init(5, 60*1000)
|
|
222
257
|
```
|
|
258
|
+
|
|
223
259
|
packageSampleCount: set sample counts of SensorData.channelSamples in onDataCallback()
|
|
224
260
|
powerRefreshInterval: callback period for onPowerChanged()
|
|
225
261
|
|
|
226
|
-
|
|
262
|
+
### 18. Check if init data transfer succeed
|
|
263
|
+
|
|
227
264
|
Use `property hasInited: bool` to check if init data transfer succeed.
|
|
265
|
+
|
|
228
266
|
```python
|
|
229
267
|
hasInited = sensorProfile.hasInited
|
|
230
268
|
```
|
|
231
269
|
|
|
232
|
-
|
|
233
|
-
|
|
270
|
+
### 19. DataNotify
|
|
271
|
+
|
|
272
|
+
Use `def startDataNotification() -> bool` to start data notification.
|
|
234
273
|
|
|
235
274
|
Please call if hasInited return True
|
|
236
|
-
|
|
275
|
+
|
|
276
|
+
#### 19.1 Start data transfer
|
|
237
277
|
|
|
238
278
|
```python
|
|
239
|
-
success =
|
|
279
|
+
success = sensorProfile.startDataNotification()
|
|
240
280
|
```
|
|
241
281
|
|
|
242
282
|
Data type list:
|
|
@@ -273,25 +313,30 @@ def on_data_callback(sensor, data):
|
|
|
273
313
|
sensorProfile.onDataCallback = on_data_callback
|
|
274
314
|
```
|
|
275
315
|
|
|
276
|
-
|
|
277
|
-
|
|
316
|
+
#### 19.2 Stop data transfer
|
|
317
|
+
|
|
318
|
+
Use `def stopDataNotification() -> bool` to stop data transfer.
|
|
319
|
+
|
|
278
320
|
```python
|
|
279
|
-
success =
|
|
321
|
+
success = sensorProfile.stopDataNotification()
|
|
280
322
|
```
|
|
281
323
|
|
|
282
|
-
|
|
324
|
+
#### 19.3 Check if it's data transfering
|
|
325
|
+
|
|
283
326
|
Use `property isDataTransfering: bool` to check if it's data transfering.
|
|
327
|
+
|
|
284
328
|
```python
|
|
285
329
|
isDataTransfering = sensorProfile.isDataTransfering
|
|
286
330
|
```
|
|
287
331
|
|
|
288
|
-
|
|
289
|
-
|
|
332
|
+
### 20. Get battery level
|
|
333
|
+
|
|
334
|
+
Use `def getBatteryLevel() -> int` to get battery level. Please call after device in 'Ready' state.
|
|
290
335
|
|
|
291
336
|
```python
|
|
292
|
-
batteryPower =
|
|
337
|
+
batteryPower = sensorProfile.getBatteryLevel()
|
|
293
338
|
|
|
294
339
|
# batteryPower is battery level returned, value ranges from 0 to 100, 0 means out of battery, while 100 means full.
|
|
295
340
|
```
|
|
296
341
|
|
|
297
|
-
Please check
|
|
342
|
+
Please check console.py in examples directory
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# sensor-sdk
|
|
2
2
|
|
|
3
3
|
Synchroni sdk for Python
|
|
4
4
|
|
|
@@ -6,7 +6,6 @@ Synchroni sdk for Python
|
|
|
6
6
|
|
|
7
7
|
Synchroni SDK is the software development kit for developers to access Synchroni products.
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
## Contributing
|
|
11
10
|
|
|
12
11
|
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
@@ -20,10 +19,10 @@ MIT
|
|
|
20
19
|
## Installation
|
|
21
20
|
|
|
22
21
|
```sh
|
|
23
|
-
pip install
|
|
22
|
+
pip install sensor-sdk
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
## 1. Permission
|
|
25
|
+
## 1. Permission
|
|
27
26
|
|
|
28
27
|
Application will obtain bluetooth permission by itself.
|
|
29
28
|
|
|
@@ -33,58 +32,66 @@ Application will obtain bluetooth permission by itself.
|
|
|
33
32
|
from sensor import *
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
## SensorController methods
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
### 1. Initalize
|
|
39
38
|
|
|
40
39
|
```python
|
|
41
|
-
|
|
40
|
+
SensorControllerInstance = SensorController()
|
|
42
41
|
|
|
43
42
|
# register scan listener
|
|
44
|
-
if not
|
|
45
|
-
def on_device_callback(
|
|
43
|
+
if not SensorControllerInstance.hasDeviceFoundCallback:
|
|
44
|
+
def on_device_callback(deviceList: List[BLEDevice]):
|
|
46
45
|
# return all devices doesn't connected
|
|
47
46
|
pass
|
|
48
|
-
|
|
47
|
+
SensorControllerInstance.onDeviceFoundCallback = on_device_callback
|
|
49
48
|
```
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
### 2. Start scan
|
|
51
|
+
|
|
52
|
+
Use `def startScan(period_in_ms: int) -> bool` to start scan
|
|
53
|
+
|
|
53
54
|
```python
|
|
54
|
-
success =
|
|
55
|
+
success = SensorControllerInstance.startScan(6000)
|
|
55
56
|
```
|
|
57
|
+
|
|
56
58
|
returns true if start scan success, periodInMS means onDeviceCallback will be called every periodInMS
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
### 3. Stop scan
|
|
61
|
+
|
|
62
|
+
Use `def stopScan() -> None` to stop scan
|
|
59
63
|
|
|
60
|
-
Use `async def stop_scan() -> None` to stop scan
|
|
61
64
|
```python
|
|
62
|
-
|
|
65
|
+
SensorControllerInstance.stopScan()
|
|
63
66
|
```
|
|
64
|
-
|
|
67
|
+
|
|
68
|
+
### 4. Check scaning
|
|
65
69
|
|
|
66
70
|
Use `property isScanning: bool` to check scanning status
|
|
71
|
+
|
|
67
72
|
```python
|
|
68
|
-
isScanning =
|
|
73
|
+
isScanning = SensorControllerInstance.isScanning
|
|
69
74
|
```
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
### 5. Check if bluetooth is enabled
|
|
72
77
|
|
|
73
78
|
Use `property isEnabled: bool` to check if bluetooth is enabled
|
|
79
|
+
|
|
74
80
|
```python
|
|
75
|
-
isEnabled =
|
|
81
|
+
isEnabled = SensorControllerInstance.isEnabled
|
|
76
82
|
```
|
|
77
|
-
|
|
83
|
+
|
|
84
|
+
### 6. Create SensorProfile
|
|
78
85
|
|
|
79
86
|
Use `def requireSensor(device: BLEDevice) -> SensorProfile | None` to create SensorProfile.
|
|
80
87
|
|
|
81
88
|
If bleDevice is invalid, result is None.
|
|
82
89
|
|
|
83
90
|
```python
|
|
84
|
-
sensorProfile =
|
|
91
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
85
92
|
```
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
### 7. Get SensorProfile
|
|
88
95
|
|
|
89
96
|
Use `def getSensor(device: BLEDevice) -> SensorProfile | None` to get SensorProfile.
|
|
90
97
|
|
|
@@ -94,26 +101,48 @@ If SensorProfile didn't created, result is None.
|
|
|
94
101
|
sensorProfile = SensorControllerInstance.getSensor(bleDevice)
|
|
95
102
|
```
|
|
96
103
|
|
|
97
|
-
|
|
104
|
+
### 8. Get Connected SensorProfiles
|
|
98
105
|
|
|
99
106
|
Use `def getConnectedSensors() -> list[SensorProfile]` to get connected SensorProfiles.
|
|
107
|
+
|
|
100
108
|
```python
|
|
101
109
|
sensorProfiles = SensorControllerInstance.getConnectedSensors()
|
|
102
110
|
```
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
### 9. Get Connected BLE Devices
|
|
105
113
|
|
|
106
114
|
Use `def getConnectedDevices() -> list[SensorProfile]` to get connected BLE Devices.
|
|
115
|
+
|
|
107
116
|
```python
|
|
108
117
|
bleDevices = SensorControllerInstance.getConnectedDevices()
|
|
109
118
|
```
|
|
110
119
|
|
|
111
|
-
|
|
120
|
+
### 10. Terminate
|
|
121
|
+
|
|
122
|
+
Use `def terminate()` to terminate sdk
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
|
|
126
|
+
def terminate():
|
|
127
|
+
SensorControllerInstance.terminate()
|
|
128
|
+
exit()
|
|
129
|
+
|
|
130
|
+
def main():
|
|
131
|
+
signal.signal(signal.SIGINT, lambda signal, frame: terminate())
|
|
132
|
+
time.sleep(30)
|
|
133
|
+
SensorControllerInstance.terminate()
|
|
134
|
+
|
|
135
|
+
Please MAKE SURE to call terminate when exit main() or press Ctrl+C
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## SensorProfile methods
|
|
139
|
+
|
|
140
|
+
### 11. Initalize
|
|
112
141
|
|
|
113
|
-
## 1. Initalize
|
|
114
142
|
Please register callbacks for SensorProfile
|
|
143
|
+
|
|
115
144
|
```python
|
|
116
|
-
sensorProfile =
|
|
145
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
117
146
|
|
|
118
147
|
# register callbacks
|
|
119
148
|
def on_state_changed(sensor, newState):
|
|
@@ -138,26 +167,30 @@ sensorProfile.onPowerChanged = on_power_changed
|
|
|
138
167
|
sensorProfile.onDataCallback = on_data_callback
|
|
139
168
|
```
|
|
140
169
|
|
|
141
|
-
|
|
142
|
-
|
|
170
|
+
### 12. Connect device
|
|
171
|
+
|
|
172
|
+
Use `def connect() -> bool` to connect.
|
|
173
|
+
|
|
143
174
|
```python
|
|
144
|
-
success =
|
|
175
|
+
success = sensorProfile.connect()
|
|
145
176
|
```
|
|
146
177
|
|
|
147
|
-
|
|
148
|
-
|
|
178
|
+
### 13. Disconnect
|
|
179
|
+
|
|
180
|
+
Use `def disconnect() -> bool` to disconnect.
|
|
181
|
+
|
|
149
182
|
```python
|
|
150
|
-
success =
|
|
183
|
+
success = sensorProfile.disconnect()
|
|
151
184
|
```
|
|
152
185
|
|
|
186
|
+
### 14. Get device status
|
|
153
187
|
|
|
154
|
-
|
|
155
|
-
Use `property connectionState: DeviceStateEx` to get device status.
|
|
188
|
+
Use `property deviceState: DeviceStateEx` to get device status.
|
|
156
189
|
|
|
157
190
|
Please send command in 'Ready' state, should be after connect() return True.
|
|
158
191
|
|
|
159
192
|
```python
|
|
160
|
-
deviceStateEx = sensorProfile.
|
|
193
|
+
deviceStateEx = sensorProfile.deviceState
|
|
161
194
|
|
|
162
195
|
# deviceStateEx has define:
|
|
163
196
|
# class DeviceStateEx(Enum):
|
|
@@ -169,21 +202,22 @@ deviceStateEx = sensorProfile.connectionState
|
|
|
169
202
|
# Invalid = 5
|
|
170
203
|
```
|
|
171
204
|
|
|
205
|
+
### 15. Get BLE device of SensorProfile
|
|
172
206
|
|
|
173
|
-
|
|
174
|
-
## 5. Get BLE device of SensorProfile
|
|
175
207
|
Use `property BLEDevice: BLEDevice` to get BLE device of SensorProfile.
|
|
208
|
+
|
|
176
209
|
```python
|
|
177
210
|
bleDevice = sensorProfile.BLEDevice
|
|
178
211
|
```
|
|
179
212
|
|
|
180
|
-
|
|
181
|
-
|
|
213
|
+
### 16. Get device info of SensorProfile
|
|
214
|
+
|
|
215
|
+
Use `def getDeviceInfo() -> dict | None` to get device info of SensorProfile.
|
|
182
216
|
|
|
183
217
|
Please call after device in 'Ready' state, return None if it's not connected.
|
|
184
218
|
|
|
185
219
|
```python
|
|
186
|
-
deviceInfo =
|
|
220
|
+
deviceInfo = sensorProfile.getDeviceInfo()
|
|
187
221
|
|
|
188
222
|
# deviceInfo has defines:
|
|
189
223
|
# deviceInfo = {
|
|
@@ -201,31 +235,37 @@ Please call after device in 'Ready' state, return None if it's not connected.
|
|
|
201
235
|
# }
|
|
202
236
|
```
|
|
203
237
|
|
|
238
|
+
### 17. Init data transfer
|
|
204
239
|
|
|
205
|
-
|
|
206
|
-
Use `async def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
240
|
+
Use `def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
207
241
|
|
|
208
242
|
Please call after device in 'Ready' state, return True if init succeed.
|
|
243
|
+
|
|
209
244
|
```python
|
|
210
|
-
success =
|
|
245
|
+
success = sensorProfile.init(5, 60*1000)
|
|
211
246
|
```
|
|
247
|
+
|
|
212
248
|
packageSampleCount: set sample counts of SensorData.channelSamples in onDataCallback()
|
|
213
249
|
powerRefreshInterval: callback period for onPowerChanged()
|
|
214
250
|
|
|
215
|
-
|
|
251
|
+
### 18. Check if init data transfer succeed
|
|
252
|
+
|
|
216
253
|
Use `property hasInited: bool` to check if init data transfer succeed.
|
|
254
|
+
|
|
217
255
|
```python
|
|
218
256
|
hasInited = sensorProfile.hasInited
|
|
219
257
|
```
|
|
220
258
|
|
|
221
|
-
|
|
222
|
-
|
|
259
|
+
### 19. DataNotify
|
|
260
|
+
|
|
261
|
+
Use `def startDataNotification() -> bool` to start data notification.
|
|
223
262
|
|
|
224
263
|
Please call if hasInited return True
|
|
225
|
-
|
|
264
|
+
|
|
265
|
+
#### 19.1 Start data transfer
|
|
226
266
|
|
|
227
267
|
```python
|
|
228
|
-
success =
|
|
268
|
+
success = sensorProfile.startDataNotification()
|
|
229
269
|
```
|
|
230
270
|
|
|
231
271
|
Data type list:
|
|
@@ -262,25 +302,30 @@ def on_data_callback(sensor, data):
|
|
|
262
302
|
sensorProfile.onDataCallback = on_data_callback
|
|
263
303
|
```
|
|
264
304
|
|
|
265
|
-
|
|
266
|
-
|
|
305
|
+
#### 19.2 Stop data transfer
|
|
306
|
+
|
|
307
|
+
Use `def stopDataNotification() -> bool` to stop data transfer.
|
|
308
|
+
|
|
267
309
|
```python
|
|
268
|
-
success =
|
|
310
|
+
success = sensorProfile.stopDataNotification()
|
|
269
311
|
```
|
|
270
312
|
|
|
271
|
-
|
|
313
|
+
#### 19.3 Check if it's data transfering
|
|
314
|
+
|
|
272
315
|
Use `property isDataTransfering: bool` to check if it's data transfering.
|
|
316
|
+
|
|
273
317
|
```python
|
|
274
318
|
isDataTransfering = sensorProfile.isDataTransfering
|
|
275
319
|
```
|
|
276
320
|
|
|
277
|
-
|
|
278
|
-
|
|
321
|
+
### 20. Get battery level
|
|
322
|
+
|
|
323
|
+
Use `def getBatteryLevel() -> int` to get battery level. Please call after device in 'Ready' state.
|
|
279
324
|
|
|
280
325
|
```python
|
|
281
|
-
batteryPower =
|
|
326
|
+
batteryPower = sensorProfile.getBatteryLevel()
|
|
282
327
|
|
|
283
328
|
# batteryPower is battery level returned, value ranges from 0 to 100, 0 means out of battery, while 100 means full.
|
|
284
329
|
```
|
|
285
330
|
|
|
286
|
-
Please check
|
|
331
|
+
Please check console.py in examples directory
|
|
@@ -61,7 +61,7 @@ class SensorController:
|
|
|
61
61
|
def terminate(self):
|
|
62
62
|
for sensor in self._sensor_profiles.values():
|
|
63
63
|
if sensor.deviceState == DeviceStateEx.Connected or sensor.deviceState == DeviceStateEx.Ready:
|
|
64
|
-
sensor.
|
|
64
|
+
sensor._destroy()
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
def _match_device(self, _device: bleak.BLEDevice, adv: AdvertisementData):
|
|
@@ -104,7 +104,7 @@ class SensorController:
|
|
|
104
104
|
self._enable_callback = callback
|
|
105
105
|
|
|
106
106
|
@property
|
|
107
|
-
def
|
|
107
|
+
def hasDeviceFoundCallback(self) -> bool:
|
|
108
108
|
"""
|
|
109
109
|
检查是否有扫描设备回调。
|
|
110
110
|
|
|
@@ -112,7 +112,7 @@ class SensorController:
|
|
|
112
112
|
"""
|
|
113
113
|
return self._device_callback != None
|
|
114
114
|
|
|
115
|
-
@
|
|
115
|
+
@hasDeviceFoundCallback.setter
|
|
116
116
|
def onDeviceFoundCallback(self, callback: Callable[[List[sensor_profile.BLEDevice]], None]):
|
|
117
117
|
"""
|
|
118
118
|
设置扫描设备回调。
|
|
@@ -375,8 +375,8 @@ class SensorProfileDataCtx:
|
|
|
375
375
|
saturation = 0.0
|
|
376
376
|
if sensorData.dataType == DataType.NTF_ECG:
|
|
377
377
|
impedanceChannelIndex = self.sensorDatas[SensorDataType.DATA_TYPE_EEG].channelCount
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
impedance = _impedanceData[impedanceChannelIndex]
|
|
379
|
+
saturation = _saturationData[impedanceChannelIndex]
|
|
380
380
|
impedanceChannelIndex += 1
|
|
381
381
|
|
|
382
382
|
dataItem = Sample()
|
|
@@ -70,9 +70,9 @@ class SensorProfile:
|
|
|
70
70
|
反初始化 SensorProfile 类的实例。
|
|
71
71
|
|
|
72
72
|
"""
|
|
73
|
-
self.
|
|
73
|
+
self._destroy()
|
|
74
74
|
|
|
75
|
-
def
|
|
75
|
+
def _destroy(self):
|
|
76
76
|
if self._device_state == DeviceStateEx.Connected or self._device_state == DeviceStateEx.Ready:
|
|
77
77
|
self.disconnect()
|
|
78
78
|
if (self._data_event_loop != None):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sensor-sdk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Python sdk for Synchroni
|
|
5
5
|
Home-page: https://github.com/oymotion/SynchroniSDKPython
|
|
6
6
|
Author: Martin Ye
|
|
@@ -9,7 +9,7 @@ Requires-Python: >=3.8.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.txt
|
|
11
11
|
|
|
12
|
-
#
|
|
12
|
+
# sensor-sdk
|
|
13
13
|
|
|
14
14
|
Synchroni sdk for Python
|
|
15
15
|
|
|
@@ -17,7 +17,6 @@ Synchroni sdk for Python
|
|
|
17
17
|
|
|
18
18
|
Synchroni SDK is the software development kit for developers to access Synchroni products.
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
## Contributing
|
|
22
21
|
|
|
23
22
|
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
@@ -31,10 +30,10 @@ MIT
|
|
|
31
30
|
## Installation
|
|
32
31
|
|
|
33
32
|
```sh
|
|
34
|
-
pip install
|
|
33
|
+
pip install sensor-sdk
|
|
35
34
|
```
|
|
36
35
|
|
|
37
|
-
## 1. Permission
|
|
36
|
+
## 1. Permission
|
|
38
37
|
|
|
39
38
|
Application will obtain bluetooth permission by itself.
|
|
40
39
|
|
|
@@ -44,58 +43,66 @@ Application will obtain bluetooth permission by itself.
|
|
|
44
43
|
from sensor import *
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
## SensorController methods
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
### 1. Initalize
|
|
50
49
|
|
|
51
50
|
```python
|
|
52
|
-
|
|
51
|
+
SensorControllerInstance = SensorController()
|
|
53
52
|
|
|
54
53
|
# register scan listener
|
|
55
|
-
if not
|
|
56
|
-
def on_device_callback(
|
|
54
|
+
if not SensorControllerInstance.hasDeviceFoundCallback:
|
|
55
|
+
def on_device_callback(deviceList: List[BLEDevice]):
|
|
57
56
|
# return all devices doesn't connected
|
|
58
57
|
pass
|
|
59
|
-
|
|
58
|
+
SensorControllerInstance.onDeviceFoundCallback = on_device_callback
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
### 2. Start scan
|
|
62
|
+
|
|
63
|
+
Use `def startScan(period_in_ms: int) -> bool` to start scan
|
|
64
|
+
|
|
64
65
|
```python
|
|
65
|
-
success =
|
|
66
|
+
success = SensorControllerInstance.startScan(6000)
|
|
66
67
|
```
|
|
68
|
+
|
|
67
69
|
returns true if start scan success, periodInMS means onDeviceCallback will be called every periodInMS
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
### 3. Stop scan
|
|
72
|
+
|
|
73
|
+
Use `def stopScan() -> None` to stop scan
|
|
70
74
|
|
|
71
|
-
Use `async def stop_scan() -> None` to stop scan
|
|
72
75
|
```python
|
|
73
|
-
|
|
76
|
+
SensorControllerInstance.stopScan()
|
|
74
77
|
```
|
|
75
|
-
|
|
78
|
+
|
|
79
|
+
### 4. Check scaning
|
|
76
80
|
|
|
77
81
|
Use `property isScanning: bool` to check scanning status
|
|
82
|
+
|
|
78
83
|
```python
|
|
79
|
-
isScanning =
|
|
84
|
+
isScanning = SensorControllerInstance.isScanning
|
|
80
85
|
```
|
|
81
86
|
|
|
82
|
-
|
|
87
|
+
### 5. Check if bluetooth is enabled
|
|
83
88
|
|
|
84
89
|
Use `property isEnabled: bool` to check if bluetooth is enabled
|
|
90
|
+
|
|
85
91
|
```python
|
|
86
|
-
isEnabled =
|
|
92
|
+
isEnabled = SensorControllerInstance.isEnabled
|
|
87
93
|
```
|
|
88
|
-
|
|
94
|
+
|
|
95
|
+
### 6. Create SensorProfile
|
|
89
96
|
|
|
90
97
|
Use `def requireSensor(device: BLEDevice) -> SensorProfile | None` to create SensorProfile.
|
|
91
98
|
|
|
92
99
|
If bleDevice is invalid, result is None.
|
|
93
100
|
|
|
94
101
|
```python
|
|
95
|
-
sensorProfile =
|
|
102
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
96
103
|
```
|
|
97
104
|
|
|
98
|
-
|
|
105
|
+
### 7. Get SensorProfile
|
|
99
106
|
|
|
100
107
|
Use `def getSensor(device: BLEDevice) -> SensorProfile | None` to get SensorProfile.
|
|
101
108
|
|
|
@@ -105,26 +112,48 @@ If SensorProfile didn't created, result is None.
|
|
|
105
112
|
sensorProfile = SensorControllerInstance.getSensor(bleDevice)
|
|
106
113
|
```
|
|
107
114
|
|
|
108
|
-
|
|
115
|
+
### 8. Get Connected SensorProfiles
|
|
109
116
|
|
|
110
117
|
Use `def getConnectedSensors() -> list[SensorProfile]` to get connected SensorProfiles.
|
|
118
|
+
|
|
111
119
|
```python
|
|
112
120
|
sensorProfiles = SensorControllerInstance.getConnectedSensors()
|
|
113
121
|
```
|
|
114
122
|
|
|
115
|
-
|
|
123
|
+
### 9. Get Connected BLE Devices
|
|
116
124
|
|
|
117
125
|
Use `def getConnectedDevices() -> list[SensorProfile]` to get connected BLE Devices.
|
|
126
|
+
|
|
118
127
|
```python
|
|
119
128
|
bleDevices = SensorControllerInstance.getConnectedDevices()
|
|
120
129
|
```
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
### 10. Terminate
|
|
132
|
+
|
|
133
|
+
Use `def terminate()` to terminate sdk
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
|
|
137
|
+
def terminate():
|
|
138
|
+
SensorControllerInstance.terminate()
|
|
139
|
+
exit()
|
|
140
|
+
|
|
141
|
+
def main():
|
|
142
|
+
signal.signal(signal.SIGINT, lambda signal, frame: terminate())
|
|
143
|
+
time.sleep(30)
|
|
144
|
+
SensorControllerInstance.terminate()
|
|
145
|
+
|
|
146
|
+
Please MAKE SURE to call terminate when exit main() or press Ctrl+C
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## SensorProfile methods
|
|
150
|
+
|
|
151
|
+
### 11. Initalize
|
|
123
152
|
|
|
124
|
-
## 1. Initalize
|
|
125
153
|
Please register callbacks for SensorProfile
|
|
154
|
+
|
|
126
155
|
```python
|
|
127
|
-
sensorProfile =
|
|
156
|
+
sensorProfile = SensorControllerInstance.requireSensor(bleDevice)
|
|
128
157
|
|
|
129
158
|
# register callbacks
|
|
130
159
|
def on_state_changed(sensor, newState):
|
|
@@ -149,26 +178,30 @@ sensorProfile.onPowerChanged = on_power_changed
|
|
|
149
178
|
sensorProfile.onDataCallback = on_data_callback
|
|
150
179
|
```
|
|
151
180
|
|
|
152
|
-
|
|
153
|
-
|
|
181
|
+
### 12. Connect device
|
|
182
|
+
|
|
183
|
+
Use `def connect() -> bool` to connect.
|
|
184
|
+
|
|
154
185
|
```python
|
|
155
|
-
success =
|
|
186
|
+
success = sensorProfile.connect()
|
|
156
187
|
```
|
|
157
188
|
|
|
158
|
-
|
|
159
|
-
|
|
189
|
+
### 13. Disconnect
|
|
190
|
+
|
|
191
|
+
Use `def disconnect() -> bool` to disconnect.
|
|
192
|
+
|
|
160
193
|
```python
|
|
161
|
-
success =
|
|
194
|
+
success = sensorProfile.disconnect()
|
|
162
195
|
```
|
|
163
196
|
|
|
197
|
+
### 14. Get device status
|
|
164
198
|
|
|
165
|
-
|
|
166
|
-
Use `property connectionState: DeviceStateEx` to get device status.
|
|
199
|
+
Use `property deviceState: DeviceStateEx` to get device status.
|
|
167
200
|
|
|
168
201
|
Please send command in 'Ready' state, should be after connect() return True.
|
|
169
202
|
|
|
170
203
|
```python
|
|
171
|
-
deviceStateEx = sensorProfile.
|
|
204
|
+
deviceStateEx = sensorProfile.deviceState
|
|
172
205
|
|
|
173
206
|
# deviceStateEx has define:
|
|
174
207
|
# class DeviceStateEx(Enum):
|
|
@@ -180,21 +213,22 @@ deviceStateEx = sensorProfile.connectionState
|
|
|
180
213
|
# Invalid = 5
|
|
181
214
|
```
|
|
182
215
|
|
|
216
|
+
### 15. Get BLE device of SensorProfile
|
|
183
217
|
|
|
184
|
-
|
|
185
|
-
## 5. Get BLE device of SensorProfile
|
|
186
218
|
Use `property BLEDevice: BLEDevice` to get BLE device of SensorProfile.
|
|
219
|
+
|
|
187
220
|
```python
|
|
188
221
|
bleDevice = sensorProfile.BLEDevice
|
|
189
222
|
```
|
|
190
223
|
|
|
191
|
-
|
|
192
|
-
|
|
224
|
+
### 16. Get device info of SensorProfile
|
|
225
|
+
|
|
226
|
+
Use `def getDeviceInfo() -> dict | None` to get device info of SensorProfile.
|
|
193
227
|
|
|
194
228
|
Please call after device in 'Ready' state, return None if it's not connected.
|
|
195
229
|
|
|
196
230
|
```python
|
|
197
|
-
deviceInfo =
|
|
231
|
+
deviceInfo = sensorProfile.getDeviceInfo()
|
|
198
232
|
|
|
199
233
|
# deviceInfo has defines:
|
|
200
234
|
# deviceInfo = {
|
|
@@ -212,31 +246,37 @@ Please call after device in 'Ready' state, return None if it's not connected.
|
|
|
212
246
|
# }
|
|
213
247
|
```
|
|
214
248
|
|
|
249
|
+
### 17. Init data transfer
|
|
215
250
|
|
|
216
|
-
|
|
217
|
-
Use `async def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
251
|
+
Use `def init(packageSampleCount: int, powerRefreshInterval: int) -> bool`.
|
|
218
252
|
|
|
219
253
|
Please call after device in 'Ready' state, return True if init succeed.
|
|
254
|
+
|
|
220
255
|
```python
|
|
221
|
-
success =
|
|
256
|
+
success = sensorProfile.init(5, 60*1000)
|
|
222
257
|
```
|
|
258
|
+
|
|
223
259
|
packageSampleCount: set sample counts of SensorData.channelSamples in onDataCallback()
|
|
224
260
|
powerRefreshInterval: callback period for onPowerChanged()
|
|
225
261
|
|
|
226
|
-
|
|
262
|
+
### 18. Check if init data transfer succeed
|
|
263
|
+
|
|
227
264
|
Use `property hasInited: bool` to check if init data transfer succeed.
|
|
265
|
+
|
|
228
266
|
```python
|
|
229
267
|
hasInited = sensorProfile.hasInited
|
|
230
268
|
```
|
|
231
269
|
|
|
232
|
-
|
|
233
|
-
|
|
270
|
+
### 19. DataNotify
|
|
271
|
+
|
|
272
|
+
Use `def startDataNotification() -> bool` to start data notification.
|
|
234
273
|
|
|
235
274
|
Please call if hasInited return True
|
|
236
|
-
|
|
275
|
+
|
|
276
|
+
#### 19.1 Start data transfer
|
|
237
277
|
|
|
238
278
|
```python
|
|
239
|
-
success =
|
|
279
|
+
success = sensorProfile.startDataNotification()
|
|
240
280
|
```
|
|
241
281
|
|
|
242
282
|
Data type list:
|
|
@@ -273,25 +313,30 @@ def on_data_callback(sensor, data):
|
|
|
273
313
|
sensorProfile.onDataCallback = on_data_callback
|
|
274
314
|
```
|
|
275
315
|
|
|
276
|
-
|
|
277
|
-
|
|
316
|
+
#### 19.2 Stop data transfer
|
|
317
|
+
|
|
318
|
+
Use `def stopDataNotification() -> bool` to stop data transfer.
|
|
319
|
+
|
|
278
320
|
```python
|
|
279
|
-
success =
|
|
321
|
+
success = sensorProfile.stopDataNotification()
|
|
280
322
|
```
|
|
281
323
|
|
|
282
|
-
|
|
324
|
+
#### 19.3 Check if it's data transfering
|
|
325
|
+
|
|
283
326
|
Use `property isDataTransfering: bool` to check if it's data transfering.
|
|
327
|
+
|
|
284
328
|
```python
|
|
285
329
|
isDataTransfering = sensorProfile.isDataTransfering
|
|
286
330
|
```
|
|
287
331
|
|
|
288
|
-
|
|
289
|
-
|
|
332
|
+
### 20. Get battery level
|
|
333
|
+
|
|
334
|
+
Use `def getBatteryLevel() -> int` to get battery level. Please call after device in 'Ready' state.
|
|
290
335
|
|
|
291
336
|
```python
|
|
292
|
-
batteryPower =
|
|
337
|
+
batteryPower = sensorProfile.getBatteryLevel()
|
|
293
338
|
|
|
294
339
|
# batteryPower is battery level returned, value ranges from 0 to 100, 0 means out of battery, while 100 means full.
|
|
295
340
|
```
|
|
296
341
|
|
|
297
|
-
Please check
|
|
342
|
+
Please check console.py in examples directory
|
|
@@ -8,7 +8,7 @@ with open(os.path.join(this_directory, 'README.md'), "r", encoding="utf-8") as f
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name='sensor-sdk',
|
|
11
|
-
version='0.0.
|
|
11
|
+
version='0.0.3',
|
|
12
12
|
description='Python sdk for Synchroni',
|
|
13
13
|
long_description=long_description,
|
|
14
14
|
long_description_content_type='text/markdown',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|