Describe the issue
I am experiencing frequent intermittent "unavailable" states with this integration in Home Assistant. After diagnosing my local network, I noticed that my heat pump has a slightly unstable Wi-Fi connection with occasional packet loss (dropping a ping here and there).
Since the integration communicates via UDP, any single dropped packet during an update cycle causes _send() to immediately raise a TimeoutError, which subsequently breaks the Home Assistant state update.
Analysis of client.py
In the current implementation of PoolComfortClient._send, the thread blocks on slot.event.wait(self.timeout). If the heat pump doesn't reply within the timeout window, a TimeoutError is raised immediately:
if not slot.event.wait(self.timeout):
raise TimeoutError("no response from heat pump")
There is no mechanism to retry the transmission if a packet is lost in transit.
Proposed Solution
I suggest wrapping the inner logic of _send() in a retry loop (e.g., maximum 3 attempts) with a brief delay (time.sleep) between attempts. If a packet is dropped due to weak Wi-Fi signal, the client will automatically re-transmit the same packet (keeping the same sequence number).
This would greatly improve reliability for users with outdoor or distant Wi-Fi installations without impacting users with strong connections.
Code proposal from Gemini 3.5
def _send(self, packet: Packet) -> Packet:
if self._sock is None:
raise RuntimeError("client is not connected")
key = (packet.sequence, packet.message_type)
max_retries = 3
retry_delay = 0.3
for attempt in range(1, max_retries + 1):
slot = _Pending(event=threading.Event())
with self._pending_lock:
self._pending[key] = slot
try:
with self._send_lock:
if self._sock is None:
raise RuntimeError("client is not connected")
self._sock.sendto(packet.build(), (self.host, CONTROL_PORT))
self._last_send = time.monotonic()
# Vänta på svar från lästråden
if slot.event.wait(self.timeout):
if slot.reply is None:
raise RuntimeError("client closed during send")
return slot.reply
# Om vi hamnar här har slot.event.wait() nått timeout (returnerat False)
if attempt < max_retries:
import logging
logger = logging.getLogger(__name__)
logger.warning(
"Pool communication timeout. Retrying packet (seq: %s, type: %s). Attempt %d/%d",
packet.sequence, packet.message_type, attempt, max_retries
)
time.sleep(retry_delay)
else:
raise TimeoutError("no response from heat pump after maximum retries")
finally:
with self._pending_lock:
self._pending.pop(key, None)
Describe the issue
I am experiencing frequent intermittent "unavailable" states with this integration in Home Assistant. After diagnosing my local network, I noticed that my heat pump has a slightly unstable Wi-Fi connection with occasional packet loss (dropping a ping here and there).
Since the integration communicates via UDP, any single dropped packet during an update cycle causes
_send()to immediately raise aTimeoutError, which subsequently breaks the Home Assistant state update.Analysis of client.py
In the current implementation of
PoolComfortClient._send, the thread blocks onslot.event.wait(self.timeout). If the heat pump doesn't reply within the timeout window, aTimeoutErroris raised immediately:There is no mechanism to retry the transmission if a packet is lost in transit.
Proposed Solution
I suggest wrapping the inner logic of _send() in a retry loop (e.g., maximum 3 attempts) with a brief delay (time.sleep) between attempts. If a packet is dropped due to weak Wi-Fi signal, the client will automatically re-transmit the same packet (keeping the same sequence number).
This would greatly improve reliability for users with outdoor or distant Wi-Fi installations without impacting users with strong connections.
Code proposal from Gemini 3.5