Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Xiaomi Air Purifier 3C #47924

Closed

Conversation

abrilevskiy
Copy link

@abrilevskiy abrilevskiy commented Mar 14, 2021

Breaking change

Proposed change

  • Add Xiaomi Air Purifier 3C support.
  • Add fan percentage support and split the attributes in different sensor entities.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Example entry for configuration.yaml:

# Example configuration.yaml

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • Untested files have been added to .coveragerc.

The integration reached or maintains the following Integration Quality Scale:

  • No score or internal
  • 🥈 Silver
  • 🥇 Gold
  • 🏆 Platinum

To help with the load of incoming pull requests:

@homeassistant
Copy link
Contributor

Hi @abrilevskiy,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@probot-home-assistant
Copy link

Hey there @rytilahti, @syssi, @starkillerOG, mind taking a look at this pull request as its been labeled with an integration (xiaomi_miio) you are listed as a codeowner for? Thanks!
(message by CodeOwnersMention)

@starkillerOG
Copy link
Contributor

Looks good to me, not sure why the tests fail

@abrilevskiy
Copy link
Author

@starkillerOG , all tests are finally gets passed now.

Copy link
Contributor

@starkillerOG starkillerOG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@notherealmarco
Copy link

I'm testing the integration by running it as a custom component. I'm not able to change the speed of the 3C's fan in manual mode, and I can't see the attributes (like air quality ecc.).

@abrilevskiy
Copy link
Author

abrilevskiy commented Mar 15, 2021

@notherealmarco, I also can not change the speed, but as far as I understand - it is a separate issue. Please let me know otherwise.
I did testing by modification of original Home-Assistant python files and with enabled debug I see the following:

2021-03-15 19:31:16 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Got new state: <AirPurifierMB4Status aqi=None buzzer=False child_lock=False favorite_rpm=850 filter_hours_used=484 filter_life_remaining=86 is_on=True led_brightness_level=3 mode=OperationMode.Silent motor_speed=392 power=on>
2021-03-15 19:31:46 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Got new state: <AirPurifierMB4Status aqi=None buzzer=False child_lock=False favorite_rpm=850 filter_hours_used=484 filter_life_remaining=86 is_on=True led_brightness_level=3 mode=OperationMode.Silent motor_speed=392 power=on>
2021-03-15 19:32:16 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Got new state: <AirPurifierMB4Status aqi=None buzzer=False child_lock=False favorite_rpm=850 filter_hours_used=484 filter_life_remaining=86 is_on=True led_brightness_level=3 mode=OperationMode.Silent motor_speed=388 power=on>

aqi=None - is due to filtering "1"

Could you please check python-miio version (miiocli --version)?

@notherealmarco
Copy link

notherealmarco commented Mar 15, 2021

I'm running version 0.5.5 (as declared in the manifest.json)

image

Don't know if this can help, but when it loads the fan entity, it throws an exception, here's the stacktrace:

2021-03-15 19:27:28 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new fan.xiaomi_miio entity: fan.zhimi_airpurifier_mb4
2021-03-15 19:27:35 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [547491654096] The speed_list [] does not contain any valid speeds.
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 583, in percentage_to_speed
    return percentage_to_ordered_list_item(speed_list, percentage)
  File "/usr/src/homeassistant/homeassistant/util/percentage.py", line 45, in percentage_to_ordered_list_item
    raise ValueError("The ordered list is empty")
ValueError: The ordered list is empty

