Lautsprecher-System für Durchsagen

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Hallo ihr lieben,


    ich habe eins zwei Hürden bei meinem Projekt zu nehmen.


    Projekt:

    Mit mehreren Relais lassen sich verschiede Lautsprecher-Zonen ansteuern (z.B. Theater, Bar, Pool, Gym, Aussenbereich....)

    Dieses Funktioniert auch sehr gut mit unserem Durchsagesystem für Live-Durchsagen.

    Nun möchte ich aber gewisse Sounds, Lieder, aufgenommene Durchsagen in den Bereichen spielen.


    Meine Idee: Ein Pi ist an der Lautsprecheranlage angeschlossen, spielt über Klinke die Signale und schaltet mit GPIO die Relais damit die Lautsprecheranlage weiß, das was der PI jetzt spielt soll im z.B. Theater laufen.


    An der Rezeption und in meinem Technikerraum soll ein weitere PI stehen mit einem Touchscreen wo ich dann z.B. einfach auf "Durchsage Theater öffnet" drücke. Dann soll der PI an der Lautsprecheranlage z.B. GPIO 5,7,9 & 18 ansteuern, die *.wav Datei abspielen und danach die GPIOs wieder ausschalten.


    Ich habe auf dem PI an der LS-Anlage den OMXPLAYER-PI installiert und kann auch über SSH die Sounds abspielen oder eine BASH ausführen. Ich würde halt gerne die BASH so schreiben, das die GPIOs gesteuert werden, dann die OMSPLAYER auspielt und danach die GPIOs zurück gesetzt werden.


    Probleme macht mir der PI mit dem Touchscreen. Hier wollte ich mit Phyton was schreiben, was mir die GUI und Buttons anzeigt (soweit bin ich noch nicht) und dann über "paramiko" eine SSH-Verbindung aufbaut und die dem endsprechende BASH an dem PI der Lautsprecheranlage ausführt.

    Die Paramiko Verbindung steht auch. exec_command wie "sudo reboot" führt er aus aber wenn ich z.B. die BASH starten möchte oder einfach den OMXPLAYER (omxplayer-pi /home/pi/Music/xxx.wav) wird dieses nicht aufgeführt. Per Putty und Konsole läuft es aber.





    import paramiko

    import time


    ssh = paramiko.SSHClient()

    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    ssh.connect('192.168.76.59', port=22, username='pi', password='meinpasswort')


    time.sleep(5)

    print('connected')

    stdin, stdout, stderr = ssh.exec_command("bash /home/pi/2klang.sh")



    als exec_command geht "sudo reboot". den führt er aus aber halt sachen wie "omxplayer-pi /home/pi/Music/blablabla.wav" oder "bash /home/pi/2klang.sh" nicht.



    Kann mir jemand sagen wo mein Fehler ist?


    Danke im Vorraus

  • Hallo Bennetr,


    nein es gibt leider keine Ausgabe.


    Ich bin absoluter Anfänger und habe mein Wissen aus Youtube-Videos, sobald ich weiß, was Codeblöcke sind werde ich diese benutzen :)



    Danke für deine Antwort.

  • Hallo DeFlou,


    willkommen im Forum! :)

    sobald ich weiß, was Codeblöcke sind werde ich diese benutzen :)

    Du klickst einfach hier im Foreneditor auf den Button für mehrzeiligen Code (pasted-from-clipboard.png) und kopierst dann Deinen Code in das Fensterchen ein, das sich dadurch geöffnet hat. ;)

  • Ganz einfach. An dem Pi, der die *.wav spielen soll ist zu Testzwecken ein Lautsprecher angeschlossen. Wenn ich über das Teminal mit SSH auf den Pi gehe und „bash 2klang.sh“ schreibe, spielt er den Ton. Über das Phyton-Skript nicht.


    Inhalt der 2klang.sh: „omxplayer-pi /home/pi/Music/2klangschnell.wav“

  • Problem gelöst!!!


    Ich arbeite nicht mehr mit dem omxplayer-pi sondern mit aplay

    Inhalt der 2klang.sh: „aplay /home/pi/Music/2klangschnell.wav“


    Es läuft.

    Nun muss ich mich an die GUI für den Touchscreen machen.

  • Mit einer kleinen Webanwendung ließe sich das einfacherer und sicherer entwickeln. Klar, SSH ist verschlüsselt, aber du führst dann darüber direkt Befehle auf dem Player aus. Besser ist es nur das zu können/dürfen, was man braucht.


    Falls genügend Python-Kentnisse vorhanden sind, würde ich FastAPI empfehlen. Wenn du aber am Anfang stehst, wird das sicherlich einige Fragen aufwerfen. Unter anderem werden bei FastAPI TypeHints zur Validation der Eingabe verwendet.


    In deinem Fall wäre das jetzt, mit Kanonen auf Spatzen schießen. Es ist kontraproduktiv, eine Sprache und Framework gleichzeitig zu lernen. Aber behalte mal im Hinterkopf, dass Webserver auch kein HTML ausliefern, sondern reine "Befehlsempfänger" sein können.

  • .... ein weiterer Tipp...


    Ich liebe node Red.

    Damit kannst Du recht einfach auf dem PI ein GUI gestalten.

    Und die GPIOs lassen

    Sich sehr einfach ansteuern.


    Ev. Würde sogar das Sound anspielen klappen.


    Ein weiterer Vorteil: Du benötigst nur 1 PI.


    Und Du könntest per mqtt oder http weitere Knöpfe zum steuern integrieren....

  • domipo Der Nachteil bei nur einem Pi ist, dass der nicht an den drei benötigten Orten gleichzeitig sein kann, also an der Lautsprecheranlage (1), im Technikerraum (2) und an der Rezeption (3). ?


    Falls im Technikerraum und an der Rezeption Geräte mit Webbrowser zur Verfügung stehen, würde das auch für eine Webanwendung sprechen die auf dem einen Pi an der Lautsprecheranlage läuft. Dann wären wir natürlich wieder bei einem Rahmenwerk, zum Beispiel Bottle oder Flask, und wenn das nicht so ganz statisch auf der Clientseite sein soll, käme dann noch JavaScript als Programmiersprache dazu. Und da vielleicht auch noch ein Rahmenwerk.

    😡 Host Europe hat alle meine Emojis gefressen! 😭

  • Ich hatte mal ein Projekt angefangen und dann aufgehört, da wir dann doch eine andere Lösung verfolgt haben.


    Jedenfalls hatte ich einen ESP32 mit einer SD-Karte bestückt, auf der sich Wav-Dateien befinden. Via I2S konnte ich dann Sound (44,1kHz/16Bit/Stereo) abspielen.


    Die Kommunikation habe ich via ESPNow realisiert. Der Grund war, dass wir keine existierende Infrastruktur (WLAN/Netzwerk) nutzen konnten, da dies nicht immer zur Verfügung stand.


    Dieses Konzept ermöglicht es eine oder mehrere Controller zu haben und mehrere Empfänger, die dann die Wav-Dateien abspielen. Kostengünstiger ist es auch, da einem die Controller hinterher geschmisen werden.


    Wenn man keine Lust hat zu löten, findet man auf AliExpress sicherlich auch Boards mit integriertem Audiochip via I2S.

    Wenn ich @home bin, kann ich hier mal den Code posten.

  • domipo Der Nachteil bei nur einem Pi ist, dass der nicht an den drei benötigten Orten gleichzeitig sein kann, also an der Lautsprecheranlage (1), im Technikerraum (2) und an der Rezeption (3). ?


    Falls im Technikerraum und an der Rezeption Geräte mit Webbrowser zur Verfügung stehen, würde das auch für eine Webanwendung sprechen die auf dem einen Pi an der Lautsprecheranlage läuft. Dann wären wir natürlich wieder bei einem Rahmenwerk, zum Beispiel Bottle oder Flask, und wenn das nicht so ganz statisch auf der Clientseite sein soll, käme dann noch JavaScript als Programmiersprache dazu. Und da vielleicht auch noch ein Rahmenwerk.

    Warum soll der PI denn an dreI Standorten sein ? Der PI muss doch nur die 3 Relais ansteuern.
    Wenn die 3 Relais an unterschiedlichen Standorten sein müssen, können alternativ auch SHELLY WiFi Relay eingesetzt werden.

  • domipo Der soll an drei Standorten sein weil das so im ersten Beitrag steht. Es geht hier nicht um 3 Relais, sondern um eine Lautsprecheranlage und zwei Orte von denen aus die steuerbar sein soll. Die Anzahl der Relais ist offen gelassen, aber die Aufzählung „(z.B. Theater, Bar, Pool, Gym, Aussenbereich....)“ lässt mehr als drei Lautsprecher-Zonen vermuten.

    😡 Host Europe hat alle meine Emojis gefressen! 😭

  • Player - ESP32


    Controler: https://www.amazon.de/gp/product/B071P98VTG (Affiliate-Link)

    I2S-Audio: https://www.amazon.de/gp/product/B09NXKPZ8N (Affiliate-Link)

    Firmware: https://micropython.org/download/

    SD-Slot: Adapter von MicroSD auf SD. Die Leitungen habe ich am Adapter direkt angelötet.

    Alternative: https://www.amazon.de/Adater-Storage-Breakout-Interface-Treibermodul/dp/B0B3RQZTXJ (Affiliate-Link)

    Es gibt aber auch Boards mit integriertem SD-Slot.



    Controller - ESP32

    Gleiche wie Player, nur ohne I2S. Soll lediglich via ESPNow dem Player start/pause/stop mitteilen.



    Code: Audio.7z

    Den Code habe ich mal einfach von beiden Controllern kopiert. Da ich nicht viel getestet habe, sind sicherlich noch ein paar Fehler drin. Jedenfalls kann ich damit WAV-Dateien abspielen, die sich auf der SD-Karte befinden. Den Einschaltsound habe ich von Black Mesa verwendet, ist aber nicht mit im Archiv.

  • domipo Der soll an drei Standorten sein weil das so im ersten Beitrag steht. Es geht hier nicht um 3 Relais, sondern um eine Lautsprecheranlage und zwei Orte von denen aus die steuerbar sein soll. Die Anzahl der Relais ist offen gelassen, aber die Aufzählung „(z.B. Theater, Bar, Pool, Gym, Aussenbereich....)“ lässt mehr als drei Lautsprecher-Zonen vermuten.


    ...

    Projekt:

    Mit mehreren Relais lassen sich verschiede Lautsprecher-Zonen ansteuern (z.B. Theater, Bar, Pool, Gym, Aussenbereich....)

    Dieses Funktioniert auch sehr gut mit unserem Durchsagesystem für Live-Durchsagen.

    Nun möchte ich aber gewisse Sounds, Lieder, aufgenommene Durchsagen in den Bereichen spielen.


    Wenn ich das richtig verstehe, gibt es schon eine bestehende Anlage, welche modifiziert werden soll. Statt der Relais könnte man bestimmt auch elektronische Schalter ( IC's zum Schalten / Umschalten von NF Signalen ) verwenden. Es kommt halt immer auf die Gegebenheiten vor Ort an bzw. ob man so eine Schaltung vor oder hinter einem Verstärker einbauen will.


    Edit:

    Ein weiterer Aspekt, der RPi hat ja ( falls vorhanden ) nur einen Audioausgang, das würde dann bedeuten, dass direkte Ansagen in einen bestimmten Bereich nur hintereinander bzw. an alle gemeinsam erfolgen können, oder soll der RPi noch mit weiteren USB Soundkarten erweitert werden?

  • DeaD_EyE Leider bin ich mit noch in meinen Anfängen. Aber eine Webanwendung wäre eine sexy Lösung. Ob verschlüsselt oder nicht ist in meinem Fall egal, da es eh nur in meinem Techniker-Netzwerk funkt.


    domipo Danke für den Hinweiß. Node Red habe ich nicht auf dem Zettel. In der Tat suche ich noch ein Programm mit den ich mir einfach eine GUI basteln kann.


    __blackjack__ Klingt gut, nur bei mir gibt es halt das Problem, dass ich mit dem programmieren der Sache kaum Ahnung habe.


    Fliegenhals Es ist ein Lautsprecher System vorhanden:


    Das Audiosignal von dem RPi wird im Technikraum ein eine AudioMatrix angeschlosen (Ein Audioweg). Mit den GPIO Kontakten im Audiomatrix-System kann ich dann sagen, wenn z.B. GPI1 geschaltet wird, sendet es das Audio vom Pi ins Theater. Wenn GPI 2, 3 & 4 geschaltet werden läuft das Audio an die Bar, Restaurant und Pool. Es wird also nur ein Pi mit einem Audioausgang als Auspieler benötigt. Auf den anderen PIs soll ich halt die gespeicherte Durchsage auslösen können.

    Ich arbeite aktuell mit paramiko und guizero. Wenn ich z.B. an der Rezeption einen Knopf drücke, sendet er einen Befehl an den RPi an der Lautsprecheranlage der dann dort eine Bash ausführt.


    Ablaufbeispiel bei Gewitter:

    Die Rezeption drückt einen Knopf auf dem Touch und im Technikraum führt der RPi an der LS Anlage folgendes aus:

    1. GPIO 4 wird geschaltet - „Die AudioMatrix des Hauses schaltet den PI Audioeingang auf die Pool Lautsprecher“

    2. Der RPi spielt die *.wav ab

    3. GPIO 4 wird zurück gesetzt.


    Das funktioniert auch alles Wunderbar.

    Allerdings muss ich vorher in Bash auf dem Auspiel RPi festlegen, wo die *.wav zu hören sein soll, da in der Bash ja auch die Zonen (GPIOs) geschaltet werden. Ich würde aber gerne bei einigen Signalen selbst auf dem Touchscreen an der Rezeption bestimmen können, wo es zu hören sein wird. Dafür habe ich noch keine Lösung.


    Beispiel: Ich möchte jetzt einen Gong auflösen im Restautant. Irgendwann später möchte ich einen Gong auslösen an der Bar und am Pool.

    Ich würde halt gerne auf dem Touch alle meine Zonen (GPIOs) anwählen können und dann den Gong.wav auslösen.

    Also ich drücke auf Bar danach auf Pool, sehe das ich sie ausgewählt habe und dann auf Gong. Dann soll der GPIO für Bar und Pool gesetzt werden, die Wav soll laufen und danach die GPIOS wieder zurückgesetzt werden.

    Dafür habe ich noch keine Lösung, weder im Programmier Weg noch in der GUI Gestaltung.


    Ist es möglich, wenn ich ein Mikrofon am PI anschließe auch damit eine Durchsage zu tätigen?

    Beispiel Rezeption:

    1. Ich drücke und halte einen Hardware-Knopf der eine Mikroaufnahme startet und sie beim loslassen beendet.

    2. Ich höre mir über einen kleine Lautsprecher am RPI die Durchsage an wenn ich es möchte.

    3. Ich wähle meinen Zonen aus und starte meine Aufnahme, sie läuft.


    Es reicht ja wenn die Aufnahme immer in die selbe Datei geschrieben wird. (durchsage.wav). Dann kann ich sie ja wie oben den Gong abspielen. Also Zone vorauswählen und dann abspielen. Ich kann die Datei auf dem vorhanden NAS ablegen oder vielleicht gibt es eine Möglichkeit, das sie direkt an den Pi an der LautsprecherMatrix gesendet wird.



    Zusätzlich realisiere ich grade noch einen zweiten RPi für das Theater. Dort zeigen wir ab und zu Filme auf der Leinwand. Mein Gedanke ist nun einen weiteren RPi im Theater zu verbauen, der den Beamer mit dem Film per HDMI bespielt.

    Ich schalte auf dem Touchscreen das „Kino“ ein.


    Ablaufbeispiel Kino an:

    1. Ein GPIO am Pi wird gesetzt und schaltet an der AudioMatrix, diese schaltet nun die Backgroundmusik im Theater ein.

    2. Ein weiterer GPIO am Pi schaltet ein kurzen Impuls der dem Lichtpult sagt, mache Einlasslicht an.

    3. Über „snap7“ wird in Python ein Befehl an die Siemens Logo geschickt. Diese steuert die Beamer-Leinwand.

    4. (Noch keine Lösung gefunden, aber auch noch nicht aktiv gesucht) Unser Beamer den ich über das Netzwerk erreiche schaltet sich ein.


    Ablaufbeispiel „Ich wähle ein Film aus:

    1. Der GPIO der der AudioMatrix sagt sie soll Backgroundmusik spielen wird zurückgesetzt. Die Backgroundmusik geht aus. Ein andere GPIO wird gesetzt und schaltet nun den Ton vom RPI auf die Anlage im Theater.

    2. Ein GPIO sagt per Impuls dem Lichtpult das sich das Licht abdunkeln soll.

    3. Der Film startet.


    Ablaufbeispiel „Film ist zuende:

    1. GPIO der den RPI Ton über die AudioMatrix auf die Theater Anlage lässt setzt sich zurück. Der RPI Sound ist nicht mehr auf der Anlage.

    2. GPIO vom Pi ans Lichtpult schaltet das Saallicht wieder an.

    3. snap7 sagt der Siemens Logo sie soll die Leinwand hochfahren.

    4. (Noch keine Lösung gefunden, aber auch noch nicht aktiv gesucht) Unser Beamer den ich über das Netzwerk erreiche schaltet sich aus.



    So, das ist erstmal viel neues. Ich schick hier einfach mal mein jetziges Python Skript rein.



    import paramiko

    import os
    import time
    from guizero import App, Text, Box, PushButton


    screenheight = 400
    screenwidth =800


    gridheight=int(screenheight/(2*20))
    gridwidth=int(screenwidth/(3*10))


    # Funktion zum SSH starten von Bash Datein auf Pi Lautsprecher
    def do_nothing(audio):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('192.168.1.11', port=22, username='pi', password='xxx')
    print('connected')
    stdin, stdout, stderr = ssh.exec_command('bash ' + audio)
    return 0


    # Funktion zum SSH starten von Bash Datein auf Pi Kino
    def do_nothing1(audio):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('192.168.178.12', port=22, username='pi', password='xxx')
    print('connected')
    stdin, stdout, stderr = ssh.exec_command('bash ' + audio)
    return 0



    # Box 1 Theater Durchsagen
    def theater():
    global box1h, box2h, box3h, box4h, box5h, button1, text
    box5h.hide()
    box4h.hide()
    box3h.hide()
    box2h.hide()
    box1h.show()
    text = Text(app, width=40, height=1, color="black", text="Theater-Durchsagen", grid=[0,0])


    # Box 2 RobyClub
    def robyclub():
    global box1h, box2h, box3h, box4h, box5h, button1,text
    box1h.hide()
    box2h.show()
    box3h.hide()
    box4h.hide()
    box5h.hide()
    text = Text(app, width=40, height=1, color="red", text="RobyClub Lieder", grid=[0,0])


    # Box 3 Kino Main
    def kinomain():
    global box1h, box2h, box3h, box4h, box5h, button1,text
    box1h.hide()
    box2h.hide()
    box3h.show()
    box4h.hide()
    box5h.hide()
    text = Text(app, width=40, height=1, color="red", text="Kino-System", grid=[0,0])


    # Box 4 Kino Filme
    def kinofilm():
    global box1h, box2h, box3h, box4h, box5h, button1,text
    box1h.hide()
    box2h.hide()
    box3h.hide()
    box4h.show()
    box5h.hide()
    text = Text(app, width=40, height=1, color="red", text="Kino-Filmstart", grid=[0,0])


    # Box 5 Kino Filme
    def haus():
    global box1h, box2h, box3h, box4h, box5h, button1,text
    box1h.hide()
    box2h.hide()
    box3h.hide()
    box4h.hide()
    box5h.show()
    text = Text(app, width=40, height=1, color="red", text="Haus-Signale", grid=[0,0])



    # Festerüberschrift
    app = App(title="Media System", height=screenheight, width=screenwidth, layout="grid")





    # Text Überschrift Box 1
    text = Text(app, width=40, height=1, color="black", text="Theater-Durchsagen", grid=[0,0])


    # setup box1h for Theater-Durchsagen with all it's buttons
    box1h = Box(app, layout="grid", grid=[0,1])


    # top buttons to change half
    buttonfirst1 = PushButton(box1h, command=theater, text="Theater-Durchsagen", grid=[0,0])
    buttonsecond1 = PushButton(box1h, command=robyclub, text="RobyClub Lieder", grid=[1,0])
    buttondritte1 = PushButton(box1h, command=kinomain, text="Kino-System", grid=[2,0])
    buttonvierte1 = PushButton(box1h, command=haus, text="Haus-Signale", grid=[3,0])


    # individual buttons for each sound effect. button1 before each one to show it's a first half button
    button11 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/videotest.sh"], text="Theater öffnet", grid=[0,2])
    button12 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing1, args=["/home/pi/soundtest.sh"], text="Theater startet gleich", grid=[1,2])
    button13 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Right.wav"], text="Keine Getränke Dorfpl.Bar.Rest.Eng.", grid=[2,2])
    button14 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Left.wav"], text="Showstart", grid=[0,3])
    button15 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Center.wav"], text="Theater schließt", grid=[1,3])
    button16 = PushButton(box1h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="Keine Getränke / Theater", grid=[2,3])


    # setup box2h for RobyClub with all it's buttons
    box2h = Box(app, layout="grid", grid=[0,1])
    # hides it immedatelly as first half buttons will be shown first.
    box2h.hide()
    # top buttons to change half
    buttonfirst = PushButton(box2h, command=theater, text="Theater-Durchsagen", grid=[0,0])
    buttonsecond = PushButton(box2h, command=robyclub, text="Robyclub Lieder", grid=[1,0])
    buttondritte1 = PushButton(box2h, command=kinomain, text="Kino-System", grid=[2,0])
    buttonvierte1 = PushButton(box2h, command=haus, text="Haus-Signale", grid=[3,0])
    # individual buttons for each sound effect. button2 before each one to show it's a second half button
    button21 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Noise.wav"], text="RobyTanz", grid=[0,2])
    button22 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Center.wav"], text="Kinderessen - Leckerschmecker", grid=[1,2])
    #button23 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Right.wav"], text="Second Half 2 ", grid=[2,2])
    #button24 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Left.wav"], text="Second Half 4", grid=[0,3])
    #button25 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Center.wav"], text="5", grid=[1,3])
    #button26 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="6", grid=[2,3])


    # setup box3h for Kino-System with all it's buttons
    box3h = Box(app, layout="grid", grid=[0,1])
    # hides it immedatelly as first half buttons will be shown first.
    box3h.hide()
    # top buttons to change half
    buttonfirst = PushButton(box3h, command=theater, text="Theater-Durchsagen", grid=[0,0])
    buttonsecond = PushButton(box3h, command=robyclub, text="Robyclub Lieder", grid=[1,0])
    buttondritte1 = PushButton(box3h, command=kinofilm, text="Kino-Filme", grid=[2,0])
    buttonvierte1 = PushButton(box3h, command=haus, text="Haus-Signale", grid=[3,0])
    # individual buttons for each sound effect. button2 before each one to show it's a second half button
    button21 = PushButton(box3h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Noise.wav"], text="Kino Einschalten", grid=[0,2])
    button22 = PushButton(box3h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Center.wav"], text="Kino Ausschalten", grid=[1,2])
    button23 = PushButton(box3h, height=gridheight, width=gridwidth, command=kinofilm, text="Filme", grid=[2,2])
    #button24 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Left.wav"], text="Second Half 4", grid=[0,3])
    #button25 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Center.wav"], text="5", grid=[1,3])
    #button26 = PushButton(box2h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="6", grid=[2,3])


    # setup box4h for Kino-Filme with all it's buttons
    box4h = Box(app, layout="grid", grid=[0,1])
    # hides it immedatelly as first half buttons will be shown first.
    box4h.hide()
    # top buttons to change half
    buttonfirst = PushButton(box4h, command=theater, text="Theater-Durchsagen", grid=[0,0])
    buttonsecond = PushButton(box4h, command=robyclub, text="Robyclub Lieder", grid=[1,0])
    buttondritte1 = PushButton(box4h, command=kinomain, text="Kino-System", grid=[2,0])
    buttonvierte1 = PushButton(box4h, command=haus, text="Haus-Signale", grid=[3,0])
    # individual buttons for each sound effect. button2 before each one to show it's a second half button
    button21 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Coco.sh"], text="Coco", grid=[0,2])
    button22 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Center.wav"], text="Film 2", grid=[1,2])
    button23 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Right.wav"], text="Film 3", grid=[2,2])
    button24 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Left.wav"], text="Film 4", grid=[0,3])
    button25 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Center.wav"], text="Film 5", grid=[1,3])
    button26 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="Film 6", grid=[2,3])



    # setup box5h for Haus-Signale with all it's buttons
    box5h = Box(app, layout="grid", grid=[0,1])
    # hides it immedatelly as first half buttons will be shown first.
    box5h.hide()
    # top buttons to change half
    buttonfirst = PushButton(box5h, command=theater, text="Theater-Durchsagen", grid=[0,0])
    buttonsecond = PushButton(box5h, command=robyclub, text="Robyclub Lieder", grid=[1,0])
    buttondritte1 = PushButton(box5h, command=kinomain, text="Kino-System", grid=[2,0])
    buttonvierte1 = PushButton(box5h, command=haus, text="Haus-Signale", grid=[3,0])
    # individual buttons for each sound effect. button2 before each one to show it's a second half button
    button21 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Noise.wav"], text="Unwetter Aussenpool", grid=[0,2])
    button22 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Center.wav"], text="Pool schließt 5min", grid=[1,2])
    button23 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Front_Right.wav"], text="Pool schließt", grid=[2,2])
    button24 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Left.wav"], text="Restautant schließt 15min", grid=[3,2])
    button25 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Center.wav"], text="Restaurant schließt", grid=[0,3])
    button26 = PushButton(box5h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="JeKaMi auf Dorfplatz (Bar)", grid=[1,3])
    #button27 = PushButton(box4h, height=gridheight, width=gridwidth, command=do_nothing, args=["/home/pi/Music/Rear_Right.wav"], text="Gong Pool", grid=[1,3])



    # this I think acutally runs the GUIZero app thing
    app.display()

  • DeFlou Da Einrückung bei Python wichtig ist, muss man Quelltexte hier im Forum als Code setzen. Das ist die Schaltfläche mit der Beschriftung „</>“ im Beitragseditor.


    Was an dem Quelltext als erstes auffällt ist das da ganz viel mehrfach kopiert und leicht angepasst wurde. Das macht man als Programmierer nicht, genau dafür sind ja Programmiersprachen da, um Wiederholungen nicht tatsächlich immer wieder hinschreiben zu müssen und mehrere ähnliche Sachen *einmal* verallgemeinern kann.


    `os` und `time` werden importiert, aber nirgends verwendet.


    Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.


    Konstantennamen werden KOMPLETT_GROSS geschrieben. Das mit den Fenstergrössen und Inhaltsgrössen in absoluten Pixeln funktioniert so nicht. Das ist abhängig von Displaygrösse, -auflösung, und -einstellungen. Das sieht bei mir beispielsweise so aus:



    Die Fenstergrösse ergibt sich automatisch aus dem Inhalt. Ebenso die Grösse von enthaltenen GUI-Elementen. Ein gleichmässiges Grid-Layout erreicht man mit `rowconfigure()` und `columnconfigure()` und der `uniform`-Option. Dafür muss man nicht nur von `guizero` auf `tkinter` runtergehen, sondern auch die Tk-Dokumentation lesen, denn `uniform` ist soweit ich weiss für `tkinter` nirgends dokumentiert.


    Wo `guizero` auch nicht ausreicht, ist so etwas wie ein `ttk.Notebook` was Du hier effektiv selbst zu implementieren scheinst, mit komischen Mitteln (`hide()`/`show()`) und falsch, weil die Überschrift bei jedem wechseln neu erstellt wird, und so immer mehr und mehr Widgets in der einen Gridzelle übereinander gestapelt werden. So etwas macht man absichtlich *einmal* und holt dann das was angezeigt werden soll immer nach vorne. Wenn man sich so etwas wie `ttk.Notebook` selbst bastelt, statt das fertige zu nehmen. Bei der Überschrift würde man aber nur *ein* Label erstellen und dann bei Änderungen den Text davon ändern, statt immer neue Label-Objekte zu erstellen.


    Den aktuell aktiven Bereich würde man auch eher nicht durch eine Wiederholung eines Button-Texts in einer Überschrift kennzeichnen, sondern in dem man den Button selbst entsprechend hervorhebt. Oder ”eindrückt”, so dass das kein Taster ist sondern ein Schalter der “einrastet“. In `tkinter` kann man das mit Radiobuttons lösen, die man auch als normale Buttons anzeigen lassen kann, die entsprechend ”einrasten”.


    Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Der Name soll dem Leser vermitteln was der Wert dahinter im Programm bedeutet, nicht zum rätseln zwingen.


    Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste.


    Funktions- und Methodennamen werden üblicherweise nacht der Tätigkeit benannt die sie durchführen. Damit der Leser weiss was sie machen und um sie von eher passiven Werten unterscheiden zu können. `theater`, `kinofilm`, `haus` und so weiter sind keine Tätigkeiten. `do_nothing()` ist da an sich besser, ausser natürlich, dass es inhaltlich nicht stimmt. Die Funktion tut ja etwas. Der Funktionsname sollte verraten was das ist.


    `do_nothing()` und `do_nothing1()` unterscheiden sich nur durch einen Wert (die IP) innerhalb des Codes. Das sind also keine zwei Funktionen, sondern *eine* Funktion, welche diesen Wert als Argument übergeben bekommt.


    `audio` ist hier Dateiname, aber so funktioniert das ja nicht, denn die Bash kann ja keine WAV-Dateien ausführen. Der Code kann so also nicht gelaufen sein.


    Verbindungen die man öffnet, sollte man auch wieder schliessen. `SSHClient` ist ein Kontextmanager, kann dafür also mit ``with`` verwendet werden.


    Rückgabewerte die man nicht verwendet, braucht man auch nicht an Namen binden.


    Und man sollte auch selbst keine sinnlosen Rückgabewerte liefern. Das ``return 0`` macht keinen Sinn, weil die Funktion dann *immer* 0 zurückgibt, und der Aufrufer damit auch überhaupt gar nichts anfängt.


    ``global`` bitte gleich wieder vergessen. Alles was eine Funktion oder Methode ausser Konstanten benötigt, wird als Argument(e) überbegen. Das bedeutet bei jeder nicht-trivialen GUI, dass man objektorientierte Programmierung (OOP) können muss. Also eigene Klassen schreiben kann.


    Letztlich ist das Programm hier ein Codegerüst um Daten, die eigentlich in einer Datenstruktur stecken sollten, mit ein bisschen Code der daraus dann eine GUI aufbaut.

    😡 Host Europe hat alle meine Emojis gefressen! 😭

  • __blackjack__ Danke für dein Feedback und die Hinweise. Das ist ein gefundenes Python-Projekt aus dem Netz, was ich angepasst habe. Ich habe paramiko importiert, do_nothing auf paramiko angepasst und do_nighting1 erstellt. Einige Buttons sollen die Sounds auf dem PI der Anlage spielen und die Film-Buttons sollen einen zweiten Pi ansteuern der die Filme auf den Beamer spielt. Es werden Bash Dateien auf z.B. dem Anlagen PI ausgeführt. In der Bash steht dann ein mplayer Befehl der den Sound dort abspielt.


    Mittlerweile habe ich mir node-red angeschaut und denke das ich mich eher damit auseinandersetzen werde.

  • Node-red gefällt mir sehr gut. Nun wollte ich das Paket speakerpi installieren damit mein RPI Sounddateien abspielen kann, geht aber nicht. Habe bei der Installation nur Error Meldungen. Und wenn ich per exec Bautstein ein Befehl sende (DISPLAY=:0 mplayer -fs /home/pi/Videos/202260.mp4) spielt er das Video zwar ab, aber ohne Ton. Wenn ich den Befehl per SSH Verbindung eingebe, läuft es mit Ton. Genau wie bei diesem Befehl (mplayer /home/pi/Music/2klang.mp3). Über SSH läuft es, mit dem exec Baustein aber nicht. wodran kann das liegen?