weheat 2024.7.8__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.

Files changed (37) hide show
  1. weheat-2024.7.8/PKG-INFO +105 -0
  2. weheat-2024.7.8/README.md +91 -0
  3. weheat-2024.7.8/pyproject.toml +30 -0
  4. weheat-2024.7.8/setup.cfg +7 -0
  5. weheat-2024.7.8/setup.py +47 -0
  6. weheat-2024.7.8/weheat/__init__.py +42 -0
  7. weheat-2024.7.8/weheat/abstractions/__init__.py +3 -0
  8. weheat-2024.7.8/weheat/abstractions/auth.py +34 -0
  9. weheat-2024.7.8/weheat/abstractions/discovery.py +47 -0
  10. weheat-2024.7.8/weheat/abstractions/heat_pump.py +150 -0
  11. weheat-2024.7.8/weheat/api/__init__.py +6 -0
  12. weheat-2024.7.8/weheat/api/energy_log_api.py +228 -0
  13. weheat-2024.7.8/weheat/api/heat_pump_api.py +530 -0
  14. weheat-2024.7.8/weheat/api/heat_pump_log_api.py +553 -0
  15. weheat-2024.7.8/weheat/api_client.py +766 -0
  16. weheat-2024.7.8/weheat/api_response.py +25 -0
  17. weheat-2024.7.8/weheat/configuration.py +442 -0
  18. weheat-2024.7.8/weheat/exceptions.py +166 -0
  19. weheat-2024.7.8/weheat/models/__init__.py +22 -0
  20. weheat-2024.7.8/weheat/models/boiler_type.py +42 -0
  21. weheat-2024.7.8/weheat/models/device_state.py +46 -0
  22. weheat-2024.7.8/weheat/models/dhw_type.py +41 -0
  23. weheat-2024.7.8/weheat/models/energy_view_dto.py +118 -0
  24. weheat-2024.7.8/weheat/models/heat_pump_log_view_dto.py +768 -0
  25. weheat-2024.7.8/weheat/models/heat_pump_model.py +41 -0
  26. weheat-2024.7.8/weheat/models/heat_pump_status_enum.py +46 -0
  27. weheat-2024.7.8/weheat/models/heat_pump_type.py +42 -0
  28. weheat-2024.7.8/weheat/models/raw_heat_pump_log_dto.py +513 -0
  29. weheat-2024.7.8/weheat/models/read_all_heat_pump_dto.py +121 -0
  30. weheat-2024.7.8/weheat/models/read_heat_pump_dto.py +114 -0
  31. weheat-2024.7.8/weheat/py.typed +0 -0
  32. weheat-2024.7.8/weheat/rest.py +327 -0
  33. weheat-2024.7.8/weheat.egg-info/PKG-INFO +105 -0
  34. weheat-2024.7.8/weheat.egg-info/SOURCES.txt +36 -0
  35. weheat-2024.7.8/weheat.egg-info/dependency_links.txt +1 -0
  36. weheat-2024.7.8/weheat.egg-info/requires.txt +4 -0
  37. weheat-2024.7.8/weheat.egg-info/top_level.txt +1 -0
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.1
2
+ Name: weheat
3
+ Version: 2024.7.8
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
+ Keywords: OpenAPI,OpenAPI-Generator,Weheat Backend
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: urllib3<2.1.0,>=1.25.3
11
+ Requires-Dist: python-dateutil
12
+ Requires-Dist: pydantic<2,>=1.10.5
13
+ Requires-Dist: aenum
14
+
15
+ # Weheat backend client
16
+
17
+ This is a client for the Weheat backend. It is automatically generated from the OpenAPI specification.
18
+
19
+ ## Requirements.
20
+
21
+ Python 3.7+
22
+
23
+ ## Installation & Usage
24
+
25
+ You can install directly using:
26
+
27
+ ```sh
28
+ pip install weheat
29
+ ```
30
+
31
+ Then import the package:
32
+
33
+ ```python
34
+ import weheat
35
+ ```
36
+
37
+
38
+
39
+ ## Getting Started
40
+
41
+ After installation, you can now use the client to interact with the Weheat backend.
42
+
43
+ ```python
44
+ import datetime
45
+ from keycloak import KeycloakOpenID # install with pip install python-keycloak
46
+ from weheat import ApiClient, Configuration, HeatPumpApi, HeatPumpLogApi, EnergyLogApi
47
+
48
+ # input your information here
49
+ auth_url = 'https://auth.weheat.nl/auth/'
50
+ api_url = 'https://api.weheat.nl'
51
+ realm_name = 'Weheat'
52
+ my_client_id = 'WeheatCommunityAPI' # client ID and secret provided by Weheat
53
+ my_client_secret = ''
54
+ username = '' # username and password used for the online portal
55
+ password = ''
56
+ my_heat_pump_id = '' # your heat pump UUID
57
+
58
+ # Get the access token from keycloak
59
+ keycloak_open_id = KeycloakOpenID(server_url=auth_url,
60
+ client_id=my_client_id,
61
+ realm_name=realm_name,
62
+ client_secret_key=my_client_secret)
63
+
64
+ token_response = keycloak_open_id.token(username, password)
65
+ keycloak_open_id.logout(token_response['refresh_token'])
66
+
67
+ # Create the cinfiguration object
68
+ config = Configuration(host=api_url, access_token=token_response['access_token'])
69
+
70
+ # with the client the APIs can be accessed
71
+ with ApiClient(configuration=config) as client:
72
+ # Getting all heat pumps that the user has access to
73
+ response = HeatPumpApi(client).api_v1_heat_pumps_get_with_http_info()
74
+
75
+ if response.status_code == 200:
76
+ print(f'My heat pump: {response.data}')
77
+
78
+ # Getting the latest log of the heat pump
79
+ response = HeatPumpLogApi(client).api_v1_heat_pumps_heat_pump_id_logs_latest_get_with_http_info(
80
+ heat_pump_id=my_heat_pump_id)
81
+
82
+ if response.status_code == 200:
83
+ print(f'My heat pump logs: {response.data}')
84
+
85
+ # Getting the energy logs of the heat pump in a specific period
86
+ # interval can be "Minute", "FiveMinute", "FifteenMinute", "Hour", "Day", "Week", "Month", "Year"
87
+ response = EnergyLogApi(client).api_v1_energy_logs_heat_pump_id_get_with_http_info(heat_pump_id=my_heat_pump_id,
88
+ start_time=datetime.datetime(
89
+ 2024, 6,
90
+ 22, 0, 0,
91
+ 0),
92
+ end_time=datetime.datetime(2024,
93
+ 6, 22,
94
+ 15, 0,
95
+ 0),
96
+ interval='Hour')
97
+
98
+ if response.status_code == 200:
99
+ print(f'My energy logs: {response.data}')
100
+
101
+
102
+ ```
103
+
104
+
105
+
@@ -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 = "2024.07.08"
4
+ description = "Weheat Backend"
5
+ authors = ["Jesper Raemaekers <jesper.raemaekers@wefabricate.com>", "Kjell van Straaten <kjell.van.straaten@wefabricate.com>"]
6
+ license = "NoLicense"
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, <2"
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,7 @@
1
+ [flake8]
2
+ max-line-length = 99
3
+
4
+ [egg_info]
5
+ tag_build =
6
+ tag_date = 0
7
+
@@ -0,0 +1,47 @@
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 = "2024.07.08"
25
+ PYTHON_REQUIRES = ">=3.7"
26
+ REQUIRES = [
27
+ "urllib3 >= 1.25.3, < 2.1.0",
28
+ "python-dateutil",
29
+ "pydantic >= 1.10.5, < 2",
30
+ "aenum"
31
+ ]
32
+
33
+ setup(
34
+ name=NAME,
35
+ version=VERSION,
36
+ description="Weheat Backend client",
37
+ author="Jesper Raemaekers",
38
+ author_email="jesper.raemaekers@wefabricate.com",
39
+ url="https://github.com/wefabricate/wh-python",
40
+ keywords=["OpenAPI", "OpenAPI-Generator", "Weheat Backend"],
41
+ install_requires=REQUIRES,
42
+ packages=find_packages(exclude=["test", "tests"]),
43
+ include_package_data=True,
44
+ long_description_content_type='text/markdown',
45
+ long_description=pathlib.Path("README.md").read_text(), # noqa: E501
46
+ package_data={"weheat": ["py.typed"]},
47
+ )
@@ -0,0 +1,42 @@
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
+
24
+ # import ApiClient
25
+ from weheat.api_response import ApiResponse
26
+ from weheat.api_client import ApiClient
27
+ from weheat.configuration import Configuration
28
+ from weheat.exceptions import OpenApiException
29
+ from weheat.exceptions import ApiTypeError
30
+ from weheat.exceptions import ApiValueError
31
+ from weheat.exceptions import ApiKeyError
32
+ from weheat.exceptions import ApiAttributeError
33
+ from weheat.exceptions import ApiException
34
+
35
+ # import models into sdk package
36
+ from weheat.models.device_state import DeviceState
37
+ from weheat.models.energy_view_dto import EnergyViewDto
38
+ from weheat.models.heat_pump_log_view_dto import HeatPumpLogViewDto
39
+ from weheat.models.raw_heat_pump_log_dto import RawHeatPumpLogDto
40
+ from weheat.models.read_all_heat_pump_dto import ReadAllHeatPumpDto
41
+ from weheat.models.read_heat_pump_dto import ReadHeatPumpDto
42
+
@@ -0,0 +1,3 @@
1
+ from weheat.abstractions.auth import AbstractAuth
2
+ from weheat.abstractions.discovery import HeatPumpDiscovery
3
+ from weheat.abstractions.heat_pump import HeatPump
@@ -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,47 @@
1
+ from dataclasses import dataclass
2
+
3
+ from weheat.configuration import Configuration
4
+ from weheat.api_client import ApiClient
5
+ from weheat.api.heat_pump_api import HeatPumpApi
6
+
7
+
8
+ class HeatPumpDiscovery:
9
+ @dataclass
10
+ class HeatPumpInfo:
11
+ uuid: str
12
+ name: str
13
+ model: str
14
+ sn : str
15
+ has_dhw: bool = False
16
+
17
+ @staticmethod
18
+ def discover(api_url: str, access_token: str) -> list[HeatPumpInfo]:
19
+ discovered_pumps = []
20
+
21
+ config = Configuration(host=api_url, access_token=access_token)
22
+
23
+ with ApiClient(configuration=config) as client:
24
+ # try:
25
+ response = HeatPumpApi(client).api_v1_heat_pumps_get_with_http_info()
26
+ if response.status_code == 200:
27
+ for pump in response.data:
28
+ model_string = "BlackBird P80 heat pump"
29
+ if pump.model == 1:
30
+ model_string = "BlackBird P60 heat pump"
31
+ elif pump.model == 2:
32
+ model_string = "Sparrow P60 heat pump"
33
+
34
+ dhw = False
35
+ if pump.dhw_type is not None and pump.dhw_type == 1:
36
+ dhw = True
37
+
38
+ discovered_pumps.append(
39
+ HeatPumpDiscovery.HeatPumpInfo(
40
+ uuid=pump.id,
41
+ name=pump.name,
42
+ model=model_string,
43
+ sn=pump.serial_number,
44
+ has_dhw=dhw,
45
+ )
46
+ )
47
+ return discovered_pumps
@@ -0,0 +1,150 @@
1
+ from enum import Enum, auto
2
+ from weheat.configuration import Configuration
3
+ from weheat.api_client import ApiClient
4
+ from weheat.api.heat_pump_log_api import HeatPumpLogApi
5
+
6
+
7
+ class HeatPump:
8
+ class State(Enum):
9
+ UNDEFINED = auto()
10
+ STANDBY = auto()
11
+ WATER_CHECK = auto()
12
+ HEATING = auto()
13
+ COOLING = auto()
14
+ DHW = auto()
15
+ LEGIONELLA_PREVENTION = auto()
16
+ DEFROSTING = auto()
17
+ SELF_TEST = auto()
18
+ MANUAL_CONTROL = auto()
19
+
20
+ def __init__(self, api_url: str, uuid: str) -> None:
21
+ self._api_url = api_url
22
+ self._uuid = uuid
23
+ self._last_log = None
24
+
25
+ def get_status(self, access_token: str):
26
+ try:
27
+ config = Configuration(host=self._api_url, access_token=access_token)
28
+
29
+ with ApiClient(configuration=config) as client:
30
+ response = HeatPumpLogApi(
31
+ client
32
+ ).api_v1_heat_pumps_heat_pump_id_logs_latest_get_with_http_info(
33
+ heat_pump_id=self._uuid
34
+ )
35
+ if response.status_code == 200:
36
+ self._last_log = response.data
37
+ except Exception as e:
38
+ self._last_log = None
39
+ raise e
40
+
41
+ def _update_properties(self):
42
+ pass
43
+
44
+ def _if_available(self, key):
45
+ if self._last_log is not None and hasattr(self._last_log, key):
46
+ return getattr(self._last_log, key)
47
+ return None
48
+
49
+ def __str__(self):
50
+ return f"WeheatHeatPump(uuid={self._uuid}, last update={self._if_available('timestamp')})"
51
+
52
+ def __repr__(self):
53
+ return self.__str__()
54
+
55
+ @property
56
+ def water_inlet_temperature(self):
57
+ return self._if_available("t_water_in")
58
+
59
+ @property
60
+ def water_outlet_temperature(self):
61
+ return self._if_available("t_water_out")
62
+
63
+ @property
64
+ def water_house_in_temperature(self):
65
+ return self._if_available("t_water_house_in")
66
+
67
+ @property
68
+ def air_inlet_temperature(self):
69
+ return self._if_available("t_air_in")
70
+
71
+ @property
72
+ def air_outlet_temperature(self):
73
+ return self._if_available("t_air_out")
74
+
75
+ @property
76
+ def thermostat_water_setpoint(self):
77
+ return self._if_available("t_thermostat_setpoint")
78
+
79
+ @property
80
+ def thermostat_room_temperature(self):
81
+ return self._if_available("t_room")
82
+
83
+ @property
84
+ def thermostat_room_temperature_setpoint(self):
85
+ return self._if_available("t_room_target")
86
+
87
+ @property
88
+ def thermostat_on_off_state(self):
89
+ return self._if_available("on_off_thermostat_state")
90
+
91
+ @property
92
+ def power_input(self):
93
+ return self._if_available("cm_mass_power_in")
94
+
95
+ @property
96
+ def power_output(self):
97
+ return self._if_available("cm_mass_power_out")
98
+
99
+ @property
100
+ def cop(self):
101
+ """
102
+ Returns the coefficient of performance of the heat pump.
103
+ Note that this is calculated from a singular log entry and might not be accurate when the
104
+ heat pump is changing its output power or switching states
105
+ """
106
+ input = self.power_input
107
+ output = self.power_output
108
+ if input is not None and output is not None and input != 0:
109
+ return output / input
110
+
111
+ @property
112
+ def inside_unit_water_pump_state(self):
113
+ return self._if_available("control_bridge_status_decoded_water_pump")
114
+
115
+ @property
116
+ def inside_unit_auxilary_pump_state(self):
117
+ return self._if_available("control_bridge_status_decoded_water_pump2")
118
+
119
+ @property
120
+ def inside_unit_dhw_valve_or_pump_state(self):
121
+ return self._if_available("control_bridge_status_decoded_dhw_valve")
122
+
123
+ @property
124
+ def inside_unit_gas_boiler_state(self):
125
+ return self._if_available("control_bridge_status_decoded_gas_boiler")
126
+
127
+ @property
128
+ def heat_pump_state(self) -> State:
129
+ numeric_state = self._if_available("state")
130
+ if numeric_state is None:
131
+ return self.State.UNDEFINED
132
+
133
+ if numeric_state == 40:
134
+ return self.State.STANDBY
135
+ elif numeric_state == 70:
136
+ return self.State.HEATING
137
+ elif numeric_state == 130:
138
+ return self.State.COOLING
139
+ elif numeric_state == 150:
140
+ return self.State.DHW
141
+ elif numeric_state == 160:
142
+ return self.State.LEGIONELLA_PREVENTION
143
+ elif numeric_state == 170:
144
+ return self.State.SELF_TEST
145
+ elif numeric_state == 180:
146
+ return self.State.MANUAL_CONTROL
147
+ elif numeric_state == 200:
148
+ return self.State.DEFROSTING
149
+ else:
150
+ return self.State.UNDEFINED
@@ -0,0 +1,6 @@
1
+ # flake8: noqa
2
+
3
+ # import apis into api package
4
+ from weheat.api.energy_log_api import EnergyLogApi
5
+ from weheat.api.heat_pump_api import HeatPumpApi
6
+ from weheat.api.heat_pump_log_api import HeatPumpLogApi