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

Potentially problematic release.


This version of weheat might be problematic. Click here for more details.

@@ -0,0 +1,121 @@
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
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from datetime import datetime
21
+ from typing import Optional
22
+ from pydantic import BaseModel, Field, StrictStr, constr
23
+ from weheat.models.boiler_type import BoilerType
24
+ from weheat.models.device_state import DeviceState
25
+ from weheat.models.dhw_type import DhwType
26
+ from weheat.models.heat_pump_model import HeatPumpModel
27
+ from weheat.models.heat_pump_status_enum import HeatPumpStatusEnum
28
+ from weheat.models.heat_pump_type import HeatPumpType
29
+
30
+ class ReadAllHeatPumpDto(BaseModel):
31
+ """
32
+ Heat Pump dto used for the GetAll operation where the firmware version is needed # noqa: E501
33
+ """
34
+ id: StrictStr = Field(..., description="Identifier of the heat pump")
35
+ control_board_id: StrictStr = Field(..., alias="controlBoardId", description="Identifier of the control board that is connected to the heat pump")
36
+ serial_number: constr(strict=True, min_length=1) = Field(..., alias="serialNumber", description="Serial Number of this heat pump")
37
+ part_number: Optional[StrictStr] = Field(None, alias="partNumber", description="Part Number of this heat pump")
38
+ state: DeviceState = Field(...)
39
+ name: Optional[StrictStr] = Field(None, description="Internal nickname of this heat pump")
40
+ model: Optional[HeatPumpModel] = None
41
+ dhw_type: Optional[DhwType] = Field(None, alias="dhwType")
42
+ boiler_type: Optional[BoilerType] = Field(None, alias="boilerType")
43
+ status: Optional[HeatPumpStatusEnum] = None
44
+ type: Optional[HeatPumpType] = None
45
+ commissioned_at: Optional[datetime] = Field(None, alias="commissionedAt", description="Date when the heat pump was last commissioned (decommissioning sets this to null)")
46
+ firmware_version: Optional[StrictStr] = Field(None, alias="firmwareVersion", description="Firmware version of control board connected to heat pump")
47
+ __properties = ["id", "controlBoardId", "serialNumber", "partNumber", "state", "name", "model", "dhwType", "boilerType", "status", "type", "commissionedAt", "firmwareVersion"]
48
+
49
+ class Config:
50
+ """Pydantic configuration"""
51
+ allow_population_by_field_name = True
52
+ validate_assignment = True
53
+
54
+ def to_str(self) -> str:
55
+ """Returns the string representation of the model using alias"""
56
+ return pprint.pformat(self.dict(by_alias=True))
57
+
58
+ def to_json(self) -> str:
59
+ """Returns the JSON representation of the model using alias"""
60
+ return json.dumps(self.to_dict())
61
+
62
+ @classmethod
63
+ def from_json(cls, json_str: str) -> ReadAllHeatPumpDto:
64
+ """Create an instance of ReadAllHeatPumpDto from a JSON string"""
65
+ return cls.from_dict(json.loads(json_str))
66
+
67
+ def to_dict(self):
68
+ """Returns the dictionary representation of the model using alias"""
69
+ _dict = self.dict(by_alias=True,
70
+ exclude={
71
+ },
72
+ exclude_none=True)
73
+ # set to None if part_number (nullable) is None
74
+ # and __fields_set__ contains the field
75
+ if self.part_number is None and "part_number" in self.__fields_set__:
76
+ _dict['partNumber'] = None
77
+
78
+ # set to None if name (nullable) is None
79
+ # and __fields_set__ contains the field
80
+ if self.name is None and "name" in self.__fields_set__:
81
+ _dict['name'] = None
82
+
83
+ # set to None if commissioned_at (nullable) is None
84
+ # and __fields_set__ contains the field
85
+ if self.commissioned_at is None and "commissioned_at" in self.__fields_set__:
86
+ _dict['commissionedAt'] = None
87
+
88
+ # set to None if firmware_version (nullable) is None
89
+ # and __fields_set__ contains the field
90
+ if self.firmware_version is None and "firmware_version" in self.__fields_set__:
91
+ _dict['firmwareVersion'] = None
92
+
93
+ return _dict
94
+
95
+ @classmethod
96
+ def from_dict(cls, obj: dict) -> ReadAllHeatPumpDto:
97
+ """Create an instance of ReadAllHeatPumpDto from a dict"""
98
+ if obj is None:
99
+ return None
100
+
101
+ if not isinstance(obj, dict):
102
+ return ReadAllHeatPumpDto.parse_obj(obj)
103
+
104
+ _obj = ReadAllHeatPumpDto.parse_obj({
105
+ "id": obj.get("id"),
106
+ "control_board_id": obj.get("controlBoardId"),
107
+ "serial_number": obj.get("serialNumber"),
108
+ "part_number": obj.get("partNumber"),
109
+ "state": obj.get("state"),
110
+ "name": obj.get("name"),
111
+ "model": obj.get("model"),
112
+ "dhw_type": obj.get("dhwType"),
113
+ "boiler_type": obj.get("boilerType"),
114
+ "status": obj.get("status"),
115
+ "type": obj.get("type"),
116
+ "commissioned_at": obj.get("commissionedAt"),
117
+ "firmware_version": obj.get("firmwareVersion")
118
+ })
119
+ return _obj
120
+
121
+
@@ -0,0 +1,114 @@
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
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from datetime import datetime
21
+ from typing import Optional
22
+ from pydantic import BaseModel, Field, StrictStr, constr
23
+ from weheat.models.boiler_type import BoilerType
24
+ from weheat.models.device_state import DeviceState
25
+ from weheat.models.dhw_type import DhwType
26
+ from weheat.models.heat_pump_model import HeatPumpModel
27
+ from weheat.models.heat_pump_status_enum import HeatPumpStatusEnum
28
+ from weheat.models.heat_pump_type import HeatPumpType
29
+
30
+ class ReadHeatPumpDto(BaseModel):
31
+ """
32
+ ReadHeatPumpDto
33
+ """
34
+ id: StrictStr = Field(..., description="Identifier of the heat pump")
35
+ control_board_id: StrictStr = Field(..., alias="controlBoardId", description="Identifier of the control board that is connected to the heat pump")
36
+ serial_number: constr(strict=True, min_length=1) = Field(..., alias="serialNumber", description="Serial Number of this heat pump")
37
+ part_number: Optional[StrictStr] = Field(None, alias="partNumber", description="Part Number of this heat pump")
38
+ state: DeviceState = Field(...)
39
+ name: Optional[StrictStr] = Field(None, description="Internal nickname of this heat pump")
40
+ model: Optional[HeatPumpModel] = None
41
+ dhw_type: Optional[DhwType] = Field(None, alias="dhwType")
42
+ boiler_type: Optional[BoilerType] = Field(None, alias="boilerType")
43
+ status: Optional[HeatPumpStatusEnum] = None
44
+ type: Optional[HeatPumpType] = None
45
+ commissioned_at: Optional[datetime] = Field(None, alias="commissionedAt", description="Date when the heat pump was last commissioned (decommissioning sets this to null)")
46
+ __properties = ["id", "controlBoardId", "serialNumber", "partNumber", "state", "name", "model", "dhwType", "boilerType", "status", "type", "commissionedAt"]
47
+
48
+ class Config:
49
+ """Pydantic configuration"""
50
+ allow_population_by_field_name = True
51
+ validate_assignment = True
52
+
53
+ def to_str(self) -> str:
54
+ """Returns the string representation of the model using alias"""
55
+ return pprint.pformat(self.dict(by_alias=True))
56
+
57
+ def to_json(self) -> str:
58
+ """Returns the JSON representation of the model using alias"""
59
+ return json.dumps(self.to_dict())
60
+
61
+ @classmethod
62
+ def from_json(cls, json_str: str) -> ReadHeatPumpDto:
63
+ """Create an instance of ReadHeatPumpDto from a JSON string"""
64
+ return cls.from_dict(json.loads(json_str))
65
+
66
+ def to_dict(self):
67
+ """Returns the dictionary representation of the model using alias"""
68
+ _dict = self.dict(by_alias=True,
69
+ exclude={
70
+ },
71
+ exclude_none=True)
72
+ # set to None if part_number (nullable) is None
73
+ # and __fields_set__ contains the field
74
+ if self.part_number is None and "part_number" in self.__fields_set__:
75
+ _dict['partNumber'] = None
76
+
77
+ # set to None if name (nullable) is None
78
+ # and __fields_set__ contains the field
79
+ if self.name is None and "name" in self.__fields_set__:
80
+ _dict['name'] = None
81
+
82
+ # set to None if commissioned_at (nullable) is None
83
+ # and __fields_set__ contains the field
84
+ if self.commissioned_at is None and "commissioned_at" in self.__fields_set__:
85
+ _dict['commissionedAt'] = None
86
+
87
+ return _dict
88
+
89
+ @classmethod
90
+ def from_dict(cls, obj: dict) -> ReadHeatPumpDto:
91
+ """Create an instance of ReadHeatPumpDto from a dict"""
92
+ if obj is None:
93
+ return None
94
+
95
+ if not isinstance(obj, dict):
96
+ return ReadHeatPumpDto.parse_obj(obj)
97
+
98
+ _obj = ReadHeatPumpDto.parse_obj({
99
+ "id": obj.get("id"),
100
+ "control_board_id": obj.get("controlBoardId"),
101
+ "serial_number": obj.get("serialNumber"),
102
+ "part_number": obj.get("partNumber"),
103
+ "state": obj.get("state"),
104
+ "name": obj.get("name"),
105
+ "model": obj.get("model"),
106
+ "dhw_type": obj.get("dhwType"),
107
+ "boiler_type": obj.get("boilerType"),
108
+ "status": obj.get("status"),
109
+ "type": obj.get("type"),
110
+ "commissioned_at": obj.get("commissionedAt")
111
+ })
112
+ return _obj
113
+
114
+
weheat/py.typed ADDED
File without changes
weheat/rest.py ADDED
@@ -0,0 +1,327 @@
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
+
14
+
15
+ import io
16
+ import json
17
+ import logging
18
+ import re
19
+ import ssl
20
+
21
+ from urllib.parse import urlencode, quote_plus
22
+ import urllib3
23
+
24
+ from weheat.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError, BadRequestException
25
+
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
30
+
31
+
32
+ def is_socks_proxy_url(url):
33
+ if url is None:
34
+ return False
35
+ split_section = url.split("://")
36
+ if len(split_section) < 2:
37
+ return False
38
+ else:
39
+ return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES
40
+
41
+
42
+ class RESTResponse(io.IOBase):
43
+
44
+ def __init__(self, resp) -> None:
45
+ self.urllib3_response = resp
46
+ self.status = resp.status
47
+ self.reason = resp.reason
48
+ self.data = resp.data
49
+
50
+ def getheaders(self):
51
+ """Returns a dictionary of the response headers."""
52
+ return self.urllib3_response.headers
53
+
54
+ def getheader(self, name, default=None):
55
+ """Returns a given response header."""
56
+ return self.urllib3_response.headers.get(name, default)
57
+
58
+
59
+ class RESTClientObject:
60
+
61
+ def __init__(self, configuration, pools_size=4, maxsize=None) -> None:
62
+ # urllib3.PoolManager will pass all kw parameters to connectionpool
63
+ # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
64
+ # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
65
+ # maxsize is the number of requests to host that are allowed in parallel # noqa: E501
66
+ # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
67
+
68
+ # cert_reqs
69
+ if configuration.verify_ssl:
70
+ cert_reqs = ssl.CERT_REQUIRED
71
+ else:
72
+ cert_reqs = ssl.CERT_NONE
73
+
74
+ addition_pool_args = {}
75
+ if configuration.assert_hostname is not None:
76
+ addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
77
+
78
+ if configuration.retries is not None:
79
+ addition_pool_args['retries'] = configuration.retries
80
+
81
+ if configuration.tls_server_name:
82
+ addition_pool_args['server_hostname'] = configuration.tls_server_name
83
+
84
+
85
+ if configuration.socket_options is not None:
86
+ addition_pool_args['socket_options'] = configuration.socket_options
87
+
88
+ if maxsize is None:
89
+ if configuration.connection_pool_maxsize is not None:
90
+ maxsize = configuration.connection_pool_maxsize
91
+ else:
92
+ maxsize = 4
93
+
94
+ # https pool manager
95
+ if configuration.proxy:
96
+ if is_socks_proxy_url(configuration.proxy):
97
+ from urllib3.contrib.socks import SOCKSProxyManager
98
+ self.pool_manager = SOCKSProxyManager(
99
+ cert_reqs=cert_reqs,
100
+ ca_certs=configuration.ssl_ca_cert,
101
+ cert_file=configuration.cert_file,
102
+ key_file=configuration.key_file,
103
+ proxy_url=configuration.proxy,
104
+ headers=configuration.proxy_headers,
105
+ **addition_pool_args
106
+ )
107
+ else:
108
+ self.pool_manager = urllib3.ProxyManager(
109
+ num_pools=pools_size,
110
+ maxsize=maxsize,
111
+ cert_reqs=cert_reqs,
112
+ ca_certs=configuration.ssl_ca_cert,
113
+ cert_file=configuration.cert_file,
114
+ key_file=configuration.key_file,
115
+ proxy_url=configuration.proxy,
116
+ proxy_headers=configuration.proxy_headers,
117
+ **addition_pool_args
118
+ )
119
+ else:
120
+ self.pool_manager = urllib3.PoolManager(
121
+ num_pools=pools_size,
122
+ maxsize=maxsize,
123
+ cert_reqs=cert_reqs,
124
+ ca_certs=configuration.ssl_ca_cert,
125
+ cert_file=configuration.cert_file,
126
+ key_file=configuration.key_file,
127
+ **addition_pool_args
128
+ )
129
+
130
+ def request(self, method, url, query_params=None, headers=None,
131
+ body=None, post_params=None, _preload_content=True,
132
+ _request_timeout=None):
133
+ """Perform requests.
134
+
135
+ :param method: http request method
136
+ :param url: http request url
137
+ :param query_params: query parameters in the url
138
+ :param headers: http request headers
139
+ :param body: request json body, for `application/json`
140
+ :param post_params: request post parameters,
141
+ `application/x-www-form-urlencoded`
142
+ and `multipart/form-data`
143
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
144
+ be returned without reading/decoding response
145
+ data. Default is True.
146
+ :param _request_timeout: timeout setting for this request. If one
147
+ number provided, it will be total request
148
+ timeout. It can also be a pair (tuple) of
149
+ (connection, read) timeouts.
150
+ """
151
+ method = method.upper()
152
+ assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
153
+ 'PATCH', 'OPTIONS']
154
+
155
+ if post_params and body:
156
+ raise ApiValueError(
157
+ "body parameter cannot be used with post_params parameter."
158
+ )
159
+
160
+ post_params = post_params or {}
161
+ headers = headers or {}
162
+ # url already contains the URL query string
163
+ # so reset query_params to empty dict
164
+ query_params = {}
165
+
166
+ timeout = None
167
+ if _request_timeout:
168
+ if isinstance(_request_timeout, (int,float)): # noqa: E501,F821
169
+ timeout = urllib3.Timeout(total=_request_timeout)
170
+ elif (isinstance(_request_timeout, tuple) and
171
+ len(_request_timeout) == 2):
172
+ timeout = urllib3.Timeout(
173
+ connect=_request_timeout[0], read=_request_timeout[1])
174
+
175
+ try:
176
+ # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
177
+ if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
178
+
179
+ # no content type provided or payload is json
180
+ if not headers.get('Content-Type') or re.search('json', headers['Content-Type'], re.IGNORECASE):
181
+ request_body = None
182
+ if body is not None:
183
+ request_body = json.dumps(body)
184
+ r = self.pool_manager.request(
185
+ method, url,
186
+ body=request_body,
187
+ preload_content=_preload_content,
188
+ timeout=timeout,
189
+ headers=headers)
190
+ elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
191
+ r = self.pool_manager.request(
192
+ method, url,
193
+ fields=post_params,
194
+ encode_multipart=False,
195
+ preload_content=_preload_content,
196
+ timeout=timeout,
197
+ headers=headers)
198
+ elif headers['Content-Type'] == 'multipart/form-data':
199
+ # must del headers['Content-Type'], or the correct
200
+ # Content-Type which generated by urllib3 will be
201
+ # overwritten.
202
+ del headers['Content-Type']
203
+ r = self.pool_manager.request(
204
+ method, url,
205
+ fields=post_params,
206
+ encode_multipart=True,
207
+ preload_content=_preload_content,
208
+ timeout=timeout,
209
+ headers=headers)
210
+ # Pass a `string` parameter directly in the body to support
211
+ # other content types than Json when `body` argument is
212
+ # provided in serialized form
213
+ elif isinstance(body, str) or isinstance(body, bytes):
214
+ request_body = body
215
+ r = self.pool_manager.request(
216
+ method, url,
217
+ body=request_body,
218
+ preload_content=_preload_content,
219
+ timeout=timeout,
220
+ headers=headers)
221
+ else:
222
+ # Cannot generate the request from given parameters
223
+ msg = """Cannot prepare a request message for provided
224
+ arguments. Please check that your arguments match
225
+ declared content type."""
226
+ raise ApiException(status=0, reason=msg)
227
+ # For `GET`, `HEAD`
228
+ else:
229
+ r = self.pool_manager.request(method, url,
230
+ fields={},
231
+ preload_content=_preload_content,
232
+ timeout=timeout,
233
+ headers=headers)
234
+ except urllib3.exceptions.SSLError as e:
235
+ msg = "{0}\n{1}".format(type(e).__name__, str(e))
236
+ raise ApiException(status=0, reason=msg)
237
+
238
+ if _preload_content:
239
+ r = RESTResponse(r)
240
+
241
+ # log response body
242
+ logger.debug("response body: %s", r.data)
243
+
244
+ if not 200 <= r.status <= 299:
245
+ if r.status == 400:
246
+ raise BadRequestException(http_resp=r)
247
+
248
+ if r.status == 401:
249
+ raise UnauthorizedException(http_resp=r)
250
+
251
+ if r.status == 403:
252
+ raise ForbiddenException(http_resp=r)
253
+
254
+ if r.status == 404:
255
+ raise NotFoundException(http_resp=r)
256
+
257
+ if 500 <= r.status <= 599:
258
+ raise ServiceException(http_resp=r)
259
+
260
+ raise ApiException(http_resp=r)
261
+
262
+ return r
263
+
264
+ def get_request(self, url, headers=None, query_params=None, _preload_content=True,
265
+ _request_timeout=None):
266
+ return self.request("GET", url,
267
+ headers=headers,
268
+ _preload_content=_preload_content,
269
+ _request_timeout=_request_timeout,
270
+ query_params=query_params)
271
+
272
+ def head_request(self, url, headers=None, query_params=None, _preload_content=True,
273
+ _request_timeout=None):
274
+ return self.request("HEAD", url,
275
+ headers=headers,
276
+ _preload_content=_preload_content,
277
+ _request_timeout=_request_timeout,
278
+ query_params=query_params)
279
+
280
+ def options_request(self, url, headers=None, query_params=None, post_params=None,
281
+ body=None, _preload_content=True, _request_timeout=None):
282
+ return self.request("OPTIONS", url,
283
+ headers=headers,
284
+ query_params=query_params,
285
+ post_params=post_params,
286
+ _preload_content=_preload_content,
287
+ _request_timeout=_request_timeout,
288
+ body=body)
289
+
290
+ def delete_request(self, url, headers=None, query_params=None, body=None,
291
+ _preload_content=True, _request_timeout=None):
292
+ return self.request("DELETE", url,
293
+ headers=headers,
294
+ query_params=query_params,
295
+ _preload_content=_preload_content,
296
+ _request_timeout=_request_timeout,
297
+ body=body)
298
+
299
+ def post_request(self, url, headers=None, query_params=None, post_params=None,
300
+ body=None, _preload_content=True, _request_timeout=None):
301
+ return self.request("POST", url,
302
+ headers=headers,
303
+ query_params=query_params,
304
+ post_params=post_params,
305
+ _preload_content=_preload_content,
306
+ _request_timeout=_request_timeout,
307
+ body=body)
308
+
309
+ def put_request(self, url, headers=None, query_params=None, post_params=None,
310
+ body=None, _preload_content=True, _request_timeout=None):
311
+ return self.request("PUT", url,
312
+ headers=headers,
313
+ query_params=query_params,
314
+ post_params=post_params,
315
+ _preload_content=_preload_content,
316
+ _request_timeout=_request_timeout,
317
+ body=body)
318
+
319
+ def patch_request(self, url, headers=None, query_params=None, post_params=None,
320
+ body=None, _preload_content=True, _request_timeout=None):
321
+ return self.request("PATCH", url,
322
+ headers=headers,
323
+ query_params=query_params,
324
+ post_params=post_params,
325
+ _preload_content=_preload_content,
326
+ _request_timeout=_request_timeout,
327
+ body=body)
@@ -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
+