effiziente Abfragestrategie

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,
    ich möchte in der Nacht überprüfen lassen, ob alle Rollläden geschlossen sind. Dazu habe ich in die Panzer Magnete eingebaut, die bei einer bestimmten Stellung einen Reedkontakt mit Adressgeber schließen. Es entsteht dann ein Ordner in der Art

    Zitat

    /sys/bus/w1/devices/01-0000161f81b5/name


    dessen Vorhandensein ich abfragen kann. Sind alle Ordner vorhanden, soll eine grüne LED leuchten.

    Die Frage ist nun, welche Strategie ist am effizientesten, belastet also den RasPi am wenigsten?
    Sollte ich ein Programm schreiben in der Art:

    Bash
    #!/bin/bash
    #
    echo "0" > /sys/class/gpio/gpio7/value   # Kontroll-LED kurz aus
    sleep 0.5
    if [ -f /sys/bus/w1/devices/01-0000161ed6bf/name ];then
    echo "1" > /sys/class/gpio/gpio7/value
    fi
    Exit 0


    und lasse das Programm mittels crontab zwischen meinetwegen 22 Uhr bis 6 Uhr alle Minute starten?

    Oder
    packe die Abfrage in eine while-Schleife mit einer zeitabhängigen Abbruchbedingung und starte das Programm jeden Tag um 22 Uhr?

    Bitte nicht kreuzigen, ich bin kein Programmierer.

    Also, welche Strategie ist besser, oder gibt es noch was Anderes?

    EDIT: die andere Frage hat sich erledigt, es fehlte ein Leerzeichen. Darum habe ich sie gelöscht, um nicht zu verwirren.

    Viele Grüße
    DocAdams

    1x RaspberryPi 2, 1x RaspberryPi 3, 1x OpenELEC, 1x RaspberryPi 4 mit ioBroker ,

    Einmal editiert, zuletzt von docadams (24. Juli 2014 um 22:40)

  • Mit dem folgenden Code kannst Du recht einfach diverse Magnete abfragen und die entsprechenden gpios steuern. Der eigentlichen Steuercode habe ich auskommentiert, da ich keine Magnete habe.

    Kernpunkt ist eine map, die die Ids der Magnete mit den gpios verknüpft. Du kannst das Script so mal bei Dir aufrufen um eine Idee zu bekommen was es tut.

    Welchen Weg Du beschreitest mit dem Aufruf ist wohl ziemlich egal. Vermutlich wird der sleep im Script die CPU weniger belasten, aber da würde ich mir keine grossen Gedanken drum machen.

    Edit: Die folgende Seite hat ein paar Codesnippets zu assoziative Arrays in bash.

  • Die Lösung über cron verballert imho wesentlich mehr Resourcen.
    Da muss ein Prozess erzeugt und überlagert sowie ein Environment aufgebaut werden. Dann wird darin wiederum ein script gestartet und dann erst erfolgt die Abfrage ... und anschliessend muss der ganze Kram wieder abgebaut und frei gegeben werden.

    cu,
    -ds-

  • Hallo Docadams,

    ich würde die Abfrage ein wenig intelligenter gestalten.

    Du musst eigentlich nur zwischen wenigen Zuständen sauber unterscheiden:
    1. Rolladen ist unten. Hier musst Du nur abfragen, ob er hochfährt.
    2. Rolladen ist hochgefahren. Hier musst Du nur abfragen, ob die Zeit zum Herunterfahren gekommen ist.

    Meines Erachtens ist es nicht erforderlich, ständig abzufragen, ob er nachts immer noch unten ist. Wenn der Rollladen unten war, sich nicht bewegt hat, kannst Du beliebig oft den Status abfragen - er wird immer noch unten sein.

    Beste Grüsse

    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.

  • Vielen Dank für eure Anteilnahme und Tipps.

    framp
    ich wollte nicht, dass irgendwie pro Reedkontakt ein bestimmter GPIO irgendwas macht, sondern nur wenn alle Magnete an ihrer Position sind, ein bestimmter GPIO (GPIO7) schaltet. Das ist meine Mindestforderung und für mich schon eine Herausforderung.
    Vielleicht später einmal (im Winter) könnte noch eine HTML-basierte Auswertung kommen, welcher der Kontakte nicht geschlossen ist. Machbar wäre das sicher, denn die Kontakte haben ja eindeutige Namen. Jetzt wäre ich erst mal zufrieden, wenn für alle sichtbar eine LED leuchtet, wenn alles in Ordnung ist, oder eben nicht leuchtet.

    Andreas
    Das habe ich falsch formuliert. Die eigentliche Rollladensteuerung ist ein anderes Thema. Da soll dass Rollo nur runter gefahren und danach geprüft werden, ob der Kontakt geschlossen ist. Wenn der Kontakt geschlossen wurde, ist Schluss mit dem eigentlichen Rollladensteuerprogramm.
    Meine jetzige Frage ist eher ein nützliches Addon weil ja die Hardware (Reedkontakte) vorhanden ist. Nämlich die Kontrolle, ob alle Fenster geschlossen sind, auch die, die nicht mit Motoren ausgestattet sind, und die ständige Kontrolle in der Nacht, ob sie auch geschlossen bleiben, oder etwa jemand sich daran zu schaffen macht. (Dann nutzt zwar die LED wenig, aber das löse ich schon noch)

    dreamshader
    das hatte ich schon befürchtet. Schade, denn mit den Cronjobs habe ich das heute Nacht schon zu meiner bescheidenen Zufriedenheit hinbekommen.
    Aber mit der Formulierung der Abbruchbedingung stochere ich im Nebel. Ich denke mal, ich muss die Zeit definieren und vergleichen, ob sie größer ist, als die Vorgabe.
    Bisher bin ich soweit:

    Ich scheitere am break-Befehl.

    Viele Grüße
    DocAdams

    1x RaspberryPi 2, 1x RaspberryPi 3, 1x OpenELEC, 1x RaspberryPi 4 mit ioBroker ,

  • Da sieht man mal wieder dass es schon schwer ist eine genaue Spezifikation zu erstellen. Das habe ich einfach falsch verstanden. Anbei Code der dann wohl eher passen sollte ;)

  • Vielen Dank für den Code, das ist etwas ganz anderes, als was ich zusammengestottert habe.
    Vor allem lässt es sich bequem auf mehr Fenster erweitern.

    Eine Frage zu hab ich noch, obwohl es nicht mehr direkt zum Startthema gehört. Kann man in dem Code noch die Ordner anders zuordnen, dass es also nicht heißt ".../devices/01-000569e76bf/name ist offen", sondern "Fenster 3 ist offen"?

    Viele Grüße
    DocAdams

    1x RaspberryPi 2, 1x RaspberryPi 3, 1x OpenELEC, 1x RaspberryPi 4 mit ioBroker ,

  • Klar doch ;) Dann benutze doch ein assoziatives Array wie ich es in meinem ersten Vorschlag getan habe und pass zwei Stellen im Code entsprechend an.

    Code
    declare -A MYMAP=([01-000161ed6bf]="Wohnzimmer links" \
    				  [01-0001387d6bf]="Wohnzimmer rechts" \
    				  [01-000569e76bf]="Schlafzimmer" \
    				  [01-057469e76bf]="Kinderzimmer")


    und dann bekommst Du

    Code
    Checking /sys/bus/w1/devices/01-000569e76bf/name
    !!! 'Schlafzimmer' is open
    Checking /sys/bus/w1/devices/01-057469e76bf/name
    !!! 'Kinderzimmer' is open
    Checking /sys/bus/w1/devices/01-000161ed6bf/name
    !!! 'Wohnzimmer links' is open
    Checking /sys/bus/w1/devices/01-0001387d6bf/name
    !!! 'Wohnzimmer rechts' is open
    Some ports open
  • Aha, toll. :bravo2:

    Habe aber ein kleines und ein großes Problem damit. Wenn die Bezeichnung aus mehreren Wörtern besteht, kommt eine Fehlermeldung.

    Code
    declare -A MYMAP=([01-0000161f2bd4]="Wohnzimmer links" \
    
    
    Checking /sys/bus/w1/devices/Wohnzimmer links/name
    ./kontrolle.sh: Zeile 24: [: /sys/bus/w1/devices/Wohnzimmer: Zweistelliger (bin▒rer) Operator erwartet.

    Bei

    Zitat

    declare -A MYMAP=([01-0000161f2bd4]="Wohnzimmer-links" \


    ist es OK.

    Das größere Problem ist, dass immer die Ports als nicht vorhanden angesehen werden. Müssen evtl. die Zeilen

    Code
    for port in "${MYMAP[@]}"; do
    if [ ! -f /sys/bus/w1/devices/$port/name ];then


    noch angepasst werden?

    Viele Grüße
    DocAdams

    1x RaspberryPi 2, 1x RaspberryPi 3, 1x OpenELEC, 1x RaspberryPi 4 mit ioBroker ,

  • Wenn Du die beiden Schleifen in meinem Code fuer ein assoziatives Array und ein normales Array vergleichst, wirst Du sehen, dass die etwas unterschiedlich sind: Einmal wird mit ! über die Schlüssel geloopt und einmal ohne ! über die Werte.

    Du loopst gerade bei Dir im Code über die Werte (Wohnzimmer links) und die Ports gibt es ja nicht

    Zitat

    Checking /sys/bus/w1/devices/Wohnzimmer links/name

    . Wenn Du über die Schlüssel loopst mit ! werden die kryptischen Portids benutzt

    Zitat

    Checking /sys/bus/w1/devices/01-0001387d6bf/name

    ;)

  • Ich hatte viel rumexperimentiert, bevor ich gestern die Frage gestellt hatte, aber das Ausrufezeichen hatte ich nicht beachtet.
    Der Code sieht nun so aus:


    So werde ich es erst mal belassen.
    Vielen Dank für die Hilfe und Geduld. Ich denke, ich habe auch für später einiges dazugelernt.

    Viele Grüße
    DocAdams

    1x RaspberryPi 2, 1x RaspberryPi 3, 1x OpenELEC, 1x RaspberryPi 4 mit ioBroker ,

    Einmal editiert, zuletzt von docadams (30. Juli 2014 um 17:48)

  • ...Ich denke, ich habe auch für später einiges dazugelernt...


    Sieht jetzt sehr gut aus. Das mit dem ! ist schon schwer zu sehen - ist aber auf der oben von mir verlinkten Seite in den Beispielen erklärt (vielleicht sieht Du Dir die Seite - Abschnitt zu looping - jetzt noch mal an mit dem neuen Wissen was Du hast :) )

    Zwei kleine Tips noch:
    1) Ich würde nicht `...Befehl...` benutzen sondern die besser lesbare Darstellung $(...Befehl...).
    2) Die FOR und DONE Zeile würde ich noch so einrücken, dass sie genau unter d=`date ... stehen. Dann liest sich der Code leichter.

Jetzt mitmachen!

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