Busmaster mit 2x S0-Interface

Begonnen von Bastel-Frank, 30 Oktober 2014, 13:28:26

Vorheriges Thema - Nächstes Thema

Niel

Hallo!

Ich hänge hier mal meine angepassten Dateien an, da doch nach der Möglichkeit gefragt wird, wie man die S0-Zähler resetten kann.

Grüße

Niel

Prof. Dr. Peter Henning

Per PN  bin ich nach Quellen für vollwertige USB 1Wire Adapter gefragt worden.

Schaut bei EBay, den billigsten habe ich für 8 € gefunden:
http://m.ebay.com/itm/231260963718?_mwBanner=1

Und für weniger als 25 € incl. Versand: http://m.ebay.de/itm/1Wire-interface-USB-zu-1-Wire-Dallas-DS2480-1Wire-einfach-seriell-abfragen-/131571350410?nav=SEARCH

Etwas darüber
http://m.ebay.de/itm/171041719472?_mwBanner=1
http://www.fuchs-shop.com/de/shop/17/1/13372111/

Also noch mal der Tipp: SMSGuard Sonderlösung vergessen, Standardprodukte verwenden.

LG

pah

Joshibaer

Nach stundenlanger Fehlersuche musste ich feststellen das bei mir der USB Stick auf ttyUSB1 liegt.
Ich habe ein neuen Raspi mir 1GB Hauptspeicher.

Jetzt die Frage wie habt ihr es Programmtechnisch realiesiert , den KW Verbrauch zu berechnen.




fiedel

FeatureLevel: 6.1 auf Wyse N03D ; Deb. 11 ; Perl: v5.14.2 ; IO: HM-MOD-RPI-PCB + VCCU|CUL 868 V 1.66|LinkUSBi |TEK603
HM: SEC-SCO|SCI-3-FM|LC-SW4-PCB|ES-PMSW1-PL|RC-4-2|SEN-MDIR-O|SEC-WDS-2
CUL: HMS100TF|FS20 S4A-2 ; OWDevice: DS18S20|DS2401|DS2406|DS2423

Joshibaer

Ok danke , jetzt bin ich weiter gekommen wie im Log 1 zu sehen werden die Internen Zählimpule angezeigt

define FileLog_s0zaehler FileLog ./log/s0zaehler-%Y.log s0zaehler:.*


2015-08-29_18:30:36 s0zaehler A: 0
2015-08-29_18:30:36 s0zaehler B: 17586
2015-08-29_18:30:36 s0zaehler A:0 - B: 17586
2015-08-29_18:30:46 s0zaehler A: 0
2015-08-29_18:30:46 s0zaehler B: 17587
2015-08-29_18:30:46 s0zaehler A:0 - B: 17587



Nachdem ich es etwas modifiziert habe bekomme ich im Log 2 es so angezeigt.
Die Dopplung muss ich aber irgendwann noch enfernen.

define s0zaehlerab dummy


define notify_s0zaehler notify s0zaehler { \
      my $a = ReadingsVal("s0zaehler","A",0)/1 ;; \
      my $b = ReadingsVal("s0zaehler","B",0)/1 ;; \
      my $text = "Z1: $a , Z2: $b " ;; \
      fhem ("set s0zaehlerab $text") ;; \
           }

define FileLog_s0zaehler_ab FileLog ./log/FileLog_s0zaehler_ab-%Y-%m.log s0zaehlerab




2015-08-29_18:58:44 s0zaehlerab Z1: 0 , Z2: 17688
2015-08-29_18:58:44 s0zaehlerab Z1: 0 , Z2: 17688
2015-08-29_18:58:54 s0zaehlerab Z1: 0 , Z2: 17689
2015-08-29_18:58:54 s0zaehlerab Z1: 0 , Z2: 17689
2015-08-29_18:59:04 s0zaehlerab Z1: 0 , Z2: 17690
2015-08-29_18:59:04 s0zaehlerab Z1: 0 , Z2: 17690
2015-08-29_18:59:14 s0zaehlerab Z1: 0 , Z2: 17690
2015-08-29_18:59:14 s0zaehlerab Z1: 0 , Z2: 17690
2015-08-29_18:59:24 s0zaehlerab Z1: 0 , Z2: 17691
2015-08-29_18:59:24 s0zaehlerab Z1: 0 , Z2: 17691



