diff --git a/pysolarmanv5/pysolarmanv5.py b/pysolarmanv5/pysolarmanv5.py index 593b5a8..5154037 100644 --- a/pysolarmanv5/pysolarmanv5.py +++ b/pysolarmanv5/pysolarmanv5.py @@ -1,12 +1,13 @@ """pysolarmanv5.py""" +import time import errno import queue import struct import socket import logging -import selectors import platform +import selectors from threading import Thread, Event from multiprocessing import Queue @@ -299,9 +300,9 @@ def _send_receive_v5_frame(self, data_logging_stick_frame): return v5_response def _received_frame_is_valid(self, frame): - """Check that the frame is valid and that the serial number of the received + """ + Check that the frame is valid and that the serial number of the received frame matches with the last sent one. - Ignore also any frames with control code 0x4710 (counter frame). """ if not frame.startswith(self.v5_start): self.log.debug("[%s] V5_MISMATCH: %s", self.serial, frame.hex(" ")) @@ -309,8 +310,32 @@ def _received_frame_is_valid(self, frame): if frame[5] != self.sequence_number: self.log.debug("[%s] V5_SEQ_NO_MISMATCH: %s", self.serial, frame.hex(" ")) return False + return True + + def _handle_protocol_frame(self, frame): + """ + Handles protocol frames with control code 0x4710 (heartbeat frame). + """ if frame.startswith(self.v5_start + b"\x01\x00\x10\x47"): - self.log.debug("[%s] COUNTER: %s", self.serial, frame.hex(" ")) + self.log.debug("[%s] V5_HEARTBEAT: %s", self.serial, frame.hex(" ")) + response_frame = bytearray( + self.v5_start + + struct.pack(" None: """ Socket reader loop with extra logic when auto-reconnect is enabled @@ -185,6 +224,8 @@ async def _conn_keeper(self) -> None: break if not self._received_frame_is_valid(data): continue + if not await self._handle_protocol_frame(data): + continue if self.data_wanted_ev.is_set(): self._send_data(data) else: