Giter VIP home page Giter VIP logo

ha-dyson's Introduction

HomeAssistant Custom Integration for Dyson

This custom integration is still under development.

This is a HA custom integration for dyson. There are several main differences between this custom integration and the official dyson integration:

  • It does not rely on dyson account. Which means once configured, the integration will no longer login to the Dyson cloud service so fast and more reliable start up process.

  • Config flow and discovery is supported, so easier configuration.

  • Based on a new library that is better structured so the code in the integration itself is simplified.

My goal is to make this integration official. However, at the current stage, I don't want to do the changes in core since there could be a lot of breaking changes. Therefore, I'll do be merge when everything seems stable.

Important note regarding connection via Dyson Link

If you use your Dyson Link account to connect to the integration, you may or may not encounter a libdyson.exceptions.DysonInvalidAuth error. In this case, try disconnecting from the mobile app first, it should clear the error. Sometimes, you just need to try multiple times. If you discover a workaround for this issue please open a pull request.

Installation

The minimum supported Home Assistant version is 2021.12.0.

You can install using HACS. Adding https://github.com/shenxn/ha-dyson as custom repository and then install Dyson Local. If you want cloud functionalities as well, add https://github.com/shenxn/ha-dyson-cloud and install Dyson Cloud.

You can also install manually

Local and Cloud

There are two integrations, Dyson Local and Dyson Cloud. Due to the limitation of HACS, they are split into two repositories. This repository hosts Dyson Local, and https://github.com/shenxn/ha-dyson-cloud hosts Dyson Cloud.

Dyson Local

Dyson Local uses MQTT-based protocol to communicate with local Dyson devices using credentials. Currently it supports

  • Dyson 360 Eye robot vacuum
  • Dyson 360 Heurist robot vacuum
  • Dyson Pure Cool
  • Dyson Pure Cool Desk
  • Dyson Pure Cool Link
  • Dyson Pure Cool Link Desk
  • Dyson Pure Hot+Cool
  • Dyson Pure Hot+Cool Link
  • Dyson Pure Humidity+Cool

Dyson Cloud

Dyson Cloud uses HTTP-based API to communicate with cloud service. Currently it supports getting device credentials and show all devices as discovered entities under the Integrations page. It also supports getting cleaning maps as camera entities for 360 Eye robot vacuum.

Setup

Setup using device WiFi information

Version 0.6.1 introduced a new way to set up. This is inspired by https://community.home-assistant.io/t/dyson-pure-cool-link-local-mqtt-control/217263. Set up through UI and select "Setup using WiFi information". Find your device WiFi SSID and password on the sticker on your device body or user's manual (See the figure below). Don't fill in your home WiFi information. Note that this method only uses SSID and password to calculate serial, credential, and device type so you still need to setup your device on the official mobile app first.

Setup using Dyson cloud account

You can also set up Dyson Cloud first so that you don't need to manually get device credentials. To do so, go to Configuration -> Integrations and click the + button. Then find Dyson Cloud. After successful setup, all devices under the account will be shown as discovered entities and you can then set up Dyson Local with single click. Leave host blank to using zeroconf discovery. After that, you can even remove Dyson Cloud entity if you don't need cleaning maps. All local devices that are already set up will remain untouched.

Setup manually

If you want to manually set up Dyson Local, you need to get credentials first. Clone or download https://github.com/shenxn/libdyson, then use python3 get_devices.py to do that. You may need to install some dependencies using pip3 install -r requirements.txt.

Debug Log

To enable debug log, add the following lines to your configuration.yaml and restart your HomeAssistant.

logger:
  default: info
  logs:
    libdyson: debug
    custom_components.dyson_local: debug
    custom_components.dyson_cloud: debug

FAQ

I got "not a valid add-on repository" when I try to add this repo

This is a custom integration not a custom add-on. You need to install HACS and add this repo there.

ha-dyson's People

Contributors

austinbeam avatar crowbarz avatar flameeyes avatar graham33 avatar jasperslits avatar kakise avatar lrb2 avatar pfrybar avatar shenxn avatar vickyg3 avatar

Stargazers

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

Watchers

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

ha-dyson's Issues

API error when sending a dyson_local.set_timer of 0 to cancel timer

Thanks for all the work on this integration, it is really great.

I am using v0.6.0 through HACS

There is a small contradiction between the documentation and the API call for 'dyson_local.set_timer'. When you send a value of 0 it produces an error:

service: dyson_local.set_timer
data:
  entity_id: fan.master_bedroom
  timer: 0

"ValueError: Duration must be between 1 and 540"

However the documentation string in Home Assistant says this should be allowed:
"timer | The value in minutes to set the timer to, 0 to disable it"

I believe values of 0 used to be allowed, to cancel the timer.

Thanks for taking a look. Let me know if you need any further info...

