python-tado 0.18.4__tar.gz → 0.18.6__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.
Files changed (34) hide show
  1. {python_tado-0.18.4/python_tado.egg-info → python_tado-0.18.6}/PKG-INFO +121 -19
  2. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/http.py +8 -0
  3. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/interface/api/hops_tado.py +12 -0
  4. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/interface/api/my_tado.py +29 -0
  5. python_tado-0.18.6/PyTado/interface/interface.py +303 -0
  6. python_tado-0.18.6/README.md +130 -0
  7. {python_tado-0.18.4 → python_tado-0.18.6}/pyproject.toml +6 -2
  8. {python_tado-0.18.4 → python_tado-0.18.6/python_tado.egg-info}/PKG-INFO +121 -19
  9. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/requires.txt +5 -0
  10. {python_tado-0.18.4 → python_tado-0.18.6}/tests/test_my_tado.py +13 -0
  11. python_tado-0.18.4/PyTado/interface/interface.py +0 -39
  12. python_tado-0.18.4/README.md +0 -32
  13. {python_tado-0.18.4 → python_tado-0.18.6}/AUTHORS +0 -0
  14. {python_tado-0.18.4 → python_tado-0.18.6}/LICENSE +0 -0
  15. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/__init__.py +0 -0
  16. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/__main__.py +0 -0
  17. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/const.py +0 -0
  18. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/exceptions.py +0 -0
  19. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/interface/__init__.py +0 -0
  20. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/interface/api/__init__.py +0 -0
  21. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/logger.py +0 -0
  22. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/zone/__init__.py +0 -0
  23. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/zone/hops_zone.py +0 -0
  24. {python_tado-0.18.4 → python_tado-0.18.6}/PyTado/zone/my_zone.py +0 -0
  25. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/SOURCES.txt +0 -0
  26. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/dependency_links.txt +0 -0
  27. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/entry_points.txt +0 -0
  28. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/not-zip-safe +0 -0
  29. {python_tado-0.18.4 → python_tado-0.18.6}/python_tado.egg-info/top_level.txt +0 -0
  30. {python_tado-0.18.4 → python_tado-0.18.6}/setup.cfg +0 -0
  31. {python_tado-0.18.4 → python_tado-0.18.6}/tests/test_hops_zone.py +0 -0
  32. {python_tado-0.18.4 → python_tado-0.18.6}/tests/test_http.py +0 -0
  33. {python_tado-0.18.4 → python_tado-0.18.6}/tests/test_my_zone.py +0 -0
  34. {python_tado-0.18.4 → python_tado-0.18.6}/tests/test_tado_interface.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: python-tado
3
- Version: 0.18.4
3
+ Version: 0.18.6
4
4
  Summary: PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem
5
5
  Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>, FilBr <filippo.barba@protonmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -696,43 +696,145 @@ License-File: AUTHORS
696
696
  Requires-Dist: requests
697
697
  Provides-Extra: dev
698
698
  Requires-Dist: black>=24.3; extra == "dev"
699
+ Requires-Dist: pre-commit; extra == "dev"
699
700
  Requires-Dist: pytype; extra == "dev"
700
701
  Requires-Dist: pylint; extra == "dev"
701
702
  Requires-Dist: types-requests; extra == "dev"
703
+ Requires-Dist: requests; extra == "dev"
702
704
  Requires-Dist: responses; extra == "dev"
703
705
  Requires-Dist: coverage; extra == "dev"
704
706
  Requires-Dist: pytest; extra == "dev"
705
707
  Requires-Dist: pytest-cov; extra == "dev"
708
+ Provides-Extra: all
709
+ Requires-Dist: python-tado[dev]; extra == "all"
706
710
 
707
- PyTado -- Pythonize your central heating
708
- ========================================
711
+ # PyTado -- Pythonize your central heating
709
712
 
