home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.11k stars 29.79k forks source link

Dyson Integration unable to log on #38607

Closed olbjan closed 4 years ago

olbjan commented 4 years ago

The problem

Starting within the last 24 hours the Dyson integration has stopped working when HA is being restarted. It can no longer log on to the Dyson cloud account.

Environment

Problem-relevant configuration.yaml

dyson:
  username: !secret dyson_user
  password: !secret dyson_password
  language: DE
  devices:
    - device_id: !secret dyson_device_id # eg: Pure Cool Link device
      device_ip: 192.168.0.19

Traceback/Error logs

2020-08-06 17:45:15 INFO (MainThread) [homeassistant.setup] Setting up dyson
2020-08-06 17:45:15 INFO (SyncWorker_5) [homeassistant.components.dyson] Creating new Dyson component
2020-08-06 17:45:15 INFO (SyncWorker_5) [homeassistant.components.dyson] Creating new Dyson component
2020-08-06 17:45:15 ERROR (SyncWorker_5) [homeassistant.components.dyson] Not connected to Dyson account. Unable to add devices
2020-08-06 17:45:15 ERROR (SyncWorker_5) [homeassistant.components.dyson] Not connected to Dyson account. Unable to add devices
2020-08-06 17:45:15 INFO (MainThread) [homeassistant.setup] Setup of domain dyson took 0.7 seconds
2020-08-06 17:45:15 ERROR (MainThread) [homeassistant.setup] Setup failed for dyson: Integration failed to initialize.

Additional information

Krocko commented 4 years ago

I have the same problem.

tobiaswrzal commented 4 years ago

Same here. Issue started to appear for me after upgrading to 0.113.3

Phontana commented 4 years ago

Same here. I just added my new Dyson fan yesterday and it worked fine. I was already on 0.113.3. After a Home Assistant restart I just did, I get the same error message.

I just tried the login POST request I looked up in the code of the integration (https://github.com/etheralm/libpurecool/blob/master/libpurecool/dyson.py) made by @etheralm and that seems to work fine, I get a HTTP 200 response. Based on the code and my results, the login should return true instead of false what it does right now.

det-peralta commented 4 years ago

yeah have the same problem

googanhiem commented 4 years ago

Same on Hassio. It happened today after a reboot.

Don’t think 113.3 is the cause as I was running that for a day before the issue. Anyone try downgrading?

googanhiem commented 4 years ago

Seems the dyson api servers are down, which is required for the device list and authentication. https://github.com/etheralm/libpurecool/issues/23

geekofweek commented 4 years ago

I think @Phontana is on to something. I also ran down the API doing both the POST and GET commands and receive a 200 response with the proper JSON payload, however it appears the library thinks it is not getting a proper response and sets the login value to FALSE those making the home assistant integration dump out thinking you never logged in.

googanhiem commented 4 years ago

Looks like the integrations user agent is getting blocked, Dyson might be trying to keep non-app users from using the api. https://github.com/etheralm/libpurecool/issues/24

sungokay commented 4 years ago

I think that the problem is caused by a Dyson server. The Dyson server's filtering and blocking a python request. That's because I had solved the problem after adding a "User-Agent: curl/7.64.0" to web request as a below.

--- libpurecool/dyson.py.org    2020-08-06 17:21:28.046324038 +0900
+++ libpurecool/dyson.py        2020-08-07 16:57:22.738101057 +0900
@@ -39,6 +39,7 @@
         self._country = country
         self._logged = False
         self._auth = None
+        self._headers = {'User-Agent': 'curl/7.64.0'}

     def login(self):
         """Login to dyson web services."""
@@ -52,7 +53,7 @@
         }
         login = requests.post(
             "https://{0}/v1/userregistration/authenticate?country={1}".format(
-                DYSON_API_URL, self._country), request_body, verify=False)
+                DYSON_API_URL, self._country), headers=self._headers, data=request_body, verify=False)
         # pylint: disable=no-member
         if login.status_code == requests.codes.ok:
             json_response = login.json()