Full log below:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 141, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1488, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 578, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 642, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 681, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 679, in _handle_entity_call
    await result
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/dyson_local/fan.py", line 163, in set_timer
    self._device.set_sleep_timer(timer)
  File "/usr/local/lib/python3.8/site-packages/libdyson/dyson_device.py", line 394, in set_sleep_timer
    raise ValueError("Duration must be between 1 and 540")
ValueError: Duration must be between 1 and 540

Dyson Pure Hot+Cool auto discovered but only adds Climate entity, fan is missing (error: No module named 'homeassistant.util.percentage')

hi,
I was using the homeassistant built in dyson integration uptil a couple of months ago when it stopped working. I have removed that configuration from my configuration.yaml file.
I used the Dyson CLoud and Dyson local configuration to detect my Pure Hot+Cool dyson fan and it was auto discovered.
When I added the device it only added the climate entity, and I am missing the fan controls to set the fanspeed.

I checked and the below error shows up for Dyson.local when setting up the fan entity:

Logger: homeassistant.setup
Source: setup.py:280
First occurred: 9:24:05 (1 occurrences)
Last logged: 9:24:05

Unable to prepare setup for platform dyson_local.fan: Platform not found (No module named 'homeassistant.util.percentage').

I am running homeassistant in a docker and the version is:
Home Assistant 2021.1.5

Support for Dyson Pure Humidify+Cool

Shows up as model 358. It works pretty well, all sensors and controls, with the exception of the desired humidity setting, which is missing. Is it possible to add it? I can help with testing.

integration official

I think the time is good for replacing the old Dyson on the core. If you open a PR soon, it should go into 2021.4

Missing on/off switch

I just updated from version 0.8.1 to 0.11.0. The on/off switch become unavailable. and oscillating as well.
My device is Dyson Pure Cool (TP04)

Pure hot + cool link | Missing oscillation and sleep timer features.

Good day, first of all thank you for creating and maintaining this project, I have recently started using home assistant and this project has been a wonderful addition to my home automation.

All features on displayed on the screenshot below have been working wonderfully, sadly I have been unable to find the oscillation option or the sleep timer that I do have access through on my Dyson remote or the official Dyson app.
From my little python knowledge it seems that these two settings are part of the project and I have also seen the oscillation and sleep timer options in screenshots of other peoples issues for their devices.

Thank you in advance and my apologies if I have missed something very obvious or if I missed an already resolved issue for this.

SSID: DYSON-PT4-EU-XXXXXXXX-455

chrome_rH77Clw9CW
chrome_aYHw8UHypU

Pure Cool Link always in state Off at HA start

Hi, first thank you for working on this! Really nice to have an alternative integration for Dyson especially after the OOTB version started failing last week.

I wanted to let you know that I successfully connected to my Pure Cool Link and everything seems to be going well, except that when the server starts, the fan is always in state "off". I generally leave the fan on Auto 24/7. If I toggle Auto in the Dyson app, then HA catches up and shows On state + Auto speed. I'm not a python expert but happy to try troubleshooting if you'd like.

Thanks!

More service options.

This is an amazing custom component and very good substitute for original built-in dyson integration.
But I cannot find the services for night mode and flow direction.
Is there any way to control these features?

Can't configure Dyson Pure Hot+Cool Link (wrong device type discovered)

I have followed the configuration instructions, but I don't seem to be able to configure this integration properly.

System details:

  • Docker Home Assistant 2021.4.5
  • ha-dyson (attempts with versions v0.10.0 and v0.11.0)
  • Installation using HACS

Note: it seems that the wrong device type is getting discovered (360 Eye robot vacuum, instead Pure Hot+Cool link). To be very clear, I don't have any other Dyson devices than this fan.

Setup manually

Credentials acquired using https://github.com/shenxn/libdyson
Screen Shot 2021-04-22 at 12 08 58 pm
Log message:
DEBUG (MainThread) [custom_components.dyson_local.config_flow] Failed to connect to device:

Setup using device WiFi information logs

Log message:

21-04-22 13:08:12 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Successfully parse WiFi information                                                                                                                                                                                                                                                                            
2021-04-22 13:08:12 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Serial: XXX-AU-XXXXXXXX                                                                                                                                                                                                                                                                                        
2021-04-22 13:08:12 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Device Type: N223                                                                                                                                                                                                                                                                                              
2021-04-22 13:08:12 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Device Type Name: 360 Eye robot vacuum                                                                                                                                                                                                                                                                         
2021-04-22 13:08:12 DEBUG (zeroconf-ServiceBrowser__360eye_mqtt._tcp.local.-_dyson_mqtt._tcp.local._326) [custom_components.dyson_local.config_flow] Found device at XXX.XXX.X.XXX                                                                                                                                                                                                                
2021-04-22 13:08:31 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Failed to connect to device:  

Comparing devices numbers from the credential process (455) does not seem to match the one in the ha-dyson configuration logs (N223).

I have attempted this process selecting either the correct device type (Pure Hot+Cool Link) and the vacuum type as well, always getting Failed to connect to device.

Please let me know what am I doing wrong or missing.

