cron Uhrzeit überprüfen nach reboot


  • Hallo meigrafd,


    habe jetzt einiges ausprobiert. Dein regain.sh skript ( alles markiert und reinkopiert) wirft mir folgende Fehlermeldung aus:

    Code
    awk: line 1: syntax error at or near print
    awk: line 1: syntax error at or near print
    awk: line 1: syntax error at or near print
    awk: line 1: syntax error at or near print


    Liegt am awk-Aufruf im unteren Abschnitt. da ist Dir ein $-zeichen reingerutscht. Habe ich bei mir geändert. Soweit läufts jetzt. Habe Deine Versoin abgeänderte (wegen den GPIO-Nummern) die läuft irgendwie noch nicht rund... :mad_GREEN:


    Ahja Oke $print ... So hast du wenigstens auch was gemacht :D


    Hier ist mein gheändertes Skript (nur der Teil mit den GPIO-Definitionen ist anders, der Rest Original)


    Wat is dat denn für eine Verunstaltung des Scripts? :D


    Vielleicht kannt Du mal drüber scheuen ob das so passt, bzw. hast wieder eine tolle Idee was man da verbessern kann.


    Du kannst 'Relais' zu einem Array machen und somit wäre dass dann auch flexibler bzw cooler :fies: Bedarf nur 3 kleinen Anpassungen.


    Beispiel:


  • Hallo meigrafd,




    Wat is dat denn für eine Verunstaltung des Scripts? :D


    Hm wie Du sagtest " so hab ich auch etwas gemacht"... zumindest war ich mir sicher, daß es so funktioniert - zugegeben Deine Lösung mit dem Array ist cooler und schöner! Wenn man weiß, daß es diese Lösung gibt :bravo2: Ich bin ja am Lernen und glücklich, daß meine kleine Steuerung, Dank Deiner Hilfe, immer mehr zu dem wird was ich mir vorstelle :thumbs1:

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

  • So habe nun die 3 Tabellen erstellt.
    Administration über phpMyAdmin. User Pi angelegt mit Zugriffsrechten auf die Datenbank "aquariumsteuer".
    Weiter habe ich das bisherige relais.sh Skript angepasst:
    relaistest.sh:


    Die Statusabfrage in phpMyAdmin wie in meigrafd`s Beispiel:

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().


  • relaistest.sh:


    Nix gelernt? :D -> array


  • Erstmal vielen Dank Erleuchteter :angel:


    :bravo2:


    Quote from meigrafd


    Nix gelernt? :D -> array


    Stimmt irgendwie... Habe es probiert mit dem Array aber ich hab das Array nicht wirklich kapiert. Gebe es zu =( Ca. 2h lang habe ich probiert meine relais.sh mit dem Array umzuschreiben - scheitere aber an einer Idee wie ich also beim Aufruf:


    [/quote]


    Siehe Beitrag#18.


    Denkbar wären zum Beispiel 3 Tabellen: Typ, Status, Vorgang.
    - "Typ" besteht aus 2 Spalten: id und Bezeichnung. id ist fortlaufend eindeutig und Bezeichnung beinhaltet jeweils "Nachtlicht", "Tageslicht" usw
    - "Status" besteht aus 2 Spalten: id und Bezeichnung. Hier gäbe es nur 2 Einträge: id=1, Bezeichnung=An ... id=2, Bezeichnung=Aus
    - "Vorgang" besteht aus 3 Spalten: id, id_Typ, id_Status und Zeit. id ist fortlaufend eindeutig, id_Typ enthält die jeweilige id aus der "Typ" Tabelle ebenso wie id_Status und Zeit ist der Timestamp wann geschaltet wurde.


    Habe ich genau so umgesetzt. Aber es gibt in jeder Tabelle die Spalte id...


    Quote from meigrafd


    .. dann muss in der Tabelle 'Vorgang' die "id" von dem Typ hinterlegt sein


    genau hier steige ich aus :s - wie geht das? Also die "Hinterlegung der id in der Tabelle "Vorgang" aus der Tabelle "Typ"?
    SELECT'en wie hier:

    Quote from meigrafd


    Du willst "aus" schalten, also SELECT'est du "id" aus der Tabelle dessen Eintrag "Nachtlicht" enthält :fies:


    geht ja meiner Meinung nach hier nicht - oder doch???



    Das ist eine gute Idee werde mich daran probieren!



    By the way - nachdem ich eine 4.Tabelle mit Ein- und Ausschaltzeiten für die Überprüfung beim reboot und für die "UPDATES" erstellt habe


    Zum Beispiel:
    [code=php]
    - "Schalten" besteht aus 3 Spalten: id_Typ, Einschaltzeit und Ausschaltzeit und id_Typ aus der "Typ" Tabelle, /wenn ich sa mal überzuckert habe wie das geht).
    [/php]


    passt das so? Aber wie lese ich die Einschaltzeit und Ausschaltzeit mit crontable aus (Syntax)?


    Bitte nicht falsch verstehen - ich möchte es ja nicht als "drag and drop" haben. Aber mir fehlen die Denkansätze...
    Ich weiß ich bin anstregend... :rolleyes: Aber SQL, als Computer-Methusalem, im Schnelldurchlauf zu lernen ist nicht einfach... :s Hoffentlich kannst Du mir nochmals erklärend unter die Arme greifen... :danke_ATDE:
    Ich hoffe daher nochmals auf Deine :helpnew:

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • Zum Array:


    Bei der Übergabe an das Script wird das erste ans Script übergebene Argument in $1 hinterlegt. Du möchtest jetzt anhand der Zahl festlegen welcher GPIO dafür zuständig ist.
    Also wie kann man das hier:


    Stattdessen mit dem oben gezeigten Array anwenden?

    Code
    #format: Relais[<relais#>]=<gpio#>
    Relais["1"]=0
    Relais["2"]=2
    Relais["3"]=3
    Relais["4"]=12
    Relais["5"]=1


    Überlegung: Was entspricht dem was in $1 drin steht ? --> Das Index des Arrays, also das was in [ ] drin steht. $1 könnte zum Beispiel eine 1 sein oder eine 5. Das entspricht dann exakt dem Index des Arrays.


    Du kannst dann also ganz einfach folgendes machen:

    Code
    if [ $2 = "aus" ]; then
        Status="${Relais[$1]} 0"
    fi


    [hr]


    Zur Datenbank:


    Du hast 3 Tabellen: Typ, Status und Vorgang.
    Zum erstellen solch einer Tabelle hat man zB. folgendes verwendet:[code=php]CREATE TABLE Typ (id INT(11) NOT NULL AUTO_INCREMENT, Bezeichnung VARCHAR(255), PRIMARY KEY (id))[/php]


    Dort gibt man an das sich 'id' von selbst erhöht, pro Eintrag der gemacht wird. Also der erste INSERT erhält die id 1, der zweite INSERT kriegt die id 2 usw. Löscht man einen Eintrag und fügt einen neuen Hinzu kriegt der ebenfalls eine andere id fortlaufend - also ist id immer eindeutig (unique). Diese 'id' kann man also verwenden um einen eindeutigen Eintrag auszuwählen, einen anderen Eintrag mit dieser id wird es nie geben.


    Die Tabelle Status wird sich nie verändern, dort steht einfach nur "Aus" oder "An" drin. Zum Beispiel hätte dann "Aus" die id 1 und "An" die id 2.
    Bei Typ wird sich so schnell denk ich auch nichts ändern, da trägst du ein mal die Standorte die geschaltet werden sollen/können ein und belässt das dann vermutlich erst mal so. So hätte dann zB. Nachtlicht die id 1 usw.
    Bei der Vorgang Tabelle ändert sich dann natürlich ständig etwas da dass dann dein Log wäre. In dieser Tabelle stehen dann alle Schaltvorgänge drin und anhand dessen kannst du nach einem Reboot dann auch ermitteln wie der letzte Schaltvorgang aussah - du brauchst also nicht noch eine weitere Tabelle.


    Du gehst also wie gesagt wie folgt vor:

    • alle 3 Tabellen erzeugen
    • Status befüllen.
    • Typ in der Reihenfolge befüllen wie später die 'id' passend wäre, damit du beim bash Script mit $1 arbeiten kannst... Ansonsten müsstest du für id_Typ auch eine SQL Abfrage machen.

    Dann brauchst du eigentlich nur noch bei jedem Schaltvorgang erst die jeweils passende ID abfragen:
    [code=php]
    if [ $2 = "aus" ]; then
    Status="${Relais[$1]} 0"
    SQL="SELECT id FROM Status WHERE Bezeichnung='Aus'"
    id_Status=$(mysql --silent -D $mySQLdatabase --execute="$SQL;")
    id_Typ=$1
    fi
    [/php]


    Und gehst dann beim Schaltvorgang so vor das du ein INSERT mit den notwendigen Daten machst:


    [code=php]
    SQL="INSERT INTO Vorgang (id_Typ,id_Status,Zeit) VALUES (\"$id_Typ\",\"$id_Status\",\"$(date +%s)\");"
    mysql --silent -D $mySQLdatabase --execute="$SQL;"
    [/php]


    Wenn du nun nach einem Reboot die letzten Schaltvorgänge auslesen willst brauchst du dir nur den letzten Treffer der passenden id_Typ ausgeben lassen. Dazu holt man sich erst alle verfügbaren Typ's aus der Datenbank und fragt anschließend den jeweils letzten Eintrag aus der Vorgang Tabelle ab:


    [code=php]
    IFS='\n'
    while read Line; do
    LASTsql="SELECT Typ.Bezeichnung AS TypBezeichnung, Status.Bezeichnung AS StatusBezeichnung FROM Vorgang LEFT JOIN Typ ON Vorgang.id_Typ = Typ.id LEFT JOIN Status ON Vorgang.id_Status = Status.id "
    LASTsql+="WHERE id_Typ=$Line ORDER BY Zeit DESC LIMIT 0,1"
    LAST=$(mysql -s -D $mySQLdatabase -e "$LASTsql;")
    echo $LAST
    done < <(mysql --silent -D $mySQLdatabase --execute="SELECT id FROM Typ;")
    [/php]

  • Danke meigrafd. Wie immer ausführlich und sehr verständlich erklärt. :thumbs1:
    Das mit dem Array hab ich jetzt dank Dir gefressen




    Richtig habe ich alles so gemacht. Allerdings hatte ich durch Befüllen mit phpMyAdmin (Deine Befehle aus Beitrag#18 im Reiter SQl eingefügt) jeden Eintrag 4x. Ich habe dann händisch die jeweiligen 3 überflüssigen Einträge gelöscht und die Nummerierung händisch geändert. Beim nachträgliche eintregen eines neuen Eintrags ist mir aufgefallen, dass SQL gemeldet hat "Zeile 18 eingefügt". ALso werde ich die 3 Tabellen löschen und nochmals neu anlegen. Damit alles sauber vorhanden ist.


    Mit der Eindeutigkeit des Typs muß ich mir was überlegen - es gibt Steckdose 1-4 und Relais 1-8. Eventuell nutze ich SQL und mache 2 Einträge zusätzlich zu den 8 Relais die ich wieder lösche. Dann würden die USB Steckdosen die Nummern 11-14 erhalten - ist leicht zu merken :D und eindeutig (unique).




    Wenn du nun nach einem Reboot die letzten Schaltvorgänge auslesen willst brauchst du dir nur den letzten Treffer der passenden id_Typ ausgeben lassen. Dazu holt man sich erst alle verfügbaren Typ's aus der Datenbank und fragt anschließend den jeweils letzten Eintrag aus der Vorgang Tabelle ab


    OK leuchtet mir auch ein. Danke



    Bei der Vorgang Tabelle ändert sich dann natürlich ständig etwas da dass dann dein Log wäre. In dieser Tabelle stehen dann alle Schaltvorgänge drin und anhand dessen kannst du nach einem Reboot dann auch ermitteln wie der letzte Schaltvorgang aussah - du brauchst also nicht noch eine weitere Tabelle.


    Die 4. Tabelle war mein Gedanke wegen der BeiträgeBeiträge von Rasp-Berlin (#6) und dbv (#8). Aber Du bist ja der einzige der mir hier weiterhilft.
    [font="Times New Roman"]

    [/font]


    [font="Times New Roman"]Du hast eine Datenbank, in der der Status zu jeder Zeit enthalten ist.[/font]
    [font="Times New Roman"]Du hast dann nicht unterschiedliche Crontab-Einträge, die zu dieser, oder jeden Zeit, diese oder jene Steckdose schaltet, sondern einen,d er regelmäßig nach sieht (z.B. stündlich oder halbstündlich) was geschaltet sein sollte, und dieses dann durchführt.[/font]
    [font="Times New Roman"]So musst du, nach einem Neustart, nur nachsehen (lassen) was zum aktuellen Zeitpunkt an und aus sein sollte, und hast den Soll-Status schnell auf den Ist-Status abgebildet.[/font]
    [font="Times New Roman"]

    [/font]
    [font="Times New Roman"]

    [/font]


    [font="Times New Roman"]So siehst aus ;). stehen in den .sh scripten dann aufrufe zu Python scripten drin? [/font]
    [font="Times New Roman"]Edit: du kannst ihn auch jede Minute über die db laufen lassen undefined[/font]
    [font="Times New Roman"] [/font]
    [font="Times New Roman"]Edit2: Obwohl ich persönlich die Scripte zusammenfassen würde. Ich krieg bei den Dateinamen schon Knoten im Kopf ;). Sprich 1 Script für Steckdosen, eins für Releais[/font]
    [font="Times New Roman"]

    [/font]


    Eventuell verfolgen die Beiden eine andere Strategie als Du. Sollte das so sein, dann lasse ich, der Einfacheit halber, die Zeiten in der crontab. Wird eventuell etwas unübersichtlich und voll... und mit einer 4. Tabelle könnte ich eventuell einige Zeilen aus crontab entfernen.. ???
    Bei einer 4. Tabelle würde jede Änderung in dieser Tabelle erfolgen und wäre schön übersichtlich (nicht so durcheinander wie in der crontab).
    Daher meine Frage wie ich dann mit crontab diese Zeiten auslese, bzw. wie die Verbindung crontab mit dieser 4. Tabelle aussieht. Aber wie immer hab ich keinen blassen Schimmer wie das gehen könnte... :blush:

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • Da würde ich dann einen Blick in mein 'wecker' Script für cronbot werfen, das ist zwar in PHP aber ließe sich auch in bash umsetzen oder crontab führt halt nen php Script aus wär auch egal...


    http://www.forum-raspberrypi.de/Thread-php-wecker


    Und dann kannste natürlich auch eine Tabelle für die Schaltzeiten je Typ erstellen, sure ;)


    Die Möglichkeiten sind Unendlich :fies:

  • Ich wollte mal ein Update meiner Aktivitäten machen (falls es jemanden interessiert, bzw. falls jemand mal ein ähnliches Projekt angeht ist es vielleicht eine Anregung):


    Da ja in den Tabellen, wie von meigrafd vorgeschlagen, alles eindeutig sein muß, habe ich nun für alle Schaltvorgänge 1 Skript (mit Array :fies: ). Dank der vielen Hilfestellungen von meigrafd war das dann nicht mehr so schwer. :danke_ATDE:
    schalten.sh:



    Zur Erläuterung wie es dazu kam:
    - Path = ... benötigte ich da crontab mir das Array sonst nicht ausgeführt hat. Tante Google hat mir aber dabei geholfen den Fehler zu finden.
    - Alle Steckdosen werden über die Zahlen 1-4 angesteuert
    - Alle Relais werden über die Zahlen 11-18 angesteuert
    - Die Relais 16-18 sollen eine Dosierpumpe anschalten die nach Ablauf einer bestimmten Zeit (jeweils separat einstellbar über Timer) dann selbsständig ausschalten
    - Zusätzlich wird über einen crontab-Eintrag jede Dosierpumpe nach 2min nochmals ausgeschaltet (zusätzliche Sicherheit eingebaut) - schadet ja nicht.
    - Es gibt, zugegeben, eine Menge if-Schleifen aber durch die zusätzliche Verwendung der case-Schleifen wird es (für mich) übersichtlicher und damit steuere ich die verschiedenen von mir gewünschten Schaltvorgänge


    Ich weiß es gibt sicherlich eine Menge Möglichkeiten wie man das schöner oder sogar besser machen kann. Falls jemand einen Vorschlag hat - bitte posten. Aber mein Skript tut z. Zt. was es soll und das ist mir wichtig.


    Was folgt als nächstes?
    Nun da ich nur noch 1 Skript habe und alles eindeutig ist werde ich mich an die SQL-Geschichte machen. Die Ausgaben des Skripts in die SQL-Tabellen umschreiben und die Überprüfung der Schaltzustände nach reboot oder Stromausfall angehen.
    Den Vorschlag von meigrafd:


    finde ich sehr gut. Soweit ich mit der SQL-Geschichte soweit bin wird auch das, wohl in php, angegangen werden.

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • Habe bei meinem Update meiner Aktivitäten noch etwas vergessen (sorry aber das Alter...):


    Da ich leider kein Minimal System sauber installiert bekam startet mein Raspi B Rev.2 jetzt von SD und läuft dann auf einem USB-Stick. Auch im Standard-wheezy (Raspbian) - gefühlt sehr schnell. Zu diesem Schritt habe ich mich entschlossen nachdem ich das Tutorial von
    rafii6311 - Vom USB-Stick starten:

    http://www.forum-raspberrypi.d…ial-vom-usb-stick-starten


    gelesen habe.
    Zusätzlich zu dienem tutorial habe ich dann noch per Gparted die Boot-Partition auf eine kleine SD-Karte kopiert (meine Bootpartition ist gerade mal 56MB groß). Also reicht eine kleine 1GB, die ich rumliegen hatte, ganz leicht. Wer wissen will wie ich das gemacht habe liest sich Beitrag #6 im oben genannten Tut durch.
    Jetzt kann ich bei Problemen ganz schnell beide Datenträger mit hier rumliegenden Teilen wiederherstellen.
    Ich bin mit der Lösung mehr als zufrieden.


    Ein weiteres Projekt ist mir noch eingefallen:


    Wenn auf meinem PI dann alles drauf ist dann hätte ich gerne noch eine "Kommandozentrale" - wird dann auch in PHP erfolgen. Wo doch der Rest schon in PHP ist bietet sich das an.

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • So jetzt habe ich die 3 Tabellen neu gemacht + 1 zusätzlich die Tabelle Zeiten (in dieser sollen später die Schaltzeiten ein - aus zentral hinlegt werdensollen, ohne crontab-Einträge)
    Zur Verdeutlichung habe ich die 4 Tabellen in Excel angelegt und als Angang hierangehängt. Diese wurden genauso in MySQl angelegt und befüllt.
    Inspiriert durch:
    Idee wie in:


    http://www.forum-raspberrypi.d…-befehle-mit-php-absetzen
    Beitrag #6 (meigrafd)


    Habe ich auch mit PHP experimerntiert und viel nachgelesen. Mein Gedanke ist statt des schalten.sh skripts nun schalten.php aufzurufen in dem dann mit shell_exec das schalten.sh skript (zum eigentlichen Schaltvorgang) ausgeführt wird und der Schreibvorgang in die MySQl Tabellen dann php erledigt.
    Um wieder nur 1 Skript in PHP zu haben dachte ich geht wie in der Shell:

    Code
    php schalten.php 11 ein


    dann bekomme ich aber als Ergebnis:

    Code
    /home/pi/aquarium/sh/schalten.sh: Zeile 5: ((: >=1: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=1\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 25: ((: >=11: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=11\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 51: ((: >=16: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=16\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 86: ((: >=16: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=16\").


    Also gehe ich davon aus, daß PHP die $1 und $2 Variablen aus dem Aufruf nicht an die Shell weitergibt, bzw. diese nicht mitverarbeitet.
    Ein

    PHP
    #!/usr/bin/php
    <?php
            echo $n1;
    ?>


    Liefert als Ergebnis:

    Code
    PHP Notice:  Undefined variable: n1 in /home/pi/schalten2.php on line 3


    Bin ich also nun mit PHP auf dem Holzweg und ich lasse das schalten.sh Skript auch in die MySQL Tabelle "Vorgang" schreiben, weil es ja schon (bis auf das MySQL schreiben) fix fertig ist und funzt. Oder wie muß ich die "11" und "ein" sonst an das schalten.php Skript mitübergeben?


    Ich brauche also wieder mal :helpnew:


    :danke_ATDE: im Voraus.


  • Um wieder nur 1 Skript in PHP zu haben dachte ich geht wie in der Shell:

    Code
    php schalten.php 11 ein


    dann bekomme ich aber als Ergebnis:

    Code
    /home/pi/aquarium/sh/schalten.sh: Zeile 5: ((: >=1: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=1\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 25: ((: >=11: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=11\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 51: ((: >=16: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=16\").
    /home/pi/aquarium/sh/schalten.sh: Zeile 86: ((: >=16: Syntax Fehler: Operator erwartet. (Fehlerverursachendes Zeichen ist \">=16\").


    Bash mag es nicht wenn kein Leerzeichen zwischen dem Operator und dem Vergleichswert ist. Du musst also anstatt ">=1" das machen: ">= 1"



    Also gehe ich davon aus, daß PHP die $1 und $2 Variablen aus dem Aufruf nicht an die Shell weitergibt, bzw. diese nicht mitverarbeitet.
    Ein

    PHP
    #!/usr/bin/php
    <?php
            echo $n1;
    ?>


    Liefert als Ergebnis:

    Code
    PHP Notice:  Undefined variable: n1 in /home/pi/schalten2.php on line 3


    Ja weil die Variable $n1 nirgends definiert wurde ;)


    Wenn du an eine PHP Datei beim ausführen ein Argument übergibst musst du dies auch erfassen und verarbeiten. Das geht ähnlich wie in Python mithilfe von argv:


    [code=php]
    <?php
    echo $argv[1];
    ?>
    [/php]


    Warum du jetzt aber aus einer PHP Datei ein bash script nutzt um dann wieder PHP auszuführen, versteh ich nicht :s Mach das doch alles direkt in PHP. Dann könntest du in dem Script auch Funktionen definieren, dieses "schalten.php" dann in deiner Seite include'n und direkt die Funktionen ausführen, ohne exec(); bzw das kannst du dann in der schalten.php nutzen ;)

  • :danke_ATDE:
    Und wieder unglaublich schnell geholfen der meigrafd! Super - vielen Dank für die ausführliche Erklärung. Man sucht sich per Google teilweise einen Wolf! Vor allem wenn man nicht weiß wonach man genau suchen soll. Aber ich hab den Wink mit dem Zaunpfahl verstanden! :D
    Jetzt weiß ich, daß ich es komplett in PHP machen muß :^^:



    Warum du jetzt aber aus einer PHP Datei ein bash script nutzt um dann wieder PHP auszuführen, versteh ich nicht :s Mach das doch alles direkt in PHP. Dann könntest du in dem Script auch Funktionen definieren, dieses "schalten.php" dann in deiner Seite include'n und direkt die Funktionen ausführen, ohne exec(); bzw das kannst du dann in der schalten.php nutzen ;)


    Ehrlich gesagt: weil ich, wie man hier sagt: ein PHP-Nackerbazi (null Ahnung), bin. Mein schalten.sh läuft wie ein Uhrwerk. Darum wollte ich es mir einfach machen und das Skript über PHP ausführen. Ich werde versuchen das schalten.sh auf PHP zu übertragen. Mal sehen ob ich das hinbekomme...

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

  • Also mein Skript /var/www/schalten.php:

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • EDIT: Hier stand Quatsch daher Beitrag geändert:
    Habe jetzt meine benötigten Daten aus der SQL Tabelle als Array vorliegen:
    [code=php]
    printf("id=%s Start_h=%s Start_min=%s id_Typ=%s
    ",$rows['id'],$rows['start_h'],$rows['start_min'],$rows['id_Typ']); // Ausgabe Daten
    [/php]
    Hänge nun beim Schreiben in Datei
    Output soll sein:
    [code=php]
    $rows['start_min'];$rows['start_h'];*;*;*;/usr/bin/php;/var/www/schalten.php;$rows['id_Typ'];ein
    [/php]
    Statt ; brauche ich aber ein "Leerzeichen".
    mit fwrite bekomme ich die Fehlermeldung - zuviele Argumente:
    [code=php]
    $daten = "$rows['start_min'];$rows['start_h'];*;*;*;/usr/bin/php;/var/www/schalten.php;$rows['id_Typ'];ein";
    $dateihandle = fopen("$filename","w");
    fwrite($dateihandle, $daten);
    [/php]


    Ich hoffe es kann mir jemand helfen.

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • Anscheinend ist explode die Lösung, wie bei meigrafd`s Weckerskript.
    Aber ich verstehe die Synthax dazu nicht - bekomme es nicht hin!

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

  • Hallo meigrafd - auf Dich hatte ich als Helfer gehofft!
    Ja so ähnlich geht`s mir auch: :D


    Kannst du bitte noch mal einen ausführlichen Zwischenbericht, mit Beschreibung was du vor hast bzw erreichen willst, sowie deinem bisherigen Code, posten? Hab den Überblick verloren...


    Ich weiß nicht ob ich mit meinem Plan auf dem Holz weg bin:
    Was habe ich bis jetzt:
    Das Schaltscript: /var/www/schalten.php:


    Das Auslesescript: /var/www/lesen.php:


    Den crontab:


    schalten.php und crontab funktionieren tadellos.
    auslesen.php liest (aus der SQL Tabelle "Zeiten") und übergibt über printf.. auch alles was ich glaube zu benötigen am Bildschirm aus.
    Da schalten.php die [id_Typ] und den [Status] benötigt lese ich die + die Einschlatstunde und Einschaltminute, genauso für Ausschalten, aus. Den Status den ich zu den Zeiten benötige kenne ich ja und gebe in händisch mit.
    Und was will ich jetzt noch? :
    Entweder - mit aulesen.php eine Datei erzeugen (also die arrays in eine Datei schreiben) die ich mit cron entweder als crontab ausführen kann. Ergebnis ist dann eine Datei wie ich sie händisch per crontab -e erstelle. Problem hierbei: mit fwrite (siehe Beitrag #35) bekomme ich die Fehlermeldung - zuviele Argumente. "explode" bekomme ich nicht hin.
    Oder aber im crontab einen Eintrag setzen, wie in meigrafd`s weckerscript, damit der cron dann täglich das ausführt was ich bisher händisch in meine crontab geschrieben habe. Hier verstehe ich das Weckerscript, trotz vielem googlen zu wenig um mir das so umzubiegen. Also wie schicke ich die Daten für schalten.php mit?
    Ich hoffe ich nerve nicht mit den Spoilern aber so bleibt es übersichtlich und konnte klar ausdrücken was ich vorhabe. Jetzt hänge ich fest und benötige Hilfe.
    Vielen Dank im Voraus dafür.

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().

  • Auch wenn Einrückungen bei PHP nicht zwingend notwendig sind, solltest du trotzdem darauf achten welche zu haben - das erhöht die Lesbarkeit und somit auch das verstehen was wo gemacht wird und Zugehörigkeiten etc.


    Ziel ist doch eigentlich, nur noch einen Crontabeintrag zu haben der jede Minute "schalten.php" ausführt, oder nicht?


    Du übergibst derzeit an "schalten.php" die "Typ ID" welche geschaltet werden soll und auch den Zustand an oder aus. Der von dir übergebene Zustand ist aber nicht id_Status, was du aber dann direkt INSERT'est, ist also falsch.
    switch ist genau so wie case, keine Schleife, sondern eine Abfrage wie "if". Auch musst du nicht in jeder Abfrage eine MySQL-Verbindung herstellen etc. Reduziere das ganze auf nur das nötigste. Setze Variablen oder mach Abfragen und handle dann entsprechen. Erst verarbeitest du alles, legst fest was passieren soll und erst dann führst du nötige Aktionen durch.


    "lesen.php" erscheint mir überflüssig zu sein. Dort holst du dir aber auch alles " * " und lässt dir dann nur "start" ausgeben, dann holst du noch mal alles " * " und lässt dir nur "end" ausgeben... Das ist auch Quatsch. Mal abgesehen davon das man nicht * nutzen sollte da das weitaus langsamer ist - man sollte dort nur das angeben was man auch haben will und wenn das alle Spalten sein sollen dann gibt man halt alle Spalten an...



    Also zunächst mal solltest du dir überlegen nur an einem Ort die Konfigurationen zu speichern, nicht in 5 verschiedenen Dateien. Wenn du noch ein bash Script nutzt - was ich jetzt nicht rauslesen konnte - reicht es diese dort drin stehen zu haben und die PHP Scripts lesen die nur aus... Ansonsten erstellst du eine "config.php" in der die MySQL-Zugangsdaten drin stehen und die anderen Script laden sich diese Datei rein, zB über require("config.php") ... http://php.net/manual/de/function.require.php


    Dann machst du nur einen einzigen Crontabeintrag:

    Code
    * * * * *   /usr/bin/php /var/www/schalten.php >/dev/null 2>&1


    Dann gestalten wir jetzt erst mal die benötigte Tabelle: Schaltzeit


    id: Ist wie die anderen mal auch, eindeutig und AUTO_INCREMENT
    WochenTag: Beinhaltet die Nummer des Wochentags, 1 (für Montag) bis 7 (für Sonntag) - optional, muss nicht befüllt sein. Wenn etwas zum Beispiel nur ein paar mal die Woche an bestimmten Tagen geschaltet werden soll, zB nur Mittwochs das Wasser ablassen ;)
    Stunde: Beinhaltet die Stunde, im 24h Format.
    Minute: Beinhaltet die Minute, mit führender 0.
    id_Typ: Beinhaltet die ID des zu schaltenden Geräts, zum Beispiel "4" was dann "Nachfüllanlage" wäre.
    id_Status: Beinhaltet die ID des Schaltzustands, also 1 oder 2.


    Tabelle erzeugen:

    Code
    CREATE TABLE Schaltzeit (id INT(11) NOT NULL AUTO_INCREMENT, WochenTag INT(1), Stunde INT(2), Minute NOT NULL INT(2), id_Typ INT(11) NOT NULL, id_Status INT(11) NOT NULL, PRIMARY KEY (id))


    Für jeden Schaltvorgang brauchst du also 2 Einträge:
    - Zum Einschalten.
    - zum Ausschalten.


    Beispiel:

    SQL
    INSERT INTO Schaltzeit (Minute,id_Typ,id_Status) VALUES ('10','4','1')
    INSERT INTO Schaltzeit (Minute,id_Typ,id_Status) VALUES ('30','4','2')


    Es soll also an jedem Tag und zu jeder Stunde, ein mal um :10 Gerät 4 eingeschaltet und um :30 wieder ausgeschaltet werden.
    Wenn es jeden Tag und jede Stunde geschaltet werden soll bleiben die WochenTag / Stunde Spalten leer.


    In "schalten.php" machen wir dann folgendes....


    Als erstes legen wir ein paar Funktionen fest um uns die Arbeit zu erleichtern und Fehler besser verarbeiten zu können - den selben Code immer wieder erneut zu wiederholen ist Quatsch.
    [code=php]
    // functions
    //------------------------------------------------------
    // http://www.w3schools.com/php/php_ref_mysqli.asp
    function query($query_string) {
    global $conid, $showqueries;
    if (!isset($conid) OR !$conid) { $conid = mysql_con(); }
    if (!isset($showqueries)) { $showqueries = 0; }
    if ($showqueries) { echo "Query: $query_string <br/>\n"; }
    $query_id = mysqli_query($conid, $query_string);
    if (!$query_id) { echo "Invalid SQL: $query_string <br/>\n"; } else { return $query_id; }
    }
    function mysql_con() {
    global $mySQLserver, $mySQLport, $mySQLuser, $mySQLpass, $mySQLdatabase;
    $conid = mysqli_connect($mySQLserver, $mySQLuser, $mySQLpass, $mySQLdatabase, $mySQLport);
    if (mysqli_connect_errno()) { die('Error connecting to MySQL: ' . mysqli_connect_error()); }
    return $conid;
    }
    //------------------------------------------------------
    [/php]



    Nun die MySQL-Zugangsdaten in dieses Script holen und die MySQL-Verbindung herstellen:
    [code=php]//Verbindung herstellen
    $mySQLserver = "127.0.0.1";
    $mySQLport = "3306";
    $mySQLuser = "user";
    $mySQLpass = "passwd";
    $mySQLdatabase = "aquasteuer";


    $conid = mysql_con();
    [/php]


    Nun machen wir es uns einfach - die LEFT JOIN Geschichte scheinst du ja nicht zu mögen. Wir holen uns jetzt einfach alle relevanten Daten aus der Datenbank und hinterlegen sie in Arrays, damit wir damit später leichter hantieren und auch "Vorgang" befüllen können.
    Als erstes die Informations-Tabellen: Typ und Status
    [code=php]//Typ auslesen
    $Typ = array();
    $query = query("SELECT id, Bezeichnung FROM Typ");
    while ($row = mysqli_fetch_array($query)) {
    $Typ[$row['id']] = $row['Bezeichnung'];
    }


    //Status auslesen
    $Status = array();
    $query = query("SELECT id, Bezeichnung FROM Status");
    while ($row = mysqli_fetch_array($query)) {
    $Status[$row['id']] = $row['Bezeichnung'];
    }
    [/php]


    Dann hinterlegen wir uns die aktuellen "jetzt" Zeit Werte in Variablen:
    [code=php]
    $currentDAY = date("N"); $currentHOUR = date("H"); $currentMINUTE = date("i");
    [/php]
    Das ist ME einfacher abzulesen als sich zu merken wofür "N" oder "i" steht...


    Dann brauchen wir jetzt die Schaltzeiten.
    [code=php]//Schaltzeit auslesen
    $SchaltWochenTag = array(); $SchaltStunde = array(); $SchaltMinute = array(); $SchaltTyp = array(); $SchaltStatus = array();
    $query = query("SELECT WochenTag, Stunde, Minute, id_Typ, id_Status FROM Schaltzeit");
    while ($row = mysqli_fetch_array($query)) {
    if (empty($row['WochenTag'])) { $SchaltWochenTag[$row['id']] = $currentDAY; } else { $SchaltWochenTag[$row['id']] = $row['WochenTag']; } //wenn "WochenTag" leer ist dann soll es jeden Tag geschaltet werden.
    if (empty($row['Stunde'])) { $SchaltStunde[$row['id']] = $currentHOUR; } else { $SchaltStunde[$row['id']] = $row['Stunde']; } //wenn "Stunde" leer ist dann soll es jede Stunde geschaltet werden.
    $SchaltMinute[$row['id']] = $row['Minute'];
    $SchaltTyp[$row['id']] = $row['id_Typ'];
    $SchaltStatus[$row['id']] = $row['id_Status'];
    }
    [/php]


    And now comes the Magic.


    Hier gehen wir nun daher und ermitteln ob aktuell etwas geschaltet werden muss, und falls wir das tun tragen wir das in 'Vorgang' ein.
    Welches Array wir von Schalt* nun verwenden ist egal, alle wurden mit der eindeutigen "id" erstellt.
    [code=php]
    foreach ($SchaltMinute AS $id => $value) {
    if (($SchaltWochenTag[$id] == $currentDAY) AND ($SchaltStunde[$id] == $currentHOUR) AND ($SchaltMinute[$id] == $currentMINUTE)) {
    echo $Typ[$SchaltTyp[$id]] ."wird <b>". $Status[$SchaltStatus[$id]] ."</b> geschaltet<br/>";
    // Schaltvorgang durchfuehren und in 'Vorgang' eintragen
    exec("sudo /var/sudowebscript.sh ".$SchaltTyp[$id]." ".$Status[$SchaltStatus[$id]], $error, $return_var);
    $insert = query("INSERT INTO Vorgang (id_Typ, id_Status, Zeit) VALUES ('".$SchaltTyp[$id]."', '".$SchaltStatus[$id]."', UNIX_TIMESTAMP());");
    }
    }


    mysqli_close($conid);
    [/php]die echo Zeile habe ich nur drin damit du die Datei ggf auch über den Webserver aufrufen kannst. Ansonsten ist die aber überflüssig. Siehe dazu weiter unten ("Spaß")




    Wie du vielleicht bemerkt hast verwende ich mysqli_ Funktionsaufrufe, nicht das veraltete mysql_ ... Letzteres sollte man heutzutage nicht mehr verwenden, ist langsamer und fliegt irgendwann aus PHP raus.



    Aus Spaß bzw zur Demonstration, wenn du dir später auch noch die Schaltvorgänge anzeigen lassen möchtest, kannst das wie folgt verwenden - aber für "schalten.php" wird das nicht benötigt:




    PS: Ich hab das hier vereinfacht dargestellt - professionell sähe es nämlich komplizierter aus :fies:

  • WOW - :danke_ATDE::angel: für die Menge an Arbeit!



    PS: Ich hab das hier vereinfacht dargestellt - professionell sähe es nämlich komplizierter aus :fies:


    Gut, daß Du es nicht professionell gemacht hast - dann würde ich nichts mehr kapieren - ist so schon ne Menge Input. (nicht böse gemeint)
    Ehrlich gesagt - das muß ich jetzt erstmal verdauen und vor allem umsetzen!
    Wenn ich das richtig verstanden habe, dann entfällt jetzt sogar die Prüfung was sollte geschaltet sein, nach reboot. Da der crotab ja jede Minute durchgefürt wird.
    Hammer :thumbs1: Ich melde mich auf jeden Fall mit einem Feedback sobald ich das alles druchgeackert habe.

    Wer einen Schreibfehler findet darf ihn behalten!
    Adler-Suchsystem ist auch nicht ganz einfach zu handhaben...


    In einem wankenden Schiff fällt um, wer stillesteht, nicht wer sich bewegt.
    (Ludwig Börne)

    Edited once, last by janzeitler ().