@@ -68,10 +69,10 @@
         if self._logged:
             device_response = requests.get(
                 "https://{0}/v1/provisioningservice/manifest".format(
-                    DYSON_API_URL), verify=False, auth=self._auth)
+                    DYSON_API_URL), headers=self._headers, verify=False, auth=self._auth)
             device_v2_response = requests.get(
                 "https://{0}/v2/provisioningservice/manifest".format(
-                    DYSON_API_URL), verify=False, auth=self._auth)
+                    DYSON_API_URL), headers=self._headers, verify=False, auth=self._auth)
             devices = []
             for device in device_response.json():
                 if is_360_eye_device(device):
googanhiem commented 4 years ago

Those header changes look good, don't know how to test custom requirements since I recently moved to hassio. Anyone else try it?

@sungokay you going put a pull request for libpurecool?

sungokay commented 4 years ago

@googanhiem I’m sorry I hadn’t requested that. It’s not familiar to me. So I just had tested it on my raspberry pi.

geekofweek commented 4 years ago

I looked at that for way too many hours and even did test python user agents GET and POST data thinking that was it but they all passed, apparently it's a very narrowly focused user-agent block. That was going to be my next step in testing this morning, so this is a solid find.

Ideally if we could find the User-agent that the app is using it would keep their ability to block in the future pretty limited.

KibosJ commented 4 years ago

The user-agent appears to be DysonLink/29019 CFNetwork/1188 Darwin/20.0.0

MartianMH1 commented 4 years ago

Thanks a lot, works with DysonLink/29019 CFNetwork/1188 Darwin/20.0.0 for me

Phontana commented 4 years ago

Just updated the dyson.py file in my Home Assistant Docker instance and the new user agent seems to fix the issue.

Krocko commented 4 years ago

How to do that @Phontana?

Phontana commented 4 years ago

@Krocko The easiest way to do it is by mounting the new dyson.py file from the PR to the Docker container. In docker-compose it can be done this way:

volumes:
  - /PATH/TO/LOCAL/FILE/dyson.py:/usr/local/lib/python3.8/site-packages/libpurecool/dyson.py

You can also ssh into the container and edit the file at the location in the snippet above.

BreBar07 commented 4 years ago

Does anyone know where the file is located on Hassio? I’ve searched for us and also used find dyson.py But no such file exists....

oneseventhree commented 4 years ago

Any update if there is a fix for this?

Phontana commented 4 years ago

@oneseventhree as you can see in the thread above several people are working towards a fix. There is a pull request which needs to be merged into the main branch and then a library bump in Home Assistant is required. So we need to wait for that to happen. In the meantime, you can temporarily fix it with the instructions above.

oneseventhree commented 4 years ago

@oneseventhree as you can see in the thread above several people are working towards a fix. There is a pull request which needs to be merged into the main branch and then a library bump in Home Assistant is required. So we need to wait for that to happen. In the meantime, you can temporarily fix it with the instructions above.

Thank you. I have no idea how to update my files on docker, mine is running on a RasberryPi?

KibosJ commented 4 years ago

For those using the Docker container the file is located at /usr/local/lib/python3.8/site-packages/libpurecool/

Also as a quick note you should use find -name dyson.py

niekniek89 commented 4 years ago

Hello,

I have adjusted the below, but unfortunately it doesn't work yet. I may still miss some rules

self._headers = {'User-Agent': 'DysonLink/29019 CFNetwork/1188 Darwin/20.0.0'}

KibosJ commented 4 years ago

Hello,

I have adjusted the below, but unfortunately it doesn't work yet. I may still miss some rules

self._headers = {'User-Agent': 'DysonLink/29019 CFNetwork/1188 Darwin/20.0.0'}

Replace the whole file, there's more than just that line changed

niekniek89 commented 4 years ago

@KibosJ thnx for you’re help. You mean this whole file:

https://github.com/etheralm/libpurecool/pull/25/commits/90a17ecc32ff17196044773b55649364444508b9

KibosJ commented 4 years ago

@KibosJ thnx for you’re help. You mean this whole file:

etheralm/libpurecool@90a17ec

Yup 🙂

https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py

