Ankündigung

Einklappen
Keine Ankündigung bisher.

encode dpt9 mit der Shell

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    encode dpt9 mit der Shell

    Ich würde gerne meine 1Wire Daten Minutengenau mittels eibd versenden um die Werte über Linknx Visu darzustellen. Nach langem suchen im Netz bin ich auf folgenden Code gestoßen! Soweit geht das prima aber leider nur Temperaturwerte von -40 bis +40. Leider reichen mir die +40 nicht da ich auch die Heizung mit darstellen möchte.
    Kennt sich jemand mit der bash Programierung aus um mir unter die Arme zu greifen?


    Code:
    #!/bin/sh
    
    var=`exec /opt/owfs/bin/owdir  -s 4304 /28.6C858B020000/temperature | tr -d " "`
    #var=-41.00
    nb=0
    var=$(echo "$var*100/1" |bc) #/1 pour suppression de la virgule
    if [ $var -gt 0 ]
    then
            while [ $var -gt 2047 ]
            do
            nb=$nb+1
            var=$(echo "$var/2" |bc)
            done
    nb=$(echo "$nb*2048" |bc)
    var=$(echo "ibase=10;obase=16;$var+$nb"|bc)
    elif [ $var -lt 0 ]
    then
    var=$(echo "$var*-1" |bc) #*1 pour revenir en positif
            while [ $var -gt 2047 ]
            do
            nb=$nb+1
            var=$(echo "$var/2" |bc)
            done
    nb=$(echo "$nb*2048" |bc)
    echo $var
    var=$(echo "ibase=10;obase=16;4096-$var+$nb+32768-2048"|bc)
    fi
    #verification si 4 caract
    if [ ${#var} = 1 ]
    then
    var="00 0${var}"
    elif [ ${#var} = 2 ]
    then
    var="00 ${var}"
    elif [ ${#var} = 3 ]
    then
    var="0${var}"
    var1=`expr substr $var 1 2`
    var2=`expr substr $var 3 2`
    var="${var1} ${var2}"
    elif [ ${#var} = 4 ]
    then
    var1=`expr substr $var 1 2`
    var2=`expr substr $var 3 2`
    var="${var1} ${var2}"
    fi
    exec /usr/bin/groupwrite ip:192.168.2.41 10/0/3 $var
    Ich steige da leider nicht durch
    Gibt es einen besseren weg? Ist es möglich mit Linknx direkt die 1wire Daten abzurufen ?

    Gruß Maik

    #2
    Nun, ich kann dir nur die sicher funktionierenden Varianten anbieten encode_dpt9 , der in linknx stimmt, der genannte dürfte von dem im mh abstammen, der schlicht falsch ist..

    Nochmal in C:
    Code:
    ... (switch (dpt))
    ...
        case 9:
            fval=atof(data);
          if (fval<0)
            sign = 0x8000;
          mant = (int)(fval * 100.0);
          while (abs(mant) > 2047) {
              mant = mant >> 1;
              exp++;
          }
          i = sign | (exp << 11) | (mant & 0x07ff);
          buf[2] = i >> 8;
          buf[3] = i & 0xff;
          len=4;
          break;
    ...
    Das in Shellcode umzusetzen überlasse ich Dir aber die community freut sich bestimmt über das Ergebniss! Machbar ist es sicherlich, wenns Detailfragen gibt: fragen aber zum fertig-kauen fehlt mir grad Elan&die Notwendigkeit
    Es wird nur allzuoft falsch gemacht, deswegen nenne ich eben diese beiden Beispiele..

    Makki
    EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
    -> Bitte KEINE PNs!

    Kommentar


      #3
      Danke Makki,
      aber ich blicke da nicht wirklich durch und mit try and error komme ich da sicher nicht weit

      Ich werde mich weiter auf die suche machen in der Hoffnung bald was zu finden was meinen Wünschen entspricht.

      Eibd <> Linknx <> KnxWeb läuft super und hat mich noch nie im Stich gelassen! Temperatur Daten werden in eine mysql Datenbank gesammelt und über jpgraph ausgegeben.
      Nur die 1Wire Daten muss ich noch nach Linknx bekommen

      evtl. die nächste Version von smarthome.py?
      Oder die Wiregate Kopie in meiner VM? <-- zeitweise hohe cpulast und Hänger denen ich noch auf den Grund gehen könnte?

      Kann Linknx die 1Wire Daten nicht auch selber über einen Trigger abfragen?


      Ich bin auch nicht an die Shell gebunden! evtl. jemand da der encode_dpt9 über PHP am laufen hat?


      Gruß Maik

      Kommentar


        #4
        php function

        Code:
        function DECtoDPT9($DEC)
        {
            $DEC *= 100;
            $dpt9 = 0;
            $exponent = 0;
            if ($DEC < 0)
            {
                $dpt9 = 0x08000;
                $DEC = -$DEC;
            }  
            while ($DEC > 0x07ff)
            {
                $DEC >>= 1;
                $exponent++;
            }
            if ($dpt9 != 0) $DEC = -$DEC;
            $dpt9 |= $DEC & 0x7ff;
            $dpt9 |= ($exponent << 11) & 0x07800;
            return strtoupper(chunk_split(str_pad(dechex($dpt9 & 0x0ffff),4,'0',STR_PAD_LEFT),2,' '));
        }
        So sollte das gehen.

        Kommentar


          #5
          Code:
          <objects>
          <object id="temp1"                              gad="10/0/3" flags="crwtu" init="persist" type="EIS5">temp1</object>
          <object id="temp2"                              gad="10/0/4" flags="crwtu" init="persist" type="EIS5">temp2</object>
          <object id="temp3"                              gad="10/0/5" flags="crwtu" init="persist" type="EIS5">temp3</object>
          <object id="temp4"                              gad="10/0/6" flags="crwtu" init="persist" type="EIS5">temp4</object>
          <object id="temp5"                              gad="10/0/7" flags="crwtu" init="persist" type="EIS5">temp5</object>
          <object id="temp6"                              gad="10/0/8" flags="crwtu" init="persist" type="EIS5">temp6</object>
          <object id="temp7"                              gad="10/0/9" flags="crwtu" init="persist" type="EIS5">temp7</object>
          </objects>
          
          
          <rule id="1wire-read">
          <condition type="timer" trigger="true">
          <every>1m</every>
          </condition>
          <actionlist>
          <action type="script">
          function read1wire(id, objname)
          out = io.popen("/usr/bin/owread -s 192.168.2.200:4304 "..id);
          value = string.match(out:read("*a"), "[0-9.]+");
          out:close();
          set(objname, value);
          end;
          read1wire("28.E82BCB010000/temperature","temp1");
          read1wire("28.6C858B020000/temperature","temp2");
          read1wire("28.7CA28B020000/temperature","temp3");
          read1wire("28.A126CB010000/temperature","temp4");
          read1wire("28.61A18B020000/temperature","temp5");
          read1wire("28.2534CB010000/temperature","temp6");
          read1wire("28.8F2B73020000/temperature","temp7");
          read1wire("26.083811010000/temperature","temp8");
          </action>
          </actionlist>
          </rule>
          Ich bin noch am testen ... aber
          Gruß Maik

          Kommentar


            #6
            Zitat von MaBo76 Beitrag anzeigen
            aber ich blicke da nicht wirklich durch und mit try and error komme ich da sicher nicht weit
            Mal so unter uns, das habe ich damals geschrieben ohne KNX-Member zu sein, also mit ebensowenig Infos. damit zu sagen das manche Quelle so nicht richtig ist nachträglich natürlich einfach..
            An dem DPT9 habe ich 2x nachgebessert, was mir stinkt, ich will aber vermeiden das es noch 5 falschgemacht wird, weil das brauchts echt ned.
            Ich würde mich mehr über konstruktive Eingebungen freuen

            Makki
            EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
            -> Bitte KEINE PNs!

            Kommentar


              #7
              Ich muss diesen alten Thread nochmals vorkramen.

              Ich stehe momentan vor dem gleichen Problem:
              Wie kann ich in einem Shell-Script einen Temperaturwert von Dezimal nach DPT9 umrechnen.

              Hintergrund:
              EIBD/CV/ laufen auf einem Raspberry.
              6x 1-Wire Sensoren und 4 Digitaleingänge (Status Pumpe an/aus) hängen (räumlich getrennt) an einem AVR-NetIO.
              Auf dem AVR läuft Ethersex.
              Der Raspberry holt die Temperaturen und Stati minütlich vom AVR und schreibt diese in eine RRD. Alle 10 min wird per RRD-Graph ein Diagramm erzeugt, welches ich in der CV sehen kann.
              Nun möchte ich auch einen aktuellen Status sehen. Mit den Pumpen ist es einfach , da ich ja per groupswrite nur 0 oder ein senden brauch.
              Wenn ich aber Temperaturen senden möchte, müssen dies erst umgerechnet werden.
              Und da komme ich momentan nicht weiter.

              DANKE

              Kommentar


                #8
                Gibt es wirklich niemand, der mir helfen kann?
                Kann mir eventuell jemand erklären, wie ich die PHP-Funktion von franzler in die sh-Datei integrieren kann?

                Kommentar


                  #9
                  Da ich nach langen Suchen auch nichts gefunden habe, musste ich doch selber mal etwas zusammenbasteln.

                  Zur Vereinfachung habe ich den Exponent fix auf 2 festgelegt. Damit erspare ich mir etwas Rechnerei, begrenze aber den möglichen Wertebereich auf -81 bis +81 Grad. Die Genauigkeit ist rechnerisch 1/25 Grad. Da ich als Sensoren 1-Wire-Sensoren nutze mit einer Nachkommastelle, recht es mir.
                  Wer einen grösseren Wertebereich benötigt, setzt die Variable expo auf 3 und kann dann von ca -160 bis 160 Grad arbeiten.
                  Da ich von Linux eigendlich keine Ahnung habe und das meisste im Script aus dem Netz zusammenkopiert ist, ist der Stil vielleicht nicht der beste. Aber bei mir funktioniert es.
                  Anmerkungen/Verbesserungen sind willkommen.
                  Code:
                  #!/bin/sh
                  gawk="/usr/bin/gawk"
                  
                  ###Beginn Funktion###
                  function dec2dpt9(){
                  
                  ein="$1"
                  expo=2
                  exp_ges=`echo "scale=0; 2^($expo)" | bc -l`
                  ein=`echo "scale=0; $ein * 100" | bc` #erweitern auf 1/100
                  ein=`echo "scale=0; $ein / $exp_ges" | bc` #Mantisse berechnen
                  
                  # Vorzeichen bestimmen
                  wahr=$(echo  "$ein >  0 " | bc)
                   if  [ $wahr = 1 ]; then 
                      vz=0
                     else 
                      vz=1
                      eina=`echo "-2048 - $ein" | bc`
                      ein=`echo "$eina * -1" | bc`
                   fi
                  
                  man_bin=`echo "obase=2; $ein" | bc` #Mantisse nach bin
                  man11=`echo $man_bin | awk '{printf("%.11u\n", $1)}'` #bin bei bedarf auf 11 Stellen erweitern
                  exp_bin=`echo "obase=2; $expo" | bc`
                  exp4=`echo $exp_bin | awk '{printf("%.4u\n", $1)}'` #expo auf 4 stellen erweitern
                  binresult=$vz$exp4$man11 #komplette bin zusammensetzen
                  hexresult=$(echo 'obase=16;ibase=2;'$binresult | bc) #nach hex umrechnen
                  hex=`echo ${hexresult:0:2}" "${hexresult:2:2}` #Leerstelle einfügen
                  echo $hex
                  }
                  ###Ende Funktion###
                  
                  ###Testumgebung###
                  echo "Temperatureingabe"
                  read data
                  hexausgabe=$(dec2dpt9 $data)
                  echo $hexausgabe
                  
                  groupwrite ip:127.0.0.1 9/1/9 $hexausgabe #auf die testadresse schreiben

                  Kommentar


                    #10
                    Weil es ein ähnliches Problem ist:

                    Ich will meine Zähler (Strom) auf den Bus bekommen.

                    Datentyp: DPT 13

                    Mein Problem momentan: wie bekomme ich die Hex-Zahl erweitert?

                    zB Dezimal ist 500 -> Hex 1f4
                    Ich benötige als Zahl nicht 1f4 sondern 000001f4.

                    Im Obigen Script iste iene Funktion zum Erwetern einer Zahl:

                    exp4=`echo $exp_bin | awk '{printf("%.4u\n", $1)}'`

                    Leider arbeitet diese Zeile scheinbar nur mit dezimalen Zahlen. Wie bringe ich dem Befehl Hex bei?

                    Kommentar


                      #11
                      Ich habe das Problem inzwischen gelösst (zumindest für mich)
                      Code:
                      #!/bin/bash
                      
                      dpt13(){
                      ein="$1"
                      VAR=`echo $ein | awk '{printf("%08x\n", $1)}'`
                      hex=`echo ${VAR:0:2}" "${VAR:2:2}" "${VAR:4:2}" "${VAR:6:2}`
                      echo $hex
                      }
                      
                      echo "eingabe"
                      read zahl
                      hex4=$(dpt13 $zahl)
                      echo $hex4 #ausgabe des string
                      groupwrite ip:127.0.0.1 9/0/14 $hex4 #auf die testadresse schreibe
                      Allerding gibt es dabei offensichtlich keine Kommastellen?
                      Oder??

                      Kommentar


                        #12
                        Archiveintrag.
                        die ganze sache brauchte ich rückwärts, also die knx-temperaturwerte in der bash auslesen und per email versenden. der thread hat mir geholfen, ich bin auch kein programmierer und habe das mal zusammengestöpselt. aber das ergebnis scheint zu stimmen. (es müsste noch etwas posix-fest gemacht werden und kann alles gekürzt und bestimmt zig-fach verbessert werden, aber der weg ist zu sehen. denke ich.) also für die nächsten suchenden (vielleicht/hoffentlich) eine klitzekleine hilfe.

                        Code:
                        #!/bin/bash
                        
                        
                        
                        # main
                        
                        # zerlege hex in 2x 8bit binary:
                        #3E90 (hex) ist Binär geschrieben 0110 1110 1001 0000 (bin)
                        #
                        #Lt. Kapitel 3.10 Datapoint Types “2-Octet Float Value” des (von Michel) erwähnten Dokumentes "Datapoint Types" ist dieser Binär-Wert folgendermassen kodiert:
                        #
                        #0011 1110 1001 0000 (bin) = 3E90 (hex)
                        #MEEE EMMM MMMM MMMM
                        #
                        #Damit ergibt sich:
                        #M = 690 (hex) = 1680 (dez)
                        #E = 7 (hex) = 7 (dez)
                        #
                        #Lt. Dokument: FloatValue = 0,01 * M * 2^E
                        #
                        #Deine Werte eingesetzt:
                        #FloatValue = 0,01 * 1680 * 2^7 = 2150,4
                        #
                        #
                        knx=$(groupreadresponse ip:192.168.14.231 15/0/3)
                        echo "debug hex1: $knx"
                        echo "----------"
                        hex01=${knx: -6:2}
                        echo "debug hex01: $hex01"
                        echo "----------"
                        hex02=${knx: -3}
                        echo "debug hex02: $hex02"
                        echo "----------"
                        
                        dec01=$(echo "obase=2; ibase=16; $hex01" | bc )
                        echo "debug dec01: $dec01"
                        echo "----------"
                        
                        dec01=$( echo $dec01 | awk '{printf("%.8u\n", $1)}' )
                        # auf 8 stellen erweitern, bc macht das nicht von selbst
                        echo "debug dec01: $dec01"
                        echo "----------"
                        
                        dec02=$(echo "obase=2; ibase=16; $hex02" | bc )
                        echo "debug dec02: $dec02"
                        echo "----------"
                        
                        dec02=$( echo $dec02 | awk '{printf("%.8u\n", $1)}' )
                        # auf 8 stellen erweitern, bc macht das nicht von selbst
                        echo "debug dec02: $dec02"
                        echo "----------"
                        
                        bin01=$dec01$dec02
                        echo "debug bin01: $bin01"
                        echo "----------"
                        
                        hex03=$(echo "obase=10; ibase=2; $bin01" | bc )
                        echo "debug hex03: $hex03"
                        echo "----------"
                        
                        exp01=`expr substr $bin01 1 4`
                        echo "debug exp01: $exp01"
                        echo "----------"
                        
                        man01=`expr substr $bin01 5 15`
                        echo "debug man01: $man01"
                        echo "----------"
                        
                        exp02=$(echo "obase=10; ibase=2; $exp01" | bc )
                        echo "debug exp02: $exp02"
                        echo "----------"
                        
                        man02=$(echo "obase=10; ibase=2; $man01" | bc )
                        echo "debug man02: $man02"
                        echo "----------"
                        
                        tmp_float1=`echo "0.01 * ${man02}" | bc -l`
                        echo "debug flo1: $tmp_float1"
                        echo "----------"
                        
                        tmp_float2=`echo "scale=0; 2^($exp02)" | bc -l`
                        echo "debug flo2: $tmp_float2"
                        echo "----------"
                        
                        tmp_float=`echo "${tmp_float1} * ${tmp_float2}" | bc -l`
                        echo "debug float: $tmp_float"
                        echo "----------"

                        Kommentar


                          #13
                          ...und hier die Sache für DPT 7:
                          Code:
                          #!/bin/bash
                          dpt7(){
                            ein="$1"
                            VAR=`echo $ein | awk '{printf("%04x\n", $1)}'`
                            hex=`echo ${VAR:0:2}" "${VAR:2:2}`
                            echo $hex
                          }
                          echo "eingabe"
                          read zahl
                          hex2=$(dpt7 $zahl)
                          echo $hex2 #ausgabe des string
                          groupwrite ip:127.0.0.1 9/0/14 $hex2 #auf die Testadresse schreiben

                          Kommentar


                            #14
                            Zitat von ozett Beitrag anzeigen
                            Archiveintrag.
                            die ganze sache brauchte ich rückwärts, also die knx-temperaturwerte in der bash auslesen und per email versenden. der thread hat mir geholfen, ich bin auch kein programmierer und habe das mal zusammengestöpselt. aber das ergebnis scheint zu stimmen. (es müsste noch etwas posix-fest gemacht werden und kann alles gekürzt und bestimmt zig-fach verbessert werden, aber der weg ist zu sehen. denke ich.) also für die nächsten suchenden (vielleicht/hoffentlich) eine klitzekleine hilfe.
                            Aus meiner Sicht ist hier ein Fehler in der Bildung des Exponenten (bei exp01) bzw. der Mantisse (bei man01) passiert. Hier korrigiert:
                            Code:
                            #!/bin/bash
                            # main
                            
                            # zerlege hex in 2x 8bit binary:
                            #3E90 (hex) ist Binär geschrieben 0110 1110 1001 0000 (bin)
                            #
                            #Lt. Kapitel 3.10 Datapoint Types “2-Octet Float Value” des (von Michel) erwähnten Dokumentes "Datapoint Types" ist dieser Binär-Wert folgendermassen kodiert:
                            #
                            #0011 1110 1001 0000 (bin) = 3E90 (hex)
                            #MEEE EMMM MMMM MMMM
                            #
                            #Damit ergibt sich:
                            #M = 690 (hex) = 1680 (dez)
                            #E = 7 (hex) = 7 (dez)
                            #
                            #Lt. Dokument: FloatValue = 0,01 * M * 2^E
                            #
                            #Deine Werte eingesetzt:
                            #FloatValue = 0,01 * 1680 * 2^7 = 2150,4
                            #
                            #
                            knx=$(knxtool read ip:localhost 2/3/120)
                            #echo "debug hex1: $knx"
                            #echo "----------"
                            hex01=${knx: -6:2}
                            #echo "debug hex01: $hex01"
                            #echo "----------"
                            hex02=${knx: -3}
                            #echo "debug hex02: $hex02"
                            #echo "----------"
                            
                            dec01=$(echo "obase=2; ibase=16; $hex01" | bc )
                            #echo "debug dec01: $dec01"
                            #echo "----------"
                            
                            dec01=$( echo $dec01 | awk '{printf("%.8u\n", $1)}' )
                            # auf 8 stellen erweitern, bc macht das nicht von selbst
                            #echo "debug dec01: $dec01"
                            #echo "----------"
                            
                            dec02=$(echo "obase=2; ibase=16; $hex02" | bc )
                            #echo "debug dec02: $dec02"
                            #echo "----------"
                            
                            dec02=$( echo $dec02 | awk '{printf("%.8u\n", $1)}' )
                            # auf 8 stellen erweitern, bc macht das nicht von selbst
                            #echo "debug dec02: $dec02"
                            #echo "----------"
                            
                            bin01=$dec01$dec02
                            #echo "debug bin01: $bin01"
                            #echo "----------"
                            
                            hex03=$(echo "obase=10; ibase=2; $bin01" | bc )
                            #echo "debug hex03: $hex03"
                            #echo "----------"
                            
                            exp01=`expr substr $bin01 2 4`
                            #echo "debug exp01: $exp01"
                            #echo "----------"
                            
                            man01=`expr substr $bin01 1 1`
                            man01=$man01`expr substr $bin01 6 15`
                            #echo "debug man01: $man01"
                            #echo "----------"
                            
                            exp02=$(echo "obase=10; ibase=2; $exp01" | bc )
                            #echo "debug exp02: $exp02"
                            #echo "----------"
                            
                            man02=$(echo "obase=10; ibase=2; $man01" | bc )
                            #echo "debug man02: $man02"
                            #echo "----------"
                            
                            tmp_float1=`echo "0.01 * ${man02}" | bc -l`
                            #echo "debug flo1: $tmp_float1"
                            #echo "----------"
                            
                            tmp_float2=`echo "scale=0; 2^($exp02)" | bc -l`
                            #echo "debug flo2: $tmp_float2"
                            #echo "----------"
                            
                            tmp_float=`echo "${tmp_float1} * ${tmp_float2}" | bc -l`
                            #echo "debug float: $tmp_float"
                            echo $tmp_float
                            #echo "----------"

                            Kommentar


                              #15
                              Zitat von cprinz Beitrag anzeigen

                              Aus meiner Sicht ist hier ein Fehler in der Bildung des Exponenten (bei exp01) bzw. der Mantisse (bei man01) passiert. Hier korrigiert:
                              [CODE]
                              #!/bin/bash
                              ...

                              auch wenn seitdem ja nur 3 Jahre vergangen sind, Verbesserungen sind immer gut, oder?
                              Ich habe allerdings viele der KNX-Werte mitlerweile direkt in Node-Red eingelesen und lass diese dort verarbeiten.
                              Oder in MQTT übersetzen und mit Node-Red steuern. Die Zeit bringt eben auch andere Entwicklungen mit sich ...

                              Kommentar

                              Lädt...
                              X