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 support for Xiaomi Zero Fog Free Humidifier #33736

Closed
wants to merge 2 commits into from

Conversation

iromeo
Copy link

@iromeo iromeo commented Apr 6, 2020

Breaking change

Proposed change

Add support for: Xiaomi Zero Fog Free Humidifier support (shuii.humidifier.jsq001)

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
fan:
  - platform: xiaomi_miio
    name: 'Air Humidifier'
    host: !secret humidifier_ip
    token: !secret humidifier_token
    model: shuii.humidifier.jsq001

Additional information

My PR to python-miio is already accepted and released in 0.5.0.0 (see rytilahti/python-miio#642) This PR adds itegration for the device type.

image

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

@homeassistant
Copy link
Contributor

Hi @iromeo,

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

This pull request needs to be manually signed off by @home-assistant/core before it can get merged.

@probot-home-assistant
Copy link

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

@iromeo
Copy link
Author

iromeo commented Apr 6, 2020

Also, there is shuii.humidifier.jsq002 model (syssi/xiaomi_airpurifier#50), but issue author doesn't respond and I cannot add support for it without access to the real device.

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.

This integration and platform needs to be refactored first to follow our design guidelines regarding fan modes, state attributes and entity access, before any more additions are made.

}

AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER = {
**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
ATTR_TARGET_HUMIDITY: "target_humidity",
ATTR_HARDWARE_VERSION: "hardware_version",
ATTR_USE_TIME: "use_time",
Copy link
Member

Choose a reason for hiding this comment

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

Is this a relative time? Relative times are not allowed in the state machine. We only allow absolute utc timestamps.

Copy link
Author

@iromeo iromeo Apr 6, 2020

Choose a reason for hiding this comment

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

This change is a refactoring of existing attributes, I just moved some unsupported attributes from common to more specific attributes sets. use_time attribute was added in 25.03.2018 by @syssi (see e36f27d). So I assume that it is in UTC.

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately this platform isn't following our design guidelines so we can not trust that the existing code is ok.

Copy link
Author

Choose a reason for hiding this comment

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

You recently accepted PR #31729 with the same code.

I could revert this change to the state before my commit if you want. But I don't think that copy-paste is better than trivial refactoring of the code working for more than 2 years.

Copy link
Member

@MartinHjelmare MartinHjelmare Apr 6, 2020

Choose a reason for hiding this comment

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

We won't accept this PR until the integration and platform have been refactored. That should be done in a separate PR first.

This integration and platform needs to be refactored first to follow our design guidelines regarding fan modes, state attributes and entity access, before any more additions are made.

Copy link
Author

Choose a reason for hiding this comment

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

@rytilahti, @syssi As code owners of the integration do you understand how it should be refactored to address this request?

Copy link
Member

@rytilahti rytilahti Apr 6, 2020

Choose a reason for hiding this comment

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

@syssi is more knowledgeable on this specific case, but some things I feel should be refactored:

  • Moving supported features, available attributes towards the backend library.

    • This involves, e.g., moving the list of available fan speeds to the backend, like was done recently for the vacuum platform.
    • Homeassistant has only 3 different fan speeds (+ off), so rest of those need to be exposed over separate services (if wanted).
  • Moving supported models also towards the backend. This will simplify future developments when the backend lib is the only source of truth.

  • I think reading somewhere that sensors are preferred over custom state attributes, but cannot find the reference from the docs at the moment. So, these attributes are the ones that should be exposed through the main device: https://developers.home-assistant.io/docs/entity_fan/#properties

    • This would mean creating new entities for those custom attributes, that are linked to the main device.
    • We can adapt the backend to report what type of attribute something is, that can then be used inside homeassistant to create sensors, binary_sensors, switches, etc. depending on the type.
    • I'm not sure what Martin means with entity access, maybe that's related?
  • Firmware information etc. should only be exposed to the device registry (https://developers.home-assistant.io/docs/device_registry_index/)

  • Lot of common code could be shared with all the platforms, e.g., the initialization is almost always the same, but is still c&p in different platforms.

Copy link
Member

@rytilahti rytilahti Apr 6, 2020

Choose a reason for hiding this comment

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

Ah, found it (thanks @MartinHjelmare on that other PR: https://developers.home-assistant.io/docs/entity_sensor/#available-device-classes .

So in this case, to my understanding, we should have the following new entities (depending on the supported features of the device):

  • sensors:

    • temperature
    • humidity
  • binary_sensors:

    • child lock
    • led
    • no water
    • lid open
    • buzzer
  • unknown:

    • mode
    • led brightness

Copy link
Member

Choose a reason for hiding this comment

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

One more point, this architecture issue is relevant to this, too: home-assistant/architecture#310

Copy link
Member

Choose a reason for hiding this comment

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

@rytilahti I think that's a great plan and summary. It's not a small task though, so it will take some time and need to be taken step wise. 👍

With entity access I meant accessing the entity directly from outside the entity instead of via core or dispatcher. Direct entity access from outside is fragile since it only works after the entity has been added to home assistant. Now we also have a service helper that platforms can use to easily register services that need to call into an entity method.

await getattr(device, method["method"])(**params)
update_tasks.append(device.async_update_ha_state(True))

Here's the docs for the service helper:
https://developers.home-assistant.io/docs/dev_101_services#entity-services

And here's a real example how to use the service helper:

platform = entity_platform.current_platform.get()
platform.async_register_entity_service(
SERVICE_EFFECT,
{
vol.Optional(ATTR_EFFECT): vol.Any(cv.positive_int, cv.string),
vol.Optional(ATTR_INTENSITY): vol.All(
vol.Coerce(int), vol.Range(min=0, max=255)
),
vol.Optional(ATTR_REVERSE): cv.boolean,
vol.Optional(ATTR_SPEED): vol.All(
vol.Coerce(int), vol.Range(min=0, max=255)
),
},
"async_effect",
)

ATTR_TRANS_LEVEL: "trans_level",
ATTR_BUTTON_PRESSED: "button_pressed",
}

AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA_AND_CB = {
**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
ATTR_TARGET_HUMIDITY: "target_humidity",
ATTR_HARDWARE_VERSION: "hardware_version",
Copy link
Member

Choose a reason for hiding this comment

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

Static info is not meant for state attributes unless it's essential for automations.

Copy link
Author

Choose a reason for hiding this comment

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

These 2 attributes were moved from AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON to more specific implementations because they are not common for all humidifiers and not supported by shuii.humidifier.jsq001.

**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
ATTR_LED: "led",
ATTR_NO_WATER: "no_water",
ATTR_LID_OPENED: "lid_opened",
Copy link
Member

Choose a reason for hiding this comment

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

lid_opened seems like it should be a binary sensor. We want to minimize state attributes and instead break out to as many individual sensors as possible.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, it could be a binary sensor. Could you guide me with some example of how I could replace with sate with a binary sensor?

self._led_brightness_enum = AirhumidifierJsqLedBrightness
self._led_brightness_default = 0
self._operation_mode_enum = AirhumidifierJsqOperationMode
self._speed_list = [mode.name for mode in AirhumidifierJsqOperationMode]
Copy link
Member

Choose a reason for hiding this comment

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

We only allow the modes in the fan base entity integration:

SPEED_OFF = "off"
SPEED_LOW = "low"
SPEED_MEDIUM = "medium"
SPEED_HIGH = "high"

Copy link
Author

@iromeo iromeo Apr 6, 2020

Choose a reason for hiding this comment

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

The device does not fall into such a specification

Same issue as in #31729 (review)

@springstan springstan changed the title Xiaomi Zero Fog Free Humidifier support (shuii.humidifier.jsq001) Add support for Xiaomi Zero Fog Free Humidifier Apr 6, 2020
@MartinHjelmare MartinHjelmare self-assigned this Apr 19, 2020
@starkillerOG
Copy link
Contributor

Maybe relevant for this PR too: I am busy with supporting Config Flow for the Xiaomi Miio platform, see PR: #32091

@stale
Copy link

stale bot commented May 20, 2020

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.

@stale stale bot added the stale label May 20, 2020
@stale stale bot closed this May 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants