core: Dyson integration stopped working with 2021.2

The problem

I have been using the dyson integration with my hot/cold fan successfully for a while. I upgraded HA last night to 2021.2 and saw alerts that the integration couldn’t initialize

What is version of Home Assistant Core has the issue?

2021.2

What was the last working version of Home Assistant Core?

2021.1

What type of installation are you running?

Home Assistant Core

Integration causing the issue

Dyson

Link to integration documentation on our website

https://www.home-assistant.io/integrations/dyson/

Example YAML snippet

dyson:
  username: EMAIL
  password: !secret SECRET
  language: GB
  devices:
    - device_id: DEVICE_ID
      device_ip: LAN_IP

Anything in the logs that might be useful for us?


# First Warning in logs

2021-02-11 03:17:41 ERROR (SyncWorker_2) [homeassistant.components.dyson] Not connected to Dyson account. Unable to add devices
2021-02-11 03:17:41 INFO (MainThread) [homeassistant.setup] Setup of domain dyson took 0.6 seconds
2021-02-11 03:17:41 ERROR (MainThread) [homeassistant.setup] Setup failed for dyson: Integration failed to initialize.
2021-02-11 03:17:41 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=persistent_notification, service=create, service_data=title=Invalid config, message=The following integrations and platforms could not be set up:
- dyson


# Later warning in logs. I'm not sure if this is actually from dyson or not. The IP looked weird, but when I googled it, it's some AWS thing. 

