indevolt-api 1.7.0__tar.gz → 1.7.2__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.7.0
3
+ Version: 1.7.2
4
4
  Summary: Python API client for Indevolt devices
5
5
  Author: A. Gideonse
6
6
  License: MIT
@@ -329,6 +329,11 @@ Get system configuration from the device.
329
329
 
330
330
  - Dictionary with device system configuration
331
331
 
332
+ **Raises:**
333
+
334
+ - `TimeoutError`: If the request exceeds the configured timeout
335
+ - `aiohttp.ClientError`: On network errors or non-200 HTTP responses
336
+
332
337
  **Example:**
333
338
 
334
339
  ```python
@@ -400,7 +405,7 @@ Discover Indevolt devices on the local network using UDP broadcast.
400
405
 
401
406
  **Parameters:**
402
407
 
403
- - `timeout` (float): Discovery timeout in seconds (default: 3.0)
408
+ - `timeout` (float): Discovery timeout in seconds (default: 5.0)
404
409
 
405
410
  **Returns:**
406
411
 
@@ -436,15 +441,19 @@ if device.name:
436
441
 
437
442
  ## Exception Handling
438
443
 
439
- The library provides custom exceptions for API errors and limit violations.
444
+ The library has two exception-handling behaviours depending on the method:
445
+
446
+ **Methods that raise** (`fetch_data`, `get_config`): network and HTTP errors propagate to the caller.
440
447
 
441
- ### `APIException`
448
+ **Methods that return `False`** (`set_data`, `stop`, `charge`, `discharge`): all network, HTTP, and decoding errors are caught internally and logged at DEBUG level. These methods never raise on communication failure.
442
449
 
443
- Raised when there's a client error during API communication (network errors, HTTP errors).
450
+ ### `TimeoutError`
444
451
 
445
- ### `TimeOutException`
452
+ Built-in Python exception raised by `fetch_data` and `get_config` when a request exceeds the configured timeout (default: 10 seconds). Not raised by `set_data` or the convenience helpers.
446
453
 
447
- Raised when an API request times out (default timeout: 10 seconds).
454
+ ### `aiohttp.ClientError`
455
+
456
+ Raised by `fetch_data` and `get_config` on network errors or non-200 HTTP responses. Not raised by `set_data` or the convenience helpers.
448
457
 
449
458
  ### `PowerExceedsMaxError`
450
459
 
@@ -461,14 +470,21 @@ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target
461
470
  **Example:**
462
471
 
463
472
  ```python
464
- from indevolt_api import IndevoltAPI, APIException, TimeOutException
473
+ import aiohttp
474
+ from indevolt_api import IndevoltAPI
465
475
 
476
+ # fetch_data and get_config raise on error
466
477
  try:
467
478
  data = await api.fetch_data("7101")
468
- except TimeOutException:
479
+ except TimeoutError:
469
480
  print("Request timed out")
