Dyson Link Action and Sensor

It stopped working. But I havnet had any time to delve into it more. Could be a simple thing like its gotten a new IP address from my router as its not static

I have it retrying 10 times in the config, and until it stops trying, my Home Assistant will not start - you might want to have a look at changing that if you can?

2017-05-13 14:08:10 INFO (Thread-12) [homeassistant.components.fan.dyson] Creating new Dyson platform
2017-05-13 14:08:11 INFO (Thread-12) [homeassistant.components.fan.dyson] Connected to Dyson account
2017-05-13 14:08:11 INFO (Thread-12) [homeassistant.components.fan.dyson] Trying to connect to device DysonDevice(PE8-UK-HHA0158A,True,Pürity,21.03.08,True,False,455,None) with timeout=10 and retry=10
2017-05-13 14:08:19 WARNING (MainThread) [homeassistant.setup] Setup of fan is taking over 10 seconds.
2017-05-13 14:08:20 WARNING (MainThread) [homeassistant.components.fan] Setup of platform dyson is taking over 10 seconds.
2017-05-13 14:08:21 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 0
2017-05-13 14:08:34 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 1
2017-05-13 14:08:46 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 2
2017-05-13 14:08:59 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 3
2017-05-13 14:09:11 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 4
2017-05-13 14:09:24 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 5
2017-05-13 14:09:36 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 6
2017-05-13 14:09:49 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 7
2017-05-13 14:10:01 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 8
2017-05-13 14:10:14 ERROR (Thread-12) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 9
2017-05-13 14:10:16 WARNING (Thread-12) [homeassistant.components.fan.dyson] Unable to connect to device DysonDevice(PE8-UK-HHA0158A,True,Pürity,21.03.08,True,False,455,None)

I’ve experienced the same problem, but after a couple of restarts it started working again. And like Charlesblonde said after this things seem to get better… strange :confused:

Thanks for you feedback.

@elPaulio can you try to reduce the timeout parameter ? Maybe something like 2 or 3 ? The Dyson Link app is still able to control the fan ? Your Home Assistant installation is on Wifi or Ethernet ?

I’ll try to improve this but I have no good ideas because I don’t know if issues are coming from my code or from the Dyson devices.

And it’s really interesting to know that the component setup is blocking Home Assistant startup. I have to do something about that because it’s not acceptable.

Apologies, havent had much time for testing this this week.

Ive changed the retry to 3 and can still confirm that HA will not continue setting up anything else until these 3 retries are done

My HA is connected via 1G ethernet
The Dyson link app still works fine

the first errors that appear when HA is restarted, are the same

Are there any other logs/debug info I can look at to give you an idea?
I could remove the account details from the yaml, and re-add them after restarting HA - are there any files/cached entries anywhere I should also delete if I were to start from scratch?

2017-05-15 14:23:13 INFO (Thread-3) [homeassistant.components.fan.dyson] Creating new Dyson platform
2017-05-15 14:23:13 INFO (Thread-3) [homeassistant.components.fan.dyson] Connected to Dyson account
2017-05-15 14:23:13 INFO (Thread-3) [homeassistant.components.fan.dyson] Trying to connect to device DysonDevice(PE8-UK-HHA0158A,True,Pürity,21.03.08,True,False,455,None) with timeout=10 and retry=3
2017-05-15 14:23:21 WARNING (MainThread) [homeassistant.setup] Setup of fan is taking over 10 seconds.
2017-05-15 14:23:23 WARNING (MainThread) [homeassistant.components.fan] Setup of platform dyson is taking over 10 seconds.
2017-05-15 14:23:23 ERROR (Thread-3) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 0
2017-05-15 14:23:36 ERROR (Thread-3) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 1
2017-05-15 14:23:48 ERROR (Thread-3) [libpurecoollink.dyson] Unable to find device PE8-UK-HHA0158A, try 2
2017-05-15 14:23:51 WARNING (Thread-3) [homeassistant.components.fan.dyson] Unable to connect to device DysonDevice(PE8-UK-HHA0158A,True,Pürity,21.03.08,True,False,455,None)

Hi and sorry for the delay, I have been quite busy this week and I was unable to find a way to improve the device discovery.

It is not acceptable if discovery is not working fine but I had an idea this morning and I would like to share with you and get your feedback (and of course your help). It’s not perfect but at least, with a little work, I think it can bypass the discovery issue.

Just a few words to explain how are working Dyson devices (Pure cool link but I think the 360 robot should work the same way) and this component:

