hardware:channels:meters:power:edl-ehz:iskra_mt372
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungLetzte ÜberarbeitungBeide Seiten der Revision | ||
hardware:channels:meters:power:edl-ehz:iskra_mt372 [2015/11/15 12:29] – [Hardware] udo1 | hardware:channels:meters:power:edl-ehz:iskra_mt372 [2016/10/29 18:59] – verschoben jau | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== ISKRAemeco MT 372 ====== | + | Verschoben |
- | + | ||
- | + | ||
- | Genauer Typ: MT372-D1A51-B11L11-M2K0agZ | + | |
- | Das " | + | |
- | Der Zähler kann nach DIN EN 62056-21 über die IR-Schnittstelle nur nach Aufforderung ausgelesen werden. Er sendet nicht automatisch.\\ | + | |
- | Zusätzlich trägt der Zähler das DLMS-Logo. | + | |
- | + | ||
- | ====== Hardware ====== | + | |
- | + | ||
- | Zum Testen habe ich hterm verwendet, da test1107 nach dem der Zähler mit seiner Typenbezeichnung geantwortet hatte, in ein Timeout lief (Tout).\\ | + | |
- | Einzustellen sind:\\ | + | |
- | Port: bei Windows: | + | |
- | Baud: 300\\ | + | |
- | Data: 7\\ | + | |
- | Stop: 1\\ | + | |
- | Parity: Even\\ | + | |
- | Bei „input control“: Send on Enter auf „CR-LF“\\ | + | |
- | Auf „Connect“ klicken, dann im Eingabefeld “/?!“ (ohne Anführungszeichen) eingeben und Enter drücken. Wenn im Feld „received data“ was erscheint, funktioniert die Kommunikation prinzipiell. \\ | + | |
- | + | ||
- | ====== Beispiel vzlogger.conf ====== | + | |
- | ====== Testverlauf ====== | + | |
- | + | ||
- | Der Artikel | + | |
- | Bei genauer Betrachtung steht dort, dass man innerhalb von 1,5s nach der Initialisierung mit\\ | + | |
- | < | + | |
- | wobei Z = 00 für 300bd und\\ | + | |
- | Y = 00 den Standarddatensatz abrufen kann.\\ | + | |
- | Man muss mit hterm nach "/? | + | |
- | < | + | |
- | senden, dann antwortet der Zähler mit seinem Standarddatensatz.\\ | + | |
- | Das ist schwierig zu realisieren. Ich habe darauf hin einfach ein paar (hex 00) zwischen Inistialisierung und <ACK> gesteckt und alles in einer Zeichefolge aus hterm gesendet. Ab sechs NUL aufwärts klappt es bei meinem Zähler. | + | |
- | + | ||
- | ====== Ergebnis ====== | + | |
- | + | ||
- | Gesendet: /?! CR LF NUL NUL NUL NUL NUL NUL ACK 0 0 0 CR LF (hex 2F 3F 21 0D 0A 00 00 00 00 00 00 00 06 30 30 30 0D 0A)\\ | + | |
- | Antwort des Zählers im hterm:\\ | + | |
- | / | + | |
- | /? | + | |
- | < | + | |
- | 0.0.0(58231541)< | + | |
- | C.1.1(00000000)< | + | |
- | C.1.0(58231541)< | + | |
- | 0.9.1(175102)< | + | |
- | 0.9.2(120619)< | + | |
- | 1.8.0(00132.149*kWh)< | + | |
- | 1.8.1(00132.149*kWh)< | + | |
- | 1.8.2(00000.000*kWh)< | + | |
- | 1.8.3(00000.000*kWh)< | + | |
- | 1.8.4(00000.000*kWh)< | + | |
- | !< | + | |
- | < | + | |
- | + | ||
- | ======Weitere Erkenntnisse ====== | + | |
- | Der Zähler scheint nur mit 300bd zu arbeiten. Trotz der Antwort: / | + | |
- | + | ||
- | Hier ein Python-Script zum Auslesen des Zählers: | + | |
- | Dank an G.Angerer.\\ | + | |
- | < | + | |
- | from __future__ import print_function | + | |
- | import serial | + | |
- | import time | + | |
- | + | ||
- | def send(port, bytes, tr): | + | |
- | """ | + | |
- | port - the open serial port | + | |
- | bytes - the string to be send | + | |
- | tr - the responce time | + | |
- | """ | + | |
- | # | + | |
- | port.write(bytes) | + | |
- | time.sleep(tr) | + | |
- | echo = port.read(len(bytes)) | + | |
- | if (echo != bytes): | + | |
- | print(" | + | |
- | # | + | |
- | + | ||
- | def read_datablock(): | + | |
- | ACK = ' | + | |
- | STX = ' | + | |
- | ETX = ' | + | |
- | tr = 0.3 | + | |
- | """ | + | |
- | try: | + | |
- | IskraMT171=serial.Serial(port='/ | + | |
- | # 1 -> | + | |
- | time.sleep(tr) | + | |
- | Request_message='/? | + | |
- | send(IskraMT171, | + | |
- | # 2 <- | + | |
- | time.sleep(tr) | + | |
- | Identification_message=IskraMT171.readline() # IEC 62056-21: | + | |
- | if (Identification_message[0] != '/' | + | |
- | print(" | + | |
- | IskraMT171.close() | + | |
- | return "" | + | |
- | if (len(Identification_message) < 7): | + | |
- | print(" | + | |
- | IskraMT171.close() | + | |
- | return "" | + | |
- | if (Identification_message[4].islower()): | + | |
- | tr = 0.02 | + | |
- | manufacturers_ID = Identification_message[1: | + | |
- | if (Identification_message[5] == ' | + | |
- | identification = Identification_message[7: | + | |
- | else: | + | |
- | identification = Identification_message[5: | + | |
- | speed = Identification_message[4] | + | |
- | # | + | |
- | if (speed == " | + | |
- | elif (speed == " | + | |
- | elif (speed == " | + | |
- | elif (speed == " | + | |
- | #elif (speed == " | + | |
- | elif (speed == " | + | |
- | else: | + | |
- | new_baud_rate = 300 | + | |
- | speed = " | + | |
- | # | + | |
- | # 3 -> | + | |
- | Acknowledgement_message=ACK + ' | + | |
- | send(IskraMT171, | + | |
- | IskraMT171.baudrate=new_baud_rate | + | |
- | time.sleep(tr) | + | |
- | # 4 <- | + | |
- | datablock = "" | + | |
- | if (IskraMT171.read() == STX): | + | |
- | x = IskraMT171.read() | + | |
- | BCC = 0 | + | |
- | while (x != ' | + | |
- | BCC = BCC ^ ord(x) | + | |
- | datablock = datablock + x | + | |
- | x = IskraMT171.read() | + | |
- | while (x != ETX): | + | |
- | BCC = BCC ^ ord(x) # ETX itself is part of block check | + | |
- | x = IskraMT171.read() | + | |
- | BCC = BCC ^ ord(x) | + | |
- | x = IskraMT171.read() # x is now the Block Check Character | + | |
- | # last character is read, could close connection here | + | |
- | if (BCC != ord(x)): # received correctly? | + | |
- | datablock = "" | + | |
- | print(" | + | |
- | else: | + | |
- | print(" | + | |
- | IskraMT171.close() | + | |
- | return datablock | + | |
- | except: | + | |
- | print(" | + | |
- | if (IskraMT171.isOpen()): | + | |
- | IskraMT171.close() | + | |
- | return "" | + | |
- | + | ||
- | def meter_data(datablock, | + | |
- | """ | + | |
- | if header != 0 a list with data type and units is returned """ | + | |
- | line = [] | + | |
- | ## initialise line | + | |
- | for l in range(len(map)): | + | |
- | if (header == 1): | + | |
- | line.append(map[l][1]) | + | |
- | elif (map[l][0] == " | + | |
- | line.append(time.strftime(" | + | |
- | else: | + | |
- | line.append("" | + | |
- | datasets = datablock.split(' | + | |
- | for dataset in datasets: | + | |
- | if (dataset != "" | + | |
- | x = dataset.split(' | + | |
- | address = x[0] | + | |
- | x = x[1][: | + | |
- | value = x[0] | + | |
- | try: | + | |
- | unit = ' | + | |
- | except: | + | |
- | unit = "" | + | |
- | for l in range(len(map)): | + | |
- | if (map[l][0] == address): | + | |
- | if (header == 0): | + | |
- | line[l] = value | + | |
- | else: | + | |
- | line[l] = map[l][1] + unit | + | |
- | break; | + | |
- | return line | + | |
- | + | ||
- | def output(filename, | + | |
- | f = open(filename, | + | |
- | print(line, file=f) | + | |
- | f.close() | + | |
- | + | ||
- | map = [ | + | |
- | # The structure of the meter_data() output can be set with this variable | + | |
- | # first string on each line is the cosim adress of the data you want to safe or " | + | |
- | # the second string on each line is a description of the type of data belonging to the cosim address | + | |
- | # the order of the lines sets the order of the meter_data() output | + | |
- | # example | + | |
- | # header: [' | + | |
- | # data: [' | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | [" | + | |
- | ] | + | |
- | + | ||
- | example_datablock = """ | + | |
- | 0.0.0(12345678) | + | |
- | C.1.0(12345678) | + | |
- | C.1.1(90123456) | + | |
- | 0.9.1(114138) | + | |
- | 0.9.2(140420) | + | |
- | 1.8.0(25915.768*kWh) | + | |
- | 1.8.1(15798.415*kWh) | + | |
- | 1.8.2(10117.353*kWh) | + | |
- | 1.8.3(00000.000*kWh) | + | |
- | 1.8.4(00000.000*kWh) | + | |
- | F.97.0(00000000) | + | |
- | C.241.0(016) | + | |
- | C.244.0(00000000) | + | |
- | 0.2.0((ER11)) | + | |
- | """ | + | |
- | + | ||
- | # | + | |
- | # | + | |
- | + | ||
- | + | ||
- | file = " | + | |
- | previous_data = "" | + | |
- | data = read_datablock() | + | |
- | + | ||
- | output(file, | + | |
- | while (1): | + | |
- | if (data == "" | + | |
- | print(time.strftime(" | + | |
- | elif (previous_data != data): | + | |
- | output(file, | + | |
- | previous_data = data | + | |
- | time.sleep(3) # minimum waiting time is 3 seconds, less and the meter doesn' | + | |
- | data = read_datablock() | + | |
- | </ | + |