ics_2000_python 0.1.1__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/PKG-INFO +10 -4
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/README.md +7 -1
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/command.py +2 -2
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/encryption.py +6 -4
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/color_temperature_device.py +15 -1
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/device.py +9 -1
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/dim_device.py +25 -1
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/entity.py +12 -3
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/switch_device.py +27 -0
- ics_2000_python-0.1.3/ics_2000/exceptions.py +12 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/hub.py +60 -24
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/pyproject.toml +2 -2
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/LICENSE +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/__init__.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/config.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/__init__.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/__init__.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/device_config.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/device_data.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/entity_type.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/smart_meter_data.py +0 -0
- {ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/model/smart_meter_data_current.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: ics_2000_python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary:
|
|
5
|
-
Home-page: https://github.com/zefanjajobse/ics_2000_python
|
|
6
5
|
Keywords: ics_2000,ics-2000,klikaanklikuit
|
|
7
6
|
Author: iiTzArcur
|
|
8
7
|
Author-email: zefanjaj@gmail.com
|
|
9
8
|
Requires-Python: >=3.12,<4.0
|
|
10
9
|
Classifier: Programming Language :: Python :: 3
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
12
|
Requires-Dist: pycryptodome (>=3.21.0,<4.0.0)
|
|
13
13
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
14
14
|
Project-URL: Repository, https://github.com/zefanjajobse/ics_2000_python
|
|
@@ -19,8 +19,14 @@ This library gives methods to control a ICS-2000 from KlikAanKlikUit. It is made
|
|
|
19
19
|
|
|
20
20
|
## Usage example:
|
|
21
21
|
```py
|
|
22
|
+
from ics_2000.entities.dim_device import DimDevice
|
|
23
|
+
from ics_2000.entities.switch_device import SwitchDevice
|
|
24
|
+
from ics_2000.hub import Hub
|
|
25
|
+
|
|
22
26
|
hub = Hub("example@email.com", "password")
|
|
23
|
-
hub.login()
|
|
27
|
+
homes = hub.login() # Authenticate
|
|
28
|
+
print(homes) # returns a dictionary of homes, ex: {"0": "test home}
|
|
29
|
+
hub.select_home("132829") # Select the right home by id
|
|
24
30
|
hub.get_devices() # request devices
|
|
25
31
|
for device in hub.devices:
|
|
26
32
|
if type(device) is SwitchDevice or type(device) is DimDevice:
|
|
@@ -3,8 +3,14 @@ This library gives methods to control a ICS-2000 from KlikAanKlikUit. It is made
|
|
|
3
3
|
|
|
4
4
|
## Usage example:
|
|
5
5
|
```py
|
|
6
|
+
from ics_2000.entities.dim_device import DimDevice
|
|
7
|
+
from ics_2000.entities.switch_device import SwitchDevice
|
|
8
|
+
from ics_2000.hub import Hub
|
|
9
|
+
|
|
6
10
|
hub = Hub("example@email.com", "password")
|
|
7
|
-
hub.login()
|
|
11
|
+
homes = hub.login() # Authenticate
|
|
12
|
+
print(homes) # returns a dictionary of homes, ex: {"0": "test home}
|
|
13
|
+
hub.select_home("132829") # Select the right home by id
|
|
8
14
|
hub.get_devices() # request devices
|
|
9
15
|
for device in hub.devices:
|
|
10
16
|
if type(device) is SwitchDevice or type(device) is DimDevice:
|
|
@@ -13,10 +13,10 @@ class Command:
|
|
|
13
13
|
hub_mac: str,
|
|
14
14
|
device_id: int,
|
|
15
15
|
device_function: int,
|
|
16
|
-
value: int,
|
|
16
|
+
value: int | float,
|
|
17
17
|
aes_key: str,
|
|
18
18
|
entity_type: Entity_Type,
|
|
19
|
-
device_functions: List[int] = [],
|
|
19
|
+
device_functions: List[int | float] = [],
|
|
20
20
|
):
|
|
21
21
|
self.hub_mac = hub_mac
|
|
22
22
|
self.device_id = device_id
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
from Crypto.Cipher import AES
|
|
3
3
|
from Crypto.Util.Padding import unpad
|
|
4
|
-
from Crypto.Random import get_random_bytes
|
|
5
4
|
|
|
6
5
|
encoding = "utf-8"
|
|
7
6
|
block_size = 16
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def pad(s):
|
|
10
|
+
return s + (block_size - len(s) % block_size) * chr(
|
|
11
|
+
block_size - len(s) % block_size
|
|
12
|
+
)
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def decrypt(string: str, aes: str) -> str:
|
{ics_2000_python-0.1.1 → ics_2000_python-0.1.3}/ics_2000/entities/color_temperature_device.py
RENAMED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
1
2
|
from ..model.device_data import DeviceData
|
|
2
3
|
from .dim_device import DimDevice
|
|
3
4
|
from ..model.device_config import DeviceConfig
|
|
4
5
|
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from ..hub import Hub
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class ColorTemperatureDevice(DimDevice):
|
|
7
|
-
|
|
11
|
+
"""Class used for color changeable, dimmable devices"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self, hub: "Hub", device_data: DeviceData, device_config: DeviceConfig
|
|
15
|
+
):
|
|
8
16
|
super().__init__(hub, device_data, device_config)
|
|
9
17
|
|
|
10
18
|
if device_config.color_temperature_function is None:
|
|
@@ -15,6 +23,9 @@ class ColorTemperatureDevice(DimDevice):
|
|
|
15
23
|
def change_color_temperature(
|
|
16
24
|
self, color_temperature: float, send_local: bool = True
|
|
17
25
|
) -> None:
|
|
26
|
+
if self.device_config.color_temperature_function is None:
|
|
27
|
+
return
|
|
28
|
+
|
|
18
29
|
return self.get_hub().change_color_temperature(
|
|
19
30
|
self.entity_id,
|
|
20
31
|
self.device_config.color_temperature_function,
|
|
@@ -24,5 +35,8 @@ class ColorTemperatureDevice(DimDevice):
|
|
|
24
35
|
)
|
|
25
36
|
|
|
26
37
|
def get_color_temperature(self) -> float:
|
|
38
|
+
if self.device_config.color_temperature_function is None:
|
|
39
|
+
return 0
|
|
40
|
+
|
|
27
41
|
status = self.get_hub().get_device_status(self.entity_id)
|
|
28
42
|
return status[self.device_config.color_temperature_function]
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
1
2
|
from .entity import Entity
|
|
2
3
|
from ..model.device_data import DeviceData
|
|
3
4
|
from ..model.device_config import DeviceConfig
|
|
4
5
|
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from ..hub import Hub
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class Device(Entity):
|
|
7
|
-
def __init__(
|
|
11
|
+
def __init__(
|
|
12
|
+
self, hub: "Hub", device_data: DeviceData, device_config: DeviceConfig
|
|
13
|
+
):
|
|
8
14
|
super().__init__(
|
|
9
15
|
hub, device_data, "group" in device_data.data and "group" or "module"
|
|
10
16
|
)
|
|
11
17
|
self.device_config = device_config
|
|
18
|
+
"""List of device functions"""
|
|
12
19
|
self.disabled = (
|
|
13
20
|
device_config.disabled if device_config.disabled is not None else False
|
|
14
21
|
)
|
|
22
|
+
"""If the device can be changed"""
|
|
@@ -1,16 +1,33 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
1
2
|
from ..model.device_data import DeviceData
|
|
2
3
|
from .switch_device import SwitchDevice
|
|
3
4
|
from ..model.device_config import DeviceConfig
|
|
4
5
|
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from ..hub import Hub
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class DimDevice(SwitchDevice):
|
|
7
|
-
|
|
11
|
+
"""Class used for all dimmable devices"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self, hub: "Hub", device_data: DeviceData, device_config: DeviceConfig
|
|
15
|
+
):
|
|
8
16
|
super().__init__(hub, device_data, device_config)
|
|
9
17
|
|
|
10
18
|
if device_config.dim_function is None:
|
|
11
19
|
raise ValueError(f"Dim function not defined for '{self.device_data.name}'")
|
|
12
20
|
|
|
13
21
|
def dim(self, dim_level: int, send_local: bool = True) -> None:
|
|
22
|
+
"""Change the dim level of the device.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
dim_level: new dim level (0-255).
|
|
26
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
27
|
+
"""
|
|
28
|
+
if self.device_config.dim_function is None:
|
|
29
|
+
return
|
|
30
|
+
|
|
14
31
|
return self.get_hub().dim_device(
|
|
15
32
|
self.entity_id,
|
|
16
33
|
self.device_config.dim_function,
|
|
@@ -20,5 +37,12 @@ class DimDevice(SwitchDevice):
|
|
|
20
37
|
)
|
|
21
38
|
|
|
22
39
|
def get_dim_level(self) -> int:
|
|
40
|
+
"""Get the dim level of a device
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Current dim level (0-255)."""
|
|
44
|
+
if self.device_config.dim_function is None:
|
|
45
|
+
return 0
|
|
46
|
+
|
|
23
47
|
status = self.get_hub().get_device_status(self.entity_id)
|
|
24
48
|
return status[self.device_config.dim_function]
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
from typing import List
|
|
1
|
+
from typing import List, TYPE_CHECKING
|
|
2
|
+
|
|
2
3
|
from ..model.device_data import DeviceData
|
|
3
4
|
from ..model.entity_type import EntityType
|
|
4
5
|
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from ..hub import Hub
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class Entity:
|
|
7
|
-
|
|
11
|
+
"""Class used for all devices"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, hub: "Hub", device_data: DeviceData, entity_type: EntityType):
|
|
8
14
|
self._hub = hub
|
|
15
|
+
"""Main hub"""
|
|
9
16
|
self.entity_id = int(device_data.id)
|
|
17
|
+
"""ID"""
|
|
10
18
|
self.name = device_data.data[entity_type].get("name", "")
|
|
19
|
+
"""Name of the device"""
|
|
11
20
|
self.device_type = (
|
|
12
21
|
device_data.data[entity_type].get("device", "")
|
|
13
22
|
if "device" in device_data.data[entity_type]
|
|
@@ -19,7 +28,7 @@ class Entity:
|
|
|
19
28
|
def get_status(self) -> List[int]:
|
|
20
29
|
return self._hub.get_device_status(self.entity_id)
|
|
21
30
|
|
|
22
|
-
def get_hub(self):
|
|
31
|
+
def get_hub(self) -> "Hub":
|
|
23
32
|
return self._hub
|
|
24
33
|
|
|
25
34
|
def change_status(self, device_function: int, value: int, send_local: bool) -> None:
|
|
@@ -4,6 +4,8 @@ from .device import Device
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class SwitchDevice(Device):
|
|
7
|
+
"""Class used for all switch devices"""
|
|
8
|
+
|
|
7
9
|
def __init__(self, hub, device_data: DeviceData, device_config: DeviceConfig):
|
|
8
10
|
super().__init__(hub, device_data, device_config)
|
|
9
11
|
|
|
@@ -13,6 +15,14 @@ class SwitchDevice(Device):
|
|
|
13
15
|
)
|
|
14
16
|
|
|
15
17
|
def turn_on_off(self, on: bool, send_local: bool = True) -> None:
|
|
18
|
+
"""Change the state of the device.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
on: new state of the device, True == on.
|
|
22
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
23
|
+
"""
|
|
24
|
+
if self.device_config.on_off_function is None:
|
|
25
|
+
return
|
|
16
26
|
self.get_hub().turn_device_on_off(
|
|
17
27
|
self.entity_id,
|
|
18
28
|
on,
|
|
@@ -22,6 +32,13 @@ class SwitchDevice(Device):
|
|
|
22
32
|
)
|
|
23
33
|
|
|
24
34
|
def turn_on(self, send_local: bool = True) -> None:
|
|
35
|
+
"""Turn on the device.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
39
|
+
"""
|
|
40
|
+
if self.device_config.on_off_function is None:
|
|
41
|
+
return
|
|
25
42
|
self.get_hub().turn_device_on_off(
|
|
26
43
|
self.entity_id,
|
|
27
44
|
True,
|
|
@@ -31,6 +48,13 @@ class SwitchDevice(Device):
|
|
|
31
48
|
)
|
|
32
49
|
|
|
33
50
|
def turn_off(self, send_local: bool = True) -> None:
|
|
51
|
+
"""Turn off the device.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
55
|
+
"""
|
|
56
|
+
if self.device_config.on_off_function is None:
|
|
57
|
+
return
|
|
34
58
|
self.get_hub().turn_device_on_off(
|
|
35
59
|
self.entity_id,
|
|
36
60
|
False,
|
|
@@ -40,5 +64,8 @@ class SwitchDevice(Device):
|
|
|
40
64
|
)
|
|
41
65
|
|
|
42
66
|
def get_on_status(self) -> bool:
|
|
67
|
+
"""Returns true if device is turned on"""
|
|
68
|
+
if self.device_config.on_off_function is None:
|
|
69
|
+
return False
|
|
43
70
|
status = self.get_status()
|
|
44
71
|
return status[self.device_config.on_off_function] == 1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
class InvalidAuthException(Exception):
|
|
3
|
+
"""When the authentication failed"""
|
|
4
|
+
|
|
5
|
+
class InvalidHomeException(Exception):
|
|
6
|
+
"""When selected home does not exist as a option"""
|
|
7
|
+
|
|
8
|
+
class InvalidMacOrAuthException(Exception):
|
|
9
|
+
"""When the auth or mac address is not set"""
|
|
10
|
+
|
|
11
|
+
class NoHomeSelectedException(Exception):
|
|
12
|
+
"""When no home is selected"""
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
import json
|
|
3
3
|
import requests
|
|
4
|
+
|
|
5
|
+
from ics_2000.exceptions import InvalidAuthException, InvalidHomeException, InvalidMacOrAuthException, NoHomeSelectedException
|
|
4
6
|
from .command import Command
|
|
5
7
|
from .encryption import decrypt
|
|
6
8
|
from .config import API_URL, device_configs
|
|
@@ -14,22 +16,43 @@ from .model.entity_type import Entity_Type
|
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
class Hub:
|
|
19
|
+
"""KlikAanKlikUit ICS-2000 Control Station connection info
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
email: Email address of the account connected to the ICS-2000
|
|
24
|
+
password: Password of the account connected to the ICS-2000
|
|
25
|
+
"""
|
|
26
|
+
|
|
17
27
|
def __init__(self, email: str, password: str):
|
|
28
|
+
self.homes = []
|
|
18
29
|
self.devices: list[
|
|
19
30
|
Device | DimDevice | SwitchDevice | ColorTemperatureDevice
|
|
20
31
|
] = []
|
|
32
|
+
"""List of available devices within the authenticated home"""
|
|
21
33
|
self.aes_key: str | None = None
|
|
34
|
+
"""Authentication key"""
|
|
22
35
|
self.mac: str | None = None
|
|
36
|
+
"""MAC-Address of the KlikAanKlikUit ICS-2000"""
|
|
23
37
|
self.home_name: str | None = None
|
|
38
|
+
"""Name of the home given within KlikAanKlikUit"""
|
|
24
39
|
self.home_id: str | None = None
|
|
40
|
+
"""ID of the home"""
|
|
25
41
|
self.email = email
|
|
42
|
+
"""Email address of the account connected to the ICS-2000"""
|
|
26
43
|
self.password = password
|
|
44
|
+
"""Password of the account connected to the ICS-2000"""
|
|
27
45
|
self.local_address: str | None = None
|
|
46
|
+
"""Local IP address when you want to control it locally"""
|
|
28
47
|
self.device_statuses: dict[int, list[int]] = {}
|
|
48
|
+
"""Statuses of the devices"""
|
|
29
49
|
self.update_date = datetime.min
|
|
50
|
+
"""When the device statuses were last updated"""
|
|
30
51
|
|
|
31
|
-
def login(self):
|
|
32
|
-
|
|
52
|
+
def login(self) -> dict[str, str]:
|
|
53
|
+
"""Logs in to the account given"""
|
|
54
|
+
self.homes = []
|
|
55
|
+
response = requests.post(
|
|
33
56
|
f"{API_URL}/account.php",
|
|
34
57
|
{
|
|
35
58
|
"action": "login",
|
|
@@ -41,24 +64,28 @@ class Hub:
|
|
|
41
64
|
},
|
|
42
65
|
)
|
|
43
66
|
|
|
44
|
-
if
|
|
45
|
-
if
|
|
46
|
-
raise
|
|
47
|
-
raise
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
raise
|
|
67
|
+
if response.status_code != 200:
|
|
68
|
+
if response.status_code == 401:
|
|
69
|
+
raise InvalidAuthException("Incorrect username or password")
|
|
70
|
+
raise InvalidAuthException(response.content)
|
|
71
|
+
|
|
72
|
+
data = response.json()
|
|
73
|
+
if data is not None:
|
|
74
|
+
self.homes = data.get("homes", [])
|
|
75
|
+
return dict([(home.get("home_id"), home.get("home_name"))for home in self.homes])
|
|
76
|
+
|
|
77
|
+
def select_home(self, home_id: str) -> None:
|
|
78
|
+
home = next(home for home in self.homes if home.get("home_id") == home_id)
|
|
79
|
+
if home is None:
|
|
80
|
+
raise InvalidHomeException()
|
|
81
|
+
self.aes_key = home.get("aes_key", "")
|
|
82
|
+
self.mac = home.get("mac", "")
|
|
83
|
+
self.home_id = home.get("home_id")
|
|
84
|
+
self.home_name = home.get("home_name")
|
|
58
85
|
|
|
59
86
|
def get_raw_devices_data(self, decrypt_data, decrypt_status) -> list:
|
|
60
87
|
if self.aes_key is None or self.mac is None:
|
|
61
|
-
raise
|
|
88
|
+
raise InvalidMacOrAuthException()
|
|
62
89
|
|
|
63
90
|
device_info = requests.post(
|
|
64
91
|
f"{API_URL}/gateway.php",
|
|
@@ -91,9 +118,12 @@ class Hub:
|
|
|
91
118
|
|
|
92
119
|
return data
|
|
93
120
|
|
|
94
|
-
def get_devices(
|
|
121
|
+
def get_devices(
|
|
122
|
+
self,
|
|
123
|
+
) -> list[Device | DimDevice | SwitchDevice | ColorTemperatureDevice]:
|
|
124
|
+
"""Gets all devices connected to the hub"""
|
|
95
125
|
if self.home_id is None:
|
|
96
|
-
raise
|
|
126
|
+
raise NoHomeSelectedException()
|
|
97
127
|
|
|
98
128
|
entities = self.get_raw_devices_data(True, False)
|
|
99
129
|
for device in entities:
|
|
@@ -129,14 +159,19 @@ class Hub:
|
|
|
129
159
|
self.devices.append(SwitchDevice(self, device_data, device_config))
|
|
130
160
|
else:
|
|
131
161
|
self.devices.append(Device(self, device_data, device_config))
|
|
162
|
+
return self.devices
|
|
132
163
|
|
|
133
164
|
def create_command(
|
|
134
|
-
self,
|
|
165
|
+
self,
|
|
166
|
+
device_id: int,
|
|
167
|
+
device_function: int,
|
|
168
|
+
value: int | float,
|
|
169
|
+
entity_type: Entity_Type,
|
|
135
170
|
) -> Command:
|
|
136
171
|
if self.aes_key is None or self.mac is None:
|
|
137
|
-
raise
|
|
172
|
+
raise InvalidMacOrAuthException()
|
|
138
173
|
|
|
139
|
-
device_functions: list[int] = []
|
|
174
|
+
device_functions: list[int | float] = []
|
|
140
175
|
|
|
141
176
|
# if entity_type == Entity_Type.Group:
|
|
142
177
|
# device_functions = self.device_statuses.get(device_id, [])
|
|
@@ -159,6 +194,7 @@ class Hub:
|
|
|
159
194
|
is_group: bool,
|
|
160
195
|
send_local: bool,
|
|
161
196
|
) -> None:
|
|
197
|
+
"""Change to the enabled state of the device"""
|
|
162
198
|
command = self.create_command(
|
|
163
199
|
device_id,
|
|
164
200
|
on_function,
|
|
@@ -236,7 +272,7 @@ class Hub:
|
|
|
236
272
|
self, data: dict, decrypt_data: bool, decrypt_status: bool
|
|
237
273
|
) -> dict:
|
|
238
274
|
if self.aes_key is None or self.mac is None:
|
|
239
|
-
raise
|
|
275
|
+
raise InvalidMacOrAuthException()
|
|
240
276
|
|
|
241
277
|
if decrypt_data:
|
|
242
278
|
data["data"] = json.loads(decrypt(data.get("data", ""), self.aes_key))
|
|
@@ -294,7 +330,7 @@ class Hub:
|
|
|
294
330
|
self,
|
|
295
331
|
device_id: int,
|
|
296
332
|
color_temp_function: int,
|
|
297
|
-
color_temperature:
|
|
333
|
+
color_temperature: float,
|
|
298
334
|
is_group: bool,
|
|
299
335
|
send_local: bool,
|
|
300
336
|
):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "ics_2000_python"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.3"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["iiTzArcur <zefanjaj@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -15,7 +15,7 @@ pycryptodome = "^3.21.0"
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
[tool.poetry.group.test.dependencies]
|
|
18
|
-
pytest = "^8.3.
|
|
18
|
+
pytest = "^8.3.4"
|
|
19
19
|
requests-mock = "^1.12.1"
|
|
20
20
|
|
|
21
21
|
[build-system]
|
|
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
|