salus-it600-client 0.1.0__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.
- salus_it600_client-0.1.0/LICENSE +21 -0
- salus_it600_client-0.1.0/PKG-INFO +140 -0
- salus_it600_client-0.1.0/README.md +114 -0
- salus_it600_client-0.1.0/pyproject.toml +39 -0
- salus_it600_client-0.1.0/salus_it600/__init__.py +18 -0
- salus_it600_client-0.1.0/salus_it600/__version__.py +3 -0
- salus_it600_client-0.1.0/salus_it600/const.py +48 -0
- salus_it600_client-0.1.0/salus_it600/encryptor.py +28 -0
- salus_it600_client-0.1.0/salus_it600/exceptions.py +25 -0
- salus_it600_client-0.1.0/salus_it600/gateway.py +1014 -0
- salus_it600_client-0.1.0/salus_it600/gateway_singleton.py +33 -0
- salus_it600_client-0.1.0/salus_it600/models.py +92 -0
- salus_it600_client-0.1.0/salus_it600_client.egg-info/PKG-INFO +140 -0
- salus_it600_client-0.1.0/salus_it600_client.egg-info/SOURCES.txt +19 -0
- salus_it600_client-0.1.0/salus_it600_client.egg-info/dependency_links.txt +1 -0
- salus_it600_client-0.1.0/salus_it600_client.egg-info/requires.txt +2 -0
- salus_it600_client-0.1.0/salus_it600_client.egg-info/top_level.txt +1 -0
- salus_it600_client-0.1.0/setup.cfg +4 -0
- salus_it600_client-0.1.0/tests/test_climate_compat.py +98 -0
- salus_it600_client-0.1.0/tests/test_encryptor.py +40 -0
- salus_it600_client-0.1.0/tests/test_gateway_request.py +101 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Julius Vitkauskas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: salus-it600-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Asynchronous Python client for Salus iT600 local gateways
|
|
5
|
+
Author: Julius Vitkauskas, Jordi-14
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Jordi-14/salus-it600-client
|
|
8
|
+
Project-URL: Issues, https://github.com/Jordi-14/salus-it600-client/issues
|
|
9
|
+
Project-URL: Source, https://github.com/Jordi-14/salus-it600-client
|
|
10
|
+
Project-URL: Original, https://github.com/epoplavskis/pyit600
|
|
11
|
+
Keywords: salus,it600,api,async,client,home-assistant
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Framework :: AsyncIO
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Home Automation
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: aiohttp>=3.9
|
|
24
|
+
Requires-Dist: cryptography>=42.0.0
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# salus-it600-client
|
|
28
|
+
|
|
29
|
+
Asynchronous Python client for Salus iT600 devices.
|
|
30
|
+
|
|
31
|
+
## For end users
|
|
32
|
+
See https://github.com/Jordi-14/homeassistant_salus to use this in Home Assistant.
|
|
33
|
+
|
|
34
|
+
FHEM users might be interested in https://github.com/dominikkarall/fhempy which provides subset of functionality.
|
|
35
|
+
|
|
36
|
+
## About
|
|
37
|
+
|
|
38
|
+
This package allows you to control and monitor your Salus iT600 smart home devices locally through Salus UG600 universal gateway. Currently heating thermostats, binary sensors, temperature sensors, covers and switches are supported. You have any other devices and would like to contribute - you are welcome to create an issue or submit a pull request.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install salus-it600-client
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
- Instantiate the IT600Gateway device with local ip address and EUID of your gateway. You can find EUID written down on the bottom of your gateway (eg. `001E5E0D32906128`).
|
|
48
|
+
- Status can be polled using the `poll_status()` command.
|
|
49
|
+
- Callbacks to be notified of state updates can be added with the `add_climate_update_callback(method)` or `add_sensor_update_callback(method)` method.
|
|
50
|
+
|
|
51
|
+
### Basic example
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from salus_it600.gateway import IT600Gateway
|
|
55
|
+
|
|
56
|
+
async with IT600Gateway(host=args.host, euid=args.euid) as gateway:
|
|
57
|
+
await gateway.connect()
|
|
58
|
+
await gateway.poll_status()
|
|
59
|
+
|
|
60
|
+
climate_devices = gateway.get_climate_devices()
|
|
61
|
+
|
|
62
|
+
print("All climate devices:")
|
|
63
|
+
print(repr(climate_devices))
|
|
64
|
+
|
|
65
|
+
for climate_device_id in climate_devices:
|
|
66
|
+
print(f"Climate device {climate_device_id} status:")
|
|
67
|
+
print(repr(climate_devices.get(climate_device_id)))
|
|
68
|
+
|
|
69
|
+
print(f"Setting heating device {climate_device_id} temperature to 21 degrees celsius")
|
|
70
|
+
await gateway.set_climate_device_temperature(climate_device_id, 21)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Supported devices
|
|
74
|
+
|
|
75
|
+
Thermostats:
|
|
76
|
+
* HTRP-RF(50)
|
|
77
|
+
* TS600
|
|
78
|
+
* VS10WRF/VS10BRF
|
|
79
|
+
* VS20WRF/VS20BRF
|
|
80
|
+
* SQ610
|
|
81
|
+
* SQ610RF
|
|
82
|
+
* FC600
|
|
83
|
+
|
|
84
|
+
Binary sensors:
|
|
85
|
+
* SW600
|
|
86
|
+
* WLS600
|
|
87
|
+
* OS600
|
|
88
|
+
* SD600 (sometimes gateway may not expose required information for these devices to be detected, reason is unknown)
|
|
89
|
+
* TRV10RFM (only heating state on/off)
|
|
90
|
+
* RX10RF (only heating state on/off)
|
|
91
|
+
|
|
92
|
+
Temperature sensors:
|
|
93
|
+
* PS600
|
|
94
|
+
|
|
95
|
+
Switch devices:
|
|
96
|
+
* SPE600
|
|
97
|
+
* RS600
|
|
98
|
+
* SR600
|
|
99
|
+
|
|
100
|
+
Cover devices:
|
|
101
|
+
* RS600
|
|
102
|
+
|
|
103
|
+
### Unsupported devices
|
|
104
|
+
|
|
105
|
+
Buttons perform actions only in Salus Smart Home app:
|
|
106
|
+
* SB600
|
|
107
|
+
* CSB600
|
|
108
|
+
|
|
109
|
+
### Untested devices
|
|
110
|
+
|
|
111
|
+
These switch devices have not been tested, but may work:
|
|
112
|
+
* SP600
|
|
113
|
+
|
|
114
|
+
These binary sensors have not been tested, but may work:
|
|
115
|
+
* MS600
|
|
116
|
+
|
|
117
|
+
### Troubleshooting
|
|
118
|
+
|
|
119
|
+
If you can't connect using EUID written down on the bottom of your gateway (which looks something like `001E5E0D32906128`), try using `0000000000000000` as EUID.
|
|
120
|
+
|
|
121
|
+
Also check if you have "Local Wifi Mode" enabled:
|
|
122
|
+
* Open Smart Home app on your phone
|
|
123
|
+
* Sign in
|
|
124
|
+
* Double tap your Gateway to open info screen
|
|
125
|
+
* Press gear icon to enter configuration
|
|
126
|
+
* Scroll down a bit and check if "Disable Local WiFi Mode" is set to "No"
|
|
127
|
+
* Scroll all the way down and save settings
|
|
128
|
+
* Restart Gateway by unplugging/plugging USB power
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
### Contributing
|
|
132
|
+
|
|
133
|
+
If you want to help to get your device supported, open GitHub issue and add your device model number and output of `main.py` program. Be sure to run this program with --debug option.
|
|
134
|
+
|
|
135
|
+
## Project origin
|
|
136
|
+
|
|
137
|
+
This project is a maintained fork/successor of `epoplavskis/pyit600`.
|
|
138
|
+
It was renamed from the `pyit600` Python import namespace to `salus_it600`
|
|
139
|
+
to avoid collisions with the original unmaintained package while preserving
|
|
140
|
+
the original MIT license and attribution.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# salus-it600-client
|
|
2
|
+
|
|
3
|
+
Asynchronous Python client for Salus iT600 devices.
|
|
4
|
+
|
|
5
|
+
## For end users
|
|
6
|
+
See https://github.com/Jordi-14/homeassistant_salus to use this in Home Assistant.
|
|
7
|
+
|
|
8
|
+
FHEM users might be interested in https://github.com/dominikkarall/fhempy which provides subset of functionality.
|
|
9
|
+
|
|
10
|
+
## About
|
|
11
|
+
|
|
12
|
+
This package allows you to control and monitor your Salus iT600 smart home devices locally through Salus UG600 universal gateway. Currently heating thermostats, binary sensors, temperature sensors, covers and switches are supported. You have any other devices and would like to contribute - you are welcome to create an issue or submit a pull request.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install salus-it600-client
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
- Instantiate the IT600Gateway device with local ip address and EUID of your gateway. You can find EUID written down on the bottom of your gateway (eg. `001E5E0D32906128`).
|
|
22
|
+
- Status can be polled using the `poll_status()` command.
|
|
23
|
+
- Callbacks to be notified of state updates can be added with the `add_climate_update_callback(method)` or `add_sensor_update_callback(method)` method.
|
|
24
|
+
|
|
25
|
+
### Basic example
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from salus_it600.gateway import IT600Gateway
|
|
29
|
+
|
|
30
|
+
async with IT600Gateway(host=args.host, euid=args.euid) as gateway:
|
|
31
|
+
await gateway.connect()
|
|
32
|
+
await gateway.poll_status()
|
|
33
|
+
|
|
34
|
+
climate_devices = gateway.get_climate_devices()
|
|
35
|
+
|
|
36
|
+
print("All climate devices:")
|
|
37
|
+
print(repr(climate_devices))
|
|
38
|
+
|
|
39
|
+
for climate_device_id in climate_devices:
|
|
40
|
+
print(f"Climate device {climate_device_id} status:")
|
|
41
|
+
print(repr(climate_devices.get(climate_device_id)))
|
|
42
|
+
|
|
43
|
+
print(f"Setting heating device {climate_device_id} temperature to 21 degrees celsius")
|
|
44
|
+
await gateway.set_climate_device_temperature(climate_device_id, 21)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Supported devices
|
|
48
|
+
|
|
49
|
+
Thermostats:
|
|
50
|
+
* HTRP-RF(50)
|
|
51
|
+
* TS600
|
|
52
|
+
* VS10WRF/VS10BRF
|
|
53
|
+
* VS20WRF/VS20BRF
|
|
54
|
+
* SQ610
|
|
55
|
+
* SQ610RF
|
|
56
|
+
* FC600
|
|
57
|
+
|
|
58
|
+
Binary sensors:
|
|
59
|
+
* SW600
|
|
60
|
+
* WLS600
|
|
61
|
+
* OS600
|
|
62
|
+
* SD600 (sometimes gateway may not expose required information for these devices to be detected, reason is unknown)
|
|
63
|
+
* TRV10RFM (only heating state on/off)
|
|
64
|
+
* RX10RF (only heating state on/off)
|
|
65
|
+
|
|
66
|
+
Temperature sensors:
|
|
67
|
+
* PS600
|
|
68
|
+
|
|
69
|
+
Switch devices:
|
|
70
|
+
* SPE600
|
|
71
|
+
* RS600
|
|
72
|
+
* SR600
|
|
73
|
+
|
|
74
|
+
Cover devices:
|
|
75
|
+
* RS600
|
|
76
|
+
|
|
77
|
+
### Unsupported devices
|
|
78
|
+
|
|
79
|
+
Buttons perform actions only in Salus Smart Home app:
|
|
80
|
+
* SB600
|
|
81
|
+
* CSB600
|
|
82
|
+
|
|
83
|
+
### Untested devices
|
|
84
|
+
|
|
85
|
+
These switch devices have not been tested, but may work:
|
|
86
|
+
* SP600
|
|
87
|
+
|
|
88
|
+
These binary sensors have not been tested, but may work:
|
|
89
|
+
* MS600
|
|
90
|
+
|
|
91
|
+
### Troubleshooting
|
|
92
|
+
|
|
93
|
+
If you can't connect using EUID written down on the bottom of your gateway (which looks something like `001E5E0D32906128`), try using `0000000000000000` as EUID.
|
|
94
|
+
|
|
95
|
+
Also check if you have "Local Wifi Mode" enabled:
|
|
96
|
+
* Open Smart Home app on your phone
|
|
97
|
+
* Sign in
|
|
98
|
+
* Double tap your Gateway to open info screen
|
|
99
|
+
* Press gear icon to enter configuration
|
|
100
|
+
* Scroll down a bit and check if "Disable Local WiFi Mode" is set to "No"
|
|
101
|
+
* Scroll all the way down and save settings
|
|
102
|
+
* Restart Gateway by unplugging/plugging USB power
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
### Contributing
|
|
106
|
+
|
|
107
|
+
If you want to help to get your device supported, open GitHub issue and add your device model number and output of `main.py` program. Be sure to run this program with --debug option.
|
|
108
|
+
|
|
109
|
+
## Project origin
|
|
110
|
+
|
|
111
|
+
This project is a maintained fork/successor of `epoplavskis/pyit600`.
|
|
112
|
+
It was renamed from the `pyit600` Python import namespace to `salus_it600`
|
|
113
|
+
to avoid collisions with the original unmaintained package while preserving
|
|
114
|
+
the original MIT license and attribution.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel", "packaging>=24.2"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "salus-it600-client"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Asynchronous Python client for Salus iT600 local gateways"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Julius Vitkauskas" },
|
|
14
|
+
{ name = "Jordi-14" }
|
|
15
|
+
]
|
|
16
|
+
keywords = ["salus", "it600", "api", "async", "client", "home-assistant"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Framework :: AsyncIO",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Topic :: Home Automation"
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"aiohttp>=3.9",
|
|
29
|
+
"cryptography>=42.0.0"
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/Jordi-14/salus-it600-client"
|
|
34
|
+
Issues = "https://github.com/Jordi-14/salus-it600-client/issues"
|
|
35
|
+
Source = "https://github.com/Jordi-14/salus-it600-client"
|
|
36
|
+
Original = "https://github.com/epoplavskis/pyit600"
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
include = ["salus_it600", "salus_it600.*"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Asynchronous Python client for Salus iT600 smart devices."""
|
|
2
|
+
|
|
3
|
+
from .__version__ import __version__
|
|
4
|
+
from .exceptions import (
|
|
5
|
+
IT600AuthenticationError,
|
|
6
|
+
IT600CommandError,
|
|
7
|
+
IT600ConnectionError,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def __getattr__(name: str):
|
|
12
|
+
"""Load gateway classes lazily so utility imports stay lightweight."""
|
|
13
|
+
if name == "IT600Gateway":
|
|
14
|
+
from .gateway import IT600Gateway
|
|
15
|
+
|
|
16
|
+
return IT600Gateway
|
|
17
|
+
|
|
18
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Constants for the Salus iT600 smart devices."""
|
|
2
|
+
|
|
3
|
+
# Degree units
|
|
4
|
+
DEGREE = "°"
|
|
5
|
+
|
|
6
|
+
# Temperature units
|
|
7
|
+
TEMP_CELSIUS = f"{DEGREE}C"
|
|
8
|
+
|
|
9
|
+
# States
|
|
10
|
+
STATE_UNKNOWN = "unknown"
|
|
11
|
+
|
|
12
|
+
# Supported climate features
|
|
13
|
+
SUPPORT_TARGET_TEMPERATURE = 1
|
|
14
|
+
SUPPORT_FAN_MODE = 8
|
|
15
|
+
SUPPORT_PRESET_MODE = 16
|
|
16
|
+
|
|
17
|
+
# Supported cover features
|
|
18
|
+
SUPPORT_OPEN = 1
|
|
19
|
+
SUPPORT_CLOSE = 2
|
|
20
|
+
SUPPORT_SET_POSITION = 4
|
|
21
|
+
|
|
22
|
+
# HVAC modes
|
|
23
|
+
HVAC_MODE_OFF = "off"
|
|
24
|
+
HVAC_MODE_HEAT = "heat"
|
|
25
|
+
HVAC_MODE_COOL = "cool"
|
|
26
|
+
HVAC_MODE_AUTO = "auto"
|
|
27
|
+
|
|
28
|
+
# HVAC states
|
|
29
|
+
CURRENT_HVAC_OFF = "off"
|
|
30
|
+
CURRENT_HVAC_HEAT = "heating"
|
|
31
|
+
CURRENT_HVAC_HEAT_IDLE = "heating (idling)"
|
|
32
|
+
CURRENT_HVAC_COOL = "cooling"
|
|
33
|
+
CURRENT_HVAC_COOL_IDLE = "cooling (idling)"
|
|
34
|
+
CURRENT_HVAC_IDLE = "idle"
|
|
35
|
+
|
|
36
|
+
# Supported presets
|
|
37
|
+
PRESET_FOLLOW_SCHEDULE = "Follow Schedule"
|
|
38
|
+
PRESET_PERMANENT_HOLD = "Permanent Hold"
|
|
39
|
+
PRESET_TEMPORARY_HOLD = "Temporary Hold"
|
|
40
|
+
PRESET_ECO = "Eco"
|
|
41
|
+
PRESET_OFF = "Off"
|
|
42
|
+
|
|
43
|
+
# Supported fan modes
|
|
44
|
+
FAN_MODE_AUTO = "Auto"
|
|
45
|
+
FAN_MODE_HIGH = "High"
|
|
46
|
+
FAN_MODE_MEDIUM = "Medium"
|
|
47
|
+
FAN_MODE_LOW = "Low"
|
|
48
|
+
FAN_MODE_OFF = "Off"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Encryptor for Salus iT600 local mode communication."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
|
|
5
|
+
from cryptography.hazmat.backends import default_backend
|
|
6
|
+
from cryptography.hazmat.primitives import padding
|
|
7
|
+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class IT600Encryptor:
|
|
11
|
+
iv = bytes([0x88, 0xa6, 0xb0, 0x79, 0x5d, 0x85, 0xdb, 0xfc, 0xe6, 0xe0, 0xb3, 0xe9, 0xa6, 0x29, 0x65, 0x4b])
|
|
12
|
+
|
|
13
|
+
def __init__(self, euid: str):
|
|
14
|
+
key: bytes = hashlib.md5(f"Salus-{euid.lower()}".encode("utf-8")).digest() + bytes([0] * 16)
|
|
15
|
+
self.cipher = Cipher(algorithms.AES(key), modes.CBC(self.iv), default_backend())
|
|
16
|
+
|
|
17
|
+
def encrypt(self, plain: str) -> bytes:
|
|
18
|
+
encryptor = self.cipher.encryptor()
|
|
19
|
+
padder = padding.PKCS7(128).padder()
|
|
20
|
+
padded_data: bytes = padder.update(plain.encode("utf-8")) + padder.finalize()
|
|
21
|
+
return encryptor.update(padded_data) + encryptor.finalize()
|
|
22
|
+
|
|
23
|
+
def decrypt(self, cypher: bytes) -> str:
|
|
24
|
+
decryptor = self.cipher.decryptor()
|
|
25
|
+
padded_data: bytes = decryptor.update(cypher) + decryptor.finalize()
|
|
26
|
+
unpadder = padding.PKCS7(128).unpadder()
|
|
27
|
+
plain: bytes = unpadder.update(padded_data) + unpadder.finalize()
|
|
28
|
+
return plain.decode("utf-8")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Exceptions for Salus iT600 smart devices."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class IT600Error(Exception):
|
|
5
|
+
"""Salus iT600 exception."""
|
|
6
|
+
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class IT600AuthenticationError(IT600Error):
|
|
11
|
+
"""Salus iT600 authentication exception."""
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IT600CommandError(IT600Error):
|
|
17
|
+
"""Salus iT600 command exception."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class IT600ConnectionError(IT600Error):
|
|
23
|
+
"""Salus iT600 connection exception."""
|
|
24
|
+
|
|
25
|
+
pass
|