und zum Schluss  noch der Aktuellen Zählerstand




attr s0zaehler stateFormat { sprintf("%.3f kWh %.3f kWh", ReadingsVal("s0zaehler","displayA","kWh"), ReadingsVal("s0zaehler","displayB","kWh"));; }
attr s0zaehler userReadings displayA {ReadingsVal("s0zaehler","A",0)/1000.0+AttrVal("s0zaehler","offsetA",0);;}, consumption_power differential {ReadingsVal("s0zaehler","A",0)*3600*0.001;;}, daily_power {ReadingsVal("s0zaehler","displayA",0)-Value("Dum_DP_Diff_D");;}, displayB {ReadingsVal("s0zaehler","B",0)/800.0+AttrVal("s0zaehler","offsetB",0);;}, consumption_power2 differential {ReadingsVal("s0zaehler","B",0)*3600*0.00125;;}, daily_power2 {ReadingsVal("s0zaehler","displayB",0)-Value("Dum_DG_Diff_D");;}




OW2S0SMSGUARD

s0zaehler 0.000 kWh 22.802 kWh




Alles Top .
In der Anleitung ist erklärt , wie ich den Tages und Monatswert berechne.
Ich möchte aber den Momentanverbrauch angezeigt bekommen.

Wie kann ich dieses Problem Lösen ?



Hier der ganze Code




define s0zaehler OW2S0SMSGUARD /dev/ttyUSB1
#z1 =1000/KWh
#z2 =800 /KWh
attr s0zaehler offsetA 00000.00
attr s0zaehler offsetB 00000.00
attr s0zaehler room Energie
attr s0zaehler stateFormat { sprintf("%.3f kWh %.3f kWh", ReadingsVal("s0zaehler","displayA","kWh"), ReadingsVal("s0zaehler","displayB","kWh"));; }
attr s0zaehler userReadings displayA {ReadingsVal("s0zaehler","A",0)/1000.0+AttrVal("s0zaehler","offsetA",0);;}, consumption_power differential {ReadingsVal("s0zaehler","A",0)*3600*0.001;;}, daily_power {ReadingsVal("s0zaehler","displayA",0)-Value("Dum_DP_Diff_D");;}, displayB {ReadingsVal("s0zaehler","B",0)/800.0+AttrVal("s0zaehler","offsetB",0);;}, consumption_power2 differential {ReadingsVal("s0zaehler","B",0)*3600*0.00125;;}, daily_power2 {ReadingsVal("s0zaehler","displayB",0)-Value("Dum_DG_Diff_D");;}


define FileLog_s0zaehler FileLog ./log/s0zaehler-%Y.log s0zaehler:.*
attr FileLog_s0zaehler logtype text


define s0zaehlerab dummy


define notify_s0zaehler notify s0zaehler { \
      my $a = ReadingsVal("s0zaehler","A",0)/1 ;; \
      my $b = ReadingsVal("s0zaehler","B",0)/1 ;; \
      my $text = "Z1: $a , Z2: $b " ;; \
      fhem ("set s0zaehlerab $text") ;; \
           }

define FileLog_s0zaehler_ab FileLog ./log/FileLog_s0zaehler_ab-%Y-%m.log s0zaehlerab



fiedel

