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.
Files changed (110) hide show
  1. python_selve_new-2.5.1/CHANGELOG.md +34 -0
  2. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/PKG-INFO +14 -1
  3. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/README.md +12 -0
  4. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/pyproject.toml +2 -4
  5. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/PKG-INFO +14 -1
  6. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/SOURCES.txt +2 -1
  7. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/__init__.py +134 -8
  8. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/_version.py +3 -3
  9. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/command.py +4 -0
  10. python_selve_new-2.5.1/selve/commands/firmware.py +24 -0
  11. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/param.py +33 -0
  12. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/__init__.py +9 -0
  13. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_edge_cases.py +2 -2
  14. python_selve_new-2.4.0/python_selve_new.egg-info/entry_points.txt +0 -2
  15. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/FUNDING.yml +0 -0
  16. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/architect.chatmode.md +0 -0
  17. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/ask.chatmode.md +0 -0
  18. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/code.chatmode.md +0 -0
  19. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/debug.chatmode.md +0 -0
  20. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/workflows/python-publish.yml +0 -0
  21. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.github/workflows/tests.yml +0 -0
  22. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.gitignore +0 -0
  23. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/.gitignore +0 -0
  24. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  25. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/misc.xml +0 -0
  26. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/modules.xml +0 -0
  27. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/python-selve-new.iml +0 -0
  28. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/.idea/vcs.xml +0 -0
  29. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/LICENSE +0 -0
  30. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/coverage_xdist_example.txt +0 -0
  31. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/debug_response.py +0 -0
  32. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/debug_test.bat +0 -0
  33. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/direct_hardware_test.bat +0 -0
  34. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/direct_hardware_test.py +0 -0
  35. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/generate_coverage.bat +0 -0
  36. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/package.sh +0 -0
  37. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/dependency_links.txt +0 -0
  38. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/requires.txt +0 -0
  39. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/python_selve_new.egg-info/top_level.txt +0 -0
  40. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/release.py +0 -0
  41. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_all_tests.bat +0 -0
  42. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_hardware_tests.bat +0 -0
  43. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_integration_tests.bat +0 -0
  44. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_mock_tests.bat +0 -0
  45. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_single_test.bat +0 -0
  46. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/run_tests.bat +0 -0
  47. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/__init__.py +0 -0
  48. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/device.py +0 -0
  49. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/event.py +0 -0
  50. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/group.py +0 -0
  51. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/iveo.py +0 -0
  52. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/senSim.py +0 -0
  53. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/sender.py +0 -0
  54. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/sensor.py +0 -0
  55. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/commands/service.py +0 -0
  56. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/device.py +0 -0
  57. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/gateway.py +0 -0
  58. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/group.py +0 -0
  59. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/iveo.py +0 -0
  60. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/senSim.py +0 -0
  61. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/sender.py +0 -0
  62. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/sensor.py +0 -0
  63. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/errors.py +0 -0
  64. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/protocol.py +0 -0
  65. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/selve/util/serial_transport.py +0 -0
  66. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup.cfg +0 -0
  67. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup.py +0 -0
  68. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/setup_and_test.bat +0 -0
  69. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/__init__.py +0 -0
  70. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/conftest.py +0 -0
  71. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/README.md +0 -0
  72. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/__init__.py +0 -0
  73. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/conftest.py +0 -0
  74. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_device_integration.py +0 -0
  75. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_gateway_integration.py +0 -0
  76. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_hardware.py +0 -0
  77. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/integration/test_selve_integration.py +0 -0
  78. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/test_import.py +0 -0
  79. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/test_replacement.py +0 -0
  80. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/__init__.py +0 -0
  81. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/mock_utils.py +0 -0
  82. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_command_coverage.py +0 -0
  83. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_commands.py +0 -0
  84. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device.py +0 -0
  85. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_classes_coverage.py +0 -0
  86. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_device_commands_extended.py +0 -0
  87. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_configuration_issues.py +0 -0
  88. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_gateway_error_handling_fixed.py +0 -0
  89. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_group.py +0 -0
  90. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_group_commands.py +0 -0
  91. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_missing_components.py +0 -0
  92. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_commands.py +0 -0
  93. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_devices_and_groups.py +0 -0
  94. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_mock_sensors_and_senders.py +0 -0
  95. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_param_commands_extended.py +0 -0
  96. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_port_discovery.py +0 -0
  97. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_advanced_coverage.py +0 -0
  98. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_core_coverage.py +0 -0
  99. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_gateway.py +0 -0
  100. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_comprehensive.py +0 -0
  101. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_response_coverage.py +0 -0
  102. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_init_simple.py +0 -0
  103. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_selve_main_class_extensive.py +0 -0
  104. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sender_commands_extended.py +0 -0
  105. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensim_commands_extended.py +0 -0
  106. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_sensor_commands_extended.py +0 -0
  107. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_service_command_errors.py +0 -0
  108. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_service_commands.py +0 -0
  109. {python_selve_new-2.4.0 → python_selve_new-2.5.1}/tests/unit/test_util.py +0 -0
  110. {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.4.0
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.4.0
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.commandResult(response)
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.name
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 commandResult(self, response: IveoResultResponse | CommandResultResponse):
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 - ToDo
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.4.0'
32
- __version_tuple__ = version_tuple = (2, 4, 0)
31
+ __version__ = version = '2.5.1'
32
+ __version_tuple__ = version_tuple = (2, 5, 1)
33
33
 
34
- __commit_id__ = commit_id = 'g287c44c4a'
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 commandResult method edge cases."""
152
+ """Test _handleCommandResult method edge cases."""
153
153
  selve = Selve()
154
154
 
155
155
  # Test with None response
156
156
  try:
157
- selve.commandResult(None)
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
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- my-script = my_package.module:function