470
- except APIException as e:
471
- print(f"API error: {e}")
481
+ except aiohttp.ClientError as e:
482
+ print(f"Network/HTTP error: {e}")
483
+
484
+ # set_data and helpers return False on error — no try/except needed
485
+ succeeded = await api.set_data(IndevoltConfig.WRITE_DISCHARGE_LIMIT, 50)
486
+ if not succeeded:
487
+ print("Command failed")
472
488
  ```
473
489
 
474
490
  **Note:** You can adjust the timeout when creating the API client:
@@ -1,14 +1,12 @@
1
1
  """Indevolt API - Python client for Indevolt devices."""
2
2
 
3
3
  from .client import (
4
- APIException,
5
4
  ActiveDiscoveryProtocol,
6
5
  DiscoveredDevice,
7
6
  IndevoltAPI,
8
7
  PassiveDiscoveryProtocol,
9
8
  PowerExceedsMaxError,
10
9
  SocBelowMinimumError,
11
- TimeOutException,
12
10
  async_discover,
13
11
  )
14
12
  from .const import (
@@ -29,11 +27,10 @@ from .const import (
29
27
  IndevoltSystem,
30
28
  )
31
29
 
32
- __version__ = "1.7.0"
30
+ __version__ = "1.7.1"
33
31
 
34
32
  __all__ = [
35
33
  "IndevoltAPI",
36
- "APIException",
37
34
  "ActiveDiscoveryProtocol",
38
35
  "DiscoveredDevice",
39
36
  "PassiveDiscoveryProtocol",
@@ -54,6 +51,5 @@ __all__ = [
54
51
  "IndevoltSystem",
55
52
  "PowerExceedsMaxError",
56
53
  "SocBelowMinimumError",
57
- "TimeOutException",
58
54
  "async_discover",
59
55
  ]
@@ -22,14 +22,6 @@ from .const import (
22
22
  _LOGGER = logging.getLogger(__name__)
23
23
 
24
24
 
25
- class TimeOutException(Exception):
26
- """Raised when an API call times out."""
27
-
28
-
29
- class APIException(Exception):
30
- """Raised on client error during API call."""
31
-
32
-
33
25
  class PowerExceedsMaxError(Exception):
34
26
  """Raised when requested (dis)charge power exceeds the device maximum."""
35
27
 
@@ -293,14 +285,14 @@ class IndevoltAPI:
293
285
  try:
294
286
  async with self.session.post(url, timeout=self.timeout) as response:
295
287
  if response.status != 200:
296
- raise APIException(f"HTTP status error: {response.status}")
288
+ raise ClientError(f"HTTP status error: {response.status}")
297
289
  return await response.json()
298
290
 
299
- except TimeoutError as err:
300
- raise TimeOutException(f"{endpoint} Request timed out") from err
291
+ except TimeoutError:
292
+ raise
301
293
 
302
294
  except aiohttp.ClientError as err:
303
- raise APIException(f"{endpoint} Network error: {err}") from err
295
+ raise ClientError(f"{endpoint} Network error: {err}") from err
304
296
 
305
297
  async def fetch_data(self, t: str | list[str]) -> dict[str, Any]:
306
298
  """Fetch raw JSON data from the device.
@@ -342,25 +334,26 @@ class IndevoltAPI:
342
334
  t_int = int(t)
343
335
  v_int = [int(item) for item in v]
344
336
 
345
- response = await self._request(
346
- "Indevolt.SetData", {"f": 16, "t": t_int, "v": v_int}
347
- )
337
+ try:
338
+ response = await self._request(
339
+ "Indevolt.SetData", {"f": 16, "t": t_int, "v": v_int}
340
+ )
348
341
 
349
- return bool(response.get("result", False))
342
+ return bool(response.get("result", False))
343
+
344
+ except (OSError, ClientError, ValueError) as err:
345
+ _LOGGER.debug("SetData request failed for t=%s, v=%s: %s", t, v, err)
346
+ return False
350
347
 
351
348
  async def stop(self) -> bool:
352
349
  """Stop any active real-time charge or discharge action.
353
350
 
354
351
  Returns True on success, False if the command was rejected.
355
352
  """
356
- try:
357
- return await self.set_data(
358
- SET_REALTIME_ACTION,
359
- [IndevoltRealtimeAction.STOP, 0, 0],
360
- )
361
- except (TimeOutException, ClientError, ConnectionError, OSError) as err:
362
- _LOGGER.debug("stop command failed: %s", err)
363
- return False
353
+ return await self.set_data(
354
+ SET_REALTIME_ACTION,
355
+ [IndevoltRealtimeAction.STOP, 0, 0],
356
+ )
364
357
 
365
358
  async def charge(self, power: int, target_soc: int) -> bool:
366
359
  """Send a real-time charge command to the device.
@@ -368,14 +361,10 @@ class IndevoltAPI:
368
361
  Returns True on success, False if the command was rejected.
369
362
  Raises ValueError if power or target_soc are out of range.
370
363
  """
371
- try:
372
- return await self.set_data(
373
- SET_REALTIME_ACTION,
374
- [IndevoltRealtimeAction.CHARGE, power, target_soc],
375
- )
376
- except (TimeOutException, ClientError, ConnectionError, OSError) as err:
377
- _LOGGER.debug("charge command failed: %s", err)
378
- return False
364
+ return await self.set_data(
365
+ SET_REALTIME_ACTION,
366
+ [IndevoltRealtimeAction.CHARGE, power, target_soc],
367
+ )
379
368
 
380
369
  async def discharge(self, power: int, target_soc: int) -> bool:
381
370
  """Send a real-time discharge command to the device.
@@ -383,14 +372,10 @@ class IndevoltAPI:
383
372
  Returns True on success, False if the command was rejected.
384
373
  Raises ValueError if power or target_soc are out of range.
385
374
  """
386
- try:
387
- return await self.set_data(
388
- SET_REALTIME_ACTION,
389
- [IndevoltRealtimeAction.DISCHARGE, power, target_soc],
390
- )
391
- except (TimeOutException, ClientError, ConnectionError, OSError) as err:
392
- _LOGGER.debug("discharge command failed: %s", err)
393
- return False
375
+ return await self.set_data(
376
+ SET_REALTIME_ACTION,
377
+ [IndevoltRealtimeAction.DISCHARGE, power, target_soc],
378
+ )
394
379
 
395
380
  def check_charge_limits(self, power: int, target_soc: int, generation: int) -> None:
396
381
  """Check that charge parameters do not exceed device limits.
@@ -445,7 +430,7 @@ class IndevoltAPI:
445
430
  try:
446
431
  async with self.session.get(url, timeout=self.timeout) as response:
447
432
  if response.status != 200:
448
- raise APIException(f"HTTP status error: {response.status}")
433
+ raise ClientError(f"HTTP status error: {response.status}")
449
434
  data = await response.json()
450
435
 
451
436
  # Enrich response with device generation
@@ -467,7 +452,7 @@ class IndevoltAPI:
467
452
  return data
468
453
 
469
454
  except TimeoutError as err:
470
- raise TimeOutException("Sys.GetConfig Request timed out") from err
455
+ raise TimeoutError("Sys.GetConfig Request timed out") from err
471
456
 
472
457
  except aiohttp.ClientError as err:
473
- raise APIException(f"Sys.GetConfig Network error: {err}") from err
458
+ raise ClientError(f"Sys.GetConfig Network error: {err}") from err
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: indevolt-api
3
- Version: 1.7.0
3
+ Version: 1.7.2
4
4
  Summary: Python API client for Indevolt devices
5
5
  Author: A. Gideonse
6
6
  License: MIT
@@ -329,6 +329,11 @@ Get system configuration from the device.
329
329
 
330
330
  - Dictionary with device system configuration
331
331
 
332
+ **Raises:**
333
+
334
+ - `TimeoutError`: If the request exceeds the configured timeout
335
+ - `aiohttp.ClientError`: On network errors or non-200 HTTP responses
336
+
332
337
  **Example:**
333
338
 
334
339
  ```python