2021-02-11 03:17:41 ERROR (SyncWorker_2) [homeassistant.components.dyson] Not connected to Dyson account. Unable to add devices
2021-02-11 03:17:41 INFO (MainThread) [homeassistant.setup] Setup of domain dyson took 0.6 seconds
2021-02-11 03:17:41 ERROR (MainThread) [homeassistant.setup] Setup failed for dyson: Integration failed to initialize.
2021-02-11 03:17:41 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=persistent_notification, service=create, service_data=title=Invalid config, message=The following integrations and platforms could not be set up:
- dyson
Please check your config and [logs](/config/logs)., notification_id=invalid_config>
2021-02-11 03:17:41 DEBUG (SyncWorker_0) [botocore.utils] Caught retryable HTTP exception while making metadata service request to http://169.254.169.254/latest/api/token: Connect timeout on endpoint URL: "http://169.254.169.254/latest/api/token"
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 169, in _new_conn
conn = connection.create_connection(
File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 96, in create_connection
raise err
File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 86, in create_connection
sock.connect(sa)
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/botocore/httpsession.py", line 311, in send
urllib_response = conn.urlopen(
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 755, in urlopen
retries = retries.increment(
File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 506, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/usr/local/lib/python3.8/site-packages/urllib3/packages/six.py", line 735, in reraise
raise value
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 234, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/local/lib/python3.8/http/client.py", line 1255, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.8/site-packages/botocore/awsrequest.py", line 92, in _send_request
rval = super(AWSConnection, self)._send_request(
File "/usr/local/lib/python3.8/http/client.py", line 1301, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.8/http/client.py", line 1250, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.8/site-packages/botocore/awsrequest.py", line 120, in _send_output
self.send(msg)
File "/usr/local/lib/python3.8/site-packages/botocore/awsrequest.py", line 204, in send
return super(AWSConnection, self).send(str)
File "/usr/local/lib/python3.8/http/client.py", line 950, in send
self.connect()
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 200, in connect
conn = self._new_conn()
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 174, in _new_conn
raise ConnectTimeoutError(
urllib3.exceptions.ConnectTimeoutError: (<botocore.awsrequest.AWSHTTPConnection object at 0x7f41143bd5e0>, 'Connection to 169.254.169.254 timed out. (connect timeout=1)')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/botocore/utils.py", line 377, in _fetch_metadata_token
response = self._session.send(request.prepare())
File "/usr/local/lib/python3.8/site-packages/botocore/httpsession.py", line 344, in send
raise ConnectTimeoutError(endpoint_url=request.url, error=e)
botocore.exceptions.ConnectTimeoutError: Connect timeout on endpoint URL: "http://169.254.169.254/latest/api/token"
2021-02-11 03:17:41 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=persistent_notification.invalid_config, old_state=None, new_state=<state persistent_notification.invalid_config=notifying; title=Invalid config, friendly_name=Invalid config, message=The following integrations and platforms could not be set up:
- dyson

I’m running the qcow2 image in KVM. Happy to muck about with suggested tweaks if it helps narrow down the issue.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 28
  • Comments: 156 (10 by maintainers)

Commits related to this issue

Most upvoted comments

i am running a supervised os. i have portainer installed as addon. can anyone tell me how to get it working?

Here are the steps to replace the dyson.py on Pi4 running Home Assistant OS:

  • install Portainer Addon, disable protection mode, start addon and open web-ui.
  • in Portainer settings remove core and homeassistant from the disabled devices
  • now from the containr list select homeassistant, clic the console button and enter the three lines above one after the other:
cd /usr/local/lib/python3.8/site-packages/libpurecool/
rm dyson.py
curl -O https://raw.githubusercontent.com/bfayers/libpurecool/fix_auth/libpurecool/dyson.py
  • Reboot core and Voilà !

Thanks to everyone involved in this integration !

ok, after having to redig into the issue, the permanent solution i have is this:

  1. install HACS
  2. add the following repositories to HACS:
  1. go to configuration -> integration -> + new integration -> dyson cloud
  2. enter your credentials including the 2FA code (yes 2FA code hooray!) and then fill in IP information for each dyson device it finds for you (yes you don’t need to fill in stuff in configuration.yaml anymore)
  3. Done!

At this point, the core integration has been broken for months. If nobody wants to put the time in to fix it (which is fair enough, no complaint here), it might be worth removing it entirely, there’s no point keeping broken code around except letting new users think this is a working integration when it’s not. Or at the very least updating the documentation to make it obvious.

Any update on when this fix will be implemented ?

Hi,

This might sound like a super noob question, but with HassOS, how you do the above?

Thanks!

connect to the console for it and run docker exec -t homeassistant pip3 install --upgrade git+https://github.com/bfayers/libpurecool.git@fix_auth Then restart hass.

You will need to do this after every HASS update until a new library version can be released and set in hass.

At this point, the core integration has been broken for months. If nobody wants to put the time in to fix it (which is fair enough, no complaint here), it might be worth removing it entirely, there’s no point keeping broken code around except letting new users think this is a working integration when it’s not. Or at the very least updating the documentation to make it obvious.

Agree, it’s just misleading to have a posted official integration on HA’s site. Is there an official deprecation procedure?

So this was me, just setup Dyson and found its not working and landed here. Please remove if its not supported and hopefully it will return at some point soon.

so now the big question, how can we get the shenxn dyson integration into the main HA-Core setup and drop the legacy version?

Same here,

update to latest version (2021.3.2 in my case), curl fix (see attached Dyson_problemen.txt), logout of Dyson app, reboot HA, login into Dyson app.

SOLVED

yea, I’m in the same boat as well, just upgraded to 2021.3.0 and it isn’t working anymore

Did the following:

  1. sign out of Dyson App on Phone
  2. Apply fix to HA with bfayers code
  3. signed in Dyson App with the 2FA code (which is new, which I noticed, which other people noticed as well)
  4. quickly try to restart HA right after logging in Dyson App on Phone

If i am missing a step above let me know, thanks!

Also if there are documented ways how to do shenxn\ha-dyson setup, I’m all ears too! (I’ve read the whole thread, and there wasn’t a direct connection/documented way to do it, unless i am super blind, [has happened, sorry in advanced])

While @shenxn achieve the new component development, here is a temporary workaround which does not need to communicate with Dysons servers (talks directly with the fan’s MQTT broker):

https://community.home-assistant.io/t/dyson-pure-cool-link-local-mqtt-control/217263

The down side is that you no longer have a fan entity to expose to HomeKit for example…

Yes, this component is a little clunky and forgotten. @shenxn is looking to build a new component that may fix a lot of the current issues.

The current component relies on this initial auth to gain control, these credentials are not cached so they’re updated on every reboot of HA.

@kurozero0 The Dyson website and this component appear to use different servers, so the issues are probably unrelated

For what it’s worth, it doesn’t work after downgrade to 2021.1.5 either, so it looks like a Dyson-side change

I guess that now that Dyson has changed something on their end, Dyson Cloud isn’t able to login anymore (probably as of yesterday). Hope there’s a way to solve this!

For you, and anyone else in the thread trying to use shexn’s integration (or the stock one with my library change)

Sign out of the Dyson App, then log into it again and then restart home assistant as soon as you’ve logged in on the app - should be fine after that.

Last week, the problem was solved by replacing dyson.py by: https://raw.githubusercontent.com/bfayers/libpurecool/auth_customdeps/libpurecool/dyson.py

It stops working today. No success with: pip3 install --upgrade git+https://github.com/bfayers/libpurecool.git@fix_auth

i am running a supervised os. i have portainer installed as addon. can anyone tell me how to get it working?

Here are the steps to replace the dyson.py on Pi4 running Home Assistant OS:

  • install Portainer Addon, disable protection mode, start addon and open web-ui.
  • in Portainer settings remove core and homeassistant from the disabled devices
  • now from the containr list select homeassistant, clic the console button and enter the three lines above one after the other:
cd /usr/local/lib/python3.8/site-packages/libpurecool/
rm dyson.py
curl -O https://raw.githubusercontent.com/bfayers/libpurecool/auth_customdeps/libpurecool/dyson.py
  • Reboot core and Voilà !

Thanks to everyone involved in this integration !

You are a life saver! Thank you!!!

In my case my machines have static IPs and they are all configured manually in my configuration.yml, so I don’t know why in this case this integration even needs the email and password.

While the machines themselves run local MQTT they need credentials that only the Dyson server can provide 😕

This is still an issue pending #53801.

I have been holding off any of these fixes hoping the fix would be added to Core, but today I removed all existing dyson integration and entities, added the dyson-local integration to HACS and set up the device using wifi information using the instructions here: https://github.com/shenxn/ha-dyson/

It was super easy, and everything is working fine, wish I did it sooner! Thanks for posting the instructions to add the repository to HACS, it made me finally do it.

ok, after having to redig into the issue, the permanent solution i have is this:

  1. install HACS
  2. add the following repositories to HACS:
  1. go to configuration -> integration -> + new integration -> dyson cloud
  2. enter your credentials including the 2FA code (yes 2FA code hooray!) and then fill in IP information for each dyson device it finds for you (yes you don’t need to fill in stuff in configuration.yaml anymore)
  3. Done!

This worked for me but I just want to tell everyone to make sure your fan is actively on. Being in standby isn’t enough. At least it wasn’t for me. This did work though once my fan was on. Thank you!

curl -O https://raw.githubusercontent.com/bfayers/libpurecool/fix_auth/libpurecool/dyson.py

anyone know why this doesn’t work on Home Assistant Core 2021.3? It worked on the previous release for me.

The Dyson Fan entity doesn’t show up BUT the climate entity does so its half working. Why wouldn’t the fan entity work?

EDIT: I had to DELETE the iPhone App and reinstall - the UI changed on the app so I am guessing there was an update and now it all works - Hope this helps someone else 😃

That seems to make sense why we’re all experiencing the issue since the HA update. The integration authenticates once on HA startup, and so is able to communicate locally. We have all been running out HA for days/weeks, and have had that working credential. Then as we all upgraded and HA rebooted, we’re all now hitting the existing Auth issue as it tries to auth on startup.

For people in this thread - don’t use the auth_customdeps branch - use the fix_auth one @romquenin @curt7000

Hi, sorry new to HA. I’ve done steps 1, 2 but when I do step 3, I don’t see the ‘Dyson Cloud’ option after clicking on ‘+ New Integration’. Have I missed some steps? Thanks!

Have you tried clearing your browser cache or surfing to the integrations page in incognito mode? A few have noted that was required after installing and before the integration showed up. Fwiw I had the same issue a while back and gave up - so let me know if that works for you 😃

Hi, sorry new to HA. I’ve done steps 1, 2 but when I do step 3, I don’t see the ‘Dyson Cloud’ option after clicking on ‘+ New Integration’. Have I missed some steps? Thanks!

Have you tried clearing your browser cache or surfing to the integrations page in incognito mode? A few have noted that was required after installing and before the integration showed up. Fwiw I had the same issue a while back and gave up - so let me know if that works for you 😃

Thank-you stupid-I-clever. I accessed it using a different device and the Dyson integrations are now appearing and have successfully setup my Dyson fans.

ok, after having to redig into the issue, the permanent solution i have is this:

  1. install HACS
  2. add the following repositories to HACS:
  1. go to configuration -> integration -> + new integration -> dyson cloud
  2. enter your credentials including the 2FA code (yes 2FA code hooray!) and then fill in IP information for each dyson device it finds for you (yes you don’t need to fill in stuff in configuration.yaml anymore)
  3. Done!

Hi, sorry new to HA. I’ve done steps 1, 2 but when I do step 3, I don’t see the ‘Dyson Cloud’ option after clicking on ‘+ New Integration’. Have I missed some steps? Thanks!

Native integration: I’ve noticed you don’t need to log out / in on the Dyson mobile app to clear the error (/me on Android) - open HA mobile, open Dyson mobile, restart HA (restart core, restart server, reboot host all seem to work); must be a token refresh refresh / aging cycle on the Dyson app now… You only need to run the auth-fix after HA updates.

fwiw I’ve never had much luck with HACS - my system invariably becomes unstable, many errors, much instability, always end up restoring a pre-hacs snap.

Using HA 2021.3.2.

Applied the curl fix, logged out of the Dyson iOS app, logged back in, used the app, restarted HA.

The integration works again. Not 2FA on the iOS app though.

Still using HA 2021.1.5, not updated. I did applied curl fix some time ago and it was working, and now it is not. So;

logout of Dyson login again with 2FA code sent to my e-mail restart HA

now it is working again.

I guess that now that Dyson has changed something on their end, Dyson Cloud isn’t able to login anymore (probably as of yesterday). Hope there’s a way to solve this!

For you, and anyone else in the thread trying to use shexn’s integration (or the stock one with my library change)

Sign out of the Dyson App, then log into it again and then restart home assistant as soon as you’ve logged in on the app - should be fine after that.

thanks. it works with ha_dyson_cloud and leads to the discovery by ha_dyson.

Now all sensors and scripts work weel

@damiano75 are you using shenxn’s ha-dyson service, or the native integration? It must be ha-dyson as native’s still wonky on my side.

shenxn’s one, because with native integration I have also another issue: every time I unplug my device from the power HA loses the connection with the device and I have to restart HA to re-establish the connection. With this local integration I don’t have any connection issue

@bfayers , that worked like a charm, after restarting HassOS, it now sees all 4 of my Dyson Purifiers now. Hopefully they will integrate this fix in the near future.

@mgaeremynck you might want to remove your serial numbers (“device_id”)… as someone could mess with your dyson account with them.

This login method modification seems to work for me:

   def __init__(self):
        [... existing code...]
        self._authNextTime = None

   def login(self):
        self._logged = False
        if self._authNextTime != None and self._authNextTime > datetime.datetime.now():
            print("Could not identify for the moment, next authent will be made at: %s" % (self._authNextTime))
        else:
            """Login to dyson web services."""
            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
            print("Disabling insecure request warnings since "
                  "dyson are using a self signed certificate.")
            pre_login = requests.get(
                "https://{0}/v1/userregistration/userstatus?country={1}&email={2}".format(
                    self._dyson_api_url, self._country, self._email),
                headers=self._headers,
                verify=False
            )
            print("pre_login return code: %d, text: %s" % (pre_login.status_code, pre_login.text))
            if pre_login.status_code == requests.codes.ok:
                json_response = pre_login.json()
                if 'accountStatus' in json_response and json_response['accountStatus'] == 'ACTIVE':
                    request_body = {
                        "Email": self._email,
                        "Password": self._password
                    }
                    login = requests.post(
                        "https://{0}/v1/userregistration/authenticate?country={1}".format(
                            self._dyson_api_url, self._country),
                        headers=self._headers,
                        json=request_body,
                        verify=False
                    )
                    # pylint: disable=no-member
                    print("login return code: %d, text: %s" % (login.status_code, login.text))
                    if login.status_code == requests.codes.ok:
                        json_response = login.json()
                        print(json_response)
                        self._auth = HTTPBasicAuth(json_response["Account"],
                                                   json_response["Password"])
                        self._logged = True
                    elif 'Retry-After' in login.headers:
                        self._authNextTime = datetime.datetime.now() + datetime.timedelta(seconds=int(login.headers['Retry-After']))
        print("Return %d" % self._logged, flush=True)
        return self._logged

If i can, this week-end, i will make a proper PR. This code use print, this is not safe obviously