python-selve-new 2.4.0__tar.gz → 2.5.2__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 (113) hide show
  1. python_selve_new-2.5.2/.github/workflows/python-publish.yml +45 -0
  2. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/workflows/tests.yml +2 -2
  3. python_selve_new-2.5.2/CHANGELOG.md +34 -0
  4. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/PKG-INFO +15 -2
  5. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/README.md +12 -0
  6. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/pyproject.toml +3 -5
  7. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/python_selve_new.egg-info/PKG-INFO +15 -2
  8. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/python_selve_new.egg-info/SOURCES.txt +2 -1
  9. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/python_selve_new.egg-info/requires.txt +1 -1
  10. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/__init__.py +172 -60
  11. python_selve_new-2.5.2/selve/_version.py +24 -0
  12. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/command.py +4 -0
  13. python_selve_new-2.5.2/selve/commands/firmware.py +24 -0
  14. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/param.py +33 -0
  15. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/util/__init__.py +9 -0
  16. python_selve_new-2.5.2/selve/util/serial_transport.py +121 -0
  17. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/setup.py +1 -2
  18. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/conftest.py +22 -6
  19. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/conftest.py +11 -11
  20. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/test_device_integration.py +12 -12
  21. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/test_selve_gateway_integration.py +2 -11
  22. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/test_selve_integration.py +19 -32
  23. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/test_replacement.py +16 -17
  24. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_gateway_configuration_issues.py +2 -2
  25. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_gateway_error_handling_fixed.py +6 -8
  26. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_missing_components.py +18 -20
  27. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_mock_commands.py +23 -25
  28. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_mock_devices_and_groups.py +28 -30
  29. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_mock_sensors_and_senders.py +25 -27
  30. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_port_discovery.py +5 -5
  31. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_advanced_coverage.py +5 -9
  32. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_core_coverage.py +17 -99
  33. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_edge_cases.py +2 -2
  34. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_gateway.py +8 -10
  35. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_init_comprehensive.py +20 -23
  36. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_init_simple.py +9 -13
  37. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_main_class_extensive.py +13 -26
  38. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_service_command_errors.py +2 -2
  39. python_selve_new-2.4.0/.github/workflows/python-publish.yml +0 -100
  40. python_selve_new-2.4.0/python_selve_new.egg-info/entry_points.txt +0 -2
  41. python_selve_new-2.4.0/selve/_version.py +0 -34
  42. python_selve_new-2.4.0/selve/util/serial_transport.py +0 -129
  43. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/FUNDING.yml +0 -0
  44. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/architect.chatmode.md +0 -0
  45. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/ask.chatmode.md +0 -0
  46. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/code.chatmode.md +0 -0
  47. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.github/debug.chatmode.md +0 -0
  48. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.gitignore +0 -0
  49. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/.gitignore +0 -0
  50. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  51. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/misc.xml +0 -0
  52. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/modules.xml +0 -0
  53. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/python-selve-new.iml +0 -0
  54. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/.idea/vcs.xml +0 -0
  55. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/LICENSE +0 -0
  56. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/coverage_xdist_example.txt +0 -0
  57. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/debug_response.py +0 -0
  58. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/debug_test.bat +0 -0
  59. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/direct_hardware_test.bat +0 -0
  60. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/direct_hardware_test.py +0 -0
  61. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/generate_coverage.bat +0 -0
  62. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/package.sh +0 -0
  63. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/python_selve_new.egg-info/dependency_links.txt +0 -0
  64. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/python_selve_new.egg-info/top_level.txt +0 -0
  65. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/release.py +0 -0
  66. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_all_tests.bat +0 -0
  67. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_hardware_tests.bat +0 -0
  68. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_integration_tests.bat +0 -0
  69. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_mock_tests.bat +0 -0
  70. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_single_test.bat +0 -0
  71. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/run_tests.bat +0 -0
  72. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/__init__.py +0 -0
  73. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/device.py +0 -0
  74. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/event.py +0 -0
  75. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/group.py +0 -0
  76. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/iveo.py +0 -0
  77. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/senSim.py +0 -0
  78. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/sender.py +0 -0
  79. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/sensor.py +0 -0
  80. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/commands/service.py +0 -0
  81. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/device.py +0 -0
  82. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/gateway.py +0 -0
  83. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/group.py +0 -0
  84. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/iveo.py +0 -0
  85. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/senSim.py +0 -0
  86. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/sender.py +0 -0
  87. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/sensor.py +0 -0
  88. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/util/errors.py +0 -0
  89. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/selve/util/protocol.py +0 -0
  90. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/setup.cfg +0 -0
  91. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/setup_and_test.bat +0 -0
  92. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/__init__.py +0 -0
  93. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/README.md +0 -0
  94. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/__init__.py +0 -0
  95. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/integration/test_selve_hardware.py +0 -0
  96. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/test_import.py +0 -0
  97. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/__init__.py +0 -0
  98. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/mock_utils.py +0 -0
  99. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_command_coverage.py +0 -0
  100. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_commands.py +0 -0
  101. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_device.py +0 -0
  102. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_device_classes_coverage.py +0 -0
  103. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_device_commands_extended.py +0 -0
  104. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_group.py +0 -0
  105. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_group_commands.py +0 -0
  106. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_param_commands_extended.py +0 -0
  107. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_selve_init_response_coverage.py +0 -0
  108. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_sender_commands_extended.py +0 -0
  109. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_sensim_commands_extended.py +0 -0
  110. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_sensor_commands_extended.py +0 -0
  111. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_service_commands.py +0 -0
  112. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_util.py +0 -0
  113. {python_selve_new-2.4.0 → python_selve_new-2.5.2}/tests/unit/test_utility_coverage.py +0 -0
