sleep(), time.sleep, oder ganz was anderes?

  • Sehr geehrte Damen und Herren,
    Servus,


    Mein Problem ist folgendes:
    Ich spreche einen MCP23017 über I2C an.
    Dieser wiederum schaltet eine Relaisplatte mit 16 Relais.
    Diese schalten dann die Rollo meines Hauses (naja, eigentlich noch nicht, aber ich bin kurz davor :-)


    Das ganze läuft folgendermaßen,
    Ich erhalte eine html Seite auf meinem Handy wenn ich eine meinen Apache2 auf dem Raspberry anfordere.
    auf dieser Seite kann ich auswählen welche Rollo fahren sollen.
    Dieses html-Skript sendet dann die entsprechenden mit Häckchen versehenen variablen an ein php-Skript.
    Das php-Skript wertet diese aus und beschreibt den MCP23017 mit den entsprechenden 1en und 0en.


    Nun dauert es eine weile bis die Rollo runtergefahren sind. ca. 20s


    soweit würde es funktionieren.


    Aber ich würde gerne die Rollo/Relais nach dieser Zeit wieder auf "nicht geschaltet" setzen und während der Rollofahrt auch noch die fahrt unterbrechen können, falls z.B. ein Gegenstand im weg ist.


    Also sleep() scheidet daher aus, weil der Browser dann keine Befehle mehr annimmt.


    Kann ich das php skript irgendwie so gestalten, dass eine Zeit abläuft in der die Rollo fahren und gleichzeitig über die html-Seite einen Stop schicken?
    Das wäre dann die Lösung meines Problems.


    Ich hatte es schon mit Shell_exec("/var.../pytonprogramm.py")
    und dann im pythonprogramm über


    #!/usr/bin/env python

    import thread
    import time
    import os


    time.sleep(5)


    os.system ("sudo i2cset -y 1 0x20 0x00 0xFF")
    os.system ("sudo i2cset -y 1 0x20 0x01 0xFF")



    versucht, aber das führt PHP wohl nicht aus.
    Im Shell über Putty funktioniert das Pythonprogramm einwandfrei.
    Aber eben nicht über das PHP-skript.


    Danke


    Gruß Ben

  • So ein MischMasch mit PHP und Python würde ich vermeiden.
    Da man mit Python die umfangreichsten Möglichkeiten hat, sowohl GPIO als auch I2C anzusprechen, würde ich PHP und apache2 komplett weg lassen und stattdessen Python verwenden.


    Davon abgesehen, siehst du es schon richtig. Solange PHP beschäftigt ist kannst du es nicht unterbrechen. PHP unterstützt auch kein Threading, wird hierbei aber eigentlich auch nicht gebraucht - wie gesagt macht PHP die Sache nur unnötig kompliziert da damit die Möglichkeiten ziemlich eingeschränkt sind.
    Du beachtest dabei aber auch nicht dass das Python Script durch den www-data Benutzer ausgeführt wird und der darf standardmäßig kein sudo verwenden... FAQ => Nützliche Links / Linksammlung => Befehle über PHP mit root Rechten ausführen (sudo webscript)



    Mach es lieber ohne PHP und apache2: FAQ => Nützliche Links / Linksammlung => [Python] Webserver, Websocket und ein bisschen AJAX
    Ein Beispiel damit findest du zB auch hier: https://github.com/meigrafd/Sa…aster/_bottle/Alarmanlage


  • Da man mit Python die umfangreichsten Möglichkeiten hat, sowohl GPIO als auch I2C anzusprechen, ...


    ... eine der geilsten und dämlichsten Aussagen, die ich je gelesen habe... :D


    Quetsch mal mit Python (Interpreter) einen 8/16 Bit Wert an GPIO''s die als Ausgang geschaltet sind...
    Du hast das 1. Bit evtl. grade draussen... ich bin fertig...
    Also hör auf so nen Unsinn zu reden.


    Python mag für den Anfänger ok sein... schnelle aha Erlebnisse.. aber das war's dann...

    Edited once, last by root ().


  • Ich finde deine Ausdrucksweise in letzter Zeit ziemlich daneben, das ginge auch freundlicher.
    Meine Aussage war übrigens "die umfangreichsten Möglichkeiten", nicht "die schnellste".. Aber das ist dir offensichtlich egal.
    Und das Du kein Python magst ist bekannt, aber kein Grund es bei jeder Gelegenheit runter zu machen, das hilft (insbesondere hier) niemandem, oder kannst du anstatt nur zu meckern dem TE/TO auch eine bessere Alternative zu PHP nennen? :-/


    So ein Verhalten deinerseits ist echt schade, aber naja das Du leider ständig Sachen suchst um gegen mich zu wettern ist hier jedem bekannt - aus dem Kontext gerissen kann man jedes Wort irgendwie ins lächerliche ziehen.



    Ich bin dann raus hier, :danke_ATDE: root!


  • ...Du leider ständig Sachen suchst um gegen mich zu wettern ist hier auch jedem bekannt - aus dem Kontext gerissen kann man jedes Wort irgendwie ins lächerliche ziehen.


    ... ich suche gar nichts ... ich will dass solche dämlichen Aussagen nicht als bare Münze genommen werden
    ...fertig, aus, basta... hast ein logisches Gegenargument ?... es gibt keines :baeh2:
    End of Discussion...


  • ... ich suche gar nichts ... ich will dass solche dämlichen Aussagen nicht als bare Münze genommen werden
    ...fertig, aus, basta... hast ein logisches Gegenargument ?... es gibt keines :baeh2:
    End of Discussion...


    logisches Gegenargument ? => Meine Aussage war übrigens "die umfangreichsten Möglichkeiten", nicht "die schnellste".. Aber das ist dir offensichtlich egal.


    End of Discussion.

  • ot : on
    hey jungs !!
    letzten endes sind wir hier um zusammen zu einem ergebnis zu kommen und nicht um uns zu streiten !
    jeder einzelne von uns hat seine stärken und schwächen !
    lasst die stärken lieber ma bündeln anstatt uns anzufeinden !
    ich lese gerne hier da ich viele ideen klasse finde !
    begrabt den kriegsstuhl - damit ist jedem schneller geholfen !
    ot : aus

  • Guten Morgen Freunde der Sonne,
    da freut man sich auf 6 Antworten und dann sowas - schade.
    Aber danke an meigrafd für die Antwort.


    Ich frage mich wieso ich über PHP Shell-Befehle ausführen kann aber keine Programme starten kann.
    Wenn ich das im Browser aufrufe funktioniert das einwandfrei.
    zum Beispiel meine Datei - Stop.php:
    <?php


    exec("i2cset -y 1 0x20 0x00 0xFF");
    exec("i2cset -y 1 0x20 0x01 0xFF");


    header("Location:RolloRaffstore.html");


    ?>


    Fazit, ich brauche um Programme zu starten sudo und um shell Befehle auszuführen brauche ich kein sudo?


    ich müßte nur das obige Programm etwas zeitverzögert ausführen, das wäre es schon.
    Da muss es doch was geben? Von mir aus auch total umständlich.
    Wenn ihr meine Programmierung sehen würdet, würdet ihr wahrscheinlich sowieso zusammenbrechen vor lachen :blush: - Aber das ist ein anders Thema.


    Ich muss im php nur etwas starten, dass dann 20 Sekunden wartet und dann die obigen shell befehle sendet und ausführt.
    Also ein Progamm startet, und dass ich während dessen meinen NotHalt ausführen kann.


    Jetzt hab ich es schon soweit geschafft und möchte nicht alles umschreiben bzw. neu programmieren.


    Danke.


  • Fazit, ich brauche um Programme zu starten sudo und um shell Befehle auszuführen brauche ich kein sudo?


    Nein. Das Problem ist das DU über php sudo verwendest, aber nicht jeder darf einfach so sudo nutzen. Was für ein Sinn hätte das auch.
    Lässt du sudo im php Script weg funktioniert es, nutzt du sudo funktioniert es nicht weil dann der Benutzer nach einem Password gefragt wird, diese Frage siehst du über deinen Browser aber nicht - ergo müsstest du den "www-data" Benutzer, über den der apache2 läuft, erst dazu berechtigen "sudo" ohne Password zu verwenden!
    Das ist nur die Erklärung wieso es über den Browser mit sudo nicht auf Anhieb funktioniert. Das bedeutet aber nicht das du sudo verwenden musst.


    Das ist auch im ersten Link beschrieben, den ich in Beitrag#2 nannte.



    ich müßte nur das obige Programm etwas zeitverzögert ausführen, das wäre es schon.
    Da muss es doch was geben? Von mir aus auch total umständlich.


    Ich muss im php nur etwas starten, dass dann 20 Sekunden wartet und dann die obigen shell befehle sendet und ausführt.
    Also ein Progamm startet, und dass ich während dessen meinen NotHalt ausführen kann.


    Dann probier es so:
    - Schick das Python Script in den Hintergrund sodass das PHP Script nicht blockiert wird.
    - Erzeuge optional vom PHP Script eine temporäre Datei in /tmp/ so von wegen "STOP".
    - Bevor das Python Script die Aktion durchführt prüfe auf diese temporäre Datei.
    - Lösche anschließend wieder die temporäre Datei.


    Alternativ erstellst du ein Python Script das permanent läuft und auf Befehle via Socket wartet, dein PHP Script sendet dann Befehle an eben dieses Python Script.

  • Servus de wadl,


    also jetz muss ich mich schon fast selber loben, ich sollte Progrmmierer werden :D


    Eine Zeile! und das ganze funktioniert wie am Schnürchen!


    Die Lösung ist:
    exec("sleep 20");

    exec("i2cset -y 1 0x20 0x00 0xFF");
    exec("i2cset -y 1 0x20 0x01 0xFF");


    dieser Text am Ende des PHP-Skripts bewirkt genau das was ich wollte.
    Relais bleiben für 20 Sekunden geschaltet und werden dann wieder auf
    AUS gesetzt (also beide Bänke des MCP23017 sind dann auf AUS)
    Ich kann sogar noch auf meiner html Seite den Stop Button bzw. NotHalt drücken - lässig oder?


    Danke und Bitteschön. :angel:


    Oder ist das schrott :denker: ? egal ich mach es jetz so... :bussi2:


    Grüße


  • Oder ist das schrott :denker: ?


    Das merkst du irgendwann hoffentlich selbst :fies:


    exec("sleep 20");
    wird nicht im Hintergrund ausgeführt, ergo wird für die Zeit bis der Befehl beendet wird das PHP Script blockiert.
    HTML ist davon unabhängig, wenn dein Button auf das selbe PHP Script zeigt wird nur eine weitere Instanz ausgeführt, das ursprüngliche bleibt aber für 20 sec blockiert.


    Ein Auto Motor dreht auch mit 7000 U/min, hält das aber nicht lange durch.


    Such dir lieber eine andere Lösung. Langsamer geht schneller.

  • Aber wenn ich eine Zeit ablaufen lassen möchte bis irgendwann wieder was passieren soll wird doch immer irgendwas blockiert oder?
    Ist doch immer irgendein sleep Befehl in irgendeinem Programmskript.
    Oder? Warum Ist das hier was anderes?


    Mein stop Button verweist auf ein separates PHP, das wird auch ausgeführt während das andere noch denn sleep Befehl abwartet..


    Leider versteh ich (noch) nicht warum das so schlecht ist.
    Ist der raspi dabei dann so ausgelastet?


    Wenn ja macht das nichts, da die Rollo nur maximal 4 vielleicht 5 mal wenn überhaupt nach oben oder nach unten fahren. Also insgesamt ca. 100 Sekunden


    Also ein paar mal im roten Bereich bei 7000U/min ist auch beim Auto in Ordnung.


    Ein Python Programm das ständig im Hintergrund läuft würde vielleicht sogar mehr Auslastung verursachen -aber ich hab keine Ahnung sonst wär ich nicht hier...


    Vielleicht schau ich mal irgendwann nach einer professionelleren Programierlösung aber vorerst wird es wohl so bleiben. Ich bin zufrieden :^^:

  • Mit Auslastung des Pi's hat das nichts zu tun.


    Du hast dann PHP Scripts die beide von einander nichts wissen.
    Führst du erst "an.php" aus, wartest die 20 Sekunden aber nicht ab, sondern führst direkt danach "aus.php" aus, was passiert dann? Erst schaltest du "aus" aber nach ~20s gehts plötzlich wieder an.


    Das exec("sleep 20"); ist nichts anderes als ein direkter "sleep(20);" nativ in PHP zu setzen.



    In Beitrag#9 stehen 2 Möglichkeiten, wieso du aber nur die letzte beachtest weißt nur du? :s


    Möglichkeit #1 aus Beitrag#9:


    an.php
    [code=php]
    <?php
    exec("/usr/bin/python /var/www/html/rollo_runter.py 20 &");
    ?>
    [/php]


    /var/www/html/rollo_runter.py
    [code=php]
    import os
    import sys
    from time import sleep


    sleep(sys.argv[1])


    if os.path.exists("/tmp/STOP"):
    os.remove("/tmp/STOP")
    sys.exit()


    os.system("i2cset -y 1 0x20 0x00 0xFF")
    os.system("i2cset -y 1 0x20 0x01 0xFF")
    [/php]


    aus.php
    [code=php]
    <?php
    touch("/tmp/STOP");
    ?>
    [/php]


    Das Python Script zum runterfahren des Rollos wird in den Hintergrund geschickt und blockiert nicht das PHP-Script. Beim ausführen wird die sleep-time mit übergeben.
    aus.php erzeugt unabhängig davon eine temporäre Datei /tmp/STOP
    Bevor das Python-Script tatsächlich in Aktion tritt prüft es auf Existenz der /tmp/STOP Datei, falls vorhanden macht es nichts bzw löscht die Datei und beendet sich..



    Ich hab keine Ahnung ob das so 1:1 von dir übernommen werden kann damit es funktioniert, da ich kein blassen Dunst deines gesamten Konstrukts habe! Du musst das also zwangsweise für Deine Bedürfnisse anpassen oder was auch immer.



    //EDIT: Alternativ:


    /var/www/html/rollo_runter.py
    [code=php]
    import os
    import sys
    from time import sleep


    os.system("....einschalten....")


    c=0
    while c < sys.argv[1]:
    if os.path.exists("/tmp/STOP"):
    os.remove("/tmp/STOP")
    break
    c+=1
    sleep(1)


    os.system("....ausschalten....")


    #EOF
    [/php]