"tm" always added at the end of device name

Hi,

Not a huge deal, but by default my fan came on as "Dyson Pure Link™", which I then renamed to Bedroom fan. Now my entity is named "fan.bedroom_fantm" and I can't seem to be able to do anything about that tm at the end.

Apart from this minor naming issue everything is working like a charm and it's cloudless, many thanks !

'idle' on auto mode indicates as 'off'

I always set my Dyson DP04 on auto mode.
I found a problem.
When DP04 is idle(fan stops because the air is clear), the entity indicates as 'off'(but it is still 'on').
In this condition, I cannot turn off my dyson DP04.(even though it is still on)
Can you resolve this problem?

Can't set auto mode through service fan.set_preset_mode

I'm unable to set the auto mode through the service fan.set_preset_mode. The preset_modes array of the fan is empty:

preset_modes: 

When calling the service like this:

service: fan.set_preset_mode
data:
  entity_id: fan.pure_cool_link
  preset_mode: auto

I get the following error (because the array is empty):

The preset_mode auto is not a valid preset_mode: []

I can set the auto mode by toggling the switch switch.pure_cool_link_auto_mode but it would be nice if the fan supported the preset_modes as well.

Fan status error in HA 2021.3.4 version

Hello?
I am using a Humidify model, it has been successful without the humidification function.
But, updating HA to 2021.3.4 and updating Dyson Local to 0.8.1 adds a humidification function, but there are problems with the fan's condition and execution.
First, the status information of the fan cannot be obtained, and the on/off is controlled at the speed of the fan, but it is also not stable.
Please review it.

  • HA version : 2021.3.4

  • Dyson Cloud version : v0.8.0

  • Dyson Local version : v0.8.1

  • Components : fan.mydyson

  • State: unavailable

  • Status Properties
    restored: true
    speed_list:

    • 'off'
    • low
    • medium
    • high
      preset_modes: []
      supported_features: 3
      friendly_name: mydyson

detail logs

Logger: homeassistant
Source: custom_components/dyson_local/fan.py:255
First occurred: 오후 3:59:31 (77 occurrences)
Last logged: 오후 5:26:59

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 282, in async_update_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 322, in _async_write_ha_state
attr.update(self.device_state_attributes or {})
File "/config/custom_components/dyson_local/fan.py", line 260, in device_state_attributes
return {ATTR_OSCILLATION_MODE: self.oscillation_mode}
File "/config/custom_components/dyson_local/fan.py", line 255, in oscillation_mode
return OSCILLATION_MODE_ENUM_TO_STR[self._device.oscillation_mode]
File "/usr/local/lib/python3.8/site-packages/libdyson/dyson_pure_humidify_cool.py", line 29, in oscillation_mode
return HumidifyOscillationMode(self._get_field_value(self._status, "ancp"))
File "/usr/local/lib/python3.8/enum.py", line 339, in call
return cls.new(cls, value)
File "/usr/local/lib/python3.8/enum.py", line 662, in new
raise ve_exc
ValueError: 'CUST' is not a valid HumidifyOscillationMode

Logger: homeassistant.components.fan
Source: custom_components/dyson_local/fan.py:255
Integration: fan (documentation, issues)
First occurred: 오후 3:51:58 (2 occurrences)
Last logged: 오후 3:52:00

Error adding entities for domain fan with platform dyson_local
Error while setting up dyson_local platform for fan
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 317, in async_add_entities
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 509, in _async_add_entity
await entity.add_to_platform_finish()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 530, in add_to_platform_finish
self.async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 295, in async_write_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 322, in _async_write_ha_state
attr.update(self.device_state_attributes or {})
File "/config/custom_components/dyson_local/fan.py", line 260, in device_state_attributes
return {ATTR_OSCILLATION_MODE: self.oscillation_mode}
File "/config/custom_components/dyson_local/fan.py", line 255, in oscillation_mode
return OSCILLATION_MODE_ENUM_TO_STR[self._device.oscillation_mode]
File "/usr/local/lib/python3.8/site-packages/libdyson/dyson_pure_humidify_cool.py", line 29, in oscillation_mode
return HumidifyOscillationMode(self._get_field_value(self._status, "ancp"))
File "/usr/local/lib/python3.8/enum.py", line 339, in call
return cls.new(cls, value)
File "/usr/local/lib/python3.8/enum.py", line 662, in new
raise ve_exc
ValueError: 'CUST' is not a valid HumidifyOscillationMode

** Temporary Resolved
I removed and executed the logic of "dyson_local/fan.py" file to solve the problem.
So I did normal action.
However, I don't know how to correct the error.

↓removed code↓

@property
def oscillation_mode(self) -> str:
    """Return oscillation mode."""
    return OSCILLATION_MODE_ENUM_TO_STR[self._device.oscillation_mode]

@property
def device_state_attributes(self) -> dict:
    """Return optional state attributes."""
return {ATTR_OSCILLATION_MODE: self.oscillation_mode}

