indevolt-api 1.2.3__tar.gz → 1.3.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: indevolt-api
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Summary: Python API client for Indevolt devices
5
5
  Author: A. Gideonse
6
6
  License: MIT
@@ -223,6 +223,64 @@ config = await api.get_config()
223
223
  print(config)
224
224
  ```
225
225
 
226
+ #### `check_charge_limits(power: int, target_soc: int, generation: int) -> None`
227
+
228
+ Check that charge parameters do not exceed device limits. Raises an exception if any boundary is violated.
229
+
230
+ **Parameters:**
231
+
232
+ - `power` (int): Requested charge power in watts
233
+ - `target_soc` (int): Target state of charge percentage
234
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
235
+
236
+ **Raises:**
237
+
238
+ - `ChargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
239
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
240
+
241
+ **Example:**
242
+
243
+ ```python
244
+ config = await api.get_config()
245
+ generation = config["device"]["generation"]
246
+
247
+ try:
248
+ api.check_charge_limits(power=1000, target_soc=80, generation=generation)
249
+ except ChargePowerExceedsMaxError as e:
250
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
251
+ except SocBelowMinimumError as e:
252
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
253
+ ```
254
+
255
+ #### `check_discharge_limits(power: int, target_soc: int, generation: int) -> None`
256
+
257
+ Check that discharge parameters do not exceed device limits. Raises an exception if any boundary is violated.
258
+
259
+ **Parameters:**
260
+
261
+ - `power` (int): Requested discharge power in watts
262
+ - `target_soc` (int): Target state of charge percentage
263
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
264
+
265
+ **Raises:**
266
+
267
+ - `DischargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
268
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
269
+
270
+ **Example:**
271
+
272
+ ```python
273
+ config = await api.get_config()
274
+ generation = config["device"]["generation"]
275
+
276
+ try:
277
+ api.check_discharge_limits(power=600, target_soc=10, generation=generation)
278
+ except DischargePowerExceedsMaxError as e:
279
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
280
+ except SocBelowMinimumError as e:
281
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
282
+ ```
283
+
226
284
  ### async_discover(timeout: float = 5.0) -> list[DiscoveredDevice]
227
285
 
228
286
  Discover Indevolt devices on the local network using UDP broadcast.
@@ -265,7 +323,7 @@ if device.name:
265
323
 
266
324
  ## Exception Handling
267
325
 
268
- The library provides two custom exceptions:
326
+ The library provides custom exceptions for API errors and limit violations.
269
327
 
270
328
  ### `APIException`
271
329
 
@@ -275,6 +333,24 @@ Raised when there's a client error during API communication (network errors, HTT
275
333
 
276
334
  Raised when an API request times out (default timeout: 10 seconds).
277
335
 
336
+ ### `ChargePowerExceedsMaxError`
337
+
338
+ Raised by `check_charge_limits()` when the requested charge power exceeds the device maximum.
339
+
340
+ **Attributes:** `power`, `max_power`, `generation`
341
+
342
+ ### `DischargePowerExceedsMaxError`
343
+
344
+ Raised by `check_discharge_limits()` when the requested discharge power exceeds the device maximum.
345
+
346
+ **Attributes:** `power`, `max_power`, `generation`
347
+
348
+ ### `SocBelowMinimumError`
349
+
350
+ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target SOC is below the hard minimum of 5%.
351
+
352
+ **Attributes:** `target_soc`, `minimum_soc`
353
+
278
354
  **Example:**
279
355
 
280
356
  ```python
@@ -2,18 +2,28 @@
2
2
 
3
3
  from .client import (
4
4
  APIException,
5
+ ChargePowerExceedsMaxError,
5
6
  DiscoveredDevice,
7
+ DischargePowerExceedsMaxError,
6
8
  IndevoltAPI,
9
+ MINIMUM_SOC,
10
+ POWER_LIMITS,
11
+ SocBelowMinimumError,
7
12
  TimeOutException,
8
13
  async_discover,
9
14
  )