@@ -0,0 +1,45 @@
1
+ # Publishes to PyPI after the "Run Tests" workflow succeeds on a version tag.
2
+
3
+ name: Publish Python Package
4
+
5
+ on:
6
+ workflow_run:
7
+ workflows: ["Run Tests"]
8
+ types: [completed]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ deploy:
15
+ runs-on: ubuntu-latest
16
+ # Only publish when tests passed AND the trigger was a version tag (e.g. v2.5.2)
17
+ if: |
18
+ github.event.workflow_run.conclusion == 'success' &&
19
+ startsWith(github.event.workflow_run.head_branch, 'v')
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ fetch-depth: 0 # Fetch all history for setuptools_scm
25
+ ref: ${{ github.event.workflow_run.head_sha }}
26
+
27
+ - name: Set up Python
28
+ uses: actions/setup-python@v5
29
+ with:
30
+ python-version: '3.x'
31
+
32
+ - name: Install build dependencies
33
+ run: |
34
+ python -m pip install --upgrade pip
35
+ pip install build setuptools-scm
36
+
37
+ - name: Build package
38
+ run: |
39
+ python -m build
40
+
41
+ - name: Publish package to PyPI
42
+ uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
43
+ with:
44
+ user: __token__
45
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -15,7 +15,7 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
18
+ python-version: ['3.10', '3.11', '3.12', '3.13']
19
19
 
20
20
  steps:
21
21
  - uses: actions/checkout@v4
@@ -48,7 +48,7 @@ jobs:
48
48
 
49
49
  - name: Run integration tests (without hardware)
50
50
  run: |
51
- pytest tests/integration/ -v -m "not hardware" --timeout=30
51
+ pytest tests/integration/ -v -m "not hardware" --timeout=30 --ignore=tests/integration/test_selve_hardware.py
52
52
 
53
53
  - name: Generate coverage report (Python 3.11 only)
54
54
  if: matrix.python-version == '3.11'
@@ -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.2
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,11 +16,12 @@ 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
22
23
  Requires-Dist: requests
23
- Requires-Dist: pyserial
24
+ Requires-Dist: serialx
24
25
  Requires-Dist: pybase64
25
26
  Requires-Dist: untangle
26
27
  Requires-Dist: nest_asyncio
@@ -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,11 +26,12 @@ 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",
33
- "pyserial",
34
+ "serialx",
34
35
  "pybase64",
35
36
  "untangle",
36
37
  "nest_asyncio",
@@ -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.2
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,11 +16,12 @@ 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
22
23
  Requires-Dist: requests
23
- Requires-Dist: pyserial
24
+ Requires-Dist: serialx
24
25
  Requires-Dist: pybase64
25
26
  Requires-Dist: untangle
26
27
  Requires-Dist: nest_asyncio
@@ -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
@@ -1,5 +1,5 @@
1
1
  requests
2
- pyserial
2
+ serialx
3
3
  pybase64
4
4
  untangle
5
5
  nest_asyncio