mirror of https://github.com/simbaja/ha_gehome.git
- more reconnection/online/offline handling
This commit is contained in:
parent
3409ae9e03
commit
3e845764ec
|
@ -16,6 +16,7 @@ MOBILE_DEVICE_TOKEN = "mdt"
|
|||
XMPP_CREDENTIALS = "xmpp_credentials"
|
||||
|
||||
UPDATE_INTERVAL = 30
|
||||
APPLIANCE_LIST_UPDATE_INTERVAL = 300
|
||||
ASYNC_TIMEOUT = 30
|
||||
MIN_RETRY_DELAY = 15
|
||||
MAX_RETRY_DELAY = 1800
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"name": "GE Kitchen",
|
||||
"config_flow": true,
|
||||
"documentation": "https://github.com/simbaja/ha_components",
|
||||
"requirements": ["gekitchensdk==0.3.3","magicattr==0.1.5"],
|
||||
"requirements": ["gekitchensdk==0.3.4","magicattr==0.1.5"],
|
||||
"codeowners": ["@simbaja"]
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ from .const import (
|
|||
DOMAIN,
|
||||
EVENT_ALL_APPLIANCES_READY,
|
||||
UPDATE_INTERVAL,
|
||||
APPLIANCE_LIST_UPDATE_INTERVAL,
|
||||
MIN_RETRY_DELAY,
|
||||
MAX_RETRY_DELAY,
|
||||
RETRY_OFFLINE_COUNT,
|
||||
|
@ -46,6 +47,11 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
self._config_entry = config_entry
|
||||
self._username = config_entry.data[CONF_USERNAME]
|
||||
self._password = config_entry.data[CONF_PASSWORD]
|
||||
self._reset_initialization()
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN)
|
||||
|
||||
def _reset_initialization(self):
|
||||
self.client = None # type: Optional[GeWebsocketClient]
|
||||
self._appliance_apis = {} # type: Dict[str, ApplianceApi]
|
||||
|
||||
|
@ -55,8 +61,6 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
self._retry_count = 0
|
||||
self.initialization_future = asyncio.Future()
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN)
|
||||
|
||||
def create_ge_client(self, event_loop: Optional[asyncio.AbstractEventLoop]) -> GeWebsocketClient:
|
||||
"""
|
||||
Create a new GeClient object with some helpful callbacks.
|
||||
|
@ -88,6 +92,14 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
"""
|
||||
return self.client is not None or self._retry_count <= RETRY_OFFLINE_COUNT
|
||||
|
||||
@property
|
||||
def connected(self) -> bool:
|
||||
"""
|
||||
Indicates whether the coordinator is connected
|
||||
TODO: Make this a part of the client properties as websocket is not applicable for all
|
||||
"""
|
||||
return self.client and self.client.websocket and not self.client.websocket.closed
|
||||
|
||||
def _get_appliance_api(self, appliance: GeAppliance) -> ApplianceApi:
|
||||
api_type = get_appliance_api_type(appliance.appliance_type)
|
||||
return api_type(self, appliance)
|
||||
|
@ -110,14 +122,12 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
"""Get a new GE Websocket client."""
|
||||
if self.client:
|
||||
try:
|
||||
#for now, just clear the one we care about using internals...
|
||||
#new version of sdk needed to clear handles
|
||||
self.client.clear_event_handlers()
|
||||
await self.client.disconnect()
|
||||
except Exception as err:
|
||||
_LOGGER.warn(f'exception while disconnecting client {err}')
|
||||
finally:
|
||||
self.client = None
|
||||
self._reset_initialization()
|
||||
|
||||
loop = self._hass.loop
|
||||
self.client = self.create_ge_client(event_loop=loop)
|
||||
|
@ -211,6 +221,19 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
_LOGGER.debug("forcing a state refresh while disconnected")
|
||||
await self._refresh_ha_state()
|
||||
|
||||
@callback
|
||||
def appliance_list_refresh(self) -> None:
|
||||
self.hass.loop.create_task(self.async_appliance_list_refresh())
|
||||
|
||||
async def async_appliance_list_refresh(self) -> None:
|
||||
"""Try to refresh the appliance list, including online/offline state"""
|
||||
_LOGGER.debug("refreshing appliance list/states")
|
||||
try:
|
||||
if(self.connected):
|
||||
await self.client.get_appliance_list()
|
||||
except:
|
||||
_LOGGER.debug("could not refresh appliance list")
|
||||
|
||||
@callback
|
||||
def shutdown(self, event) -> None:
|
||||
"""Close the connection on shutdown.
|
||||
|
@ -257,9 +280,13 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
self.last_update_success = True
|
||||
if not self._got_roster:
|
||||
self._got_roster = True
|
||||
#TODO: Probably should have a better way of confirming we're good to go...
|
||||
await asyncio.sleep(5) # After the initial roster update, wait a bit and hit go
|
||||
await self.async_maybe_trigger_all_ready()
|
||||
|
||||
#initialize the next refresh
|
||||
self.hass.loop.call_later(APPLIANCE_LIST_UPDATE_INTERVAL, self.appliance_list_refresh)
|
||||
|
||||
async def on_device_initial_update(self, appliance: GeAppliance):
|
||||
"""When an appliance first becomes ready, let the system know and schedule periodic updates."""
|
||||
_LOGGER.debug(f'Got initial update for {appliance.mac_addr}')
|
||||
|
@ -267,9 +294,9 @@ class GeKitchenUpdateCoordinator(DataUpdateCoordinator):
|
|||
self.maybe_add_appliance_api(appliance)
|
||||
await self.async_maybe_trigger_all_ready()
|
||||
_LOGGER.debug(f'Requesting updates for {appliance.mac_addr}')
|
||||
while self.client and not self.client.websocket.closed and appliance.available:
|
||||
while self.connected and appliance.available:
|
||||
await asyncio.sleep(UPDATE_INTERVAL)
|
||||
if self.client and not self.client.websocket.closed:
|
||||
if self.connected:
|
||||
await appliance.async_request_update()
|
||||
|
||||
_LOGGER.debug(f'No longer requesting updates for {appliance.mac_addr}')
|
||||
|
|
Loading…
Reference in New Issue