ics_2000_python 0.1.2__tar.gz → 0.1.4__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 (23) hide show
  1. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/PKG-INFO +6 -4
  2. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/README.md +3 -1
  3. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/config.py +4 -1
  4. ics_2000_python-0.1.4/ics_2000/entities/blind_device.py +74 -0
  5. ics_2000_python-0.1.4/ics_2000/exceptions.py +12 -0
  6. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/hub.py +33 -22
  7. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/device_config.py +6 -0
  8. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/pyproject.toml +1 -1
  9. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/LICENSE +0 -0
  10. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/__init__.py +0 -0
  11. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/command.py +0 -0
  12. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/encryption.py +0 -0
  13. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/__init__.py +0 -0
  14. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/color_temperature_device.py +0 -0
  15. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/device.py +0 -0
  16. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/dim_device.py +0 -0
  17. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/entity.py +0 -0
  18. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/entities/switch_device.py +0 -0
  19. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/__init__.py +0 -0
  20. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/device_data.py +0 -0
  21. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/entity_type.py +0 -0
  22. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/smart_meter_data.py +0 -0
  23. {ics_2000_python-0.1.2 → ics_2000_python-0.1.4}/ics_2000/model/smart_meter_data_current.py +0 -0
@@ -1,14 +1,14 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: ics_2000_python
3
- Version: 0.1.2
3
+ Version: 0.1.4
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
@@ -24,7 +24,9 @@ from ics_2000.entities.switch_device import SwitchDevice
24
24
  from ics_2000.hub import Hub
25
25
 
26
26
  hub = Hub("example@email.com", "password")
27
- hub.login() # Authenticate
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
28
30
  hub.get_devices() # request devices
29
31
  for device in hub.devices:
30
32
  if type(device) is SwitchDevice or type(device) is DimDevice:
@@ -8,7 +8,9 @@ from ics_2000.entities.switch_device import SwitchDevice
8
8
  from ics_2000.hub import Hub
9
9
 
10
10
  hub = Hub("example@email.com", "password")
11
- hub.login() # Authenticate
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
12
14
  hub.get_devices() # request devices
13
15
  for device in hub.devices:
14
16
  if type(device) is SwitchDevice or type(device) is DimDevice:
@@ -1,3 +1,4 @@
1
+
1
2
  from .model.device_config import DeviceConfig
2
3
 
3
4
 
@@ -94,8 +95,10 @@ device_configs: dict[int, DeviceConfig] = {
94
95
  model_name="AWMT Buil-in wall switch",
95
96
  ),
96
97
  23: DeviceConfig(
97
- disabled=True,
98
98
  model_name="Somfy Actuator",
99
+ index_open=0,
100
+ index_my=1,
101
+ index_close=2,
99
102
  ),
100
103
  24: DeviceConfig(
101
104
  model_name="KAKU dimmable lightbulb",
@@ -0,0 +1,74 @@
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__(self, hub, device_data: device_data.DeviceData, device_config: DeviceConfig):
8
+ super().__init__(hub, device_data, device_config)
9
+
10
+ if device_config.index_open is None:
11
+ raise ValueError(
12
+ f"index_open not defined for '{self.device_data.name}'"
13
+ )
14
+ if device_config.index_close is None:
15
+ raise ValueError(
16
+ f"index_close not defined for '{self.device_data.name}'"
17
+ )
18
+ if device_config.index_my is None:
19
+ raise ValueError(
20
+ f"index_my not defined for '{self.device_data.name}'"
21
+ )
22
+
23
+ def open(self, send_local: bool = False) -> None:
24
+ """Turn off the device.
25
+
26
+ Args:
27
+ send_local: Use the ip_address set on the hub to talk to the device
28
+ send_local set to false, because it triggers a time out.
29
+ """
30
+ if self.device_config.index_open is None:
31
+ return
32
+
33
+ self.get_hub().change_status(
34
+ self.entity_id,
35
+ self.device_config.index_open,
36
+ 0,
37
+ self.is_group,
38
+ send_local,
39
+ )
40
+
41
+ def close(self, send_local: bool = False) -> None:
42
+ """Turn off the device.
43
+
44
+ Args:
45
+ send_local: Use the ip_address set on the hub to talk to the device
46
+ send_local set to false, because it triggers a timeout.
47
+ """
48
+ if self.device_config.index_close is None:
49
+ return
50
+
51
+ self.get_hub().change_status(
52
+ self.entity_id,
53
+ self.device_config.index_close,
54
+ 0,
55
+ self.is_group,
56
+ send_local,
57
+ )
58
+ def stop(self, send_local: bool = False) -> None:
59
+ """Turn off the device.
60
+
61
+ Args:
62
+ send_local: Use the ip_address set on the hub to talk to the device
63
+ send_local set to false, because it triggers a timeout.
64
+ """
65
+ if self.device_config.index_my is None:
66
+ return
67
+
68
+ self.get_hub().change_status(
69
+ self.entity_id,
70
+ self.device_config.index_my,
71
+ 0,
72
+ self.is_group,
73
+ send_local,
74
+ )
@@ -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,9 +1,12 @@
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
9
+ from .entities.blind_device import BlindDevice
7
10
  from .entities.color_temperature_device import ColorTemperatureDevice
8
11
  from .entities.device import Device
9
12
  from .entities.dim_device import DimDevice
@@ -23,8 +26,9 @@ class Hub:
23
26
  """
24
27
 
25
28
  def __init__(self, email: str, password: str):
29
+ self.homes = []
26
30
  self.devices: list[
27
- Device | DimDevice | SwitchDevice | ColorTemperatureDevice
31
+ Device | DimDevice | SwitchDevice | ColorTemperatureDevice | BlindDevice
28
32
  ] = []
29
33
  """List of available devices within the authenticated home"""
30
34
  self.aes_key: str | None = None
@@ -46,9 +50,10 @@ class Hub:
46
50
  self.update_date = datetime.min
47
51
  """When the device statuses were last updated"""
48
52
 
49
- def login(self) -> None:
53
+ def login(self) -> dict[str, str]:
50
54
  """Logs in to the account given"""
51
- test = requests.post(
55
+ self.homes = []
56
+ response = requests.post(
52
57
  f"{API_URL}/account.php",
53
58
  {
54
59
  "action": "login",
@@ -60,24 +65,28 @@ class Hub:
60
65
  },
61
66
  )
62
67
 
63
- if test.status_code != 200:
64
- if test.status_code == 401:
65
- raise Exception("Incorrect username or password")
66
- raise Exception(test.content)
67
-
68
- response = test.json()
69
- if len(response.get("homes", [])) > 0:
70
- home: dict = response["homes"][0]
71
- self.aes_key = home.get("aes_key", "")
72
- self.mac = home.get("mac", "")
73
- self.home_id = home.get("home_id")
74
- self.home_name = home.get("home_name")
75
- else:
76
- raise Exception("No homes")
68
+ if response.status_code != 200:
69
+ if response.status_code == 401:
70
+ raise InvalidAuthException("Incorrect username or password")
71
+ raise InvalidAuthException(response.content)
72
+
73
+ data = response.json()
74
+ if data is not None:
75
+ self.homes = data.get("homes", [])
76
+ return dict([(home.get("home_id"), home.get("home_name"))for home in self.homes])
77
+
78
+ def select_home(self, home_id: str) -> None:
79
+ home = next(home for home in self.homes if home.get("home_id") == home_id)
80
+ if home is None:
81
+ raise InvalidHomeException()
82
+ self.aes_key = home.get("aes_key", "")
83
+ self.mac = home.get("mac", "")
84
+ self.home_id = home.get("home_id")
85
+ self.home_name = home.get("home_name")
77
86
 
78
87
  def get_raw_devices_data(self, decrypt_data, decrypt_status) -> list:
79
88
  if self.aes_key is None or self.mac is None:
80
- raise Exception("no mac or auth key")
89
+ raise InvalidMacOrAuthException()
81
90
 
82
91
  device_info = requests.post(
83
92
  f"{API_URL}/gateway.php",
@@ -112,10 +121,10 @@ class Hub:
112
121
 
113
122
  def get_devices(
114
123
  self,
115
- ) -> list[Device | DimDevice | SwitchDevice | ColorTemperatureDevice]:
124
+ ) -> list[Device | DimDevice | SwitchDevice | ColorTemperatureDevice | BlindDevice]:
116
125
  """Gets all devices connected to the hub"""
117
126
  if self.home_id is None:
118
- raise Exception("no home")
127
+ raise NoHomeSelectedException()
119
128
 
120
129
  entities = self.get_raw_devices_data(True, False)
121
130
  for device in entities:
@@ -149,6 +158,8 @@ class Hub:
149
158
 
150
159
  elif device_config.on_off_function is not None:
151
160
  self.devices.append(SwitchDevice(self, device_data, device_config))
161
+ elif device_config.index_open is not None and device_config.index_close is not None and device_config.index_my is not None:
162
+ self.devices.append(BlindDevice(self, device_data, device_config))
152
163
  else:
153
164
  self.devices.append(Device(self, device_data, device_config))
154
165
  return self.devices
@@ -161,7 +172,7 @@ class Hub:
161
172
  entity_type: Entity_Type,
162
173
  ) -> Command:
163
174
  if self.aes_key is None or self.mac is None:
164
- raise Exception("no mac or auth key")
175
+ raise InvalidMacOrAuthException()
165
176
 
166
177
  device_functions: list[int | float] = []
167
178
 
@@ -264,7 +275,7 @@ class Hub:
264
275
  self, data: dict, decrypt_data: bool, decrypt_status: bool
265
276
  ) -> dict:
266
277
  if self.aes_key is None or self.mac is None:
267
- raise Exception("no mac or auth key")
278
+ raise InvalidMacOrAuthException()
268
279
 
269
280
  if decrypt_data:
270
281
  data["data"] = json.loads(decrypt(data.get("data", ""), self.aes_key))
@@ -11,6 +11,9 @@ class DeviceConfig:
11
11
  color_temperature_function: Optional[int] = None,
12
12
  max_brightness: Optional[int] = None,
13
13
  max_color_temperature: Optional[int] = None,
14
+ index_open: Optional[int] = None,
15
+ index_close: Optional[int] = None,
16
+ index_my: Optional[int] = None,
14
17
  ):
15
18
  self.disabled = disabled
16
19
  self.model_name = model_name
@@ -19,3 +22,6 @@ class DeviceConfig:
19
22
  self.color_temperature_function = color_temperature_function
20
23
  self.max_brightness = max_brightness
21
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,6 @@
1
1
  [tool.poetry]
2
2
  name = "ics_2000_python"
3
- version = "0.1.2"
3
+ version = "0.1.4"
4
4
  description = ""
5
5
  authors = ["iiTzArcur <zefanjaj@gmail.com>"]
6
6
  readme = "README.md"
File without changes