v0.5.1 : Error messages and no 'fan.xxxx' entity in Dyson Local integration

After I upgraded this component to v0.5.1., I got an error message like this.

Invalid config
The following integrations and platforms could not be set up:

dyson_local.fan
Please check your config and logs.

And error logs:

Logger: homeassistant.config_entries
Source: helpers/entity_component.py:172
First occurred: 오전 12:37:52 (5 occurrences)
Last logged: 오전 12:38:00

Error unloading entry 서재 for fan
Error unloading entry 서재 for air_quality
Error unloading entry 서재 for sensor
Error unloading entry 서재 for switch
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 325, in async_unload
result = await component.async_unload_entry(hass, self) # type: ignore
File "/usr/src/homeassistant/homeassistant/components/fan/init.py", line 105, in async_unload_entry
return await hass.data[DOMAIN].async_unload_entry(entry)
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 172, in async_unload_entry
raise ValueError("Config entry was never loaded!")
ValueError: Config entry was never loaded!

Logger: homeassistant.setup
Source: setup.py:280
First occurred: 오전 12:35:17 (2 occurrences)
Last logged: 오전 12:39:09

Unable to prepare setup for platform dyson_local.fan: Platform not found (No module named 'homeassistant.util.percentage').

There was no error messages like this in previous version.
And 'fan.xxxx' entity is not created.
Other entities(sensors and switches) are created and works well.

Everything stopped working after update to 2021.5.3

Integration stopped working completely on core version 2021.5.3. Reboot did not help. In log, I see only this multiple times:

2021-05-14 10:06:29 WARNING (MainThread) [homeassistant.helpers.service] Unable to find referenced entities fan.obyvaci_pokoj
2021-05-14 10:07:42 WARNING (MainThread) [homeassistant.helpers.service] Unable to find referenced entities switch.obyvaci_pokoj_night_mode

(obyvaci_pokoj is my Dyson Pure Cool TP04)

dyson_local & dyson_cloud version: 0.12.0

Devices Type ?

I have install shenxn/ha-dyson using HACS.
Then, when trying to set-up the Dyson_Local integration, in the dropdown list "Device Types", I can see
"360 eyes ...",
"Pure Cool Link",
"Pure Humidity + Cool",
etc.
but no "Pure Hot + Cool".
Do you know how to make this last choice appear or how to enter it or is it possible to setup within configuration.yaml (with which parameters) ?
Thanks.

Capture d’écran 2021-03-05 à 14 14 13

Dyson local - no way to actually turn Pure Cool Link Desk on or off

Hello,

Maybe I am missing something, but I have no way to actually turn the device on or off, control the power, osciliation or any of those options. Only options i have are night more or auto mode. Is this expected or is something not working with my install?

Attached screenshot:

image

Any help appreciated
Matt

Dyson i360 N223 missing entities

Hi,

I added my i360 a few updates ago and all was well.
After updating to the latest version (local .81), i noticed i was missing the vacuum.xxx entity.
I am also only seeing the map in the cloud version.
I tried re-adding, but i still don't have the vacuum.xx entity, just the 2 power levels. Its being correctly identified as an i360 - N223.
I wonder if the definition has been accidentally broken when a new model was added?

Thanks!

Local Discovery Times Out

I have three Dyson devices. Two were able to be successfully discovered and work great. My Dyson Pure Hot & Cool gets the error message: "Failed to find the device via discovery" when trying to configure it via integrations.

The only message in the log is:
2021-03-20 07:54:45 DEBUG (MainThread) [custom_components.dyson_local.config_flow] Discovery timed out

Any suggestions? Thanks!

Can't login to dyson_cloud

When I try to install dyson_cloud, I always get "Failed to connect". When I try manually with libdyson, I get:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/urllib3/util/ssl_.py", line 343, in ssl_wrap_socket
context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
ssl.SSLError: [X509] PEM lib (_ssl.c:4062)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 677, in urlopen
chunked=chunked,
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 381, in _make_request
self._validate_conn(conn)
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 976, in validate_conn
conn.connect()
File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 370, in connect
ssl_context=context,
File "/usr/local/lib/python3.7/site-packages/urllib3/util/ssl
.py", line 345, in ssl_wrap_socket
raise SSLError(e)
urllib3.exceptions.SSLError: [X509] PEM lib (_ssl.c:4062)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 725, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "/usr/local/lib/python3.7/site-packages/urllib3/util/retry.py", line 439, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='appapi.cp.dyson.com', port=443): Max retries exceeded with url: /v3/userregistration/email/userstatus?country=GB (Caused by SSLError(SSLError(9, '[X509] PEM lib (_ssl.c:4062)')))

Failed to connect

I'm trying to set up integration.

After getting credentials (1kMi......kg==) I'm getting "Failed to connect error", however in the logs there is
2021-03-04 10:29:12 INFO (MainThread) [libdyson.dyson_device] Connected to device PT4-EU-JK* line.

