Hallo,
Ich wollte euch mal zeigen, wie ich meinen Standardstromzähler von Logarex per RS485 auslese. Mein Energieversorger hat mir den Stromzähler von Logarex installiert. Dieser hat eine RS485 Schnittstelle, mit der die Üblichen Daten des zähler ausgelesen werden kann.
Man braucht:
- Raspberry Pi3, mit FHEM, und FHEM Pyhton Modul
- InfluxDB
- Grafana server
Das Python Skript liest den Speicher des Zählers aus, (im 20 Sekundentakt), baut für jede Speicherzelle ein REading uns schickt es an FHEM. Dieses FHEM ist mit einer InfluxDB verbunden und schreibt seinerseits alle DAten in die Datenbank. Ein Grafana dashboard hold diese Daten aus der InfluxDB und stellt diese dann dar.
Ich lese folgende Daten aus:
Speicherblock_Bezeichnung = (
"1-0:96.1.0*255(001LOG0065800***)Hersteller unabhaengige Identifikationsnummer –Produktionsnummer",
"1-0:1.8.0*255(000000.0000*kWh)Kumulatives Register der aktiven Energie in kWh T1+T2",
"1-0:2.8.0*255(000000.0000*kWh)-A Energie",
"1-0:16.7.0*255(000000*W)aktuelle Gesamtleistung",
"1-0:32.7.0*255(000.0*V)Spannung L1, Auflösung 0.1 V",
"1-0:52.7.0*255(000.0*V)Spannung L2, Auflösung 0.1 V",
"1-0:72.7.0*255(228.8*V)Spannung L3, Auflösung 0.1 V",
"1-0:31.7.0*255(000.00*A)Strom L1, Auflösung 0.01 A",
"1-0:51.7.0*255(000.00*A)Strom L2, Auflösung 0.01 A",
"1-0:71.7.0*255(000.00*A)Strom L3, Auflösung 0.01 A",
"1-0:81.7.1*255(000*deg)Phasenwinkel UL2 : UL1",
"1-0:81.7.2*255(000*deg)Phasenwinkel UL3 : UL1",
"1-0:81.7.4*255(000*deg)Phasenwinkel IL1 : UL1",
"1-0:81.7.15*255(000*deg)Phasenwinkel IL2 : UL2",
"1-0:81.7.26*255(000*deg)Phasenwinkel IL3 : UL3",
"1-0:14.7.0*255(50.0*Hz)Netz Frequenz in Hz",
"1-0:1.8.0*96(00000.0*kWh)Historischer Energieverbrauchswert vom letzten Tag (1d)",
"1-0:1.8.0*97(00000.0*kWh)Historischer Energieverbrauchswert der letzten Woche (7d)",
"1-0:1.8.0*98(00000.0*kWh)Historischer Energieverbrauchswert des letzten Monats (30d)",
"1-0:1.8.0*99(00000.0*kWh)Historischer Energieverbrauchswert des letzten Jahres (365d)",
"1-0:1.8.0*100(00000.0*kWh)Historischer Energieverbrauchswert seit letzter Rückstellung",
"1-0:0.2.0*255(ver.03,432F,20170504)Firmware Version, Firmware Prüfsumme CRC , Datum",
"1-0:96.90.2*255(F0F6)Prüfsumme -CRC der eingestellten Parameter",
"1-0:97.97.0*255(00000000)FF -Status Register -Interner Gerätefehler")
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import serial
import serial.rs485
import fhem
# Hier wird der String defniert, der spaeter zum senden an FHEM benutzt wird
op = "setreading" # Befehl, der in FHEM Syntax zu beginn steht
dev = "RS485_Strom_Zaehler" # FHEM - Device, dass mit dem befehl angesprochen werden soll
Speicherblock_Bezeichnung = (
"1-0:96.1.0*255(001LOG0065800***)Hersteller unabhaengige Identifikationsnummer –Produktionsnummer",
"1-0:1.8.0*255(000000.0000*kWh)Kumulatives Register der aktiven Energie in kWh T1+T2",
"1-0:2.8.0*255(000000.0000*kWh)-A Energie",
"1-0:16.7.0*255(000000*W)aktuelle Gesamtleistung",
"1-0:32.7.0*255(000.0*V)Spannung L1, Auflösung 0.1 V",
"1-0:52.7.0*255(000.0*V)Spannung L2, Auflösung 0.1 V",
"1-0:72.7.0*255(228.8*V)Spannung L3, Auflösung 0.1 V",
"1-0:31.7.0*255(000.00*A)Strom L1, Auflösung 0.01 A",
"1-0:51.7.0*255(000.00*A)Strom L2, Auflösung 0.01 A",
"1-0:71.7.0*255(000.00*A)Strom L3, Auflösung 0.01 A",
"1-0:81.7.1*255(000*deg)Phasenwinkel UL2 : UL1",
"1-0:81.7.2*255(000*deg)Phasenwinkel UL3 : UL1",
"1-0:81.7.4*255(000*deg)Phasenwinkel IL1 : UL1",
"1-0:81.7.15*255(000*deg)Phasenwinkel IL2 : UL2",
"1-0:81.7.26*255(000*deg)Phasenwinkel IL3 : UL3",
"1-0:14.7.0*255(50.0*Hz)Netz Frequenz in Hz",
"1-0:1.8.0*96(00000.0*kWh)Historischer Energieverbrauchswert vom letzten Tag (1d)",
"1-0:1.8.0*97(00000.0*kWh)Historischer Energieverbrauchswert der letzten Woche (7d)",
"1-0:1.8.0*98(00000.0*kWh)Historischer Energieverbrauchswert des letzten Monats (30d)",
"1-0:1.8.0*99(00000.0*kWh)Historischer Energieverbrauchswert des letzten Jahres (365d)",
"1-0:1.8.0*100(00000.0*kWh)Historischer Energieverbrauchswert seit letzter Rückstellung",
"1-0:0.2.0*255(ver.03,432F,20170504)Firmware Version, Firmware Prüfsumme CRC , Datum",
"1-0:96.90.2*255(F0F6)Prüfsumme -CRC der eingestellten Parameter",
"1-0:97.97.0*255(00000000)FF -Status Register -Interner Gerätefehler")
Speicherblock_Variablenname = (
"Zaehler-ID",
"Zaehlerstand",
"Energie",
"P_act",
"U_L1",
"U_L2",
"U_L3",
"I_L1",
"I_L2",
"I_L3",
"Phasenwinkel_UL2UL1",
"Phasenwinkel_UL3UL1",
"Phasenverschiebeung_IL1UL1",
"Phasenverschiebeung_IL2UL2",
"Phasenverschiebeung_IL3UL3",
"Netzfrequenz",
"Energie_1d",
"Energie_7d",
"Energie_30d",
"Energie_365d",
"Energie_SeitReset",
"FWVersion_FWCRC_Datum",
"Parameter_CRC",
"int_Fehler"
)
Speicherblock_Wert = [
"Leerer Text",
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
"Leerer Text",
"Leerer Text",
"Leerer Text"
]
Speicherblock_Einheit = ("Zeichenkette",
"kWh",
"kWh",
"W",
"V",
"V",
"V",
"A",
"A",
"A",
"deg",
"deg",
"deg",
"deg",
"deg",
"Hz",
"kWh",
"kWh",
"kWh",
"kWh",
"kWh",
"Zeichenkette",
"Byte",
"Byte",
"Byte",
)
for i in range(0, len(Speicherblock_Bezeichnung) - 1):
print(Speicherblock_Bezeichnung[i], Speicherblock_Variablenname[i], Speicherblock_Wert[i], Speicherblock_Einheit[i])
print("try to Connect to FHEM")
fh = fhem.Fhem("localhost", port=7072, use_ssl=False, password="CndoOS39#")
fh.connect()
print("connected")
print("init RS485")
while 1:
ser = serial.rs485.RS485(
port='/dev/ttyUSB1', # Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
baudrate=9600,
timeout=5
)
ser.rs485_mode = serial.rs485.RS485Settings()
print('check which port was really used')
print(ser.name) # check which port was really used
print(ser)
jetzt = time.localtime()
a = ser.readline()
print("Steht mist im Buffer:\n" + str(a) + "\n")
print("Schicke InitBytes\n")
values = bytearray([47, 63, 33, 13, 10]) # /?!<CR><LF> Carrige Retrun <CR> # Line Feed <LF>
ser.write(values)
print("Warte\n")
time.sleep(0.3)
a = ser.readline()
print("Buffer gelesen\n")
# print("Anzahl Bytes empfangen: %d" % ser.inWaiting())
if len(a) > 0:
print("Folgendes Bytearry wurde empfangen:\n" + str(a) + "\n")
else:
print("Nix drin\n")
ser.close()
time.sleep(1)
print("Schnittstelle neu initialiseren mit 9600bd\n")
ser = serial.rs485.RS485(
port='/dev/ttyUSB1', # Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
baudrate=9600,
timeout=2
)
ser.rs485_mode = serial.rs485.RS485Settings()
values = bytearray([6, 48, 35, 48, 13, 10]) # <ACK>050<CR><LF> Carrige Retrun <CR> # Line Feed <LF>
ser.write(values)
time.sleep(0.4)
x = ser.readlines()
if len(x) > 0:
print("Folgendes Bytearry wurde empfangen:\n" + str(x) + "\n")
print(len(x))
for i in range(0, len(Speicherblock_Bezeichnung)):
# m = maske.match(str(x[i]))
StartIndex = 0
EndIndexStar = 0
EndIndexklammer = 0
# print(m.group(1))
# print(m.group(2))
Speicherblock = str(x[i])
StartIndex = Speicherblock.index("(") # Finden von der öffnenden Klammer
EndIndexStar = Speicherblock.index("*") # Finden von Einheitenmultiplikator
EndIndexklammer = Speicherblock.index(")") # Finden der schließenden Klammer
summ = StartIndex + EndIndexStar + EndIndexklammer
if summ > 0: # Es gibt entweder eine der Klammern oder einen STern
if StartIndex > 0: # Es gibt eine oeffnende Klammer
m = Speicherblock[StartIndex + 1:EndIndexklammer] # Substring zwischen den Klammern
print("Anfang:")
print(m) # String zwischen den klammern
if "*" in m: # Gibt es im Substring einen Stern?
print("Stern ist an position %d" % m.index("*"))
Speicherblock_Wert[i] = float(m[0:m.index("*")])
print("Das wird in den Speicherblock geschrieben: %f" % float(m[0:m.index("*")]))
cmd = '%s %s %s %f' % (op, dev, Speicherblock_Variablenname[i], Speicherblock_Wert[
i]) # Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
print(cmd) # debugging
fh.send_cmd(cmd, 0)
else:
Speicherblock_Wert[i] = m
print("Das wird in den Speicherblock geschrieben:", str(m))
cmd = '%s %s %s %s' % (op, dev, Speicherblock_Variablenname[i], Speicherblock_Wert[
i]) # Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
print(cmd) # debugging
fh.send_cmd(cmd, 0)
# Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
else:
print("Da iss keine klammer" % i)
else:
print("Verdammt!!!\n")
ser.close()
print("Time to sleep")
time.sleep(20)