Ankündigung

Einklappen
Keine Ankündigung bisher.

smarthome.py und vclient

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

    smarthome.py und vclient

    Hallo liebe smarthome.py-Gemeinde!

    Ich benötige mal eure Hilfe. Ich nutze smarthome.py schon länger zusammen mit smartVISU und dem KNX-Plugin, das funktioniert auch soweit bestens. Jetzt möchte ich aber gerne meine Viessmann-Heizung einbinden, um diverse Werte abfragen zu können (nur lesen, keine Werte ändern, z.B. Warmwassertemperatur, Kesseltemperatur, etc abfragen). Hierzu möchte ich vclient (siehe: https://openv.wikispaces.com/vclient) nutzen, um die Werte von vcontrold abzufragen. Mir ist es schon möglich über eine SSH-Verbindung ohne die Abfrage von Zugangsdaten vclient auf dem sich an der Heizung befindlichen RaspberryPi auszuführen und die Werte auf meinem Visu-Server in der Konsole anzuzeigen.

    Im Screenshot ist zu erkennen, dass ich remote einen Wert (hier: getTempKessel) abfragen kann und diesen auf dem VISU-Server ausgeben kann (hier rot eingerahmt: 61,09998 °C).
    abfrage_vclient_remote.jpg


    Mein Problem stellt derzeit die Einbindung in smarthome.py dar, da ich gerade ganz stark auf dem Schlauch stehe. Meine Annahme ist derzeit, dass ich die Einbindung mittels dem network-Plugin umsetzten kann. Ich weiss derzeit aber nicht, wie. Die Doku unter http://mknx.github.io/smarthome/plugins/network.html habe ich mir schon angesehen, blos steige ich hier nicht ganz durch. Evtl. bin ich aber auch komplett auf dem Holzweg und ich muss es über ein anderes Plugin machen. Daher wende ich mich hiermit an euch, in der Hoffnung, dass mir geholfen werden kann. Sollten euch noch wichtige Infos fehlen, einfach kurz melden. Wäre super, wenn mir mal jemand an Hand meiner o.g. Abfage eine Beispiel-Konfig geben könnte.

    Im Vorau vielen Dank und Gruß,

    Christian
    Zuletzt geändert von kamikaze2508; 27.02.2016, 14:43.

    #2
    Hallo,

    prinzipiell kann man ssh per subprocess-Modul aufrufen. https://docs.python.org/3/library/su...ule-subprocess

    Ich denke es ist aber besser direkt mit dem Daemon über die Telnet-Schnittstelle zu kommunizieren. Dazu müsstest Du mal googeln.
    Das Netzwerkplugin ist dafür aber nicht geeignet.

    Bis bald

    Marcus

    Kommentar


      #3
      Hallo!

      Ich dachte, die Kommunikation über den vclient sei die einfachere Methode, so kann man sich irren.
      Ich kann über Telnet auf Port 3002 eine Verbindung mit dem Daemon aufbauen. Im Falle meines obigen Beispielwertes würde das dann so aussehen:

      Code:
      telnet 192.168.0.37 3002
      Daraufhin erhalte ich einen Prompt "vctrld>".
      Hier kann ich nun einen Wert abfragen, z.B.:

      Code:
      vctrld>getTempKessel
      59.900002 °C
      vctrld>
      Anschließend muss ich die Verbindung mit Eingabe von quit beenden. Die Einheit °C kann ich Daemon-Seitig rauskonfigurieren, damit ich nur den reinen Wert erhalte. Soweit kein Problem. Wie würde ich dann aber in diesem Fall die Einbindung in smarthome.py umsetzen? Mit netcat habe ich noch folgende Möglichkeit herausgefunden, mit dem Daemon per Telnet zu kommunizieren:

      Code:
      root@smarthome:~# printf "getTempKessel \nquit\n" | netcat 192.168.0.37 3002
      vctrld>57.200001 °C
      vctrld>good bye!
      root@smarthome:~#
      Könnte man diese Variante evtl. gebrauchen?

      Im Voraus nochmals vielen Dank.

      Gruß,
      Christian
      Zuletzt geändert von kamikaze2508; 13.02.2016, 11:11.

      Kommentar


        #4
        Hi,

        ich habe nicht gesagt einfacher.
        1. Schritt Python Telnet Skript schreiben http://lmgtfy.com/?q=python3+telnet+client&l=1
        2. Schritt Plugin erstellen https://github.com/mknx/smarthome/wi...ugin-5-minutes

        Bis bald

        Marcus

        Kommentar


          #5
          Ich habe das etwas anders gelöst.

          Ob die Prozesse auf dem selben Rechner laufen oder nicht, ist insofern egal, als die Kommunikation übers Netzwerk läuft.

          Auf dem "Sensor-Rechner" läuft der vcontrold, der die Hardware-Verbindung zur Heizung hat (Optokoppler).

          Auf dem sh.py-Rechner läuft per cronjob ein Skript:

          Code:
          * * * * * /usr/local/bin/vclient -h hauspi:3002 -f /home/sh/vito/vito.txt -t /home/sh/vito/vito.tmpl -x /home/sh/vito/update.sh
          hauspi ist der Rechnername, auf dem der vcontrold läuft. Ich nutze die template-Funktion vom vclient (s.u.).

          vclient liest das "Skript" vito.txt:
          Code:
           getTempA
           getTempSekVL
           getTempSekRL
           getTempWWIstOben
           getSpdFan
           getSpdKomp
           getBetriebsart
           getStatusPumpe
           getLZPumpe
           getAnzQuelleSek
           getStatusSekP
           getLZPumpeSek
           getAnzHK
           getAnzHeizstabSt1
           getLZHeizstabSt1
           getAnzHeizstabSt2
           getLZHeizstabSt2
           getStatusVentilWW
           unit off
           getBetriebsart
          und gibt die Befehle der Reihe nach an den vcontrold. Die Ergebnisse werden genutzt, um das Template vito.tmpl zu befüllen:
          Code:
           #!/bin/bash
          
           if  [ "x$E1" != "xOK" ]; then
                   echo -n `date`  >>/tmp/vc-err.txt
                   echo "es ist ein Fehler aufgetreten: $C1:$E1" >>/tmp/vc-err.txt
                   exit 1;
           fi
          
          REM /// analog für alle Parameter wiederholen, aus Platzgründen hier entfernt...
          
           if  [ "x$E20" != "xOK" ]; then
                   echo -n `date`  >>/tmp/vc-err.txt
                   echo "es ist ein Fehler aufgetreten: $C20:$E20" >>/tmp/vc-err.txt
                   exit 1;
           fi
          
           printf "%.2f" $1 > /dev/udp/localhost/42000     # getTempA
           printf "%.2f" $2 > /dev/udp/localhost/42001     # getTempSekVL
           printf "%.2f" $3 > /dev/udp/localhost/42002     # getTempSekRL
           printf "%.2f" $4 > /dev/udp/localhost/42003     # getTempWWIstOben
           printf "%.2f" $5 > /dev/udp/localhost/42004     # getSpdFan
           printf "%.2f" $6 > /dev/udp/localhost/42005     # getSpdKomp
           echo $R7 > /dev/udp/localhost/42006             # getBetriebsart
           echo $R8 > /dev/udp/localhost/42007             # getStatusPumpe
           echo "$9/3600" | bc > /dev/udp/localhost/42008  # getLZPumpe
           printf "%.0f" $R10 > /dev/udp/localhost/42009   # getAnzQuelleSek
           echo $R11 > /dev/udp/localhost/42010            # getStatusSekP
           printf "%.0f" $12 > /dev/udp/localhost/42011    # getLZPumpeSek
           printf "%.0f" $R13 > /dev/udp/localhost/42012   # getAnzHK
           printf "%.0f" $R14 > /dev/udp/localhost/42013   # getAnzHeizstabSt1
           printf "%.0f" $15 > /dev/udp/localhost/42014    # getLZHeizstabSt1
           printf "%.0f" $R16 > /dev/udp/localhost/42015   # getAnzHeizstabSt2
           printf "%.0f" $17 > /dev/udp/localhost/42016    # getLZHeizstabSt2
           echo $R18 > /dev/udp/localhost/42017            # getStatusVentilWW
           echo $R20 > /dev/udp/localhost/42018            # getBetriebsart [num]
          Sobald vclient das Template mit den entsprechenden Werten befüllt hat ($1...$20 werden durch die ausgelesenen Werte ersetzt), wird das Skript unter "update.sh" gespeichert (siehe Kommandozeile vom vclient) und ausgeführt.

          Dabei werden dann über UDP die Daten ins Netz (hier an localhost) gesendet.

          Auf der Empfangsseite ist im sh.py das "network"-Plugin aktiviert und die entsprechenden Netzwerkports in der items.conf konfiguriert:

          Code:
                   [[aussentemperatur]]
                           type=num
                           nw_udp_listen = 42000
                           rrd=yes
                           rrd_min=yes
                           rrd_max=yes
                           visu_acl = rw
          und vergleichbar bzw. analog für jeden weiteren Wert. Da jeder Wert einen eigenen Port bekommt, muss man die nicht weiter auseinanderhalten.

          Du kannst auch sehen, dass ich die Werte gleich in die RRD-Datenbank schreibe.

          Ist vielleicht nicht die eleganteste Lösung, aber sie funktioniert für mich ganz gut.

          Wenn vclient nicht auf dem sh.py-Rechner läuft, muss man dass über netcat machen, dann geht die Abkürzung über /dev/udp/localhost/[port] nicht - aber da vclient übers Netz auf vcontrold zugreift, kann man den vclient ja direkt auf dem sh.py-Rechner laufen lassen.

          Kommentar


            #6
            Hallo Morg,
            vielen Dank für deinen Beitrag. Diese Lösung gefällt mir. Das ist genau das, was ich mir vorgestellt habe. Am kommenden Wochenende werde ich mir deine Lösung genauer ansehen und werde versuchen, diese zu adaptieren. Eine Frage hätte ich noch direkt. Konntest du den vclient einzeln kompilieren, oder muss ich auf dem abfragenden Server das komplette vcontrold-Paket kompilieren?

            Vielen Dank im Voraus.

            Viele Grüße

            Christian

            Kommentar


              #7
              Hi Christian,

              schön, dass du damit weiter kommst. Ich habe den Weg mit den Templates auch irgendwo (wahrscheinlich auf der openv-Seite) gefunden. Die zusätzliche Umsetzung mit der UDP-Verbindung über /dev fand ich ziemlich elegant...

              vclient müsstest du gem. http://openv.wikispaces.com/vclient auch getrennt übersetzen können. Meines Wissens läuft das einfach als standalone-Programm.

              Gruß
              Sebastian

              Kommentar


                #8
                Hallo Sebastian,

                möchte mich noch mal kurz melden. Ich habe deine Lösung adaptieren können. Ich musste nur zwei Anpassungen vornehmen. Zum Einen musste ich im Template für das Script das Nummerierungsformat ändern, da er mir die Nachkommastellen der Dezimalzahlen immer mit Komma anstatt einem Punkt ausgegeben hat. Das hat das Script nicht vertragen. Mit einem Eintrag LC_NUMERIC=C LC_COLLATE=C direkt unter #!/bin/bash war das erledigt. Des Weiteren musste ich im Template localhost gegen die Loopback-IP 127.0.0.1 ersetzten. Seitedem läuft's prima! Ich muss jetzt nur nochmal im openv-Forum nachhaken, warum ich an einigen Stellen falsche Werte bekomme. Ansonsten alles bestens!

                Viele Grüße
                Christian

                Kommentar


                  #9
                  Ich habe vor einiger Zeit ein Plugin geschrieben, dass über vcontrold Werte abfragen kann. Die Items sehen dann so aus:
                  [[Aussentemperatur]]
                  type = num
                  vclient_cmd = getTempA
                  vclient_unit = Grad Celsius

                  Der direkte Aufruf von vclient war mir zu langsam daher wird direkt mit vcontrold geredet.
                  Ich habe das Plugin aktuell nicht im Einsatz, da ich den RPi gerade neu aufsetzen musste. Es sollte aber funktionieren.

                  Viele Grüße,
                  Thomas
                  Angehängte Dateien

                  Kommentar


                    #10
                    Hallo,
                    ich nutze das plugin von thesing. Bekomme aber immer folgende Fehler:

                    Code:
                    2017-05-05  23:23:42 ERROR    vclient-cmds Method vclient-cmds exception: error receiving data: timeout
                    Traceback (most recent call last):
                      File "/usr/local/smarthome/plugins/vclient/__init__.py", line 95, in _request
                        chunk = self._sock.recv(100)
                    socket.timeout: timed out
                    
                    During handling of the above exception, another exception occurred:
                    
                    Traceback (most recent call last):
                      File "/usr/local/smarthome/lib/scheduler.py", line 400, in _task
                        obj()
                      File "/usr/local/smarthome/plugins/vclient/__init__.py", line 124, in _command_cycle
                        output = self._request(cmd)
                      File "/usr/local/smarthome/plugins/vclient/__init__.py", line 102, in _request
                        raise vcex("error receiving data: timeout")
                    plugins.vclient.vcex: error receiving data: timeout
                    2017-05-05  23:23:42 DEBUG    Connections  Data: b'vctrld>'
                    2017-05-05  23:23:42 INFO     Connections  vclient: connected to 127.0.0.1:3002
                    Wenn ich das richtig interpretiere kommt es zu einem Timeout verbindet aber gleich danach wieder mit vclient?

                    Hat jemand eine Idee?

                    Gruß Grisu

                    Kommentar


                      #11
                      Hallo,

                      deine Interpretation stimmt.

                      Ich habe inzwischen vcontrold und das Plugin auf github:
                      https://github.com/thelsing/viessmann und https://github.com/thelsing/vcontrold

                      Das Plugin dort funktioniert nur noch mit meiner vcontrold Version. Vcontrold kann auch über yaml mehrere Werte mit einer Anfrage liefern. Der Code im Plugin dafür ist mir abhanden gekommen.

                      Falls jemand was verbessern mag. Immer her damit

                      Kommentar


                        #12
                        Danke erstmal, werde ich die Tage mal ausprobieren!

                        Kommentar


                          #13
                          Hallo,
                          ich bin nach langer Zeit (viele andere Dinge am Haus waren zu tun) dazu gekommen deine Version auf einem Testsystem zu probieren.
                          Leider gibt es beim kompilieren einen Fehler:

                          PHP-Code:
                          gcc -DPACKAGE_NAME="vcontrol" -DPACKAGE_TARNAME="vcontrol" -DPACKAGE_VERSION="1.0" -DPACKAGE_STRING="vcontrol\ 1.0" -DPACKAGE_BUGREPORT="mschroether@gmx.de" -DPACKAGE_URL="" -DPACKAGE="vcontrol" -DVERSION="1.0" -DHAVE_SYS_TYPES_H=-DHAVE_SYS_STAT_H=-DHAVE_STDLIB_H=-DHAVE_STRING_H=-DHAVE_MEMORY_H=-DHAVE_STRINGS_H=-DHAVE_INTTYPES_H=-DHAVE_STDINT_H=-DHAVE_UNISTD_H=-DHAVE_ARPA_INET_H=-DHAVE_FCNTL_H=-DHAVE_NETDB_H=-DHAVE_STDINT_H=-DHAVE_STDLIB_H=-DHAVE_STRING_H=-DHAVE_SYS_IOCTL_H=-DHAVE_SYS_SOCKET_H=-DHAVE_SYS_TIME_H=-DHAVE_SYSLOG_H=-DHAVE_TERMIOS_H=-DHAVE_UNISTD_H=-DHAVE_SYS_TYPES_H=-DHAVE_SYS_IPC_H=-DHAVE_SYS_SEM_H=-Dvfork=fork -DRETSIGTYPE=void -I.   -I/usr/include/libxml2  --O2 --o vclient.o vclient.c
                          In file included from vclient
                          .c:25:0:
                          common.h:4:19fatal errorcstdlibDatei oder Verzeichnis nicht gefunden
                           
                          #include <cstdlib>
                                             
                          ^
                          compilation terminated.
                          Makefile:438: die Regel für Ziel „vclient.o“ scheiterte
                          make
                          : *** [vclient.oFehler 1 

                          Hast du eine Ahnung woran das liegen kann?

                          Kommentar


                            #14
                            Da ich mit Visual Studio entwickle, brauche ich das autotools-Zeug nicht. Daher ging es nicht.Ich habe es jetzt repariert.

                            Kommentar


                              #15
                              Hallo,

                              danke dir erst einmal für deine Bemühungen.
                              Leider scheitere ich an einer weiteren Hürde:
                              PHP-Code:
                              vcontrold.cpp:30:27fatal erroryaml-cpp/yaml.hDatei oder Verzeichnis nicht gefunden
                               
                              #include <yaml-cpp/yaml.h>
                                                         
                              ^
                              compilation terminated
                              ???

                              Kommentar

                              Lädt...
                              X