Guck mal weiter unten bei "Plotfile Strom (stromverbrauch.gplot):" Darin siehst du, was du für den Momentanverbrauch loggen und plotten musst.
FeatureLevel: 6.1 auf Wyse N03D ; Deb. 11 ; Perl: v5.14.2 ; IO: HM-MOD-RPI-PCB + VCCU|CUL 868 V 1.66|LinkUSBi |TEK603
HM: SEC-SCO|SCI-3-FM|LC-SW4-PCB|ES-PMSW1-PL|RC-4-2|SEN-MDIR-O|SEC-WDS-2
CUL: HMS100TF|FS20 S4A-2 ; OWDevice: DS18S20|DS2401|DS2406|DS2423

Joshibaer

Ui da war ich wohl blind gewesen.

Mit


define s0zaehlerb_momentanverbrauch readingsProxy s0zaehler:consumption_power2


Habe ich den Wert  der benötigt wird.

das ganze gerundet auf 3 Stellen nach dem Komma sieht so aus


define s0zaehlerb_momentanverbrauch readingsProxy s0zaehler
attr s0zaehlerb_momentanverbrauch room Energie
attr s0zaehlerb_momentanverbrauch stateFormat {sprintf("%.3f KW ",ReadingsVal("s0zaehler","consumption_power2",0)) }



Damit der Wert nicht zusehr schwankt frage ich ihn nur alle 30 sec ab.


define s0zaehler OW2S0SMSGUARD /dev/ttyUSB1 30



Auch das Doppellogproblem ist gelösst indem das notify geändert wurde.


