Core: Unable to connect Tado bridge as HomeKit climate device

Created on 29 Sep 2018  Â·  110Comments  Â·  Source: home-assistant/core

Home Assistant release with the issue:
0.79.0

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):
Hass.io

Component/platform:
https://www.home-assistant.io/components/climate.homekit_controller/

Description of problem:
I am trying to add my Tado bridge to Home Assistant using the homekit_controller component. This would allow me to have offline control for my heating instead of using the tado API. Home Assistant throws an error when I try to pair the bridge in the UI. This is what I did:

  1. Reset HomeKit on the tado bridge so it's not connected to my iPad anymore. The devices disappeared from the Home app, so this seems to have worked.
  2. Add HomeKit discovery to my configuration.yaml and restart HA.
  3. Click "configure" on the "tado Internet Bridge" item in the UI.
  4. Enter the HomeKit code from the sticker on the bridge and click submit.

After a while the dialog closes end the stacktrace mentioned below appeared in the logs.

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

discovery:
  enable:
    - homekit

Traceback (if applicable):

Error executing service <ServiceCall configurator.configure (c:53514ee038d142deafe498967e874b70): configure_id=1825889744-2, fields=code=<<HomeKit code from sticker on device>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/core.py", line 1177, in _event_to_service_call
    await service_handler.func(service_call)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/configurator.py", line 224, in async_handle_service_call
    call.data.get(ATTR_FIELDS, {}))
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/homekit_controller/__init__.py", line 146, in device_config_callback
    pairing_id)
  File "/usr/local/lib/python3.6/site-packages/homekit/protocol.py", line 69, in perform_pair_setup
    connection.request('POST', '/pair-setup', request_tlv, headers)
  File "/usr/local/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1250, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/local/lib/python3.6/http/client.py", line 1108, in putrequest
    raise CannotSendRequest(self.__state)
http.client.CannotSendRequest: Request-sent

Additional information:

homekit_controller

Most helpful comment

Yep =) Pretty sure I can write a patch to fix this.

All 110 comments

I don't know how this is related to the tado component? Does a component have to have some special behaviors to support homekit?

It's indeed not related to the tado component. I was trying to add my homekit compatable tado thermostat using the homekit protocol. That would allow offline control of the thermostat, instead of depending on tado's web API.

I'm seeing the same problem. Entering HomeKit code does nothing
image

again homekit has nothing to do with tado!

As I tried to explain in my previous comment: this issue is indeed not about the tado component. It is about using the homekit_controller component to control a HomeKit compatible thermostat (that happens to be a tado) using the HomeKit protocol.

Maybe someone could remove the tado_component and climate.tado labels to make this clear 🙂

Tado has HomeKit support if you are using the new bridge. So I guess it is being discovered by discovery when having HomeKit enabled

Ahhhh now I understand the problem :)

@cgarwood the label of this issue should be platform: climate.homekit and component: homekit. We can't solve any problem here with the tado component, afaik!

I am having the same issue. "tado Internet Bridge" is discovered as homekit device, but entering the HomeKit code does nothing. There is no error message in the UI or in the logs, but when I enable debug logging, the following appears in the log:

`2019-03-25 09:29:22 DEBUG (SyncWorker_12) [root] #1 ios -> accessory: send SRP start request

2019-03-25 09:29:22 DEBUG (SyncWorker_12) [homekit.protocol.tlv] sending [
6: (1 bytes) 0x01
0: (1 bytes) 0x01
]
2019-03-25 09:29:22 DEBUG (SyncWorker_12) [homekit.protocol.tlv] receiving [
6: (1 bytes) 0x01
0: (1 bytes) 0x01
]
2019-03-25 09:29:22 DEBUG (SyncWorker_12) [root] write message: [
6: (1 bytes) 0x01
0: (1 bytes) 0x01
]`

Having this problem as well, I need the homekit discovery for some devices. But there is no way to ignore or setup this tado bridge one.

Very annoying as the persistant notification is very very persistant now. Any way to either configure it or just to ignore this device entirely?

Edit: so I found a way to ignore this from discovery. Go to ~/site-packages/homeassistant/components/homekit_controller/__init__.py

Add the following to the ignore list (it is on the top, Tradfri Hub is listed there as well)

tado Internet Bridge

It will be ignored upon reboot now and it will no longer put a persistent notification.

@cf00 Are there any more log messages after that?

All three of those log messages are produced by the same bit of code - its trying to send:

[
        (TLV.kTLVType_State, TLV.M1),
        (TLV.kTLVType_Method, TLV.PairSetup)
]

to the device. This is the pairing start command. The 6 in your log is kTLVType_State and the 0 is the kTLVType_Method. So far this is completely normal.

The tado bridge should then reply with an TLV.M2 message. It might be responding with an error code or it might enter pairing mode.

If you don't see this in your logs then the tado bridge is not replying at all:

#3 ios -> accessory: send SRP verify request

The connection might be rejected or too slow or there could be a problem with discovery.

@Jc2k No, there is nothing after that.

Would be really nice if this could be made to work. Currently, the only way to control the tado system is trough the cloud and this would allow local control.

Thanks for the reply. Do you have an iPhone to test it with so we can rule out weird networking issues?

Can you describe your environment a bit - is it arm/intel/etc? Docker? VM? Can you think of anything in your environment that’s non standard or weird?

Is it currently connected to the cloud? (Trying to rule out of the homekit functionality is somehow tied to the cloud being on or off).

Does everything work as expected through the cloud interface?

How comfortable are you with installing python packages outside of HA?

I use an iphone (not the one you responded to though). In my case everything works fine through the cloud. My environment is, Ubuntu 18.04 (desktop) on a Hyper-V server with HA installed in venv. In my particular case all is standard. (No weird stuff). I am perfectly comfortable with installing python packages outside of HA.

I know you weren’t asking me, however if there is a way to help I’d be willing to.

Thanks. Happy to have you help too if you can confirm you are in the same situation with the logs on latest HA (only one iOS -> accessory debug message)

I am at work now, but will figure out how to get those logs when I get back. In my particular case when trying to add the brigde in Home Assistant (where it asks for the homekit code), whenever I press submit nothing happens. (When looking at the console nothing happens either, in HA dev-tools there is nothing either)

So it is pretty strange, as I remember some time ago, that it would just throw errors in the console, but now it does absolutely nothing. Will check it again tonight.

Btw: I said nothing weird in my networking which is not entirely true. My network is in a domain (AD) and have dns/dhcp running on a windows server but I don’t think it would make a difference though.

Unfortunately I don't have an iPhone to test it (only android devices).

I am now running homeassistant in docker on Ubuntu 18.10 on an Intel NUC. Previously I used docker on a QNAP NAS and had the identical issue. Networking is somewhat non-standard I think, in that use a macvlan network for docker (so that the container has its own IP). This setup works flawlessly for everything else and as I had the same issue before with my previous setup, I doubt it is the problem.

The tado bridge is connected to the tado cloud (plugged directly into the router) and works as expected. I just checked the tado website, and it doesn't mention anything about homekit and cloud functionality interfering with each other (as far as the cloud is concerned, changing settings via homekit is supposed to be treated as if the user had changed a setting manually on a a device)

As for installing python packages, I am moderately incompetent at anything linux, but I can access a shell inside the container and I can follow (and copy&paste) instructions.

Are you sure about that? I got the gut feeling that even homekit only gives a command to the “cloud”. I have tried searching for offline capabilities, but when the internet is down, the tado things don’t work for me (haven’t tried homekit though whilst internet is down). But I could try to simulate an outage and see what happens.

Here are the steps to pair a homekit device on the command line entirely outside of HA. I'm doing this on a Mac where python3 is previously installed via Brew, should work on Linux more or less the same.

If you are running it from a Docker container, i'd probably go with an Ubuntu 18.04 one.

$ python3 -m venv homekit_test

$ source homekit_test/bin/activate

$ pip install "homekit[IP]==0.13.0"

$ python -m homekit.init_controller_storage -f test.json

$ python -m homekit.discover
Name: DemoAccessory._hap._tcp.local.
Url: http_impl://192.168.1.254:8085
Configuration number (c#): 67
Feature Flags (ff): No support for HAP Pairing (Flag: 0)
Device ID (id): ff:f0:00:00:00:00
Model Name (md): DemoAccessory
Protocol Version (pv): 1.0
State Number (s#): 1
Status Flags (sf): Accessory has not been paired with any controllers. (Flag: 1)
Category Identifier (ci): Lightbulb (Id: 5)

$ python -m homekit.identify -d ff:f0:00:00:00:00 --log DEBUG

$ python -m homekit.pair -f test.json -p 031-45-154 -a test -d ff:f0:00:00:00:00 --log DEBUG
2019-04-12 21:31:36,880 __init__.py:0108 DEBUG #1 ios -> accessory: send SRP start request
2019-04-12 21:31:36,881 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-12 21:31:36,884 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-12 21:31:36,884 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-12 21:31:36,926 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (384 bytes) 0xe13d364821d9beb8c2a48253cb748657bc64de9b7b5217fd3c9719fad276ace63ea8dce38e43c242590e74d8448cd5740b1326fe9784ee4567f4b34393c9d1aa146d88e885770d67bfb8c6ce73cee2ff8fe38537145e6172fcc2ca783f01fe5f76e3b07ad0e324c7d8a7e01e3c734bd553f5aa252d2fb2da287d8309d3fa4b3a5a384e887e1d3dd0fcbac27a4bfa037af5dc3717a87698e1d9ae202d4d092e4c86532b846aedf4094685952ca99696b6db4c0d2b786698700b4289f6b2b8c158e3a4c9accf07396008d168517bddba8d7b52359a982ba7b1524f06bffc60eedbd97898bcede7edbce025d4f7ec8b765969d909cdd458f6b8dc972e2e0f215a6a0a9cde161c26781c1746bf4202b427a7a6553e6ebfdc466c05366c370cd0092c5dab811f2ba92059aea92f53e65ffa10c98d800d970cc47e1357b4cbc4fc9cfca0ef9d8b14aebf943efd3cf21904ea1aef41a8044088548dbbce47fbaa1d3e18371fe779b960e1d8b44a0825e7cdf9be5b07b0c1b9b55a01ca8ffd4bf14e3de5
  2: (16 bytes) 0x65685766785a4d6a774566593954486c
]

2019-04-12 21:31:36,926 __init__.py:0068 DEBUG response: [
  6: (1 bytes) 0x02
  3: (384 bytes) 0xe13d364821d9beb8c2a48253cb748657bc64de9b7b5217fd3c9719fad276ace63ea8dce38e43c242590e74d8448cd5740b1326fe9784ee4567f4b34393c9d1aa146d88e885770d67bfb8c6ce73cee2ff8fe38537145e6172fcc2ca783f01fe5f76e3b07ad0e324c7d8a7e01e3c734bd553f5aa252d2fb2da287d8309d3fa4b3a5a384e887e1d3dd0fcbac27a4bfa037af5dc3717a87698e1d9ae202d4d092e4c86532b846aedf4094685952ca99696b6db4c0d2b786698700b4289f6b2b8c158e3a4c9accf07396008d168517bddba8d7b52359a982ba7b1524f06bffc60eedbd97898bcede7edbce025d4f7ec8b765969d909cdd458f6b8dc972e2e0f215a6a0a9cde161c26781c1746bf4202b427a7a6553e6ebfdc466c05366c370cd0092c5dab811f2ba92059aea92f53e65ffa10c98d800d970cc47e1357b4cbc4fc9cfca0ef9d8b14aebf943efd3cf21904ea1aef41a8044088548dbbce47fbaa1d3e18371fe779b960e1d8b44a0825e7cdf9be5b07b0c1b9b55a01ca8ffd4bf14e3de5
  2: (16 bytes) 0x65685766785a4d6a774566593954486c
]

2019-04-12 21:31:36,926 __init__.py:0120 DEBUG #3 ios -> accessory: send SRP verify request
2019-04-12 21:31:36,969 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xe26fa60c00933e27c616aa4b5d1c2bfc5c7cbfa2b587ed3d0d0f2b4c5295dc0340b1abf4f07fadc567bdf28096d33630679baaa5e7399678f64c1c2d44525ef26867aefa04b2c0f6a220beacc0cdcd38fb9bbdd9c8f23c16d10a7caf5856baea8dd3d18cc614fa122d887353489adc3f531404d3963cfa4b0817f168544ea365772e25e3f1a76702ca3a518ede9e021a1f0537955c530cc2b6c6c0310f4a40cf21e972051f761513c3e9290660b20c3956c0620d821a94ccc90a8925bca44da3f77d1d80e414bd939c10d88d02ac88b48a3be9f82e2b6c5a268b14576ede2692e3b8ab501187caf62d100daf9781a61122bd78dfc4ff68a2a565608e781f05e51b09dfd0661f6357f26100b2e4acd4798ba2f5935315b8cb6c8e3fbf7fb9b9b395213d083ccfb94f21da6c210ecdf3da9685817988678b3038dff457c709c1e5a65bed40ba6a8c4106c877008fd4d1559f7bd0dfb82131480f3796f31b7bae2dc7957e03c1924b263a070eab373638d5b7d313dd7cacdc3c0cf36f2e07f529bf
  4: (64 bytes) 0xa08e93477fed158e16e27bac4d25aef5f03d89f4529c4fafbbd43c5330672e8b52c8f4eaf6e324d4d4ce3737ebd24bd43041bb9ed87a0cab2a650e20388e9c37
]

2019-04-12 21:31:36,969 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xe26fa60c00933e27c616aa4b5d1c2bfc5c7cbfa2b587ed3d0d0f2b4c5295dc0340b1abf4f07fadc567bdf28096d33630679baaa5e7399678f64c1c2d44525ef26867aefa04b2c0f6a220beacc0cdcd38fb9bbdd9c8f23c16d10a7caf5856baea8dd3d18cc614fa122d887353489adc3f531404d3963cfa4b0817f168544ea365772e25e3f1a76702ca3a518ede9e021a1f0537955c530cc2b6c6c0310f4a40cf21e972051f761513c3e9290660b20c3956c0620d821a94ccc90a8925bca44da3f77d1d80e414bd939c10d88d02ac88b48a3be9f82e2b6c5a268b14576ede2692e3b8ab501187caf62d100daf9781a61122bd78dfc4ff68a2a565608e781f05e51b09dfd0661f6357f26100b2e4acd4798ba2f5935315b8cb6c8e3fbf7fb9b9b395213d083ccfb94f21da6c210ecdf3da9685817988678b3038dff457c709c1e5a65bed40ba6a8c4106c877008fd4d1559f7bd0dfb82131480f3796f31b7bae2dc7957e03c1924b263a070eab373638d5b7d313dd7cacdc3c0cf36f2e07f529bf
  4: (64 bytes) 0xa08e93477fed158e16e27bac4d25aef5f03d89f4529c4fafbbd43c5330672e8b52c8f4eaf6e324d4d4ce3737ebd24bd43041bb9ed87a0cab2a650e20388e9c37
]