Just replace it with that file, either manually or using Phontana's method of mounting it into the container (https://github.com/home-assistant/core/issues/38607#issuecomment-670936284)

niekniek89 commented 4 years ago

is there an easier way than via portainer console to replace the whole file? I don’t use docker compose... copy paste in the console in portainer?

KibosJ commented 4 years ago

is there an easier way than via portainer console to replace the whole file? I don’t use docker compose... copy paste in the console in portainer?

In console you could use curl

  1. cd /usr/local/lib/python3.8/site-packages/libpurecool/
  2. mv dyson.py dyson.py.old or rm dyson.py
  3. curl -O https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py
oneseventhree commented 4 years ago

is there an easier way than via portainer console to replace the whole file? I don’t use docker compose... copy paste in the console in portainer?

In console you could use curl

  1. cd /usr/local/lib/python3.8/site-packages/libpurecool/
  2. mv dyson.py dyson.py.old or rm dyson.py
  3. curl -O https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py

I've downloaded portainer onto my HA UI. Where's "Console"?

KibosJ commented 4 years ago

is there an easier way than via portainer console to replace the whole file? I don’t use docker compose... copy paste in the console in portainer?

In console you could use curl

  1. cd /usr/local/lib/python3.8/site-packages/libpurecool/
  2. mv dyson.py dyson.py.old or rm dyson.py
  3. curl -O https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py

I've downloaded portainer onto my HA UI. Where's "Console"?

Screenshot 2020-08-09 at 09 52 16@2x

niekniek89 commented 4 years ago

@KibosJ it works!!! thnx for you're help!

oneseventhree commented 4 years ago

Worked for me too. Thanks!

BreBar07 commented 4 years ago

Thanks everyone awesome working for me too! Also second dyson device (HP04) which previously didnt should up as a "climate" device is now working! Great result, thanks again!

noheton commented 4 years ago

Works for me as well.

arifroni commented 4 years ago

Where can i find this file on hassio running on raspberry pi4?

genericnerd99 commented 4 years ago

Same error for me, im running Home Assistant 0.113.3 on Ubuntu 20.04.1 LTS I don't have the same path as the others and after searching whole drive i don't have a dyson.py anywhere :/

rayng86 commented 4 years ago

will there eventually be some kind of pr to address this issue?

Phontana commented 4 years ago

There is a PR already, that’s where the changes mentioned in this thread are coming from: https://github.com/etheralm/libpurecool/pull/25. I think we should wait for @etheralm to review and merge it, and then a PR for Home Assistant can be made.

curt7000 commented 4 years ago

Same error for me, im running Home Assistant 0.113.3 on Ubuntu 20.04.1 LTS I don't have the same path as the others and after searching whole drive i don't have a dyson.py anywhere :/

Same here, running HA in a VENV on Ubuntu Server, any advise where to find the dyson.py file?

googanhiem commented 4 years ago

If you're in a venv it should be in your python site packages, so

/srv/homeassistant/lib/python3.7/site-packages/libpurecool/dyson.py

or

/srv/homeassistant/lib/python3.8/site-packages/libpurecool/dyson.py

curt7000 commented 4 years ago

If you're in a venv it should be in your python site packages, so

/srv/homeassistant/lib/python3.7/site-packages/libpurecool/dyson.py

or

/srv/homeassistant/lib/python3.8/site-packages/libpurecool/dyson.py

Found it in /srv/homeassistant/lib/python3.8/site-packages/libpurecool/dyson.py

Working! Thank you!

tongaimaramba commented 4 years ago

Hey all. Firstly, thanks to everyone on this thread for the fast work solving the problem, it was impressive to watch!

Sorry to be bringing this noob question to this thread (I'm sure I'm asking in totally the wrong place), but I hope the answer will be quick and easy for one of you: how do I install this integration?

  1. I set up the configuration as recommended in the documentation - then I got the log-in error which brought me to this thread. Screenshot 2020-08-10 at 15 50 54
  2. I copied the files from the Dyson repository into my /config/custom_components folder
  3. I installed Portainer and then followed the suggestion to use curl by @KibosJ

