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

Fix for #97 Detected IO inside event loop #99

Merged
merged 7 commits into from
May 2, 2020
Merged
Show file tree
Hide file tree
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
87 changes: 51 additions & 36 deletions custom_components/wiser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# import time
from datetime import datetime, timedelta
from functools import partial
import voluptuous as vol
from wiserHeatingAPI.wiserHub import (
wiserHub,
Expand Down Expand Up @@ -132,33 +133,38 @@ def retryWiserHubSetup():
async def wiserHubSetup():
_LOGGER.info("Initiating WiserHub connection")
try:
if await data.async_update():
if data.wiserhub.getDevices is None:
_LOGGER.error("No Wiser devices found to set up")
return False

hass.data[DOMAIN] = data

for platform in WISER_PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
config_entry, platform
if await data.async_connect():
if await data.async_update():
if data.wiserhub.getDevices is None:
_LOGGER.error("No Wiser devices found to set up")
return False

hass.data[DOMAIN] = data

for platform in WISER_PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(
config_entry, platform
)
)
)

_LOGGER.info("Wiser Component Setup Completed")
return True
else:
await scheduleWiserHubSetup()
return True
_LOGGER.info("Wiser Component Setup Completed")
await data.async_update_device_registry()
return True
else:
await scheduleWiserHubSetup()
return True
except (asyncio.TimeoutError):
await scheduleWiserHubSetup()
return True
except WiserHubTimeoutException:
await scheduleWiserHubSetup()
return True
except Exception:
await scheduleWiserHubSetup()
return True

