python-selve-new 2.4.0__tar.gz → 2.5.1__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.
- python_selve_new-2.5.1/CHANGELOG.md +34 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/PKG-INFO +14 -1
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/README.md +12 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/pyproject.toml +2 -4
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/PKG-INFO +14 -1
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/SOURCES.txt +2 -1
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/__init__.py +134 -8
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/_version.py +3 -3
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/command.py +4 -0
- python_selve_new-2.5.1/selve/commands/firmware.py +24 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/param.py +33 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/__init__.py +9 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_edge_cases.py +2 -2
- python_selve_new-2.4.0/python_selve_new.egg-info/entry_points.txt +0 -2
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/FUNDING.yml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/architect.chatmode.md +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/ask.chatmode.md +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/code.chatmode.md +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/debug.chatmode.md +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/workflows/python-publish.yml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/workflows/tests.yml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.gitignore +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/.gitignore +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/misc.xml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/modules.xml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/python-selve-new.iml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/vcs.xml +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/LICENSE +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/coverage_xdist_example.txt +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/debug_response.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/debug_test.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/direct_hardware_test.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/direct_hardware_test.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/generate_coverage.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/package.sh +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/dependency_links.txt +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/requires.txt +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/top_level.txt +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/release.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_all_tests.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_hardware_tests.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_integration_tests.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_mock_tests.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_single_test.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_tests.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/__init__.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/device.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/event.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/group.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/iveo.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/senSim.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/sender.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/sensor.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/service.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/device.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/gateway.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/group.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/iveo.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/senSim.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/sender.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/sensor.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/errors.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/protocol.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/serial_transport.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup.cfg +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup_and_test.bat +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/__init__.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/conftest.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/README.md +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/__init__.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/conftest.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_device_integration.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_gateway_integration.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_hardware.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_integration.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/test_import.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/test_replacement.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/__init__.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/mock_utils.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_command_coverage.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_commands.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_classes_coverage.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_commands_extended.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_configuration_issues.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_error_handling_fixed.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_group.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_group_commands.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_missing_components.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_commands.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_devices_and_groups.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_sensors_and_senders.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_param_commands_extended.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_port_discovery.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_advanced_coverage.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_core_coverage.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_gateway.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_comprehensive.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_response_coverage.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_simple.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_main_class_extensive.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sender_commands_extended.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensim_commands_extended.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensor_commands_extended.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_service_command_errors.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_service_commands.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_util.py +0 -0
- {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_utility_coverage.py +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [2.5.0] - 2026-02-11
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Firmware commands**: `FirmwareGetVersion`, `FirmwareUpdate` with response classes for gateway firmware management.
|
|
9
|
+
- **Parameter commands**: `ParamSetDuty`, `ParamSetRf`, `ParamGetTemperature` with response classes for duty cycle, RF configuration, and temperature readout.
|
|
10
|
+
- **Command result**: `CommandResult` command class for retrieving pending command results.
|
|
11
|
+
- **Enums**: `CommeoFirmwareCommand` enum, `FIRMWARE` entry in `CommandType`, `SETDUTY`/`SETRF`/`GETTEMPERATURE` in `CommeoParamCommand`.
|
|
12
|
+
- **Controller methods**: `firmwareGetVersion()`, `firmwareUpdate()`, `setDuty()`, `setRF()`, `getTemperature()`, `deviceSavePos1()`, `deviceSavePos2()`, `commandResult()`, `iveoSetConfig()`, `iveoGetConfig()`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Group name discovery bug**: During `setup(discover=True)`, groups now correctly use `config.groupName` instead of `config.name` (which returned the XML-RPC method name `selve.GW.group.read` instead of the actual group name).
|
|
16
|
+
- **`iveoTeach()` / `iveoFactoryReset()`**: Now correctly accept `id` parameter (was missing, causing TypeError).
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- `GroupReadResponse` attribute renamed from `name` to `groupName` to avoid collision with the inherited `MethodResponse.name` (XML method name).
|
|
20
|
+
|
|
21
|
+
## [2.4.0] - 2025-01-15
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- senSim device support (simulated sensors)
|
|
25
|
+
- Sender teach/write/delete services
|
|
26
|
+
- Sensor teach/write/delete services
|
|
27
|
+
- Comprehensive device management (scan, save, delete, write manual)
|
|
28
|
+
- Group management (read, write, delete, move commands)
|
|
29
|
+
- IVEO teach/learn/repeater services
|
|
30
|
+
- Gateway parameter services (events, forwarding, LED, duty, RF)
|
|
31
|
+
|
|
32
|
+
## [2.3.6] - Previous releases
|
|
33
|
+
|
|
34
|
+
See git history for earlier changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-selve-new
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.1
|
|
4
4
|
Summary: Python library for interfacing with selve devices using the USB-RF controller. Written completely new.
|
|
5
5
|
Home-page: https://github.com/Kannix2005/python-selve-new
|
|
6
6
|
Author: Stefan Altheimer
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
20
|
Requires-Python: >=3.9
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
License-File: LICENSE
|
|
@@ -170,6 +171,18 @@ name = device.name # Device name
|
|
|
170
171
|
device_type = device.type # Device type
|
|
171
172
|
```
|
|
172
173
|
|
|
174
|
+
### Gateway & Firmware Methods
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# Firmware
|
|
178
|
+
version = await controller.firmwareGetVersion() # Gateway firmware version
|
|
179
|
+
|
|
180
|
+
# Gateway parameters
|
|
181
|
+
await controller.setDuty(mode) # Set duty cycle mode
|
|
182
|
+
await controller.setRF(addr) # Set RF base address
|
|
183
|
+
temp = await controller.getTemperature() # Internal gateway temperature
|
|
184
|
+
```
|
|
185
|
+
|
|
173
186
|
## Home Assistant Integration
|
|
174
187
|
|
|
175
188
|
This library is used by the [homeassistant-selve](https://github.com/Kannix2005/homeassistant-selve) integration to provide native Selve device support in Home Assistant.
|
|
@@ -139,6 +139,18 @@ name = device.name # Device name
|
|
|
139
139
|
device_type = device.type # Device type
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
### Gateway & Firmware Methods
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Firmware
|
|
146
|
+
version = await controller.firmwareGetVersion() # Gateway firmware version
|
|
147
|
+
|
|
148
|
+
# Gateway parameters
|
|
149
|
+
await controller.setDuty(mode) # Set duty cycle mode
|
|
150
|
+
await controller.setRF(addr) # Set RF base address
|
|
151
|
+
temp = await controller.getTemperature() # Internal gateway temperature
|
|
152
|
+
```
|
|
153
|
+
|
|
142
154
|
## Home Assistant Integration
|
|
143
155
|
|
|
144
156
|
This library is used by the [homeassistant-selve](https://github.com/Kannix2005/homeassistant-selve) integration to provide native Selve device support in Home Assistant.
|
|
@@ -26,7 +26,8 @@ classifiers = [
|
|
|
26
26
|
"Programming Language :: Python :: 3.9",
|
|
27
27
|
"Programming Language :: Python :: 3.10",
|
|
28
28
|
"Programming Language :: Python :: 3.11",
|
|
29
|
-
"Programming Language :: Python :: 3.12"
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13"
|
|
30
31
|
]
|
|
31
32
|
dependencies = [
|
|
32
33
|
"requests",
|
|
@@ -38,9 +39,6 @@ dependencies = [
|
|
|
38
39
|
]
|
|
39
40
|
dynamic = ["version"]
|
|
40
41
|
|
|
41
|
-
[project.scripts]
|
|
42
|
-
my-script = "my_package.module:function"
|
|
43
|
-
|
|
44
42
|
# ... other project metadata fields as listed in:
|
|
45
43
|
# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
|
|
46
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-selve-new
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.1
|
|
4
4
|
Summary: Python library for interfacing with selve devices using the USB-RF controller. Written completely new.
|
|
5
5
|
Home-page: https://github.com/Kannix2005/python-selve-new
|
|
6
6
|
Author: Stefan Altheimer
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
20
|
Requires-Python: >=3.9
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
License-File: LICENSE
|
|
@@ -170,6 +171,18 @@ name = device.name # Device name
|
|
|
170
171
|
device_type = device.type # Device type
|
|
171
172
|
```
|
|
172
173
|
|
|
174
|
+
### Gateway & Firmware Methods
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
# Firmware
|
|
178
|
+
version = await controller.firmwareGetVersion() # Gateway firmware version
|
|
179
|
+
|
|
180
|
+
# Gateway parameters
|
|
181
|
+
await controller.setDuty(mode) # Set duty cycle mode
|
|
182
|
+
await controller.setRF(addr) # Set RF base address
|
|
183
|
+
temp = await controller.getTemperature() # Internal gateway temperature
|
|
184
|
+
```
|
|
185
|
+
|
|
173
186
|
## Home Assistant Integration
|
|
174
187
|
|
|
175
188
|
This library is used by the [homeassistant-selve](https://github.com/Kannix2005/homeassistant-selve) integration to provide native Selve device support in Home Assistant.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
.gitignore
|
|
2
|
+
CHANGELOG.md
|
|
2
3
|
LICENSE
|
|
3
4
|
README.md
|
|
4
5
|
coverage_xdist_example.txt
|
|
@@ -34,7 +35,6 @@ setup_and_test.bat
|
|
|
34
35
|
python_selve_new.egg-info/PKG-INFO
|
|
35
36
|
python_selve_new.egg-info/SOURCES.txt
|
|
36
37
|
python_selve_new.egg-info/dependency_links.txt
|
|
37
|
-
python_selve_new.egg-info/entry_points.txt
|
|
38
38
|
python_selve_new.egg-info/requires.txt
|
|
39
39
|
python_selve_new.egg-info/top_level.txt
|
|
40
40
|
selve/__init__.py
|
|
@@ -50,6 +50,7 @@ selve/commands/__init__.py
|
|
|
50
50
|
selve/commands/command.py
|
|
51
51
|
selve/commands/device.py
|
|
52
52
|
selve/commands/event.py
|
|
53
|
+
selve/commands/firmware.py
|
|
53
54
|
selve/commands/group.py
|
|
54
55
|
selve/commands/iveo.py
|
|
55
56
|
selve/commands/param.py
|
|
@@ -36,6 +36,7 @@ from selve.commands.event import *
|
|
|
36
36
|
from selve.commands.senSim import *
|
|
37
37
|
from selve.commands.sensor import *
|
|
38
38
|
from selve.commands.sender import *
|
|
39
|
+
from selve.commands.firmware import *
|
|
39
40
|
from selve.device import SelveDevice
|
|
40
41
|
from selve.group import SelveGroup
|
|
41
42
|
from selve.iveo import IveoDevice
|
|
@@ -490,7 +491,7 @@ class Selve:
|
|
|
490
491
|
if isinstance(response, CommandResultResponse)\
|
|
491
492
|
or isinstance(response, IveoResultResponse):
|
|
492
493
|
#update device values
|
|
493
|
-
self.
|
|
494
|
+
self._handleCommandResult(response)
|
|
494
495
|
if isinstance(response, DeviceGetValuesResponse):
|
|
495
496
|
self.updateCommeoDeviceValuesFromResponse(int(response.parameters[1][1]), response)
|
|
496
497
|
if isinstance(response, SenderTeachResultResponse) \
|
|
@@ -571,10 +572,16 @@ class Selve:
|
|
|
571
572
|
return ParamSetEventResponse(methodName, flat_params_list)
|
|
572
573
|
if methodName == "selve.GW." + str(CommeoParamCommand.GETEVENT.value):
|
|
573
574
|
return ParamGetEventResponse(methodName, flat_params_list)
|
|
575
|
+
if methodName == "selve.GW." + str(CommeoParamCommand.SETDUTY.value):
|
|
576
|
+
return ParamSetDutyResponse(methodName, flat_params_list)
|
|
574
577
|
if methodName == "selve.GW." + str(CommeoParamCommand.GETDUTY.value):
|
|
575
578
|
return ParamGetDutyResponse(methodName, flat_params_list)
|
|
579
|
+
if methodName == "selve.GW." + str(CommeoParamCommand.SETRF.value):
|
|
580
|
+
return ParamSetRfResponse(methodName, flat_params_list)
|
|
576
581
|
if methodName == "selve.GW." + str(CommeoParamCommand.GETRF.value):
|
|
577
582
|
return ParamGetRfResponse(methodName, flat_params_list)
|
|
583
|
+
if methodName == "selve.GW." + str(CommeoParamCommand.GETTEMPERATURE.value):
|
|
584
|
+
return ParamGetTemperatureResponse(methodName, flat_params_list)
|
|
578
585
|
|
|
579
586
|
##Device
|
|
580
587
|
if methodName == "selve.GW." + str(CommeoDeviceCommand.SCANSTART.value):
|
|
@@ -714,6 +721,12 @@ class Selve:
|
|
|
714
721
|
if methodName == "selve.GW." + str(IveoCommand.RESULT.value):
|
|
715
722
|
return IveoResultResponse(methodName, flat_params_list)
|
|
716
723
|
|
|
724
|
+
##Firmware
|
|
725
|
+
if methodName == "selve.GW." + str(CommeoFirmwareCommand.GETVERSION.value):
|
|
726
|
+
return FirmwareGetVersionResponse(methodName, flat_params_list)
|
|
727
|
+
if methodName == "selve.GW." + str(CommeoFirmwareCommand.UPDATE.value):
|
|
728
|
+
return FirmwareUpdateResponse(methodName, flat_params_list)
|
|
729
|
+
|
|
717
730
|
##Events
|
|
718
731
|
if methodName == "selve.GW." + str(CommeoEventCommand.DEVICE.value):
|
|
719
732
|
return CommeoDeviceEventResponse(methodName, flat_params_list)
|
|
@@ -823,7 +836,7 @@ class Selve:
|
|
|
823
836
|
config: GroupReadResponse = await self.executeCommandSyncWithResponse(GroupRead(i))
|
|
824
837
|
device = SelveGroup(i)
|
|
825
838
|
device.device_type = SelveTypes.GROUP
|
|
826
|
-
device.name = config.
|
|
839
|
+
device.name = config.groupName
|
|
827
840
|
device.mask = config.mask
|
|
828
841
|
self.addOrUpdateDevice(device, SelveTypes.GROUP)
|
|
829
842
|
|
|
@@ -1060,7 +1073,7 @@ class Selve:
|
|
|
1060
1073
|
callback(response)
|
|
1061
1074
|
|
|
1062
1075
|
|
|
1063
|
-
def
|
|
1076
|
+
def _handleCommandResult(self, response: IveoResultResponse | CommandResultResponse):
|
|
1064
1077
|
|
|
1065
1078
|
# if isinstance(response, IveoResultResponse):
|
|
1066
1079
|
# for id in response.executedIds:
|
|
@@ -1234,6 +1247,21 @@ class Selve:
|
|
|
1234
1247
|
response: ParamGetRfResponse = await self.executeCommandSyncWithResponse(command)
|
|
1235
1248
|
return response
|
|
1236
1249
|
|
|
1250
|
+
async def setDuty(self, mode: int):
|
|
1251
|
+
command = ParamSetDuty(mode)
|
|
1252
|
+
response: ParamSetDutyResponse = await self.executeCommandSyncWithResponse(command)
|
|
1253
|
+
return response.executed
|
|
1254
|
+
|
|
1255
|
+
async def setRF(self, netAddress: int, resetCount: int):
|
|
1256
|
+
command = ParamSetRf(netAddress, resetCount)
|
|
1257
|
+
response: ParamSetRfResponse = await self.executeCommandSyncWithResponse(command)
|
|
1258
|
+
return response.executed
|
|
1259
|
+
|
|
1260
|
+
async def getTemperature(self):
|
|
1261
|
+
command = ParamGetTemperature()
|
|
1262
|
+
response: ParamGetTemperatureResponse = await self.executeCommandSyncWithResponse(command)
|
|
1263
|
+
return response
|
|
1264
|
+
|
|
1237
1265
|
|
|
1238
1266
|
|
|
1239
1267
|
##Device functions
|
|
@@ -1298,6 +1326,22 @@ class Selve:
|
|
|
1298
1326
|
response: DeviceWriteManualResponse = await self.executeCommandSyncWithResponse(command)
|
|
1299
1327
|
return response.executed
|
|
1300
1328
|
|
|
1329
|
+
async def deviceSavePos1(self, device: SelveDevice, type=DeviceCommandType.MANUAL):
|
|
1330
|
+
"""Save current position as Position 1 for the device."""
|
|
1331
|
+
await self.executeCommand(CommandSavePos1(device.id, type))
|
|
1332
|
+
await self.updateCommeoDeviceValuesAsync(device.id)
|
|
1333
|
+
|
|
1334
|
+
async def deviceSavePos2(self, device: SelveDevice, type=DeviceCommandType.MANUAL):
|
|
1335
|
+
"""Save current position as Position 2 for the device."""
|
|
1336
|
+
await self.executeCommand(CommandSavePos2(device.id, type))
|
|
1337
|
+
await self.updateCommeoDeviceValuesAsync(device.id)
|
|
1338
|
+
|
|
1339
|
+
async def commandResult(self):
|
|
1340
|
+
"""Query the result of the last command execution."""
|
|
1341
|
+
command = CommandResult()
|
|
1342
|
+
response: CommandResultResponse = await self.executeCommandSyncWithResponse(command)
|
|
1343
|
+
return response
|
|
1344
|
+
|
|
1301
1345
|
async def updateCommeoDeviceValues(self, id: int):
|
|
1302
1346
|
response: DeviceGetValuesResponse = await self.executeCommandSyncWithResponse(DeviceGetValues(id))
|
|
1303
1347
|
self.updateCommeoDeviceValuesFromResponse(id, response)
|
|
@@ -1533,13 +1577,13 @@ class Selve:
|
|
|
1533
1577
|
response: IveoGetIdsResponse = await self.executeCommandSyncWithResponse(command)
|
|
1534
1578
|
return response
|
|
1535
1579
|
|
|
1536
|
-
async def iveoFactoryReset(self):
|
|
1537
|
-
command = IveoFactory()
|
|
1580
|
+
async def iveoFactoryReset(self, id: int):
|
|
1581
|
+
command = IveoFactory(id)
|
|
1538
1582
|
response: IveoFactoryResponse = await self.executeCommandSyncWithResponse(command)
|
|
1539
1583
|
return response.executed
|
|
1540
1584
|
|
|
1541
|
-
async def iveoTeach(self):
|
|
1542
|
-
command = IveoTeach()
|
|
1585
|
+
async def iveoTeach(self, id: int):
|
|
1586
|
+
command = IveoTeach(id)
|
|
1543
1587
|
response: IveoTeachResponse = await self.executeCommandSyncWithResponse(command)
|
|
1544
1588
|
return response.executed
|
|
1545
1589
|
|
|
@@ -1558,6 +1602,12 @@ class Selve:
|
|
|
1558
1602
|
response: IveoAutomaticResponse = await self.executeCommandSyncWithResponse(command)
|
|
1559
1603
|
return response.executed
|
|
1560
1604
|
|
|
1605
|
+
async def iveoCommandResult(self):
|
|
1606
|
+
"""Query the result of the last iveo command execution."""
|
|
1607
|
+
command = IveoResult()
|
|
1608
|
+
response: IveoResultResponse = await self.executeCommandSyncWithResponse(command)
|
|
1609
|
+
return response
|
|
1610
|
+
|
|
1561
1611
|
|
|
1562
1612
|
|
|
1563
1613
|
### Sensor
|
|
@@ -1612,10 +1662,86 @@ class Selve:
|
|
|
1612
1662
|
|
|
1613
1663
|
|
|
1614
1664
|
|
|
1615
|
-
### SenSim
|
|
1665
|
+
### SenSim
|
|
1666
|
+
async def senSimGetIds(self):
|
|
1667
|
+
command = SenSimGetIds()
|
|
1668
|
+
response: SenSimGetIdsResponse = await self.executeCommandSyncWithResponse(command)
|
|
1669
|
+
return response
|
|
1670
|
+
|
|
1671
|
+
async def senSimGetConfig(self, id: int):
|
|
1672
|
+
command = SenSimGetConfig(id)
|
|
1673
|
+
response: SenSimGetConfigResponse = await self.executeCommandSyncWithResponse(command)
|
|
1674
|
+
return response
|
|
1675
|
+
|
|
1676
|
+
async def senSimSetConfig(self, id: int, activity: bool):
|
|
1677
|
+
command = SenSimSetConfig(id, activity)
|
|
1678
|
+
response: SenSimSetConfigResponse = await self.executeCommandSyncWithResponse(command)
|
|
1679
|
+
return response.executed
|
|
1680
|
+
|
|
1681
|
+
async def senSimGetValues(self, id: int):
|
|
1682
|
+
command = SenSimGetValues(id)
|
|
1683
|
+
response: SenSimGetValuesResponse = await self.executeCommandSyncWithResponse(command)
|
|
1684
|
+
return response
|
|
1685
|
+
|
|
1686
|
+
async def senSimSetValues(self, id: int, windDigital: int, rainDigital: int, tempDigital: int, lightDigital: int,
|
|
1687
|
+
tempAnalog: int, windAnalog: int, sun1Analog: int, dayLightAnalog: int,
|
|
1688
|
+
sun2Analog: int, sun3Analog: int):
|
|
1689
|
+
command = SenSimSetValues(id, windDigital, rainDigital, tempDigital, lightDigital,
|
|
1690
|
+
tempAnalog, windAnalog, sun1Analog, dayLightAnalog,
|
|
1691
|
+
sun2Analog, sun3Analog)
|
|
1692
|
+
response: SenSimSetValuesResponse = await self.executeCommandSyncWithResponse(command)
|
|
1693
|
+
return response.executed
|
|
1694
|
+
|
|
1695
|
+
async def senSimSetLabel(self, id: int, label: str):
|
|
1696
|
+
command = SenSimSetLabel(id, label)
|
|
1697
|
+
response: SenSimSetLabelResponse = await self.executeCommandSyncWithResponse(command)
|
|
1698
|
+
return response.executed
|
|
1699
|
+
|
|
1700
|
+
async def senSimDrive(self, id: int, driveCommand: SenSimCommandType):
|
|
1701
|
+
command = SenSimDrive(id, driveCommand)
|
|
1702
|
+
response: SenSimDriveResponse = await self.executeCommandSyncWithResponse(command)
|
|
1703
|
+
return response.executed
|
|
1704
|
+
|
|
1705
|
+
async def senSimStore(self, id: int, actorId: int):
|
|
1706
|
+
command = SenSimStore(id, actorId)
|
|
1707
|
+
response: SenSimStoreResponse = await self.executeCommandSyncWithResponse(command)
|
|
1708
|
+
return response.executed
|
|
1709
|
+
|
|
1710
|
+
async def senSimDelete(self, id: int, actorId: int):
|
|
1711
|
+
command = SenSimDelete(id, actorId)
|
|
1712
|
+
response: SenSimDeleteResponse = await self.executeCommandSyncWithResponse(command)
|
|
1713
|
+
return response.executed
|
|
1714
|
+
|
|
1715
|
+
async def senSimFactory(self, id: int):
|
|
1716
|
+
command = SenSimFactory(id)
|
|
1717
|
+
response: SenSimFactoryResponse = await self.executeCommandSyncWithResponse(command)
|
|
1718
|
+
return response.executed
|
|
1719
|
+
|
|
1720
|
+
async def senSimGetTest(self, id: int):
|
|
1721
|
+
command = SenSimGetTest(id)
|
|
1722
|
+
response: SenSimGetTestResponse = await self.executeCommandSyncWithResponse(command)
|
|
1723
|
+
return response
|
|
1724
|
+
|
|
1725
|
+
async def senSimSetTest(self, id: int, testMode: int):
|
|
1726
|
+
command = SenSimSetTest(id, testMode)
|
|
1727
|
+
response: SenSimSetTestResponse = await self.executeCommandSyncWithResponse(command)
|
|
1728
|
+
return response.executed
|
|
1729
|
+
|
|
1616
1730
|
async def updateSenSimValuesAsync(self, id: int):
|
|
1617
1731
|
await self.executeCommand(SenSimGetValues(id))
|
|
1618
1732
|
|
|
1733
|
+
|
|
1734
|
+
### Firmware
|
|
1735
|
+
async def firmwareGetVersion(self):
|
|
1736
|
+
command = FirmwareGetVersion()
|
|
1737
|
+
response: FirmwareGetVersionResponse = await self.executeCommandSyncWithResponse(command)
|
|
1738
|
+
return response
|
|
1739
|
+
|
|
1740
|
+
async def firmwareUpdate(self):
|
|
1741
|
+
command = FirmwareUpdate()
|
|
1742
|
+
response: FirmwareUpdateResponse = await self.executeCommandSyncWithResponse(command)
|
|
1743
|
+
return response.executed
|
|
1744
|
+
|
|
1619
1745
|
### Sender
|
|
1620
1746
|
async def senderTeachStart(self):
|
|
1621
1747
|
command = SenderTeachStart()
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.5.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 5, 1)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gb1e462646'
|
|
@@ -109,6 +109,10 @@ class CommandAutoOffGroup(CommeoCommand):
|
|
|
109
109
|
super().__init__(id, DriveCommandCommeo.AUTOOFF, type, param, True)
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
class CommandResult(GatewayCommand):
|
|
113
|
+
def __init__(self):
|
|
114
|
+
super().__init__(CommeoCommandCommand.RESULT)
|
|
115
|
+
|
|
112
116
|
|
|
113
117
|
class CommandGroupMan(GatewayCommand):
|
|
114
118
|
def __init__(self, command, type: DeviceCommandType, ids: dict, param: int = 0):
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from selve.util import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class FirmwareGetVersion(GatewayCommand):
|
|
5
|
+
def __init__(self):
|
|
6
|
+
super().__init__(CommeoFirmwareCommand.GETVERSION)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FirmwareUpdate(GatewayCommand):
|
|
10
|
+
def __init__(self):
|
|
11
|
+
super().__init__(CommeoFirmwareCommand.UPDATE)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FirmwareGetVersionResponse(MethodResponse):
|
|
15
|
+
def __init__(self, name, parameters):
|
|
16
|
+
super().__init__(name, parameters)
|
|
17
|
+
self.version = str(parameters[0][1]) if len(parameters) > 0 else "unknown"
|
|
18
|
+
self.state = str(parameters[1][1]) if len(parameters) > 1 else "unknown"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class FirmwareUpdateResponse(MethodResponse):
|
|
22
|
+
def __init__(self, name, parameters):
|
|
23
|
+
super().__init__(name, parameters)
|
|
24
|
+
self.executed = bool(parameters[0][1])
|
|
@@ -79,3 +79,36 @@ class ParamGetRfResponse(MethodResponse):
|
|
|
79
79
|
self.rfSensorId = int(parameters[4][1])
|
|
80
80
|
self.iveoResetCount = int(parameters[5][1])
|
|
81
81
|
self.rfIveoId = int(parameters[6][1])
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ParamSetDuty(GatewayCommand):
|
|
85
|
+
def __init__(self, mode: int):
|
|
86
|
+
super().__init__(CommeoParamCommand.SETDUTY, [(ParameterType.INT, mode)])
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ParamSetDutyResponse(MethodResponse):
|
|
90
|
+
def __init__(self, name, parameters):
|
|
91
|
+
super().__init__(name, parameters)
|
|
92
|
+
self.executed = bool(parameters[0][1])
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ParamSetRf(GatewayCommand):
|
|
96
|
+
def __init__(self, netAddress: int, resetCount: int):
|
|
97
|
+
super().__init__(CommeoParamCommand.SETRF, [(ParameterType.INT, netAddress), (ParameterType.INT, resetCount)])
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class ParamSetRfResponse(MethodResponse):
|
|
101
|
+
def __init__(self, name, parameters):
|
|
102
|
+
super().__init__(name, parameters)
|
|
103
|
+
self.executed = bool(parameters[0][1])
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ParamGetTemperature(GatewayCommand):
|
|
107
|
+
def __init__(self):
|
|
108
|
+
super().__init__(CommeoParamCommand.GETTEMPERATURE)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ParamGetTemperatureResponse(MethodResponse):
|
|
112
|
+
def __init__(self, name, parameters):
|
|
113
|
+
super().__init__(name, parameters)
|
|
114
|
+
self.temperature = int(parameters[0][1])
|
|
@@ -203,8 +203,11 @@ class CommeoParamCommand(Enum):
|
|
|
203
203
|
GETFORWARD = "param.getForward"
|
|
204
204
|
SETEVENT = "param.setEvent"
|
|
205
205
|
GETEVENT = "param.getEvent"
|
|
206
|
+
SETDUTY = "param.setDuty"
|
|
206
207
|
GETDUTY = "param.getDuty"
|
|
208
|
+
SETRF = "param.setRF"
|
|
207
209
|
GETRF = "param.getRF"
|
|
210
|
+
GETTEMPERATURE = "param.getTemperature"
|
|
208
211
|
|
|
209
212
|
class CommeoDeviceCommand(Enum):
|
|
210
213
|
SCANSTART = "device.scanStart"
|
|
@@ -290,6 +293,11 @@ class IveoCommand(Enum):
|
|
|
290
293
|
RESULT = "iveo.commandResult"
|
|
291
294
|
|
|
292
295
|
|
|
296
|
+
class CommeoFirmwareCommand(Enum):
|
|
297
|
+
UPDATE = "firmware.update"
|
|
298
|
+
GETVERSION = "firmware.getVersion"
|
|
299
|
+
|
|
300
|
+
|
|
293
301
|
class CommandType(Enum):
|
|
294
302
|
def __getattr__(self, item):
|
|
295
303
|
if item != '_value_':
|
|
@@ -305,6 +313,7 @@ class CommandType(Enum):
|
|
|
305
313
|
COMMAND = CommeoCommandCommand
|
|
306
314
|
EVENT = CommeoEventCommand
|
|
307
315
|
IVEO = IveoCommand
|
|
316
|
+
FIRMWARE = CommeoFirmwareCommand
|
|
308
317
|
|
|
309
318
|
### Responses
|
|
310
319
|
|
|
@@ -149,12 +149,12 @@ class TestSelveEdgeCases:
|
|
|
149
149
|
logger.info.assert_called_with("Test Device")
|
|
150
150
|
|
|
151
151
|
def test_command_result_edge_cases(self):
|
|
152
|
-
"""Test
|
|
152
|
+
"""Test _handleCommandResult method edge cases."""
|
|
153
153
|
selve = Selve()
|
|
154
154
|
|
|
155
155
|
# Test with None response
|
|
156
156
|
try:
|
|
157
|
-
selve.
|
|
157
|
+
selve._handleCommandResult(None)
|
|
158
158
|
# This might not raise an error, which is fine
|
|
159
159
|
except AttributeError:
|
|
160
160
|
# This is also acceptable
|
|
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
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/inspectionProfiles/profiles_settings.xml
RENAMED
|
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
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/dependency_links.txt
RENAMED
|
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
|
|
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
|
|
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
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_device_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_classes_coverage.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_commands_extended.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_configuration_issues.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_error_handling_fixed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_devices_and_groups.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_sensors_and_senders.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_param_commands_extended.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_advanced_coverage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_comprehensive.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_response_coverage.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_main_class_extensive.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sender_commands_extended.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensim_commands_extended.py
RENAMED
|
File without changes
|
{python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensor_commands_extended.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|