indevolt-api 1.0.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.
- indevolt_api-1.0.0/LICENSE +21 -0
- indevolt_api-1.0.0/PKG-INFO +173 -0
- indevolt_api-1.0.0/indevolt_api/__init__.py +11 -0
- indevolt_api-1.0.0/indevolt_api/client.py +113 -0
- indevolt_api-1.0.0/indevolt_api.egg-info/PKG-INFO +173 -0
- indevolt_api-1.0.0/indevolt_api.egg-info/SOURCES.txt +10 -0
- indevolt_api-1.0.0/indevolt_api.egg-info/dependency_links.txt +1 -0
- indevolt_api-1.0.0/indevolt_api.egg-info/requires.txt +1 -0
- indevolt_api-1.0.0/indevolt_api.egg-info/top_level.txt +1 -0
- indevolt_api-1.0.0/pyproject.toml +41 -0
- indevolt_api-1.0.0/readme.md +147 -0
- indevolt_api-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 XirtNL
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: indevolt-api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python API client for Indevolt devices
|
|
5
|
+
Author: A. Gideonse
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xirtnl/indevolt-api
|
|
8
|
+
Project-URL: Repository, https://github.com/xirtnl/indevolt-api
|
|
9
|
+
Project-URL: Issues, https://github.com/xirtnl/indevolt-api/issues
|
|
10
|
+
Keywords: indevolt,api,async,aiohttp
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: System :: Hardware
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# Indevolt API
|
|
28
|
+
|
|
29
|
+
Python client library for communicating with Indevolt devices (home battery systems).
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Async/await support using aiohttp
|
|
34
|
+
- Fully typed with type hints
|
|
35
|
+
- Simple and intuitive API
|
|
36
|
+
- Comprehensive error handling
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install indevolt-api
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import asyncio
|
|
48
|
+
import aiohttp
|
|
49
|
+
from indevolt_api import IndevoltAPI
|
|
50
|
+
|
|
51
|
+
async def main():
|
|
52
|
+
async with aiohttp.ClientSession() as session:
|
|
53
|
+
api = IndevoltAPI(host="192.168.1.100", port=8080, session=session)
|
|
54
|
+
|
|
55
|
+
# Get device configuration
|
|
56
|
+
config = await api.get_config()
|
|
57
|
+
print(f"Device config: {config}")
|
|
58
|
+
|
|
59
|
+
# Fetch data from specific cJson points
|
|
60
|
+
data = await api.fetch_data(["7101", "1664"])
|
|
61
|
+
print(f"Data: {data}")
|
|
62
|
+
|
|
63
|
+
# Write data (single data point) to device
|
|
64
|
+
response = await api.set_data("1142", 50)
|
|
65
|
+
print(f"Set data response: {response}")
|
|
66
|
+
|
|
67
|
+
# Write data (multiple data points) to device
|
|
68
|
+
response = await api.set_data("47015", [2, 700, 5])
|
|
69
|
+
print(f"Set data response: {response}")
|
|
70
|
+
|
|
71
|
+
asyncio.run(main())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API Reference
|
|
75
|
+
|
|
76
|
+
### IndevoltAPI
|
|
77
|
+
|
|
78
|
+
#### `__init__(host: str, port: int, session: aiohttp.ClientSession)`
|
|
79
|
+
|
|
80
|
+
Initialize the API client.
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
- `host` (str): Device hostname or IP address
|
|
84
|
+
- `port` (int): Device port number (typically 80)
|
|
85
|
+
- `session` (aiohttp.ClientSession): An aiohttp client session
|
|
86
|
+
|
|
87
|
+
#### `async fetch_data(t: str | list[str]) -> dict[str, Any]`
|
|
88
|
+
|
|
89
|
+
Fetch data from the device.
|
|
90
|
+
|
|
91
|
+
**Parameters:**
|
|
92
|
+
- `t`: Single cJson point or list of cJson points to retrieve (e.g., `"7101"` or `["7101", "1664"]`)
|
|
93
|
+
|
|
94
|
+
**Returns:**
|
|
95
|
+
- Dictionary with device response containing cJson point data
|
|
96
|
+
|
|
97
|
+
**Example:**
|
|
98
|
+
```python
|
|
99
|
+
# Single point
|
|
100
|
+
data = await api.fetch_data("7101")
|
|
101
|
+
|
|
102
|
+
# Multiple points
|
|
103
|
+
data = await api.fetch_data(["7101", "1664", "7102"])
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### `async set_data(t: str | int, v: Any) -> dict[str, Any]`
|
|
107
|
+
|
|
108
|
+
Write data to the device.
|
|
109
|
+
|
|
110
|
+
**Parameters:**
|
|
111
|
+
- `t`: cJson point identifier (e.g., `"47015"` or `47015`)
|
|
112
|
+
- `v`: Value(s) to write (automatically converted to list of integers)
|
|
113
|
+
|
|
114
|
+
**Returns:**
|
|
115
|
+
- Dictionary with device response
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
```python
|
|
119
|
+
# Single value
|
|
120
|
+
await api.set_data("47016", 100)
|
|
121
|
+
|
|
122
|
+
# Multiple values
|
|
123
|
+
await api.set_data("47015", [2, 700, 5])
|
|
124
|
+
|
|
125
|
+
# String or int identifiers
|
|
126
|
+
await api.set_data(47016, "100")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### `async get_config() -> dict[str, Any]`
|
|
130
|
+
|
|
131
|
+
Get system configuration from the device.
|
|
132
|
+
|
|
133
|
+
**Returns:**
|
|
134
|
+
- Dictionary with device system configuration
|
|
135
|
+
|
|
136
|
+
**Example:**
|
|
137
|
+
```python
|
|
138
|
+
config = await api.get_config()
|
|
139
|
+
print(config)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Exception Handling
|
|
143
|
+
|
|
144
|
+
The library provides two custom exceptions:
|
|
145
|
+
|
|
146
|
+
### `APIException`
|
|
147
|
+
|
|
148
|
+
Raised when there's a client error during API communication (network errors, HTTP errors).
|
|
149
|
+
|
|
150
|
+
### `TimeOutException`
|
|
151
|
+
|
|
152
|
+
Raised when an API request times out (default timeout: 60 seconds).
|
|
153
|
+
|
|
154
|
+
**Example:**
|
|
155
|
+
```python
|
|
156
|
+
from indevolt_api import IndevoltAPI, APIException, TimeOutException
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
data = await api.fetch_data("7101")
|
|
160
|
+
except TimeOutException:
|
|
161
|
+
print("Request timed out")
|
|
162
|
+
except APIException as e:
|
|
163
|
+
print(f"API error: {e}")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Requirements
|
|
167
|
+
|
|
168
|
+
- Python 3.11+
|
|
169
|
+
- aiohttp >= 3.9.0
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT License - see LICENSE file for details
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""API client for HTTP communication with Indevolt devices."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import aiohttp
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TimeOutException(Exception):
|
|
10
|
+
"""Raised when an API call times out."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class APIException(Exception):
|
|
14
|
+
"""Raised on client error during API call."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IndevoltAPI:
|
|
18
|
+
"""Handle all HTTP communication with Indevolt devices."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, host: str, port: int, session: aiohttp.ClientSession) -> None:
|
|
21
|
+
"""Initialize the Indevolt API client.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
host: Device hostname or IP address
|
|
25
|
+
port: Device port number
|
|
26
|
+
session: aiohttp ClientSession for HTTP requests
|
|
27
|
+
"""
|
|
28
|
+
self.host = host
|
|
29
|
+
self.port = port
|
|
30
|
+
self.session = session
|
|
31
|
+
self.base_url = f"http://{host}:{port}/rpc"
|
|
32
|
+
self.timeout = aiohttp.ClientTimeout(total=60)
|
|
33
|
+
|
|
34
|
+
async def _request(self, endpoint: str, config_data: dict[str, Any]) -> dict[str, Any]:
|
|
35
|
+
"""Make HTTP request to device endpoint.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
endpoint: RPC endpoint name (e.g., "Indevolt.GetData")
|
|
39
|
+
config_data: Configuration data to send
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Device response dictionary
|
|
43
|
+
"""
|
|
44
|
+
config_param = json.dumps(config_data).replace(" ", "")
|
|
45
|
+
url = f"{self.base_url}/{endpoint}?config={config_param}"
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
async with self.session.post(url, timeout=self.timeout) as response:
|
|
49
|
+
if response.status != 200:
|
|
50
|
+
raise APIException(f"HTTP status error: {response.status}")
|
|
51
|
+
return await response.json()
|
|
52
|
+
|
|
53
|
+
except TimeoutError as err:
|
|
54
|
+
raise TimeOutException(f"{endpoint} Request timed out") from err
|
|
55
|
+
except aiohttp.ClientError as err:
|
|
56
|
+
raise APIException(f"{endpoint} Network error: {err}") from err
|
|
57
|
+
|
|
58
|
+
async def fetch_data(self, t: Any) -> dict[str, Any]:
|
|
59
|
+
"""Fetch raw JSON data from the device.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
t: cJson Point(s) of the API to retrieve (e.g., ["7101", "1664"] or "7101")
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Device response dictionary with cJson Point data
|
|
66
|
+
"""
|
|
67
|
+
if not isinstance(t, list):
|
|
68
|
+
t = [t]
|
|
69
|
+
|
|
70
|
+
return await self._request("Indevolt.GetData", {"t": t})
|
|
71
|
+
|
|
72
|
+
async def set_data(self, t: str | int, v: Any) -> dict[str, Any]:
|
|
73
|
+
"""Write/push data to the device.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
t: cJson Point identifier of the API (e.g., "47015" or 47015)
|
|
77
|
+
v: Value(s) to write (will be converted to list of integers if needed)
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Device response dictionary
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
await api.set_data("47015", [2, 700, 5])
|
|
84
|
+
await api.set_data("47016", 100)
|
|
85
|
+
await api.set_data(47016, "100")
|
|
86
|
+
"""
|
|
87
|
+
# Convert v to list if not already
|
|
88
|
+
if not isinstance(v, list):
|
|
89
|
+
v = [v]
|
|
90
|
+
|
|
91
|
+
t_int = int(t)
|
|
92
|
+
v_int = [int(item) for item in v]
|
|
93
|
+
|
|
94
|
+
return await self._request("Indevolt.SetData", {"f": 16, "t": t_int, "v": v_int})
|
|
95
|
+
|
|
96
|
+
async def get_config(self) -> dict[str, Any]:
|
|
97
|
+
"""Get system configuration from the device.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Device system configuration dictionary
|
|
101
|
+
"""
|
|
102
|
+
url = f"{self.base_url}/Sys.GetConfig"
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
async with self.session.get(url, timeout=self.timeout) as response:
|
|
106
|
+
if response.status != 200:
|
|
107
|
+
raise APIException(f"HTTP status error: {response.status}")
|
|
108
|
+
return await response.json()
|
|
109
|
+
|
|
110
|
+
except TimeoutError as err:
|
|
111
|
+
raise TimeOutException("Sys.GetConfig Request timed out") from err
|
|
112
|
+
except aiohttp.ClientError as err:
|
|
113
|
+
raise APIException(f"Sys.GetConfig Network error: {err}") from err
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: indevolt-api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python API client for Indevolt devices
|
|
5
|
+
Author: A. Gideonse
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xirtnl/indevolt-api
|
|
8
|
+
Project-URL: Repository, https://github.com/xirtnl/indevolt-api
|
|
9
|
+
Project-URL: Issues, https://github.com/xirtnl/indevolt-api/issues
|
|
10
|
+
Keywords: indevolt,api,async,aiohttp
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: System :: Hardware
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# Indevolt API
|
|
28
|
+
|
|
29
|
+
Python client library for communicating with Indevolt devices (home battery systems).
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Async/await support using aiohttp
|
|
34
|
+
- Fully typed with type hints
|
|
35
|
+
- Simple and intuitive API
|
|
36
|
+
- Comprehensive error handling
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install indevolt-api
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import asyncio
|
|
48
|
+
import aiohttp
|
|
49
|
+
from indevolt_api import IndevoltAPI
|
|
50
|
+
|
|
51
|
+
async def main():
|
|
52
|
+
async with aiohttp.ClientSession() as session:
|
|
53
|
+
api = IndevoltAPI(host="192.168.1.100", port=8080, session=session)
|
|
54
|
+
|
|
55
|
+
# Get device configuration
|
|
56
|
+
config = await api.get_config()
|
|
57
|
+
print(f"Device config: {config}")
|
|
58
|
+
|
|
59
|
+
# Fetch data from specific cJson points
|
|
60
|
+
data = await api.fetch_data(["7101", "1664"])
|
|
61
|
+
print(f"Data: {data}")
|
|
62
|
+
|
|
63
|
+
# Write data (single data point) to device
|
|
64
|
+
response = await api.set_data("1142", 50)
|
|
65
|
+
print(f"Set data response: {response}")
|
|
66
|
+
|
|
67
|
+
# Write data (multiple data points) to device
|
|
68
|
+
response = await api.set_data("47015", [2, 700, 5])
|
|
69
|
+
print(f"Set data response: {response}")
|
|
70
|
+
|
|
71
|
+
asyncio.run(main())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API Reference
|
|
75
|
+
|
|
76
|
+
### IndevoltAPI
|
|
77
|
+
|
|
78
|
+
#### `__init__(host: str, port: int, session: aiohttp.ClientSession)`
|
|
79
|
+
|
|
80
|
+
Initialize the API client.
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
- `host` (str): Device hostname or IP address
|
|
84
|
+
- `port` (int): Device port number (typically 80)
|
|
85
|
+
- `session` (aiohttp.ClientSession): An aiohttp client session
|
|
86
|
+
|
|
87
|
+
#### `async fetch_data(t: str | list[str]) -> dict[str, Any]`
|
|
88
|
+
|
|
89
|
+
Fetch data from the device.
|
|
90
|
+
|
|
91
|
+
**Parameters:**
|
|
92
|
+
- `t`: Single cJson point or list of cJson points to retrieve (e.g., `"7101"` or `["7101", "1664"]`)
|
|
93
|
+
|
|
94
|
+
**Returns:**
|
|
95
|
+
- Dictionary with device response containing cJson point data
|
|
96
|
+
|
|
97
|
+
**Example:**
|
|
98
|
+
```python
|
|
99
|
+
# Single point
|
|
100
|
+
data = await api.fetch_data("7101")
|
|
101
|
+
|
|
102
|
+
# Multiple points
|
|
103
|
+
data = await api.fetch_data(["7101", "1664", "7102"])
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### `async set_data(t: str | int, v: Any) -> dict[str, Any]`
|
|
107
|
+
|
|
108
|
+
Write data to the device.
|
|
109
|
+
|
|
110
|
+
**Parameters:**
|
|
111
|
+
- `t`: cJson point identifier (e.g., `"47015"` or `47015`)
|
|
112
|
+
- `v`: Value(s) to write (automatically converted to list of integers)
|
|
113
|
+
|
|
114
|
+
**Returns:**
|
|
115
|
+
- Dictionary with device response
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
```python
|
|
119
|
+
# Single value
|
|
120
|
+
await api.set_data("47016", 100)
|
|
121
|
+
|
|
122
|
+
# Multiple values
|
|
123
|
+
await api.set_data("47015", [2, 700, 5])
|
|
124
|
+
|
|
125
|
+
# String or int identifiers
|
|
126
|
+
await api.set_data(47016, "100")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### `async get_config() -> dict[str, Any]`
|
|
130
|
+
|
|
131
|
+
Get system configuration from the device.
|
|
132
|
+
|
|
133
|
+
**Returns:**
|
|
134
|
+
- Dictionary with device system configuration
|
|
135
|
+
|
|
136
|
+
**Example:**
|
|
137
|
+
```python
|
|
138
|
+
config = await api.get_config()
|
|
139
|
+
print(config)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Exception Handling
|
|
143
|
+
|
|
144
|
+
The library provides two custom exceptions:
|
|
145
|
+
|
|
146
|
+
### `APIException`
|
|
147
|
+
|
|
148
|
+
Raised when there's a client error during API communication (network errors, HTTP errors).
|
|
149
|
+
|
|
150
|
+
### `TimeOutException`
|
|
151
|
+
|
|
152
|
+
Raised when an API request times out (default timeout: 60 seconds).
|
|
153
|
+
|
|
154
|
+
**Example:**
|
|
155
|
+
```python
|
|
156
|
+
from indevolt_api import IndevoltAPI, APIException, TimeOutException
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
data = await api.fetch_data("7101")
|
|
160
|
+
except TimeOutException:
|
|
161
|
+
print("Request timed out")
|
|
162
|
+
except APIException as e:
|
|
163
|
+
print(f"API error: {e}")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Requirements
|
|
167
|
+
|
|
168
|
+
- Python 3.11+
|
|
169
|
+
- aiohttp >= 3.9.0
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT License - see LICENSE file for details
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
pyproject.toml
|
|
3
|
+
readme.md
|
|
4
|
+
indevolt_api/__init__.py
|
|
5
|
+
indevolt_api/client.py
|
|
6
|
+
indevolt_api.egg-info/PKG-INFO
|
|
7
|
+
indevolt_api.egg-info/SOURCES.txt
|
|
8
|
+
indevolt_api.egg-info/dependency_links.txt
|
|
9
|
+
indevolt_api.egg-info/requires.txt
|
|
10
|
+
indevolt_api.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aiohttp>=3.9.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
indevolt_api
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "indevolt-api"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Python API client for Indevolt devices"
|
|
9
|
+
readme = "readme.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{name = "A. Gideonse"}
|
|
12
|
+
]
|
|
13
|
+
license = {text = "MIT"}
|
|
14
|
+
requires-python = ">=3.11"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: System :: Hardware",
|
|
25
|
+
"Typing :: Typed",
|
|
26
|
+
]
|
|
27
|
+
keywords = ["indevolt", "api", "async", "aiohttp"]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"aiohttp>=3.9.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/xirtnl/indevolt-api"
|
|
34
|
+
Repository = "https://github.com/xirtnl/indevolt-api"
|
|
35
|
+
Issues = "https://github.com/xirtnl/indevolt-api/issues"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools]
|
|
38
|
+
packages = ["indevolt_api"]
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.package-data]
|
|
41
|
+
indevolt_api = ["py.typed"]
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Indevolt API
|
|
2
|
+
|
|
3
|
+
Python client library for communicating with Indevolt devices (home battery systems).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Async/await support using aiohttp
|
|
8
|
+
- Fully typed with type hints
|
|
9
|
+
- Simple and intuitive API
|
|
10
|
+
- Comprehensive error handling
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install indevolt-api
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import asyncio
|
|
22
|
+
import aiohttp
|
|
23
|
+
from indevolt_api import IndevoltAPI
|
|
24
|
+
|
|
25
|
+
async def main():
|
|
26
|
+
async with aiohttp.ClientSession() as session:
|
|
27
|
+
api = IndevoltAPI(host="192.168.1.100", port=8080, session=session)
|
|
28
|
+
|
|
29
|
+
# Get device configuration
|
|
30
|
+
config = await api.get_config()
|
|
31
|
+
print(f"Device config: {config}")
|
|
32
|
+
|
|
33
|
+
# Fetch data from specific cJson points
|
|
34
|
+
data = await api.fetch_data(["7101", "1664"])
|
|
35
|
+
print(f"Data: {data}")
|
|
36
|
+
|
|
37
|
+
# Write data (single data point) to device
|
|
38
|
+
response = await api.set_data("1142", 50)
|
|
39
|
+
print(f"Set data response: {response}")
|
|
40
|
+
|
|
41
|
+
# Write data (multiple data points) to device
|
|
42
|
+
response = await api.set_data("47015", [2, 700, 5])
|
|
43
|
+
print(f"Set data response: {response}")
|
|
44
|
+
|
|
45
|
+
asyncio.run(main())
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API Reference
|
|
49
|
+
|
|
50
|
+
### IndevoltAPI
|
|
51
|
+
|
|
52
|
+
#### `__init__(host: str, port: int, session: aiohttp.ClientSession)`
|
|
53
|
+
|
|
54
|
+
Initialize the API client.
|
|
55
|
+
|
|
56
|
+
**Parameters:**
|
|
57
|
+
- `host` (str): Device hostname or IP address
|
|
58
|
+
- `port` (int): Device port number (typically 80)
|
|
59
|
+
- `session` (aiohttp.ClientSession): An aiohttp client session
|
|
60
|
+
|
|
61
|
+
#### `async fetch_data(t: str | list[str]) -> dict[str, Any]`
|
|
62
|
+
|
|
63
|
+
Fetch data from the device.
|
|
64
|
+
|
|
65
|
+
**Parameters:**
|
|
66
|
+
- `t`: Single cJson point or list of cJson points to retrieve (e.g., `"7101"` or `["7101", "1664"]`)
|
|
67
|
+
|
|
68
|
+
**Returns:**
|
|
69
|
+
- Dictionary with device response containing cJson point data
|
|
70
|
+
|
|
71
|
+
**Example:**
|
|
72
|
+
```python
|
|
73
|
+
# Single point
|
|
74
|
+
data = await api.fetch_data("7101")
|
|
75
|
+
|
|
76
|
+
# Multiple points
|
|
77
|
+
data = await api.fetch_data(["7101", "1664", "7102"])
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### `async set_data(t: str | int, v: Any) -> dict[str, Any]`
|
|
81
|
+
|
|
82
|
+
Write data to the device.
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
- `t`: cJson point identifier (e.g., `"47015"` or `47015`)
|
|
86
|
+
- `v`: Value(s) to write (automatically converted to list of integers)
|
|
87
|
+
|
|
88
|
+
**Returns:**
|
|
89
|
+
- Dictionary with device response
|
|
90
|
+
|
|
91
|
+
**Example:**
|
|
92
|
+
```python
|
|
93
|
+
# Single value
|
|
94
|
+
await api.set_data("47016", 100)
|
|
95
|
+
|
|
96
|
+
# Multiple values
|
|
97
|
+
await api.set_data("47015", [2, 700, 5])
|
|
98
|
+
|
|
99
|
+
# String or int identifiers
|
|
100
|
+
await api.set_data(47016, "100")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### `async get_config() -> dict[str, Any]`
|
|
104
|
+
|
|
105
|
+
Get system configuration from the device.
|
|
106
|
+
|
|
107
|
+
**Returns:**
|
|
108
|
+
- Dictionary with device system configuration
|
|
109
|
+
|
|
110
|
+
**Example:**
|
|
111
|
+
```python
|
|
112
|
+
config = await api.get_config()
|
|
113
|
+
print(config)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Exception Handling
|
|
117
|
+
|
|
118
|
+
The library provides two custom exceptions:
|
|
119
|
+
|
|
120
|
+
### `APIException`
|
|
121
|
+
|
|
122
|
+
Raised when there's a client error during API communication (network errors, HTTP errors).
|
|
123
|
+
|
|
124
|
+
### `TimeOutException`
|
|
125
|
+
|
|
126
|
+
Raised when an API request times out (default timeout: 60 seconds).
|
|
127
|
+
|
|
128
|
+
**Example:**
|
|
129
|
+
```python
|
|
130
|
+
from indevolt_api import IndevoltAPI, APIException, TimeOutException
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
data = await api.fetch_data("7101")
|
|
134
|
+
except TimeOutException:
|
|
135
|
+
print("Request timed out")
|
|
136
|
+
except APIException as e:
|
|
137
|
+
print(f"API error: {e}")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Requirements
|
|
141
|
+
|
|
142
|
+
- Python 3.11+
|
|
143
|
+
- aiohttp >= 3.9.0
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT License - see LICENSE file for details
|