11"""Communication with an Intesisbox device."""
22
3+ from __future__ import annotations
4+
35import asyncio
46from asyncio import BaseTransport , ensure_future
57from collections .abc import Callable
@@ -78,6 +80,15 @@ async def keep_alive(self):
7880 else :
7981 _LOGGER .debug ("Not connected, skipping keepalive" )
8082
83+ async def poll_ambtemp (self ):
84+ """Retrieve Ambient Temperature to prevent integration timeouts."""
85+ while self .is_connected :
86+ _LOGGER .debug ("Sending AMBTEMP" )
87+ self ._write ("GET,1:AMBTEMP" )
88+ await asyncio .sleep (10 )
89+ else :
90+ _LOGGER .debug ("Not connected, skipping Ambient Temp Request" )
91+
8192 async def query_initial_state (self ):
8293 """Fetch configuration from the device upon connection."""
8394 cmds = [
@@ -96,6 +107,12 @@ def _write(self, cmd):
96107 self ._transport .write (f"{ cmd } \r " .encode ("ascii" ))
97108 _LOGGER .debug (f"Data sent: { cmd !r} " )
98109
110+ async def _writeasync (self , cmd ):
111+ """Async write to slow down commands and await response from units."""
112+ self ._transport .write (f"{ cmd } \r " .encode ("ascii" ))
113+ _LOGGER .debug (f"Data sent: { cmd !r} " )
114+ await asyncio .sleep (1 )
115+
99116 def data_received (self , data ):
100117 """Asyncio callback when data is received on the socket."""
101118 linesReceived = data .decode ("ascii" ).splitlines ()
@@ -111,8 +128,8 @@ def data_received(self, data):
111128 if cmd == "ID" :
112129 self ._parse_id_received (args )
113130 self ._connectionStatus = API_AUTHENTICATED
114- _ = asyncio .ensure_future (self .keep_alive ())
115131 _ = asyncio .ensure_future (self .poll_status ())
132+ _ = asyncio .ensure_future (self .poll_ambtemp ())
116133 elif cmd == "CHN,1" :
117134 self ._parse_change_received (args )
118135 statusChanged = True
@@ -251,17 +268,34 @@ def set_horizontal_vane(self, vane: str):
251268 def _set_value (self , uid : str , value : str | int ) -> None :
252269 """Change a setting on the thermostat."""
253270 try :
254- self ._write (f"SET,1:{ uid } ,{ value } " )
271+ asyncio . run ( self ._writeasync (f"SET,1:{ uid } ,{ value } " ) )
255272 except Exception as e :
256273 _LOGGER .error ("%s Exception. %s / %s" , type (e ), e .args , e )
257274
258- def set_mode (self , mode : str ) -> None :
259- """Change the thermostat mode (heat, cool, etc)."""
260- if not self .is_on :
261- self .set_power_on ()
262-
275+ def set_mode (self , mode ):
276+ """Send mode and confirm change before turning on."""
277+ """Some units return responses out of order"""
278+ _LOGGER .debug (f"Setting MODE to { mode } ." )
263279 if mode in MODES :
264280 self ._set_value (FUNCTION_MODE , mode )
281+ if not self .is_on :
282+ """Check to ensure in correct mode before turning on"""
283+ retry = 30
284+ while self .mode != mode and retry > 0 :
285+ _LOGGER .debug (
286+ f"Waiting for MODE to return { mode } , currently { str (self .mode )} "
287+ )
288+ _LOGGER .debug (f"Retry attempt = { retry } " )
289+ asyncio .run (self ._writeasync ("GET,1:MODE" ))
290+ retry -= 1
291+ else :
292+ if retry != 0 :
293+ _LOGGER .debug (
294+ f"MODE confirmed now { str (self .mode )} , proceed to Power On"
295+ )
296+ self .set_power_on ()
297+ else :
298+ _LOGGER .error ("Cannot set Intesisbox mode giving up..." )
265299
266300 def set_mode_dry (self ):
267301 """Public method to set device to dry asynchronously."""
0 commit comments