@@ -400,7 +405,7 @@ Discover Indevolt devices on the local network using UDP broadcast.
400
405
 
401
406
  **Parameters:**
402
407
 
403
- - `timeout` (float): Discovery timeout in seconds (default: 3.0)
408
+ - `timeout` (float): Discovery timeout in seconds (default: 5.0)
404
409
 
405
410
  **Returns:**
406
411
 
@@ -436,15 +441,19 @@ if device.name:
436
441
 
437
442
  ## Exception Handling
438
443
 
439
- The library provides custom exceptions for API errors and limit violations.
444
+ The library has two exception-handling behaviours depending on the method:
445
+
446
+ **Methods that raise** (`fetch_data`, `get_config`): network and HTTP errors propagate to the caller.
440
447
 
441
- ### `APIException`
448
+ **Methods that return `False`** (`set_data`, `stop`, `charge`, `discharge`): all network, HTTP, and decoding errors are caught internally and logged at DEBUG level. These methods never raise on communication failure.
442
449
 
443
- Raised when there's a client error during API communication (network errors, HTTP errors).
450
+ ### `TimeoutError`
444
451
 
445
- ### `TimeOutException`
452
+ Built-in Python exception raised by `fetch_data` and `get_config` when a request exceeds the configured timeout (default: 10 seconds). Not raised by `set_data` or the convenience helpers.
446
453
 
447
- Raised when an API request times out (default timeout: 10 seconds).
454
+ ### `aiohttp.ClientError`
455
+
456
+ Raised by `fetch_data` and `get_config` on network errors or non-200 HTTP responses. Not raised by `set_data` or the convenience helpers.
448
457
 
449
458
  ### `PowerExceedsMaxError`
450
459
 
@@ -461,14 +470,21 @@ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target
461
470
  **Example:**
462
471
 
