wie werte per python / raspberry über UDP senden?

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • c_future
    Smart Home'r
    • 25.08.2015
    • 36

    #1

    wie werte per python / raspberry über UDP senden?

    Hallo

    hätte jemand ein knappes howto für mich wie man einen beliebigen wert einer variable per udp an den miniserver sendet?

    hintergrund - gpio status in der visu anzeigen, da diese ein Relais-board steuern welches wiederum für die bewässerung verantwortlich ist (das alles funkt schon per webseite und buttons)

    vielen dank im voraus!
  • jdlwguard-loxone
    Smart Home'r
    • 10.11.2015
    • 53

    #2
    Hallo c_future,

    ich habe hier exemplarisch mal mein Python-Skript zum Auslesen eines Reedkontakts (zum Bestimmen des Gasverbrauchs).

    Ich hoffe du kannst die Teile erkennen die in deinem Skript zu ergänzen sind? Falls nicht, noch einmal melden.

    Code:
    #!/usr/bin/env python
    
    import RPi.GPIO as GPIO
    import time
    import socket
    
    # GPIO definieren
    REED_gas = 32
    UDP_IP = "192.168.188.xxx"
    UDP_PORT = 5054
    MESSAGE_on = "Kontakt_0"
    MESSAGE_off = "Kontakt_1"
    
    
    GPIO.setmode(GPIO.BOARD)
    GPIO.setwarnings(False)
    
    
    # definierten GPIO als Eingang setzen
    GPIO.setup(REED_gas, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    
    status_alt=1
    while True:
        status_aktuell = GPIO.input(REED_gas)
        # REEDKONTAKT geoeffnet
        if status_aktuell == 1:
           # print "Kontakt offen"
            sock = socket.socket(socket.AF_INET, # Internet
                         socket.SOCK_DGRAM) # UDP
            sock.sendto(MESSAGE_on, (UDP_IP, UDP_PORT))
    
    
            # REEDKONTAKT geschlossen
        elif status_aktuell==0:
            # print "Kontakt geschlossen"
            sock = socket.socket(socket.AF_INET, # Internet
                         socket.SOCK_DGRAM) # UDP
            sock.sendto(MESSAGE_off, (UDP_IP, UDP_PORT))
    
            if status_alt!=status_aktuell:
                status_alt=GPIO.input(REED_gas)
    
        time.sleep(1)
    GPIO.cleanup()

    Kommentar

    • romildo
      Lebende Foren Legende
      • 25.08.2015
      • 5141

      #3
      Hallo
      Hier noch ein Beipiel von mir, nur UDP bezogen:

      Da Du die Werte per python senden möchtest, gehe ich davon aus, dass da schon alles nötige auf dem Raspberry installiert ist.

      Beispiel:
      Schreib im Raspberry ein test.py mit folgendem Inhalt:

      #!/usr/bin/env python
      #coding: utf8

      import socket

      UDP_IP = "IP von Deinem MS"
      UDP_PORT = 1234
      MESSAGE = "Test=245.7"

      print "UDP target IP:", UDP_IP
      print "UDP target port:", UDP_PORT
      print "message:", MESSAGE

      sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
      In Loxone legst Du einen Virtuellen UDP Eingang an.
      In die Senderadresse kommt die IP Adresse von Deinem Raspberry.
      Im UDP Empfangsport kommt 1234 (Kann natürlich auch ein anderer sein, muss halt der gleiche sein wie im Python)

      Under dem Virtuellen UDP Eingang legst Du einen Virtuellen UDP Eingang Befehl an.
      Als Befehlserkennung schreibst Du: Test=\v (somit wird bei einem UDP-Empfang nach dem Text "Test=" gesucht und der Wert dahinter, also 245 angezeigt)


      Das wars auch schon.

      Raspberry
      sudo python test.py
      sollte nun "Test=245.7" senden
      Zur Kontrolle dienen die print Zeilen in test.py
      UDP target IP: xxx.xxx.xxx.xxx
      UDP target port: 1234
      message: Test=245.7

      Loxone
      Im UDP Monitor von Loxone sollte dies dann angezeigt werden, sofern dieser vorher schon eingeschaltet war.
      Wenn der Virtuelle UDP Eingang Befehl visualisiert wird, sollte dort jetzt die Zahl 245.7 zu sehen sein.
      An den Eingang kann natürlich auch was angeschlossen werden, so zum Beispiel ein Virtueller Status.


      Edit: Ich war da scheinbar wieder einmal zu langsam
      Zuletzt geändert von romildo; 31.05.2016, 20:49.
      lg Romildo

      Kommentar

      • MarcusS
        LoxBus Spammer
        • 25.08.2015
        • 389

        #4
        und hier die Kurzvariante:

        Code:
        #!/usr/bin/env python
        # -*- coding: utf-8 -*-
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.sendto("? #50 ?", ("192.168.2.100", 7000))

        Ip ist der Miniserver. Dort legt man einen Eingangsverbinder an.


        Zuletzt geändert von MarcusS; 31.05.2016, 21:41.
        DoorPi DIY Türsprechstelle how to

        Kommentar

        • bdaenzer
          Smart Home'r
          • 28.08.2015
          • 92

          #5
          Hallo,
          ich habe für mich eine etwas mächtigere lösung im einsatz... und zwar hab ich eine bidirektionale multithreaded struktur in meinen skripts. der vorteil ist, dass das sehr stabil und zuverlässig läuft, auch wenn z.B. mal eine aktion etc... etwas länger dauert.

          Code:
          #!/usr/bin/python
          
          # script to process and transmit udp packets from [XXXPI] to loxone
          # running on a raspberry pi
          
          # by bernhard@daenzer.net
          # feel free to reuse the code
          
          # standard library modules used in code
          import sys
          import time
          import datetime
          import argparse
          import socket
          from Queue import Queue
          import threading
          import SocketServer
          
          import RPi.GPIO as GPIO
          
          print 'script starting'
          
          BUTTON = 22 # GPIO
          GPIO.setmode(GPIO.BCM)
          #Alerts OFF
          GPIO.setwarnings(False)
          GPIO.setup(BUTTON, GPIO.IN)
          
          
          # set script basedir
          basedir = "/home/pi/"
          
          # set up parser with command summary
          parser = argparse.ArgumentParser(
                  description='udp gateway')
          # set up arguments with associated help and defaults
          parser.add_argument('-s',
              dest='lox_ip',
              help='lox IP address',
              default='192.168.1.2')
          parser.add_argument('-u',
              dest='lox_port',
              help='lox UDP port',
              default='7777')
          parser.add_argument('-d',
              dest='debug',
              help='debug 1 or 0',
              default='0')
          
          
          # process the arguments
          args=parser.parse_args()
          
          # turn the arguments into numbers
          
          debug=int(args.debug)
          lox_ip=str(args.lox_ip)
          
          #
          #for testing only, using the tool "Packet Sender" www.packetsender.com on laptop for debugging, comment out on live pi
          #
          #lox_ip='192.168.1.10'
          #
          #
          #
          
          lox_port=int(args.lox_port)
          
          remoteHost = lox_ip
          remotePort = lox_port
          
          # tell the user what is happening if script is run in terminal/debug
          if debug == 1:
              print "script initializing...",
              print "UDP Destination"
              print "  IP: "+str(lox_ip)
              print "  Port: "+str(lox_port),
          
          
          # open the udp socket
          s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
          
          # Set some options to make it multicast-friendly
          s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
          
          try:
              s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
          except AttributeError:
              pass # Some systems don't support SO_REUSEPORT
          
          s_udp.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
          s_udp.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
          
          # Set some more multicast options
          intf = socket.gethostbyname(socket.gethostname())
          s_udp.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf))
          
          
          
          #function that is called from code to trigger a message to lox
          def s2l(s_msg):
              #add to lox udp output queue
              #do any format conversions here
              q_out.put(s_msg)
              return True
          
          
          #new multhithread function that only handles the UDP msg queue outbound to loxone
          def s2l_worker(q_out):
              while True:
                  try:
                      if q_out.empty() == False:
                          s_msg = q_out.get()
                          #output s_msg over the loxone socket
                          s_udp.sendto(s_msg, (lox_ip, int(lox_port)))
                          time.sleep(0.01)
                          q_out.task_done()
                  except:
                          #except KeyboardInterrupt:
                          exit
          
          
          #start lox outbound queue out worker thread
          q_out = Queue(maxsize=0)
          script2lox = threading.Thread(target=s2l_worker, args=(q_out,))
          script2lox.setDaemon(True)
          script2lox.start()
          
          
          #init variables of global scope
          init=1
          q_l_p = Queue(maxsize=0)
          
          #new multhithread function that only processes the inbound messages from loxone
          def procl_worker(q_l_p):
          
                  while True:
                      try:
                          Lox_data = q_l_p.get()
                      except Empty:
                          Lox_data = ''
          
                      if Lox_data:
                          if debug ==1:
                              print "procl_worker Lox_data: "+str(Lox_data)
                              l2s(Lox_data)
          
                          Lox_data = ""
                          q_l_p.task_done()
          
          
          #start processing from loxone
          proclox = threading.Thread(target=procl_worker, args=(q_l_p,))
          proclox.setDaemon(True)
          proclox.start()
          
          #new multhithread function that only handles the udp inbound message reception from loxone
          def recl_worker(q_l_in):
          
                     buf_size = 1024
          
                     # Create the socket
                     s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          
                     # Set some options to make it multicast-friendly
                     s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                     try:
                             s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
                     except AttributeError:
                             pass # Some systems don't support SO_REUSEPORT
                     s2.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
                     s2.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
          
                     # Bind to the port
                     s2.bind(('', lox_port))
          
                     # Set some more multicast options
                     intf = socket.gethostbyname(socket.gethostname())
                     s2.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf))
          
                     while True:
                          try:
                              L_data, L_sender_addr = s2.recvfrom(buf_size)
                              if L_data:
                                  q_l_p.put(L_data)
                          except:
                              exit
          
                     # Receive the data, then unregister multicast receive membership, then close the port
                     s2.close()
          
          
          #start reception handler thread from loxone
          q_l_in = Queue(maxsize=0)
          reclox = threading.Thread(target=recl_worker, args=(q_l_in,))
          reclox.setDaemon(True)
          reclox.start()
          
          
          
          #main program
          
          #function that is called upon gpio interrupt
          def system_action(BUTTON):
              print('Button press = negative edge detected on channel %s'%BUTTON)
              button_press_timer = 0
              while True:
                      if (GPIO.input(BUTTON) == False) : # while button is still pressed down
                          button_press_timer += 1 # keep counting until button is released
                      else: # button is released, figure out for how long
                          if (button_press_timer > 5) : # pressed for > 5 seconds
                              print "long press > 5", button_press_timer
                              #sample output to lox
                              s2l("BUTTON LONG PRESS"
                          elif (button_press_timer > 1) : # press for > 1 < 5 seconds
                              print "short press > 1 < 5", button_press_timer
                              #sample output to lox
                              s2l("BUTTON SHORT PRESS"
          
                          button_press_timer = 0
                      sleep(1) # 1 sec delay so we can count seconds
          
          
          # setup the thread, detect a falling edge on gpio "BUTTON" and debounce it with 200mSec
          GPIO.add_event_detect(BUTTON, GPIO.FALLING, callback=system_action, bouncetime=200)
          
          # assume this is the main code...
          try:
              while True:
                  # do whatever
                  # while "waiting" for falling edge on BUTTON
                  sleep (2)
          
          except KeyboardInterrupt:
              GPIO.cleanup()       # clean up GPIO on CTRL+C exit
          GPIO.cleanup()           # clean up GPIO on normal exit

          Kommentar

          • ilikevista
            Smart Home'r
            • 14.10.2015
            • 77

            #6
            Hier ein von mir eingesetztes Script, das auf einem Raspberry Pi mit Musicbox ermöglicht, die Lautstärke und den Track zu wechseln, evtl hilft es ja jemandem weiter.

            Es werden hier aber nur Werte vom Miniserver auf Port 9900 empfangen.
            Senden ist aber nicht schwierig, hab ich mit Code-Beispielen aus dem Internet auch schon geschafft

            LG
            Stefan

            Ps zum starten, die Endung in .py ändern (das Forum nimmt keine .py Dateien an)
            Angehängte Dateien

            Kommentar

            • c_future
              Smart Home'r
              • 25.08.2015
              • 36

              #7
              vielen dank an alle..

              hab nie was in python gemacht. aber hat nur ne knappe stunde gedauert in summe:

              6 gpio zustände auslesen und an den miniserver senden, klappt wunderbar.


              Code:
              [B]#!/usr/bin/env python[/B]
              
              [B]#coding: utf8[/B]
              
              
              [B]import RPi.GPIO as GPIO[/B]
              
              [B]import socket[/B]
              
              
              
              [B]GPIO.setwarnings(False)[/B]
              
              [B]GPIO.setmode(GPIO.BCM)[/B]
              
              [B]GPIO.setup(17,GPIO.OUT)[/B]
              
              [B]GPIO.setup(27,GPIO.OUT)[/B]
              
              [B]GPIO.setup(22,GPIO.OUT)[/B]
              
              [B]GPIO.setup(23,GPIO.OUT)[/B]
              
              [B]GPIO.setup(24,GPIO.OUT)[/B]
              
              [B]GPIO.setup(25,GPIO.OUT)[/B]
              
              
              
              [B]status17=GPIO.input(17)[/B]
              
              [B]status27=GPIO.input(27)[/B]
              
              [B]status22=GPIO.input(22)[/B]
              
              [B]status23=GPIO.input(23)[/B]
              
              [B]status24=GPIO.input(24)[/B]
              
              [B]status25=GPIO.input(25)[/B]
              
              
              [B]UDP_IP = "192.168.0.50"[/B]
              
              [B]UDP_PORT = 7007[/B]
              
              [B]MESSAGE17 = "gpio17=%s" % status17[/B]
              
              [B]MESSAGE27 = "gpio27=%s" % status27[/B]
              
              [B]MESSAGE22 = "gpio22=%s" % status22[/B]
              
              [B]MESSAGE23 = "gpio23=%s" % status23[/B]
              
              [B]MESSAGE24 = "gpio24=%s" % status24[/B]
              
              [B]MESSAGE25 = "gpio25=%s" % status25[/B]
              
              
              [B]print "UDP target IP:", UDP_IP[/B]
              
              [B]print "UDP target port:", UDP_PORT[/B]
              
              [B]print "message:", MESSAGE17[/B]
              
              [B]print "message:", MESSAGE27[/B]
              
              [B]print "message:", MESSAGE22[/B]
              
              [B]print "message:", MESSAGE23[/B]
              
              [B]print "message:", MESSAGE24[/B]
              
              [B]print "message:", MESSAGE25[/B]
              
              
              [B]sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)[/B]
              
              [B]sock.sendto(MESSAGE17, (UDP_IP, UDP_PORT))[/B]
              
              [B]sock.sendto(MESSAGE27, (UDP_IP, UDP_PORT))[/B]
              
              [B]sock.sendto(MESSAGE22, (UDP_IP, UDP_PORT))[/B]
              
              [B]sock.sendto(MESSAGE23, (UDP_IP, UDP_PORT))[/B]
              
              [B]sock.sendto(MESSAGE24, (UDP_IP, UDP_PORT))[/B]
              
              [B]sock.sendto(MESSAGE25, (UDP_IP, UDP_PORT))[/B]

              Kommentar

              • onename
                Dumb Home'r
                • 08.11.2015
                • 27

                #8
                Hallo zusammen

                Möchte bei diesem Thema noch um eine Erweiterung nachfragen.
                Ich habe auf dem Loxberry MPC installiert inkl. Webradio. Für die Senderauswahl schicke ich jeweils PHP-Skripte ans Loxberry. Ich würde nun gerne die aktuelle Lautstärke von MPC (wie der Zustand der GPIO, das funktioniert bei mir) per UDP (Oder wenn es eine bessere Methode gibt?) an den MS senden. Habe im Netz bereits danch gesucht, bin aber nicht fündig geworden. Kann mit hier jemand auf die Sprünge helfen, wie ich das erledigen kann?

                Besten Dank für eure Hilfe.

                Beste Grüsse

                onename

                Kommentar

                Lädt...