710
- Author: Chris Jewell <chrism0dwk@gmail.com>
711
- Modified: Wolfgang Malgadey <wolfgang@malgadey.de>
713
+ [![Linting and testing](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml)
714
+ [![Build and deploy to pypi](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml)
715
+ [![PyPI version](https://badge.fury.io/py/python-tado.svg)](https://badge.fury.io/py/python-tado)
716
+
717
+ PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their
718
+ Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves
719
+ currently offer.
720
+
721
+ It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their
722
+ heating setups.
723
+
724
+ ---
725
+
726
+ Original author: Chris Jewell <chrism0dwk@gmail.com>
712
727
 
713
728
  Licence: GPL v3
714
729
 
715
730
  Copyright: Chris Jewell 2016-2018
716
731
 
717
- PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves currently offer.
732
+ ## Disclaimer
718
733
 
719
- It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their heating setups.
734
+ Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use,
735
+ and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or
736
+ otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to
737
+ the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or
738
+ cause discomfort and inconvenience to others.
720
739
 
721
- Disclaimer
722
- ----------
723
- Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use, and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or cause discomfort and inconvenience to others.
724
-
725
- Example basic usage
726
- -------------------
740
+ ## Example basic usage
727
741
 
728
742
  >>> from PyTado.interface import Tado
729
743
  >>> t = Tado('my@username.com', 'mypassword')
730
744
  >>> climate = t.get_climate(zone=1)
731
745
 
732
- Development
733
- -----------
734
- This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo, drop me a line, and get involved!
746
+ ## Usage
747
+ ```python
748
+ """Example client for PyTado"""
749
+
750
+ from PyTado.interface.interface import Tado
751
+
752
+
753
+ def main() -> None:
754
+ """Retrieve all zones, once successfully logged in"""
755
+ tado = Tado(username="mail@email.com", password="password") # nosec
756
+ zones = tado.get_zones()
757
+ print(zones)
758
+
759
+
760
+ if __name__ == "__main__":
761
+ main()
762
+ ```
763
+ Note: for developers, you can create an `example_dev.py` file in the root of the project to test your changes. This file will be ignored by the `.gitignore` file.
764
+
765
+ ## Contributing
766
+
767
+ We are very open to the community's contributions - be it a quick fix of a typo, or a completely new feature!
768
+
769
+ You don't need to be a Python expert to provide meaningful improvements. To learn how to get started, check out our
770
+ [Contributor Guidelines](https://github.com/wmalgadey/econnect-python/blob/main/CONTRIBUTING.md) first, and ask for help
771
+ in [GitHub Discussions](https://github.com/wmalgadey/PyTado/discussions) if you have questions.
772
+
773
+ ## Development
774
+
775
+ We welcome external contributions, even though the project was initially intended for personal use. If you think some
776
+ parts could be exposed with a more generic interface, please open a [GitHub issue](https://github.com/wmalgadey/PyTado/issues)
777
+ to discuss your suggestion.
778
+
779
+ ### Dev Environment
780
+
781
+ To contribute to this repository, you should first clone your fork and then setup your development environment. Clone
782
+ your repository as follows (replace yourusername with your GitHub account name):
783
+
784
+ ```bash
785
+ git clone https://github.com/yourusername/PyTado.git
786
+ cd PyTado
787
+ ```
788
+
789
+ Then, to create your development environment and install the project with its dependencies, execute the following
790
+ commands in your terminal:
791
+
792
+ ```bash
793
+ # Create and activate a new virtual environment
794
+ python3 -m venv venv
795
+ source venv/bin/activate
796
+
797
+ # Upgrade pip and install all projects and their dependencies
798
+ pip install --upgrade pip
799
+ pip install -e '.[all]'
800
+
801
+ # Install pre-commit hooks
802
+ pre-commit install
803
+ ```
804
+
805
+ ### Coding Guidelines
806
+
807
+ To maintain a consistent codebase, we utilize [black][1]. Consistency is crucial as it helps readability, reduces errors,
808
+ and facilitates collaboration among developers.
809
+
810
+ To ensure that every commit adheres to our coding standards, we've integrated [pre-commit hooks][2]. These hooks
811
+ automatically run `black` before each commit, ensuring that all code changes are automatically checked and formatted.
812
+
813
+ For details on how to set up your development environment to make use of these hooks, please refer to the
814
+ [Development][3] section of our documentation.
815
+
816
+ [1]: https://github.com/ambv/black
817
+ [2]: https://pre-commit.com/
818
+ [3]: https://github.com/wmalgadey/PyTado#development
819
+
820
+ ### Testing
821
+
822
+ Ensuring the robustness and reliability of our code is paramount. Therefore, all contributions must include at least one
823
+ test to verify the intended behavior.
824
+
825
+ To run tests locally, execute the test suite using `pytest` with the following command:
826
+
827
+ ```bash
828
+ pytest tests/ --cov --cov-branch -vv
829
+ ```
830
+
831
+ ---
735
832
 
736
- Best wishes and a warm winter to all!
833
+ A message from the original author:
737
834
 
738
- Chris Jewell
835
+ > This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo,
836
+ > drop me a line, and get involved!
837
+ >
838
+ > Best wishes and a warm winter to all!
839
+ >
840
+ > Chris Jewell
@@ -8,6 +8,7 @@ import logging
8
8
  import pprint
9
9
  from datetime import datetime, timedelta
10
10
  from typing import Any
11
+ from urllib.parse import urlencode
11
12
 
12
13
  import requests
13
14
 
@@ -27,6 +28,7 @@ class Endpoint(enum.StrEnum):
27
28
  EIQ = "https://energy-insights.tado.com/api/"
28
29
  TARIFF = "https://tariff-experience.tado.com/api/"
29
30
  GENIE = "https://genie.tado.com/api/v2/"
31
+ MINDER = "https://minder.tado.com/v1/"
30
32
 
31
33
 
32
34
  class Domain(enum.StrEnum):
@@ -65,6 +67,7 @@ class TadoRequest:
65
67
  domain: Domain = Domain.HOME,
66
68
  device: int | None = None,
67
69
  mode: Mode = Mode.OBJECT,
70
+ params: dict[str, Any] | None = None,
68
71
  ):
69
72
  self.endpoint = endpoint
70
73
  self.command = command
@@ -73,6 +76,7 @@ class TadoRequest:
73
76
  self.domain = domain
74
77
  self.device = device
75
78
  self.mode = mode
79
+ self.params = params
76
80
 
77
81
 
78
82
  class TadoXRequest(TadoRequest):
@@ -87,6 +91,7 @@ class TadoXRequest(TadoRequest):
87
91
  domain: Domain = Domain.HOME,
88
92
  device: int | None = None,
89
93
  mode: Mode = Mode.OBJECT,
94
+ params: dict[str, Any] | None = None,
90
95
  ):
91
96
  super().__init__(
92
97
  endpoint=endpoint,
@@ -96,6 +101,7 @@ class TadoXRequest(TadoRequest):
96
101
  domain=domain,
97
102
  device=device,
98
103
  mode=mode,
104
+ params=params,
99
105
  )
100
106
  self._action = action
101
107
 
@@ -214,6 +220,8 @@ class Http:
214
220
  url = f"{request.endpoint}{request.domain}/{request.device}/{request.command}"
215
221
  elif request.domain == Domain.ME:
216
222
  url = f"{request.endpoint}{request.domain}"
223
+ elif request.endpoint == Endpoint.MINDER:
224
+ url = f"{request.endpoint}{request.domain}/{self.id:d}/{request.command}?{urlencode(request.params)}"
217
225
  else:
218
226
  url = f"{request.endpoint}{request.domain}/{self._id:d}/{request.command}"
219
227
  return url
@@ -335,3 +335,15 @@ class TadoX(Tado):
335
335
  request.payload = {"temperatureOffset": offset}
336
336
 
337
337
  return self._http.request(request)
338
+
339
+ def set_child_lock(self, device_id, child_lock):
340
+ """ "
341
+ Set and toggle the child lock on the device.
342
+ """
343
+
344
+ request = TadoXRequest()
345
+ request.command = f"roomsAndDevices/devices/{device_id}"
346
+ request.action = Action.CHANGE
347
+ request.payload = {"childLockEnabled": child_lock}
348
+
349
+ self._http.request(request)
@@ -424,6 +424,20 @@ class Tado:
424
424
 
425
425
  self._http.request(request)
426
426
 
427
+ def set_child_lock(self, device_id, child_lock) -> None:
428
+ """
429
+ Sets the child lock on a device
430
+ """
431
+
432
+ request = TadoRequest()
433
+ request.command = "childLock"
434
+ request.action = Action.CHANGE
435
+ request.device = device_id
436
+ request.domain = Domain.DEVICES
437
+ request.payload = {"childLockEnabled": child_lock}
438
+
439
+ self._http.request(request)
440
+
427
441
  def set_auto(self) -> None:
428
442
  """
429
443
  Sets HomeState to AUTO
@@ -621,3 +635,18 @@ class Tado:
621
635
  request.payload = {"circuitNumber": heating_circuit}
622
636
 
623
637
  return self._http.request(request)
638
+
639
+ def get_running_times(
640
+ self, date=datetime.datetime.now().strftime("%Y-%m-%d")
641
+ ) -> dict:
642
+ """
643
+ Get the running times from the Minder API
644
+ """
645
+
646
+ request = TadoRequest()
647
+ request.command = "runningTimes"
648
+ request.action = Action.GET
649
+ request.endpoint = Endpoint.MINDER
650
+ request.params = {"from": date}
651
+
652
+ return self._http.request(request)
@@ -0,0 +1,303 @@
1
+ """
2
+ PyTado interface abstraction to use app.tado.com or hops.tado.com
3
+ """
4
+
5
+ import datetime
6
+ import warnings
7
+ import functools
8
+
9
+ from PyTado.http import Http
10
+ import PyTado.interface.api as API
11
+
12
+
13
+ def deprecated(new_func_name):
14
+ def decorator(func):
15
+ @functools.wraps(func)
16
+ def wrapper(*args, **kwargs):
17
+ warnings.warn(
18
+ f"The '{func.__name__}' method is deprecated, use '{new_func_name}' instead. "
19
+ "Deprecated methods will be removed with 1.0.0.",
20
+ DeprecationWarning,
21
+ stacklevel=2,
22
+ )
23
+ return getattr(args[0], new_func_name)(*args, **kwargs)
24
+
25
+ return wrapper
26
+
27
+ return decorator
28
+
29
+
30
+ class Tado:
31
+ """Interacts with a Tado thermostat via public API.
32
+
33
+ Example usage: t = Tado('me@somewhere.com', 'mypasswd')
34
+ t.get_climate(1) # Get climate, zone 1.
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ username: str,
40
+ password: str,
41
+ http_session=None,
42
+ debug: bool = False,
43
+ ):
44
+ """Class Constructor"""
45
+
46
+ self._http = Http(
47
+ username=username,
48
+ password=password,
49
+ http_session=http_session,
50
+ debug=debug,
51
+ )
52
+
53
+ if self._http.is_x_line:
54
+ self._api = API.TadoX(http=self._http, debug=debug)
55
+ else:
56
+ self._api = API.Tado(http=self._http, debug=debug)
57
+
58
+ def __getattr__(self, name):
59
+ """Delegiert den Aufruf von Methoden an die richtige API-Client-Implementierung."""
60
+ return getattr(self._api, name)
61
+
62
+ # region Deprecated Methods
63
+ # pylint: disable=invalid-name
64
+
65
+ @deprecated("get_me")
66
+ def getMe(self):
67
+ """Gets home information. (deprecated)"""
68
+ return self.get_me()
69
+
70
+ @deprecated("get_devices")
71
+ def getDevices(self):
72
+ """Gets device information. (deprecated)"""
73
+ return self.get_devices()
74
+
75
+ @deprecated("get_zones")
76
+ def getZones(self):
77
+ """Gets zones information. (deprecated)"""
78
+ return self.get_zones()
79
+
80
+ @deprecated("set_child_lock")
81
+ def setChildLock(self, device_id, enabled):
82
+ """Set the child lock for a device"""
83
+ return self.set_child_lock(device_id, enabled)
84
+
85
+ @deprecated("get_zone_state")
86
+ def getZoneState(self, zone):
87
+ """Gets current state of Zone as a TadoZone object. (deprecated)"""
88
+ return self.get_zone_state(zone)
89
+
90
+ @deprecated("get_zone_states")
91
+ def getZoneStates(self):
92
+ """Gets current states of all zones. (deprecated)"""
93
+ return self.get_zone_states()
94
+
95
+ @deprecated("get_state")
96
+ def getState(self, zone):
97
+ """Gets current state of Zone. (deprecated)"""
98
+ return self.get_state(zone)
99
+
100
+ @deprecated("get_home_state")
101
+ def getHomeState(self):
102
+ """Gets current state of Home. (deprecated)"""
103
+ return self.get_home_state()
104
+
105
+ @deprecated("get_auto_geofencing_supported")
106
+ def getAutoGeofencingSupported(self):
107
+ """Return whether the Tado Home supports auto geofencing (deprecated)"""
108
+ return self.get_auto_geofencing_supported()
109
+
110
+ @deprecated("get_capabilities")
111
+ def getCapabilities(self, zone):
112
+ """Gets current capabilities of Zone zone. (deprecated)"""
113
+ return self.get_capabilities(zone)
114
+
115
+ @deprecated("get_climate")
116
+ def getClimate(self, zone):
117
+ """Gets temp (centigrade) and humidity (% RH) for Zone zone. (deprecated)"""
118
+ return self.get_climate(zone)
119
+
120
+ @deprecated("get_timetable")
121
+ def getTimetable(self, zone):
122
+ """Get the Timetable type currently active (Deprecated)"""
123
+ return self.get_timetable(zone)
124
+
125
+ @deprecated("get_historic")
126
+ def getHistoric(self, zone, date):
127
+ """Gets historic information on given date for zone. (Deprecated)"""
128
+ return self.get_historic(zone, date)
129
+
130
+ @deprecated("set_timetable")
131
+ def setTimetable(self, zone, _id):
132
+ """Set the Timetable type currently active (Deprecated)
133
+ id = 0 : ONE_DAY (MONDAY_TO_SUNDAY)
134
+ id = 1 : THREE_DAY (MONDAY_TO_FRIDAY, SATURDAY, SUNDAY)
135
+ id = 3 : SEVEN_DAY (MONDAY, TUESDAY, WEDNESDAY ...)"""
136
+ return self.set_timetable(zone, _id)
137
+
138
+ @deprecated("get_schedule")
139
+ def getSchedule(self, zone, _id, day=None):
140
+ """Get the JSON representation of the schedule for a zone. Zone has 3 different schedules,
141
+ one for each timetable (see setTimetable)"""
142
+ return self.get_schedule(zone, _id, day)
143
+
144
+ @deprecated("set_schedule")
145
+ def setSchedule(self, zone, _id, day, data):
146
+ """Set the schedule for a zone, day is required"""
147
+ return self.set_schedule(zone, _id, day, data)
148
+
149
+ @deprecated("get_weather")
150
+ def getWeather(self):
151
+ """Gets outside weather data (Deprecated)"""
152
+ return self.get_weather()
153
+
154
+ @deprecated("get_air_comfort")
155
+ def getAirComfort(self):
156
+ """Gets air quality information (Deprecated)"""
157
+ return self.get_air_comfort()
158
+
159
+ @deprecated("get_users")
160
+ def getAppUsers(self):
161
+ """Gets getAppUsers data (deprecated)"""
162
+ return self.get_app_user()
163
+
164
+ @deprecated("get_mobile_devices")
165
+ def getMobileDevices(self):
166
+ """Gets information about mobile devices (Deprecated)"""
167
+ return self.get_mobile_devices()
168
+
169
+ @deprecated("reset_zone_overlay")
170
+ def resetZoneOverlay(self, zone):
171
+ """Delete current overlay (Deprecated)"""
172
+ return self.reset_zone_overlay(zone)
173
+
174
+ @deprecated("set_zone_overlay")
175
+ def setZoneOverlay(
176
+ self,
177
+ zone,
178
+ overlayMode,
179
+ setTemp=None,
180
+ duration=None,
181
+ deviceType="HEATING",
182
+ power="ON",
183
+ mode=None,
184
+ fanSpeed=None,
185
+ swing=None,
186
+ fanLevel=None,
187
+ verticalSwing=None,
188
+ horizontalSwing=None,
189
+ ):
190
+ """Set current overlay for a zone (Deprecated)"""
191
+ return self.set_zone_overlay(
192
+ zone,
193
+ overlay_mode=overlayMode,
194
+ set_temp=setTemp,
195
+ duration=duration,
196
+ device_type=deviceType,
197
+ power=power,
198
+ mode=mode,
199
+ fan_speed=fanSpeed,
200
+ swing=swing,
201
+ fan_level=fanLevel,
202
+ vertical_swing=verticalSwing,
203
+ horizontal_swing=horizontalSwing,
204
+ )
205
+
206
+ @deprecated("get_zone_overlay_default")
207
+ def getZoneOverlayDefault(self, zone):
208
+ """Get current overlay default settings for zone. (Deprecated)"""
209
+ return self.get_zone_overlay_default(zone)
210
+
211
+ @deprecated("set_home")
212
+ def setHome(self):
213
+ """Sets HomeState to HOME (Deprecated)"""
214
+ return self.set_home()
215
+
216
+ @deprecated("set_away")
217
+ def setAway(self):
218
+ """Sets HomeState to AWAY (Deprecated)"""
219
+ return self.set_away()
220
+
221
+ @deprecated("change_presence")
222
+ def changePresence(self, presence):
223
+ """Sets HomeState to presence (Deprecated)"""
224
+ return self.change_presence(presence=presence)
225
+
226
+ @deprecated("set_auto")
227
+ def setAuto(self):
228
+ """Sets HomeState to AUTO (Deprecated)"""
229
+ return self.set_auto()
230
+
231
+ @deprecated("get_window_state")
232
+ def getWindowState(self, zone):
233
+ """Returns the state of the window for zone (Deprecated)"""
234
+ return self.get_window_state(zone=zone)
235
+
236
+ @deprecated("get_open_window_detected")
237
+ def getOpenWindowDetected(self, zone):
238
+ """Returns whether an open window is detected. (Deprecated)"""
239
+ return self.get_open_window_detected(zone=zone)
240
+
241
+ @deprecated("set_open_window")
242
+ def setOpenWindow(self, zone):
243
+ """Sets the window in zone to open (Deprecated)"""
244
+ return self.set_open_window(zone=zone)
245
+
246
+ @deprecated("reset_open_window")
247
+ def resetOpenWindow(self, zone):
248
+ """Sets the window in zone to closed (Deprecated)"""
249
+ return self.reset_open_window(zone=zone)
250
+
251
+ @deprecated("get_device_info")
252
+ def getDeviceInfo(self, device_id, cmd=""):
253
+ """Gets information about devices
254
+ with option to get specific info i.e. cmd='temperatureOffset' (Deprecated)
255
+ """
256
+ return self.get_device_info(device_id=device_id, cmd=cmd)
257
+
258
+ @deprecated("set_temp_offset")
259
+ def setTempOffset(self, device_id, offset=0, measure="celsius"):
260
+ """Set the Temperature offset on the device. (Deprecated)"""
261
+ return self.set_temp_offset(
262
+ device_id=device_id, offset=offset, measure=measure
263
+ )
264
+
265
+ @deprecated("get_eiq_tariffs")
266
+ def getEIQTariffs(self):
267
+ """Get Energy IQ tariff history (Deprecated)"""
268
+ return self.get_eiq_tariffs()
269
+
270
+ @deprecated("get_eiq_meter_readings")
271
+ def getEIQMeterReadings(self):
272
+ """Get Energy IQ meter readings (Deprecated)"""
273
+ return self.get_eiq_meter_readings()
274
+
275
+ @deprecated("set_eiq_meter_readings")
276
+ def setEIQMeterReadings(
277
+ self, date=datetime.datetime.now().strftime("%Y-%m-%d"), reading=0
278
+ ):
279
+ """Send Meter Readings to Tado, date format is YYYY-MM-DD, reading is without decimals (Deprecated)"""
280
+ return self.set_eiq_meter_readings(date=date, reading=reading)
281
+
282
+ @deprecated("set_eiq_tariff")
283
+ def setEIQTariff(
284
+ self,
285
+ from_date=datetime.datetime.now().strftime("%Y-%m-%d"),
286
+ to_date=datetime.datetime.now().strftime("%Y-%m-%d"),
287
+ tariff=0,
288
+ unit="m3",
289
+ is_period=False,
290
+ ):
291
+ """Send Tariffs to Tado, date format is YYYY-MM-DD,
292
+ tariff is with decimals, unit is either m3 or kWh, set is_period to true to set a period of price (Deprecated)
293
+ """
294
+ return self.set_eiq_tariff(
295
+ from_date=from_date,
296
+ to_date=to_date,
297
+ tariff=tariff,
298
+ unit=unit,
299
+ is_period=is_period,
300
+ )
301
+
302
+ # pylint: enable=invalid-name
303
+ # endregion
@@ -0,0 +1,130 @@
1
+ # PyTado -- Pythonize your central heating
2
+
3
+ [![Linting and testing](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml)
4
+ [![Build and deploy to pypi](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml)
5
+ [![PyPI version](https://badge.fury.io/py/python-tado.svg)](https://badge.fury.io/py/python-tado)
6
+
7
+ PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their
8
+ Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves
9
+ currently offer.
10
+
11
+ It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their
12
+ heating setups.
13
+
14
+ ---
15
+
16
+ Original author: Chris Jewell <chrism0dwk@gmail.com>
17
+
18
+ Licence: GPL v3
19
+
20
+ Copyright: Chris Jewell 2016-2018
21
+
22
+ ## Disclaimer
23
+
24
+ Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use,
25
+ and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or
26
+ otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to
27
+ the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or
28
+ cause discomfort and inconvenience to others.
29
+
30
+ ## Example basic usage
31
+
32
+ >>> from PyTado.interface import Tado
33
+ >>> t = Tado('my@username.com', 'mypassword')
34
+ >>> climate = t.get_climate(zone=1)
35
+
36
+ ## Usage
37
+ ```python
38
+ """Example client for PyTado"""
39
+
40
+ from PyTado.interface.interface import Tado
41
+
42
+
43
+ def main() -> None:
44
+ """Retrieve all zones, once successfully logged in"""
45
+ tado = Tado(username="mail@email.com", password="password") # nosec
46
+ zones = tado.get_zones()
47
+ print(zones)
48
+
49
+
50
+ if __name__ == "__main__":
51
+ main()
52
+ ```
53
+ Note: for developers, you can create an `example_dev.py` file in the root of the project to test your changes. This file will be ignored by the `.gitignore` file.
54
+
55
+ ## Contributing
56
+
57
+ We are very open to the community's contributions - be it a quick fix of a typo, or a completely new feature!
58
+
59
+ You don't need to be a Python expert to provide meaningful improvements. To learn how to get started, check out our
60
+ [Contributor Guidelines](https://github.com/wmalgadey/econnect-python/blob/main/CONTRIBUTING.md) first, and ask for help
61
+ in [GitHub Discussions](https://github.com/wmalgadey/PyTado/discussions) if you have questions.
62
+
63
+ ## Development
64
+
65
+ We welcome external contributions, even though the project was initially intended for personal use. If you think some
66
+ parts could be exposed with a more generic interface, please open a [GitHub issue](https://github.com/wmalgadey/PyTado/issues)
67
+ to discuss your suggestion.
68
+
69
+ ### Dev Environment
70
+
71
+ To contribute to this repository, you should first clone your fork and then setup your development environment. Clone
72
+ your repository as follows (replace yourusername with your GitHub account name):
73
+
74
+ ```bash
75
+ git clone https://github.com/yourusername/PyTado.git
76
+ cd PyTado
77
+ ```
78
+
79
+ Then, to create your development environment and install the project with its dependencies, execute the following
80
+ commands in your terminal:
81
+
82
+ ```bash
83
+ # Create and activate a new virtual environment
84
+ python3 -m venv venv
85
+ source venv/bin/activate
86
+
87
+ # Upgrade pip and install all projects and their dependencies
88
+ pip install --upgrade pip
89
+ pip install -e '.[all]'
90
+
91
+ # Install pre-commit hooks
92
+ pre-commit install
93
+ ```
94
+
95
+ ### Coding Guidelines
96
+
97
+ To maintain a consistent codebase, we utilize [black][1]. Consistency is crucial as it helps readability, reduces errors,
98
+ and facilitates collaboration among developers.
99
+
100
+ To ensure that every commit adheres to our coding standards, we've integrated [pre-commit hooks][2]. These hooks
101
+ automatically run `black` before each commit, ensuring that all code changes are automatically checked and formatted.
102
+
103
+ For details on how to set up your development environment to make use of these hooks, please refer to the
104
+ [Development][3] section of our documentation.
105
+
106
+ [1]: https://github.com/ambv/black
107
+ [2]: https://pre-commit.com/
108
+ [3]: https://github.com/wmalgadey/PyTado#development
109
+
110
+ ### Testing
111
+
112
+ Ensuring the robustness and reliability of our code is paramount. Therefore, all contributions must include at least one
113
+ test to verify the intended behavior.
114
+
115
+ To run tests locally, execute the test suite using `pytest` with the following command:
116
+
117
+ ```bash
118
+ pytest tests/ --cov --cov-branch -vv
119
+ ```
120
+
121
+ ---
122
+
123
+ A message from the original author:
124
+
125
+ > This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo,
126
+ > drop me a line, and get involved!
127
+ >
128
+ > Best wishes and a warm winter to all!
129
+ >
130
+ > Chris Jewell
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-tado"
7
- version = "0.18.4"
7
+ version = "0.18.6"
8
8
  description = "PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem"
9
9
  authors = [
10
10
  { name = "Chris Jewell", email = "chrism0dwk@gmail.com" },
@@ -31,7 +31,11 @@ classifiers = [
31
31
  GitHub = "https://github.com/wmalgadey/PyTado"
32
32
 
33
33
  [project.optional-dependencies]
34
- dev = ["black>=24.3", "pytype", "pylint", "types-requests", "responses", "coverage", "pytest", "pytest-cov"]
34
+ dev = ["black>=24.3", "pre-commit", "pytype", "pylint", "types-requests", "requests", "responses", "coverage", "pytest", "pytest-cov"]
35
+
36
+ all = [
37
+ "python-tado[dev]",
38
+ ]
35
39
 
36
40
  [project.scripts]
37
41
  pytado = "pytado.__main__:main"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: python-tado
3
- Version: 0.18.4
3
+ Version: 0.18.6
4
4
  Summary: PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem
5
5
  Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>, FilBr <filippo.barba@protonmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -696,43 +696,145 @@ License-File: AUTHORS
696
696
  Requires-Dist: requests
697
697
  Provides-Extra: dev
698
698
  Requires-Dist: black>=24.3; extra == "dev"
699
+ Requires-Dist: pre-commit; extra == "dev"
699
700
  Requires-Dist: pytype; extra == "dev"
700
701
  Requires-Dist: pylint; extra == "dev"
701
702
  Requires-Dist: types-requests; extra == "dev"
703
+ Requires-Dist: requests; extra == "dev"
702
704
  Requires-Dist: responses; extra == "dev"
703
705
  Requires-Dist: coverage; extra == "dev"
704
706
  Requires-Dist: pytest; extra == "dev"
705
707
  Requires-Dist: pytest-cov; extra == "dev"
708
+ Provides-Extra: all
709
+ Requires-Dist: python-tado[dev]; extra == "all"
706
710
 
707
- PyTado -- Pythonize your central heating
708
- ========================================
711
+ # PyTado -- Pythonize your central heating
709
712
 
710
- Author: Chris Jewell <chrism0dwk@gmail.com>
711
- Modified: Wolfgang Malgadey <wolfgang@malgadey.de>
713
+ [![Linting and testing](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/lint-and-test-matrix.yml)
714
+ [![Build and deploy to pypi](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml/badge.svg)](https://github.com/wmalgadey/PyTado/actions/workflows/publish-to-pypi.yml)
715
+ [![PyPI version](https://badge.fury.io/py/python-tado.svg)](https://badge.fury.io/py/python-tado)
716
+
717
+ PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their
718
+ Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves
719
+ currently offer.
720
+
721
+ It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their
722
+ heating setups.
723
+
724
+ ---
725
+
726
+ Original author: Chris Jewell <chrism0dwk@gmail.com>
712
727
 
713
728
  Licence: GPL v3
714
729
 
715
730
  Copyright: Chris Jewell 2016-2018
716
731
 
717
- PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves currently offer.
732
+ ## Disclaimer
718
733
 
719
- It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their heating setups.
734
+ Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use,
735
+ and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or
736
+ otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to
737
+ the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or
738
+ cause discomfort and inconvenience to others.
720
739
 
721
- Disclaimer
722
- ----------
723
- Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use, and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or cause discomfort and inconvenience to others.
724
-
725
- Example basic usage
726
- -------------------
740
+ ## Example basic usage
727
741
 
728
742
  >>> from PyTado.interface import Tado
729
743
  >>> t = Tado('my@username.com', 'mypassword')
730
744
  >>> climate = t.get_climate(zone=1)
731
745
 
732
- Development
733
- -----------
734
- This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo, drop me a line, and get involved!
746
+ ## Usage
747
+ ```python
748
+ """Example client for PyTado"""
749
+
750
+ from PyTado.interface.interface import Tado
751
+
752
+
753
+ def main() -> None:
754
+ """Retrieve all zones, once successfully logged in"""
755
+ tado = Tado(username="mail@email.com", password="password") # nosec
756
+ zones = tado.get_zones()
757
+ print(zones)
758
+
759
+
760
+ if __name__ == "__main__":
761
+ main()
762
+ ```
763
+ Note: for developers, you can create an `example_dev.py` file in the root of the project to test your changes. This file will be ignored by the `.gitignore` file.
764
+
765
+ ## Contributing
766
+
767
+ We are very open to the community's contributions - be it a quick fix of a typo, or a completely new feature!
768
+
769
+ You don't need to be a Python expert to provide meaningful improvements. To learn how to get started, check out our
770
+ [Contributor Guidelines](https://github.com/wmalgadey/econnect-python/blob/main/CONTRIBUTING.md) first, and ask for help
771
+ in [GitHub Discussions](https://github.com/wmalgadey/PyTado/discussions) if you have questions.
772
+
773
+ ## Development
774
+
775
+ We welcome external contributions, even though the project was initially intended for personal use. If you think some
776
+ parts could be exposed with a more generic interface, please open a [GitHub issue](https://github.com/wmalgadey/PyTado/issues)
777
+ to discuss your suggestion.
778
+
779
+ ### Dev Environment
780
+
781
+ To contribute to this repository, you should first clone your fork and then setup your development environment. Clone
782
+ your repository as follows (replace yourusername with your GitHub account name):
783
+
784
+ ```bash
785
+ git clone https://github.com/yourusername/PyTado.git
786
+ cd PyTado
787
+ ```
788
+
789
+ Then, to create your development environment and install the project with its dependencies, execute the following
790
+ commands in your terminal:
791
+
792
+ ```bash
793
+ # Create and activate a new virtual environment
794
+ python3 -m venv venv
795
+ source venv/bin/activate
796
+
797
+ # Upgrade pip and install all projects and their dependencies
798
+ pip install --upgrade pip
799
+ pip install -e '.[all]'
800
+
801
+ # Install pre-commit hooks
802
+ pre-commit install
803
+ ```
804
+
805
+ ### Coding Guidelines
806
+
807
+ To maintain a consistent codebase, we utilize [black][1]. Consistency is crucial as it helps readability, reduces errors,
808
+ and facilitates collaboration among developers.
809
+
810
+ To ensure that every commit adheres to our coding standards, we've integrated [pre-commit hooks][2]. These hooks
811
+ automatically run `black` before each commit, ensuring that all code changes are automatically checked and formatted.
812
+
813
+ For details on how to set up your development environment to make use of these hooks, please refer to the
814
+ [Development][3] section of our documentation.
815
+
816
+ [1]: https://github.com/ambv/black
817
+ [2]: https://pre-commit.com/
818
+ [3]: https://github.com/wmalgadey/PyTado#development
819
+
820
+ ### Testing
821
+
822
+ Ensuring the robustness and reliability of our code is paramount. Therefore, all contributions must include at least one
823
+ test to verify the intended behavior.
824
+
825
+ To run tests locally, execute the test suite using `pytest` with the following command:
826
+
827
+ ```bash
828
+ pytest tests/ --cov --cov-branch -vv
829
+ ```
830
+
831
+ ---
735
832
 
736
- Best wishes and a warm winter to all!
833
+ A message from the original author:
737
834
 
738
- Chris Jewell
835
+ > This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo,
836
+ > drop me a line, and get involved!
837
+ >
838
+ > Best wishes and a warm winter to all!
839
+ >
840
+ > Chris Jewell
@@ -1,10 +1,15 @@
1
1
  requests
2
2
 
3
+ [all]
4
+ python-tado[dev]
5
+
3
6
  [dev]
4
7
  black>=24.3
8
+ pre-commit
5
9
  pytype
6
10
  pylint
7
11
  types-requests
12
+ requests
8
13
  responses
9
14
  coverage
10
15
  pytest
@@ -79,3 +79,16 @@ class TadoTestCase(unittest.TestCase):
79
79
  with mock.patch("PyTado.http.Http.request"):
80
80
  with self.assertRaises(Exception):
81
81
  self.tado_client.set_auto()
82
+
83
+ def test_get_running_times(self):
84
+ """Test the get_running_times method."""
85
+
86
+ with mock.patch(
87
+ "PyTado.http.Http.request",
88
+ return_value=json.loads(common.load_fixture("running_times.json")),
89
+ ):
90
+ running_times = self.tado_client.get_running_times("2023-08-01")
91
+
92
+ assert self.tado_client._http.request.called
93
+ assert running_times["lastUpdated"] == "2023-08-05T19:50:21Z"
94
+ assert running_times["runningTimes"][0]["zones"][0]["id"] == 1
@@ -1,39 +0,0 @@
1
- """
2
- PyTado interface abstraction to use app.tado.com or hops.tado.com
3
- """
4
-
5
- from PyTado.http import Http
6
- import PyTado.interface.api as API
7
-
8
-
9
- class Tado:
10
- """Interacts with a Tado thermostat via public API.
11
-
12
- Example usage: t = Tado('me@somewhere.com', 'mypasswd')
13
- t.get_climate(1) # Get climate, zone 1.
14
- """
15
-
16
- def __init__(
17
- self,
18
- username: str,
19
- password: str,
20
- http_session=None,
21
- debug: bool = False,
22
- ):
23
- """Class Constructor"""
24
-
25
- self._http = Http(
26
- username=username,
27
- password=password,
28
- http_session=http_session,
29
- debug=debug,
30
- )
31
-
32
- if self._http.is_x_line:
33
- self._api = API.TadoX(http=self._http, debug=debug)
34
- else:
35
- self._api = API.Tado(http=self._http, debug=debug)
36
-
37
- def __getattr__(self, name):
38
- """Delegiert den Aufruf von Methoden an die richtige API-Client-Implementierung."""
39
- return getattr(self._api, name)
@@ -1,32 +0,0 @@
1
- PyTado -- Pythonize your central heating
2
- ========================================
3
-
4
- Author: Chris Jewell <chrism0dwk@gmail.com>
5
- Modified: Wolfgang Malgadey <wolfgang@malgadey.de>
6
-
7
- Licence: GPL v3
8
-
9
- Copyright: Chris Jewell 2016-2018
10
-
11
- PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves currently offer.
12
-
13
- It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their heating setups.
14
-
15
- Disclaimer
16
- ----------
17
- Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use, and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to the GNU Public Licence version 3, and should therefore not be used where it may endanger life, financial stakes, or cause discomfort and inconvenience to others.
18
-
19
- Example basic usage
20
- -------------------
21
-
22
- >>> from PyTado.interface import Tado
23
- >>> t = Tado('my@username.com', 'mypassword')
24
- >>> climate = t.get_climate(zone=1)
25
-
26
- Development
27
- -----------
28
- This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo, drop me a line, and get involved!
29
-
30
- Best wishes and a warm winter to all!
31
-
32
- Chris Jewell
File without changes
File without changes
File without changes