463
472
  ```python
464
- from indevolt_api import IndevoltAPI, APIException, TimeOutException
473
+ import aiohttp
474
+ from indevolt_api import IndevoltAPI
465
475
 
476
+ # fetch_data and get_config raise on error
466
477
  try:
467
478
  data = await api.fetch_data("7101")
468
- except TimeOutException:
479
+ except TimeoutError:
469
480
  print("Request timed out")
470
- except APIException as e:
471
- print(f"API error: {e}")
481
+ except aiohttp.ClientError as e:
482
+ print(f"Network/HTTP error: {e}")
483
+
484
+ # set_data and helpers return False on error — no try/except needed
485
+ succeeded = await api.set_data(IndevoltConfig.WRITE_DISCHARGE_LIMIT, 50)
486
+ if not succeeded:
487
+ print("Command failed")
472
488
  ```
473
489
 
474
490
  **Note:** You can adjust the timeout when creating the API client:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "indevolt-api"
7
- version = "1.7.0"
7
+ version = "1.7.2"
8
8
  description = "Python API client for Indevolt devices"
9
9
  readme = "readme.md"
10
10
  authors = [
@@ -303,6 +303,11 @@ Get system configuration from the device.
303
303
 
304
304
  - Dictionary with device system configuration
305
305
 
306
+ **Raises:**
307
+
308
+ - `TimeoutError`: If the request exceeds the configured timeout
309
+ - `aiohttp.ClientError`: On network errors or non-200 HTTP responses
310
+
306
311
  **Example:**
307
312
 
308
313
  ```python
@@ -374,7 +379,7 @@ Discover Indevolt devices on the local network using UDP broadcast.
374
379
 
375
380
  **Parameters:**
376
381
 
377
- - `timeout` (float): Discovery timeout in seconds (default: 3.0)
382
+ - `timeout` (float): Discovery timeout in seconds (default: 5.0)
378
383
 
379
384
  **Returns:**
380
385
 
@@ -410,15 +415,19 @@ if device.name:
410
415
 
411
416
  ## Exception Handling
412
417
 
413
- The library provides custom exceptions for API errors and limit violations.
418
+ The library has two exception-handling behaviours depending on the method:
419
+
420
+ **Methods that raise** (`fetch_data`, `get_config`): network and HTTP errors propagate to the caller.
414
421
 
415
- ### `APIException`
422
+ **Methods that return `False`** (`set_data`, `stop`, `charge`, `discharge`): all network, HTTP, and decoding errors are caught internally and logged at DEBUG level. These methods never raise on communication failure.
416
423
 
417
- Raised when there's a client error during API communication (network errors, HTTP errors).
424
+ ### `TimeoutError`
418
425
 
419
- ### `TimeOutException`
426
+ Built-in Python exception raised by `fetch_data` and `get_config` when a request exceeds the configured timeout (default: 10 seconds). Not raised by `set_data` or the convenience helpers.
420
427
 
421
- Raised when an API request times out (default timeout: 10 seconds).
428
+ ### `aiohttp.ClientError`
429
+
430
+ Raised by `fetch_data` and `get_config` on network errors or non-200 HTTP responses. Not raised by `set_data` or the convenience helpers.
422
431
 
423
432
  ### `PowerExceedsMaxError`
424
433
 
@@ -435,14 +444,21 @@ Raised by `check_charge_limits()` or `check_discharge_limits()` when the target
435
444
  **Example:**
436
445
 
437
446
  ```python
438
- from indevolt_api import IndevoltAPI, APIException, TimeOutException
447
+ import aiohttp
448
+ from indevolt_api import IndevoltAPI
439
449
 
450
+ # fetch_data and get_config raise on error
440
451
  try:
441
452
  data = await api.fetch_data("7101")
442
- except TimeOutException:
453
+ except TimeoutError:
443
454
  print("Request timed out")
444
- except APIException as e:
445
- print(f"API error: {e}")
455
+ except aiohttp.ClientError as e:
456
+ print(f"Network/HTTP error: {e}")
457
+
458
+ # set_data and helpers return False on error — no try/except needed
459
+ succeeded = await api.set_data(IndevoltConfig.WRITE_DISCHARGE_LIMIT, 50)
460
+ if not succeeded:
461
+ print("Command failed")
446
462
  ```
447
463
 
448
464
  **Note:** You can adjust the timeout when creating the API client:
File without changes
File without changes