pymiele 0.3.1__py3-none-any.whl → 0.3.2__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.
pymiele/const.py CHANGED
@@ -1,7 +1,9 @@
1
1
  """Constants for pymiele."""
2
2
 
3
- VERSION = "0.3.1"
3
+ VERSION = "0.3.2"
4
4
 
5
5
  MIELE_API = "https://api.mcs3.miele.com/v1"
6
6
  OAUTH2_AUTHORIZE = "https://api.mcs3.miele.com/thirdparty/login"
7
7
  OAUTH2_TOKEN = "https://api.mcs3.miele.com/thirdparty/token"
8
+
9
+ AIO_TIMEOUT = 15
pymiele/model.py CHANGED
@@ -1,5 +1,4 @@
1
1
  """Data models for Miele API."""
2
- # Todo: Move to pymiele when complete and stable
3
2
 
4
3
  from __future__ import annotations
5
4
 
@@ -18,6 +17,52 @@ class MieleDevices:
18
17
  return list(self.raw_data.keys())
19
18
 
20
19
 
20
+ class MieleTemperature:
21
+ """A model of temperature data."""
22
+
23
+ def __init__(self, raw_data: dict) -> None:
24
+ """Initialize MieleTemperature."""
25
+ self.raw_data = raw_data
26
+
27
+ @property
28
+ def raw(self) -> dict:
29
+ """Return raw data."""
30
+ return self.raw_data
31
+
32
+ @property
33
+ def temperature(self) -> int | None:
34
+ """Return temperature object."""
35
+ return self.raw_data["value_raw"]
36
+
37
+
38
+ class MieleActionTargetTemperature:
39
+ """A model of target temperature data."""
40
+
41
+ def __init__(self, raw_data: dict) -> None:
42
+ """Initialize MieleActionTargetTemperature."""
43
+ self.raw_data = raw_data
44
+
45
+ @property
46
+ def raw(self) -> dict:
47
+ """Return raw data."""
48
+ return self.raw_data
49
+
50
+ @property
51
+ def zone(self) -> int | None:
52
+ """Return zone value."""
53
+ return self.raw_data["zone"]
54
+
55
+ @property
56
+ def min(self) -> int | None:
57
+ """Return min value."""
58
+ return self.raw_data["min"]
59
+
60
+ @property
61
+ def max(self) -> int | None:
62
+ """Return max value."""
63
+ return self.raw_data["max"]
64
+
65
+
21
66
  class MieleDevice:
22
67
  """Data for a single device from API."""
23
68
 
@@ -96,49 +141,35 @@ class MieleDevice:
96
141
  return self.raw_data["state"]["startTime"]
97
142
 
98
143
  @property
99
- def state_target_temperature(self) -> list[dict]:
144
+ def state_target_temperature(self) -> list[MieleTemperature]:
100
145
  """Return the target temperature of the device."""
101
- return self.raw_data["state"]["targetTemperature"]
146
+ return [
147
+ MieleTemperature(temp)
148
+ for temp in self.raw_data["state"]["targetTemperature"]
149
+ ]
102
150
 
103
151
  @property
104
152
  def state_core_target_temperature(self) -> list[dict]:
105
153
  """Return the core target temperature of the device."""
106
- return self.raw_data["state"]["coreTargetTemperature"]
107
-
108
- @property
109
- def state_temperature(self) -> list[int]:
110
- """Return the temperature of the device."""
111
- return [temp["value_raw"] for temp in self.raw_data["state"]["temperature"]]
112
-
113
- @property
114
- def state_temperature_1(self) -> int:
115
- """Return the temperature in zone 1 of the device."""
116
- return self.raw_data["state"]["temperature"][0]["value_raw"]
154
+ return [
155
+ MieleTemperature(temp)
156
+ for temp in self.raw_data["state"]["coretargetTemperature"]
157
+ ]
117
158
 
118
159
  @property
119
- def state_temperature_2(self) -> int:
120
- """Return the temperature in zone 2 of the device."""
121
- return self.raw_data["state"]["temperature"][1]["value_raw"]
160
+ def state_temperatures(self) -> list[MieleTemperature]:
161
+ """Return list of all temperatures."""
122
162
 
