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

Update vesync to use new fan entity model #45585

Merged
merged 2 commits into from
Jan 28, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 49 additions & 28 deletions homeassistant/components/vesync/fan.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
"""Support for VeSync fans."""
import logging
import math

from homeassistant.components.fan import (
SPEED_HIGH,
SPEED_LOW,
SPEED_MEDIUM,
SPEED_OFF,
SUPPORT_SET_SPEED,
FanEntity,
)
from homeassistant.components.fan import SUPPORT_SET_SPEED, FanEntity
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.util.percentage import (
percentage_to_ranged_value,
ranged_value_to_percentage,
)

from .common import VeSyncDevice
from .const import DOMAIN, VS_DISCOVERY, VS_DISPATCHERS, VS_FANS
Expand All @@ -21,8 +19,11 @@
"LV-PUR131S": "fan",
}

FAN_SPEEDS = [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
FAN_MODE_AUTO = "auto"
FAN_MODE_SLEEP = "sleep"

PRESET_MODES = [FAN_MODE_AUTO, FAN_MODE_SLEEP]
Copy link
Member

Choose a reason for hiding this comment

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

Should there be a FAN_MODE_NONE so that users can disable a preset mode ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm trying to think about how I would use it.

I'm thinking I would use it like:

from Auto -> Medium Speed or Auto -> Off and wouldn't do Auto -> None -> Medium

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll do some testing with the frontend PR to make sure that is actually how I would use it with the demo fan.

Copy link
Member Author

Choose a reason for hiding this comment

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

T2Uetqxcxe

If the device still reports the fan level in Auto mode, maybe it makes sense to add Manual (suggested as None).

If the device doesn't report the fan level in auto mode then it probably is fine as is.

Copy link
Member Author

@bdraco bdraco Jan 28, 2021

Choose a reason for hiding this comment

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

I ordered a LV-PUR131S for testing and will adjust later if needed

Copy link
Contributor

Choose a reason for hiding this comment

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

I ordered a LV-PUR131S for testing and will adjust later if needed

I am available to test this when you feel it is ready as well. I have 3 of these.

Copy link
Member Author

Choose a reason for hiding this comment

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

If you could give the latest dev a try along with latest frontend with home-assistant/frontend#8216 and provide feedback, that would be most excellent.

SPEED_RANGE = (1, 3) # off is not included


async def async_setup_entry(hass, config_entry, async_add_entities):
Expand Down Expand Up @@ -68,20 +69,25 @@ def supported_features(self):
return SUPPORT_SET_SPEED

@property
def speed(self):
def percentage(self):
"""Return the current speed."""
if self.smartfan.mode == FAN_MODE_AUTO:
return None
if self.smartfan.mode == "manual":
current_level = self.smartfan.fan_level
if current_level is not None:
return FAN_SPEEDS[current_level]
return ranged_value_to_percentage(SPEED_RANGE, current_level)
return None

@property
def speed_list(self):
"""Get the list of available speeds."""
return FAN_SPEEDS
def preset_modes(self):
"""Get the list of available preset modes."""
return PRESET_MODES

@property
def preset_mode(self):
"""Get the current preset mode."""
if self.smartfan.mode == FAN_MODE_AUTO:
return FAN_MODE_AUTO
return None

@property
def unique_info(self):
Expand All @@ -99,21 +105,34 @@ def device_state_attributes(self):
"screen_status": self.smartfan.screen_status,
}

def set_speed(self, speed):
def set_percentage(self, percentage):
"""Set the speed of the device."""
if percentage == 0:
self.smartfan.turn_off()
return

if not self.smartfan.is_on:
self.smartfan.turn_on()

self.smartfan.manual_mode()
self.smartfan.change_fan_speed(FAN_SPEEDS.index(speed))

#
# The fan entity model has changed to use percentages and preset_modes
# instead of speeds.
#
# Please review
# https://developers.home-assistant.io/docs/core/entity/fan/
#
self.smartfan.change_fan_speed(
math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
)
self.schedule_update_ha_state()

def set_preset_mode(self, preset_mode):
"""Set the preset mode of device."""
if preset_mode not in self.preset_modes:
raise ValueError(
"{preset_mode} is not one of the valid preset modes: {self.preset_modes}"
)

if not self.smartfan.is_on:
self.smartfan.turn_on()

self.smartfan.auto_mode()
self.schedule_update_ha_state()

def turn_on(
self,
speed: str = None,
Expand All @@ -122,5 +141,7 @@ def turn_on(
**kwargs,
) -> None:
"""Turn the device on."""
self.smartfan.turn_on()
self.set_speed(speed)
if preset_mode:
self.set_preset_mode(preset_mode)
return
self.set_percentage(percentage)