Reboot / Shutdown PI & Reboot Windows Rechner

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo

    ich habe an meinem PI zwei Taster.
    Nun möchte ich gerne dadrüber

    Taster 1: Reboot
    Taster 2: Herunterfahren
    Taster 1&2: Neustart Windows Rechner über Netzwerk
    ([font="monospace"]net rpc shutdown -I ip.address -U user%password)[/font]

    [font="monospace"]http://www.howtogeek.com/109655/how-to-…rt-windows-pcs/[/font]

    [font="monospace"]Evtl hat einer ein gutes Script, das ich mit anpassen kann.[/font]

    [font="monospace"]Gruß[/font]

  • Hallo noxx,

    Man könnte auch die Betätigungsdauer der Taster auswerten z.B. Taster 1s gedrückt -> Reboot, bei 3s -> Shutdown.

    genau Dein Anliegen habe ich im Febraur 2014 auf diese Weise umgesetzt. Die Hardware (Taster, Widerstand) habe ich bei den meisten RPi in dieser Form installiert und die Software läuft über Autostart im Hintergrund.

    Kurzes Drücken => Reboot
    Langes Drücken => Herunterfahren

    Hier der Link...

    Solltest Du Dich für diesen Ansatz entscheiden, dann bedenke bitte, dass die dort angegebene Library zwar funktioniert, aber dass es einen Thread mit einer aktuelleren Version gibt.


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    2 Mal editiert, zuletzt von Andreas (16. Oktober 2017 um 23:21)

  • Dein Anliegen hat eher weniger mit der GPIO Hardware zu tun sondern viel mehr mit Software. Daher ist der Bereich leider falsch...

    In welcher Programmiersprache du das umsetzen willst hast du leider auch nicht erwähnt :huh:


    Fliegenhals: Dann müsste die bouncetime aber auch sehr hoch gesetzt werden wegen Schalterprellen oder habe ich da nen Denkfehler? :-/

    Ja, leider ein Denkfehler ;)

    Man kann problemlos ein Taster mit mehreren Funktionen je nach "Drückdauer" umsetzen.. Dazu brauch man nur eine Zeit und einen Timeout. Für einen Taster aber 3 Zeiträume festzulegen wird schwierig bzw schon möglich aber ohne visuelle Bestätigung wie lange man den Taster schon gedrückt hält kommt das eher einem Glücksspiel gleich :fies:

    Zunächst sollte man wissen das ein Interrupt basiertes Script besser ist als eins mit ner while Schleife.. Warum ist relativ einfach: Weniger CPU Auslastung, genauer, einfacher.
    Dann sollte man wissen das in der Interrupt_Callback nichts wildes gemacht werden sollte, da sonst diese wichtige Funktion derweil blockiert wird und in der Zeitspanne kein weiterer ISR erfasst werden kann.
    Und dann sollte man noch wissen das die Callback in einem separaten Thread läuft... Also das Script ist ein Thread, dort können Dinge abgehandelt werden, und die ISR Funktion ist davon abgekoppelt und quasi eigenständig.

    Auf dieser Grundlage erstellt man also ein Script um 2 Taster zu bedienen sowie eine Callback die bei einem Flankenwechsel nur den ausgelösten Pin sowie dessen Status in ein Queue ablegt. Dieses Queue verarbeitet man dann im Script-Thread.
    Die beiden Taster nenne ich mal switchPi und switchWin - so sollte eindeutig klar was sich dahinter verbirgt... Generell ist es super die Variablen vernünftig zu benennen ;)

    Normalerweise wird der Interrupt-Callback nur "channel" übergeben, also der GPIO-Pin der das Event ausgelöst hat. Wir müssen der Funktion aber auch das Queue zugänglich machen und die hierfür eleganteste Vorgehensweise ist mithilfe von partial direkt die Übergabe zu modifizieren:

    Python
    queue=Queue()
    GPIO.add_event_detect(switchPi, GPIO.BOTH, callback=partial(interrupt_Event, queue), bouncetime=150)
    GPIO.add_event_detect(switchWin, GPIO.BOTH, callback=partial(interrupt_Event, queue), bouncetime=150)

    Und die Callback Funktion sieht dann so aus:

    Python
    def interrupt_Event(q, channel):
        q.put( (channel, GPIO.input(channel)) )

    Sobald ein Flankenwechsel stattfindet - egal was für einer - wird ins Queue ein Eintrag in Form einer tuple vorgenommen... In diesem Fall der ausgelöste Channel und dessen Status, also zum Beispiel (17, 1). Die 1 steht für GPIO.HIGH bzw eigentlich andersherum aber egal ;)

    So, was brauchen wir jetzt noch?
    => Das Script muss das Queue abarbeiten
    Wie bereits erwähnt läuft die Interrupt_Callback im Hintergrund und trägt munter Dinge ins Queue ein. Parallel dazu können wir nun im Script ganz wilde Sachen anstellen und sozusagen unendlich viel Zeit verplempern, die ISR wird davon nicht beeinträchtigt.

    Um Einträge aus dem Queue auszulesen nutzt man queue.get() ... Dabei wartet dies solange bis etwas eingetragen wurde. Ruft man das also auf wird das Script solange blockiert bis etwas ins Queue eingetragen wurde... Für unseren Fall hier perfekt weil nichts anderes gemacht werden soll. Da wir aber nicht nur einmal sondern immer wieder Einträge verarbeiten wollen nutzen wir vorher eine while Schleife.

    Soweit so gut. Jetzt folgt der schwierige Teil :fies:

    Wir wissen was im Queue steht und wie es da drin steht. Wir speichern uns also queue.get() in eine Variable und holen uns dann jeweils aus dem tuple das Index 0 und 1, was ein mal der Pin wäre und das zweite dessen Status. In diesem Fall benenne ich's "job":

    Python
    job = queue.get()
    pin = job[0]
    state = job[1]

    Dann prüfen wir ob der Pin einer unserer gewünschten Taster switchPi oder switchWin entspricht sowie verarbeiten entsprechende Aktionen..

    Wir wollen:
    Wenn switchPi kürzer als 3 Sekunden gedrückt wurde ....
    Wenn switchPi länger als 3 Sekunden gedrückt wurde ....
    Wenn switchWin länger als 3 Sekunden gedrückt wurde ....
    ... etwas bestimmtes tun.

    Um das zu erreichen müssen wir uns also die Zeit merken wann das jeweilige Event eingetreten ist. Am einfachsten wären natürlich Sekunden und da liegt dann quasi der Unix-Timestamp auf der Hand - also die Sekunden die seit dem 1.1.1970 vergangen sind, was man in Python durch time.time() erhält.
    Wenn also switchPi eingetragen wurde und GPIO.HIGH gesetzt war, speichern wir uns die sog. triggerTime.
    Nachdem der Taster dann wieder losgelassen wurde, ein erneutes Interrupt_Event auslöst und somit GPIO.LOW setzt, rechnen wir die aktuellen Sekunden abzüglich triggerTime und erhalten dann die verstrichene Zeit, also wie lange der Taster gedrückt wurde.... Dann nur noch prüfen ob das mehr oder weniger 3 Sekunden ist, entsprechende Aktion ausführen und voilà thats it :cool:


    Bitte probier das erst mal selber aus und wenn dann Fragen sind bitte deinen Code deines Versuchs zeigen

  • Na, ich will heute mal nicht so sein..... Probiers mal damit => http://codepad.org/1Syh7Qd6
    Funktion ungeprüft


    //EDIT: Funktion geprüft => http://codepad.org/b5IkKMY2
    das eine print(pin, state) später im tatsächlichen Betrieb entfernen!

    Beachtet auch das 'bouncetime' ein Interrupt_Event unter den angegebenen Millisekunden unterdrückt, wird der Taster also schneller gedrückt bzw losgelassen wird ein Flankenwechsel nicht erfasst.

    • Offizieller Beitrag


    Taster 1 ist an GPIO 11 (Pin 23) und Ground (Pin 25)
    Taster 2 ist an GPIO 17 (Pin 09) und Ground (Pin 09)

    GPIO 17 wäre Pin 11. Pin 23 (GPIO11) hat eine Sonderfunktion und ist keine so gute Idee für einen normalen Taster, auch wenn meigrafd diesen in seinem Beispielscript genommen hat. Nimm besser einen normalen GPIO. z.B. Pin 12 (GPIO18), Pin 13 (GPIO27), Pin 15 (GPIO22), Pin 16 (GPIO23), Pin 18 (GPIO24)

    Woran siehst Du das die Taster nicht reagieren?

  • Welche GPIO's du einstellst und verwendest ist relativ egal.
    Einige GPIO's haben Sonderfunktionen die aber nur aktiv sind wenn die Sonderfunktion aktiviert wurde, meistens dann erst wenn das entsprechende Kernel Module geladen wurde bzw ein gewisser Eintrag in der config.txt vorgenommen wurde. Wenn er also kein SPI nutzt kann er die GPIO's auch als normale I/O's verwenden. Einzige Ausnahme: UART (GPIO14&15), die sind aktiv solange man sie nicht deaktiviert.

    Lies dir auch mal das durch: https://www.elektronik-kompendium.de/sites/raspberry-pi/2006051.htm

    Und wenn du sicherstellen willst das wirklich keine Reaktion kommt, dann fügst du einfach zwischen Zeile 31 und 32 ein print ein, damit du direkt nach dem auslesen des job's eine Testausgabe erhälst - also so von wegen print(pin, state) oder so

  • Hallo Hyle,


    GPIO 17 wäre Pin 11. Pin 23 (GPIO11) hat eine Sonderfunktion und ist keine so gute Idee für einen normalen Taster, auch wenn meigrafd diesen in seinem Beispielscript genommen hat. Nimm besser einen normalen GPIO. z.B. Pin 12 (GPIO18), Pin 13 (GPIO27), Pin 15 (GPIO22), Pin 16 (GPIO23), Pin 18 (GPIO24)

    Woran siehst Du das die Taster nicht reagieren?


    Gut beobachtet!
    Wie Du hier entnehmen kannst, ist jedem GPIO-Pin eine Alternativ-Funktionalität zugeordnet. Ob diese auch aktiv ist, hängt vom Bootvorgang (z.B. UART-Pins) und dem Laden von Zusatzmodulen ab.

    Der Normalfall ist der, dass die GPIO-Funktionalität aktiv ist. Wäre ein gegebener Pin nicht als GPIO erreichbar, dann würde eine Fehlemeldung daruf hinweisen.

    In der Tat muss noxx noch etwas mehr Info liefern, woran er erkennt, dass die GPIOs nicht auf die Taster reagieren. Kann eigentlich nur an der Verschaltung oder der Software liegen.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (16. Oktober 2017 um 23:20)

    • Offizieller Beitrag

    Oh, das kam wohl anders rüber als von mir gemeint. :s Ich wollte damit nur sagen, dass noxx sich den SPI-Pin für evtl. spätere Verwendung freihalten sollte. ;)
    Ich habe mich in letzter Zeit ausführlich mit der Funktionalität der GPIO auseinandersetzen müssen.

  • Ja gut, da war ich etwas unaufmerksam. :blush:

    Aber er kann ja jederzeit andere GPIO's im Script einstellen, entweder indem er es "hardcoded" im Code verändert
    [code=php]
    def main(switchPi=4, switchWin=17, specialTime=3):
    [/php]

    Oder indem er den Aufruf der main() Funktion anpasst:
    [code=php]
    if __name__ == "__main__":
    main(switchPi=4)
    [/php]
    Die anderen Werte könnte er auf die Weise auch ändern und solange kein Parameter bei Ausführung übergeben wird werden die defaults verwendet (die in der def Zeile festgelegt wurden)

  • hallo

    habe die GPIOs schon geändert.

    irgendwo ist der Wurm drin, muss das nachher mal genau prüfen.
    Werde dann mal die PINs mit nem Kabel überbrücken, nicht das ein Taster
    defekt ist.


    lptrvimt.jpg

    Einmal editiert, zuletzt von noxx (5. Februar 2017 um 13:48)

  • Wie hast du die Taster denn angeschlossen?

    Wenn ich zwei Kabel nehme und das eine Ende an Pin#1 sowie das andere an Pin#7 anschließe - wirklich verifizieren das Pin#1 und auf gar keinen Fall Pin#2 verwendet wird!! Pin#1 ist 3V3 , Pin#7 ist GPIO4
    ... und dann die Enden zusammenhalte, funktioniert es fast wie erwartet - ein kleiner Fehler ist noch drin aber es erfolgt trotzdem eine Ausgabe

    Die GPIO's sind nicht 5V tolerant! Wenn du auf einen GPIO mehr als 3V3 jagst schrottest du dir den Pi!


    //EDIT: Siehe noch mal Beitrag#10

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!