Auslesen eines Smart Grid Hubs (Webserver)

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
thomas.sc
User
Beiträge: 4
Registriert: Sonntag 22. Februar 2015, 13:05

Hallo BlackJack,
hallo Lutz,

vielen Dank für die Unterstützung und die Hinweise/Hilfe.

@Lutz das ist echt genial, ich habe den Code mal angepasst, damit kann ich jetzt weitermachen:

Code: Alles auswählen

import urllib2
import json
 
url = 'http://192.168.178.31/json.txt?LogName=name&LogPSWD=1234'
req = urllib2.Request(url)
response = urllib2.urlopen(req)
json_text = response.read()
response.close()
j_text = json_text.decode('utf8')
data = json.loads(j_text)
T0 = data['billingData:']['values'][0]['value']
T1 = data['billingData:']['values'][1]['value']
Gesamtleistung = data['billingData:']['values'][2]['value']
LeistungL1 = data['billingData:']['values'][3]['value']
LeistungL2 = data['billingData:']['values'][4]['value']
LeistungL3 = data['billingData:']['values'][5]['value']
SpannungL1 = data['billingData:']['values'][6]['value']
SpannungL2 = data['billingData:']['values'][7]['value']
SpannungL3 = data['billingData:']['values'][8]['value']
Frequenz = data['billingData:']['values'][9]['value']
FrequenzUnit = data['billingData:']['values'][9]['unit']

Kundennummer = data['billingData:']['assignment'][4]['value']
Zeitangabe = data['billingData:']['assignment'][5]['value']
print("Arbeit:")
print(T0)
print(T1)
print("Leistung:")
print(Gesamtleistung)
print(LeistungL1)
print(LeistungL2)
print(LeistungL3)
print("Spannung:")
print(SpannungL1)
print(SpannungL2)
print(SpannungL3)
print("Frequenz:")
print(Frequenz)
print(FrequenzUnit)
print(Kundennummer)
print(Zeitangabe)
Viele Grüße

Thomas
BlackJack

@thomas.sc: Also für meinen Geschmack werden dort viel zu oft gleiche Teilausdrücke ausgewertet und zu viele magische Indexwerte verwendet.
thomas.sc
User
Beiträge: 4
Registriert: Sonntag 22. Februar 2015, 13:05

Hallo BlackJack,

die Daten werden vom dem SmartGrid Hub, der an den Stromzähler ansgeschlossen ist im json-Format bereitgestellt. Um diese Daten "auswerten" zu können müssen Sie zyklisch abgerufen werden, dann in eine Datenbank geschrieben um daraus dann eine Verbrauchsgrafik (Lastprofil) zu erstellen. Welche Werte nun genau weiterverarbeitet werden, will ich mal sehen. Grundsätzlich ist der Erste Schritt, das abrufen und aufbereiten der Daten, erfolgreich abgeschlossen.

Viele Grüße

Thomas
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das meinte BlackJack nicht. Das Problem an deinem Code ist, dass da sehr viel identischer Kram drin steht, dass solltest du irgendwie zusammenfassen. Sei es nun durch einen Zwischenschritt oder durch eine Funktion. Die magischen Indexwerte beziehen sich auf die Indizes, welche da so frei in deinem Code schwirren. Da weißt du in wenigen Tagen selbst nicht mehr so genau, was die denn nun Bedeuten. Statt der "3" im Index bei "LeistungL1" solltest du dir also einen vernünftigen Namen für die drei einfallen lassen und dann daraus eine Konstante machen. Dann verrät dir der Name der Konstante auch noch in einem Jahr, was du da eigentlich gemeint hast.
Das Leben ist wie ein Tennisball.
BlackJack

Ergänzend zu EyDu: Ich habe den hoffentlich berechtigten Verdacht das man da gar keine festen Indexerte verwenden muss sondern das in den Wörterbüchern zu den einzelnen Werten nicht nur der 'value' steht, sondern auch was der bedeutet. Die Einheit für den jeweiligen Wert scheint da ja auch gespeichert zu sein. Sich am ”magischen” Index zu orientieren erscheint mehr wenig robust zu sein.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack: leider nein ganz so einfach. Eine kurze Googlesuche hat ergeben, dass neben "value" und "unit" auch eine kryptische "obis" mit ausgegeben wird, die wohl soetwas wie eine Zählernummer ist. Der korrekte Weg wäre es wohl, alles über diese OBIS zu referenzieren.
HeiLuRa
User
Beiträge: 8
Registriert: Montag 9. Februar 2015, 18:14

@Sirius3
"obis" ist keine Zählernummer, sie ist eine Referenz auf den entsprechenden Wert. Leider kann man aus der obis-Zahl nicht den Klartext erkennen. Man muss schon die Bedeutungen aus der Bedienungsanleitung (http://datenblatt.stark-elektronik.de/e ... SGH_DE.pdf) kennen bzw. referenzieren.
Hersteller ist Fa. efr. (http://www.efr.de/produkte/efr-smart-grid-hub/)

@thomas.sc
Hast Du schon Erfahrungen mit dem zyklischen Auslesen? Ich lese die Hubs alle 15sec. aus und bekommen sporadisch Fehler. (s.o.)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@HeiLuRa, @thomas.sc: wenn das also nur eine kompliziert kodierte Beschreibung ist, dann ist ja eine Übersetzung in Klartext mit einer einfachen Tabelle möglich. Dann braucht man auch keine magischen Nummern mehr.

Code: Alles auswählen

import urllib2
import json

OBIS_TO_TEXT = {
    "8181C78227FF": "Kundennummer",        
    "8181C78205FF": "Vorname",
    "8181C78206FF": "Nachname",
    "8181C78207FF": "Adresse",
    "0100000000FF": "Zählernummer",        
    "010000090B00": "Zeitstempel",     
    "0101010800FF": "Summenregister 1.8.0",    
    "0101010801FF": "Register 1.8.1",
    "0101010802FF": "Register 1.8.2",
    "0101010803FF": "Register 1.8.3",
    "0102020800FF": "Register 2.8.0",
    "0102020807FF": "Register 2.8.7",
    "0100010700FF": "Gesamtleistung",
    "0100150700FF": "Leistung Phase 1",
    "0100290700FF": "Leistung Phase 2",
    "01003D0700FF": "Leistung Phase 3",
    "10020070000": "Spannung Phase 1",
    "10034070000": "Spannung Phase 2",
    "10048070000": "Spannung Phase 3",
    "01000E070000": "Netzfrequenz",
    "10001080080": "Verbrauch heute",
    "10001080081": "Verbrauch gestern",
    "10001080082": "Verbrauch letzte Woche",
    "10001080083": "Verbrauch letzten Monat",
    "10001080084": "Verbrauch letztes Jahr",
    "10002080080": "Einspeisung heute",
    "10002080081": "Einspeisung gestern",
    "10002080082": "Einspeisung letzte Woche",
    "10002080083": "Einspeisung letzten Monat",
    "10002080084": "Einspeisung letztes Jahr",
}

 
url = 'http://192.168.178.31/json.txt?LogName=name&LogPSWD=1234'
req = urllib2.Request(url)
response = urllib2.urlopen(req)
json_text = response.read().decode('utf8')
response.close()
data = json.loads(json_text)

assignment = {
    OBIS_TO_TEXT[value['obis']]: value['value']
    for value in data['billingData:']['assignment']
}
billingData = {
    OBIS_TO_TEXT[value['obis']]: (value['value'], value['unit'])
    for value in data['billingData:']['values']
}

for key, value in billingData.items():
    print(key, value)
Antworten