@@ -51,8 +51,26 @@ def state(self):
5151 return self ._state
5252
5353 @state .setter
54- async def state (self , value ):
55- """Set the state."""
54+ def state (self , value ):
55+ """Setter that schedules the callback."""
56+ self ._state = value
57+ _LOGGER .debug ("Websocket %s" , value )
58+ # Schedule the callback asynchronously without awaiting here.
59+ try :
60+ asyncio .create_task (
61+ self .callback (SIGNAL_CONNECTION_STATE , value , self ._error_reason )
62+ )
63+ except RuntimeError :
64+ # If there's no running loop, schedule safely on the event loop.
65+ loop = asyncio .get_event_loop ()
66+ loop .call_soon_threadsafe (
67+ asyncio .create_task ,
68+ self .callback (SIGNAL_CONNECTION_STATE , value , self ._error_reason ),
69+ )
70+ self ._error_reason = None
71+
72+ async def _set_state (self , value ):
73+ """Async helper to set the state and await the callback."""
5674 self ._state = value
5775 _LOGGER .debug ("Websocket %s" , value )
5876 await self .callback (SIGNAL_CONNECTION_STATE , value , self ._error_reason )
@@ -65,7 +83,7 @@ def _get_uri(server):
6583
6684 async def running (self ):
6785 """Open a persistent websocket connection and act on events."""
68- await OpenEVSEWebsocket . state . fset ( self , STATE_STARTING )
86+ await self . _set_state ( STATE_STARTING )
6987 auth = None
7088
7189 if self ._user and self ._password :
@@ -77,7 +95,7 @@ async def running(self):
7795 heartbeat = 15 ,
7896 auth = auth ,
7997 ) as ws_client :
80- await OpenEVSEWebsocket . state . fset ( self , STATE_CONNECTED )
98+ await self . _set_state ( STATE_CONNECTED )
8199 self .failed_attempts = 0
82100 self ._client = ws_client
83101
@@ -107,11 +125,11 @@ async def running(self):
107125 else :
108126 _LOGGER .error ("Unexpected response received: %s" , error )
109127 self ._error_reason = error
110- await OpenEVSEWebsocket . state . fset ( self , STATE_STOPPED )
128+ await self . _set_state ( STATE_STOPPED )
111129 except (aiohttp .ClientConnectionError , asyncio .TimeoutError ) as error :
112130 if self .failed_attempts > MAX_FAILED_ATTEMPTS :
113131 self ._error_reason = ERROR_TOO_MANY_RETRIES
114- await OpenEVSEWebsocket . state . fset ( self , STATE_STOPPED )
132+ await self . _set_state ( STATE_STOPPED )
115133 elif self .state != STATE_STOPPED :
116134 retry_delay = min (2 ** (self .failed_attempts - 1 ) * 30 , 300 )
117135 self .failed_attempts += 1
@@ -120,16 +138,16 @@ async def running(self):
120138 retry_delay ,
121139 error ,
122140 )
123- await OpenEVSEWebsocket . state . fset ( self , STATE_DISCONNECTED )
141+ await self . _set_state ( STATE_DISCONNECTED )
124142 await asyncio .sleep (retry_delay )
125143 except Exception as error : # pylint: disable=broad-except
126144 if self .state != STATE_STOPPED :
127145 _LOGGER .exception ("Unexpected exception occurred: %s" , error )
128146 self ._error_reason = error
129- await OpenEVSEWebsocket . state . fset ( self , STATE_STOPPED )
147+ await self . _set_state ( STATE_STOPPED )
130148 else :
131149 if self .state != STATE_STOPPED :
132- await OpenEVSEWebsocket . state . fset ( self , STATE_DISCONNECTED )
150+ await self . _set_state ( STATE_DISCONNECTED )
133151 await asyncio .sleep (5 )
134152
135153 async def listen (self ):
@@ -140,7 +158,7 @@ async def listen(self):
140158
141159 async def close (self ):
142160 """Close the listening websocket."""
143- await OpenEVSEWebsocket . state . fset ( self , STATE_STOPPED )
161+ await self . _set_state ( STATE_STOPPED )
144162 await self .session .close ()
145163
146164 async def keepalive (self ):
@@ -151,7 +169,7 @@ async def keepalive(self):
151169 # Negitive time should indicate no pong reply so consider the
152170 # websocket disconnected.
153171 self ._error_reason = ERROR_PING_TIMEOUT
154- await OpenEVSEWebsocket . state . fset ( self , STATE_DISCONNECTED )
172+ await self . _set_state ( STATE_DISCONNECTED )
155173
156174 data = {"ping" : 1 }
157175 _LOGGER .debug ("Sending message: %s to websocket." , data )
@@ -168,7 +186,7 @@ async def keepalive(self):
168186 _LOGGER .error ("Error parsing data: %s" , err )
169187 except RuntimeError as err :
170188 _LOGGER .debug ("Websocket connection issue: %s" , err )
171- await OpenEVSEWebsocket . state . fset ( self , STATE_DISCONNECTED )
189+ await self . _set_state ( STATE_DISCONNECTED )
172190 except Exception as err : # pylint: disable=broad-exception-caught
173191 _LOGGER .debug ("Problem sending ping request: %s" , err )
174- await OpenEVSEWebsocket . state . fset ( self , STATE_DISCONNECTED )
192+ await self . _set_state ( STATE_DISCONNECTED )
0 commit comments