Manchmal führt ungünstige Verkabelung zu Aussetzern in der Kommunikation am seriellen Port. Ich habe keine Ahnung, ob es in pySerial passiert oder im seriellen Treiber oder weil irgendwann mehrere Threads durcheinander Daten senden und die WP sie nicht mehr quittiert. Dies wird im Plugin nicht wirklich abgefangen, weil das Handshake immer synchron abgewickelt wird (Send - Receive). D.h. nach jedem PortHandler.sendData() wird sofort PortHandler.readData() aufgerufen.
readData() hat ein Timeout von 1 Sekunde. Wenn man 50 Parameter pro Zyklus abfragt, kann so ein Zyklus mit gestörter Kommunikation 50 Sekunden in Anspruch nehmen. Wird alle 30 Sekunden gepollt, so wird ein neuer Thread gestartet, bevor der alte fertig geworden ist. Und wenn die serielle Kommunikation wieder in Ordnung wäre, könnten mehrere Threads theoretisch ihre Daten durcheinander senden, was von der WP nicht akzeptiert wird und zu weiteren Kommunikationsproblemen führt. Und so könnte die Anzahl der Threads ansteigen.
Bei mir habe ich Probleme mit den Threads nur dann beobachtet, nachdem ich das Kabel von der WP abgezogen hatte.
Versuch mal requestData() in ThzProtocol.py mit folgendem Code zu ersetzen:
Der Code schließt nach 10 Versuchen den Port, sodass er im nächsten Zyklus wieder geöffnet wird. Das Pollintervall darf aber 10 Sekunden nicht unterschreiten.
readData() hat ein Timeout von 1 Sekunde. Wenn man 50 Parameter pro Zyklus abfragt, kann so ein Zyklus mit gestörter Kommunikation 50 Sekunden in Anspruch nehmen. Wird alle 30 Sekunden gepollt, so wird ein neuer Thread gestartet, bevor der alte fertig geworden ist. Und wenn die serielle Kommunikation wieder in Ordnung wäre, könnten mehrere Threads theoretisch ihre Daten durcheinander senden, was von der WP nicht akzeptiert wird und zu weiteren Kommunikationsproblemen führt. Und so könnte die Anzahl der Threads ansteigen.
Bei mir habe ich Probleme mit den Threads nur dann beobachtet, nachdem ich das Kabel von der WP abgezogen hatte.
Versuch mal requestData() in ThzProtocol.py mit folgendem Code zu ersetzen:
PHP-Code:
def requestData(self, request):
# check the port status
if not self._portHandler.isPortOpen():
self._portErrorCount += 1
if not self._portHandler.openPort(self._serial_port, self._baudrate):
return {}
response = {}
try:
noResponseCount = 0
for name in request:
msg1 = self._sendGetRequest(MsgTemplate[name]['cmd1'])
if not msg1 == None:
noResponseCount = 0
if 'cmd2' in MsgTemplate[name]:
# there is a second command to retrieve the most significant part
msg2 = self._sendGetRequest(MsgTemplate[name]['cmd2'])
if not msg2 == None:
# get the name of the one and only parameter
param = list(msg1[name].keys())[0]
try:
# combine the two values (the most significant part is to
# be multiplied by 1000)
msg1[name][param] = round(msg2[name][param] * 1000 + msg1[name][param],3)
response.update(msg1[name])
except:
logger.warning(sys.exc_info())
else:
# there is only one response
response.update(msg1[name])
else:
# no response received
noResponseCount += 1
if noResponseCount > 10:
# missing 10 responses in a row
logger.error('Heat pump did not respond for 10 seconds')
self._portHandler.closePort()
break
except:
logger.warning(sys.exc_info())
return response
Kommentar