123
- @property
124
- def state_temperature_3(self) -> int:
125
- """Return the temperature in zone 3 of the device."""
126
- return self.raw_data["state"]["temperature"][2]["value_raw"]
163
+ return [
164
+ MieleTemperature(temp) for temp in self.raw_data["state"]["temperature"]
165
+ ]
127
166
 
128
167
  @property
129
- def state_core_temperature(self) -> list[dict]:
168
+ def state_core_temperature(self) -> list[MieleTemperature]:
130
169
  """Return the core temperature of the device."""
131
- return self.raw_data["state"]["coreTemperature"]
132
-
133
- @property
134
- def state_core_temperature_1(self) -> list[dict]:
135
- """Return the core temperature in zone 1 of the device."""
136
- return self.raw_data["state"]["coreTemperature"][0]["value_raw"]
137
-
138
- @property
139
- def state_core_temperature_2(self) -> list[dict]:
140
- """Return the core temperature in zone 2 of the device."""
141
- return self.raw_data["state"]["coreTemperature"][1]["value_raw"]
170
+ return [
171
+ MieleTemperature(temp) for temp in self.raw_data["state"]["coreTemperature"]
172
+ ]
142
173
 
143
174
  @property
144
175
  def state_signal_info(self) -> bool:
@@ -171,15 +202,25 @@ class MieleDevice:
171
202
  return self.raw_data["state"]["remoteEnable"]["mobileStart"]
172
203
 
173
204
  @property
174
- def state_ambient_light(self) -> bool:
205
+ def state_ambient_light(self) -> int:
175
206
  """Return the ambient light of the device."""
176
207
  return self.raw_data["state"]["ambientLight"]
177
208
 
209
+ @state_ambient_light.setter
210
+ def state_ambient_light(self, new_value: bool) -> None:
211
+ """Set the ambient light state."""
212
+ self.raw_data["state"]["ambientLight"] = new_value
213
+
178
214
  @property
179
- def state_light(self) -> bool:
215
+ def state_light(self) -> int:
180
216
  """Return the light of the device."""
181
217
  return self.raw_data["state"]["light"]
182
218
 
219
+ @state_light.setter
220
+ def state_light(self, new_value: int) -> None:
221
+ """Set the light state."""
222
+ self.raw_data["state"]["light"] = new_value
223
+
183
224
  @property
184
225
  def state_elapsed_time(self) -> list[int]:
185
226
  """Return the elapsed time of the device."""
@@ -188,17 +229,27 @@ class MieleDevice:
188
229
  @property
189
230
  def state_spinning_speed(self) -> int | None:
190
231
  """Return the spinning speed of the device."""
191
- return self.raw_data["state"]["spinningSpeed"]
232
+ return self.raw_data["state"]["spinningSpeed"]["value_raw"]
192
233
 
193
234
  @property
194
235
  def state_drying_step(self) -> int | None:
195
236
  """Return the drying step of the device."""
196
- return self.raw_data["state"]["dryingStep"]
237
+ return self.raw_data["state"]["dryingStep"]["value_raw"]
238
+
239
+ @state_drying_step.setter
240
+ def state_drying_step(self, new_value: int) -> None:
241
+ """Set the drying state."""
242
+ self.raw_data["state"]["dryingStep"]["value_raw"] = new_value
197
243
 
198
244
  @property
199
245
  def state_ventilation_step(self) -> int | None:
200
246
  """Return the ventilation step of the device."""
201
- return self.raw_data["state"]["ventilationStep"]
247
+ return self.raw_data["state"]["ventilationStep"]["value_raw"]
248
+
249
+ @state_ventilation_step.setter
250
+ def state_ventilation_step(self, new_value: int) -> None:
251
+ """Set the ventilation state."""
252
+ self.raw_data["state"]["ventilationStep"]["value_raw"] = new_value
202
253
 
203
254
  @property
204
255
  def state_plate_step(self) -> list[dict]:
@@ -210,6 +261,38 @@ class MieleDevice:
210
261
  """Return the eco feedback of the device."""
211
262
  return self.raw_data["state"]["ecoFeedback"]
212
263
 
264
+ @property
265
+ def current_water_consumption(self) -> float | None:
266
+ """Return the current water consumption of the device."""
267
+ if self.state_eco_feedback is None:
268
+ return None
269
+ return self.raw_data["state"]["ecoFeedback"].get("currentWaterConsumption")[
270
+ "value"
271
+ ]
272
+
273
+ @property
274
+ def current_energy_consumption(self) -> float | None:
275
+ """Return the current energy consumption of the device."""
276
+ if self.state_eco_feedback is None:
277
+ return None
278
+ return self.raw_data["state"]["ecoFeedback"]["currentEnergyConsumption"][
279
+ "value"
280
+ ]
281
+
282
+ @property
283
+ def water_forecast(self) -> float | None:
284
+ """Return the water forecast of the device."""
285
+ if self.state_eco_feedback is None:
286
+ return None
287
+ return self.raw_data["state"]["ecoFeedback"].get("waterForecast")
288
+
289
+ @property
290
+ def energy_forecast(self) -> float | None:
291
+ """Return the energy forecast of the device."""
292
+ if self.state_eco_feedback is None:
293
+ return None
294
+ return self.raw_data["state"]["ecoFeedback"].get("energyForecast")
295
+
213
296
  @property
214
297
  def state_battery_level(self) -> int | None:
215
298
  """Return the battery level of the device."""
@@ -223,7 +306,6 @@ class MieleAction:
223
306
  """Initialize MieleAction."""
224
307
  self.raw_data = raw_data
225
308
 
226
- # Todo : Add process actions
227
309
  @property
228
310
  def raw(self) -> dict:
229
311
  """Return raw data."""
@@ -277,19 +359,113 @@ class MieleAction:
277
359
  @property
278
360
  def target_temperature(self) -> list[dict]:
279
361
  """Return list of target temperature actions."""
280
- return list(self.raw_data["targetTemperature"])
362
+ return [
363
+ MieleActionTargetTemperature(temp)
364
+ for temp in self.raw_data["state"]["targetTemperature"]
365
+ ]
281
366
 
282
367
  @property
283
368
  def power_on_enabled(self) -> bool:
284
369
  """Return powerOn enabled."""
285
370
  return self.raw_data["powerOn"]
286
371
 
372
+ @power_on_enabled.setter
373
+ def power_on_enabled(self, value: bool) -> None:
374
+ """Return powerOn enabled."""
375
+ self.raw_data["powerOn"] = value
376
+
287
377
  @property
288
378
  def power_off_enabled(self) -> bool:
289
379
  """Return powerOff enabled."""
290
380
  return self.raw_data["powerOff"]
291
381
 
382
+ @power_off_enabled.setter
383
+ def power_off_enabled(self, value: bool) -> None:
384
+ """Return powerOff enabled."""
385
+ self.raw_data["powerOff"] = value
386
+
292
387
  @property
293
388
  def device_name_enabled(self) -> bool:
294
389
  """Return deviceName enabled."""
295
390
  return self.raw_data["deviceName"]