define notify_s0zaehler notify s0zaehler:.*-.* { \

Joshibaer

So ich habe noch ein kleines Update .

Da ich jetzt ja problemlos alle meine Zähler in Fehm einlesen kann , geht es an die Feinkorrektur.

Zur Kontolle möchte ich mir die Zählerstände in FHEM anzeigen lassen.

Da ich über den S0 Bus nur Zählimpulse verarbeite muss ich einen Korrekturwert errechnen.

Sehr Hilfreich war nätürlich wie immer der  Wikieintrag

Also als erste brauchen wir eine Feld um den Zählerstand ein zu tragen.

Das machen wir ganz einfach über ein Dummy:


define s0zaehler_offsetA dummy
attr s0zaehler_offsetA room Zaehler
attr s0zaehler_offsetA setList state:textField
attr s0zaehler_offsetA webCmd state




So jetzt soll ja nach der Eingabe des Aktuellen Zählerstandes der Korrekturwert berechnet werden.
Sobald man nach der Eingabe mit der Mouse ausserhalb des Eingabe Feldes drückt (Kein Enter zur Bestätigung) wird ein Notify ausgelößt :



define Func_SetOffsetA notify s0zaehler_offsetA  { \



Jetzt ein bisschen Programmcode:

Die Variable "aufrufer_SetOffset" vorbereiten:

  my $aufrufer_SetOffset = "@" ;;\

Auslesen und speichern der Zählimpulse und umrechnen in KWs (1000 Imp pro KW):

  my $valueA = (ReadingsVal("s0zaehler","A",0)/1000 );;\

Jetzten den Eingabewert einlesen und die schon gezählten KWs abziehen:

  my $setoffsetA = (ReadingsVal("s0zaehler_offsetA","state",0) - $valueA);;\

Dann das Ergebnis speichern:

{ \
     Log 1, "Setze Zaehler A auf: $setoffsetA";; \
     fhem("attr s0zaehler_offsetA $setoffsetA");;\
     fhem("set s0zaehler_offsetA $setoffsetA");;\
} \
                                             { \
     fhem("save");;\
}\
}



Jetzt steht der Korrekturwert im Eingabefeld.

So wir brauchen ein Dummy um den realen Zählerstand zu speichen und begrenzen ihn auf zwei Nachkomastellen:


define s0zaehler_ZaehlerA dummy
attr s0zaehler_ZaehlerA stateFormat {sprintf("%.2f KW ",ReadingsVal("s0zaehler_ZaehlerA","state",0) ) }


Gut jetzt zur Berechnung.Ich benutze dazu das Notify das ich auch zum loggen verwendet habe, also sobald beide Zählerstande sich geändert haben :


define notify_s0zaehler notify s0zaehler:.*-.* { \


Einlesen und speichern des Korrekturwertes :


      my $ao= ReadingsVal("s0zaehler_offsetA","state",0) ;; \


Einlesen uns speichern der Zählimpulse mit der Umrechnung in KW:

      my $a = ReadingsVal("s0zaehler","A",0)/1000 + $ao ;; \

Speichern des berechneten Zählerwertes im Dummy :

      fhem ("set s0zaehler_ZaehlerA $a") ;; \
     
Klappt alles wunderbar.

Sollte es eine einfachere Lösung geben ,wäre ich für eine Anmerkung dankbar.

Hier der ganze Code:

#*********************Stromzähler  S0*************************

define s0zaehler OW2S0SMSGUARD /dev/ttyUSB1 30
attr s0zaehler room Zaehler
attr s0zaehler stateFormat { sprintf("%.3f kWh %.3f kWh", ReadingsVal("s0zaehler","displayA","kWh"), ReadingsVal("s0zaehler","displayB","kWh"));; }
attr s0zaehler userReadings displayA {ReadingsVal("s0zaehler","A",0)/1000.0+AttrVal("s0zaehler","offsetA",0);;}, consumption_power1 differential {ReadingsVal("s0zaehler","A",0)*3600*0.001;;}, daily_power {ReadingsVal("s0zaehler","displayA",0)-Value("Dum_DP_Diff_D");;}, displayB {ReadingsVal("s0zaehler","B",0)/800.0+AttrVal("s0zaehler","offsetB",0);;}, consumption_power2 differential {ReadingsVal("s0zaehler","B",0)*3600*0.00125;;}, daily_power2 {ReadingsVal("s0zaehler","displayB",0)-Value("Dum_DG_Diff_D");;}
#z1 =1000/KWh
#z2 =800 /KWh




define s0zaehlera_momentanverbrauch readingsProxy s0zaehler
attr s0zaehlera_momentanverbrauch alias Stromverbrauch Einz.
attr s0zaehlera_momentanverbrauch room Energie
attr s0zaehlera_momentanverbrauch stateFormat {sprintf("%.0f W ",ReadingsVal("s0zaehler","consumption_power1",0)*1000) }


define s0zaehlerb_momentanverbrauch readingsProxy s0zaehler
attr s0zaehlerb_momentanverbrauch alias Stromverbrauch Ges.
attr s0zaehlerb_momentanverbrauch room Energie
attr s0zaehlerb_momentanverbrauch stateFormat {sprintf("%.0f W ",ReadingsVal("s0zaehler","consumption_power2",0)*1000) }


define FileLog_s0zaehler_a FileLog ./log/FileLog_s0zaehler_a-%Y-%m.log s0zaehlera_momentanverbrauch:stateFormat


#define s0zaehlerab dummy
define s0zaehler_ZaehlerA dummy
attr s0zaehler_ZaehlerA alias Schlafzimmer
attr s0zaehler_ZaehlerA room Energie,Zaehler
attr s0zaehler_ZaehlerA stateFormat {sprintf("%.2f KW ",ReadingsVal("s0zaehler_ZaehlerA","state",0) ) }

define s0zaehler_ZaehlerB dummy
attr s0zaehler_ZaehlerB alias Ges.Verbrauch
attr s0zaehler_ZaehlerB room Energie,Zaehler
attr s0zaehler_ZaehlerB stateFormat {sprintf("%.2f KW ",ReadingsVal("s0zaehler_ZaehlerB","state",0) ) }

define notify_s0zaehler notify s0zaehler:.*-.* { \
      my $ao= ReadingsVal("s0zaehler_offsetA","state",0) ;; \
      my $a = ReadingsVal("s0zaehler","A",0)/1000 + $ao ;; \
      my $bo= ReadingsVal("s0zaehler_offsetB","state",0)  ;; \
      my $b = ReadingsVal("s0zaehler","B",0)/800 + $bo ;; \
      my $text = "ZA:$a KWh, ZB:&b KWh" ;; \
      fhem ("set s0zaehler_ZaehlerA $a") ;; \
      fhem ("set s0zaehler_ZaehlerB $b") ;; \
      fhem ("set s0zaehler $text") ;; \
      \
     }

define FileLog_s0zaehler_ab FileLog ./log/FileLog_s0zaehler_ab-%Y-%m.log s0zaehlerab

#****************Zählerstämde******************
# Dummys zum Eingeben der realen Zählerstände:
define s0zaehler_offsetA dummy
attr s0zaehler_offsetA alias Berechn. Offset A
attr s0zaehler_offsetA comment Eingabefeld für Zählerstand Strom zur Berechnung von "offsetA"
attr s0zaehler_offsetA room Zaehler
attr s0zaehler_offsetA setList state:textField
attr s0zaehler_offsetA webCmd state

# Funktion zum Berechnen und Setzen der Offset- Werte:
define Func_SetOffsetA notify s0zaehler_offsetA  { \
\
  my $aufrufer_SetOffset = "@" ;;\
  my $valueA = (ReadingsVal("s0zaehler","A",0)/1000 );;\
  my $setoffsetA = (ReadingsVal("s0zaehler_offsetA","state",0) - $valueA);;\
{ \
     Log 1, "Setze Zaehler A auf: $setoffsetA";; \
     fhem("attr s0zaehler_offsetA $setoffsetA");;\
     fhem("set s0zaehler_offsetA $setoffsetA");;\
} \
                                             { \
     fhem("save");;\
}\
}
attr Func_SetOffsetA group Berechnungen
#attr Func_SetOffsetA room Energie


define s0zaehler_offsetB dummy
attr s0zaehler_offsetB alias Berechn. Offset B
attr s0zaehler_offsetB comment Eingabefeld für Zählerstand Strom zur Berechnung von "offsetB"
attr s0zaehler_offsetB room Zaehler
attr s0zaehler_offsetB setList state:textField
attr s0zaehler_offsetB webCmd state

# Funktion zum Berechnen und Setzen der Offset- Werte:
define Func_SetOffsetB notify s0zaehler_offsetB  { \
\
  my $aufrufer_SetOffset = "@" ;;\
  my $valueB = (ReadingsVal("s0zaehler","B",0)/800 );;\
  my $setoffsetB = (ReadingsVal("s0zaehler_offsetB","state",0) - $valueB);;\
\
{ \
     Log 1, "Setze Zaehler B auf: $setoffsetB";; \
     fhem("attr s0zaehler_offsetB $setoffsetB");;\
     fhem("set s0zaehler_offsetB $setoffsetB");;\
} \
                                             { \
     fhem("save");;\
}\
}
attr Func_SetOffsetB group Berechnungen
#attr Func_SetOffsetB room Energie

MichaelO

Hallo,
ich versuche mich seit kurzem an SmartHome mit einem RasPi und fhem. Da ich meinen S0-Stromzähler mit fhem auslesen möchte, ist mir derzeit noch nicht klar ist, wozu ich überhaupt einen 1-wire Busmaster brauche, kommt mir der SMSGuard Stick doch recht gelegen, da er schon fix und fertig und recht günstig ist.

Darf ich mal fragen, wozu man den Busmaster ansonsten brauchen könnte? Wenn ich das im Forum richtig verstanden habe, dann das Auslesen/Zählen des S0 für 1-wire nicht ohne massive Bastelei möglich, da es keine günstige und fertige Counter gibt. Dafür fehlt mir leider die Zeit.

Mein Ziel ist, möglichst günstig, verlässlich und ohne große Bastelei die Zählerinfos in fhem mitschreiben zu können. Dazu scheint der SMSGuard doch optimal, oder?

Danke
Michael


Prof. Dr. Peter Henning

Ist das nun eine Frage, oder eine Feststellung ?

LG

pah

MichaelO

Zitat von: Prof. Dr. Peter Henning am 03 Oktober 2015, 21:26:45
Ist das nun eine Frage, oder eine Feststellung ?

LG

pah

Naja, ich war kurz davor, den SMSGuard-Stick zu bestellen. Wenn es aber sinnvoller erscheint, irgendwas Bezahlbares und Verfügbares mit 1-wire umzusetzen, dann würde ich natürlich lieber das machen.

Prof. Dr. Peter Henning

Wem sinnvoller erscheint ?

LG

pah

Joshibaer

Es ist ganz einfach.
Für Leute ohne Erfahrung wenig Zeit und keine Bastelerfahrung ist das eine teure aber gute Alternative.
Du brauchst einen 1 Wire Busmaster um an deinen Raspberry den besagten 3 Leiterbus (manchmal auch nur 2 Leiter) an zu Schließen(der Raspberry kann auch einen Busmaster an seinen I/O Kanälen emulieren aber nur für 3,3V). Für den 1 W Bus gibt es dann Zählerbausteine, die die S0 Impulse zählen und die dann in FHEM ausgelesen , bearbeitet und angezeigt werden können.

Bei der hier beschriebenen Schaltung geht es recht einfach.
Anschließen und Läuft.
Alles laut Anleitung in FHEM einbinden und gut so.

Wenn man die Schaltung selbst baut, mag es für viele eine Sache der Ehre sein, aber halt nicht für jeden.

MichaelO

Zitat von: Joshibaer am 04 Oktober 2015, 11:49:42
Es ist ganz einfach.
...
Bei der hier beschriebenen Schaltung geht es recht einfach.
Anschließen und Läuft.
Alles laut Anleitung in FHEM einbinden und gut so.

Wenn man die Schaltung selbst baut, mag es für viele eine Sache der Ehre sein, aber halt nicht für jeden.


Alles klar. Da ich derzeit noch keine weitere Verwendung für 1-wire bei mir sehe - ich kann nachträglich eh keinen Bus mehr durchs ganze Haus legen- werde ich mir den Stick wohl kaufen und damit meinen Zähler auslesen. Dummerweise habe ich in Unkenntnis der Möglichkeiten einen einfachen mit S0-Bus bekauft. Jetzt hab ich gesehen, dass es auch welche gibt, die über ein Modbus-Protokoll noch mehr Daten rausgeben und nicht wirklich teurer gewesen wären. Naja, erstmal sollte es per S0 reichen. Ist schon echt verwirrend, was es so alles auf dem Markt gibt.

Danke jedenfalls!

Prof. Dr. Peter Henning

Es ist (gerade für einen Anfänger !) absoluter Unsinn, einen Zähler mit Modbus zu betreiben. Alle Informationen, die man braucht, kann man problemlos aus dem Mitlesen der S0-Daten erhalten: Leistung, Leistungspitzen, durchschnittliche Leistung, Gesamtenergie etc. ergeben sich aus der Verfolgung der Impulse. Allenfalls solche Daten wie gegenwärtige Spannung, Frequenz und Phasenfehler könnte man noch messen - aber zu welchem Zweck bitte ?

Die Smart Meter mit Modbus (und anderen...) Interfaces sind in der Regel vollständig übertechnisiert, sie stellen deshalb ein nicht unerhebliches Sicherheitsrisiko für unsere gesamte Infrastruktur dar.

Im Übrigen ist es auch Unsinn, dass man für 1-Wire ein Kabel durchs ganze Haus ziehen muss - das geht auch anders
http://www.fhemwiki.de/wiki/1W-IF-WIFI

oder,mit einem anderen Ansatz:
http://www.instructables.com/id/Low-cost-WIFI-temperature-data-logger-based-on-ESP/
http://iot-playground.com/2-uncategorised/41-esp8266-ds18b20-temperature-sensor-arduino-ide

LG

pah