Skip to content

Commit

Permalink
Fix handling of missing active program
Browse files Browse the repository at this point in the history
  • Loading branch information
ekutner committed Jul 4, 2023
1 parent f8f0be9 commit ee556ff
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
32 changes: 17 additions & 15 deletions home_connect_async/appliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ async def _async_set_program(self, key, options:Sequence[dict], mode:str) -> boo

#endregion


async def async_set_connection_state(self, connected:bool):
""" Update the appliance connection state when notified about a state change from the event stream """
if connected != self.connected:
Expand Down Expand Up @@ -535,57 +535,59 @@ async def async_update_data(self, data:dict) -> None:
# it is also possible to get operation state Run without getting the ActiveProgram event
(key == "BSH.Common.Status.OperationState" and value=="BSH.Common.EnumType.OperationState.Run")
) and \
(not self.active_program or (key == "BSH.Common.Root.ActiveProgram" and self.active_program.key != value) ) :
(not self.active_program or (key == "BSH.Common.Root.ActiveProgram" and self.active_program.key != value) ) and \
self._active_program_fail_count < 3 :
# handle program start
self.active_program = await self._async_fetch_programs("active")
if self.active_program:
self._active_program_fail_count = 0
else:
# This is a workaround to prevent rate limiting when receiving progress events but avaialable_programs returns 404
self._active_program_fail_count += 1
self.available_programs = await self._async_fetch_programs("available")
self.settings = await self._async_fetch_settings()
self.commands = await self._async_fetch_commands()
await self._callbacks.async_broadcast_event(self, Events.PROGRAM_STARTED, value)
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)
self._active_program_fail_count = 0

elif ( (key == "BSH.Common.Root.ActiveProgram" and not value) or
(key == "BSH.Common.Status.OperationState" and value in ["BSH.Common.EnumType.OperationState.Ready", "BSH.Common.EnumType.OperationState.Finished"]) or
(key == "BSH.Common.Event.ProgramFinished")
) and self.active_program:
# handle program end
prev_prog = self.active_program.key if self.active_program else None
self.active_program = None
self._active_program_fail_count = 0
self.settings = await self._async_fetch_settings()
self.commands = await self._async_fetch_commands()
self.available_programs = await self._async_fetch_programs("available")
await self._callbacks.async_broadcast_event(self, Events.PROGRAM_FINISHED, prev_prog)
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)
self._active_program_fail_count = 0

elif key == "BSH.Common.Status.OperationState" and \
value!="BSH.Common.EnumType.OperationState.Run" and \
self.status.get("BSH.Common.Status.OperationState") != value: # ignore repeat notifiations of the same state
#await self.async_fetch_data(include_static_data=False)
self.active_program = await self._async_fetch_programs("active")
self.selected_program = await self._async_fetch_programs("selected")
self.available_programs = await self._async_fetch_programs("available")
self.settings = await self._async_fetch_settings()
self.commands = await self._async_fetch_commands()
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)

elif key =="BSH.Common.Status.RemoteControlStartAllowed":
self.available_programs = await self._async_fetch_programs("available")
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)

elif ( not self.available_programs or len(self.available_programs) < 2) and \
( self._active_program_fail_count < 5 ) and \
( key in ["BSH.Common.Status.OperationState", "BSH.Common.Status.RemoteControlActive"] ) and \
( "BSH.Common.Status.OperationState" not in self.status or self.status["BSH.Common.Status.OperationState"].value == "BSH.Common.EnumType.OperationState.Ready" ) and \
( "BSH.Common.Status.RemoteControlActive" not in self.status or self.status["BSH.Common.Status.RemoteControlActive"].value):
# Handle cases were the appliance data was loaded without getting all the programs (for example when HA is restarted while a program is active)
# If the state is Ready and remote control is possible and we didn"t load the available programs before then load them now
# If the state is Ready and remote control is possible and we didn't load the available programs before then load them now
available_programs = await self._async_fetch_programs("available")
if available_programs:
self.available_programs = available_programs
await self._callbacks.async_broadcast_event(self, Events.PAIRED)
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)
self._active_program_fail_count = 0
else:
# This is a workaround to prevent rate limiting when receiving progress events but avaialable_programs returns 404
self._active_program_fail_count += 1
self.available_programs = available_programs
await self._callbacks.async_broadcast_event(self, Events.PAIRED)
await self._callbacks.async_broadcast_event(self, Events.DATA_CHANGED)

# broadcast the specific event that was received
await self._callbacks.async_broadcast_event(self, key, value)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setup(
name = 'home-connect-async',
packages = ['home_connect_async'],
version = '0.7.8',
version = '0.7.9',
license='MIT',
description = 'Async SDK for BSH Home Connect API',
author = 'Eran Kutner',
Expand Down

0 comments on commit ee556ff

Please sign in to comment.