I’m doing HTTP requests to Dyson web services (with email/password/language) in order to have information about Dyson devices. In the web services responses, I have useful information like device name, device id, encrypted device credentials (different from Dyson account credentials), …
Nevertheless, I don’t have the devices IP address (and it’s fair because it can change) so I have to do a multicast DNS (mDNS) request to discover devices on the local network. If I have answers from the mDNS request, I can then connect using MQTT protocol directly to the devices using decrypted credentials. With MQTT I’m able to get device status and send commands. Success !

The issue you have (not always but we are at least 3 to had this issue at least once so it’s not an exception) is sometimes, for an unknown reason, the Dyson devices refuse to answer to mDNS requests. I can’t explain why. Maybe I’m not sending a valid mDNS request, maybe the device is not understanding the request, maybe the device is to lazy to answer … No idea yet.

What I propose to test is to bypass the mDNS discovery step by providing the IP address directly to the component (in the configuration). It should work and it can bypass another limitation with mDNS protocol: it can only work in the same network. If your Home Assistant is not on the same network (you have a router between HA and your Dyson devices), it can not work. It must not be your case because it worked at least once.

The drawback of this solution is it is not really easy to find devices IP addresses so it should only be used if discovery is not working.

How to find devices IP Addresses

With nmap tool we can do a network scan to find computer with MQTT enable:

$ nmap -p 1883 192.168.0.0/24 --open