2019-04-12 21:31:36,969 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xe26fa60c00933e27c616aa4b5d1c2bfc5c7cbfa2b587ed3d0d0f2b4c5295dc0340b1abf4f07fadc567bdf28096d33630679baaa5e7399678f64c1c2d44525ef26867aefa04b2c0f6a220beacc0cdcd38fb9bbdd9c8f23c16d10a7caf5856baea8dd3d18cc614fa122d887353489adc3f531404d3963cfa4b0817f168544ea365772e25e3f1a76702ca3a518ede9e021a1f0537955c530cc2b6c6c0310f4a40cf21e972051f761513c3e9290660b20c3956c0620d821a94ccc90a8925bca44da3f77d1d80e414bd939c10d88d02ac88b48a3be9f82e2b6c5a268b14576ede2692e3b8ab501187caf62d100daf9781a61122bd78dfc4ff68a2a565608e781f05e51b09dfd0661f6357f26100b2e4acd4798ba2f5935315b8cb6c8e3fbf7fb9b9b395213d083ccfb94f21da6c210ecdf3da9685817988678b3038dff457c709c1e5a65bed40ba6a8c4106c877008fd4d1559f7bd0dfb82131480f3796f31b7bae2dc7957e03c1924b263a070eab373638d5b7d313dd7cacdc3c0cf36f2e07f529bf
  4: (64 bytes) 0xa08e93477fed158e16e27bac4d25aef5f03d89f4529c4fafbbd43c5330672e8b52c8f4eaf6e324d4d4ce3737ebd24bd43041bb9ed87a0cab2a650e20388e9c37
]

2019-04-12 21:31:37,030 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
  4: (64 bytes) 0xc489cc99cfb0c1f7096811d3a8473408828f0ff51957a63db293676a863528d5b92202cb7cd3c83e3942a1b3f6b5f451047d038fc9e5bc5bf64bb6c6e37b79ef
]

2019-04-12 21:31:37,030 __init__.py:0068 DEBUG response: [
  6: (1 bytes) 0x04
  4: (64 bytes) 0xc489cc99cfb0c1f7096811d3a8473408828f0ff51957a63db293676a863528d5b92202cb7cd3c83e3942a1b3f6b5f451047d038fc9e5bc5bf64bb6c6e37b79ef
]

2019-04-12 21:31:37,030 __init__.py:0171 DEBUG #5 ios -> accessory: send SRP exchange request
2019-04-12 21:31:37,148 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'8c811e54-1163-4ee9-8ca3-8c7de1487a4f'
  3: (32 bytes) b'3\xf8,\xe8,v[\xa2\xbf\xb9\x15\x06a\x84ad\xb0\xce\x86*&\x03\n\xb1\xef\xef\x94\xe9Uq1\xe7'
  10: (64 bytes) b'\xd3\xbe\t\xd9\x0cj,\xf0\x13\xa6\xbc\x9e\xf9F\xfcEe\xd6\xc8b\xd5\xf0\xf0\x88\xb9\xb9\xfa\xda\x07d\xcd\x84%P\x10\x02\x9e\x9e\x08\xf3\x07\x82\xfd=\xd0b\xb7\xfc\x98\x07)+I6RJ\x82T\xfco%\xa1i\x01'
]

2019-04-12 21:31:37,150 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xadea234c19f4f498b2837067abbef1e3ff1270402b9d7597cab187d741e6dffb820326e364e9e49416a5e51124e3f52fd063ac27a51e9fd4cf32d5054221dfb645a13e630c94b3b8a221d9c3c33891f431afc9294bd95aad94b0b082285aa971920953d4f969cfed6d8039277f5a96108f1f8281824145a429015d1d1d32c19a576dd74749666ed795cf9c06776428a8d10c732d9c667696cc23
]

2019-04-12 21:31:37,151 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xadea234c19f4f498b2837067abbef1e3ff1270402b9d7597cab187d741e6dffb820326e364e9e49416a5e51124e3f52fd063ac27a51e9fd4cf32d5054221dfb645a13e630c94b3b8a221d9c3c33891f431afc9294bd95aad94b0b082285aa971920953d4f969cfed6d8039277f5a96108f1f8281824145a429015d1d1d32c19a576dd74749666ed795cf9c06776428a8d10c732d9c667696cc23
]

2019-04-12 21:31:37,151 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xadea234c19f4f498b2837067abbef1e3ff1270402b9d7597cab187d741e6dffb820326e364e9e49416a5e51124e3f52fd063ac27a51e9fd4cf32d5054221dfb645a13e630c94b3b8a221d9c3c33891f431afc9294bd95aad94b0b082285aa971920953d4f969cfed6d8039277f5a96108f1f8281824145a429015d1d1d32c19a576dd74749666ed795cf9c06776428a8d10c732d9c667696cc23
]

2019-04-12 21:31:38,240 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x3935b5c4930fc0662a40b6aeaa3e00949226612c323cea5927a5ef561fb087a88a7c1d7c702dbd203c213b129f00adb90e085849df604c6db928ecf25e5e472da612d6df57bbb89b2b81d71cf8f718253f740e5ad580ca28a1a5999ba037b82263799ccf44f01bbca5ab899be9d1b9fe9328094784a92eb7d6ed0244349a9ed23264ee6b837495
]

2019-04-12 21:31:38,241 __init__.py:0068 DEBUG response: [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x3935b5c4930fc0662a40b6aeaa3e00949226612c323cea5927a5ef561fb087a88a7c1d7c702dbd203c213b129f00adb90e085849df604c6db928ecf25e5e472da612d6df57bbb89b2b81d71cf8f718253f740e5ad580ca28a1a5999ba037b82263799ccf44f01bbca5ab899be9d1b9fe9328094784a92eb7d6ed0244349a9ed23264ee6b837495
]

2019-04-12 21:31:38,245 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x66663a66303a30303a30303a30303a3030
  3: (32 bytes) 0xdaaf0d8f58130830efe7aaaefbd7fc2ed08075a9210aef1bed60bac0c1537a90
  10: (64 bytes) 0xdc44351e094ec9154ef63d57990d5d0e4b2c1ccc62ac0b0256302ffdca413427a1b846f9005eb19ee0d06adbea0c88309b2afd2cd1ced4d392ab5ec1bf245207
]

2019-04-12 21:31:38,286 ip_implementation.py:0399 DEBUG init session
2019-04-12 21:31:38,451 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'lu\xf0a:\xf9\x854\x8b\x05\x18\xbf\xb8|\x82{\xd3\x9a\x11\x0e\x08\x14\xce*>^\x03\xbbB\x13\xe6Z'
]

2019-04-12 21:31:38,451 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x6c75f0613af985348b0518bfb87c827bd39a110e0814ce2a3e5e03bb4213e65a
]

2019-04-12 21:31:38,451 __init__.py:0076 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x6c75f0613af985348b0518bfb87c827bd39a110e0814ce2a3e5e03bb4213e65a
]

2019-04-12 21:31:38,496 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x067658394b89dd5c5740e47b57f39d2897b2e6ba595e3da8791c645a35d0f94a
  5: (101 bytes) 0xcb50c52b604f25fb7c64ae3fc2c5fd72ba9e6852130401f6dc4e88b5388165c9081274ca0cf598d2b29c211b5d62d1d8370a04513327e51e510864cf4163d4a3832a002d7140476b9cd9852a143792e1c6fde36b64b47539deb57981a9df3d84e22218cfa6
]

2019-04-12 21:31:38,497 __init__.py:0084 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x067658394b89dd5c5740e47b57f39d2897b2e6ba595e3da8791c645a35d0f94a
  5: (101 bytes) 0xcb50c52b604f25fb7c64ae3fc2c5fd72ba9e6852130401f6dc4e88b5388165c9081274ca0cf598d2b29c211b5d62d1d8370a04513327e51e510864cf4163d4a3832a002d7140476b9cd9852a143792e1c6fde36b64b47539deb57981a9df3d84e22218cfa6
]

2019-04-12 21:31:38,498 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x66663a66303a30303a30303a30303a3030
  10: (64 bytes) 0xe3b8be49ba2e99c780d4da9238d98773a3d7a0861e6716f9fd2a03921a6480a524f46e9f43991999ecae5edc0609572922b89b43c5e731c064a9a5d79f4fcc01
]

2019-04-12 21:31:38,500 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'8c811e54-1163-4ee9-8ca3-8c7de1487a4f'
  10: (64 bytes) b'tS\x0c..\xb7\xba/=\xe1\x1f\x97\xef\xc41j\xba\xf7<\xa5\xb2\xf5\xecx\xac\xce\xdf~{\xf9\xda2W\xa0Y?\x8aW^g\x91,\\\xc6;\xf5\x97\x1c?{q\xb9^\x05\x1b7\xed\x8c\xaes\xfd\xafq\x07'
]

2019-04-12 21:31:38,501 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x290e654ba597f4b3bec256d49c074268aaf430f4dba87febd6ffba9272b25b638e979fe3ff98ffbce3b30cb1da89da22b177cfffb76e18c5b5d04bf534b5c2cf14237881e351040e1cf9ec739b7d3860f81bdf2a3641b1935357788255ea798588f2521875b753847aa6446e8a5075218ececbd6f692c707
]

2019-04-12 21:31:38,501 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x290e654ba597f4b3bec256d49c074268aaf430f4dba87febd6ffba9272b25b638e979fe3ff98ffbce3b30cb1da89da22b177cfffb76e18c5b5d04bf534b5c2cf14237881e351040e1cf9ec739b7d3860f81bdf2a3641b1935357788255ea798588f2521875b753847aa6446e8a5075218ececbd6f692c707
]

2019-04-12 21:31:38,502 __init__.py:0076 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x290e654ba597f4b3bec256d49c074268aaf430f4dba87febd6ffba9272b25b638e979fe3ff98ffbce3b30cb1da89da22b177cfffb76e18c5b5d04bf534b5c2cf14237881e351040e1cf9ec739b7d3860f81bdf2a3641b1935357788255ea798588f2521875b753847aa6446e8a5075218ececbd6f692c707
]

2019-04-12 21:31:38,505 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-12 21:31:38,505 __init__.py:0084 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-12 21:31:38,505 ip_implementation.py:0426 DEBUG session established
Pairing for "test" was established.

I kind of expect the same result as HA - that it hangs shortly after

#1 ios -> accessory: send SRP start request

If it does then we have ruled out an interaction with HA code and i'll need to have a think about next steps. Might involve tcpdump...

(Obviously you'll need to change the homekit id from ff:f0:00:00:00:00 to whatever is in homekit.discover's output, and change the pin too).

Especially interested in the output of the discover and pair commands.

@jimz011 I am not really sure, that's why I would like to see this work to test it :-) But the last time tado servers were down for a couple of hours, I remember that tado was asked on twitter about local control. They replied that the system currently does not allow for local control (and they wouldn't give any info if it was a planned feature) but they mentioned that local control is currently only possible via homekit. That gave me the idea to try the homekit componenet in homeassistant in the first place.

Ok, here are my results.

(homekit_test) root@ha:/usr/src/app# python -m homekit.discover
Name: tado Internet Bridge IBXXXXXXXXXX._hap._tcp.local.
Url: http_impl://10.X.X.101:3000
Configuration number (c#): 6
Feature Flags (ff): Supports HAP Pairing (Flag: 1)
Device ID (id): a3:d1:5e:1f:6c:03
Model Name (md): tado Internet Bridge
Protocol Version (pv): 1.0
State Number (s#): 1
Status Flags (sf): Accessory has not been paired with any controllers. (Flag: 1)
Category Identifier (ci): Bridge (Id: 2)

(homekit_test) root@ha:/usr/src/app# python -m homekit.identify -d a3:d1:5e:1f:6c:03 --log DEBUG
No response. I interrupted it after waiting 5 minutes.

(homekit_test) root@ha:/usr/src/app# python -m homekit.pair -f test.json -p XXX-XX-XXX -a test -d a3:d1:5e:1f:6c:03 --log DEBUG
2019-04-12 23:08:50,080 __init__.py:0111 DEBUG #1 ios -> accessory: send SRP start request
2019-04-12 23:08:50,080 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-12 23:08:50,081 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-12 23:08:50,082 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

Nothing after that. ^C after 5 minutes.

Ok - thats good in that it proves its not anything in the HA code. But bad in that we are not any closer to understanding it.

Let's try poking it from outside of the library altogether. HomeKit is HTTP based so we can poke some of it without anything more than curl. Here is the HomeKit interface for a Phillips Hue.

$ curl --verbose 192.168.X.X:8080/accessories
*   Trying 192.168.X.X...
* TCP_NODELAY set
* Connected to 192.168.X.X (192.168.X.X) port 8080 (#0)
> GET /accessories HTTP/1.1
> Host: 192.168.X.X:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 470 Connection Authorization Required
< Content-Length: 21
< Content-Type: application/hap+json
< 
* Connection #0 to host 192.168.1.5 left intact
{ "status" : -70401 }

(The 70401 error means its not a secure session, but it proves it spoke HTTP to the device).

Again, i'm expecting it to hang or timeout here.

Also, heres a little python script that will verify the bonjour addresses are all connectable. In particular, this will try the ipv6 addresses. This is one of the few known differences I can think of with the Apple implementation that could cause the behaviour we are seeing.

from zeroconf import ServiceBrowser, Zeroconf
import socket

class MyListener:

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        print("service: %s"  % name)

        result = socket.getaddrinfo(
            info.server,
            info.port,
            proto=socket.IPPROTO_TCP,
        )

        for (family, type, proto, canonname, sockaddr) in result:
            print("server: %s, %s, %s" % (info.server, info.port, sockaddr))

            try:
                s = socket.socket(family, type, proto)
                s.settimeout(10)
                s.connect(sockaddr)
            except Exception as e:
                print("error: %s, %s" % (sockaddr, e))
                continue
            print("connection: %s" % (sockaddr, ))


zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_hap._tcp.local.", listener)
try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()

Drop this in a file like listener.py and run it in the same virtualenv you set up before. e.g.

$ source homekit_test/bin/activate
$ python listener.py

Output will be something like:

Press enter to exit...

service: Philips hue - 371433._hap._tcp.local.
server: Philips-hue.local., 8080, ('fe80::217:88ff:fe48:2544%en0', 8080, 0, 8)
connection: ('fe80::217:88ff:fe48:2544%en0', 8080, 0, 8)
server: Philips-hue.local., 8080, ('192.168.1.5', 8080)
connection: ('192.168.1.5', 8080)

No ipv6 addresses here:

Press enter to exit...

service: tado Internet Bridge IB3183151360._hap._tcp.local.
server: tadoBridgeIB3183151360.local., 3000, ('10.6.6.101', 3000)
connection: ('10.6.6.101', 3000)
service: Philips hue - A58C06._hap._tcp.local.
server: Philips-hue.local., 8080, ('10.6.6.106', 8080)
connection: ('10.6.6.106', 8080)

btw I also tried the pair command with the hue bridge now and it was paired successfully.

And here the output of a curl command. It seems to connect but there is no response.

$ curl --verbose 10.6.6.101:3000
* Rebuilt URL to: 10.6.6.101:3000/
*   Trying 10.6.6.101...
* TCP_NODELAY set
* Connected to 10.6.6.101 (10.6.6.101) port 3000 (#0)
> GET / HTTP/1.1
> Host: 10.6.6.101:3000
> User-Agent: curl/7.61.0
> Accept: */*
>

OK current theories in play:

  • We connect OK and send something the tado doesn't like.
  • The tado replies to our request but we can't parse its response for some reason - we block waiting for more data to arrive, but tado has done sending.
  • For some reason the tado only works on ipv6 (the HA code looks like it only supports ipv4, and apparently one there was a thing about tado devices needing ipv6 capable chips to do homekit. bit of a long shot).

To help diagnose the first 2 of these I have updated listener.py:

from zeroconf import ServiceBrowser, Zeroconf
import socket

HTTP_HEADER = """
POST /pair-setup HTTP/1.1
Host: %s
Content-Length: 6
Content-Type: application/pairing+tlv8
""".strip().replace("\n", "\r\n") + ("\r\n" * 2)

HTTP_PAYLOAD = b"\x06\x01\x01\x00\x01\x01"

class MyListener:

    def add_service(self, zeroconf, type, name):
        info = zeroconf.get_service_info(type, name)
        print("service: %s"  % name)

        if "tado" not in name:
            print("SKIPPING")
            return

        result = socket.getaddrinfo(
            info.server,
            info.port,
            proto=socket.IPPROTO_TCP,
        )

        for (family, type, proto, canonname, sockaddr) in result:
            print("server: %s, %s, %s" % (info.server, info.port, sockaddr))

            s = socket.socket(family, type, proto)

            try:
                s.settimeout(10)
                s.connect(sockaddr)
            except Exception as e:
                print("error connecting: %s, %s" % (sockaddr, e))
                continue
            print("connection: %s" % (sockaddr, ))

            payload = (HTTP_HEADER % name.rstrip(".")).encode("utf-8") + HTTP_PAYLOAD
            print(payload)
            s.send(payload)

            buffer = b''
            try:
                next = s.recv(1024)
                while next:
                    buffer += next
                    next = s.recv(1024)
            except socket.timeout:
                print("TIMEOUT RECV: %s" % buffer)
                continue

            print(buffer)


zeroconf = Zeroconf()
listener = MyListener()
browser = ServiceBrowser(zeroconf, "_hap._tcp.local.", listener)
try:
    input("Press enter to exit...\n\n")
finally:
    zeroconf.close()

It sends a payload based on packet dumps of what an iPhone sends to pair with an accessory, and it will print the entire response, it doesn't try to parse it. I tweaked it to only target your todo and not your Hue.

Note that the connection will be left open and timeout after 10s (no parsing means can't see when full message has been sent) so will take longer to run this time.

It does look like the homekit client isn't byte for byte perfect - there are 2 differents in the initial handshake:

  • Extra HTTP Header (Accept-Encoding: identity)
  • Host header is set to ip:port, iPhone sends Bonjour service name

So it could be this variation that the tado doesn't like...

$ python listener.py
Press enter to exit...

service: tado Internet Bridge IB3183151360._hap._tcp.local.
server: tadoBridgeIB3183151360.local., 3000, ('10.6.6.101', 3000)
connection: ('10.6.6.101', 3000)
b'POST /pair-setup HTTP/1.1\r\nHost: tado Internet Bridge IB3183151360._hap._tcp.local\r\nContent-Length: 6\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x00\x01\x01'
TIMEOUT RECV: b'HTTP/1.1 200 OK\r\nContent-Length:409\r\nContent-Type:application/pairing+tlv8\r\n\r\n\x06\x01\x02\x03\xff\xa2\x0bM\x17\xf8\xcd\xf0mz6`\xb66\x96\xaa\xe0_\x14\xb1\xdf\xc3\xcb)\x05\x95\xb4\xc3\xb5\xbe\xed5\xfe\'\xc2\x94\xbea\x84\x85w\xac\xe3\xe2F\x89\x82\xaa0\xad\x99\x1bx,\xde\x16\x9d\x93\\v{\xbe\xa87\xfb\xc0\xf6\xad\x8f \xce\xbd\x90\xb1\x17[W\xb4&\xeaN\'\xe6\xbcTo0\xe2\xbf\xb0\x04C\xc6Y\xb0\x08\xf3\xc9\x14\xbdW\xc0\x14\x82&\xc1\x85\x0eH8\xc2`\xfaXY\xbd\x01\\\xee$Yy\x9e\x97\xe1\x94\xb5\x80\xb6\xa3\x8c\x9c2\x8e3\x08\xd3\xd6\xc2\xffI\x1bJ\xf2\x11\x1b\x86\xe3\xe2\x19\xa7\xeb\xe7J\xdd*fX{\xd1\xdbw\x95KB\xf1\x04\xf0pz\nZ_\x9e\x04`e\x83(5!\x0fDC\x0c\xe0"\x13\xed\xabd49\x0c\xfc\x96\x1d\xfc\xa8\x91;G\xfe\x01\xff8\x17\xc0i\xc7u\x94S\x15\x1d\x9b\xeby\xc8\x14\xb1\'\xdd\xe39\x81\x81\xe3\x0f\x81\xe4\xe4\xb4n:\xe6l\x02\xad{(]\xc1\xec\xc8\xcd\xad\xe0m&\xca\x81\xcb\xc1\xf4\x1e\x03\x81\x89\t*t\xd2\xd0\xc9\xe6e\xce\xc7\xe7\xb3\x98\xaai\x9d\xa6\xbbp\x9d4\xda\x18\xbf\xa5M\xbd\xa8\xee\x01\xce~%\xabe\xaa\xac\xc9)w\xb6\xcb\x1f\xe2\xa4\x1av\xc3\xe9\xfem\xf6|\x91,L\x9f\xfb\xae\x96\xa5\xf2\x84\x02\xc2s\xb7\xa6\xb3U\x95\x0f;\xe9#\xc9m\xaa\x96}\xc1\x19\x17\x7f\\\x93\xba\x8dW\x11\xca\x8dh\xa4=\xb0m\xf8\x8c#\xba\xcd0\xd1\xad@L\xb7`5e\x00\xc0\xeeLC4T.\xb5\xbes\x90\xc1,\x94\xf7\xa9\x02\x10\xa0\x91-F\x7f\xd0R(\xf5\xe8\xd4Q\\\xd87\xab'

OK two changes to try. First, change the HTTP_HEADER bit from:

Host: %s
Content-Length: 6
Content-Type: application/pairing+tlv8

Make it

Host: %s
Accept-Encoding: identity
Content-Length: 6
Content-Type: application/pairing+tlv8

And try again

$ python listener.py
Press enter to exit...

service: Philips hue - A58C06._hap._tcp.local.
SKIPPING
service: tado Internet Bridge IB3183151360._hap._tcp.local.
server: tadoBridgeIB3183151360.local., 3000, ('10.6.6.101', 3000)
connection: ('10.6.6.101', 3000)
b'POST /pair-setup HTTP/1.1\r\nHost: tado Internet Bridge IB3183151360._hap._tcp.local\r\nAccept-Encoding: identity\r\nContent-Length: 6\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x00\x01\x01'
TIMEOUT RECV: b''

So the python library is sending an extra header that it doesn't understand and its not replying because of that. Let's just make sure. Go back to the previous version without the Accept-Encoding change (i.e. as it was in https://github.com/home-assistant/home-assistant/issues/16971#issuecomment-482843011).

Then change this line:

payload = (HTTP_HEADER % name.rstrip(".")).encode("utf-8") + HTTP_PAYLOAD

for

payload = (HTTP_HEADER % "10.6.6.101:3000").encode("utf-8") + HTTP_PAYLOAD

I got lazy and hardcoded it, but thats the format that the python currently uses for the Host header. Hopefully it still has some output after the timeout with this variant.

Yes, the output is still there.

So, I guess that's good news in that you at least know what the problem seems to be ...

$ python listener.py
Press enter to exit...

service: Philips hue - A58C06._hap._tcp.local.
SKIPPING
service: tado Internet Bridge IB3183151360._hap._tcp.local.
server: tadoBridgeIB3183151360.local., 3000, ('10.6.6.101', 3000)
connection: ('10.6.6.101', 3000)
b'POST /pair-setup HTTP/1.1\r\nHost: 10.6.6.101:3000\r\nContent-Length: 6\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x00\x01\x01'
TIMEOUT RECV: b'HTTP/1.1 200 OK\r\nContent-Length:409\r\nContent-Type:application/pairing+tlv8\r\n\r\n\x06\x01\x02\x03\xff;\x87\xdf\xa7\xfb\xcfu\x83P\xe9\xd7\xf4S\xcf\x19c\xd9K\x0b\xe8z\xf3\x12\xdb`\xff\x14]g\x9b\xebl\xb6[\xfe-X\xb8\xban$\x99\x0b\xe2"2s\xff\xedr\x05Y\xbd\x9c\xa5Kw\xbc\x90wd\xad,\xb5\xe2\x8b=\x9b\x07k\x08\x00B\xd2w\xa6\x80R\xb6Y\xa2\xc4\x06\xadM\xbdp\x84(\x16\x9cO\xc1\xd61\x88`\x14\x8e\xe4=\xa5\'\x9c9\xeb\x14\xe9\xc3\xad\xb9)\xa5n\xa5\x01\x82\x18:aN\x89\xd00\xd2Y2Vb\xa4\x92\x8eh\x8a\x0ebk\xc2"\xa4\xbe\xfe\x9f\xf9v\xde\xfa\xb4f\x8a\xfe)x\x00N41\xc9\x7f\xda\x94\xe0H9\xb2\x13\x07h\x0c\xfe\xda\xd2\xa6\xf9\xb6\xcb\xaa%\xd8\xa5Z9\xce\x82,hc\x16{\xb9\x9f\xa1m\xd2\xd8\x92=\xb1\x8e\xc6\x95\xe1\xa5*\xa12K;\xbf/\xaa\x9ah\x9f=\xb1\x08\xe7\x01\xdc\x18\xbe\xf3\t\xfbU\x14PR\x13\x0c\xa53\xadq\xe6\xa1G\x94\x8d!x\xa0\x92\x9a\xf5}\xccH\xbf\x9b\xb3\xe5\xd3D\x03\x81eY\xc9\x0f\x917\xec\x95\x10\x13\x98\xa1\xeca\r\r\xd8\xb0M\xbd\x01\xe1\x8em\x03\x9e\x1acn3\x00t\x80\xb5\xcc@\xbf\x8d\xc3\xb4\xce\xef\xf7\xf36\x05sV\x1f\xc7\x02\xf3\x15\xae\xc7\x7fDy;F\xf3\xdc\x8f\xcc-\x87\x05\x11\xbf!u\x0c\xccwE\x85o\xef\xd9n\x86\xc6F\xd5\xe8}\x8a\xf9\xe0\x1f$\x84\xe6\x8eaW1\x99\x9a\xb0k`1x\xc0Qb\x93L\xa9\n\xb8\x91\x18\\\xbe\x18i|^Pc\xed\xaa\xdb*\xc0\xc2\x81\x02\x10\xa0\x91-F\x7f\xd0R(\xf5\xe8\xd4Q\\\xd87\xab'

Yep =) Pretty sure I can write a patch to fix this.

Great! Thanks for your help and your efforts.

As at total noob in those things: how long until I can use it in homeassistant to manage my heating? :-)

I need to write the patch, i'll need you to test it, i'll need to get it merged into homekit_python, then get a new homekit_python released, then open a PR to point HA at the new release of homekit_python, then wait for that to get reviewed and merged, and from then it will be up to 2 weeks or so for it to appear in a tag :-/ So, anything from 2 to 6 weeks at this stage!

Noticed that the pairing code is different to the code for actually talking over a secure session so may have to make changes there too :-/

OK, pairing patch attempt 1:

$ source venv/bin/activate
$ pip install -U https://github.com/Jc2k/homekit_python/archive/fix_tado_bridge.zip

It should say its uninstalled the old homekit and installed the new one.

Then try pairing again as in previous comment -> https://github.com/home-assistant/home-assistant/issues/16971#issuecomment-482720750

(Annnnd just pushed a fix for python 3.5, too)

Seems like progress to me, but there is an error at the end ...

$ python -m homekit.pair -f test2.json -p XXX-XX-XXX -a test -d a3:d1:5e:1f:6c:03 --log DEBUG
2019-04-13 22:49:18,372 __init__.py:0106 DEBUG #1 ios -> accessory: send SRP start request
2019-04-13 22:49:18,372 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-13 22:49:18,374 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-13 22:49:18,374 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-13 22:49:19,527 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (384 bytes) 0x1bc6fc36d2488e408a54d850d10e73a468d51ea81413276d959f4b787e7e2d2ab355001727183db4ec09d5299938f61d4fb7f436ff983156390220bf71f67683ef153aaa38eb33ca04b8de2c7669cbe6a4742eb66a32bd977de8ac469bc99c513b1cb708d977d1d5cce822fc630695d9e7d300b9dbe961eccd5f47c0a22be81b2ec3851558b643f2bbdc1b6828ddd411753b96674ad2ba985bba73642dbefc1bcd4c2ad6ce6de91d4862d50b7a2e9ae6462d550c096a71f7d5dbd4f6c4af00f1ddd98660ccefed388783186f4cec0670a7c80504316c2530f1eb57bd000376c4670627dc9a2ac85424eaf687fe18a2e8f5a5e7c2091e6752327170ba3cb7bda0ab1156deef4194e0cb81b3fe021229103c7bc76d15a72481e9156a27d2aa4aa9d23c521824c845c98f7191e461e5158c47429afa4a6b052ba3984808c9cc52995211e3202bc67107f23e64521e84f0585b10c8e9007afdbe19cf5fe8ab9e18e0c6227faa8d3987275c7e31e8c398cb19af50205db05cc14e375a029c3454b332
  2: (16 bytes) 0xa0912d467fd05228f5e8d4515cd837ab
]

2019-04-13 22:49:19,528 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x02
  3: (384 bytes) 0x1bc6fc36d2488e408a54d850d10e73a468d51ea81413276d959f4b787e7e2d2ab355001727183db4ec09d5299938f61d4fb7f436ff983156390220bf71f67683ef153aaa38eb33ca04b8de2c7669cbe6a4742eb66a32bd977de8ac469bc99c513b1cb708d977d1d5cce822fc630695d9e7d300b9dbe961eccd5f47c0a22be81b2ec3851558b643f2bbdc1b6828ddd411753b96674ad2ba985bba73642dbefc1bcd4c2ad6ce6de91d4862d50b7a2e9ae6462d550c096a71f7d5dbd4f6c4af00f1ddd98660ccefed388783186f4cec0670a7c80504316c2530f1eb57bd000376c4670627dc9a2ac85424eaf687fe18a2e8f5a5e7c2091e6752327170ba3cb7bda0ab1156deef4194e0cb81b3fe021229103c7bc76d15a72481e9156a27d2aa4aa9d23c521824c845c98f7191e461e5158c47429afa4a6b052ba3984808c9cc52995211e3202bc67107f23e64521e84f0585b10c8e9007afdbe19cf5fe8ab9e18e0c6227faa8d3987275c7e31e8c398cb19af50205db05cc14e375a029c3454b332
  2: (16 bytes) 0xa0912d467fd05228f5e8d4515cd837ab
]

2019-04-13 22:49:19,528 __init__.py:0118 DEBUG #3 ios -> accessory: send SRP verify request
2019-04-13 22:49:19,604 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xb75b048cd845f409f079b448cd37612aad7d92bdb89393c1473dc2f2d00532f29df4260e8d6d9f5f3859b41d9addbcb5889182405f17d4ed0f7d9280c681ef00a98c0d67f1b7fd782cff83432b14ce951c1179abe564d119f1593dde422c4caaa3c007fb5e5bc331abd4ca255601932a973abd64e08ceb727c30aa032ce6aec81204fd2cf0cdf43d4b9eeb84526ae1b0d91d3cfaeaa7048a5e8bb80a349a655c4fbe7e41992cef1c5b5d5df70f085ba6f91c1203a48cb05af3282747780438b49fe9ad291d841eea755256e47c2e42f4027c461ddbd73bc56c03bacdd852c88b893b3e5095d58dff9099bdd86fd9fb54877fc4f4dcdfe2168657e988232953e25dae3c5c551f77affea197a43d98a7acf6c131d25ae9c59688af4ea3d5970c4268dcf341fb9777009ee6f1345d5a4b4af541fe3fe26ccdce87a0d8342bc504b50f6118d32da53e76f6181266377445f9185ca4d0b90573e9afd2ec538753d610ba4c34a71c1a7b33850ceba43caff9eeea53852b089c8e8b98e8ed2ff2510a33
  4: (64 bytes) 0xfc85bfd1fa1062f87709628016a68a1af72a87e3283d2bf197849698ab5ce0835e0eb498eb2bab7f21db68f2d41cdcc4210dba886c264a757f85ad96a6d50797
]

2019-04-13 22:49:19,605 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xb75b048cd845f409f079b448cd37612aad7d92bdb89393c1473dc2f2d00532f29df4260e8d6d9f5f3859b41d9addbcb5889182405f17d4ed0f7d9280c681ef00a98c0d67f1b7fd782cff83432b14ce951c1179abe564d119f1593dde422c4caaa3c007fb5e5bc331abd4ca255601932a973abd64e08ceb727c30aa032ce6aec81204fd2cf0cdf43d4b9eeb84526ae1b0d91d3cfaeaa7048a5e8bb80a349a655c4fbe7e41992cef1c5b5d5df70f085ba6f91c1203a48cb05af3282747780438b49fe9ad291d841eea755256e47c2e42f4027c461ddbd73bc56c03bacdd852c88b893b3e5095d58dff9099bdd86fd9fb54877fc4f4dcdfe2168657e988232953e25dae3c5c551f77affea197a43d98a7acf6c131d25ae9c59688af4ea3d5970c4268dcf341fb9777009ee6f1345d5a4b4af541fe3fe26ccdce87a0d8342bc504b50f6118d32da53e76f6181266377445f9185ca4d0b90573e9afd2ec538753d610ba4c34a71c1a7b33850ceba43caff9eeea53852b089c8e8b98e8ed2ff2510a33
  4: (64 bytes) 0xfc85bfd1fa1062f87709628016a68a1af72a87e3283d2bf197849698ab5ce0835e0eb498eb2bab7f21db68f2d41cdcc4210dba886c264a757f85ad96a6d50797
]

2019-04-13 22:49:19,605 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xb75b048cd845f409f079b448cd37612aad7d92bdb89393c1473dc2f2d00532f29df4260e8d6d9f5f3859b41d9addbcb5889182405f17d4ed0f7d9280c681ef00a98c0d67f1b7fd782cff83432b14ce951c1179abe564d119f1593dde422c4caaa3c007fb5e5bc331abd4ca255601932a973abd64e08ceb727c30aa032ce6aec81204fd2cf0cdf43d4b9eeb84526ae1b0d91d3cfaeaa7048a5e8bb80a349a655c4fbe7e41992cef1c5b5d5df70f085ba6f91c1203a48cb05af3282747780438b49fe9ad291d841eea755256e47c2e42f4027c461ddbd73bc56c03bacdd852c88b893b3e5095d58dff9099bdd86fd9fb54877fc4f4dcdfe2168657e988232953e25dae3c5c551f77affea197a43d98a7acf6c131d25ae9c59688af4ea3d5970c4268dcf341fb9777009ee6f1345d5a4b4af541fe3fe26ccdce87a0d8342bc504b50f6118d32da53e76f6181266377445f9185ca4d0b90573e9afd2ec538753d610ba4c34a71c1a7b33850ceba43caff9eeea53852b089c8e8b98e8ed2ff2510a33
  4: (64 bytes) 0xfc85bfd1fa1062f87709628016a68a1af72a87e3283d2bf197849698ab5ce0835e0eb498eb2bab7f21db68f2d41cdcc4210dba886c264a757f85ad96a6d50797
]

2019-04-13 22:49:21,549 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
  4: (64 bytes) 0x2acd377c72c5b446f471068657f2bf74df344fb4acaccc1eb6018edb8053fc57378102dabf241c264c7618154a810c7713c6e3b1b9e76eb0052657e633a6ee24
]

2019-04-13 22:49:21,549 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x04
  4: (64 bytes) 0x2acd377c72c5b446f471068657f2bf74df344fb4acaccc1eb6018edb8053fc57378102dabf241c264c7618154a810c7713c6e3b1b9e76eb0052657e633a6ee24
]

2019-04-13 22:49:21,550 __init__.py:0169 DEBUG #5 ios -> accessory: send SRP exchange request
2019-04-13 22:49:21,671 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'23f4dc6d-45ff-44ad-8057-4db76babd60d'
  3: (32 bytes) b'v\x81\xec\xbaf\xf51\x95\xc4\xc0\xf4\xa2\xf3\x88\x1e\xfe)\xca\xd7\x9f\xef\xcb\xd9\xf9\xd6\x7fV\xa5\xe0\x9a\xe4\xe8'
  10: (64 bytes) b"%\xb2\xc4\x01\xb8\x0f\xd5H\xe0\xb6xi\xe1'\xdc\x87/W#\xcd[\x86\x03\x91\xb0}\xf9\xc6\xe2\xb5S\xf5\xed\xea\\U\x8a\xeft\x8e\x08C\xd3\xa0'\x9a\x16\n\xd0\x8d\x96\x10\x1b\xec\xfd\xb8\xcf:\x10$\xc5f/\x0c"
]

2019-04-13 22:49:21,673 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x05
  5: (154 bytes) 0x46c18cf32ffd62a7304f744d6fac11dc21af953745c5e0dcf10c11658bb17ecb5d162a17cf88bbbd5b8ff9f8a2a702ef614d7185cc882b58ae4ac378e5efcf6fd20070bbe12341b51a13336f9849d8d21b165a310c1c8fb0ddd7b03418cf9cd39d357d471b27c8d221b4881589d53a296d72917983c1825eff6c029278e17c22c48741933687c5e9fe00a85594c04244aa7eae49a1ad4f9615dd
]

2019-04-13 22:49:21,673 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x05
  5: (154 bytes) 0x46c18cf32ffd62a7304f744d6fac11dc21af953745c5e0dcf10c11658bb17ecb5d162a17cf88bbbd5b8ff9f8a2a702ef614d7185cc882b58ae4ac378e5efcf6fd20070bbe12341b51a13336f9849d8d21b165a310c1c8fb0ddd7b03418cf9cd39d357d471b27c8d221b4881589d53a296d72917983c1825eff6c029278e17c22c48741933687c5e9fe00a85594c04244aa7eae49a1ad4f9615dd
]

2019-04-13 22:49:21,673 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x05
  5: (154 bytes) 0x46c18cf32ffd62a7304f744d6fac11dc21af953745c5e0dcf10c11658bb17ecb5d162a17cf88bbbd5b8ff9f8a2a702ef614d7185cc882b58ae4ac378e5efcf6fd20070bbe12341b51a13336f9849d8d21b165a310c1c8fb0ddd7b03418cf9cd39d357d471b27c8d221b4881589d53a296d72917983c1825eff6c029278e17c22c48741933687c5e9fe00a85594c04244aa7eae49a1ad4f9615dd
]

2019-04-13 22:49:22,080 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x6725e07d561bfa7d70934ba94def1ef4b31a1ce8da49997fddc4ba9e43aaa8605378bfa51b23819e74c3f89087965a92c2599bd3ee42469e42b706bdee9ad9a77d6150fb62a0cefd7aa2b874fbe3bd3af6044f66483298a05254e3bc9a4d7c23d4b796e5b14141aaf3de0463c6e8d0fdd4da3edc17c7f46c6bce187a4e2448c487afef2275d14d
]

2019-04-13 22:49:22,081 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x6725e07d561bfa7d70934ba94def1ef4b31a1ce8da49997fddc4ba9e43aaa8605378bfa51b23819e74c3f89087965a92c2599bd3ee42469e42b706bdee9ad9a77d6150fb62a0cefd7aa2b874fbe3bd3af6044f66483298a05254e3bc9a4d7c23d4b796e5b14141aaf3de0463c6e8d0fdd4da3edc17c7f46c6bce187a4e2448c487afef2275d14d
]

2019-04-13 22:49:22,084 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x61333a64313a35653a31663a36633a3033
  3: (32 bytes) 0x47f4a56162de3b5104b04ea4a3ded80d38b2528819a8c2137c49830c797225f8
  10: (64 bytes) 0xede3da5e7f357ac96f045bbff3b64bf025f6100607e2480a55762566a814107c4236ef78ca570d1ca65253b0af6d936669593721000e938d218625848cdd4309
]

2019-04-13 22:49:22,130 ip_implementation.py:0399 DEBUG init session
2019-04-13 22:49:22,209 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'\xe8\xe5&R\xb5 I\xdb0\x10\xe2g\xe2\x80VD\xd6\xbc\x96\x9d\xcb\x13\x91r\xaa_\xc5\xc5\x9eU\xf4)'
]

2019-04-13 22:49:22,210 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0xe8e52652b52049db3010e267e2805644d6bc969dcb139172aa5fc5c59e55f429
]

2019-04-13 22:49:22,210 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0xe8e52652b52049db3010e267e2805644d6bc969dcb139172aa5fc5c59e55f429
]

2019-04-13 22:49:22,253 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x6a05c612e54eaec1644602f05eac95859a6feea77d3769125fdc423ee7d06a6e
  5: (101 bytes) 0x5ee784e9e00a13fa7c16c8813b4e879e266375515dd32b1531a7bd8d238547efd63d0163387ac83f68eb95d3fb048481812868d121ee7c218e29ede9ecfbf080a225a5a769e8685d155162db9ecfaf81f096636495dbd086ef102eaa85a8764698a453c968
]

2019-04-13 22:49:22,253 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x6a05c612e54eaec1644602f05eac95859a6feea77d3769125fdc423ee7d06a6e
  5: (101 bytes) 0x5ee784e9e00a13fa7c16c8813b4e879e266375515dd32b1531a7bd8d238547efd63d0163387ac83f68eb95d3fb048481812868d121ee7c218e29ede9ecfbf080a225a5a769e8685d155162db9ecfaf81f096636495dbd086ef102eaa85a8764698a453c968
]

2019-04-13 22:49:22,256 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x61333a64313a35653a31663a36633a3033
  10: (64 bytes) 0x8f667540b07073dcf500225fc7becc8eeaa90bfae348af4da61eb6d97cadd9eca441d6630db2ab35f83427aef0f6e81a4c6091915e8db683c9956514f6ff940c
]

2019-04-13 22:49:22,263 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'23f4dc6d-45ff-44ad-8057-4db76babd60d'
  10: (64 bytes) b'\xa1\xcd\xcd\x98\x9f{T\xc2\xfb\x08\xf0\xe4\x1a\xc6|\xb9w7-\\\xf9\x07^\x04+\x16\xad\xe0nA\\\xc2W\x00\'=\xfb\xe4"p>\x86\xfc\x9f\x8d\xbc\xae\xfc\x8d~\x8a\xa3\x82\x86\xeb\xc6[\xa8\x8d\xfaU\xe9\x10\x00'
]

2019-04-13 22:49:22,266 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47225e29d54b7ae043ad8c5550ec41fdd3692cc048d1871450267e833a6952fe4d238a6046c351a13c73201a02ddbb22f0f4e87d7ba3725817c8d4f96654452261b35a24f911463c675293b219bccf8f67f9ba951a486c522e335997376801d0dadd1d5b28a2c97625d2b718b2f0d53cc7d1870fa522b9c2
]

2019-04-13 22:49:22,266 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47225e29d54b7ae043ad8c5550ec41fdd3692cc048d1871450267e833a6952fe4d238a6046c351a13c73201a02ddbb22f0f4e87d7ba3725817c8d4f96654452261b35a24f911463c675293b219bccf8f67f9ba951a486c522e335997376801d0dadd1d5b28a2c97625d2b718b2f0d53cc7d1870fa522b9c2
]

2019-04-13 22:49:22,266 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47225e29d54b7ae043ad8c5550ec41fdd3692cc048d1871450267e833a6952fe4d238a6046c351a13c73201a02ddbb22f0f4e87d7ba3725817c8d4f96654452261b35a24f911463c675293b219bccf8f67f9ba951a486c522e335997376801d0dadd1d5b28a2c97625d2b718b2f0d53cc7d1870fa522b9c2
]

2019-04-13 22:49:22,346 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-13 22:49:22,346 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-13 22:49:22,347 ip_implementation.py:0426 DEBUG session established
Expecting value: line 1 column 1 (char 0)
2019-04-13 22:49:32,363 pair.py:0085 DEBUG Expecting value: line 1 column 1 (char 0)
Traceback (most recent call last):
  File "/home/cf/homekit_test/lib/python3.6/site-packages/homekit/pair.py", line 80, in <module>
    pairing.list_accessories_and_characteristics()
  File "/home/cf/homekit_test/lib/python3.6/site-packages/homekit/controller/ip_implementation.py", line 81, in list_accessories_and_characteristics
    accessories = json.loads(tmp)['accessories']
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Ok - next step is to figure out how to clear the homekit pairing on the bridge - i think it will now think its paired, but on the python code side it crashed before it saved the crypto keys.

It's hard to tell what's going on in that function because by that point it is encrypted in the pcap dumps. I have a few ideas but it will probably be tomorrow now.

I used the homekit library to make a mock accessory, then dumped out the HTTP requests right after decrypting them. Right now, only /accessories is relevant but i did a few types while i was in there.

Decrypted HTTP requests from iPhone client:

GET /accessories HTTP/1.1
Host: DemoAccessory._hap._tcp.local

GET /characteristics?id=1.10 HTTP/1.1
Host: DemoAccessory._hap._tcp.local

PUT /characteristics HTTP/1.1
Host: DemoAccessory._hap._tcp.local
Content-Length: 52
Content-Type: application/hap+json

Decrypted HTTP requests from HA/homekit_python client:

GET /accessories HTTP/1.1

GET /characteristics?id=1.10&meta=0&perms=0&type=0&ev=0 HTTP/1.1

PUT /characteristics HTTP/1.1
Content-Type: application/hap+json
Content-Length: 56

The most stand out difference is that for encrypted sessions we aren't sending a Host header at all.

My latest change adds a Host header to the 3 request types. Pick up the change the same way as before:

$ source venv/bin/activate
$ pip install -U https://github.com/Jc2k/homekit_python/archive/fix_tado_bridge.zip

Make sure pip reports it had uninstalled and then installed homekit or you might still have the old code.

Then you'll probaby need to reset HomeKit on the tado to make it forget its paired:

https://support.tado.com/hc/en-gb/articles/115005185843-How-do-I-perform-a-HomeKit-configuration-reset-of-the-Internet-Bridge-

Then follow the pairing steps again.

Success!

# python -m homekit.pair -f test.json -p XXX-XX-XXX -a test -d cf:35:33:9d:4b:91 --log DEBUG
2019-04-14 09:53:14,895 __init__.py:0106 DEBUG #1 ios -> accessory: send SRP start request
2019-04-14 09:53:14,896 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-14 09:53:14,896 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-14 09:53:14,896 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x01
  0: (1 bytes) 0x01
]

2019-04-14 09:53:16,037 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (384 bytes) 0x608867e07404d6067f2c21a1cbeffdac5c859d33364f51764604688797b3002c5a46a4757816424179fcaa94376b4a9c92cdf4114ff93ebe8f6526a20973901fe3e89e25a931b176e6cac14a050465728a98ea2bf97a5855c5b0953e9edc3b9f26d754f1594ca18b949ebd0b295c720891ec75bde7d72e68f063015c4d0394f69b16c4e8bf01cbafef8c3c790cfdab3b5e8b035f18e66630c4722bd40ea0833383240372e23514fe9c0f816b12a920f2afb6f8073d36ec64fde2ef4f5476a865dee79812bc4e22a6be238f4e01e8c923d8a24178d1dabaac9221f0058d67a50c1f11409393c1dcfea07356076b229e23a07fdb5cb8adf8996bf3ec7d6e4670ee42baaab4a705cb56404350bb37af1c5238a4e0307557eddfa57995da6cf319a576f757bfd3862d00bb76362b065c74b47327f47812dfbe687f3cfc34a71260bc5893d3d6c22409ede5bc93687b124082d892c9b0b14e7826cd1b1bdec20a9a1b081e57da1798dfe5522ef5d09aef970ff23f1ff3a4b9932f5a03390e3b21bf2a
  2: (16 bytes) 0xa0912d467fd05228f5e8d4515cd837ab
]

2019-04-14 09:53:16,038 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x02
  3: (384 bytes) 0x608867e07404d6067f2c21a1cbeffdac5c859d33364f51764604688797b3002c5a46a4757816424179fcaa94376b4a9c92cdf4114ff93ebe8f6526a20973901fe3e89e25a931b176e6cac14a050465728a98ea2bf97a5855c5b0953e9edc3b9f26d754f1594ca18b949ebd0b295c720891ec75bde7d72e68f063015c4d0394f69b16c4e8bf01cbafef8c3c790cfdab3b5e8b035f18e66630c4722bd40ea0833383240372e23514fe9c0f816b12a920f2afb6f8073d36ec64fde2ef4f5476a865dee79812bc4e22a6be238f4e01e8c923d8a24178d1dabaac9221f0058d67a50c1f11409393c1dcfea07356076b229e23a07fdb5cb8adf8996bf3ec7d6e4670ee42baaab4a705cb56404350bb37af1c5238a4e0307557eddfa57995da6cf319a576f757bfd3862d00bb76362b065c74b47327f47812dfbe687f3cfc34a71260bc5893d3d6c22409ede5bc93687b124082d892c9b0b14e7826cd1b1bdec20a9a1b081e57da1798dfe5522ef5d09aef970ff23f1ff3a4b9932f5a03390e3b21bf2a
  2: (16 bytes) 0xa0912d467fd05228f5e8d4515cd837ab
]

2019-04-14 09:53:16,038 __init__.py:0118 DEBUG #3 ios -> accessory: send SRP verify request
2019-04-14 09:53:16,083 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xebe1ffb5fd386845a48f4b2fb540509297da809b26a53582d8237edf28c3bd99445c2e6b617dfcfbec684c8291d5f55b4874777f2618bd1ab56b46cc6eba757b37ccc19332027712137510bdd4797033c8a8c312aebdc0dbe322bdd4a5255d7ca4c4d25c1888184e29cfe394a24858e5da69a20c73622fa061e7c1e7a5f8df7871adcc5170f6219ab53312f3a8c34f602fa7816bbff8d979abdde07114b378488301c5df9e00232ef8738fc4e23b86c3748d7d8d7b2af39590e7befb70eae20d7d93dd63f25675791d72808f57684af775e68f8c79886e0727e196eb2de69013a5d9f87e06da8e90663f7c25544cde04bb7849c1b051c602ea5b85849d4bffb84caee2a2317f0751ef61b5a435e79f084fcefaf5461e225304e1929e695c604055e6efea36b23dec1160126c31c3f3515746ae04178f51c4dca1b6932bcbba011454fd1f301c87b13cec3c771f01a0768be387dba9211c299c88ae794c464550eb4cb27c3be7a0445b5fa90d4808a9e6974e9c6616126ad9cca6be94e951b5d8
  4: (64 bytes) 0xbe90fc95199b146b00dc66574df10da47be4be62eeae631c812839f63de31a1adfa9c27ba4854739c3b63e4ede36155de82c1b5499439bcfc2f76bc8fc867aea
]

2019-04-14 09:53:16,084 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xebe1ffb5fd386845a48f4b2fb540509297da809b26a53582d8237edf28c3bd99445c2e6b617dfcfbec684c8291d5f55b4874777f2618bd1ab56b46cc6eba757b37ccc19332027712137510bdd4797033c8a8c312aebdc0dbe322bdd4a5255d7ca4c4d25c1888184e29cfe394a24858e5da69a20c73622fa061e7c1e7a5f8df7871adcc5170f6219ab53312f3a8c34f602fa7816bbff8d979abdde07114b378488301c5df9e00232ef8738fc4e23b86c3748d7d8d7b2af39590e7befb70eae20d7d93dd63f25675791d72808f57684af775e68f8c79886e0727e196eb2de69013a5d9f87e06da8e90663f7c25544cde04bb7849c1b051c602ea5b85849d4bffb84caee2a2317f0751ef61b5a435e79f084fcefaf5461e225304e1929e695c604055e6efea36b23dec1160126c31c3f3515746ae04178f51c4dca1b6932bcbba011454fd1f301c87b13cec3c771f01a0768be387dba9211c299c88ae794c464550eb4cb27c3be7a0445b5fa90d4808a9e6974e9c6616126ad9cca6be94e951b5d8
  4: (64 bytes) 0xbe90fc95199b146b00dc66574df10da47be4be62eeae631c812839f63de31a1adfa9c27ba4854739c3b63e4ede36155de82c1b5499439bcfc2f76bc8fc867aea
]

2019-04-14 09:53:16,084 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x03
  3: (384 bytes) 0xebe1ffb5fd386845a48f4b2fb540509297da809b26a53582d8237edf28c3bd99445c2e6b617dfcfbec684c8291d5f55b4874777f2618bd1ab56b46cc6eba757b37ccc19332027712137510bdd4797033c8a8c312aebdc0dbe322bdd4a5255d7ca4c4d25c1888184e29cfe394a24858e5da69a20c73622fa061e7c1e7a5f8df7871adcc5170f6219ab53312f3a8c34f602fa7816bbff8d979abdde07114b378488301c5df9e00232ef8738fc4e23b86c3748d7d8d7b2af39590e7befb70eae20d7d93dd63f25675791d72808f57684af775e68f8c79886e0727e196eb2de69013a5d9f87e06da8e90663f7c25544cde04bb7849c1b051c602ea5b85849d4bffb84caee2a2317f0751ef61b5a435e79f084fcefaf5461e225304e1929e695c604055e6efea36b23dec1160126c31c3f3515746ae04178f51c4dca1b6932bcbba011454fd1f301c87b13cec3c771f01a0768be387dba9211c299c88ae794c464550eb4cb27c3be7a0445b5fa90d4808a9e6974e9c6616126ad9cca6be94e951b5d8
  4: (64 bytes) 0xbe90fc95199b146b00dc66574df10da47be4be62eeae631c812839f63de31a1adfa9c27ba4854739c3b63e4ede36155de82c1b5499439bcfc2f76bc8fc867aea
]

2019-04-14 09:53:19,114 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
  4: (64 bytes) 0xbd8dba9e33869b7dc2b9af5c6b44a2d61b4ade9f1af125c9f73ef2b868098a574a0f8d0c8527fe2dbeaa2714655c716c65e74c1fe3ed0bccb394b123dd3bcc12
]

2019-04-14 09:53:19,114 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x04
  4: (64 bytes) 0xbd8dba9e33869b7dc2b9af5c6b44a2d61b4ade9f1af125c9f73ef2b868098a574a0f8d0c8527fe2dbeaa2714655c716c65e74c1fe3ed0bccb394b123dd3bcc12
]

2019-04-14 09:53:19,114 __init__.py:0169 DEBUG #5 ios -> accessory: send SRP exchange request
2019-04-14 09:53:19,234 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'99e5afd4-a211-48b5-a8a9-bdbc5f0389e2'
  3: (32 bytes) b"\xc9&\xda\x94\xbb\xa4\xc6\xfb\xd4\xf4\xe9\x07[\xbd\xf7\xd7\x82\x889\x1a'E:A j\xe2\xa7\xd77\n\xde"
  10: (64 bytes) b"\x88>\xe3\xcf\xea\xd4\x9f\xb7p\xf4\x8d\xa5\xff2['\x9bL\x9al$\xa2_Q\xc5\x82z\x9d\x94\x17\x89\xc2A[1\x0e\xd6\xc8o\xa8P\xec\x7fM\x0bsv\xce\xf6\x0c\xa9\xe6\xc0\x03v\x14e\xfa\xb8\xcd\x12\x9e\xc5\x00"
]

2019-04-14 09:53:19,237 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xfa04d738913993285891dc5978f127e56d7cb4d34d695aac5dc00e83b3d0ab711e12fd2152abbc8dc058eade63efa07f092d9f1f9be53c5b4d52026c828d64868cf959458f6c3e8b46db5e21ef3f4550ba438f6ff672e336a9e0bec9d5f7399d2b9d56142c58a406d771f6c8c22bd8ebb6e2a8710854a84f969b96b1618dd31a1f8783531f4ed6defc6407a902109e648758dbb5d1d121f88700
]

2019-04-14 09:53:19,237 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xfa04d738913993285891dc5978f127e56d7cb4d34d695aac5dc00e83b3d0ab711e12fd2152abbc8dc058eade63efa07f092d9f1f9be53c5b4d52026c828d64868cf959458f6c3e8b46db5e21ef3f4550ba438f6ff672e336a9e0bec9d5f7399d2b9d56142c58a406d771f6c8c22bd8ebb6e2a8710854a84f969b96b1618dd31a1f8783531f4ed6defc6407a902109e648758dbb5d1d121f88700
]

2019-04-14 09:53:19,237 __init__.py:0060 DEBUG write message: [
  6: (1 bytes) 0x05
  5: (154 bytes) 0xfa04d738913993285891dc5978f127e56d7cb4d34d695aac5dc00e83b3d0ab711e12fd2152abbc8dc058eade63efa07f092d9f1f9be53c5b4d52026c828d64868cf959458f6c3e8b46db5e21ef3f4550ba438f6ff672e336a9e0bec9d5f7399d2b9d56142c58a406d771f6c8c22bd8ebb6e2a8710854a84f969b96b1618dd31a1f8783531f4ed6defc6407a902109e648758dbb5d1d121f88700
]

2019-04-14 09:53:20,575 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x67a32cddb67ccfd765715f25dccee02d5e4d45a75b162c6d0e3c9afb10a2734817b280d3eaa529f22ffa27c912415fad81d51eb971ec4de49957c67d6d695f6e95661f607056038a00e85e8a57ca232af3171de7ba6e7782baef1c3de22da6fdd2eaacd10dec82b9ee3760cd236cb122737e9908393494224d10cad8413d9fb4710f713092bf38
]

2019-04-14 09:53:20,576 __init__.py:0067 DEBUG response: [
  6: (1 bytes) 0x06
  5: (135 bytes) 0x67a32cddb67ccfd765715f25dccee02d5e4d45a75b162c6d0e3c9afb10a2734817b280d3eaa529f22ffa27c912415fad81d51eb971ec4de49957c67d6d695f6e95661f607056038a00e85e8a57ca232af3171de7ba6e7782baef1c3de22da6fdd2eaacd10dec82b9ee3760cd236cb122737e9908393494224d10cad8413d9fb4710f713092bf38
]

2019-04-14 09:53:20,578 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x63663a33353a33333a39643a34623a3931
  3: (32 bytes) 0x4dd47cb2d600bd12b17371f00e10d365fa50d996b236e3f49629ef52ff9485e0
  10: (64 bytes) 0x43cb2c1a0c510d651b5c90d0b58c6d807b74d294a1a7d42aa99da4666fc368ea97d20f4c8c04c6e44c66717ddba135643b16a9f9914ac2d2256147df3eb5280a
]

2019-04-14 09:53:20,621 ip_implementation.py:0399 DEBUG init session
2019-04-14 09:53:20,688 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'()\xdf\xa7\tT\x16\x1e\xbd\xe5\xff\xa1\x080o\x07\xc3\xb4\x81\xbd\xbd\xcez\xda\xda\x98\xc8S\xb1\xc6Ar'
]

2019-04-14 09:53:20,688 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x2829dfa70954161ebde5ffa108306f07c3b481bdbdce7adada98c853b1c64172
]

2019-04-14 09:53:20,688 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x2829dfa70954161ebde5ffa108306f07c3b481bdbdce7adada98c853b1c64172
]

2019-04-14 09:53:20,732 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x1344be3244ed13b367f8017fa08c758b3559ff3b738807081f45885db5c8543e
  5: (101 bytes) 0x81ea55e9016156c3c567e04c82455b3b66d2b0feb9ff61f9365de28e133cb6550133f9168d8cb5b52f993a17647059317d8fe5f6a4e58535ec31d9189214de3f0aaa24d68c39d0fb143a91ccfd7ab74754c649732b83bd9c64ae8104d075d35556ab37c4b8
]

2019-04-14 09:53:20,732 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x1344be3244ed13b367f8017fa08c758b3559ff3b738807081f45885db5c8543e
  5: (101 bytes) 0x81ea55e9016156c3c567e04c82455b3b66d2b0feb9ff61f9365de28e133cb6550133f9168d8cb5b52f993a17647059317d8fe5f6a4e58535ec31d9189214de3f0aaa24d68c39d0fb143a91ccfd7ab74754c649732b83bd9c64ae8104d075d35556ab37c4b8
]

2019-04-14 09:53:20,734 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x63663a33353a33333a39643a34623a3931
  10: (64 bytes) 0x11d13ec860cb519cf8ad32587602a72dc912f01fac0cc3cb3c94a65ae18f7c56bae34dbd4b9293a0dfae7007a618c4d97b2f98c48ba8e57c0842fc0ee1c0f40c
]

2019-04-14 09:53:20,738 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'99e5afd4-a211-48b5-a8a9-bdbc5f0389e2'
  10: (64 bytes) b"L\xf3\x86Kd\x00\xb2A\xf2J\xfd\xa2\xe7@\xeb\x98e\xc3\xef'|U\x80\x17\x14\x98\x0e?O5\xf5\x07\xef%\x1f\xe1cF1:\x07\x9fl\xfe\xa1\xc2\x1aW\xee\xac\xf4A\x19Q\xa5\xac\t\x8eM\x02\xa6IO\n"
]

2019-04-14 09:53:20,740 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47d60563806cdf3ee4f96cd89cbec61456ec22316c14ccb67a0418a75cdbd1c981103bad5b27cb6277dbe195bceea085c6ae3db8deb832b94569f3b834a118f48d4d47a15fd71d90881b231dbcda78b6b75c584affb2a8570f4edcd7c93908b49c71b95ca7c5cc2e2fcb82461b48fd90ef293ce3b97fd3ab
]

2019-04-14 09:53:20,740 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47d60563806cdf3ee4f96cd89cbec61456ec22316c14ccb67a0418a75cdbd1c981103bad5b27cb6277dbe195bceea085c6ae3db8deb832b94569f3b834a118f48d4d47a15fd71d90881b231dbcda78b6b75c584affb2a8570f4edcd7c93908b49c71b95ca7c5cc2e2fcb82461b48fd90ef293ce3b97fd3ab
]

2019-04-14 09:53:20,740 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x47d60563806cdf3ee4f96cd89cbec61456ec22316c14ccb67a0418a75cdbd1c981103bad5b27cb6277dbe195bceea085c6ae3db8deb832b94569f3b834a118f48d4d47a15fd71d90881b231dbcda78b6b75c584affb2a8570f4edcd7c93908b49c71b95ca7c5cc2e2fcb82461b48fd90ef293ce3b97fd3ab
]

2019-04-14 09:53:20,825 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-14 09:53:20,825 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-14 09:53:20,825 ip_implementation.py:0426 DEBUG session established
Pairing for "test" was established.

I went ahead and applied the fix to my homeassistant instance:

I can now pair the bridge and the climate devices (both smart thermostats and radiator thermostats) show up in homeassistant with the following attributes:

current_temperature: 22.2
min_temp: 7
max_temp: 35
temperature: null
operation_mode: heat
friendly_name: tado Smart Thermostat RU2280984064
supported_features: 129

So it doesn't report the currently set target temperature. The UI doesn't work, but I can successfully use climate.set_temperature and climate.set_operation_mode to set the target temperature and turn it on and off.

Using climate.set_temperature works but throws an error in the log:

2019-04-14 10:04:02 ERROR (MainThread) [homeassistant.core] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/app/homeassistant/components/homekit_controller/__init__.py", line 189, in discovery_dispatch
    device.pairing_info is not None:
AttributeError: 'HKDevice' object has no attribute 'pairing_info'

Excellent news.

I've already opened a PR for adding Humidity support - it is available here.

The pairing_info bug is also squished here.

The HA maintainers are really busy, but hopefully both of them should land soon.

I'll see what I can see about the target temperature not showing.

There is one command i'd like to see the output of with the old CLI setup, first in human format:

python -m homekit.get_accessories -f test.json -a test

This should dump a table like this:

1.2: >accessory-information<
  1.3:  (Identify) >identify< [pw]
  1.4: lusiardi.de (Manufacturer) >manufacturer< [pr]
  1.5: Demoserver (Model) >model< [pr]
  1.6: Testlicht (Name) >name< [pr]
  1.7: 0001 (Serial Number) >serial-number< [pr]
  1.8: 0.1 (Firmware Revision) >firmware.revision< [pr]
1.9: >lightbulb<
  1.10: False (Switch state (on/off)) >on< [pw,pr,ev]

It will have a lot more entries for you. This will tell us if your device has all the characteristics we are expecting and if pr isn't set then the characteristic isn't readable for some reason. It will also read the value of the characteristic and show us if its a HA bug or a homekit_python bug or something else.

Then there is a version of this comand that returns the data as JSON. I'd like to see a copy of that as it means I can create a virtual/mock tado bridge locally and see what the problem with the UI is. It also means I can add some integration tests to HA to protect you from regressions in the future. The command for that is:

python -m homekit.get_accessories -f test.json -a test4 -o json

It looks like it tries to read the target temperature already, so hopefully with this we can figure out why it's not working for you.

Can you describe what you are trying to do in the UI? E.g. for me, it looks like setting the target temperature works. Setting the operation mode doesn't work because the drop down isn't populated, but i think thats because my mock isn't complete, still working on it. Right now I get:

current_temperature: 21.8
min_temp: 7
max_temp: 35
temperature: 21.5
operation_mode: heat
friendly_name: tado Smart Radiator Thermostat VA0032246272
supported_features: 129

I do seem to see both temperature and current_temperature for all of your thermostats.

(I am testing with dev though - what tag are you running and i can try that).

^ sent in a PR for the list of supported operations not being populated correctly.

Have opened upstream PR https://github.com/jlusiardi/homekit_python/pull/130 for the pairing changes.

In the UI, the target temperature setting doesn't show up at all, and the drop-down isn't populated, so there is nothing I can change in the UI. Current temperature and current operation mode (idle, heat or off) is displayed correctly (but both update only with about one minute delay - would that be normal?).

Other than what you see, I still see the attribute temperature: null.

I understand that the humidity and operation_list attributes are supposed to eventually show up once the PRs you mentioned are implemented?

Have you come across any other sensor values which could be retrieved via homekit? I am particularily interested in the Heating Power value (a % value indicating how much heat the device is requesting). I can retrieve it with a rest sensor through their cloud api but it would be very nice to have that locally too.

I am on the normal homeassistant (docker) version 0.91.3.

It is very weird about target temp. With the JSON you’ve sent me the same code on my end can see the target, and I can set it through the UI. We will need to do some more debugging there.

The delay is normal for now. HomeKit has events, and so does the library we are using, but stitching it all together is going to take a while.

Hopefully yes - we are 2 merged away from operation list and humidity.

There is one non official characteristic ID that I haven’t looked at yet. But it looks write only. All the endpoints we can see are in the text file you sent if you can see your value there let me know.

If I put together a branch with all the changes merged would you be able to test it?

I am sure I could manage if your provide instructions taking into account my general level of incompetence in those things.

The json I sent was from the bridge paired in the venv outside homeassistant. How can I run homekit.get_accessories with the bridge paired in homeassistant? What would be the parameters for the -f and -a arguments?

@jimz011 I can now confirm that tado via homekit works without the cloud. I tested it by blocking the interent access of the bridge and I could set temperatures and turn the devices on and off via the homekit component.

The changes to fix merging are now on homekit_python master branch and should be in the next tag. No ETA for that at present.

The changes to fix operation_list have past code review and should land on HA master when CI passes.

23040 and #22995 still need review but hopefully not far behind.

Will have a think how best to test the changes - maybe I can spin up a fork of the container or something.

@cf00 Missed it when replying yesterday but RE:

The json I sent was from the bridge paired in the venv outside homeassistant. How can I run homekit.get_accessories with the bridge paired in homeassistant? What would be the parameters for the -f and -a arguments?

The JSON file is in your configuration folder. E.g. if you have /config/configuration.yaml then you also have /config/.homekit/pairings.json (or, if i have misremembered, pairing.json).

The value for -a is the homekit id as it appears in homekit.discover (the code that looks like a mac address).

I tried this now but the output seems to be identical, with the "temperature.target" element showing the correct values.

I also managed to upgrade to the dev build (0.92.0-dev) via docker and (after upgrading the python homekit library) I can pair it and my devices show up. The operation_list attribute is now set correctly, but it still has target_temperature: null. And there is no humidity.

Since the dev build seems to break my hue sensor custom component, I went back to 0.91.3 and paired the bridge again. Not sure if it's relevant, but while my devices showed up almost immediately after pairing on the dev build, this time none showed up at first. After a restart, a few appeared, and only after two more restarts all of them are now available again.

Humidity PR still not merged so this is expected.

With operation_list set did the UI for that at least work?

get_accessories CLI uses a slightly different mechanism than HA to get values (it’s too inefficient for minutely pollings). So we could try the get_characteristic cli tool (which is what ha is doing) and see if that works, otherwise I’m going to have to litter the code with debug prints.

I think I saw a PR for the Hue sensors - they might be getting native support. That might be what caused that problem.

The delay for entities showing is known. Config entries work will help to a degree. Some of it is entities aren’t loaded until first discovery scan finished after as much as 30s. Config entries will remove that delay. Then there are some oddities about entities propagating to UI. This can sometimes be fixed with browser refreshes. Again config entries probably fix this.

With operation_list set did the UI for that at least work?

Yes.

get_accessories CLI uses a slightly different mechanism than HA to get values (it’s too inefficient for minutely pollings). So we could try the get_characteristic cli tool (which is what ha is doing) and see if that works, otherwise I’m going to have to litter the code with debug prints.

Not sure if I figured it out correctly but here is the output from get_characteristic. 3.15 should be the target temperature for a device.

# python -m homekit.get_characteristic -f /config/.homekit/pairing.json -a 83:a9:5d:9c:43:f0 -c 3.15 --log DEBUG
2019-04-16 11:11:01,755 ip_implementation.py:0399 DEBUG init session
2019-04-16 11:11:01,804 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'0\xfel\x97\x8a\x18\xdd\xe3\x8a\\\xe7<U\xc8\x10Pumpx\x8dK{\xa9\x14\xd0\x0f\x17\x1e\xeb\xc9F'
]

2019-04-16 11:11:01,804 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x30fe6c978a18dde38a5ce73c55c81050756d70788d4b7ba914d00f171eebc946
]

2019-04-16 11:11:01,804 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x30fe6c978a18dde38a5ce73c55c81050756d70788d4b7ba914d00f171eebc946
]

2019-04-16 11:11:01,849 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x31c87814876ad371ccc7bc9b7433627320a3ac3c55608986345f82fe2670be50
  5: (101 bytes) 0x12ab1f6c5ebe11a19d14caa66d482460a0b048fb235dbf3a988702d17a573c009b060f918126cb0d9d89e08ce3fa7adee493535cb99e833ae6f60e23fe8628de96c2edea7984d0472d7b06002db87291605585a9e53b2fc85cfd1335b9be1fd46aab0db03b
]

2019-04-16 11:11:01,850 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x31c87814876ad371ccc7bc9b7433627320a3ac3c55608986345f82fe2670be50
  5: (101 bytes) 0x12ab1f6c5ebe11a19d14caa66d482460a0b048fb235dbf3a988702d17a573c009b060f918126cb0d9d89e08ce3fa7adee493535cb99e833ae6f60e23fe8628de96c2edea7984d0472d7b06002db87291605585a9e53b2fc85cfd1335b9be1fd46aab0db03b
]

2019-04-16 11:11:01,853 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x38333a61393a35643a39633a34333a6630
  10: (64 bytes) 0xb66c004253b091d956a863251446447078597fd526d42396178e6e15f4da2926be691e0396c13e1c0f5d9fe1822f97adc251b2c6ab6a5333be69b744f7418502
]

2019-04-16 11:11:01,858 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'9259a111-23a4-46ca-95b7-2d50476e5459'
  10: (64 bytes) b'\x97\x88V\xcdT\xb1\xb6\xc8r\x86\xe65s\xa9\x05\x13\xb5XI\xa7\xc9>\xc0C\xb3Q2+\x9b\x00A\xe1O\xe8\x9fz\x7f`\xbc\x11\xaa@\xfbc\xc4\x15V\xac]K\xb6\x85k\x8b\xae\x10\xdf\xff\x81:Ku\xce\t'
]

2019-04-16 11:11:01,861 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0xdc3f8e769e9dcf1adf675156b44e2a2356295f64d6bd8aaca351aa97d02e925dc0bccc3d732c5faa5f27b54dca09d23e6442f6e0c6eec4d04c47a5f756b5cee42b980eb063a25c25b9d8e94d180adbe039624caf450028412df6fa8dc7235ce7edad68e39f82b62e02b4d155eb7fb5f65b868538746c6719
]

2019-04-16 11:11:01,861 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0xdc3f8e769e9dcf1adf675156b44e2a2356295f64d6bd8aaca351aa97d02e925dc0bccc3d732c5faa5f27b54dca09d23e6442f6e0c6eec4d04c47a5f756b5cee42b980eb063a25c25b9d8e94d180adbe039624caf450028412df6fa8dc7235ce7edad68e39f82b62e02b4d155eb7fb5f65b868538746c6719
]

2019-04-16 11:11:01,861 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0xdc3f8e769e9dcf1adf675156b44e2a2356295f64d6bd8aaca351aa97d02e925dc0bccc3d732c5faa5f27b54dca09d23e6442f6e0c6eec4d04c47a5f756b5cee42b980eb063a25c25b9d8e94d180adbe039624caf450028412df6fa8dc7235ce7edad68e39f82b62e02b4d155eb7fb5f65b868538746c6719
]

2019-04-16 11:11:01,942 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-16 11:11:01,943 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-16 11:11:01,944 ip_implementation.py:0426 DEBUG session established
Session closed after receiving malformed response from device
2019-04-16 11:11:01,968 get_characteristic.py:0071 DEBUG Session closed after receiving malformed response from device
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 199, in get_characteristics
    data = json.loads(response.read().decode())['characteristics']
  File "/usr/local/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/get_characteristic.py", line 68, in <module>
    include_type=args.type, include_events=args.events)
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 203, in get_characteristics
    raise AccessoryDisconnectedError("Session closed after receiving malformed response from device")
homekit.exceptions.AccessoryDisconnectedError: Session closed after receiving malformed response from device

However, if I do the same command for characteristic 3.14 (current temperature), I get the same (?) error, even though homeassistant seems to be able to retrieve that value.

# python -m homekit.get_characteristic -f /config/.homekit/pairing.json -a 83:a9:5d:9c:43:f0 -c 3.14 --log DEBUG
2019-04-16 11:16:59,678 ip_implementation.py:0399 DEBUG init session
2019-04-16 11:16:59,723 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'\x8b\xa8YS\x05\x02\xf7\xda\xd7\xc2t\x05\x06ez)\x17`\xac\x12\x8fY\xdc\xc7\x9b\xea\x0f\xd7\xc5\xfa D'
]

2019-04-16 11:16:59,724 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x8ba859530502f7dad7c2740506657a291760ac128f59dcc79bea0fd7c5fa2044
]

2019-04-16 11:16:59,724 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0x8ba859530502f7dad7c2740506657a291760ac128f59dcc79bea0fd7c5fa2044
]

2019-04-16 11:16:59,770 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x6d38b86633cc99c364f2309e4d79f8395033547125486c9f27cf63dc226fbe72
  5: (101 bytes) 0x717c6910bcc1853c9f8be1fe7353f1e860b23707205ef8dc64b173b3a8fbc76c4e1c86b313220356b9e13c065eb326186e888e9c6e89e1ff1b66de09886dd27ccc17e461664153195fc82a369eab386d9d7443236aabda4276a4b70b8e7ca097e1f0137e2f
]

2019-04-16 11:16:59,770 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x6d38b86633cc99c364f2309e4d79f8395033547125486c9f27cf63dc226fbe72
  5: (101 bytes) 0x717c6910bcc1853c9f8be1fe7353f1e860b23707205ef8dc64b173b3a8fbc76c4e1c86b313220356b9e13c065eb326186e888e9c6e89e1ff1b66de09886dd27ccc17e461664153195fc82a369eab386d9d7443236aabda4276a4b70b8e7ca097e1f0137e2f
]

2019-04-16 11:16:59,773 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x38333a61393a35643a39633a34333a6630
  10: (64 bytes) 0xb80a10382a534bb8eb18430de821da2f97cb204c1703931895b7f203b93719bdce842e16cf6d868ffe6d7d37ead7f06c81bff75ca0a3a839e6bb1a13de52690c
]

2019-04-16 11:16:59,778 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'9259a111-23a4-46ca-95b7-2d50476e5459'
  10: (64 bytes) b';\x86\x8d\xfb\xbf=\xcd\xc8\x901\x0cs\x88\x18\x15/\x18\xaa\xdfh`1\x1d\x16\x88\xf1\x1d7n\xef\xbf\x12]%:\xdf\x06.\xd8r\xe8\xb1\x0c\x9b\xd7\xd16\xb6\xc9Q\xcd\xa3\xb5\xa3\x10\xa0\x9f\xb3\xf3\x83\xa2q\x15\x06'
]

2019-04-16 11:16:59,780 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x76ed3d90c49f463f982aed37502ee3c82f3ad8f720365a85967c5e0dded1d5aac82105781a7a9ea21d640d616f9b11d00733637421650988ace4430996dd2cbfcfcd09305daa7722f3c3e811cd803f0ba4dc8be3a44496cf744261c7595bab1eccdf891505623aaba98995e8e93db47cd941d6e8c17b7210
]

2019-04-16 11:16:59,780 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x76ed3d90c49f463f982aed37502ee3c82f3ad8f720365a85967c5e0dded1d5aac82105781a7a9ea21d640d616f9b11d00733637421650988ace4430996dd2cbfcfcd09305daa7722f3c3e811cd803f0ba4dc8be3a44496cf744261c7595bab1eccdf891505623aaba98995e8e93db47cd941d6e8c17b7210
]

2019-04-16 11:16:59,780 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x76ed3d90c49f463f982aed37502ee3c82f3ad8f720365a85967c5e0dded1d5aac82105781a7a9ea21d640d616f9b11d00733637421650988ace4430996dd2cbfcfcd09305daa7722f3c3e811cd803f0ba4dc8be3a44496cf744261c7595bab1eccdf891505623aaba98995e8e93db47cd941d6e8c17b7210
]

2019-04-16 11:16:59,863 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-16 11:16:59,863 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-16 11:16:59,864 ip_implementation.py:0426 DEBUG session established
Session closed after receiving malformed response from device
2019-04-16 11:16:59,888 get_characteristic.py:0071 DEBUG Session closed after receiving malformed response from device
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 199, in get_characteristics
    data = json.loads(response.read().decode())['characteristics']
  File "/usr/local/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/get_characteristic.py", line 68, in <module>
    include_type=args.type, include_events=args.events)
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 203, in get_characteristics
    raise AccessoryDisconnectedError("Session closed after receiving malformed response from device")
homekit.exceptions.AccessoryDisconnectedError: Session closed after receiving malformed response from device

The delay for entities showing is known. Config entries work will help to a degree. Some of it is entities aren’t loaded until first discovery scan finished after as much as 30s. Config entries will remove that delay.

Where and how can I set config entries?

That's the internal name for the integrations list in homeassistant (where Hue appears). You can't yet use them for homekit accessories - it's in a branch i'm working on. It's more or less done, i've just got to get it reviewed and merged. It's a large change so breaking it up for review is taking a while though.

If you can, could you edit the file /usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py and edit line 199.

Right now it should look like:

    data = json.loads(response.read().decode())['characteristics']

Would be helpful to see the output if you change it to:

    response_bytes = response.read().decode()
    print(response_bytes)
    data = json.loads(response_bytes)['characteristics']

Ok. After the change:

# python -m homekit.get_characteristic -f /config/.homekit/pairing.json -a 83:a9:5d:9c:43:f0 -c 3.15 --log DEBUG
2019-04-16 11:49:56,993 ip_implementation.py:0401 DEBUG init session
2019-04-16 11:49:57,050 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x01
  3: (32 bytes) b'\xa7\xf6d\xc2b\xfe\xfd\xef;\x81\x19H\xc4\xba\x9b\xec\xf0P\x11\xd3\x9aj\xd3\xceE\xef\x94\x9b\xc9+\xde '
]

2019-04-16 11:49:57,050 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x01
  3: (32 bytes) 0xa7f664c262fefdef3b811948c4ba9becf05011d39a6ad3ce45ef949bc92bde20
]

2019-04-16 11:49:57,050 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x01
  3: (32 bytes) 0xa7f664c262fefdef3b811948c4ba9becf05011d39a6ad3ce45ef949bc92bde20
]

2019-04-16 11:49:57,097 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x9f5f77aed0f79f2dcbbe0b6ecf535b90f4e7c5b08adbbc4f037dac7aaf323637
  5: (101 bytes) 0xcbf0193696a870ddb4e177c28d571f46c5cf390021221ca9ed2f1636917b7fd44d19da99dced1f9d9142da3b3d97ee38ce6bbfce598daf290ac014d20fd715ba2c3e258b783f27fb7153ea16567fd47a08c6195efb4c7e0750bec2376b2fc517b6abc90eb0
]

2019-04-16 11:49:57,098 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x02
  3: (32 bytes) 0x9f5f77aed0f79f2dcbbe0b6ecf535b90f4e7c5b08adbbc4f037dac7aaf323637
  5: (101 bytes) 0xcbf0193696a870ddb4e177c28d571f46c5cf390021221ca9ed2f1636917b7fd44d19da99dced1f9d9142da3b3d97ee38ce6bbfce598daf290ac014d20fd715ba2c3e258b783f27fb7153ea16567fd47a08c6195efb4c7e0750bec2376b2fc517b6abc90eb0
]

2019-04-16 11:49:57,101 tlv.py:0117 DEBUG receiving [
  1: (17 bytes) 0x38333a61393a35643a39633a34333a6630
  10: (64 bytes) 0xf234bdb9c0f1ae77ea95628cd6870237779618cf7af5bddf4204575f98e35f0ff8045e9e721edae957bed4ca95626ed0220f9ba45c44a254916ec2e6f272f60c
]

2019-04-16 11:49:57,106 tlv.py:0134 DEBUG sending [
  1: (36 bytes) b'9259a111-23a4-46ca-95b7-2d50476e5459'
  10: (64 bytes) b'\xe5A\x1b/\xb9\x05\xc5\xd5\xee\xce\x11G\x0c\x10\xbe\xeeV\x18\xaa\x85\xbb\xf2$\xfe\x11\xdc\x14\x11\xe2\n`ELY\xe5!\x12\x1d\x8d\xfeD\xff\xf7\xc3"\x98\t\xfcBi\xd2x}\xb8<\x18\xad\xba\x1926\xd8\x1e\x00'
]

2019-04-16 11:49:57,109 tlv.py:0134 DEBUG sending [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x33f4f2dcf38852b043b3724a56fb58623c1e65f58bbdf0e4e8fdf77b7e3428d1eae6d96116259a84a11d4a33f342c3fca4b20e95cf248d4bd96b145d08227cc56b66d3c7dfa7a02c37749e5c0d20ac420a7f3aa3814aea644c130edbe19dee85a6b0d14685609fd3163c52db03a1fd7f6de5b98313ba790c
]

2019-04-16 11:49:57,109 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x33f4f2dcf38852b043b3724a56fb58623c1e65f58bbdf0e4e8fdf77b7e3428d1eae6d96116259a84a11d4a33f342c3fca4b20e95cf248d4bd96b145d08227cc56b66d3c7dfa7a02c37749e5c0d20ac420a7f3aa3814aea644c130edbe19dee85a6b0d14685609fd3163c52db03a1fd7f6de5b98313ba790c
]

2019-04-16 11:49:57,109 __init__.py:0075 DEBUG write message: [
  6: (1 bytes) 0x03
  5: (120 bytes) 0x33f4f2dcf38852b043b3724a56fb58623c1e65f58bbdf0e4e8fdf77b7e3428d1eae6d96116259a84a11d4a33f342c3fca4b20e95cf248d4bd96b145d08227cc56b66d3c7dfa7a02c37749e5c0d20ac420a7f3aa3814aea644c130edbe19dee85a6b0d14685609fd3163c52db03a1fd7f6de5b98313ba790c
]

2019-04-16 11:49:57,191 tlv.py:0117 DEBUG receiving [
  6: (1 bytes) 0x04
]

2019-04-16 11:49:57,191 __init__.py:0082 DEBUG response: [
  6: (1 bytes) 0x04
]

2019-04-16 11:49:57,192 ip_implementation.py:0428 DEBUG session established

Session closed after receiving malformed response from device
2019-04-16 11:49:57,217 get_characteristic.py:0071 DEBUG Session closed after receiving malformed response from device
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 201, in get_characteristics
    data = json.loads(response_bytes)['characteristics']
  File "/usr/local/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homekit/get_characteristic.py", line 68, in <module>
    include_type=args.type, include_events=args.events)
  File "/usr/local/lib/python3.7/site-packages/homekit/controller/ip_implementation.py", line 205, in get_characteristics
    raise AccessoryDisconnectedError("Session closed after receiving malformed response from device")
homekit.exceptions.AccessoryDisconnectedError: Session closed after receiving malformed response from device

.. it didn't print anything did it? Probably means its returned nothing, which smells like it doesn't like the HTTP request that is being sent.

You are right that it's weird that some of these are working in HA and not on the CLI. Near where you made the last change there is a bunch of code like this:

        if include_meta:
            url += '&meta=1'
        else:
            url += '&meta=0'
        if include_perms:
            url += '&perms=1'
        else:
            url += '&perms=0'
        if include_type:
            url += '&type=1'
        else:
            url += '&type=0'
        if include_events:
            url += '&ev=1'
        else:
            url += '&ev=0'

I noticed my iPhone never sends the =0 variants, so maybe the tado doesn't like that we do? So just delete that entire block of code and try again?

That's it! The CLI returns the value and it also shows up in homeassistant and the UI works.

OK, let's try a more correct version that I can slap in a PR:

        if include_meta:
            url += '&meta=1'
        if include_perms:
            url += '&perms=1'
        if include_type:
            url += '&type=1'
        if include_events:
            url += '&ev=1'

It's still working, both in the CLI and in ha.

Cool, i'll get a PR upstream for that.

All my outstanding HA fixes have landed on dev, including humidity support. If you run dev and the master branch of homekit_python the tado should work. If someone can try that it would be a big help.

I am so sorry, I said I’d help but have been sick the last few days. I am finally feeling a bit better. So I might try this later.

So I need HA dev? And how do I get the master branch of homekit_python?

I run this in a python venv. I know how to get the dev version of HA. But have no idea how to get the master branch of homekit_python.

Hi @jimz011 - glad that you are feeling better!

Yes, you need HA dev. The PR's landed in the past few hours.

For homekit_python - you should be able to do pip install https://github.com/jlusiardi/homekit_python/archive/master.zip in your venv. The only gotcha is if you already have homekit_python in your config/deps folder. I think that one might trump the system/venv one, so delete it if you do.

Ok I will try that. Dev or beta branch for HA? As I see your fixes are mentioned in the changes (on the beta page).

homekit_controller: Support cover stop (@Jc2k - #23046) (homekit_controller docs)
Fix handling of homekit_controler zeroconf c# changes (@Jc2k - #22995) (homekit_controller docs)
Support fetching/setting humidity of HomeKit controller thermostats (@Jc2k - #23040) (homekit_controller docs)

The beta has been pushed out 2 hours ago. So I am guessing that the beta might be up to date with your PR’s. But I will figure it out. I will post an answer when I have it working.

Hmm if its in beta im surprised because they only just hit dev! But looks like they are indeed on the rc branch too.

Haha, I just edited my post to say rc was pushed out 2 hours ago :P, which is fine seeing I always run rc versions of HA (and work around the broken stuff in the meantime).

Just one more question do you think I would need to update homekit_python? Or might it just work with the rc branch? I don’t see homekit_python mentioned. Though an update to HAP-Python 2.5.0 is mentioned.

Yeah you need lastest homekit_python master, will not pair without it. The fixes on HA are for after the pairing and security networking are working.

Normal workflow:

  • Make a change to homekt_python <- we are here
  • homekit_python is tagged
  • Change is made to HA to point at new tag
  • New HA is released and everyone gets the fix

So obviously there is nothing to 'see' on the HA side yet.

I can confirm that everything seems to work on 0.92.0b0 with the updated homekit_python. Target temperature, humidity and operation_list are all there; the UI works. I did not test pairing as it was still paired from the previous version (but I assume that should work too).

(Any idea why this release is not loading the custom component? My hue sensors still don't work .. I didn't find any change which would explain that. I know it's completely off topic here, but any pointer would be appreciated)

Not sure about your hue sensor problem, sorry.

Thanks anyway.

I really appreciate your help and the effort you put into getting this to work. You are doing an outstanding job.

So I have tried to install the rc, which is running fine (after some hiccups) I also installed the homekit python package. However my situation is the same. When I enter the homekit code in the configurator nothing happens. (You will see a loading wheel for a few sec). It won’t accept any code for me. I even tried some random letters, but nothing appears to be happening (nothing in logs/console either). When I press to submit the code nothing happens in the console either.

Pretty tired now, so gonna check back in tomorrow.

Edit: couldn't stand it and tried the dev version as well. Still no effect. It is like the configurator just doesn't do anything at all. (I did manage to pair my koogeek switches though, so you might think that the configurator should be working).

@jimz011 ok when you are back we can try and verify the homekit installation worked. The behaviour you are getting sounds like the new version isn’t installed right.

Update: I have tried pairing it via the cmd line as per your instructions earlier. When I try to pair it it will say: remote connection closed by the other end. (Haven’t used debug yet, as I was tired yesterday)

I might try it on a clean install tonight. The crazy thing is that it used to work a few HA updates ago (I mean the pairing part). It would throw some errors in the console. However it just does nothing at the moment.

@cf00 i noticed that Hue sensors are now supported on master - see https://github.com/home-assistant/home-assistant/commit/474ac8b09ee369916061bf1991f7f8956612a0fe. It got cherry picked into 0.92 so should be in next release.

@jimz011 right now we have a few options about why its working for others and not you:

  • sneaky older homekit_python hidden away somewhere is overriding your installation (have had this a lot when trying to do support).
  • theres a further bug that is specific to your specific hardware or firmware revision. It looks like @cf00 has firmware version 50.6 - can you pair with your phone and see what you have?

As you said before, theres nothing weird about your install so right now they are my best guesses.

Based on the code history i'm not sure how pairing could have ever worked. The bug has existed in homekit_python at least a year ago, and it's not that kind of change you could accidentally undo so i suspect it never worked. Best guess is it was a firmware update that broke it and made HTTP parsing much stricter.

Please try:

$ python3 -m venv homekit_test

$ source homekit_test/bin/activate

$ pip install --no-cache --upgrade https://github.com/jlusiardi/homekit_python/archive/master.zip

$ python -m homekit.init_controller_storage -f test.json

$ python -m homekit.discover
Name: DemoAccessory._hap._tcp.local.
Url: http_impl://192.168.1.254:8085
Configuration number (c#): 67
Feature Flags (ff): No support for HAP Pairing (Flag: 0)
Device ID (id): ff:f0:00:00:00:00
Model Name (md): DemoAccessory
Protocol Version (pv): 1.0
State Number (s#): 1
Status Flags (sf): Accessory has not been paired with any controllers. (Flag: 1)
Category Identifier (ci): Lightbulb (Id: 5)

$ python -m homekit.pair -f test.json -p 031-45-154 -a test -d ff:f0:00:00:00:00 --log DEBUG
<snip>
2019-04-12 21:31:38,505 ip_implementation.py:0426 DEBUG session established
Pairing for "test" was established.

Make sure you use that exact pip install incantation. The first version of these instructions use a release. That tag/release will not work.

If that fails please also do:

$ python -c "print(__import__('homekit').__file__)"

$ pwd

So I can check its finding the right homekit.

The first command will print something like

/private/tmp/homekit_test/lib/python3.7/site-packages/homekit/__init__.py

Copy the path into this command, replacing homekit/__init__.py with homekit/protocol/__init__.py.

$ cat /private/tmp/homekit_test/lib/python3.7/site-packages/homekit/protocol/__init__.py | grep skip
        connection.putrequest('POST', '/pair-setup', skip_accept_encoding=True)
        connection.putrequest('POST', '/pair-verify', skip_accept_encoding=True)

Ok I will give that a try, my firmware is version is the same (50.6).

If it helps, I always used the following command to update homekit_python for my HA (docker) installation whenever I switched to a different HA release during testing:

pip install --upgrade git+git://github.com/jlusiardi/homekit_python.git@master

It seems to have worked every time (disclaimer: this is just the result of trial and error, and I don't really know what it does and if this is the right/recommended way).

@Jc2k,, thanks for the hint re hue sensor. I already figured out why the custom component didn't work; I should have RTFM, it is literally the first sentence in the beta release notes.

@cf00 thanks that did it for me, pairing now seems to work in the test environment (via cmd line) and HA seems to be doing something when I enter the code now. Unfortunately I am not home so there is no way to reset the paired bridge for me remotely. Will post my results later on.

Btw, did I mention that you guys are really helpful, doing a massively great job and very friendly? Well I did now :P

@jimz011 you'll make us blush 😆

You can potentially remote unpair with the homekit cli, btw.

From docs:

python -m homekit.unpair -f ${PAIRINGDATAFILE} -a ${ALIAS} [--log ${LOGLEVEL}]

So if following my instructions from before then:

python -m homekit.unpair -f test.json -a test --log DEBUG

I don't think we've tried this on a tado yet so would be good to test it.

Seems to have worked, tried to copy the debug but almost impossible to do on a phone using rdp :P.

I have managed to unpair the device, and now it paired up with Home Assistant just fine. Entities are showing up in Home Assistant now. Haven’t tested if they actually work.

If you’d like I can post the logs later on when I have a proper pc.

Thanks a lot!

One more thing, I see it only creates a single entity as opposed to the tado component (which uses the unofficial API).

I think this is intended as there are only 2 operation modes as well (which is great as there is the heat operation mode, which the tado component lacks).

The tado component creates like 6 entities per device. That is why I ask.

I managed to get the log copied :P

2019-04-18 12:53:56,224 tlv.py:0134 DEBUG sending [
6: (1 bytes) 0x01
0: (1 bytes) 0x04
1: (36 bytes) b'd9097764-8c21-4303-9790-8eb2ed64d913'
]

2019-04-18 12:53:56,225 ip_implementation.py:0391 DEBUG init session
2019-04-18 12:53:56,346 tlv.py:0134 DEBUG sending [
6: (1 bytes) 0x01
3: (32 bytes) b'=\x1b\xad\xca\x9f>q>uc\xe7\xae\x9e\x8a\xc7"k\xa2\xcb\xd3+Z\t\x14\xbc\xefz\xcc4\x9e\xf3J'
]

2019-04-18 12:53:56,347 tlv.py:0117 DEBUG receiving [
6: (1 bytes) 0x01
3: (32 bytes) 0x3d1badca9f3e713e7563e7ae9e8ac7226ba2cbd32b5a0914bcef7acc349ef34a
]

2019-04-18 12:53:56,348 __init__.py:0075 DEBUG write message: [
6: (1 bytes) 0x01
3: (32 bytes) 0x3d1badca9f3e713e7563e7ae9e8ac7226ba2cbd32b5a0914bcef7acc349ef34a
]

2019-04-18 12:53:56,396 tlv.py:0117 DEBUG receiving [
6: (1 bytes) 0x02
3: (32 bytes) 0x8d4ea0d8077f5e52e015d90810f96021f751bbd1fd59698d0d5f047bcc99677e
5: (101 bytes) 0xd0a06e3c7057de061740e0526646e61285baea4c25f5ebf9ec5eef869ecb055dbb42437e30f43a16cfd35c64546bea22d7e001a3a9c232af599b26da936d2036280086856e13182211b8caace2025c3e42381e95069625aafd27601f07cec81772088f9e52
]

2019-04-18 12:53:56,396 __init__.py:0082 DEBUG response: [
6: (1 bytes) 0x02
3: (32 bytes) 0x8d4ea0d8077f5e52e015d90810f96021f751bbd1fd59698d0d5f047bcc99677e
5: (101 bytes) 0xd0a06e3c7057de061740e0526646e61285baea4c25f5ebf9ec5eef869ecb055dbb42437e30f43a16cfd35c64546bea22d7e001a3a9c232af599b26da936d2036280086856e13182211b8caace2025c3e42381e95069625aafd27601f07cec81772088f9e52
]

2019-04-18 12:53:56,401 tlv.py:0117 DEBUG receiving [
1: (17 bytes) 0x38633a63373a36383a34313a61633a6135
10: (64 bytes) 0x3616baad5b007998e06cb0b04f1cdc795bc85cd32a5ac6eeaefc528dc07deba439322b480d6d468766b775a3f2b4e58c0ace14abc7bf4ddeed2fa7d0fbfdb10b
]

2019-04-18 12:53:56,413 tlv.py:0134 DEBUG sending [
1: (36 bytes) b'd9097764-8c21-4303-9790-8eb2ed64d913'
10: (64 bytes) b'6\x8e\x16A\x822\xe4\xec\x0e\xc5Q98:d\xf7\xee b\xc1\xefS\x1c$X"i>\xfa\xb6[\x10\x9c>n\xfek!}T^&\x95n\xf3\x98\xdf\xe0\xb3H\x1d\x8cl\x13K\x06\xbbm\xc7i\x13\x8e\xb4\x02'
]

2019-04-18 12:53:56,418 tlv.py:0134 DEBUG sending [
6: (1 bytes) 0x03
5: (120 bytes) 0x3a2f8027f6f52e6f6269f1abbc5bf5aa08ac5d8335ef4bcf265591cc3a191d4ffc11a79ddd63b43700d91883e24e3422e06c0e7a5fc0bf87963d5ed20218f5de392573d6653e0f0f5d44d4aaff08a52e2a48fdd480c4624904f244a362edcd46c829aec826e78ecc40610fcb48decb09be95ac7dee49a427
]

2019-04-18 12:53:56,418 tlv.py:0117 DEBUG receiving [
6: (1 bytes) 0x03
5: (120 bytes) 0x3a2f8027f6f52e6f6269f1abbc5bf5aa08ac5d8335ef4bcf265591cc3a191d4ffc11a79ddd63b43700d91883e24e3422e06c0e7a5fc0bf87963d5ed20218f5de392573d6653e0f0f5d44d4aaff08a52e2a48fdd480c4624904f244a362edcd46c829aec826e78ecc40610fcb48decb09be95ac7dee49a427
]

2019-04-18 12:53:56,418 __init__.py:0075 DEBUG write message: [
6: (1 bytes) 0x03
5: (120 bytes) 0x3a2f8027f6f52e6f6269f1abbc5bf5aa08ac5d8335ef4bcf265591cc3a191d4ffc11a79ddd63b43700d91883e24e3422e06c0e7a5fc0bf87963d5ed20218f5de392573d6653e0f0f5d44d4aaff08a52e2a48fdd480c4624904f244a362edcd46c829aec826e78ecc40610fcb48decb09be95ac7dee49a427
]

2019-04-18 12:53:56,497 tlv.py:0117 DEBUG receiving [
6: (1 bytes) 0x04
]

2019-04-18 12:53:56,497 __init__.py:0082 DEBUG response: [
6: (1 bytes) 0x04
]

2019-04-18 12:53:56,497 ip_implementation.py:0418 DEBUG session established
2019-04-18 12:53:56,882 tlv.py:0117 DEBUG receiving [
6: (1 bytes) 0x02
]

2019-04-18 12:53:56,882 controller.py:0529 DEBUG response data: [[6, bytearray(b'\x02')]]
Pairing for "test" was removed.

If the unpair worked I don't need the logs.

Oh gods haha well done

Ah k, well I posted it anyways (srry about that). Anyways is it correct that there is only one entity created per device?

Edit: nvm was a stupid question, as it mimics the entities presented in homekit (which is one per device).

GH tip: If you surround your logs / tracebacks with ``` at the start and the end it uses a monospace font and is a bit easier to read.

Hard to say if i understand your question correctly as I don't have a tado. Let's say you had a thermostat and a radiator valve. I'd expect 2 entities. If you just have a thermostat and no radiator valves, i'd expect 1 entity. I'd expect these entities to be climate entities. They would have temperature readouts and you could set target temperatures and operation modes. They would potentially have humidity readouts and target humidity (entity will auto configure based on capabilities reported by the device).

If you can describe more about the 6 entities I can maybe elaborate on how that maps to homekit.

Some devices have batteries, these will be supported at some point and will probably be seperate entities. But I haven't wired up the battery service yet.

Ah yeah sorry about the monospace, seems to be different than the one on the home assistant forums (or its just me and not getting the right symbols on my phone, I have tried it in the past though).

What I meant was is that the Tado component (which currently is the only way to add Tado to HA) creates multiple entities per device. E.g.

  • climate.tadodevice
  • sensor.tadodevice_temperature
  • sensor.tadodevice_humidity
  • sensor.tadodevice_heating_power
  • sensor.tadodevice_link
  • sensor.tadodevice_overlay
  • sensor.tadodevice_power

Per device these entities will be created by the tado component. It uses the unofficial Tado API (which is just the official tado webinterface). I have to mention that most of these extra entities are completely useless to me as most of that info also resides in the climate entity.

I figured that this solution will only create a single entity per device as that is exactly what homekit would do (when I pair it to my phone).

But as I mentioned it was a stupid question to begin with. It all seems to work now, will try some integrations later on but man this is great work!

@cf00 sorry bit off topic. You said dev branch broke your custom components? Add the following file to your custom components (assuming you have already renamed all the components to the new format e.g. hue/light.py instead of light/hue.py).

__init__.py

Add this file to each folder (the file can be empty). Custom components should now work again. (I have tested this on rc as well but it isn’t working as it will throw errors). So for now it only works on dev branch.

@jimz011 thanks. I had it already figured out. Had to add also DOMAIN = 'huesensor' to __init__.py but I guess with https://github.com/home-assistant/home-assistant/pull/23177 this shouldn't be necessary any more.

Everything is working for me now on 0.92.0b0 thanks to the great support from @Jc2k.

Ah yeah, in my case all but a few custom components were failing because of it. However I can’t seem to get it to work on rc (it throws me errors on rc when adding that file, and without it they won’t load at all).

Anyways once again thanks to all of you.

If either of you are able to easily try branches (sorry I'm not sure how this works with Docker images) then it would be a great help to me if you could try this one:

https://github.com/Jc2k/home-assistant/tree/homekit_pairing_entity_maps

It shouldn't have any noticeable changes (everything should work exactly as it does now), but its an important piece of prep for my config entries PR. It would be good to know it doesn't break anything.

(This will still require you to manually install homekit_python from git).

(This is now on dev upstream if that's easier to test, and even though it's merged 'd still appreciate if you can confirm whether it works for you).

I failed miserably trying to update from github, but a new dev docker image was published just now, so I assume that would include your changes?

Anyway, I updated and am now on 0.93.0.dev0. So far everything seems normal and nothing seems to be broken. Anything in particular I should test or look at?

So in your config directory there should be a .storage directory - can you check if there is a homekit_controller-entity-map file? If that doesn't exist then my commit hasn't made it into the docker image yet (or my code is utterly broken).

Ok, in the meantime two new dev docker images have been published and it now includes your changes. Must have missed it by a few seconds previously, but by now I am an expert in updating docker images :-)

So, the homekit_controller-entity-map is there and seems to contain the info for my tado devices. Everything still seems to work, nothing unusual in the UI or in the logs/console.

Excellent news - thank you very much for helping me test that.

I have integrated everything in HA now, all is working perfectly fine. I also checked the .storage for that file. I have it as well. Thanks again for this great work.

Guys, I just started using Home Assistant (0.91.4) yesterday on a Raspberry Pi. And bumped to the same issue with my tado. I'm not that technical with Linux that I do what you guys did. Can you tell me when it will be possible for standard users to have this new version?

It is on rc (beta) channel right now. Usually it should drop next week. But probably no longer than 2 weeks.

Okay, thanks for the super quick reply. I'm not that patient so I'll have to learn myself how to update to the rc version than. :)
I've found out the console access, logged in as root and typed
hassio homeassistant update

But I guess that's updating to the latest production version. If it's simple as that to update to the rc version, can you please tell me how to do that?

I don’t use hassio, but I guess update process is similar if not the same but the normal way to do it is:

$ pip3 install --pre --upgrade homeassistant

You will also need the following as it is not yet in rc (as far as I know)

https://github.com/home-assistant/home-assistant/issues/16971#issuecomment-484426388

You said you are not very patient, but running an rc version might require a lot of it :P. As it is a beta version things might not work at all or not the way you might expect it to work. If you know your way around you can work around these issues most of the time however running the rc branch is not recommended if you do not know what you are doing.

Though it is easy to revert back to an older version of HA.

Then I guess it's better to grow some patience and wait for the stable production version. I'm quit new to this and too much things not working properly gets very confusing. Maybe later when I'm more experience. Thanks a lot for your help @jimz011 !

Well I have learned that patience gets you a long way with Home Assistant. This piece of art gets updated a lot (almost every 2 weeks) and many things get fixed and/or changed which in turn might break existing configurations.

For me not a big deal as I have fun with it, but if you are looking for something more stable you might need to look at OpenHAB (though new features are lacking as it gets updated only twice a year).

If you are looking for ideas you can look at my repo screenshots can be found here:

https://community.home-assistant.io/t/lovelace-by-jimzz011-ha-0-91-x-compatible/

Just opened #23562. This should hopefully allow tado users to pair and use their climate devices. There are some other homekit_controller climate changes queued up, hopefully they can all squeeze into 0.93, but currently out of my hands.

If people following this ticket are compfortable running the rc branch of HA i'd be interested to know how 0.93.0b2 works with tado. It should have all the fixes discussed in this ticket.

I upgraded to the latest dev version (shown as 0.94.0.dev0; there is no docker image for 0.93.0b2 available) and I am happy to report that everything seems to work now out of the box. The thermostats show up, I can control the devices, nothing unusual in the logs or console (I didn't test pairing).

Was this page helpful?
0 / 5 - 0 ratings