Skip to content

Commit

Permalink
Adds correct speed steps for Well A7. Fixes #11 (#12)
Browse files Browse the repository at this point in the history
* Uses 1-5 fan spee steps for A7

* Adds option to set api update interval
  • Loading branch information
JohNan authored May 25, 2021
1 parent 71a81bf commit afc4138
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 26 deletions.
20 changes: 10 additions & 10 deletions custom_components/wellbeing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.update_coordinator import UpdateFailed
from .api import WellbeingApiClient
from .const import CONF_PASSWORD
from .const import CONF_PASSWORD, CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
from .const import CONF_USERNAME
from .const import DOMAIN
from .const import PLATFORMS

SCAN_INTERVAL = timedelta(seconds=30)

_LOGGER: logging.Logger = logging.getLogger(__package__)


Expand All @@ -36,13 +34,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})

if entry.options.get(CONF_SCAN_INTERVAL):
update_interval = timedelta(seconds=entry.options[CONF_SCAN_INTERVAL])
else:
update_interval = timedelta(seconds=DEFAULT_SCAN_INTERVAL)

username = entry.data.get(CONF_USERNAME)
password = entry.data.get(CONF_PASSWORD)

session = async_get_clientsession(hass)
client = WellbeingApiClient(username, password, session)

coordinator = WellbeingDataUpdateCoordinator(hass, client=client)
coordinator = WellbeingDataUpdateCoordinator(hass, client=client, update_interval=update_interval)
if not await coordinator.async_login():
raise ConfigEntryAuthFailed

Expand All @@ -53,6 +56,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

hass.data[DOMAIN][entry.entry_id] = coordinator

coordinator.platforms.extend(PLATFORMS)
hass.config_entries.async_setup_platforms(entry, PLATFORMS)

entry.add_update_listener(async_reload_entry)
Expand All @@ -62,16 +66,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
class WellbeingDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the API."""

def __init__(
self,
hass: HomeAssistant,
client: WellbeingApiClient,
) -> None:
def __init__(self,hass: HomeAssistant, client: WellbeingApiClient, update_interval: timedelta) -> None:
"""Initialize."""
self.api = client
self.platforms = []

super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)

async def async_login(self) -> bool:
"""Login to Verisure."""
Expand Down
16 changes: 16 additions & 0 deletions custom_components/wellbeing/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,21 @@ def setup(self, data):
for entity in Appliance._create_entities(data) if entity.attr in data
]

@property
def ordered_named_fan_speeds(self):
if self.model == "WELLA7":
return ["0", "1", "2", "3", "4", "5"]
if self.model == "PUREA9":
return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

@property
def speed_range(self):
if self.model == "WELLA7":
return 0, 5
if self.model == "PUREA9":
return 0, 9



class Appliances:
def __init__(self, appliances) -> None:
Expand Down Expand Up @@ -319,6 +334,7 @@ async def async_get_data(self) -> Appliances:
"""Get data from the API."""
n = 0
while not await self.async_login() and n < RETRIES:
_LOGGER.debug(f"Re-trying login. Attempt {n+1} / {RETRIES}")
n += 1

if self._current_access_token is None:
Expand Down
11 changes: 8 additions & 3 deletions custom_components/wellbeing/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Adds config flow for Wellbeing."""
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_create_clientsession

from .api import WellbeingApiClient
from .const import CONF_PASSWORD
from .const import CONF_PASSWORD, CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
from .const import CONF_USERNAME
from .const import DOMAIN
from .const import PLATFORMS
Expand Down Expand Up @@ -95,8 +96,12 @@ async def async_step_user(self, user_input=None):
step_id="user",
data_schema=vol.Schema(
{
vol.Required(x, default=self.options.get(x, True)): bool
for x in sorted(PLATFORMS)
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
),
): cv.positive_int,
}
),
)
Expand Down
4 changes: 3 additions & 1 deletion custom_components/wellbeing/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
CONF_ENABLED = "enabled"
CONF_USERNAME = "username"
CONF_PASSWORD = "password"
CONF_SCAN_INTERVAL = "scan_interval"