10
15
 
11
- __version__ = "1.2.3"
16
+ __version__ = "1.3.0"
12
17
 
13
18
  __all__ = [
14
19
  "IndevoltAPI",
15
20
  "APIException",
21
+ "ChargePowerExceedsMaxError",
22
+ "DiscoveredDevice",
23
+ "DischargePowerExceedsMaxError",
24
+ "MINIMUM_SOC",
25
+ "POWER_LIMITS",
26
+ "SocBelowMinimumError",
16
27
  "TimeOutException",
17
28
  "async_discover",
18
- "DiscoveredDevice",
19
29
  ]
@@ -18,6 +18,40 @@ class APIException(Exception):
18
18
  """Raised on client error during API call."""
19
19
 
20
20
 
21
+ MINIMUM_SOC: int = 5
22
+
23
+ POWER_LIMITS: dict[int, dict[str, int]] = {
24
+ 1: {"max_discharge_power": 800, "max_charge_power": 1200},
25
+ 2: {"max_discharge_power": 2400, "max_charge_power": 2400},
26
+ }
27
+
28
+
29
+ class ChargePowerExceedsMaxError(Exception):
30
+ """Raised when requested charge power exceeds the device maximum."""
31
+
32
+ def __init__(self, power: int, max_power: int, generation: int) -> None:
33
+ self.power = power
34
+ self.max_power = max_power
35
+ self.generation = generation
36
+
37
+
38
+ class DischargePowerExceedsMaxError(Exception):
39
+ """Raised when requested discharge power exceeds the device maximum."""
40
+
41
+ def __init__(self, power: int, max_power: int, generation: int) -> None:
42
+ self.power = power
43
+ self.max_power = max_power
44
+ self.generation = generation
45
+
46
+
47
+ class SocBelowMinimumError(Exception):
48
+ """Raised when target SOC is below the API's hard minimum."""
49
+
50
+ def __init__(self, target_soc: int) -> None:
51
+ self.target_soc = target_soc
52
+ self.minimum_soc = MINIMUM_SOC
53
+
54
+
21
55
  # Discovery configuration
22
56
  DISCOVERY_PORT = 10000
23
57
  BROADCAST_PORT = 8099
@@ -282,6 +316,44 @@ class IndevoltAPI:
282
316
 
283
317
  return bool(response.get("result", False))
284
318
 
319
+ def check_charge_limits(self, power: int, target_soc: int, generation: int) -> None:
320
+ """Check that charge parameters do not exceed device limits.
321
+
322
+ Args:
323
+ power: Requested charge power in watts
324
+ target_soc: Target state of charge percentage
325
+ generation: Device hardware generation (1 or 2)
326
+
327
+ Raises:
328
+ ChargePowerExceedsMaxError: If power exceeds the device maximum
329
+ SocBelowMinimumError: If target_soc is below MINIMUM_SOC
330
+ """
331
+ max_power = POWER_LIMITS[generation]["max_charge_power"]
332
+ if power > max_power:
333
+ raise ChargePowerExceedsMaxError(power, max_power, generation)
334
+ if target_soc < MINIMUM_SOC:
335
+ raise SocBelowMinimumError(target_soc)
336
+
337
+ def check_discharge_limits(
338
+ self, power: int, target_soc: int, generation: int
339
+ ) -> None:
340
+ """Check that discharge parameters do not exceed device limits.
341
+
342
+ Args:
343
+ power: Requested discharge power in watts
344
+ target_soc: Target state of charge percentage
345
+ generation: Device hardware generation (1 or 2)
346
+
347
+ Raises:
348
+ DischargePowerExceedsMaxError: If power exceeds the device maximum
349
+ SocBelowMinimumError: If target_soc is below MINIMUM_SOC
350
+ """
351
+ max_power = POWER_LIMITS[generation]["max_discharge_power"]
352
+ if power > max_power:
353
+ raise DischargePowerExceedsMaxError(power, max_power, generation)
354
+ if target_soc < MINIMUM_SOC:
355
+ raise SocBelowMinimumError(target_soc)
356
+
285
357
  async def get_config(self) -> dict[str, Any]:
