Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
IskraEmeco MT171
Der IskraEmeco MT171 kann auch nach EN 62056-21 über die IR-Schnittstelle ausgelesen werden.
Hardware
D0 - EN 62056-21
Man benötigt den IR-Schreib-Lese-Kopf, da der Zähler erst angesprochen werden muss, bevor er sendet.
Hier ist die typische IR-Schnittstelle zu sehen.
Unter der markierten(⇒) Öffnung befindet sich der Empfänger.
Darüber muß also die IR-LED des Opto-Kopfes positioniert werden.
S0
extern zugänglich
Die S0-Schnittstelle (blinkende rote LED auf der Frontseite) wurde bisher nicht getestet.
Da hier vermutlich automatisch eine Summenbildung zwischen bezogener Energie und eingespeister Energie stattfindet, finde ich das erstmal weniger interessant.
intern
es soll zwei interne S0 Schnittstellen geben. Bisher ist mir nicht bekannt, ob hier dann zwischen Einspeisung und Bezug unterschieden wird.
Diese Schnittstellen liegen hinter der Verplombung und sind mir nicht zugänglich.
Software
Das Auslesen der Daten über die IR-Schnittstelle wird wie hier beschrieben eingeleitet.
Der Zähler antwortet mit
/ISk5MT171-0222
Der am Ende zurückgelieferte Datensatz
0-0:C.1.0*255(4744xxxx) 1-0:0.0.0*255(458xxxx) 1-0:0.2.0*255(V1.0) 1-0:1.8.0*255(007206.0 kWh) 1-0:2.8.0*255(005313.4 kWh) 0-0:F.F.0*255(00000000) !
Leider keine Momentanwerte oder zusätzliche Infos.
Ob und wie man an zusätzliche Messwerte gelangt, ist mir bisher nicht bekannt.
See here python code that reads the meter data about every 5 seconds and writes a line to file if the meter data has changed. It uses py-serial.
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.2 """ 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' # 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 (len(Identification_message) < 1 or 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'] ["1-0:0.0.0*255", "meter ID"], ["time", "datum & tijd"], ["1-0:1.8.0*255", "verbruik totaal"], ["1-0:1.8.1*255", "verbruik tarief1"], ["1-0:1.8.2*255", "verbruik tarief2"], ["1-0:2.8.0*255", "terug totaal"], ["1-0:2.8.1*255", "terug tarief1"], ["1-0:2.8.2*255", "terug tarief2"] ] 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("%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()
Example output is:
['meter ID', 'datum & tijd', 'verbruik totaal[kWh]', 'verbruik tarief1[kWh]', 'verbruik tarief2[kWh]', 'terug totaal[kWh]', 'terug tarief1[kWh]', 'terug tarief2[kWh]'] ['12345678', '2013-02-09 12:49:14', '0011540', '0000000', '0011540', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 13:00:45', '0011541', '0000000', '0011541', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 13:18:06', '0011542', '0000000', '0011542', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 13:40:14', '0011543', '0000000', '0011543', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 13:57:53', '0011544', '0000000', '0011544', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 14:15:16', '0011545', '0000000', '0011545', '0000000', '0000000', '0000000'] ['12345678', '2013-02-09 14:53:29', '0011546', '0000000', '0011546', '0000000', '0000000', '0000000']
Only change
map
in order to change header names, to add or remove what data is saved or to change the order.
Quellen
[1] MT171
[2] Elster AS1440