391
+
392
+
393
+ class MieleProgramsAvailable:
394
+ """Model for available programs."""
395
+
396
+ def __init__(self, raw_data: dict) -> None:
397
+ """Initialize MieleProgramsAvailable."""
398
+ self.raw_data = raw_data
399
+
400
+ @property
401
+ def programs(self) -> list[MieleProgramAvailable]:
402
+ """Return list of all available programs."""
403
+ return [MieleProgramAvailable(program) for program in self.raw_data]
404
+
405
+
406
+ class MieleProgramAvailable:
407
+ """Model for available programs."""
408
+
409
+ def __init__(self, raw_data: dict) -> None:
410
+ """Initialize MieleProgramAvailable."""
411
+ self.raw_data = raw_data
412
+
413
+ @property
414
+ def raw(self) -> dict:
415
+ """Return raw data."""
416
+ return self.raw_data
417
+
418
+ @property
419
+ def program_id(self) -> int | None:
420
+ """Return the ID of the program."""
421
+ return self.raw_data["programId"]
422
+
423
+ @property
424
+ def program_name(self) -> str | None:
425
+ """Return the name of the program."""
426
+ return self.raw_data["program"]
427
+
428
+ @property
429
+ def parameters(self) -> dict | None:
430
+ """Return the parameters of the program."""
431
+ return self.raw_data["parameters"]
432
+
433
+ @property
434
+ def temperature(self) -> dict | None:
435
+ """Return the temperature parameter of the program."""
436
+ return self.raw_data["parameters"].get("temperature")
437
+
438
+ @property
439
+ def temperature_min(self) -> int | None:
440
+ """Return the min temperature parameter of the program."""
441
+ return self.raw_data["parameters"]["temperature"]["min"]
442
+
443
+ @property
444
+ def temperature_max(self) -> int | None:
445
+ """Return the max temperature parameter of the program."""
446
+ return self.raw_data["parameters"]["temperature"]["max"]
447
+
448
+ @property
449
+ def temperature_step(self) -> int | None:
450
+ """Return the step temperature parameter of the program."""
451
+ return self.raw_data["parameters"]["temperature"]["step"]
452
+
453
+ @property
454
+ def temperature_mandatory(self) -> bool | None:
455
+ """Return the mandatory temperature parameter of the program."""
456
+ return self.raw_data["parameters"]["temperature"]["mandatory"]
457
+
458
+ @property
459
+ def duration_min(self) -> list[int] | None:
460
+ """Return the mandatory min parameter of the program."""
461
+ return self.raw_data["parameters"]["duration"]["min"]
462
+
463
+ @property
464
+ def duration_max(self) -> list[int] | None:
465
+ """Return the duration max parameter of the program."""
466
+ return self.raw_data["parameters"]["duration"]["max"]
467
+
468
+ @property
469
+ def duration_mandatory(self) -> bool | None:
470
+ """Return the mandatory duration parameter of the program."""
471
+ return self.raw_data["parameters"]["duration"]["mandatory"]
pymiele/pymiele.py CHANGED
@@ -12,7 +12,7 @@ from typing import Any
12
12
 
13
13
  from aiohttp import ClientResponse, ClientResponseError, ClientSession, ClientTimeout
14
14
 
15
- from .const import MIELE_API, VERSION
15
+ from .const import AIO_TIMEOUT, MIELE_API, VERSION
16
16
 
17
17
  CONTENT_TYPE = "application/json"
18
18
  USER_AGENT_BASE = f"Pymiele/{VERSION}"
@@ -59,7 +59,7 @@ class AbstractAuth(ABC):
59
59
 
60
60
  async def get_devices(self) -> dict:
61
61
  """Get all devices."""
62
- async with asyncio.timeout(10):
62
+ async with asyncio.timeout(AIO_TIMEOUT):
63
63
  res = await self.request(
64
64
  "GET", "/devices", headers={"Accept": "application/json"}
65
65
  )
@@ -68,7 +68,7 @@ class AbstractAuth(ABC):
68
68
 
69
69
  async def get_actions(self, serial: str) -> dict:
70
70
  """Get actions for a device."""