286
358
  """Get system configuration from the device.
287
359
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: indevolt-api
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Summary: Python API client for Indevolt devices
5
5
  Author: A. Gideonse
6
6
  License: MIT
@@ -223,6 +223,64 @@ config = await api.get_config()
223
223
  print(config)
224
224
  ```
225
225
 
226
+ #### `check_charge_limits(power: int, target_soc: int, generation: int) -> None`
227
+
228
+ Check that charge parameters do not exceed device limits. Raises an exception if any boundary is violated.
229
+
230
+ **Parameters:**
231
+
232
+ - `power` (int): Requested charge power in watts
233
+ - `target_soc` (int): Target state of charge percentage
234
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
235
+
236
+ **Raises:**
237
+
238
+ - `ChargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
239
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
240
+
241
+ **Example:**
242
+
243
+ ```python
244
+ config = await api.get_config()
245
+ generation = config["device"]["generation"]
246
+
247
+ try:
248
+ api.check_charge_limits(power=1000, target_soc=80, generation=generation)
249
+ except ChargePowerExceedsMaxError as e:
250
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
251
+ except SocBelowMinimumError as e:
252
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
253
+ ```
254
+
255
+ #### `check_discharge_limits(power: int, target_soc: int, generation: int) -> None`
256
+
257
+ Check that discharge parameters do not exceed device limits. Raises an exception if any boundary is violated.
258
+
259
+ **Parameters:**
260
+
261
+ - `power` (int): Requested discharge power in watts
262
+ - `target_soc` (int): Target state of charge percentage
263
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
264
+
265
+ **Raises:**
266
+
267
+ - `DischargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
268
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
269
+
270
+ **Example:**
271
+
272
+ ```python
273
+ config = await api.get_config()
274
+ generation = config["device"]["generation"]
275
+
276
+ try:
277
+ api.check_discharge_limits(power=600, target_soc=10, generation=generation)
278
+ except DischargePowerExceedsMaxError as e:
279
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
280
+ except SocBelowMinimumError as e:
281
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
282
+ ```
283
+
226
284
  ### async_discover(timeout: float = 5.0) -> list[DiscoveredDevice]
227
285
 
228
286
  Discover Indevolt devices on the local network using UDP broadcast.
@@ -265,7 +323,7 @@ if device.name:
265
323
 
266
324
  ## Exception Handling
267
325
 
268
- The library provides two custom exceptions:
326
+ The library provides custom exceptions for API errors and limit violations.
269
327
 
270
328
  ### `APIException`
271
329
 
@@ -275,6 +333,24 @@ Raised when there's a client error during API communication (network errors, HTT
275
333
 
276
334
  Raised when an API request times out (default timeout: 10 seconds).
277
335
 
336
+ ### `ChargePowerExceedsMaxError`
337
+
338
+ Raised by `check_charge_limits()` when the requested charge power exceeds the device maximum.
339
+
340
+ **Attributes:** `power`, `max_power`, `generation`
341
+
342
+ ### `DischargePowerExceedsMaxError`
343
+
344
+ Raised by `check_discharge_limits()` when the requested discharge power exceeds the device maximum.
345
+
346
+ **Attributes:** `power`, `max_power`, `generation`
347
+
348
+ ### `SocBelowMinimumError`
349
+
350
+ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target SOC is below the hard minimum of 5%.
351
+
352
+ **Attributes:** `target_soc`, `minimum_soc`
353
+
278
354
  **Example:**
279
355
 
280
356
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "indevolt-api"
7
- version = "1.2.3"
7
+ version = "1.3.0"
8
8
  description = "Python API client for Indevolt devices"
9
9
  readme = "readme.md"
10
10
  authors = [
@@ -197,6 +197,64 @@ config = await api.get_config()
197
197
  print(config)
198
198
  ```
199
199
 
200
+ #### `check_charge_limits(power: int, target_soc: int, generation: int) -> None`
201
+
202
+ Check that charge parameters do not exceed device limits. Raises an exception if any boundary is violated.
203
+
204
+ **Parameters:**
205
+
206
+ - `power` (int): Requested charge power in watts
207
+ - `target_soc` (int): Target state of charge percentage
208
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
209
+
210
+ **Raises:**
211
+
212
+ - `ChargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
213
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
214
+
215
+ **Example:**
216
+
217
+ ```python
218
+ config = await api.get_config()
219
+ generation = config["device"]["generation"]
220
+
221
+ try:
222
+ api.check_charge_limits(power=1000, target_soc=80, generation=generation)
223
+ except ChargePowerExceedsMaxError as e:
224
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
225
+ except SocBelowMinimumError as e:
226
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
227
+ ```
228
+
229
+ #### `check_discharge_limits(power: int, target_soc: int, generation: int) -> None`
230
+
231
+ Check that discharge parameters do not exceed device limits. Raises an exception if any boundary is violated.
232
+
233
+ **Parameters:**
234
+
235
+ - `power` (int): Requested discharge power in watts
236
+ - `target_soc` (int): Target state of charge percentage
237
+ - `generation` (int): Device hardware generation (`1` or `2`), available from `get_config()` under `device.generation`
238
+
239
+ **Raises:**
240
+
241
+ - `DischargePowerExceedsMaxError`: If `power` exceeds the maximum for the given generation
242
+ - `SocBelowMinimumError`: If `target_soc` is below `MINIMUM_SOC` (5%)
243
+
244
+ **Example:**
245
+
246
+ ```python
247
+ config = await api.get_config()
248
+ generation = config["device"]["generation"]
249
+
250
+ try:
251
+ api.check_discharge_limits(power=600, target_soc=10, generation=generation)
252
+ except DischargePowerExceedsMaxError as e:
253
+ print(f"Power {e.power}W exceeds max {e.max_power}W for gen {e.generation}")
254
+ except SocBelowMinimumError as e:
255
+ print(f"Target SOC {e.target_soc}% is below minimum {e.minimum_soc}%")
256
+ ```
257
+
200
258
  ### async_discover(timeout: float = 5.0) -> list[DiscoveredDevice]
201
259
 
202
260
  Discover Indevolt devices on the local network using UDP broadcast.
@@ -239,7 +297,7 @@ if device.name:
239
297
 
240
298
  ## Exception Handling
241
299
 
242
- The library provides two custom exceptions:
300
+ The library provides custom exceptions for API errors and limit violations.
243
301
 
244
302
  ### `APIException`
245
303
 
@@ -249,6 +307,24 @@ Raised when there's a client error during API communication (network errors, HTT
249
307
 
250
308
  Raised when an API request times out (default timeout: 10 seconds).
251
309
 
310
+ ### `ChargePowerExceedsMaxError`
311
+
312
+ Raised by `check_charge_limits()` when the requested charge power exceeds the device maximum.
313
+
314
+ **Attributes:** `power`, `max_power`, `generation`
315
+
316
+ ### `DischargePowerExceedsMaxError`
317
+
318
+ Raised by `check_discharge_limits()` when the requested discharge power exceeds the device maximum.
319
+
320
+ **Attributes:** `power`, `max_power`, `generation`
321
+
322
+ ### `SocBelowMinimumError`
323
+
324
+ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target SOC is below the hard minimum of 5%.
325
+
326
+ **Attributes:** `target_soc`, `minimum_soc`
327
+
252
328
  **Example:**
253
329
 
254
330
  ```python
File without changes
File without changes