The above exception was the direct cause of the following exception:

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_component.py", line 204, in handle_service
    await self.hass.helpers.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/src/homeassistant/homeassistant/components/fan/__init__.py", line 275, in async_set_percentage
    await self.async_set_speed(self.percentage_to_speed(percentage))
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 585, in percentage_to_speed
    raise NoValidSpeedsError(
homeassistant.components.fan.NoValidSpeedsError: The speed_list [] does not contain any valid speeds.
2021-03-15 19:27:35 INFO (MainThread) [homeassistant.components.automation.error_counting_automation] Error Counting Automation: Running automation actions
2021-03-15 19:27:35 INFO (MainThread) [homeassistant.components.automation.error_counting_automation] Error Counting Automation: Executing step call service
2021-03-15 19:27:36 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [547491654096] The speed_list [] does not contain any valid speeds.
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 583, in percentage_to_speed
    return percentage_to_ordered_list_item(speed_list, percentage)
  File "/usr/src/homeassistant/homeassistant/util/percentage.py", line 45, in percentage_to_ordered_list_item
    raise ValueError("The ordered list is empty")
ValueError: The ordered list is empty

The above exception was the direct cause of the following exception:

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_component.py", line 204, in handle_service
    await self.hass.helpers.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/src/homeassistant/homeassistant/components/fan/__init__.py", line 275, in async_set_percentage
    await self.async_set_speed(self.percentage_to_speed(percentage))
  File "/usr/src/homeassistant/homeassistant/components/fan/__init__.py", line 585, in percentage_to_speed
    raise NoValidSpeedsError(
homeassistant.components.fan.NoValidSpeedsError: The speed_list [] does not contain any valid speeds.

@abrilevskiy
Copy link
Author

I see the same exception when try to change Fan speed, but other functionality works:

image

@notherealmarco
Copy link

notherealmarco commented Mar 15, 2021

@abrilevskiy that's what I have:

image

And this is the configuration (I also triend setting it up from the UI):

fan:
  - platform: xiaomi_miio
    name: map_fan
    host: 192.168.188.74
    token: <my_beautiful_token>
    model: zhimi.airpurifier.mb4

Sould I try running the component by replacing the HA files instead of running it as a custom component?

@abrilevskiy
Copy link
Author

Config file should not be used - wizard is implemented in latest release.
If wizard would not help - could you please try replacing the original files and let me know the results please.

@notherealmarco
Copy link

notherealmarco commented Mar 17, 2021

@abrilevskiy

Tried both, but the result is the same. The fan entity still doesn't have all the attributes

@abrilevskiy
Copy link
Author

@notherealmarco , Could you please provide logs?
The attributes will be empty in case if regular AirPurifierMiot class is used to communicate with device, but in fan.py it is an implicit condition:

    if model == MODEL_AIRPURIFIER_3C:
        air_purifier = AirPurifierMB4(host, token)

@notherealmarco
Copy link

notherealmarco commented Mar 18, 2021

@abrilevskiy

These are the logs, I have set the logging level to debug (homeassistant.components.xiaomi_miio: debug)

2021-03-18 16:45:19 INFO (MainThread) [homeassistant.components.fan] Setting up fan.xiaomi_miio
2021-03-18 16:45:21 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Initializing with host 192.168.188.74 (token f024a...)
...
2021-03-18 16:45:23 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Got new state: <AirPurifierMB4Status aqi=None buzzer=False child_lock=False favorite_rpm=750 filter_hours_used=118 filter_life_remaining=97 is_on=True led_brightness_level=8 mode=OperationMode.Favorite motor_speed=748 power=on>
...
2021-03-18 16:45:28 DEBUG (MainThread) [homeassistant.components.xiaomi_miio.fan] Got new state: <AirPurifierMB4Status aqi=None buzzer=False child_lock=False favorite_rpm=750 filter_hours_used=118 filter_life_remaining=97 is_on=True led_brightness_level=8 mode=OperationMode.Favorite motor_speed=752 power=on>

Seems to be using the right class. The attributer are there in the logs, but not on the entity in HA.

I also tried miiocli (in the same container), and it shows well all the attributes.

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AVAILABLE_ATTRIBUTES_AIRFRESH attributes also seem to contain some measurements that should be sensor entities and not fan attributes, eg temperature, aqi, average_aqi, co2, humidity. It would be good to move them too.

homeassistant/components/xiaomi_miio/fan.py Show resolved Hide resolved
Comment on lines 175 to 176
ATTR_TEMPERATURE: "temperature",
ATTR_HUMIDITY: "humidity",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temperature and humidity should also be separate sensor entities. Please move these as well.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Air Purifier model (3C) does not have neither temperature nor humidity

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MartinHjelmare this comment seems unrelated to the pull request, which simply aims to add support for the 3C model.

The temperature and humidity values are already listed as attributes in the original home-assistant repo: https://github.com/home-assistant/core/blob/dev/homeassistant/components/xiaomi_miio/fan.py#L167

Could you open a separate issue to aim to improve this by splitting out the mentioned attributes as sensor entities?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code is already scoped beyond adding support for the 3C model, which you can see if you read the sensor platform additions. If we only want that scope, we'll need to slim that part down.

homeassistant/components/xiaomi_miio/fan.py Outdated Show resolved Hide resolved
Dev automation moved this from Needs review to Review in progress Apr 15, 2021
@MartinHjelmare MartinHjelmare changed the title Xiaomi Air Purifier 3C support is added (incl. fan percentage support and splits the attributes in different sensor entities) Add Xiaomi Air Purifier 3C Apr 15, 2021
@Disturbx

This comment has been minimized.

@andrey-skat
Copy link

@abrilevskiy do you need help with this PR?

@KalleKalee
Copy link

Any help needed?

@malfroid
Copy link

Can I help out with this? What remains to be done to approve this PR?

I am waiting for this integration to control my 3C model. The PR has been open for more than 2 months now.

@MartinHjelmare
Copy link
Member

The comments need to be addressed.

@notherealmarco
Copy link

Can I help out with this? What remains to be done to approve this PR?

I am waiting for this integration to control my 3C model. The PR has been open for more than 2 months now.

I'm sorry, I'm preparing 4 exams for the university and i have no time right now to finish addressing the issues. I will continue in July, when the exam session will be over

…n.py

Co-authored-by: Kasper Malfroid <kasper@malfroid.be>
@MartinHjelmare
Copy link
Member

Other PRs have overtaken this PR and this PR is no longer correct. We have moved the humidifiers to a new humidifier platform in #51884. And in #51791 we have implemented percentage based fan control.

I suggest we close this PR and take a new look at adding any remaining missing device support after the other work is merged.

@MartinHjelmare MartinHjelmare marked this pull request as draft June 23, 2021 07:45
@andrey-skat
Copy link

@MartinHjelmare Is humidifier platform will be correct for this device? This device is purifier and not humidifier, it has only fan control and pm2.5 sensor.

@MartinHjelmare
Copy link
Member

No this new device should still be a fan and a sensor entity. Currently though this PR has other changes that are in conflict with the ongoing restructuring work. So at minimum we'll need to rebase here when that work is done.

@mouth4war
Copy link

mouth4war commented Jun 26, 2021

@MartinHjelmare FWIW, this PR seems to have a better implementation of fan speed percentage than the already merged #51791. This PR uses the motor speed instead of the 'fan' preset and associated 3 speed presets, so it enables finer control of fan speed.

@notherealmarco can you confirm that your implementation enables more points (300-1200rpm mapped to 0-100%) in your testing?

@jbouwh
Copy link
Contributor

jbouwh commented Jun 28, 2021

@MartinHjelmare FWIW, this PR seems to have a better implementation of fan speed percentage than the already merged #51791. This PR uses the motor speed instead of the 'fan' preset and associated 3 speed presets, so it enables finer control of fan speed.

@notherealmarco can you confirm that your implementation enables more points (300-1200rpm mapped to 0-100%) in your testing?
#51791 uses the build in modes, not motor speeds.
For Humidifiers the fan platform wil not be used anymore in future. We will be adding a motor_speed controller using the number integration to support humidifies, but that can be expanded for airpurifiers if needed.

See #52173.

P.S. Of course motor speed could be in the Fan platform instead of the build in modes, but that would not be compatible with what the uses sees on the indicators on the device. I would prefer to use the build in modes only and a additional motor_speed controller.

@mouth4war
Copy link

mouth4war commented Jun 30, 2021

I see your rationale makes sense but how many people even look at their air purifiers anymore. The
mode icon is tiny and you need to go up to the purifier to squint at it. Most of display space shows AQI. If using favorite speed, the purifier will show a heart icon for favorite mode so it will indicate custom speed in use. It won't show the exact speed though.

The idea is to automate the fan speed and the finer control is more useful. Using the service approach means homeassistant will not display or change service-set fan speed in UI. I think this is a bigger issue that users already face (with existing favorite levels).

Mapping favorite speeds to fan speed percentage will make home assistant more consistent (fan speed set via service in automation will match HASS UI fan speed slider and further integrations like Homekit also).

I think we should prioritize this as defining your own custom handling of fan speed is one of the key benefits of using HASS to control air purifiers. You can use automations to override factory handling of fan speeds in response to AQI and just 3 steps doesn't make this happen. So users will have to use the service and deal with broken fan speeds in UI and beyond, again.

@TpHa1
Copy link

TpHa1 commented Aug 9, 2021

newbie. how to add 3c to HA step by step please.
thank you

@randarth
Copy link

This PR seems to have been abandoned. Maybe somebody can take over and finish it?

@bieniu
Copy link
Member

bieniu commented Aug 18, 2021

Hi, I can help but I don't have this model at home so... please contact me on Discord (Bieniu#4759) or Messenger (Maciej Bieniek).

@r4ian
Copy link

r4ian commented Aug 30, 2021

@syssi @starkillerOG @rytilahti

Could some of you please check this case? Not trying to push you, just wondering if anyone is working on it or it is forgotten.

Maybe @arturdobo or @abrilevskiy can help if there is no capacity for development (found you guys in related issues/PRs, sorry for tagging if you can't help here)

I have this model if you need help testing.

@bieniu
Copy link
Member

bieniu commented Aug 30, 2021

@starkillerOG
Copy link
Contributor

@r4ian I would love to help, but I don't own a xiaomi air purifier, so it is hard for me to develop and test code for it.
So unless someone arranges one for me, I will not be of much help, sorry.

Dev automation moved this from Review in progress to Cancelled Aug 31, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Sep 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Dev
  
Cancelled
Development

Successfully merging this pull request may close these issues.

Xiaomi Mi Air Purifier 3C (zhimi.airpurifier.mb4) is not available in Xiaomi Miio Device integration