weheat 2025.1.14rc1__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.
Potentially problematic release.
This version of weheat might be problematic. Click here for more details.
- weheat-2025.1.14rc1/LICENSE +21 -0
- weheat-2025.1.14rc1/PKG-INFO +117 -0
- weheat-2025.1.14rc1/README.md +91 -0
- weheat-2025.1.14rc1/pyproject.toml +30 -0
- weheat-2025.1.14rc1/setup.cfg +10 -0
- weheat-2025.1.14rc1/setup.py +50 -0
- weheat-2025.1.14rc1/tests/test_ha_api.py +97 -0
- weheat-2025.1.14rc1/weheat/__init__.py +45 -0
- weheat-2025.1.14rc1/weheat/abstractions/__init__.py +3 -0
- weheat-2025.1.14rc1/weheat/abstractions/auth.py +34 -0
- weheat-2025.1.14rc1/weheat/abstractions/discovery.py +62 -0
- weheat-2025.1.14rc1/weheat/abstractions/heat_pump.py +273 -0
- weheat-2025.1.14rc1/weheat/abstractions/user.py +23 -0
- weheat-2025.1.14rc1/weheat/api/__init__.py +7 -0
- weheat-2025.1.14rc1/weheat/api/energy_log_api.py +230 -0
- weheat-2025.1.14rc1/weheat/api/heat_pump_api.py +532 -0
- weheat-2025.1.14rc1/weheat/api/heat_pump_log_api.py +554 -0
- weheat-2025.1.14rc1/weheat/api/user_api.py +193 -0
- weheat-2025.1.14rc1/weheat/api_client.py +766 -0
- weheat-2025.1.14rc1/weheat/api_response.py +29 -0
- weheat-2025.1.14rc1/weheat/configuration.py +442 -0
- weheat-2025.1.14rc1/weheat/exceptions.py +166 -0
- weheat-2025.1.14rc1/weheat/models/__init__.py +24 -0
- weheat-2025.1.14rc1/weheat/models/boiler_type.py +42 -0
- weheat-2025.1.14rc1/weheat/models/device_state.py +46 -0
- weheat-2025.1.14rc1/weheat/models/dhw_type.py +41 -0
- weheat-2025.1.14rc1/weheat/models/energy_view_dto.py +121 -0
- weheat-2025.1.14rc1/weheat/models/heat_pump_log_view_dto.py +771 -0
- weheat-2025.1.14rc1/weheat/models/heat_pump_model.py +44 -0
- weheat-2025.1.14rc1/weheat/models/heat_pump_status_enum.py +46 -0
- weheat-2025.1.14rc1/weheat/models/heat_pump_type.py +42 -0
- weheat-2025.1.14rc1/weheat/models/raw_heat_pump_log_dto.py +517 -0
- weheat-2025.1.14rc1/weheat/models/read_all_heat_pump_dto.py +124 -0
- weheat-2025.1.14rc1/weheat/models/read_heat_pump_dto.py +117 -0
- weheat-2025.1.14rc1/weheat/models/read_user_dto.py +102 -0
- weheat-2025.1.14rc1/weheat/models/role.py +46 -0
- weheat-2025.1.14rc1/weheat/py.typed +0 -0
- weheat-2025.1.14rc1/weheat/rest.py +327 -0
- weheat-2025.1.14rc1/weheat.egg-info/PKG-INFO +117 -0
- weheat-2025.1.14rc1/weheat.egg-info/SOURCES.txt +42 -0
- weheat-2025.1.14rc1/weheat.egg-info/dependency_links.txt +1 -0
- weheat-2025.1.14rc1/weheat.egg-info/requires.txt +5 -0
- weheat-2025.1.14rc1/weheat.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Weheat B.V.
|
|
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,117 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: weheat
|
|
3
|
+
Version: 2025.1.14rc1
|
|
4
|
+
Summary: Weheat Backend client
|
|
5
|
+
Home-page: https://github.com/wefabricate/wh-python
|
|
6
|
+
Author: Jesper Raemaekers
|
|
7
|
+
Author-email: jesper.raemaekers@wefabricate.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: OpenAPI,OpenAPI-Generator,Weheat Backend
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: urllib3<2.1.0,>=1.25.3
|
|
13
|
+
Requires-Dist: python-dateutil
|
|
14
|
+
Requires-Dist: pydantic<3,>=1.10.5
|
|
15
|
+
Requires-Dist: aenum
|
|
16
|
+
Requires-Dist: aiohttp
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: author-email
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: keywords
|
|
23
|
+
Dynamic: license
|
|
24
|
+
Dynamic: requires-dist
|
|
25
|
+
Dynamic: summary
|
|
26
|
+
|
|
27
|
+
# Weheat backend client
|
|
28
|
+
|
|
29
|
+
This is a client for the Weheat backend. It is automatically generated from the OpenAPI specification.
|
|
30
|
+
|
|
31
|
+
## Requirements.
|
|
32
|
+
|
|
33
|
+
Python 3.7+
|
|
34
|
+
|
|
35
|
+
## Installation & Usage
|
|
36
|
+
|
|
37
|
+
You can install directly using:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
pip install weheat
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then import the package:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import weheat
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Getting Started
|
|
52
|
+
|
|
53
|
+
After installation, you can now use the client to interact with the Weheat backend.
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import datetime
|
|
57
|
+
from keycloak import KeycloakOpenID # install with pip install python-keycloak
|
|
58
|
+
from weheat import ApiClient, Configuration, HeatPumpApi, HeatPumpLogApi, EnergyLogApi
|
|
59
|
+
|
|
60
|
+
# input your information here
|
|
61
|
+
auth_url = 'https://auth.weheat.nl/auth/'
|
|
62
|
+
api_url = 'https://api.weheat.nl'
|
|
63
|
+
realm_name = 'Weheat'
|
|
64
|
+
my_client_id = 'WeheatCommunityAPI' # client ID and secret provided by Weheat
|
|
65
|
+
my_client_secret = ''
|
|
66
|
+
username = '' # username and password used for the online portal
|
|
67
|
+
password = ''
|
|
68
|
+
my_heat_pump_id = '' # your heat pump UUID
|
|
69
|
+
|
|
70
|
+
# Get the access token from keycloak
|
|
71
|
+
keycloak_open_id = KeycloakOpenID(server_url=auth_url,
|
|
72
|
+
client_id=my_client_id,
|
|
73
|
+
realm_name=realm_name,
|
|
74
|
+
client_secret_key=my_client_secret)
|
|
75
|
+
|
|
76
|
+
token_response = keycloak_open_id.token(username, password)
|
|
77
|
+
keycloak_open_id.logout(token_response['refresh_token'])
|
|
78
|
+
|
|
79
|
+
# Create the cinfiguration object
|
|
80
|
+
config = Configuration(host=api_url, access_token=token_response['access_token'])
|
|
81
|
+
|
|
82
|
+
# with the client the APIs can be accessed
|
|
83
|
+
with ApiClient(configuration=config) as client:
|
|
84
|
+
# Getting all heat pumps that the user has access to
|
|
85
|
+
response = HeatPumpApi(client).api_v1_heat_pumps_get_with_http_info()
|
|
86
|
+
|
|
87
|
+
if response.status_code == 200:
|
|
88
|
+
print(f'My heat pump: {response.data}')
|
|
89
|
+
|
|
90
|
+
# Getting the latest log of the heat pump
|
|
91
|
+
response = HeatPumpLogApi(client).api_v1_heat_pumps_heat_pump_id_logs_latest_get_with_http_info(
|
|
92
|
+
heat_pump_id=my_heat_pump_id)
|
|
93
|
+
|
|
94
|
+
if response.status_code == 200:
|
|
95
|
+
print(f'My heat pump logs: {response.data}')
|
|
96
|
+
|
|
97
|
+
# Getting the energy logs of the heat pump in a specific period
|
|
98
|
+
# interval can be "Minute", "FiveMinute", "FifteenMinute", "Hour", "Day", "Week", "Month", "Year"
|
|
99
|
+
response = EnergyLogApi(client).api_v1_energy_logs_heat_pump_id_get_with_http_info(heat_pump_id=my_heat_pump_id,
|
|
100
|
+
start_time=datetime.datetime(
|
|
101
|
+
2024, 6,
|
|
102
|
+
22, 0, 0,
|
|
103
|
+
0),
|
|
104
|
+
end_time=datetime.datetime(2024,
|
|
105
|
+
6, 22,
|
|
106
|
+
15, 0,
|
|
107
|
+
0),
|
|
108
|
+
interval='Hour')
|
|
109
|
+
|
|
110
|
+
if response.status_code == 200:
|
|
111
|
+
print(f'My energy logs: {response.data}')
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Weheat backend client
|
|
2
|
+
|
|
3
|
+
This is a client for the Weheat backend. It is automatically generated from the OpenAPI specification.
|
|
4
|
+
|
|
5
|
+
## Requirements.
|
|
6
|
+
|
|
7
|
+
Python 3.7+
|
|
8
|
+
|
|
9
|
+
## Installation & Usage
|
|
10
|
+
|
|
11
|
+
You can install directly using:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install weheat
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then import the package:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import weheat
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Getting Started
|
|
26
|
+
|
|
27
|
+
After installation, you can now use the client to interact with the Weheat backend.
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import datetime
|
|
31
|
+
from keycloak import KeycloakOpenID # install with pip install python-keycloak
|
|
32
|
+
from weheat import ApiClient, Configuration, HeatPumpApi, HeatPumpLogApi, EnergyLogApi
|
|
33
|
+
|
|
34
|
+
# input your information here
|
|
35
|
+
auth_url = 'https://auth.weheat.nl/auth/'
|
|
36
|
+
api_url = 'https://api.weheat.nl'
|
|
37
|
+
realm_name = 'Weheat'
|
|
38
|
+
my_client_id = 'WeheatCommunityAPI' # client ID and secret provided by Weheat
|
|
39
|
+
my_client_secret = ''
|
|
40
|
+
username = '' # username and password used for the online portal
|
|
41
|
+
password = ''
|
|
42
|
+
my_heat_pump_id = '' # your heat pump UUID
|
|
43
|
+
|
|
44
|
+
# Get the access token from keycloak
|
|
45
|
+
keycloak_open_id = KeycloakOpenID(server_url=auth_url,
|
|
46
|
+
client_id=my_client_id,
|
|
47
|
+
realm_name=realm_name,
|
|
48
|
+
client_secret_key=my_client_secret)
|
|
49
|
+
|
|
50
|
+
token_response = keycloak_open_id.token(username, password)
|
|
51
|
+
keycloak_open_id.logout(token_response['refresh_token'])
|
|
52
|
+
|
|
53
|
+
# Create the cinfiguration object
|
|
54
|
+
config = Configuration(host=api_url, access_token=token_response['access_token'])
|
|
55
|
+
|
|
56
|
+
# with the client the APIs can be accessed
|
|
57
|
+
with ApiClient(configuration=config) as client:
|
|
58
|
+
# Getting all heat pumps that the user has access to
|
|
59
|
+
response = HeatPumpApi(client).api_v1_heat_pumps_get_with_http_info()
|
|
60
|
+
|
|
61
|
+
if response.status_code == 200:
|
|
62
|
+
print(f'My heat pump: {response.data}')
|
|
63
|
+
|
|
64
|
+
# Getting the latest log of the heat pump
|
|
65
|
+
response = HeatPumpLogApi(client).api_v1_heat_pumps_heat_pump_id_logs_latest_get_with_http_info(
|
|
66
|
+
heat_pump_id=my_heat_pump_id)
|
|
67
|
+
|
|
68
|
+
if response.status_code == 200:
|
|
69
|
+
print(f'My heat pump logs: {response.data}')
|
|
70
|
+
|
|
71
|
+
# Getting the energy logs of the heat pump in a specific period
|
|
72
|
+
# interval can be "Minute", "FiveMinute", "FifteenMinute", "Hour", "Day", "Week", "Month", "Year"
|
|
73
|
+
response = EnergyLogApi(client).api_v1_energy_logs_heat_pump_id_get_with_http_info(heat_pump_id=my_heat_pump_id,
|
|
74
|
+
start_time=datetime.datetime(
|
|
75
|
+
2024, 6,
|
|
76
|
+
22, 0, 0,
|
|
77
|
+
0),
|
|
78
|
+
end_time=datetime.datetime(2024,
|
|
79
|
+
6, 22,
|
|
80
|
+
15, 0,
|
|
81
|
+
0),
|
|
82
|
+
interval='Hour')
|
|
83
|
+
|
|
84
|
+
if response.status_code == 200:
|
|
85
|
+
print(f'My energy logs: {response.data}')
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "weheat"
|
|
3
|
+
version = "2025.1.14rc1"
|
|
4
|
+
description = "Weheat Backend"
|
|
5
|
+
authors = ["Jesper Raemaekers <jesper.raemaekers@wefabricate.com>", "Kjell van Straaten <kjell.van.straaten@wefabricate.com>"]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
repository = "https://github.com/wefabricate/wh-python"
|
|
9
|
+
keywords = ["OpenAPI", "OpenAPI-Generator", "Weheat Backend"]
|
|
10
|
+
include = ["weheat/py.typed"]
|
|
11
|
+
|
|
12
|
+
[tool.poetry.dependencies]
|
|
13
|
+
python = "^3.7"
|
|
14
|
+
|
|
15
|
+
urllib3 = ">= 1.25.3"
|
|
16
|
+
python-dateutil = ">=2.8.2"
|
|
17
|
+
pydantic = ">=1.10.5, < 3"
|
|
18
|
+
aenum = ">=3.1.11"
|
|
19
|
+
|
|
20
|
+
[tool.poetry.dev-dependencies]
|
|
21
|
+
pytest = ">=7.2.1"
|
|
22
|
+
tox = ">=3.9.0"
|
|
23
|
+
flake8 = ">=4.0.0"
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = ["setuptools"]
|
|
27
|
+
build-backend = "setuptools.build_meta"
|
|
28
|
+
|
|
29
|
+
[tool.pylint.'MESSAGES CONTROL']
|
|
30
|
+
extension-pkg-whitelist = "pydantic"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Weheat Backend
|
|
5
|
+
|
|
6
|
+
This is the backend for the Weheat project
|
|
7
|
+
|
|
8
|
+
The version of the OpenAPI document: v1
|
|
9
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
|
+
|
|
11
|
+
Do not edit the class manually.
|
|
12
|
+
""" # noqa: E501
|
|
13
|
+
import pathlib
|
|
14
|
+
|
|
15
|
+
from setuptools import setup, find_packages # noqa: H301
|
|
16
|
+
|
|
17
|
+
# To install the library, run the following
|
|
18
|
+
#
|
|
19
|
+
# python setup.py install
|
|
20
|
+
#
|
|
21
|
+
# prerequisite: setuptools
|
|
22
|
+
# http://pypi.python.org/pypi/setuptools
|
|
23
|
+
NAME = "weheat"
|
|
24
|
+
VERSION = "2025.1.14rc1"
|
|
25
|
+
PYTHON_REQUIRES = ">=3.7"
|
|
26
|
+
REQUIRES = [
|
|
27
|
+
"urllib3 >= 1.25.3, < 2.1.0",
|
|
28
|
+
"python-dateutil",
|
|
29
|
+
"pydantic >= 1.10.5, < 3",
|
|
30
|
+
"aenum",
|
|
31
|
+
"aiohttp"
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
setup(
|
|
35
|
+
name=NAME,
|
|
36
|
+
version=VERSION,
|
|
37
|
+
description="Weheat Backend client",
|
|
38
|
+
author="Jesper Raemaekers",
|
|
39
|
+
author_email="jesper.raemaekers@wefabricate.com",
|
|
40
|
+
url="https://github.com/wefabricate/wh-python",
|
|
41
|
+
keywords=["OpenAPI", "OpenAPI-Generator", "Weheat Backend"],
|
|
42
|
+
install_requires=REQUIRES,
|
|
43
|
+
packages=find_packages(exclude=["test", "tests"]),
|
|
44
|
+
include_package_data=True,
|
|
45
|
+
long_description_content_type='text/markdown',
|
|
46
|
+
long_description=pathlib.Path("README.md").read_text(), # noqa: E501
|
|
47
|
+
package_data={"weheat": ["py.typed"]},
|
|
48
|
+
license="MIT",
|
|
49
|
+
license_files = ('LICENSE',),
|
|
50
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pydantic import ValidationError
|
|
3
|
+
|
|
4
|
+
from weheat.abstractions.heat_pump import HeatPump
|
|
5
|
+
|
|
6
|
+
from weheat.abstractions.discovery import HeatPumpDiscovery
|
|
7
|
+
from weheat.abstractions.user import async_get_user_id_from_token
|
|
8
|
+
from weheat.exceptions import UnauthorizedException, ForbiddenException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
uuid_list = [
|
|
12
|
+
'54ad613f-48e5-4583-b0e0-1a96d29131fa',
|
|
13
|
+
'306625f3-124a-42eb-8e31-952963c65932',
|
|
14
|
+
'573852f6-029f-4106-a019-2183b14a351f'
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
@pytest.mark.asyncio
|
|
18
|
+
async def test_discovery(api_fixture):
|
|
19
|
+
discovery = await HeatPumpDiscovery.async_discover_active(api_url=api_fixture.api_url, access_token=api_fixture.access_token)
|
|
20
|
+
|
|
21
|
+
#The account is configured to find at least one Blackbird, one sparrow and one flint
|
|
22
|
+
assert len(discovery) >= 3
|
|
23
|
+
|
|
24
|
+
#check some information for each pump, find it by type in the list
|
|
25
|
+
blackbird = [hp for hp in discovery if 'blackbird' in hp.model.lower()]
|
|
26
|
+
sparrow = [hp for hp in discovery if 'sparrow' in hp.model.lower()]
|
|
27
|
+
flint = [hp for hp in discovery if 'flint' in hp.model.lower()]
|
|
28
|
+
|
|
29
|
+
# sanity check lengths
|
|
30
|
+
assert len(blackbird) >= 1
|
|
31
|
+
assert len(sparrow) >= 1
|
|
32
|
+
assert len(flint) >= 1
|
|
33
|
+
|
|
34
|
+
blackbird = blackbird[0]
|
|
35
|
+
sparrow = sparrow[0]
|
|
36
|
+
flint = flint[0]
|
|
37
|
+
|
|
38
|
+
# must have a UUID
|
|
39
|
+
assert len(blackbird.uuid) == 36
|
|
40
|
+
assert len(sparrow.uuid) == 36
|
|
41
|
+
assert len(flint.uuid) == 36
|
|
42
|
+
|
|
43
|
+
# must have a serial number
|
|
44
|
+
assert len(blackbird.sn) == 12
|
|
45
|
+
assert len(sparrow.sn) == 12
|
|
46
|
+
assert len(flint.sn) == 12
|
|
47
|
+
|
|
48
|
+
@pytest.mark.asyncio
|
|
49
|
+
async def test_user(api_fixture):
|
|
50
|
+
user = await async_get_user_id_from_token(api_fixture.api_url, api_fixture.access_token)
|
|
51
|
+
|
|
52
|
+
#check we got a UUID
|
|
53
|
+
assert len(user) == 36
|
|
54
|
+
|
|
55
|
+
@pytest.mark.parametrize("uuid", uuid_list)
|
|
56
|
+
@pytest.mark.asyncio
|
|
57
|
+
async def test_hp_log(api_fixture, uuid):
|
|
58
|
+
heatpump = HeatPump(api_fixture.api_url, uuid)
|
|
59
|
+
|
|
60
|
+
# if the API is changed, this call will fail on a python validation error
|
|
61
|
+
try:
|
|
62
|
+
await heatpump.async_get_status(api_fixture.access_token)
|
|
63
|
+
except ValidationError as e:
|
|
64
|
+
print(f'Validation unsuccessful: {e}')
|
|
65
|
+
pytest.fail('Validation failed')
|
|
66
|
+
|
|
67
|
+
except UnauthorizedException as e:
|
|
68
|
+
pytest.fail('get_status call failed')
|
|
69
|
+
except ForbiddenException as e:
|
|
70
|
+
pytest.fail('get_status call failed')
|
|
71
|
+
except Exception as e:
|
|
72
|
+
pytest.fail('get_status call failed')
|
|
73
|
+
|
|
74
|
+
# check that all core values are present
|
|
75
|
+
assert heatpump.water_inlet_temperature >= 10
|
|
76
|
+
assert heatpump.water_outlet_temperature >= 10
|
|
77
|
+
assert heatpump.air_inlet_temperature >= -20
|
|
78
|
+
if heatpump.air_outlet_temperature is not None: # flint does not have an air out sensor
|
|
79
|
+
assert heatpump.air_outlet_temperature >= -20
|
|
80
|
+
if heatpump.water_house_in_temperature is not None: # indoor unit may be disconnected
|
|
81
|
+
assert heatpump.water_house_in_temperature >= -1
|
|
82
|
+
if heatpump.thermostat_room_temperature_setpoint is not None: #thermostat may be disconnected
|
|
83
|
+
assert heatpump.thermostat_room_temperature_setpoint >= -1
|
|
84
|
+
if heatpump.thermostat_room_temperature is not None: #thermostat may be disconnected
|
|
85
|
+
assert heatpump.thermostat_room_temperature >= -1
|
|
86
|
+
assert heatpump.power_input >= 0
|
|
87
|
+
assert heatpump.power_output >= 0
|
|
88
|
+
assert heatpump.compressor_rpm >= 0
|
|
89
|
+
assert heatpump.heat_pump_state in HeatPump.State
|
|
90
|
+
assert heatpump.energy_total >= 0
|
|
91
|
+
assert heatpump.energy_output >= 0
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# flake8: noqa
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Weheat Backend
|
|
7
|
+
|
|
8
|
+
This is the backend for the Weheat project
|
|
9
|
+
|
|
10
|
+
The version of the OpenAPI document: v1
|
|
11
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
12
|
+
|
|
13
|
+
Do not edit the class manually.
|
|
14
|
+
""" # noqa: E501
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
__version__ = "2024.07.08"
|
|
18
|
+
|
|
19
|
+
# import apis into sdk package
|
|
20
|
+
from weheat.api.energy_log_api import EnergyLogApi
|
|
21
|
+
from weheat.api.heat_pump_api import HeatPumpApi
|
|
22
|
+
from weheat.api.heat_pump_log_api import HeatPumpLogApi
|
|
23
|
+
from weheat.api.user_api import UserApi
|
|
24
|
+
|
|
25
|
+
# import ApiClient
|
|
26
|
+
from weheat.api_response import ApiResponse
|
|
27
|
+
from weheat.api_client import ApiClient
|
|
28
|
+
from weheat.configuration import Configuration
|
|
29
|
+
from weheat.exceptions import OpenApiException
|
|
30
|
+
from weheat.exceptions import ApiTypeError
|
|
31
|
+
from weheat.exceptions import ApiValueError
|
|
32
|
+
from weheat.exceptions import ApiKeyError
|
|
33
|
+
from weheat.exceptions import ApiAttributeError
|
|
34
|
+
from weheat.exceptions import ApiException
|
|
35
|
+
|
|
36
|
+
# import models into sdk package
|
|
37
|
+
from weheat.models.device_state import DeviceState
|
|
38
|
+
from weheat.models.energy_view_dto import EnergyViewDto
|
|
39
|
+
from weheat.models.heat_pump_log_view_dto import HeatPumpLogViewDto
|
|
40
|
+
from weheat.models.raw_heat_pump_log_dto import RawHeatPumpLogDto
|
|
41
|
+
from weheat.models.read_all_heat_pump_dto import ReadAllHeatPumpDto
|
|
42
|
+
from weheat.models.read_heat_pump_dto import ReadHeatPumpDto
|
|
43
|
+
from weheat.models.read_user_dto import ReadUserDto
|
|
44
|
+
from weheat.models.role import Role
|
|
45
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from aiohttp import ClientSession, ClientResponse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AbstractAuth(ABC):
|
|
6
|
+
"""Abstract class to make authenticated requests."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, websession: ClientSession, host: str) -> None:
|
|
9
|
+
"""Initialize the auth."""
|
|
10
|
+
self.websession = websession
|
|
11
|
+
self.host = host
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
async def async_get_access_token(self) -> str:
|
|
15
|
+
"""Return a valid access token."""
|
|
16
|
+
|
|
17
|
+
async def request(self, method, url, **kwargs) -> ClientResponse:
|
|
18
|
+
"""Make a request."""
|
|
19
|
+
headers = kwargs.get("headers")
|
|
20
|
+
|
|
21
|
+
if headers is None:
|
|
22
|
+
headers = {}
|
|
23
|
+
else:
|
|
24
|
+
headers = dict(headers)
|
|
25
|
+
|
|
26
|
+
access_token = await self.async_get_access_token()
|
|
27
|
+
headers["authorization"] = f"Bearer {access_token}"
|
|
28
|
+
|
|
29
|
+
return await self.websession.request(
|
|
30
|
+
method,
|
|
31
|
+
f"{self.host}/{url}",
|
|
32
|
+
**kwargs,
|
|
33
|
+
headers=headers,
|
|
34
|
+
)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
from weheat import DeviceState
|
|
5
|
+
from weheat.configuration import Configuration
|
|
6
|
+
from weheat.api_client import ApiClient
|
|
7
|
+
from weheat.api.heat_pump_api import HeatPumpApi
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class HeatPumpDiscovery:
|
|
11
|
+
@dataclass
|
|
12
|
+
class HeatPumpInfo:
|
|
13
|
+
uuid: str
|
|
14
|
+
name: str
|
|
15
|
+
model: str
|
|
16
|
+
sn : str
|
|
17
|
+
has_dhw: bool = False
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
async def async_discover_active(api_url: str, access_token: str) -> list[HeatPumpInfo]:
|
|
21
|
+
discovered_pumps = []
|
|
22
|
+
|
|
23
|
+
config = Configuration(host=api_url, access_token=access_token)
|
|
24
|
+
|
|
25
|
+
with ApiClient(configuration=config) as client:
|
|
26
|
+
|
|
27
|
+
response = HeatPumpApi(client).api_v1_heat_pumps_get_with_http_info('', 1, 1000, DeviceState.NUMBER_3 ,async_req=True)
|
|
28
|
+
|
|
29
|
+
response = await asyncio.to_thread(response.get)
|
|
30
|
+
|
|
31
|
+
if response.status_code == 200:
|
|
32
|
+
for pump in response.data:
|
|
33
|
+
# Model of the heat pump
|
|
34
|
+
# - BlackBirdP80: BlackBird P80 heat pump (0)
|
|
35
|
+
# - BlackBirdP60: BlackBird P60 heat pump (1)
|
|
36
|
+
# - SparrowP60Brown: Sparrow P60 heat pump, colour brown (default) (2)
|
|
37
|
+
# - SparrowP60Green: Sparrow P60 heat pump, colour green (3)
|
|
38
|
+
# - SparrowP60Grey: Sparrow P60 heat pump, colour grey (4)
|
|
39
|
+
# - FlintP40: Flint P40 heat pump (5)
|
|
40
|
+
model_string = "Blackbird P80 heat pump"
|
|
41
|
+
if pump.model == 1:
|
|
42
|
+
model_string = "Blackbird P60 heat pump"
|
|
43
|
+
elif 2 <= pump.model <= 4:
|
|
44
|
+
model_string = "Sparrow P60 heat pump"
|
|
45
|
+
elif pump.model == 5:
|
|
46
|
+
model_string = "Flint P40 heat pump"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
dhw = False
|
|
50
|
+
if pump.dhw_type is not None and pump.dhw_type == 1:
|
|
51
|
+
dhw = True
|
|
52
|
+
|
|
53
|
+
discovered_pumps.append(
|
|
54
|
+
HeatPumpDiscovery.HeatPumpInfo(
|
|
55
|
+
uuid=pump.id,
|
|
56
|
+
name=pump.name,
|
|
57
|
+
model=model_string,
|
|
58
|
+
sn=pump.serial_number,
|
|
59
|
+
has_dhw=dhw,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
return discovered_pumps
|