Now I'm getting "Setup failed for dyson: Unable to import component: No module named 'libpurecool.dyson'" in my logs. I'm sure I did something wrong in the set-up so I thought I'd start again and ask the experts.

Any advice?

googanhiem commented 4 years ago

You don't need a custom component for this fix. Using portainer to replace the dyson.py file should be the only change required. Are you sure you didn't just rename the file with the first step and not download the file with the curl command? I'd suggest using the portainer console to,

  1. cd /usr/local/lib/python3.8/site-packages/libpurecool/
  2. ls (if no dyson.py is in the list of files, you didn't download it correctly)
  3. curl -O https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py (make sure that's all in one command, not two lines, if it errors out tell us what you get)
tongaimaramba commented 4 years ago

You don't need a custom component for this fix. Using portainer to replace the dyson.sh file should be the only change required. Are you sure you didn't just rename the file with the first step and not download the file with the curl command? I'd suggest using the portainer console to,

  1. cd /usr/local/lib/python3.8/site-packages/libpurecool/
  2. ls (if no dyson.sh is in the list of files, you didn't download it correctly)
  3. curl -O https://raw.githubusercontent.com/etheralm/libpurecool/90a17ecc32ff17196044773b55649364444508b9/libpurecool/dyson.py (make sure that's all in one command, not two lines, if it errors out tell us what you get)

Success! Thank you. (for anyone reading this in future, I assumed on step 2 that when you said dyson.sh, you meant dyson.py?)

googanhiem commented 4 years ago

I assumed on step 2 that when you said dyson.sh, you meant dyson.py?

Yes, apologies, I've got scripts on the mind. I've now edited the comment.

MightyMo1704 commented 4 years ago

Hello everybody, sorry for being a total noob. I guess there is a lot of description in here on how to fix this issue. But i dont seem to get it fixed. I have a HomeAssistant running on a pi4 HassOs 4.12. I wanted to ssh into the Pi and change the Dyson.py but under /usr/local/lib/python3.8/site-packages/libpurecool/ i can only get to /lib and the rest is missing/not there. What am i doing wrong? Where are the Files?

googanhiem commented 4 years ago

I imagine you have ssh’d into the host os.

You’ll need to install the portainer addon in supervisor and use the console for the homeassistant container (As shown in the pic above). Follow the steps, but if you really don’t understand what you’re doing it might be worth waiting until this goes mainline.

MightyMo1704 commented 4 years ago

I image you have ssh’d into the host os.

You’ll need to install the portainer addon in supervisor and use the console for the homeassistant container (As shown in the pic above). Follow the steps, but if you really don’t understand what you’re doing it might be worth waiting until this goes mainline.

Thank you for your answer. I might not understand what iam doing right now :D but thats the only way for me to learn how this stuff works. If i mess something up i have no problem with starting from scratch!

Thanks again ill see where your hint will get me 📦 Best Regards

BreBar07 commented 4 years ago

Hey All, this morning on restart my 2x Dyson machines wont connect to HA. I get the following errors, any ideas?

2020-08-11 09:48:38 WARNING (MainThread) [homeassistant.setup] Setup of dyson is taking over 10 seconds. 2020-08-11 09:48:49 WARNING (MainThread) [homeassistant.bootstrap] Waiting on integrations to complete setup: dyson 2020-08-11 09:49:08 ERROR (SyncWorker_7) [homeassistant.components.dyson] Unable to connect to device NetworkDevice(name=XXX Dyson,address=xxx.xxx.xxx.xxx,port=1883): [Errno 113] Host is unreachable

Re-checked and problem has resolved itself, assume Dyson doing some things on their end.

googanhiem commented 4 years ago

Re-checked and problem has resolved itself, assume Dyson doing some things on their end.

I have always found the Dyson integration is prone to random little connection issues here and there. From what I can tell, if one device is temporarily disconnected it can timeout the setup in HA. It usually requires a restart of HA to fix.

It would be smart to get the HA integration to cache the device list and authentication for some period of time, that would solve most problems. It might also reduce the amount of queries we throw at the dyson servers, making it harder for them to shut down the integration.