From 18d62cb28a473b3f911d6581705c6c9d4c087fee Mon Sep 17 00:00:00 2001 From: Stephan Joubert Date: Sun, 27 Feb 2022 18:20:30 +0200 Subject: [PATCH] Add checksum verification and retries to the connection. --- custom_components/solarman/solarman.py | 45 +++++++++++++++++++------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/custom_components/solarman/solarman.py b/custom_components/solarman/solarman.py index 24366cb..b91a9a2 100644 --- a/custom_components/solarman/solarman.py +++ b/custom_components/solarman/solarman.py @@ -75,8 +75,23 @@ def generate_request(self, start, length): del packet_data del buisiness_field return packet + + def validate_checksum(self, packet): + checksum = 0 + length = len(packet) + # Don't include the checksum and END OF MESSAGE (-2) + for i in range(1,length-2,1): + checksum += packet[i] + checksum &= 0xFF + if checksum == packet[length-2]: + return 1 + else: + return 0 + + def send_request (self, params, start, end): + result = 0 length = end - start + 1 request = self.generate_request(start, length) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -85,18 +100,16 @@ def send_request (self, params, start, end): sock.connect((self._host, self._port)) sock.sendall(request) # Request param 0x3B up to 0x71 raw_msg = sock.recv(1024) - self.status_lastUpdate = datetime.now().strftime("%m/%d/%Y, %H:%M:%S") - self.status_connection = "Connected" - params.parse(raw_msg, start, length) + if self.validate_checksum(raw_msg) == 1: + result = 1 + params.parse(raw_msg, start, length) del raw_msg except: - print ('Could not connect to the inverter on %s:%s', self._host, self._port) - self.status_connection = "Disconnected" + result = 0 finally: - sock.close() - + sock.close() del request - return + return result @Throttle (MIN_TIME_BETWEEN_UPDATES) def update (self): @@ -105,13 +118,23 @@ def update (self): def get_statistics(self): + result = 1 params = ParameterParser(self.parameter_definition) for request in self.parameter_definition['requests']: start = request['start'] end= request['end'] - self.send_request(params, start, end) - - self._current_val = params.get_result() + if 0 == self.send_request(params, start, end): + # retry once + if 0 == self.send_request(params, start, end): + result = 0 + + if result == 1: + self.status_lastUpdate = datetime.now().strftime("%m/%d/%Y, %H:%M:%S") + self.status_connection = "Connected" + self._current_val = params.get_result() + else: + self.status_connection = "Disconnected" + def get_current_val(self): return self._current_val