[vz-users] Iskra MT 171 vzlogger conf

Ralf Löhmer rl at loehmer.de
Tue Mar 11 18:57:08 CET 2014


Am 11.03.2014 07:47, schrieb peble:
> Hallo
> Volkszählergemeinde
>
> ich versuche im Moment mit einem Raspi mit Volkszähler einen Zähler
> Iskra MT 171 auszulesen.
> Meine Hardware :
>
> -Iskra MT 171 mit D0 Protokoll
> -Raspi
> -Udos Lesekopf
> -Udos Zusatzplatine mit Schaltausgängen
> -Lesekopf direkt an der Platine angeschlossen
> -auf dem Raspi das fertige Image von Udo installiert und die vzlogger
> conf geändert!
>
> so wie es aussieht läuft der Lesekopf und vzlogger doch im Frontend
> wird nichts angezeigt
> ich denke der Zähler gibt im Moment nichts brauchbares zurück.
> ich denke bei mir stimmen die Einträge in der vzlogger conf. noch nicht!
>
> hat schonmal jemand so einen Zähler ausgelesen?
> hat evtl jemand eine vzlogger conf. für den Zähler oder einen ähnliche?
>
> Gruß
>
Hallo peble,

hast du schonmal Daten gelesen an diesem Zähler?

http://wiki.volkszaehler.org/hardware/channels/meters/power/edl-ehz/iskraemeco_mt171

Das dort angegebene Python Script ist bei mir nicht gelaufen.
Ich hab es soweit modifiziert, dass es lief, nur interessehalber.
Ich hänge das hier nochmal an. (Schnittstelle anpassen!)

bis dann
rl
-------------- next part --------------
"""
angepasst python3.3.2
"""

from __future__ import print_function 
import serial
import time

iskraID="/ISk5MT171-0222\r\n"

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
  """
  port.write(bytearray(bytes,'ascii'))
  time.sleep(tr)

def read_datablock():
  ACK = '\x06'
  STX = '\x02'
  ETX = '\x03'
  tr = 1
  """ does all that's needed to get meter data from the meter device """
  try:
    IskraMT171=serial.Serial(port='COM4', baudrate=300, bytesize=7, parity='E', stopbits=1, timeout=3); # open port at specified speed
    # 1 ->
    
    time.sleep(tr)
    Request_message='/?!\r\n' # IEC 62056-21:2002(E) 6.3.1
    send(IskraMT171, Request_message, tr)
    # 2 <-
    
    ID_message=IskraMT171.readline()
    ID_message=ID_message.decode()
    if ID_message[0] != '/':
      print("no Identification message")
      IskraMT171.close()
      return ""
    
    if (len(ID_message) < len(iskraID)):
      print("Identification message to short")
      IskraMT171.close()
      return ""
    
    if ID_message[3].islower():
       #tr = 0.02
       tr = 0.2 #critical timing
       
    manufacturers_ID = ID_message[1:4]
    
    if (ID_message[5] == '\\'):
      identification = ID_message[7:-2]
    else:
      identification = ID_message[5:-2]
 
    speed = ID_message[4]
    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
    time.sleep(tr)
    send(IskraMT171, Acknowledgement_message, tr) #300 Bps
    time.sleep(tr) #critical timing
    IskraMT171.baudrate=new_baud_rate #9600Bps
  
      # 4 <-
    datablock =  ""
    inread = IskraMT171.read()
    if ord(inread) == ord(STX):
      x = IskraMT171.read().decode()
      BCC = 0
      while (x  != '!'):
        BCC = BCC ^ ord(x)
        datablock = datablock + x
        x = IskraMT171.read().decode()
     
      while ord(x)  != ord(ETX):
        BCC = BCC ^ ord(x) # ETX itself is part of block check
        x = IskraMT171.read().decode()
      BCC = BCC ^ ord(x)
      x = IskraMT171.read().decode() # 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("%d.%m.%Y %H:%M:%S"))
      #print(line)
    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()
  print(line)

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']
  ["1-0:0.0.0*255", "Meter ID"],
  ["time", "Datum & Zeit"],
  ["1-0:1.8.0*255", "Verbrauch"],
  ["1-0:1.8.1*255", ""],
  ["1-0:1.8.2*255", ""],
  ["1-0:2.8.0*255", "Einspeisung"],
  ["1-0:2.8.1*255", ""],
  ["1-0:2.8.2*255", ""]
]

example_datablock = """0-0:C.1.0*255(12345678)
1-0:0.0.0*255(12345678)
1-0:0.2.0*255(V1.0)
1-0:1.8.0*255(0054321 kWh)
1-0:1.8.1*255(0000000 kWh)
1-0:1.8.2*255(0054321 kWh)
1-0:2.8.0*255(0000000 kWh)
1-0:2.8.1*255(0000000 kWh)
1-0:2.8.2*255(0000000 kWh)
FF(00000000)
"""

#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("%d.%m.%Y %H:%M:%S"), "No data received")
  elif (previous_data != data):
    output(file, meter_data(data , map, 0))
    previous_data = data
  time.sleep(5) # minimum waiting time is 3 seconds, less and the meter doesn't return data 
  data = read_datablock()


More information about the volkszaehler-users mailing list