GithubHelp home page GithubHelp logo

wmalgadey / pytado Goto Github PK

View Code? Open in Web Editor NEW

This project forked from chrism0dwk/pytado

72.0 8.0 41.0 175 KB

Python binding for Tado web API. Pythonize your central heating!

License: GNU General Public License v3.0

Python 100.00%
python home-automation tado

pytado's Introduction

PyTado -- Pythonize your central heating

Author: Chris Jewell [email protected]
Modified: Wolfgang Malgadey [email protected]

Licence: GPL v3

Copyright: Chris Jewell 2016-2018

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.

It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimise their heating setups.

Disclaimer

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.

Example basic usage

>>> from PyTado.interface import Tado
>>> t = Tado('[email protected]', 'mypassword')
>>> climate = t.getClimate(zone=1)

Development

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!

Release and publish to pypi.org

see: https://packaging.python.org/tutorials/packaging-projects/

TL:DR;

  • update version in setup.py
  • python3 -m pip install --user --upgrade setuptools wheel
  • python3 setup.py sdist bdist_wheel
  • python3 -m pip install --user --upgrade twine
  • python3 -m twine upload dist/*

Best wishes and a warm winter to all!

Chris Jewell

pytado's People

Contributors

andersonshatch avatar bdraco avatar bl8 avatar chiefdragon avatar chrism0dwk avatar coffee2codenl avatar diplix avatar eblekkenhorst avatar erwindouna avatar etiennesou avatar gorynychzmey avatar isk0001y avatar jasperro avatar joostlek avatar lenhartstephan avatar markusschanta avatar michaelarnauts avatar niklasastrom avatar noltari avatar north3221 avatar p0thi avatar palazzem avatar rblenkinsopp avatar savjee avatar syssi avatar vlebourl avatar wmalgadey avatar yippy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pytado's Issues

Implement Zone Controller setting

The Tado app allows each zone to select the device that calls for heat, or make a zone independent and never call for heat: https://support.tado.com/en/articles/4689126-how-does-tado-control-heating-zones-how-can-i-change-the-zone-controller-of-a-room

As the Tado TRVs are quite noisy, I make the bedroom an independent zone and set the temperature to 25° overnight - this means the valve is fully open and so the radiators still get warm if heat is required elsewhere in the house, while not waking us up with noise.

This mostly works except that it is difficult to get a good temperature in the room just before going to bed. It would be great to control this from Home Assistant, so I can set the zone to controlled temperatures during the day and then automatically switch to independent mode overnight.

The API request appears to be

PUT https://my.tado.com/api/v2/homes/HOME_ID/zones/ZONE_ID/control/heatingCircuit

with the following payload to set zone controller 1 (I only have one Tado heating zone) to call for heat:

{"circuitNumber":1}

or the following payload to make the device independent:

{"circuitNumber":null}

IDEA: Add Gas usage

Is it be possible to add gas meter usage via the API? That would be a nice feature to automatically add gas usage when combined with DSMR / Home Assistant.

Not understanding what is "data" in "TadoZone"

I'm not understanding what is "data" in "TadoZone".

How should I initialize the class?

For sure i'm a noob but i'm in need of a bit more documentation

Thank you in advance for every tipe of reply

Unable to set any modes outside of Off, Cool, Auto

Hello!
I was investigating an issue in Home Assistant for an integration (Tado) that uses this library.

TL;DR from Home Assistant I can only use [Off, Cool, Auto] modes. If I set another mode (e.g. Dry) I get an error from the Tado API. I wrote down my investigation here if you are curious about the triaging I did.

To summarize, I've reproduced the issue by using this library so it seems it's not a problem with HA. Here you can find the snippet I used:

from PyTado.interface import Tado
tado = Tado(username, password)
# Zone 8 is the AC used in the HA test above
tado.setZoneOverlay(8, "MANUAL", deviceType="AIR_CONDITIONING", fanSpeed="AUTO", mode="DRY", swing="OFF")

# Returns:
# {'errors': [{'code': 'setting.notSupported', 'title': 'fan speed not in supported fan speeds [AUTO, HIGH, LOW, MIDDLE]'}]}

I found that (code) if setTemp is not set, fanSpeed and swing are not sent as parameters during the API call. If I do a change to send them regardless (I move both outside of the if clause), then this works as expected.

I'm opening this issue to understand better what it could be and I have a few questions:

  1. Are you aware why some people get this error, while others are not? Do you know if Tado (the actual product) registers devices in a different way, and so some AC/remote requires fanSpeed and swing set?
  2. Do you know why the code sends fan speed and swing only if a temperature is set? What is the rationale around it?
  3. Do you know what are the implications of sending these values regardless of the temperature? I can submit the change for your review, but I don't know if I'm going to break something.

Thank you very much in advance!

API being turned off

I have just received this email from Tado:

We have noticed that you are using the unofficial tado° REST API with an old authentication method. That is, you are making requests similar to https://my.tado.com/api/v2/me?username=myUsername&password=myPassword where username and password are supplied as query parameters with each request.

We will discontinue the support for this type of authentication and only support OAuth 2 in the future (you can find more information at https://datatracker.ietf.org/doc/html/rfc6749).

We plan to turn off the authentication on December 4th 2023.

Important: We will stop synchronising passwords for this legacy authentication. If you reset your password, the legacy authentication might stop working even before the above date, so please try to switch to the new type of authentication as quickly as possible.

To make the transition easier for you, we have created a document explaining how to adjust the authentication flow.

API authorisation broken (since today)

i changed the client_id (tado-web-app instead of tado-webapp) and added a client_secret (which i picked up in the web-app) in https://github.com/wmalgadey/PyTado/blob/master/PyTado/interface.py#L140 to get it working again:

        data = { 'client_id' : 'tado-web-app',
                 'grant_type' : 'password',
                 'password' : password,
                 'scope' : 'home.user',
                 'username' : username,
                 'client_secret' : 'xxx' }

i don’t know if the client_secret is constant or dynamic or even session related, for the last couple of minutes it seems to work and (for now) my web client shows the same client_secret for each new session i start.

PyTado returns debug log, even if debug=False

Hello there,

I'm sorry if this is not the right way of reaching out about this issue.
PyTado returns debug log, even if debug=False in Tado(username, password, http_session, debug)

Thanks very much for any help.

Tado API changed termination mode (setZoneOverlay)

When changing the temperature in Home Assistant, Tado stays active indefinitely. It does not fall back to the schedule again.

See issue: home-assistant/core#43118

I believe this is due to this line in the library:

"termination": {"type": overlayMode},

It sends the following payload to Tado's API:

{
   "termination": {
       "type": "TADO_MODE"
   }
}

However, when I inspect requests on the Tado website, I see that they modified the request payload:

{
   "termination":{
      "typeSkillBasedApp":"NEXT_TIME_BLOCK"
   },
   "setting":{
      "type":"HEATING",
      "power":"ON",
      "temperature":{
         "celsius":18.3,
         "fahrenheit":64.94
      }
   }
}

Could you confirm this finding? (And maybe fix it in the process?)

Water tap heating not chaging mode

When I use the heating it works fine when I want to do the same for the water tap it does not work.

- id: '1545245312247'
  alias: Verwarming uit
  trigger:
  - entity_id: sensor.huiskamer_tado_mode
    platform: state
    to: AWAY
  condition: []
  action:
  - entity_id: climate.huiskamer
    service: climate.set_operation_mode
    data:
      operation_mode: Off
  - entity_id:  climate.warm_water
    service: climate.set_operation_mode
    data:
      operation_mode: Off

That is what I use.

Tag the source

Could you please tag the source? This allows distributions to get the complete source from GitHub if they want.

Thanks

New version on PyPi broken

I was trying to install version 0.2.6 from PyPi only to find out the internal package on PyPi is incorrect and the latest version that is correct is 0.2.3 .

Is it possible to upload a correct archive to PyPi for 0.2.6? Or is it because it's still labelled alpha? And when would it become the stable version?

Thanks! (Also thanks for maintaining this :)!)

_refresh_token connection reset exception

_http_session.request in _refresh_token may raise unhandled exceptions which flood Home Assistant logs.

2020-12-21 15:20:51 ERROR (MainThread) [homeassistant] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/lib/python3.8/ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/local/lib/python3.8/ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 531, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.8/site-packages/urllib3/packages/six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.8/socket.py", line 669, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/lib/python3.8/ssl.py", line 1241, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/local/lib/python3.8/ssl.py", line 1099, in read
    return self._sslobj.read(len, buffer)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/tado/__init__.py", line 108, in <lambda>
    lambda now: tadoconnector.update(),
  File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 239, in wrapper
    result = method(*args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/components/tado/__init__.py", line 198, in update
    self.update_sensor("zone", zone["id"])
  File "/usr/src/homeassistant/homeassistant/components/tado/__init__.py", line 207, in update_sensor
    data = self.tado.getZoneState(sensor)
  File "/usr/local/lib/python3.8/site-packages/PyTado/interface.py", line 176, in getZoneState
    return TadoZone(self.getState(zone), zone)
  File "/usr/local/lib/python3.8/site-packages/PyTado/interface.py", line 183, in getState
    data = self._apiCall(cmd)
  File "/usr/local/lib/python3.8/site-packages/PyTado/interface.py", line 60, in _apiCall
    self._refresh_token()
  File "/usr/local/lib/python3.8/site-packages/PyTado/interface.py", line 119, in _refresh_token
    response = self._http_session.request("post", url, params=data, timeout=self.timeout, data=json.dumps({}).encode('utf8'),
  File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

I created a PR home-assistant/core#44428, but they prefer this to be fixed here.

tado° API credentials

Hi,

I just got an email from Tado that they are changing their API.

Here is the email

Stefan Gaß (tado° Help Center)
30 jun. 13:56 CEST

Hello,

we have noticed that you are using tado° API. Even though it is not officially supported by us yet, we wanted to inform you about some upcoming breaking changes.

As you might already know, our APIs are authenticated by OAuth 2. We have recently migrated our own apps to new client credentials which uses client secret and we plan to discontinue the old credentials during next week.

Please make sure you migrate your API usages to this client credentials:

Client ID: public-api-preview
Client Secret: 4HJGRffVR8xb3XdEUQpjgZ1VplJi6Xgw

Also feel free to share these credentials with other developers. That way we will be able to easily distinguish our own apps from third party developers and make sure that the official public API will suit your needs.

Best regards,
Michal
Head of Server Development

Does this affect the PyTado implementation?

Cheers,
Ruben

Improve library reliability and quality (path to 1.0)

Intent

Hello everyone!

This post aims to support those interested in contributing to this remarkable library, whether by fixing bugs or adding new features. I hope to keep this issue open until the library meets all criteria for being considered well-tested and reliable. This is a crucial step, especially given its widespread use, including by 3.5% of active Home Assistant users and many developers working on it independently.

Moreover, some contributors may wish to address a bug or even report one, but without clear guidance and support, starting on the project can be daunting. We need to take steps to lower these barriers and facilitate contributions. @wmalgadey has been doing incredible work here, yet time is finite, and we may offer some level of support. Of course, there's no pressure to contribute!

Let's explore some baby steps we can take to enhance this library over time.

Path to 1.0

Our initial steps might include:

  1. Establishing contribution guidelines, tooling, and measure our progress towards our stability goals.
  2. Increase code coverage to prevent regressions or breaking changes.
  3. Ensuring Home Assistant Tado integration is well supported on features/fixes they need.

For Point (1), we could undertake the following tasks:

  • Update repository settings to establish some rules (merging, releases, actions, milestones, roadmap, etc.)
  • Create GitHub templates to assist contributors in reporting bugs or submitting PRs
  • Publish contribution guidelines to help newcomers with their first contributions (code standards, etc.)
  • Implement tooling (e.g., pre-commit hooks) to maintain standards and simplify the review process
  • Introduce coverage tools (Coveralls is a good enough option) to begin tracking our code coverage, aiming to improve it with each PR. Initially, code coverage will help us write all the basic tests. Subsequently, we will enhance reliability through regression testing and more specific tests (e.g., when the Tado API updates or adds new features). While reaching 100% doesn't mean much, it's still a good starting point.

For Point (2), we need contributors to start by writing at least one test for every new change. Although backfilling tests is beneficial, to me is far important that new fixes and features are covered by tests. We should use a "build over time" approach, no need to go heads down to eventually lose motivation and fun.

Point (3) is unknown to me at the moment, as there are known issues (some of which I've encountered), but it's unclear whether the solutions should be implemented in this library or directly within the integration.

Who can contribute?

Anyone with time to spare is welcome! Filling bug reports, performing code reviews, fixing bugs, writing documentation, communicating with HA Tado Integration contributors, etc., are just a few ways you can help.

As the proposer of these steps, I'm eager to take most of them, particularly all tasks related to Point (1) and some of Point (2).

How can I give feedback?

Please respond below! This post is a proposal, and feedback is what transforms a proposal into a strong one. So don't hesitate to contribute with your thoughts, and thank you in advance for any suggestions you may have!

A new request is created every api call

This has to load all the default ssl certs each request which makes this integration expensive cpu wise.

Ideally this could be refactored to take a requests Session() object and reuse it for all requests

Screen Shot 2020-02-29 at 10 46 00 AM

Release new version

Hi, thank you for taking over this project, there hasn't been a release for a long time, do you mind releasing a new version?
I'd like to use the new functionality that has been added :-)

Add geofencing

Thanks for your work, it works well (I'm using through Home Assistant).

It would be great to be able to disable geofencing (for exemple, when I have guests at home but I'm leaving).
The HTTP request is quiet simple, it's a DELETE request on presenceLock.

I can do the PR and so on but is the project still alive?

Mask access token

I think it might be a bad idea to write the full access token to the log (at the Information level). This library is used in the home assistant integration and outputs the following to the log ever x minutes (where I obviously replaced part of it by xxx):

2023-01-26 10:27:53.021 INFO (SyncWorker_13) [PyTado.interface] api call result: {"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdxxxx","token_type":"bearer","refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.xxxx","expires_in":599,"scope":"home.user","jti":"e1e7b208-9ffa-4127-a8e6-509351433ee2"}

I don't think the access and the refresh token should be in the logs at all, but if you think there is a good reason for, could you be so kind by doing that only in debug mode? Than you can opt-in to see them and the rest of the users get a little more secure.

It's just a matter of switching to _LOGGER.debug(...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.