hardware:channels:meters:power:edl-ehz:iskraemeco_mt171
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| hardware:channels:meters:power:edl-ehz:iskraemeco_mt171 [2014/12/29 19:56] – jaco | hardware:channels:meters:power:edl-ehz:iskraemeco_mt171 [2022/04/21 21:50] (aktuell) – daemon, logfile & port jau | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== | + | ====== |
| - | Der [[http://www.iskraemeco.si/ | + | {{ :hardware: |
| + | Der Iskraemeco | ||
| ===== Hardware ===== | ===== Hardware ===== | ||
| - | ====D0 - EN 62056-21==== | + | ==== D0 - EN 62056-21 ==== |
| - | Man benötigt den [[hardware: | + | Kann mit einem [[hardware: |
| + | Unter der markierten(=> | ||
| - | {{ : | + | ==== S0 ==== |
| - | Hier ist die typische IR-Schnittstelle | + | === extern === |
| - | Unter der markierten(=>) Öffnung befindet sich der Empfänger.\\ | + | Die S0-Schnittstelle (blinkende rote LED auf der Frontseite) wurde bisher nicht getestet.\\ |
| - | Darüber muß also die IR-LED des Opto-Kopfes positioniert werden.\\ | + | Bei Zweirichtungszähler wahrscheinlich nicht sinnvoll einsetzbar. |
| - | \\ | + | === intern === |
| + | Ss soll zwei interne S0 Schnittstellen geben. Bisher ist nicht bekannt, ob hier dann zwischen Einspeisung und Bezug unterschieden wird.\\ | ||
| + | Diese Schnittstellen liegen hinter der Verplombung und sind nicht zugänglich. | ||
| - | ====S0==== | + | ===== Kommunikation |
| - | ===extern zugänglich=== | + | Die Schnittstelle |
| - | Die S0-Schnittstelle | + | < |
| - | Da hier vermutlich automatisch eine Summenbildung zwischen bezogener Energie und eingespeister Energie stattfindet, finde ich das erstmal weniger interessant. | + | /?!\r\n (hex 2F 3F 21 0D 0A) |
| - | ===intern=== | + | </ |
| - | es soll zwei interne S0 Schnittstellen geben. Bisher ist mir nicht bekannt, ob hier dann zwischen Einspeisung und Bezug unterschieden wird.\\ | + | Der Zähler antwortet |
| - | Diese Schnittstellen liegen hinter der Verplombung und sind mir nicht zugänglich. | + | |
| - | ===== Software ===== | + | |
| - | Das Auslesen der Daten über die IR-Schnittstelle wird wie [[Elster_as1440|hier]] beschrieben eingeleitet.\\ | + | |
| - | Der Zähler antwortet mit | + | |
| < | < | ||
| / | / | ||
| </ | </ | ||
| - | Der am Ende zurückgelieferte | + | Um direkt weiter kommunizieren zu können, muss die Antwort des Zählers bestätigt werden mit: |
| + | < | ||
| + | < | ||
| + | </ | ||
| + | Als Datensatz | ||
| < | < | ||
| 0-0: | 0-0: | ||
| Zeile 34: | Zeile 38: | ||
| ! | ! | ||
| </ | </ | ||
| - | 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 is the meter data has changed. It uses py-serial. | + | Die Baudrate läßt sich auch auf 9600 Baud umstellen wenn man innerhalb von 2s nachdem der Zähler seine Identifikation geschickt hat, ein Acknowledge Paket (ACK050CRLF) schickt. |
| - | < | + | < |
| - | import serial | + | Worauf der Zähler beginnt seine [[hardware: |
| - | import time | + | |
| - | def send(port, bytes, tr): | + | ===== Beispiel vzlogger.conf ===== |
| - | """ | + | Im Frontend wird ein Kanal ' |
| - | 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(" | + | |
| - | # | + | |
| - | def read_datablock(): | + | <code base vzlogger.conf> |
| - | ACK = ' | + | { |
| - | | + | |
| - | ETX = ' | + | "verbosity": 15, |
| - | tr = 0.2 | + | |
| - | """ | + | "local": |
| - | try: | + | "enabled": |
| - | IskraMT171=serial.Serial(port=' | + | "port": |
| - | # 1 -> | + | "index": |
| - | time.sleep(tr) | + | "timeout": 0, |
| - | Request_message=' | + | "buffer": 0 |
| - | send(IskraMT171, | + | |
| - | # 2 <- | + | "meters": [ |
| - | time.sleep(tr) | + | |
| - | Identification_message=IskraMT171.readline() # IEC 62056-21: | + | "enabled": |
| - | if (len(Identification_message) < 1 or Identification_message[0] != '/'): | + | "allowskip": |
| - | print(" | + | "interval": |
| - | IskraMT171.close() | + | "aggtime": |
| - | return "" | + | "aggfixedinterval": |
| - | if (len(Identification_message) < 7): | + | "channels": [ |
| - | print(" | + | |
| - | IskraMT171.close() | + | "uuid": |
| - | return "" | + | "identifier": "1.8.0", |
| - | if (Identification_message[4].islower()): | + | |
| - | tr = 0.02 | + | "middleware": "http:// |
| - | manufacturers_ID = Identification_message[1: | + | " |
| - | if (Identification_message[5] == ' | + | |
| - | identification = Identification_message[7: | + | } |
| - | else: | + | |
| - | identification = Identification_message[5: | + | " |
| - | speed = Identification_message[4] | + | " |
| - | # | + | " |
| - | if (speed == "1"): new_baud_rate = 600 | + | " |
| - | | + | |
| - | | + | " |
| - | | + | "parity": "7e1", |
| - | | + | "wait_sync": "off", |
| - | elif (speed == " | + | "read_timeout": |
| - | else: | + | "baudrate_change_delay": 0 |
| - | new_baud_rate = 300 | + | |
| - | speed = "0" | + | |
| - | # | + | } |
| - | | + | |
| - | 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(" | + | |
| - | | + | |
| - | | + | |
| - | IskraMT171.close() | + | |
| - | return datablock | + | |
| - | except: | + | |
| - | | + | |
| - | if (IskraMT171.isOpen()): | + | |
| - | IskraMT171.close() | + | |
| - | return "" | + | |
| - | + | ||
| - | def meter_data(datablock, map, header): | + | |
| - | """ | + | |
| - | | + | |
| - | line = [] | + | |
| - | ## initialise line | + | |
| - | for l in range(len(map)): | + | |
| - | if (header == 1): | + | |
| - | | + | |
| - | elif (map[l][0] == "time"): | + | |
| - | | + | |
| - | else: | + | |
| - | | + | |
| - | datasets = datablock.split(' | + | |
| - | for dataset in datasets: | + | |
| - | if (dataset != "" | + | |
| - | x = dataset.split(' | + | |
| - | address = x[0] | + | |
| - | x = x[1][: | + | |
| - | value = x[0] | + | |
| - | try: | + | |
| - | | + | |
| - | | + | |
| - | 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) | + | |
| - | | + | |
| - | + | ||
| - | 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" | + | |
| - | # 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: [' | + | |
| - | ["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" | + | |
| - | ] | + | |
| - | + | ||
| - | example_datablock = "" | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | 1-0: | + | |
| - | FF(00000000) | + | |
| - | "" | + | |
| - | + | ||
| - | # | + | |
| - | # | + | |
| - | + | ||
| - | file = "meterdata.txt" | + | |
| - | previous_data = "" | + | |
| - | data = read_datablock() | + | |
| - | + | ||
| - | output(file, meter_data(data , map, 1)) # header | + | |
| - | while (1): | + | |
| - | if (data == "" | + | |
| - | | + | |
| - | elif (previous_data != data): | + | |
| - | output(file, | + | |
| - | | + | |
| - | | + | |
| - | data = read_datablock() | + | |
| </ | </ | ||
| - | Example output is: | ||
| - | |||
| - | < | ||
| - | [' | ||
| - | [' | ||
| - | [' | ||
| - | [' | ||
| - | [' | ||
| - | [' | ||
| - | [' | ||
| - | </ | ||
| - | Only change < | ||
| ===== Quellen ===== | ===== Quellen ===== | ||
| [1] [[http:// | [1] [[http:// | ||
| - | [2] [[hardware: | ||
hardware/channels/meters/power/edl-ehz/iskraemeco_mt171.1419879374.txt.gz · Zuletzt geändert: von jaco