pyaqvify 0.0.1__py3-none-any.whl
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.
- pyaqvify/__init__.py +14 -0
- pyaqvify/const.py +7 -0
- pyaqvify/model.py +71 -0
- pyaqvify/py.typed +0 -0
- pyaqvify/pyaqvify.py +95 -0
- pyaqvify-0.0.1.dist-info/METADATA +27 -0
- pyaqvify-0.0.1.dist-info/RECORD +10 -0
- pyaqvify-0.0.1.dist-info/WHEEL +5 -0
- pyaqvify-0.0.1.dist-info/licenses/LICENSE +21 -0
- pyaqvify-0.0.1.dist-info/top_level.txt +1 -0
pyaqvify/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Library for Aqvify integration with Home Assistant."""
|
|
2
|
+
|
|
3
|
+
from .const import VERSION as __version__
|
|
4
|
+
from .model import AqvifyAccount, AqvifyDeviceData, AqvifyDevices
|
|
5
|
+
from .pyaqvify import AqvifyAPI, AqvifyAuthException
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"AqvifyAPI",
|
|
9
|
+
"AqvifyAccount",
|
|
10
|
+
"AqvifyAuthException",
|
|
11
|
+
"AqvifyDeviceData",
|
|
12
|
+
"AqvifyDevices",
|
|
13
|
+
"__version__",
|
|
14
|
+
]
|
pyaqvify/const.py
ADDED
pyaqvify/model.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Data models for Aqvify API."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AqvifyDevices:
|
|
5
|
+
"""Data for all devices from API."""
|
|
6
|
+
|
|
7
|
+
def __init__(self, raw_data: dict) -> None:
|
|
8
|
+
"""Initialize AqvifyDevices."""
|
|
9
|
+
self.raw_data = raw_data
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def raw(self) -> dict:
|
|
13
|
+
"""Return raw data."""
|
|
14
|
+
return self.raw_data
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def devices(self) -> list[str]:
|
|
18
|
+
"""Return list of all devices."""
|
|
19
|
+
|
|
20
|
+
return list(self.raw_data.keys())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AqvifyDeviceData:
|
|
24
|
+
"""Data for a single device from API."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, raw_data: dict) -> None:
|
|
27
|
+
"""Initialize AqvifyDeviceData."""
|
|
28
|
+
self.raw_data = raw_data
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def raw(self) -> dict:
|
|
32
|
+
"""Return raw data."""
|
|
33
|
+
return self.raw_data
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def date_time(self) -> str | None:
|
|
37
|
+
"""Return the date and time."""
|
|
38
|
+
return self.raw_data.get("dateTime")
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def water_level(self) -> int | float | None:
|
|
42
|
+
"""Return the water level."""
|
|
43
|
+
return self.raw_data.get("waterLevel")
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def meter_value(self) -> int | float | None:
|
|
47
|
+
"""Return the meter value."""
|
|
48
|
+
return self.raw_data.get("meterValue")
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def status(self) -> str | None:
|
|
52
|
+
"""Return the status."""
|
|
53
|
+
return self.raw_data.get("status")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class AqvifyAccount:
|
|
57
|
+
"""Data for account from API."""
|
|
58
|
+
|
|
59
|
+
def __init__(self, raw_data: dict) -> None:
|
|
60
|
+
"""Initialize AqvifyAccount."""
|
|
61
|
+
self.raw_data = raw_data
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def raw(self) -> dict:
|
|
65
|
+
"""Return raw data."""
|
|
66
|
+
return self.raw_data
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def account_id(self) -> str:
|
|
70
|
+
"""Return the account ID."""
|
|
71
|
+
return self.raw_data.get("accountId", "")
|
pyaqvify/py.typed
ADDED
|
File without changes
|
pyaqvify/pyaqvify.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Library for Aqvify API."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from aiohttp import ClientResponse, ClientResponseError, ClientSession
|
|
8
|
+
|
|
9
|
+
from .const import AIO_TIMEOUT, AQVIFY_API as AQVIFY_API
|
|
10
|
+
|
|
11
|
+
_LOGGER = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
ACCEPT_DATA = "application/json"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AqvifyAPI:
|
|
17
|
+
"""Class to communicate with the Aqvify API."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, api_key: str, websession: ClientSession) -> None:
|
|
20
|
+
"""Initialize the API and store the api_key so we can make requests."""
|
|
21
|
+
self.api_key = api_key
|
|
22
|
+
self.websession = websession
|
|
23
|
+
|
|
24
|
+
async def request(
|
|
25
|
+
self, method: str, endpoint: str, **kwargs: Any
|
|
26
|
+
) -> ClientResponse:
|
|
27
|
+
"""Make a request."""
|
|
28
|
+
if headers := kwargs.pop("headers", {}):
|
|
29
|
+
headers = dict(headers)
|
|
30
|
+
|
|
31
|
+
headers["x-api-secret"] = self.api_key
|
|
32
|
+
|
|
33
|
+
res = await self.websession.request(
|
|
34
|
+
method,
|
|
35
|
+
f"{AQVIFY_API}{endpoint}",
|
|
36
|
+
**kwargs,
|
|
37
|
+
headers=headers,
|
|
38
|
+
)
|
|
39
|
+
res.raise_for_status()
|
|
40
|
+
return res
|
|
41
|
+
|
|
42
|
+
async def authenticate(self) -> bool:
|
|
43
|
+
"""Test if we can authenticate with the host."""
|
|
44
|
+
try:
|
|
45
|
+
await self.get_account_id()
|
|
46
|
+
except AqvifyAuthException:
|
|
47
|
+
return False
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
async def get_devices(self) -> dict[str, Any]:
|
|
51
|
+
"""Get all devices."""
|
|
52
|
+
async with asyncio.timeout(AIO_TIMEOUT):
|
|
53
|
+
res = await self.request(
|
|
54
|
+
"GET",
|
|
55
|
+
endpoint="/Device/Devices",
|
|
56
|
+
headers={"Accept": ACCEPT_DATA},
|
|
57
|
+
)
|
|
58
|
+
res.raise_for_status()
|
|
59
|
+
return await res.json()
|
|
60
|
+
|
|
61
|
+
async def get_device_latest_data(self, device_id: str) -> dict[str, Any]:
|
|
62
|
+
"""Get data for a specific device."""
|
|
63
|
+
async with asyncio.timeout(AIO_TIMEOUT):
|
|
64
|
+
res = await self.request(
|
|
65
|
+
"GET",
|
|
66
|
+
endpoint=f"/DeviceData/LatestValue/?deviceKey={device_id}",
|
|
67
|
+
headers={"Accept": ACCEPT_DATA},
|
|
68
|
+
)
|
|
69
|
+
res.raise_for_status()
|
|
70
|
+
return await res.json()
|
|
71
|
+
|
|
72
|
+
async def get_account_id(self) -> dict[str, Any]:
|
|
73
|
+
"""Get current account_id from api."""
|
|
74
|
+
try:
|
|
75
|
+
res = await self.request(
|
|
76
|
+
"GET",
|
|
77
|
+
endpoint="/User/GetAccountId",
|
|
78
|
+
headers={"Accept": ACCEPT_DATA},
|
|
79
|
+
)
|
|
80
|
+
return await res.json()
|
|
81
|
+
except ClientResponseError as exc:
|
|
82
|
+
_LOGGER.debug(
|
|
83
|
+
"API get_account_id failed. Status: %s, - %s", exc.code, exc.message
|
|
84
|
+
)
|
|
85
|
+
if exc.code == 401:
|
|
86
|
+
raise AqvifyAuthException from exc
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AqvifyException(Exception):
|
|
91
|
+
"""Generic aqvify exception."""
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class AqvifyAuthException(AqvifyException):
|
|
95
|
+
"""Authentication failure."""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyaqvify
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Python async library for PyAqvify integration with Home Assistant
|
|
5
|
+
Author-email: Ake Strandberg <ake@strandberg.eu>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/astrandb/pyaqvify
|
|
8
|
+
Project-URL: BugTracker, https://github.com/astrandb/pyaqvify/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Requires-Python: >=3.14.0
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: aiohttp
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
## pyaqvify
|
|
19
|
+
|
|
20
|
+
Python library for Aqvify integration with Home Assistant.
|
|
21
|
+
The library is distributed via pypi.org.
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
$ pip install pyaqvify
|
|
27
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pyaqvify/__init__.py,sha256=EEA3wC5jBZsj2QSPW5s7mOOO-3teRwOhsybsIbL8Nhw,364
|
|
2
|
+
pyaqvify/const.py,sha256=Bl5N23noj1Zrw_kVgFb_sJ6InLdhm2PVW2z8Tf5qot0,116
|
|
3
|
+
pyaqvify/model.py,sha256=JnJ_YLBtpRrTImRyjGWRe_C9WvrJ4h9qWigxDw93wvs,1739
|
|
4
|
+
pyaqvify/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
pyaqvify/pyaqvify.py,sha256=Ub3Ixv4azoqP-0U0CIIAC7qFiibThxsrdqJpN5J3E0M,2850
|
|
6
|
+
pyaqvify-0.0.1.dist-info/licenses/LICENSE,sha256=lfrsrZeXRbRw_1-Nlw2X9yLYR9vE8iNV_hsdtLDAfng,1072
|
|
7
|
+
pyaqvify-0.0.1.dist-info/METADATA,sha256=izQxQ1WYy8b-YoRA4xlKSL1_Ox9c6e2P85fER7rPMHw,759
|
|
8
|
+
pyaqvify-0.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
9
|
+
pyaqvify-0.0.1.dist-info/top_level.txt,sha256=pS0QNWt8p5fO2W75pptj6_WlwCJrqY_uCPJ_JpxbHMc,9
|
|
10
|
+
pyaqvify-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Åke Strandberg
|
|
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 @@
|
|
|
1
|
+
pyaqvify
|