Benutzer-Werkzeuge

Webseiten-Werkzeuge


hardware:channels:meters:power:edl-ehz:iskra_mt372

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Letzte ÜberarbeitungBeide Seiten der Revision
hardware:channels:meters:power:edl-ehz:iskra_mt372 [2015/11/15 12:29] – [Hardware] udo1hardware:channels:meters:power:edl-ehz:iskra_mt372 [2016/10/29 18:59] – verschoben jau
Zeile 1: Zeile 1:
-====== ISKRAemeco MT 372 ====== +Verschoben nach [[iskraemeco_mt372]]
- +
- +
-Genauer Typ: MT372-D1A51-B11L11-M2K0agZ +
-Das "K0" bedeutet, dass er über eine bidirektionale Kundenschnittstelle nach DIN EN 62056-21 verfügt. +
-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:verwendeter COM-Anschluss des USB-Adapters, bei Linux z.B. /dev/ttyUSB0\\ +
-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 [[hardware:channels:meters:power:edl-ehz:elster_as1440|]] hat mir den richtigen Weg gewiesen.\\ +
-Bei genauer Betrachtung steht dort, dass man innerhalb von 1,5s nach der Initialisierung mit\\ +
-<ACK>0ZY<CR><LF> (hex 06 30 zz yy 0D 0A)\\ +
-wobei Z = 00 für 300bd und\\ +
-Y = 00 den Standarddatensatz abrufen kann.\\ +
-Man muss mit hterm nach "/?!" innerhalb von 1,5s \\ +
-<ACK>000<CR><LF> (hex 06 30 30 30 0D 0A)\\ +
-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:\\ +
-/ISK5\2MT372-0002<\r><\n>\\ +
-/?!<\r><\n><6>000<\r><\n>\\ +
-<2>F.97.0(00000000)<\r><\n>\\ +
-0.0.0(58231541)<\r><\n>\\ +
-C.1.1(00000000)<\r><\n>\\ +
-C.1.0(58231541)<\r><\n>\\ +
-0.9.1(175102)<\r><\n>\\ +
-0.9.2(120619)<\r><\n>\\ +
-1.8.0(00132.149*kWh)<\r><\n>\\ +
-1.8.1(00132.149*kWh)<\r><\n>\\ +
-1.8.2(00000.000*kWh)<\r><\n>\\ +
-1.8.3(00000.000*kWh)<\r><\n>\\ +
-1.8.4(00000.000*kWh)<\r><\n>\\ +
-!<\r><\n>\\ +
-<3><9>\\ +
- +
-======Weitere Erkenntnisse ====== +
-Der Zähler scheint nur mit 300bd zu arbeiten. Trotz der Antwort: /ISK5\2MT372-0002<\r><\n>, die nach Norm besagt, dass man den Zähler auf 9600bd umschalten kann.\\ +
- +
-Hier ein Python-Script zum Auslesen des Zählers:\\ +
-Dank an G.Angerer.\\ +
-<code> +
-from __future__ import print_function  +
-import serial +
-import time +
- +
-def send(port, bytes, tr): +
-  """ sends an command to serial and reads and checks the echo +
-      port  - the open serial port +
-      bytes - the string to be send +
-      tr    - the responce time +
-  """ +
-  #print("start send"  +
-  port.write(bytes) +
-  time.sleep(tr) +
-  echo = port.read(len(bytes)) +
-  if (echo != bytes): +
-    print("echo is not same as send:", bytes, " vs ", echo) +
-  #print("end send"+
- +
-def read_datablock(): +
-  ACK = '\x06' +
-  STX = '\x02' +
-  ETX = '\x03' +
-  tr = 0.3 +
-  """ does all that's needed to get meter data from the meter device """  +
-  try: +
-    IskraMT171=serial.Serial(port='/dev/ttyUSB0', baudrate=300, bytesize=7, parity='E', stopbits=1, timeout=1.5); # open port at specified speed +
-    # 1 -> +
-    time.sleep(tr) +
-    Request_message='/?!\r\n' + ACK + '000\r\n' # IEC 62056-21:2002(E) 6.3.1 +
-    send(IskraMT171, Request_message, tr) +
-    # 2 <- +
-    time.sleep(tr) +
-    Identification_message=IskraMT171.readline() # IEC 62056-21:2002(E) 6.3.2 +
-    if (Identification_message[0] != '/'): +
-      print("no Identification message"+
-      IskraMT171.close() +
-      return "" +
-    if (len(Identification_message) < 7): +
-      print("Identification message to short"+
-      IskraMT171.close() +
-      return "" +
-    if (Identification_message[4].islower()): +
-      tr = 0.02 +
-    manufacturers_ID = Identification_message[1:4] +
-    if (Identification_message[5] == '\\'): +
-      identification = Identification_message[7:-2] +
-    else: +
-      identification = Identification_message[5:-2] +
-    speed = Identification_message[4] +
-    #print("speed = ", speed) +
-    if (speed == "1"): new_baud_rate = 600 +
-    elif (speed == "2"): new_baud_rate = 1200 +
-    elif (speed == "3"): new_baud_rate = 2400 +
-    elif (speed == "4"): new_baud_rate = 4800 +
-    #elif (speed == "5"): new_baud_rate = 9600 +
-    elif (speed == "6"): new_baud_rate = 19200 +
-    else: +
-      new_baud_rate = 300 +
-      speed = "0" +
-    #print(manufacturers_ID, " ", identification, " speed=", speed, ) +
-    # 3 -> +
-    Acknowledgement_message=ACK + '0' + speed + '0\r\n' # IEC 62056-21:2002(E) 6.3.3 +
-    send(IskraMT171, Acknowledgement_message, tr) +
-    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("Result not OK, try again"+
-    else: +
-      print("No STX found, not handled."+
-    IskraMT171.close() +
-    return datablock +
-  except: +
-    print("Some error reading data"+
-    if (IskraMT171.isOpen()): +
-      IskraMT171.close() +
-    return "" +
- +
-def meter_data(datablock, map, header): +
-  """ takes a datablock as received from the meter and returns a list with requested meter data as set in map +
-      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] == "time"): +
-      line.append(time.strftime("%Y-%m-%d %H:%M:%S")) +
-    else: +
-      line.append(""+
-  datasets = datablock.split('\n'+
-  for dataset in datasets: +
-    if (dataset != ""): +
-      x = dataset.split('('+
-      address = x[0] +
-      x = x[1][:-2].split(' ') # the standard seems to have a '*' instead of ' ' here +
-      value = x[0] +
-      try: +
-        unit = '['+x[1]+']' +
-      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, line): +
-  f = open(filename, "a"+
-  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 "time" to insert the time +
-  # 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: ['meter ID', 'datum & tijd', 'verbruik totaal[kWh]', 'verbruik tarief1[kWh]', 'verbruik tarief2[kWh]', 'terug totaal[kWh]', 'terug tarief1[kWh]', 'terug tarief2[kWh]'+
-  # data: ['12345678', '2013-02-08 10:08:41', '0054321', '0000000', '0054321', '0000000', '0000000', '0000000'+
-["0.0.0", "meter ID"], +
-  ["time", "datum & tijd"], +
-  ["C.1.0", "EigentumNr9-16"], +
-  ["C.1.1", "EigentumNr1-8"], +
-  ["0.9.1", "Uhr"], +
-  ["0.9.2", "Datum"],   +
-  ["1.8.0", "Verbrauch totaal"], +
-  ["1.8.1", "Verbrauch tarief1"], +
-  ["1.8.2", "Verbrauch tarief2"],   +
-  ["1.8.3", "Verbrauch tarief3"], +
-  ["1.8.4", "Verbrauch tarief4"], +
-  ["F.97.0", "Nix1"], +
-  ["C.241.0", "Nix2"], +
-  ["C.244.0", "Nix3"], +
-  ["C.2.0", "Nix4"] +
-] +
- +
-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)) +
-""" +
- +
-#print(meter_data(example_datablock , map, 1)) +
-#print(meter_data(example_datablock , map, 0)) +
- +
- +
-file = "meterdata.txt" +
-previous_data = "" +
-data = read_datablock() +
- +
-output(file, meter_data(data , map, 1)) # header +
-while (1): +
-  if (data == ""): +
-    print(time.strftime("%Y-%m-%d %H:%M:%S"), "No data received"+
-  elif (previous_data != data): +
-    output(file, meter_data(data , map, 0)) +
-    previous_data = data +
-  time.sleep(3) # minimum waiting time is 3 seconds, less and the meter doesn't return data  +
-  data = read_datablock() +
-</code>+