@sharky said in WMZ Sharky 775 einbinden:
@flispy Ich nehme mal an, dass der Volkszähler eine normale serielle Schnittstelle bereitstellt (also "COMxxx" unter Windows bzw. "/dev/ttyUSBxxx" unter Linux). Dann kannst Du das folgende Programm mal ausprobieren, Du musst nur ganz unten ggf. das "/dev/ttyUSB0" in Zeile 86 durch das in Deinem Fall richtige ersetzen. Außerdem muss mit
pip install pySerial
noch die Bibliothek für serielle Schnittstellen für Python installiert werden.
Keine Erfolgsgarantie, ich habe es nur so trocken heruntergeschrieben ...
import serial
import time
import binascii
# === mbus_checksum ===============================================================================
def mbus_checksum(data, skip):
sum = 0
for i in range(0, len(data)):
if i >= skip:
sum = sum + int(data[i])
return bytearray([sum & 255])
# === check_result ================================================================================
def check_result(where, ser):
result = ser.read(1)
if result == b'\xe5':
return True
else:
if result is None:
return True
else:
print(f'{where}: bad answer: {binascii.hexlify(bytearray(result), " ")}')
return False
# === get_data ====================================================================================
def get_data(ser):
# 2.5: at 2400, 8N1 to send 2.2s of alternating bits
ser.write(b'\x55' * 528)
# time.sleep(2.0) # 2.0s sleep -> 0.8s break -> 1.2s until the buffer is empty ...
time.sleep(1.2 + 170.0 / 2400.0)
# 2.3: change parity
ser.parity=serial.PARITY_EVEN
# 2.7.1: do selection, use jokers for serial, manufacturer, ID, medium
# 17 chars, 0.08s outgoing
selection = b'\x68\x0B\x0B\x68\x53\xFD\x52\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'
ser.write(selection)
ser.write(mbus_checksum(selection, 4))
ser.write(b'\x16')
# result arrives after 0.19s - 0.30s
check_result('Selection', ser)
# 3.1: do application reset 0x50 (to read instant values)
# 10 chars, 0.05s outgoing
app_reset = b'\x68\x04\x04\x68\x53\xFD\x50\x50'
ser.write(app_reset)
ser.write(mbus_checksum(app_reset, 4))
ser.write(b'\x16')
# result arrives after 0.08s
check_result('Application reset', ser)
# 3.2: do read data
# 5 chars, 0.02s
read_data = b'\x10\x7B\xFD'
ser.write(read_data)
ser.write(mbus_checksum(read_data, 1))
ser.write(b'\x16')
# result arrives after 0.07s, is 0.71s long (ca. 173 bytes)
result = ser.read(200) # 173 bytes plus some reserves
if result is None:
print('No data received')
else:
# debug output (hex dump) of received data
print(f'user data bytes: {binascii.hexlify(bytearray(result), " ")}')
# 2.7.2: do deselection
# 5 chars, 0.02s
deselection = b'\x10\x40\xfd'
ser.write(deselection)
ser.write(mbus_checksum(deselection, 0))
ser.write(b'\x16')
check_result('Deselection', ser)
# return bytes received
return result
# === main ========================================================================================
print('Starting up ...\n')
# 2.5: 2400, 8N1 to send 2.2s of alternating bits, long timeout due to slow response by Ultramess
ser = serial.Serial("/dev/ttyUSB0", baudrate=2400, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=0.5)
while True:
print('Reading #0')
result = get_data(ser)
time.sleep(5.0)
Hallo, ich versuchte gerade dein Skript an meinem CF Echo 2 anzupassen doch leider verstehe ein paar Sachen in deinen Skript nicht.
Wieso sieht das mit dem time.sleep so komisch aus, warum wird hier addiert und dividiert? Ich denke hier soll doch nur eine Wartezeit generiert werden oder?
Zur Zeit erhalte ich immer einen Fehler beim Check-result, das bedeutet doch auch das die Daten nicht richtig sein können oder? Oder können diese dennoch stimmen?
Hast du eine Ahnung wie ich die Daten richtig parsen kann also die Daten wie verbrauch heraus lesen kann?
Das Skript hat nur auf jeden Fall schon sehr viel weitergeholfen.
Gruß Thorsten Niemann