Starting Nmap 6.40 ( http://nmap.org ) at 2017-05-20 11:37 CEST
Nmap scan report for 192.168.0.103
Host is up (0.012s latency).
PORT     STATE SERVICE
1883/tcp open  unknown

Nmap scan report for 192.168.0.213
Host is up (0.051s latency).
PORT     STATE SERVICE
1883/tcp open  unknown

Nmap scan report for home-assistant.lan (192.168.0.233)
Host is up (0.00044s latency).
PORT     STATE SERVICE
1883/tcp open  unknown

Nmap done: 256 IP addresses (16 hosts up) scanned in 6.25 seconds

Installing nmap is out of scope and depends of your OS but is is something like apt-get install nmap on Debian/Ubuntu, yum install nmap on Red-hat/CentOS, brew install nmap on MacOS X with Homebrew or using the Installer on Windows. It can be done from the Home Assistant computer itself or from any other computer/laptop on the same network.

In this example, I’m scanning my local network (192.168.0.0/24 but it can be something else like 192.168.1.0/24) and I have 3 results (as expected):

  • The last one (192.168.0.233) is my Home Assistant installation because I have enable MQTT to implement some automation => to ignore
  • The 2 others results are my Dyson devices: 192.168.0.103 and 192.168.0.213. If you have only 1 Dyson device, it will be quite easy. In my case I’ll have to test 2 possibilities.

What I would like to have in the configuration is something like that (not yet implemented, just a proposition):

dyson:
  username: <email>
  password: <password>
  language: <language_code>
  timeout: 5 # optional
  retry: 1 # optional
  devices: # Optional, only if discovery is not working
    - device_id: <device_id_1>
      device_ip_address: <device_1_ip_address>
    - device_id: <device_id_2>
      device_ip_address: <device_2_ip_address>
    ...

If devices is provided, I’ll bypass the mDNS discovery step.

As you can see, I need the devices ID too. I can be able to use the device name (Pürity and Cooley in your feedback) but I think device ID will be more reliable. The question is: How to find device_id ? In fact you already had your devices ID in the debug logs you provided (PE8-UK-HHA0158A for example) but you can also use the Dyson link mobile application to get the device ID (on the device page, click on Settings)

NN2-EU-HFA0516A in my example.

Feedback

Now, I’ll would like to have your feedback about this proposition. With information I gave, are you able to provide Devices ID and IP address ? I don’t need them, just to know if you were able to gather them.
And do you think it is acceptable to provide a component with some complex (?) manual steps to configure ? Of course, this manual step must only be used if discovery is not working.

Thanks for your help !

To bad you can’t get dicovery to work reliable…
But your proposition is great in my opinion!
I don’t use discovery at all for any of my hass components. All my stationary devices get a fixed IP address through DHCP so I know all ip addresses. Getting the device_id of my Dyson in the app shouldn’t be a problem for me.

Hi

Yes, I have no issue using nmap - network engineer by trade
Using HA in general requires some knowledge, if not self learning - based on that, most people would be fine with using nmap, or even finding their Dyson devices IP address in their router

I have given mine a static IP in the router. Going forward, I would actually recommend this for this module anyway. You wouldnt want to be running a discovery manually, and then updating the yaml with its new IP every time it changes IP address

I can confirm Im able to get the device ID’s from the Link App. And, as you suggest it does appear in the homeassistant log file anyway

An update on my situation, my purifier had its IP changed and discovery wasnt working for some reason. So Ive switched it to a reservation in my router and it is picked up fine.

My next step, is to try and import the robot, and other IoT Dyson devices I have around the house and start playing with any data I can get back from any of them
I’ll post some feedback on this when I get around to it

Thanks for your hard work so far :slight_smile:

Having the option to specify the IP address works great for me too.

I have a MAC address reservation set in my DHCP scope for my fan so this is no issue for me either.

Hi,

With a delay, I just submit the PR: https://github.com/home-assistant/home-assistant/pull/7795

I have now to write the documentation…

@CharlesBlonde, I’ll give your latest version a test using the manual setup if you can point me in the direction of grabbing the latest version of the file(s).

@michael.muir You are right, I forgot to explain how to use this version …

You’ll have to create 3 files:

And in the configuration.yaml

dyson:
  username: <email>
  password: <password>
  language: <language_code>
  devices:
    - device_id: <device_id1>
      device_ip: <device_ip1>
    - device_id: <device_id2>
      device_ip: <device_ip2>
   ...

fan:
  - platform: dyson

sensor:
  - platform: dyson

Restart Home Assistant and it should work.

Feel free do to a review of the documentation too: https://github.com/home-assistant/home-assistant.github.io/pull/2721/files (on the content and on the english language level :slight_smile: )

Thanks !

@CharlesBlonde I think I might be missing something here, do I need some additional dependencies too?

2017-05-28 20:12:11 ERROR (MainThread) [homeassistant.loader] Error loading custom_components.fan.dyson. Make sure all dependencies are installed
Traceback (most recent call last):
File “/usr/local/lib/python3.5/dist-packages/homeassistant/loader.py”, line 141, in get_component
module = importlib.import_module(path)
File “/usr/lib/python3.5/importlib/init.py”, line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File “”, line 986, in _gcd_import
File “”, line 969, in _find_and_load
File “”, line 958, in _find_and_load_unlocked
File “”, line 673, in _load_unlocked
File “”, line 665, in exec_module
File “”, line 222, in _call_with_frames_removed
File “/home/michael/.homeassistant/custom_components/fan/dyson.py”, line 6, in
from homeassistant.components.dyson import DYSON_DEVICES
ImportError: No module named ‘homeassistant.components.dyson’
2017-05-28 20:12:11 ERROR (MainThread) [homeassistant.loader] Unable to find component fan.dyson
2017-05-28 20:12:23 ERROR (MainThread) [homeassistant.loader] Error loading custom_components.sensor.dyson. Make sure all dependencies are installed
Traceback (most recent call last):
File “/usr/local/lib/python3.5/dist-packages/homeassistant/loader.py”, line 141, in get_component
module = importlib.import_module(path)
File “/usr/lib/python3.5/importlib/init.py”, line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File “”, line 986, in _gcd_import
File “”, line 969, in _find_and_load
File “”, line 958, in _find_and_load_unlocked
File “”, line 673, in _load_unlocked
File “”, line 665, in exec_module
File “”, line 222, in _call_with_frames_removed
File “/home/michael/.homeassistant/custom_components/sensor/dyson.py”, line 4, in
from homeassistant.components.dyson import DYSON_DEVICES
ImportError: No module named ‘homeassistant.components.dyson’
2017-05-28 20:12:23 ERROR (MainThread) [homeassistant.loader] Unable to find component sensor.dyson

It seems Home Assistant is unable to find the parent Dyson component (hub).

Following your logs, the file should be here : /home/michael/.homeassistant/custom_components/dyson.py with the following content: https://github.com/CharlesBlonde/home-assistant/blob/dyson/homeassistant/components/dyson.py

If it’s not working, try to put this file in the same directory where the alexa.py file is (find /<home-assistant-directory>/ -name alexa.py).

I never heard about custom_components directory, do you have a link with documentation ? Because it can be very useful.

@CharlesBlonde not much in regards to documentation but https://home-assistant.io/developers/creating_components/

Also I do not appear to have a alexa.py file.

Ok, I just did some tests and it seems component dependencies doesn’t work with custom_components directory (dependencies are searched in the Home Assistant directory and not in custom_components folder).
So you can keep fan/dyson.py and sensor/dyson.py in custom_components folder but you’ll have to put the hub/parent Dyson component in Home Assistant main directory.

The problem is to find where is your Home Assistant main directory. With your logs, I think it is in /usr/local/lib/python3.5/dist-packages/homeassistant/. So the the file has to added to /usr/local/lib/python3.5/dist-packages/homeassistant/components/dyson.py (and the alexa.py should be in the same directory).

Does it help ?

@CharlesBlonde I think we are one step closer, I moved the parent file into /usr/local/lib/python3.5/dist-packages/homeassistant/components/dyson.py as requested and we have much fewer errors now.

When the sensor/dyson.py was used it broke my sensors (which threw the house into turmoil) so I’ll deal with that one shortly but the inclusion of the fan now only produces the following result in the log:

File "/home/michael/.homeassistant/custom_components/fan/dyson.py", line 6, in <module>
    from homeassistant.components.dyson import DYSON_DEVICES
  File "/usr/local/lib/python3.5/dist-packages/homeassistant/components/dyson.py", line 90
    return False
               ^
SyntaxError: 'return' outside function

Hi,

I can’t access my environment test right now but I think this issue is due to a copy/paste error. Python is indentation dependant and this error means there is an indentation error . It can be my fault but I guess you made a mistake while you created the file (else the units tests should have failed).

Can you check twice the file is correct?

Morning

Ive updated the components as above, and gotten the same problem with my sensors. Theyve all gone
my update process was just,
cd to the destination directory (home assistant/components/…) for those files (dyson.py) and then
wget (github URL)
overwriting if needed

This is the HA log currently.
It worked better with the old version of dyson.py as it was able to pick up more than one device (but not a robot unfortunately)

2017-05-31 09:25:03 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File “/usr/lib/python3.5/asyncio/tasks.py”, line 239, in _step
result = coro.send(None)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/helpers/discovery.py”, line 155, in async_load_platform
hass, component, hass_config)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/setup.py”, line 49, in async_setup_component
return (yield from setup_tasks[domain])
File “/usr/lib/python3.5/asyncio/futures.py”, line 382, in iter
return self.result() # May raise too.
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/asyncio/tasks.py”, line 241, in _step
result = coro.throw(exc)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/setup.py”, line 60, in async_setup_component
return (yield from task)
File “/usr/lib/python3.5/asyncio/futures.py”, line 380, in iter
yield self # This tells Task to wait for completion.
File “/usr/lib/python3.5/asyncio/tasks.py”, line 304, in _wakeup
future.result()
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/asyncio/tasks.py”, line 239, in _step
result = coro.send(None)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/setup.py”, line 155, in _async_setup_component
conf_util.async_process_component_config(hass, config, domain)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/config.py”, line 567, in async_process_component_config
platform = get_platform(domain, p_name)
File “/usr/local/lib/python3.5/dist-packages/homeassistant/loader.py”, line 103, in get_platform
return get_component(PLATFORM_FORMAT.format(domain, platform))
File “/usr/local/lib/python3.5/dist-packages/homeassistant/loader.py”, line 141, in get_component
module = importlib.import_module(path)
File “/usr/lib/python3.5/importlib/init.py”, line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File “”, line 986, in _gcd_import
File “”, line 969, in _find_and_load
File “”, line 958, in _find_and_load_unlocked
File “”, line 673, in _load_unlocked
File “”, line 669, in exec_module
File “”, line 775, in get_code
File “”, line 735, in source_to_code
File “”, line 222, in _call_with_frames_removed
File “/usr/local/lib/python3.5/dist-packages/homeassistant/components/sensor/dyson.py”, line 7

^
SyntaxError: invalid syntax

Im going to reverse the changes so I get the sensors back, but let me know if you need any further testing done

Ta
Paul

Hum, it’s maybe my fault because I made link to Github pages and not to the raw files them self (I hope, because else I don’t understand).

@elPaulio can you edit your sensors/dyson.py file (vi, nano, etc) and tell me if it is a Python or HTML file ?
@michael.muir Have you been able to do some more tests ?

I give you the direct links to the raw files (you can wget/curl this URLs and overwrite existing files).:

If it’s fixing your issues, I’m really sorry because I made wrong links …

And note that a developer added comments on the PR and I’ll have to do some changes. And there will be an impact on configuration.yaml file. I hope I’ll be able to do this changes before this WE and I’ll keep you posted.

You are right, it is HTML files, I didnt think to check the files themselves, just thought I had a conflicting sensor or something :slight_smile:

I’ll overwrite them with the new links - no worries

Cheers