# Defaults
DEFAULT_NAME = DOMAIN
DEFAULT_NAME = DOMAIN
DEFAULT_SCAN_INTERVAL = 30
24 changes: 15 additions & 9 deletions custom_components/wellbeing/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
from .entity import WellbeingEntity

SUPPORTED_FEATURES = SUPPORT_SET_SPEED | SUPPORT_PRESET_MODE
SPEED_RANGE = (0, 9)
ORDERED_NAMED_FAN_SPEEDS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

PRESET_MODES = [
Mode.OFF,
Expand Down Expand Up @@ -48,6 +46,14 @@ def __init__(self, coordinator: WellbeingDataUpdateCoordinator, config_entry, pn
self._preset_mode = str(self.get_appliance.mode)
self._speed = self.get_entity.state

@property
def _speed_range(self):
return self.get_appliance.speed_range

@property
def _ordered_named_fan_speeds(self):
return self.get_appliance.ordered_named_fan_speeds

@property
def name(self):
"""Return the name of the sensor."""
Expand All @@ -59,12 +65,12 @@ def speed(self) -> str:

@property
def speed_list(self) -> list:
return list(range(SPEED_RANGE[0], SPEED_RANGE[1]+1))
return list(range(self._speed_range[0], self._speed_range[1]+1))

@property
def speed_count(self) -> int:
"""Return the number of speeds the fan supports."""
return int_states_in_range(SPEED_RANGE)
return int_states_in_range(self._speed_range)

@property
def percentage(self):
Expand All @@ -73,11 +79,11 @@ def percentage(self):
if speed == 0:
return 0

return ranged_value_to_percentage(SPEED_RANGE, speed)
return ranged_value_to_percentage(self._speed_range, speed)

async def async_set_percentage(self, percentage: int) -> None:
"""Set the speed percentage of the fan."""
self._speed = percentage_to_ranged_value(SPEED_RANGE, percentage)
self._speed = percentage_to_ranged_value(self._speed_range, percentage)
self.get_entity.clear_state()
self.async_write_ha_state()

Expand All @@ -90,7 +96,7 @@ async def async_set_percentage(self, percentage: int) -> None:
if not is_manual:
await self.async_set_preset_mode(Mode.MANUAL)

await self.api.set_fan_speed(self.pnc_id, int(percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage)))
await self.api.set_fan_speed(self.pnc_id, int(percentage_to_ordered_list_item(self._ordered_named_fan_speeds, percentage)))

if is_manual:
await asyncio.sleep(10)
Expand Down Expand Up @@ -128,13 +134,13 @@ def is_on(self):
async def async_turn_on(self, speed: str = None, percentage: int = None,
preset_mode: str = None, **kwargs) -> None:
self._preset_mode = Mode(preset_mode or Mode.AUTO.value)
self._speed = percentage_to_ranged_value(SPEED_RANGE, percentage or 10)
self._speed = percentage_to_ranged_value(self._speed_range, percentage or 10)
self.get_appliance.clear_mode()
self.get_entity.clear_state()
self.async_write_ha_state()

await self.api.set_work_mode(self.pnc_id, self._preset_mode)
await self.api.set_fan_speed(self.pnc_id, int(percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage or 10)))
await self.api.set_fan_speed(self.pnc_id, int(percentage_to_ordered_list_item(self._ordered_named_fan_speeds, percentage or 10)))
await asyncio.sleep(10)
await self.coordinator.async_request_refresh()

Expand Down
4 changes: 1 addition & 3 deletions custom_components/wellbeing/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
"step": {
"user": {
"data": {
"binary_sensor": "Binary sensor enabled",
"sensor": "Sensor enabled",
"switch": "Switch enabled"
"scan_interval": "API update interval (seconds)"
}
}
}
Expand Down

0 comments on commit afc4138

Please sign in to comment.