ics_2000_python 0.1.3__tar.gz → 0.1.5__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.3 → ics_2000_python-0.1.5}/PKG-INFO +1 -1
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/command.py +3 -2
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/config.py +3 -2
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/encryption.py +1 -0
- ics_2000_python-0.1.5/ics_2000/entities/blind_device.py +71 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/color_temperature_device.py +2 -1
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/device.py +3 -2
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/dim_device.py +2 -1
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/entity.py +2 -2
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/hub.py +24 -7
- ics_2000_python-0.1.5/ics_2000/model/device_config.py +27 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/model/device_data.py +2 -5
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/model/entity_type.py +1 -1
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/model/smart_meter_data.py +1 -2
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/model/smart_meter_data_current.py +1 -4
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/pyproject.toml +1 -1
- ics_2000_python-0.1.3/ics_2000/model/device_config.py +0 -21
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/LICENSE +0 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/README.md +0 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/__init__.py +0 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/__init__.py +0 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/entities/switch_device.py +1 -1
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/exceptions.py +0 -0
- {ics_2000_python-0.1.3 → ics_2000_python-0.1.5}/ics_2000/model/__init__.py +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import List
|
|
3
2
|
import socket
|
|
3
|
+
|
|
4
4
|
import requests
|
|
5
|
+
|
|
5
6
|
from .config import API_URL
|
|
6
7
|
from .encryption import encrypt
|
|
7
8
|
from .model.entity_type import Entity_Type
|
|
@@ -16,7 +17,7 @@ class Command:
|
|
|
16
17
|
value: int | float,
|
|
17
18
|
aes_key: str,
|
|
18
19
|
entity_type: Entity_Type,
|
|
19
|
-
device_functions:
|
|
20
|
+
device_functions: list[int | float] = [],
|
|
20
21
|
):
|
|
21
22
|
self.hub_mac = hub_mac
|
|
22
23
|
self.device_id = device_id
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from .model.device_config import DeviceConfig
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
API_URL = "https://trustsmartcloud2.com/ics2000_api"
|
|
5
4
|
device_configs: dict[int, DeviceConfig] = {
|
|
6
5
|
1: DeviceConfig(
|
|
@@ -94,8 +93,10 @@ device_configs: dict[int, DeviceConfig] = {
|
|
|
94
93
|
model_name="AWMT Buil-in wall switch",
|
|
95
94
|
),
|
|
96
95
|
23: DeviceConfig(
|
|
97
|
-
disabled=True,
|
|
98
96
|
model_name="Somfy Actuator",
|
|
97
|
+
index_open=0,
|
|
98
|
+
index_my=1,
|
|
99
|
+
index_close=2,
|
|
99
100
|
),
|
|
100
101
|
24: DeviceConfig(
|
|
101
102
|
model_name="KAKU dimmable lightbulb",
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from ..model import device_data
|
|
2
|
+
from ..model.device_config import DeviceConfig
|
|
3
|
+
from .device import Device
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BlindDevice(Device):
|
|
7
|
+
def __init__(
|
|
8
|
+
self, hub, device_data: device_data.DeviceData, device_config: DeviceConfig
|
|
9
|
+
):
|
|
10
|
+
super().__init__(hub, device_data, device_config)
|
|
11
|
+
|
|
12
|
+
if device_config.index_open is None:
|
|
13
|
+
raise ValueError(f"index_open not defined for '{self.device_data.name}'")
|
|
14
|
+
if device_config.index_close is None:
|
|
15
|
+
raise ValueError(f"index_close not defined for '{self.device_data.name}'")
|
|
16
|
+
if device_config.index_my is None:
|
|
17
|
+
raise ValueError(f"index_my not defined for '{self.device_data.name}'")
|
|
18
|
+
|
|
19
|
+
def open(self, send_local: bool = False) -> None:
|
|
20
|
+
"""Turn off the device.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
24
|
+
send_local set to false, because it triggers a time out.
|
|
25
|
+
"""
|
|
26
|
+
if self.device_config.index_open is None:
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
self.get_hub().change_status(
|
|
30
|
+
self.entity_id,
|
|
31
|
+
self.device_config.index_open,
|
|
32
|
+
0,
|
|
33
|
+
self.is_group,
|
|
34
|
+
send_local,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def close(self, send_local: bool = False) -> None:
|
|
38
|
+
"""Turn off the device.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
42
|
+
send_local set to false, because it triggers a timeout.
|
|
43
|
+
"""
|
|
44
|
+
if self.device_config.index_close is None:
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
self.get_hub().change_status(
|
|
48
|
+
self.entity_id,
|
|
49
|
+
self.device_config.index_close,
|
|
50
|
+
0,
|
|
51
|
+
self.is_group,
|
|
52
|
+
send_local,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def stop(self, send_local: bool = False) -> None:
|
|
56
|
+
"""Turn off the device.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
send_local: Use the ip_address set on the hub to talk to the device
|
|
60
|
+
send_local set to false, because it triggers a timeout.
|
|
61
|
+
"""
|
|
62
|
+
if self.device_config.index_my is None:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
self.get_hub().change_status(
|
|
66
|
+
self.entity_id,
|
|
67
|
+
self.device_config.index_my,
|
|
68
|
+
0,
|
|
69
|
+
self.is_group,
|
|
70
|
+
send_local,
|
|
71
|
+
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
|
-
|
|
3
|
-
from ..model.device_data import DeviceData
|
|
2
|
+
|
|
4
3
|
from ..model.device_config import DeviceConfig
|
|
4
|
+
from ..model.device_data import DeviceData
|
|
5
|
+
from .entity import Entity
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from ..hub import Hub
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from ..model.device_config import DeviceConfig
|
|
2
4
|
from ..model.device_data import DeviceData
|
|
3
5
|
from .switch_device import SwitchDevice
|
|
4
|
-
from ..model.device_config import DeviceConfig
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from ..hub import Hub
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from ..model.device_data import DeviceData
|
|
4
4
|
from ..model.entity_type import EntityType
|
|
@@ -25,7 +25,7 @@ class Entity:
|
|
|
25
25
|
self.device_data = device_data
|
|
26
26
|
self.is_group = entity_type == "group"
|
|
27
27
|
|
|
28
|
-
def get_status(self) ->
|
|
28
|
+
def get_status(self) -> list[int]:
|
|
29
29
|
return self._hub.get_device_status(self.entity_id)
|
|
30
30
|
|
|
31
31
|
def get_hub(self) -> "Hub":
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
1
|
import json
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
3
4
|
import requests
|
|
4
5
|
|
|
5
|
-
from ics_2000.exceptions import
|
|
6
|
+
from ics_2000.exceptions import (
|
|
7
|
+
InvalidAuthException,
|
|
8
|
+
InvalidHomeException,
|
|
9
|
+
InvalidMacOrAuthException,
|
|
10
|
+
NoHomeSelectedException,
|
|
11
|
+
)
|
|
12
|
+
|
|
6
13
|
from .command import Command
|
|
7
|
-
from .encryption import decrypt
|
|
8
14
|
from .config import API_URL, device_configs
|
|
15
|
+
from .encryption import decrypt
|
|
16
|
+
from .entities.blind_device import BlindDevice
|
|
9
17
|
from .entities.color_temperature_device import ColorTemperatureDevice
|
|
10
18
|
from .entities.device import Device
|
|
11
19
|
from .entities.dim_device import DimDevice
|
|
@@ -27,7 +35,7 @@ class Hub:
|
|
|
27
35
|
def __init__(self, email: str, password: str):
|
|
28
36
|
self.homes = []
|
|
29
37
|
self.devices: list[
|
|
30
|
-
Device | DimDevice | SwitchDevice | ColorTemperatureDevice
|
|
38
|
+
Device | DimDevice | SwitchDevice | ColorTemperatureDevice | BlindDevice
|
|
31
39
|
] = []
|
|
32
40
|
"""List of available devices within the authenticated home"""
|
|
33
41
|
self.aes_key: str | None = None
|
|
@@ -72,7 +80,9 @@ class Hub:
|
|
|
72
80
|
data = response.json()
|
|
73
81
|
if data is not None:
|
|
74
82
|
self.homes = data.get("homes", [])
|
|
75
|
-
return dict(
|
|
83
|
+
return dict(
|
|
84
|
+
[(home.get("home_id"), home.get("home_name")) for home in self.homes]
|
|
85
|
+
)
|
|
76
86
|
|
|
77
87
|
def select_home(self, home_id: str) -> None:
|
|
78
88
|
home = next(home for home in self.homes if home.get("home_id") == home_id)
|
|
@@ -94,7 +104,7 @@ class Hub:
|
|
|
94
104
|
"email": self.email,
|
|
95
105
|
"mac": self.mac,
|
|
96
106
|
"password_hash": self.password,
|
|
97
|
-
"home_id":
|
|
107
|
+
"home_id": self.home_id,
|
|
98
108
|
},
|
|
99
109
|
)
|
|
100
110
|
data = []
|
|
@@ -120,12 +130,13 @@ class Hub:
|
|
|
120
130
|
|
|
121
131
|
def get_devices(
|
|
122
132
|
self,
|
|
123
|
-
) -> list[Device | DimDevice | SwitchDevice | ColorTemperatureDevice]:
|
|
133
|
+
) -> list[Device | DimDevice | SwitchDevice | ColorTemperatureDevice | BlindDevice]:
|
|
124
134
|
"""Gets all devices connected to the hub"""
|
|
125
135
|
if self.home_id is None:
|
|
126
136
|
raise NoHomeSelectedException()
|
|
127
137
|
|
|
128
138
|
entities = self.get_raw_devices_data(True, False)
|
|
139
|
+
print(entities)
|
|
129
140
|
for device in entities:
|
|
130
141
|
device_data = DeviceData(
|
|
131
142
|
home_id=self.home_id,
|
|
@@ -157,6 +168,12 @@ class Hub:
|
|
|
157
168
|
|
|
158
169
|
elif device_config.on_off_function is not None:
|
|
159
170
|
self.devices.append(SwitchDevice(self, device_data, device_config))
|
|
171
|
+
elif (
|
|
172
|
+
device_config.index_open is not None
|
|
173
|
+
and device_config.index_close is not None
|
|
174
|
+
and device_config.index_my is not None
|
|
175
|
+
):
|
|
176
|
+
self.devices.append(BlindDevice(self, device_data, device_config))
|
|
160
177
|
else:
|
|
161
178
|
self.devices.append(Device(self, device_data, device_config))
|
|
162
179
|
return self.devices
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DeviceConfig:
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
model_name: str,
|
|
8
|
+
disabled: bool | None = None,
|
|
9
|
+
on_off_function: int | None = None,
|
|
10
|
+
dim_function: int | None = None,
|
|
11
|
+
color_temperature_function: int | None = None,
|
|
12
|
+
max_brightness: int | None = None,
|
|
13
|
+
max_color_temperature: int | None = None,
|
|
14
|
+
index_open: int | None = None,
|
|
15
|
+
index_close: int | None = None,
|
|
16
|
+
index_my: int | None = None,
|
|
17
|
+
):
|
|
18
|
+
self.disabled = disabled
|
|
19
|
+
self.model_name = model_name
|
|
20
|
+
self.on_off_function = on_off_function
|
|
21
|
+
self.dim_function = dim_function
|
|
22
|
+
self.color_temperature_function = color_temperature_function
|
|
23
|
+
self.max_brightness = max_brightness
|
|
24
|
+
self.max_color_temperature = max_color_temperature
|
|
25
|
+
self.index_open = index_open
|
|
26
|
+
self.index_close = index_close
|
|
27
|
+
self.index_my = index_my
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
from typing import Dict
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
class DeviceData:
|
|
5
2
|
def __init__(
|
|
6
3
|
self,
|
|
@@ -9,8 +6,8 @@ class DeviceData:
|
|
|
9
6
|
name: str,
|
|
10
7
|
device: int,
|
|
11
8
|
isGroup: bool,
|
|
12
|
-
status:
|
|
13
|
-
data:
|
|
9
|
+
status: dict[str, dict[str, int]],
|
|
10
|
+
data: dict[str, dict[str, int]],
|
|
14
11
|
):
|
|
15
12
|
self.home_id = home_id
|
|
16
13
|
self.id = id
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from typing import Union
|
|
2
1
|
from datetime import datetime
|
|
3
2
|
|
|
4
3
|
Precision = str
|
|
@@ -7,7 +6,7 @@ Precision = str
|
|
|
7
6
|
class SmartMeterData:
|
|
8
7
|
def __init__(
|
|
9
8
|
self,
|
|
10
|
-
date:
|
|
9
|
+
date: datetime | str | int,
|
|
11
10
|
power_consumed_low_tariff: float,
|
|
12
11
|
power_consumed: float,
|
|
13
12
|
power_produced_low_tariff: float,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
class SmartMeterDataCurrent:
|
|
5
2
|
def __init__(
|
|
6
3
|
self,
|
|
@@ -11,7 +8,7 @@ class SmartMeterDataCurrent:
|
|
|
11
8
|
current_consumption: float,
|
|
12
9
|
current_production: float,
|
|
13
10
|
gas: float,
|
|
14
|
-
raw_data_array:
|
|
11
|
+
raw_data_array: list[float],
|
|
15
12
|
):
|
|
16
13
|
self.power_consumed_low_tariff = power_consumed_low_tariff
|
|
17
14
|
self.power_consumed = power_consumed
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class DeviceConfig:
|
|
5
|
-
def __init__(
|
|
6
|
-
self,
|
|
7
|
-
model_name: str,
|
|
8
|
-
disabled: Optional[bool] = None,
|
|
9
|
-
on_off_function: Optional[int] = None,
|
|
10
|
-
dim_function: Optional[int] = None,
|
|
11
|
-
color_temperature_function: Optional[int] = None,
|
|
12
|
-
max_brightness: Optional[int] = None,
|
|
13
|
-
max_color_temperature: Optional[int] = None,
|
|
14
|
-
):
|
|
15
|
-
self.disabled = disabled
|
|
16
|
-
self.model_name = model_name
|
|
17
|
-
self.on_off_function = on_off_function
|
|
18
|
-
self.dim_function = dim_function
|
|
19
|
-
self.color_temperature_function = color_temperature_function
|
|
20
|
-
self.max_brightness = max_brightness
|
|
21
|
-
self.max_color_temperature = max_color_temperature
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|