I'm not sure how to trouble shoot this issue.

Collect device WiFi SSID

I'm currently working on a new way of setting up through device WiFi SSID and password. See https://community.home-assistant.io/t/dyson-pure-cool-link-local-mqtt-control/217263. I would like to collect some device SSIDs so that I can know how to parse them. Look for the WiFi information sticker and find the device WiFi SSID. For privacy, you can use X to represents some of the bits in your SSID. For example, for SSID like DYSON-NK6-US-YUK5722Y-475, you can put DYSON-NK6-XX-XXXXXXXX-475. Please also provide your device model as well.

I also write a small script to calculate MQTT credential from device WiFi password. Clone the dev branch of libdyson (https://github.com/shenxn/libdyson/tree/dev) and run python3 calculate_device_credenial.py to see if it works for your device.

Thanks a lot for everyone making this integration and HomeAssistant better.

Socket leak when integration is started with Dyson powered off

Hi there,

I've been having a problem with a leak of localhost socket connections causing my HA instance to eventually die due to lack of file descriptors. I posted some details here: https://community.home-assistant.io/t/ha-continually-opens-connections-to-localhost-causing-fd-leak/294362.

I think I might have tracked the problem down to an issue with the dyson_local custom component. It has been difficult to debug since the problem doesn't happen all the time, but I've now discovered that it happens specifically when one of my Dyson units is powered off (at the wall socket) and HA is started/restarted (note if all my Dysons are up when HA starts and subsequently powered off, I don't see any issues).

I suspect there might be a problem with the reconnect logic either in ha-dyson or libdyson. When I can reproduce the problem, the leaking sockets are of the form:

tcp        0      0 localhost:35407         localhost:51616         ESTABLISHED hass       14353592   5307/python3.8                                                                                                                   
tcp        0      0 localhost:51616         localhost:35407         ESTABLISHED hass       14353591   5307/python3.8                                                                                                                   

One side of the socket is created here:

Apr 03 23:01:59 hostname hass[5307]: socket.connect (<socket.socket fd=34, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>, ('127.0.0.1', 35407))                                            
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/5kznrncnp9v828a7i723j72bh9wkbkg7-python3-3.8.8/lib/python3.8/threading.py", line 890, in _bootstrap                                                                            
Apr 03 23:01:59 hostname hass[5307]:     self._bootstrap_inner()                                                                                                                                                                       
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/5kznrncnp9v828a7i723j72bh9wkbkg7-python3-3.8.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner                                                                      
Apr 03 23:01:59 hostname hass[5307]:     self.run()                                                                                                                                                                                    
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/5kznrncnp9v828a7i723j72bh9wkbkg7-python3-3.8.8/lib/python3.8/threading.py", line 870, in run                                                                                   
Apr 03 23:01:59 hostname hass[5307]:     self._target(*self._args, **self._kwargs)                                                                                                                                                     
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/5kznrncnp9v828a7i723j72bh9wkbkg7-python3-3.8.8/lib/python3.8/concurrent/futures/thread.py", line 80, in _worker                                                                
Apr 03 23:01:59 hostname hass[5307]:     work_item.run()                                                                                                                                                                               
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/5kznrncnp9v828a7i723j72bh9wkbkg7-python3-3.8.8/lib/python3.8/concurrent/futures/thread.py", line 57, in run                                                                    
Apr 03 23:01:59 hostname hass[5307]:     result = self.fn(*self.args, **self.kwargs)                                                                                                                                                   
Apr 03 23:01:59 hostname hass[5307]:   File "/var/lib/hass/custom_components/dyson_local/__init__.py", line 79, in setup_entry                                                                                                         
Apr 03 23:01:59 hostname hass[5307]:     device.connect(host)                                                                                                                                                                          
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/51zs1710gnpk4079cjgjk12pgr7kg1r1-python3.8-libdyson-0.7.0/lib/python3.8/site-packages/libdyson/dyson_device.py", line 76, in connect                                           
Apr 03 23:01:59 hostname hass[5307]:     self._mqtt_client = mqtt.Client(protocol=mqtt.MQTTv31)                                                                                                                                        
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/p95vd7ysgrbw4gx3nb9n14b0gjmr320k-python3.8-paho-mqtt-1.5.1/lib/python3.8/site-packages/paho/mqtt/client.py", line 569, in __init__                                             
Apr 03 23:01:59 hostname hass[5307]:     self._sockpairR, self._sockpairW = _socketpair_compat()                                                                                                                                       
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/p95vd7ysgrbw4gx3nb9n14b0gjmr320k-python3.8-paho-mqtt-1.5.1/lib/python3.8/site-packages/paho/mqtt/client.py", line 280, in _socketpair_compat                                   
Apr 03 23:01:59 hostname hass[5307]:     sock1.connect(("127.0.0.1", port))                                                                                                                                                            
Apr 03 23:01:59 hostname hass[5307]:   File "/nix/store/mb66xsxx0hpdbxchan09hxkmpp98pgar-homeassistant-2021.3.4/bin/.hass-wrapped", line 11, in _my_audit_hook                                                                         
Apr 03 23:01:59 hostname hass[5307]:     msg += "".join(traceback.format_stack())                                                                                                                                                      

and I believe the other side is paho-mqtt in HA.

It looks like whenever a libdyson DysonDevice.connect creates an MQTT client which creates this socket connection to localhost. I presume that connection fails but a reference is held to this client object and the socket is not cleaned up. I don't see a connection error message in the log, and it is only logged on discovery (https://github.com/shenxn/ha-dyson/blob/main/custom_components/dyson_local/__init__.py#L92-L98), so it's hard to tell exactly what happens next, but I assume the failure leads to a ConfigEntryNotReady being thrown and then HA calls async_setup_entry again later. I get a new socket connection with the same stack exactly every 90s, so HA presumably retries that frequently.

Any suggestions on how to fix or work around this? Now that I know the circumstances in which it occurs it's easier to avoid, but it's still quite problematic since the FD leak eventually renders my HA process useless when it hits the FD limit.

Thanks!

Humidifier auto mode pure humidify and cool (model 358)

Control of the humidifier parameter works great, but only works if you turn off auto mode.
Maybe just disable auto mode for the humidifier when a custom settings is required similar as the fanspeed control when changing the fan speed
There auto mode is turned off when I enable a custom speed.

Running version 0.8.1

Possible to get device token from dyson local?

I noticed that when I setup Dyson Cloud that Dyson Local was created, so guessing you're able to pull in the token, is it possible for us to see that token so that we can save that for future use?

Some services missing

I've tried the dyson_local today and it's working really well.

Thank shenxn for coming up with such a fantastic solution for running dyson devices completely off the cloud.

I just noticed compared with the official dyson integration, some services are missing. like

  • dyson.set_flow_direction_front
  • dyson.set_timer
  • ...

It would be great to have these servcies integrated... :)

Error in automation : state 'fail' cannot be processed as a number

Hello,
I've create automation numeric state trigger base on air quality, This is configuration.

platform: numeric_state
entity_id: air_quality.dyson_tp04_living_room_air_quality
for: '00:10:00'
above: '50'

Automation works fine, but I got random warning message from home assistant log.


Logger: homeassistant.components.homeassistant.triggers.numeric_state
Source: components/homeassistant/triggers/numeric_state.py:163
Integration: Home Assistant Core Integration (documentation, issues)
First occurred: 10:59:10 AM (1 occurrences)
Last logged: 10:59:10 AM

Error in '[Stairway] Attic Fan Turn Off' trigger: In 'numeric_state' condition: entity air_quality.dyson_tp04_living_room_air_quality state 'fail' cannot be processed as a number


When message appear air quality not reach 50 yet (It's just 3)
I not sure is there any message other than integer send out from Air Quality state ?

homekit?

This might not be the right place to ask, but I'm not able to get these fan entities to show up in HomeKit. Has anyone gotten that to work or know what the issue might be?

Cannot add as an integration

I've added both of the repositories to HACS (see screenshot) but when I search for them in the Integrations page they are not showing up.

I've restarted HA, but still nothing.

Am I missing a step? I'm running 2021.3.3

image

Dyson Local integration success, but didn't update

Hello All,

I use Docker HA 2021.3.4 with latest dyson cloud and dyson local
I setup dyson cloud first, then dyson local add, and discover my TP04
and then integration is added success
however I found that the status will never update
it's only get the value from the first times setup or restart the HA get the once status
and then keep the temp or hum or another status the same value
What is the problem??

Thanks~

Pure Hot Cool Link Device Automations fail to detect current mode

Using Device Conditions in Automations or Scripts fail to detect the current mode of the Dyson device. As a result, the following automation step produces no action, even though the climate device shows a "heat" state and the physical device is heating the room.

choose:
  - conditions:
      - condition: device
        device_id: 4de31c580c0b72b61b008d44c39fd1
        domain: climate
        entity_id: climate.attic_dyson_air
        type: is_hvac_mode
        hvac_mode: heat
    sequence:
      - service: climate.set_temperature
        data:
          temperature: 60
        target:
          entity_id: climate.dyson_air
      - delay:
          hours: 1
          minutes: 0
          seconds: 0
          milliseconds: 0
      - device_id: 4de31c580c0b72b61b008d44c39fd1
        domain: fan
        entity_id: fan.attic_dyson_air
        type: turn_off
  - conditions:
      - condition: device
        device_id: 4de31c580c0b72b61b008d44c39fd104
        domain: climate
        entity_id: climate.attic_dyson_air
        type: is_hvac_mode
        hvac_mode: cool
    sequence:
      - device_id: 4de31c580c0b72b61b008d44c39fd1
        domain: fan
        entity_id: fan.attic_dyson_air
        type: turn_off
default: []

Get credentials

Update:

@shenxn: #5 (comment)

I've added 2FA support to libdyson (https://github.com/shenxn/libdyson). Download or clone the repo, then run python3 get_devices.py to get credentials. You may also need to install some dependencies using pip3 install -r requirements.txt.

Old

Not an actual issue, but wanted to make this available for other people

I've managed to get credentials in two ways:

1. Using libpurecool

Use this fork of libpurecool (fix_auth branch): https://github.com/bfayers/libpurecool/tree/fix_auth
python3 -m pip install https://github.com/bfayers/libpurecool/archive/fix_auth.zip

  1. Create a new file called whatever.py
  2. Paste this in:
    #!/usr/bin/python3
    from libpurecool.dyson import DysonAccount
    
    dyson_account = DysonAccount("email","password","lang")
    logged = dyson_account.login()
    
    if not logged:
        print('Unable to login to Dyson account')
        exit(1)
    devices = dyson_account.devices()
    for device in devices:
        print(device.serial);
        print(device.name);
        print(device.credentials);
        print(" ");
  1. Open your DysonLink app and stare at the welcome screen :)
  2. python3 whatever.py
  3. Cross your fingers 🤞 and hope it works.

⚠️ Don't try to loging in too fast/spam the script or you'll get IP blocked by Dyson
I've also noticed that I'm getting immediately denied login if I'm going through a VPN

2. Using an Android phone

You can probably do this with an iOS device, but I haven't tested (https://stackoverflow.com/a/8512455)

  1. Download the Packet Capture app from Google Playstore (https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture&hl=en&gl=US)
  2. Open Dyson Link and leave it running in the background
  3. Run the Packet Capture app, allow it to create a VPN if you're prompted
  4. Hit the play button with the 1 and choose the Dyson Link app
  5. Switch to the Dyson Link app, it will probably do a quick refresh of the welcome page
  6. Switch back to Packet Capture and stop capturing
  7. Look through the captured packets for something like this:
    Screenshot_20210305-024635

Can No Longer Turn Off Fan in Auto Mode

As a byproduct of Issue #12 (v0.5.1) when the Fan is in the Auto Mode preset it can no longer be shutoff. I agree with the logic that Auto Mode should still report the device as On, however even at that state you can not shut the fan off completely and will remain in auto mode as "On" unless the fan percentage is changed to another value to remove the "Auto" preset. I think a preset mode of "None" or "Off" that is a valid option might resolve it slightly being able to remove it from "Auto" without setting a fan percentage. Or if a fan.turn_off is issued shut the fan down and remove it from auto mode.

Example fan.turn_off on an entity in Auto Mode continues to stay on and in Auto mode
Log Error:

2021-03-09 12:55:24 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 282, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 321, in _async_write_ha_state
    attr.update(self.state_attributes or {})
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 602, in state_attributes
    data[ATTR_SPEED] = self.speed
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 452, in speed
    percentage = self.percentage
  File "/config/custom_components/dyson_local/fan.py", line 119, in percentage
    return ranged_value_to_percentage(SPEED_RANGE, int(self._device.speed))
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

Feature Request: Fetch current position

Hi,

It would be nice if we could 'fetch' the current angle of the (Pure Cool) fans.
In the latest release(s) (0.5.2 and up) we can manually set the fan to a specific angle/position and have it oscillate between two angles.

I don't know if it's possible of course. Maybe that info isn't fed back from the units. But it would be a 'nice to have'.

Invalid fan entity state and its parameters

Some of the parameters shown under the fan entity are invalid. So far, I've found these two:

  • oscillating: false (Dyson is set to oscillate and is currently oscillating)
  • percentage: null (I don't think null is correct value)

Fan connection disconnect cause integration to become unresponsive

Thanks @shenxn for this great work on this integration. Since the 2FA changes I been running this exclusively to run my fans, and it’s very good.

One issue I’m experiencing is if the Dyson fan loses connection even temporarily, the integration becomes unresponsive, the sensors cease updating and requires a system restart to work again. It provides no errors or warnings in the log.

Reloading the integration doesn’t resolve the issue and results in the error “fan entity does not exist”.

As there’s no log trail this is a tricky one to troubleshoot. Do you think you could add a warning for disconnections or timeouts?

attribute angle_low & angle_high is not updating for TP04

TP04 pure cool has oscillating feature of multiple angles. The attribute of the angle is angle_low & angle_high, it's not updating in the HA when the angle is changed by Dyson remote control, nor is the attribute value able to overwriten by user through HA. Please help to enable it, thanks.

speed_list: off, low, medium, high
preset_modes:
oscillating: true
speed: high
percentage: 100
percentage_step: 10
preset_mode: null
angle_low: 135
angle_high: 225
friendly_name: Living room
supported_features: 3

Additional services

Would be nice to have additional services from current official integration. Currently, there are missing things like angles setting, flow direction etc.
Otherwise nice job!

Unsupported device Dyson 360 Eye heurist

After successfully completing Dyson cloud setup, I try to register my two Dyson discovered devices using the configure button, write ip address in the host field and then it fails with "Unknown error occurred" message.
Log file contains the following exception:

...
File "/config/custom_components/dyson_local/config_flow.py", line 151, in _async_get_entry_data
device.connect(host)
AttributeError: 'NoneType' object has no attribute 'connect'

My two devices are:

Dyson 360 Eye robot vacuum
Dyson Pure Cool

Full stack trace is:

Logger: aiohttp.server
Source: custom_components/dyson_local/config_flow.py:151
First occurred: 9:03:26 AM (1 occurrences)
Last logged: 9:03:26 AM

Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
resp = await self._request_handler(request)
File "/usr/local/lib/python3.8/site-packages/aiohttp/web_app.py", line 499, in _handle
resp = await handler(request)
File "/usr/local/lib/python3.8/site-packages/aiohttp/web_middlewares.py", line 119, in impl
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 56, in security_filter_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 172, in forwarded_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 18, in request_context_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 72, in ban_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 129, in auth_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 129, in handle
result = await result
File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 150, in post
return await super().post(request, flow_id)
File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 60, in wrapper
result = await method(view, request, *args, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 106, in post
result = await self._flow_mgr.async_configure(flow_id, data)
File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 158, in async_configure
result = await self._async_handle_step(flow, cur_step["step_id"], user_input)
File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 216, in _async_handle_step
result: Dict = await getattr(flow, method)(user_input)
File "/config/custom_components/dyson_local/config_flow.py", line 79, in async_step_host
data = await self._async_get_entry_data(
File "/config/custom_components/dyson_local/config_flow.py", line 151, in _async_get_entry_data
device.connect(host)
AttributeError: 'NoneType' object has no attribute 'connect'

Thanks.

Issue setting fan attributes through automation: Unable to find service

Please help me out fixing the following. I have configured my Dyson fan (TP04) using the Local setup.

The Dyson entity seems to be working correctly, I can use the switches (like auto mode, night mode, front airflow switch, etc.) in my dashboards (ignore speed control, that one isn't working):
image

State screenshot from dev-tools:
dyson_01

Interestingly enough, it seems like my fan is not recognizing the dyson speeds, but is using the HA default LOW, MEDIUM, HIGH. Not sure if I did something wrong during setup, I have no clue how to get rid of this..

My issue is that I am getting errors when trying to set any attribute through an automation. I am struggling to get working:

  • Speed
  • Oscillation (true/false)
  • Angle (low and high)
  • Front airflow (using the switch on a dashboard works, but not when calling dyson.set_flow_direction_front in an automation..)
  • etc.

The automation that I am trying to run should turn on my fan using a number of parameters:

- id: bedroom_cooling
  alias: Bedroom Cooling
  description: Cool the bedroom in the evening
  trigger:
  - platform: numeric_state
    entity_id: sensor.dyson_temperature
    above: '22'
  condition:
    condition: and
    conditions:
    - condition: state
      entity_id: group.lights_living
      state: 'off'
    - condition: state
      entity_id: input_boolean.not_home_enabled
      state: 'off'
  action:
  - service: dyson.set_speed
    data:
      speed: 4
      entity_id: fan.dyson
  - service: dyson.set_flow_direction_front
    data:
      entity_id: fan.dyson
      flow_direction_front: true
  - service: dyson.set_angle
    data:
      angle_low: '90'
      angle_high: '135'
      entity_id: fan.dyson
  - service: fan.oscillate
    data:
      oscillating: true
      entity_id: fan.dyson
  mode: restart

The error that I am getting from HA Trace is: 'Unable to find service dyson.set_speed':
image

I must be doing something wrong here, but I have been trying for weeks and I am probably overlooking something stupid here...

Can you please support me in figuring out what's happening because I am going crazy here, hehe.
Thanks for the great integration in any case, after TFA messed up my fan setup, I am happily using your solution.

ValueError: 'OFF' is not a valid AirQualityTarget

When my Pure Cool Link is off, I see this error in the logs. The integration is working fine if the device is on though.

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 282, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 322, in _async_write_ha_state
    attr.update(self.device_state_attributes or {})
  File "/config/custom_components/dyson_local/fan.py", line 175, in device_state_attributes
    return {ATTR_AIR_QUALITY_TARGET: self.air_quality_target}
  File "/config/custom_components/dyson_local/fan.py", line 170, in air_quality_target
    return AIR_QUALITY_TARGET_ENUM_TO_STR[self._device.air_quality_target]
  File "/usr/local/lib/python3.8/site-packages/libdyson/dyson_pure_cool_link.py", line 33, in air_quality_target
    return AirQualityTarget(self._get_field_value(self._status, "qtar"))
  File "/usr/local/lib/python3.8/enum.py", line 339, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.8/enum.py", line 662, in __new__
    raise ve_exc
ValueError: 'OFF' is not a valid AirQualityTarget

I'm using version 0.5.1 of the integration and 2021.3 of Home Assistant.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.