Ankündigung

Einklappen
Keine Ankündigung bisher.

S0 Zähler

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [wiregate] S0 Zähler

    Edit: aktuelle Version immer auf Github (https://github.com/J-N-K/wgplugin/bl...r/S0Zaehler.pl)

    Hallo,

    anbei ein neues Plugin. Mein Gaszähler liefert S0-Impulse, die ein MDT-Binäreingang im Zählermodus auf den Bus bringt. Dieses Plugin macht daraus den aktuellen Zählerstand sowie aus der Zeit zwischen den Impulsen den aktuellen Verbrauch.

    Code:
    # S0 Zaehler v1.0
    #
    # Copyright 2016: JNK (https://knx-user-forum.de/members/jnk.html)
    # latest version available on https://github.com/J-N-K/wgplugin
    #
    
    #
    # config starts here
    #
    
    my $s0_ga = '5/4/101'; # GA auf der die S0-Impulse ankommen
    my $zaehler_ga = '5/4/1'; # GA auf den der Gesamtzaehlerstand gesendet wird
    my $verbrauch_ga = '5/4/11'; # GA auf den der aktuelle Verbrauch gesendet wird
    
    my $ctr_offset = 68737500; # Offset des Zaehlers gegenueber den S0 Impulsen
    my $s0_scaler = 1000; # Faktor Impulse/Einheit
    
    my $rrdpath = "/var/www/rrd";        #Pfad fuer RRDs
    my @countermodes = (5,15,60,1440);    #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
    
    my $debug = 0; # Debug-Meldungen ausgeben?
    
    #
    # config ends here
    #
    
    if (($msg{'apci'} eq "A_GroupValue_Write") && ($msg{'dst'} eq $s0_ga)) {
      # calculate counter value
      my $s0_cts = $msg{'value'};
      my $ctr_total = $ctr_offset + $s0_cts;  
      my $now = time();
     
      # store in RRD
      foreach (@countermodes) {
        my $counterid = "strom";
        my $rrdname = $counterid."_".$_."\.rrd";
        my $rrdfile = $rrdpath."\/".$rrdname;
        unless (-e $rrdfile) {
          RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s ".($_*60));
        }
        my $storevalue = int($ctr_total*$_*60);
        RRDs::update("$rrdfile", "N:$storevalue");
      }
     
      # write to knx
      my $ctr_value = $ctr_total/$s0_scaler;
      if ($zaehler_ga) {
        knx_write($zaehler_ga, $ctr_value);
      }
     
      my $verbrauch = ($ctr_total - $plugin_info{$plugname.'_value'})/($now - $plugin_info{$plugname.'_valuelast'});
      if ($verbrauch_ga) {
        knx_write($verbrauch_ga, $verbrauch);
      }
        
      # save last value and timestamp
      $plugin_info{$plugname.'_value'} = $ctr_total;
      $plugin_info{$plugname.'_valuelast'} = $now;
        
      plugin_log($plugname, "Counts=$s0_cts, Gesamt=$ctr_value, Verbrauch=$verbrauch") if $debug;
    } else {
      $plugin_subscribe{$s0_ga}{$plugname} = 1;
      $plugin_info{$plugname.'_cycle'} = 0;
    }
    
    return;
    Zuletzt geändert von JNK; 02.03.2016, 20:09.
    KNX, DMX over E1.31, DALI, 1W, OpenHAB, MQTT

    #2
    Find ich gut probier ich gleich mal aus mit meiner WP.

    Kommentar


      #3
      Sollte wenn ich das richtig sehe auch 1:1 für einen Stromzähler funktionieren, oder?
      Gruß -mfd-
      KNX-UF-IconSet since 2011

      Kommentar


        #4
        Ja, das sollte gehen. Ich überarbeite das gerade noch einmal um mehrere Zähler in einem Plugin zu bearbeiten (ich nutze im Augenblick zwei Instanzen, eine für Gas und eine für Strom).
        KNX, DMX over E1.31, DALI, 1W, OpenHAB, MQTT

        Kommentar


          #5
          Ich hab das Script umgebaut um meine 7 Zähler damit abzuwickeln, hier der Code

          Code:
          # S0 Zaehler v1.0
          #     
          # Copyright 2016: JNK (https://knx-user-forum.de/members/jnk.html)
          # latest version available on https://github.com/J-N-K/wgplugin
          #
          # version 1.1 by gc (https://knx-user-forum.de/member/5432-chris5020)
          # unterstuetzt mehrere S0-Zaehler
          
          
          # define array
          my @aCounter;        # array mit Zaehlern
          
          #
          # ======================================== config starts here ========================================
          #
          
          push @aCounter, { id => "strom_bezug", ga_s0 => "4/6/10", ga_counter => "4/6/210", ga_current => "4/6/220", offset => 0, scale => 250 };        #210    Strom Gesamt Bezug
          push @aCounter, { id => "strom_einsp", ga_s0 => "4/6/11", ga_counter => "4/6/211", ga_current => "4/6/221", offset => 0, scale => 250 };        #211    Strom Gesamt Einspeisung
          # push @aCounter, { id => "strom_pv", ga_s0 => "4/6/12", ga_counter => "4/6/212", ga_current => "4/6/222", offset => 0, scale => 800 };        #212    Strom Erzeugt PV
          push @aCounter, { id => "strom_wp", ga_s0 => "4/6/15", ga_counter => "4/6/215", ga_current => "4/6/225", offset => 0, scale => 800 };        #215    Strom Wärmepumpe
          push @aCounter, { id => "strom_ht", ga_s0 => "4/6/16", ga_counter => "4/6/216", ga_current => "4/6/226", offset => 0, scale => 800 };        #216    Strom Haustechnik
          push @aCounter, { id => "strom_gp", ga_s0 => "4/6/17", ga_counter => "4/6/217", ga_current => "4/6/227", offset => 0, scale => 800 };        #217    Strom Garage/Pool
          push @aCounter, { id => "strom_rest", ga_s0 => "4/6/18", ga_counter => "4/6/218", ga_current => "4/6/228", offset => 0, scale => 800 };        #218    Strom Rest
          
          my $rrdpath = "/var/www/rrd";         # Pfad fuer RRDs
          my @countermodes = (5,15,60,1440);    # Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
          
          my $debug = 1; # Debug-Meldungen ausgeben?
          
          #
          # ======================================== config ends here ========================================
          #
          
          if ($msg{'apci'} eq "A_GroupValue_Write") { # Telegramm eingetroffen
              plugin_log($plugname, 'empfangen GO:'.$msg{'dst'}.' Wert:'.$msg{'value'}) if $debug;
              foreach my $element (@aCounter) {    # alle Zaehler durchlaufen
                  if ($msg{'dst'} eq "$element->{ga_s0}") {
          
                    # calculate counter value
                    my $s0_cts = $msg{'value'};
                    my $ctr_total = $element->{offset} + $s0_cts;  
                    my $now = time();
                      my $counterid = $element->{id};
                  
                    # store in RRD
                    foreach (@countermodes) {
                      my $rrdname = $counterid."_".$_."\.rrd";
                      my $rrdfile = $rrdpath."\/".$rrdname;
                      unless (-e $rrdfile) {
                        RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s ".($_*60));
                      }
                      my $storevalue = int($ctr_total*$_*60);
                      RRDs::update("$rrdfile", "N:$storevalue");
                    }
                  
                    # write to knx
                    my $ctr_value = $ctr_total/$element->{scale};
                    if ($element->{ga_counter}) {
                      knx_write($element->{ga_counter}, $ctr_value);
                    }
                  
                    my $verbrauch = ($ctr_total - $plugin_info{$plugname.'_value_'.$counterid})/($now - $plugin_info{$plugname.'_valuelast_'.$counterid});
                    if ($element->{ga_current}) {
                      knx_write($element->{ga_current}, $verbrauch);
                    }
                      
                    # save last value and timestamp
                    $plugin_info{$plugname.'_value_'.$counterid} = $ctr_total;
                    $plugin_info{$plugname.'_valuelast_'.$counterid} = $now;
                  
                    plugin_log($plugname, "Counts=$s0_cts, Gesamt=$ctr_value, Verbrauch=$verbrauch") if $debug;
                  }
              } # foreach
          } # if received
          else {
          # Subscribe GAs
              foreach my $element (@aCounter) {
                  plugin_log($plugname, 'registriere S0-GA:'.$element->{ga_s0});
                  $plugin_subscribe{$element->{ga_s0}}{$plugname} = 1;
                  $plugin_info{$plugname.'_cycle'} = 0;
              }
          } # else
          return;
          läuft erst seit ein paar Minuten, aber sieht gut aus. Ein wenig aufgehalten hatte mich der falsche DPT bei den GAs, den musste ich auf 13.001 umstellen

          lg, chris

          Kommentar


            #6
            Allerdings finde ich die Berechnung für "Verbrauch" nicht ideal, sind jetzt ja Impulse/Sekunde

            Sollte man das nicht in kw umrechnen?

            müsste dann sein:
            Code:
            my $verbrauch = ($ctr_total - $plugin_info{$plugname.'_value_'.$counterid})/($now - $plugin_info{$plugname.'_valuelast_'.$counterid}) * 60 * 60 / $element->{scale};
            lg, Chris

            Kommentar


              #7
              Ich habe eine etwas andere Lösung, befindet sich auf Github (https://github.com/J-N-K/wgplugin/bl...r/S0Zaehler.pl). Die DPT sollte ich vielleicht noch dokumentieren, wobei das ganze eigentlich mit jedem DPT funktionieren sollte, wenn dieser im WG richtig eingestelllt und für die jeweiligen Daten kompatibel ist. Ich benutze

              S0: 13.001
              Wert: 14.018
              Verbrauch: 9.024

              Was noch zu programmieren ist: ReadResponse für Wert und Verbrauch. Allerdings habe ich daran im Augenblick nur bedingt Interesse.

              Gruss,

              Jan
              KNX, DMX over E1.31, DALI, 1W, OpenHAB, MQTT

              Kommentar


                #8
                Da zeigt sich halt, dass ich kein Perl-Programmierer bin

                Die Idee mit der GA als Key zu arbeiten ist natürlich elegant und spart ressourcen.


                Bezüglich DPT war mein Problem eh, dass im Wiregate der falsche Typ hinterlegt war (1.001) und dann kommt als Wert nur 0

                Kommentar


                  #9
                  Ich hab das aktuelle Script im Einsatz, allerdings ist da ein Bug in Zeile 65

                  Code:
                   my $usage = ($total - $plugin_info{$plugname.'_'.$name.'_value'})/($now - $plugin_info{$plugname.'_'.$name.'_last'})*$counter->{'scaling'};;
                  Du MULTIPLIZIERST mit dem Scale, das sollte aber eher DIVIDIERT sein wie in Zeile 60

                  Ergebnis sind dann aber kWh/s, müsste man also mit 3600 Multiplizieren, damit man kW bekommt

                  Ausserdem ist mir aufgefallen, dass die Werte NICHT an den Bus gesendet werden, im eibd-log sehe ich keine Einträge, funktioniert das bei wem?
                  War natürlich mein Fehler, hatte die neuen GAs nicht importiert, und das ist notwendig
                  Zuletzt geändert von chris5020; 06.03.2016, 07:41. Grund: Fehler mit Senden GA behoben

                  Kommentar


                    #10
                    Was den Verbrauch angeht hast Du recht. Ich habe das ein wenig angpasst, die neue Version hat einen zusätzlichen Parameter "usagescaling". Grund: Mein Gaszähler liefert m³, da ist sowas wie m³/s oder ähnliches ein guter Wert, ich muss also nur die S0-Counts passend skalieren, der Stromzähler liefert jedoch kWh, mich interessieren aber W, also müssen aus den Stunden Sekungen und aus den kW Watt werden. Deswegen ist mir der Bug * statt / auch nicht gleich aufgefallen: *3600000/1000 ist von der Größenordnung das gleiche wie *1000.
                    KNX, DMX over E1.31, DALI, 1W, OpenHAB, MQTT

                    Kommentar

                    Lädt...
                    X