async def scheduleWiserHubSetup(interval=30):
async def scheduleWiserHubSetup(interval=10):
_LOGGER.error(
"Unable to connect to the Wiser Hub, retrying in {} seconds".format(
interval
Expand All @@ -167,8 +173,7 @@ async def scheduleWiserHubSetup(interval=30):
hass.loop.call_later(interval, retryWiserHubSetup)
return

hass.async_create_task(wiserHubSetup())
await data.async_update_device_registry()
await wiserHubSetup()
return True


Expand Down Expand Up @@ -214,7 +219,7 @@ def __init__(self, hass, config_entry, ip, secret):
self._name = config_entry.data[CONF_NAME]
self.ip = ip
self.secret = secret
self.wiserhub = wiserHub(self.ip, self.secret)
self.wiserhub = None
self.minimum_temp = TEMP_MINIMUM
self.maximum_temp = TEMP_MAXIMUM
self.boost_temp = config_entry.data.get(CONF_BOOST_TEMP, DEFAULT_BOOST_TEMP)
Expand All @@ -223,6 +228,12 @@ def __init__(self, hass, config_entry, ip, secret):
)
self.timer_handle = None

async def async_connect(self):
self.wiserhub = await self._hass.async_add_executor_job(
partial(wiserHub, self.ip, self.secret)
)
return True

@callback
def do_hub_update(self):
self._hass.async_create_task(self.async_update())
Expand Down Expand Up @@ -256,7 +267,7 @@ async def async_update(self, no_throttle: bool = False):
dispatcher_send(self._hass, "WiserHubUpdateMessage")
return True
else:
_LOGGER.error("**Unable to update from wiser hub**")
_LOGGER.error("Unable to update from wiser hub")
return False
except json.decoder.JSONDecodeError as JSONex:
_LOGGER.error(
Expand All @@ -265,15 +276,11 @@ async def async_update(self, no_throttle: bool = False):
)
return False
except WiserHubTimeoutException as ex:
_LOGGER.error(
"***Failed to get update from Wiser hub due to timeout error***"
)
_LOGGER.error("Unable to update from Wiser hub due to timeout error")
_LOGGER.debug("Error is {}".format(ex))
return False
except Exception as ex:
_LOGGER.error(
"***Failed to get update from Wiser hub due to unknown error***"
)
_LOGGER.error("Unable to update from Wiser hub due to unknown error")
_LOGGER.debug("Error is {}".format(ex))
return False

Expand All @@ -297,22 +304,26 @@ async def async_update_device_registry(self):
async def set_away_mode(self, away, away_temperature):
mode = "AWAY" if away else "HOME"
if self.wiserhub is None:
self.wiserhub = wiserHub(self.ip, self.secret)
self.wiserhub = await self.async_connect()
_LOGGER.debug(
"Setting away mode to {} with temp {}.".format(mode, away_temperature)
)
try:
self.wiserhub.setHomeAwayMode(mode, away_temperature)
await self._hass.async_add_executor_job(
partial(self.wiserhub.setHomeAwayMode, mode, away_temperature)
)
await self.async_update(no_throttle=True)
except BaseException as e:
_LOGGER.debug("Error setting away mode! {}".format(str(e)))

async def set_system_switch(self, switch, mode):
if self.wiserhub is None:
self.wiserhub = wiserHub(self.ip, self.secret)
self.wiserhub = await self.async_connect()
_LOGGER.debug("Setting {} system switch to {}.".format(switch, mode))
try:
self.wiserhub.setSystemSwitch(switch, mode)
await self._hass.async_add_executor_job(
partial(self.wiserhub.setSystemSwitch, switch, mode)
)
await self.async_update(no_throttle=True)
except BaseException as e:
_LOGGER.debug("Error setting {} system switch! {}".format(switch, str(e)))
Expand All @@ -325,11 +336,13 @@ async def set_smart_plug_state(self, plug_id, state):
:return:
"""
if self.wiserhub is None:
self.wiserhub = wiserHub(self.ip, self.secret)
self.wiserhub = await self.async_connect()
_LOGGER.info("Setting SmartPlug {} to {} ".format(plug_id, state))

try:
self.wiserhub.setSmartPlugState(plug_id, state)
await self._hass.async_add_executor_job(
partial(self.wiserhub.setSmartPlugState, plug_id, state)
)
# Add small delay to allow hub to update status before refreshing
await asyncio.sleep(0.5)
await self.async_update(no_throttle=True)
Expand All @@ -346,14 +359,16 @@ async def set_hotwater_mode(self, hotwater_mode):

"""
if self.wiserhub is None:
self.wiserhub = wiserHub(self.ip, self.secret)
self.wiserhub = await self.async_connect()
_LOGGER.info("Setting Hotwater to {} ".format(hotwater_mode))
# Add small delay to allow hub to update status before refreshing
await asyncio.sleep(0.5)
await self.async_update(no_throttle=True)

try:
self.wiserhub.setHotwaterMode(hotwater_mode)
await self._hass.async_add_executor_job(
partial(self.wiserhub.setHotwaterMode, hotwater_mode)
)

except BaseException as e:
_LOGGER.debug(
Expand Down
30 changes: 26 additions & 4 deletions custom_components/wiser/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@

import voluptuous as vol

from functools import partial
from homeassistant.components.climate import ClimateDevice
from homeassistant.core import callback

from homeassistant.components.climate.const import (
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
HVAC_MODE_AUTO,
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_PRESET_MODE,
Expand Down Expand Up @@ -331,6 +334,13 @@ def device_info(self):
"model": ROOM.title(),
}

@property
def hvac_action(self):
if self.data.wiserhub.getRoom(self.room_id).get("ControlOutputState") == "On":
return CURRENT_HVAC_HEAT
else:
return CURRENT_HVAC_IDLE

@property
def hvac_mode(self):
state = self.data.wiserhub.getRoom(self.room_id).get("Mode")
Expand Down Expand Up @@ -477,7 +487,11 @@ async def async_set_temperature(self, **kwargs):
_LOGGER.debug(
"Setting temperature for {} to {}".format(self.name, target_temperature)
)
self.data.wiserhub.setRoomTemperature(self.room_id, target_temperature)
await self.hass.async_add_executor_job(
partial(
self.data.wiserhub.setRoomTemperature, self.room_id, target_temperature
)
)
self._force_update = True
await self.async_update_ha_state(True)

Expand All @@ -490,15 +504,21 @@ async def set_room_mode(self, room_id, mode, boost_temp=None, boost_time=None):
_LOGGER.debug(
"Setting Room Mode to {} for roomId {}".format(mode, self.room_id)
)
self.data.wiserhub.setRoomMode(room_id, mode, boost_temp, boost_time)
await self.hass.async_add_executor_job(
partial(
self.data.wiserhub.setRoomMode, room_id, mode, boost_temp, boost_time
)
)
self._force_update = True
await self.async_update_ha_state(True)
return True

async def set_room_schedule(self, room_id, scheduleData):
if scheduleData != None:
scheduleData = convert_to_wiser_schedule(scheduleData)
self.data.wiserhub.setRoomSchedule(room_id, scheduleData)
await self.hass.async_add_executor_job(
partial(self.data.wiserhub.setRoomSchedule, room_id, scheduleData)
)
_LOGGER.debug("Set room schedule for {}".format(self.name))
self._force_update = True
await self.async_update_ha_state(True)
Expand All @@ -507,7 +527,9 @@ async def set_room_schedule(self, room_id, scheduleData):
return False

async def copy_room_schedule(self, room_id, to_room_id):
self.data.wiserhub.copyRoomSchedule(room_id, to_room_id)
await self.hass.async_add_executor_job(
partial(self.data.wiserhub.copyRoomSchedule, room_id, to_room_id)
)
_LOGGER.debug(
"Copied room schedule from {} to {}".format(
self.name, self.data.wiserhub.getRoom(to_room_id).get("Name")
Expand Down