71
- async with asyncio.timeout(10):
71
+ async with asyncio.timeout(AIO_TIMEOUT):
72
72
  res = await self.request(
73
73
  "GET",
74
74
  f"/devices/{serial}/actions",
@@ -79,7 +79,7 @@ class AbstractAuth(ABC):
79
79
 
80
80
  async def get_programs(self, serial: str) -> dict:
81
81
  """Get programs for a device."""
82
- async with asyncio.timeout(10):
82
+ async with asyncio.timeout(AIO_TIMEOUT):
83
83
  res = await self.request(
84
84
  "GET",
85
85
  f"/devices/{serial}/programs",
@@ -90,7 +90,7 @@ class AbstractAuth(ABC):
90
90
 
91
91
  async def get_rooms(self, serial: str) -> dict:
92
92
  """Get rooms for a device."""
93
- async with asyncio.timeout(10):
93
+ async with asyncio.timeout(AIO_TIMEOUT):
94
94
  res = await self.request(
95
95
  "GET",
96
96
  f"/devices/{serial}/rooms",
@@ -104,7 +104,7 @@ class AbstractAuth(ABC):
104
104
  ) -> ClientResponse:
105
105
  """Set target temperature."""
106
106
  temp = round(temperature)
107
- async with asyncio.timeout(10):
107
+ async with asyncio.timeout(AIO_TIMEOUT):
108
108
  data = {"targetTemperature": [{"zone": zone, "value": temp}]}
109
109
  res = await self.request(
110
110
  "PUT",
@@ -125,7 +125,7 @@ class AbstractAuth(ABC):
125
125
  """Send action command."""
126
126
 
127
127
  _LOGGER.debug("send_action serial: %s, data: %s", serial, data)
128
- async with asyncio.timeout(10):
128
+ async with asyncio.timeout(AIO_TIMEOUT):
129
129
  res = await self.request(
130
130
  "PUT",
131
131
  f"/devices/{serial}/actions",
@@ -145,7 +145,7 @@ class AbstractAuth(ABC):
145
145
  """Send start program command."""
146
146
 
147
147
  _LOGGER.debug("set_program serial: %s, data: %s", serial, data)
148
- async with asyncio.timeout(10):
148
+ async with asyncio.timeout(AIO_TIMEOUT):
149
149
  res = await self.request(
150
150
  "PUT",
151
151
  f"/devices/{serial}/programs",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymiele
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Python library for Miele integration with Home Assistant
5
5
  Author-email: Ake Strandberg <ake@strandberg.eu>
6
6
  License: MIT
@@ -0,0 +1,10 @@
1
+ pymiele/__init__.py,sha256=w_JvyaBHVGM7eo-FFwIWFbQUeAowoA_fbnAfCWJFGek,221
2
+ pymiele/const.py,sha256=tQ4KYDdMAlp4qWvwseOUfUpngPyRzsKlfVEtXG3H-ek,237
3
+ pymiele/model.py,sha256=0MNzVw6gG7o9EJlPjDp8isaNmuigRZtz-6ka-ij33-8,14816
4
+ pymiele/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ pymiele/pymiele.py,sha256=M5P_rW61XZV06aelw5i9-qzJ9exabMYgLcehzuKd7-Y,8723
6
+ pymiele-0.3.2.dist-info/licenses/LICENSE,sha256=scGm4_U2pd-rsGa6Edf6zsXFebrMT4RoyQz7-904_Wg,1072
7
+ pymiele-0.3.2.dist-info/METADATA,sha256=AWxGU1nbL90SZUx91_55a72lew-BqMlVIiODSF-lnL8,675
8
+ pymiele-0.3.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
9
+ pymiele-0.3.2.dist-info/top_level.txt,sha256=BwkHrSO2w_Bfxh6s8Ikcao5enEuQOpQhJ3SwUXBqY10,8
10
+ pymiele-0.3.2.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- pymiele/__init__.py,sha256=w_JvyaBHVGM7eo-FFwIWFbQUeAowoA_fbnAfCWJFGek,221
2
- pymiele/const.py,sha256=GNfH7v747oYiA1E-eQZeLVHJr70PPM5wkJqUhB6lGbw,219
3
- pymiele/model.py,sha256=PTMJ-9F_r3Hb4Zs96TFESSZ-r39cLCNIcSmFV5DrDjw,9442
4
- pymiele/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- pymiele/pymiele.py,sha256=3edghDZLPDg4KBV7AVTUGNeeyDPAAegyzRfBG9pFgeU,8647
6
- pymiele-0.3.1.dist-info/licenses/LICENSE,sha256=scGm4_U2pd-rsGa6Edf6zsXFebrMT4RoyQz7-904_Wg,1072
7
- pymiele-0.3.1.dist-info/METADATA,sha256=8gerA20pt0tKdijbYGzMsJm20pVbUxgW1iInKA-OlJo,675
8
- pymiele-0.3.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
9
- pymiele-0.3.1.dist-info/top_level.txt,sha256=BwkHrSO2w_Bfxh6s8Ikcao5enEuQOpQhJ3SwUXBqY10,8
10
- pymiele-0.3.1.dist-info/RECORD,,