Alarmanlage - Magnetkontakte auslesen und speichern - Webserver Interface

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

    In diesem Tutorial möchte ich euch zeigen, wie ihr 2 oder mehr Magnetkontakte auslesen könnt.
    Zudem kann der aktuelle Status, sowie ein Log lokal auf einem Webserver eingesehen werden.
    Außerdem wird jede Zustandsänderung der Kontakte in einer Datenbank (SQlite3) gespeichert.

    Das Tutorial ist aus meinem Alarmanlagen Projekt entstanden. Hier findet ihr noch weitere Fotos.
    Dort findet ihr auch Fotos von meinem Webinterface mit dem ich die komplette Anlage steuern und überwachen kann.

    Was benötigt ihr:

    • Raspberry Pi Model A(Wlan Modul) oder B
    • Kabel (ich habe dieses von Conrad benutzt), Jumpwires, Steckbrett ....
    • SD-Karte mit aktuellem Raspbian
    • Magnetkontakte (ich habe diese von Conrad benutzt)


    Hardware:
    Die Magnetkontakte verdrahtet ihr wie folgt.

    Ich habe die Eingänge auf Pin 19 (MOSI) und Pin 21 (MISO) ausgewählt.
    Von dort geht ihr an das eine Ende des Magnetkontakts. Das andere wird an Masse (Ground)
    angeschlossen. Schließt beide Kontakte so an.
    Wir benötigen keine Pullup Widerstände, da wir per Software die internen Widerstände aktivieren.


    Ihr könnt die Magnetkontakte auch in Reihe schalten. Somit wird trotzdem nur ein Eingang benutzt.
    Natürlich könnt ihr dann nicht genau lokalisieren welcher Kontakt ausgelöst hat, da sie in Reihe geschaltet sind.

    Ich habe alles auf einem Steckbrett [Anzeige] aufgebaut und nutzte zusätzlich den T-Cobbler von Adafruit [Anzeige]
    Das war es auch schon mit der Hardware.

    Software:
    Starte nun deinen Raspberry Pi mit deiner vorbereiteten SD-Karte.
    Als erstes installieren wir den Webserver und PHP5 sowie SQLite 3.

    Code
    sudo apt-get update
    sudo apt-get install lighttpd php5-cgi php5-sqlite sqlite3
    sudo lighty-enable-mod fastcgi-php
    sudo service lighttpd force-reload


    Nun ist der Webserver installiert und wir können mit der Software weitermachen.

    Das Python Script:
    Wir werten unsere Eingänge mithilfe von Python aus. Dazu habe ich folgendes Script geschrieben kommentiert. Wer Fragen oder Verbesserungsvorschläge hat, kann sie gerne loswerden.

    Hier der grobe Ablauf des Scripts:
    In einem Loop werden die Eingänge auf Veränderung überprüft. Dabei merkt sich das Script jedem neuen Durchgang den Zustand aus dem letzten Loop.
    Im Loop überprüft er folgende Bedingungen.

    Wenn Tür 1 vorher geschlossen war UND jetzt offen ist UND nicht scharf gestellt ist (REED_01_on) DANN -> "Tür 1 offen"
    Wenn Tür 1 vorher geschlossen war UND jetzt offen ist UND scharf gestellt ist (REED_01_on) DANN -> "Tür 1 ALARM"
    Wenn Tür 1 vorher geöffnet war UND jetzt geschlossen ist DANN -> "Tür 1 geschlossen"

    Das wird nun auch noch für Tür 2 durchgespielt. Ihr könnt auch noch weitere Türen/Fenster hinzufügen indem ihr die entsprechenden Codeblöcke einfach kopiert.

    Bei allen Bedingungen wird ein Text in der Shell ausgegeben und die Meldung in die Datenbank geschrieben.
    An folgender Stelle könnt ihr nun weiter mit Python arbeiten: "#Email,SMS,Anruf,Sirene,Foto oder Video aufnehmen"
    Ihr könntet LEDS schalten, Sirenen heulen lassen, eine Webcam starten, oder eine Email verschicken.
    Ihr müsst es nur programmieren. :baeh2:


    doors.py

    Wir wechseln also nun in das Verzeichnis /var/www , erstellen eine neue Datei mit dem Editor und fügen das Script von oben ein.

    Code
    cd /var/www
    sudo nano doors.py

    Als nächstes benötigen wir eine Datenbank: Ich habe diese bereits vorbereitet. Ihr könnt die leere Datenbank via wget runter laden.

    Code
    sudo wget https://dl.dropboxusercontent.com/u/43005441/rpiforum/database.db


    database.db.txt
    Nun können wir das PythonScript testen.
    Schließt eure beiden Magnetkontakte und führt das Programm aus.

    Code
    sudo python doors.py

    Jetzt öffnet und schließt nacheinander beide Kontakte.
    Ihr solltet folgende Ausgabe sehen:

    Zitat


    pi@raspberrypi /var/www $ sudo python doors.py
    Tuer 1 ALARM
    Tuer 2 offen
    Tuer 1 geschlossen
    Tuer 2 geschlossen

    Als nächstes überprüfen wir, ob Die Datenbank gefüllt wurde.

    Code
    sudo sqlite3 database.db


    Nun müsst ihr die Werte aus der Tabelle abfragen.
    tippt folgendes ein: SELECT * FROM tbl_log; und bestätigt mit der ENTER-Taste

    Nun solltet ihr folgende Ausgabe sehen.

    Zitat


    sqlite> SELECT * FROM tbl_log;
    1|1375280607|Tuer 1|Alarm
    2|1375280607|Tuer 2|geoeffnet
    3|1375280608|Tuer 1|geschlossen
    4|1375280608|Tuer 2|geschlossen

    Wenn das alles geklappt hat kommen wir zum Webserver Script. Es ist nur ein einfaches Script um zu zeigen wie ihr auf die Datenbank zugreift, oder den aktuellen Status anzeigen lasst.

    Die PHP Scripte:
    Folgende Scripte einfach in den Ordner /var/www erstellen.

    demo1.php - Listet den aktuellen Status der Türen auf
    demo1.php

    !! Für dieses Script benötigt ihr zusätzlich das Programm wiringpi !!
    Installation (kurzform):

    Spoiler anzeigen
    Code
    cd
    sudo apt-get update
    sudo apt-get install git-core
    git clone git://git.drogon.net/wiringPi
    cd wiringPi
    ./build


    Ausführlicher ist die Installation hier beschrieben.
    http://wiringpi.com/download-and-install/



    [code=php]<?php
    // https://www.forum-raspberrypi.de
    // benoetigt wiringpi
    // http://wiringpi.com/download-and-install/

    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    $val_tuer1 = trim(@shell_exec("/usr/local/bin/gpio -g read 10"));
    $val_tuer2 = trim(@shell_exec("/usr/local/bin/gpio -g read 9"));

    echo "Tuer 1:";
    if ($val_tuer1 == 1)
    {
    echo("geoeffnet");
    } else{
    echo("geschlossen");
    }

    echo "<br/> Tuer 2:";
    if ($val_tuer2 == 1)
    {
    echo("geoeffnet");
    } else{
    echo("geschlossen");
    }

    ?>[/php]


    demo2.php - Listet euch den Log auf
    demo2.php

    [code=php]<?php
    // https://www.forum-raspberrypi.de
    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    $db = new PDO('sqlite:database.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $result = $db->query('SELECT id, time, obj, message FROM tbl_log ORDER BY id DESC;');

    echo '<table>
    <tr>
    <td><b>ID</b></td>
    <td><b>Zeit</b></td>
    <td><b>Ort</b></td>
    <td><b>Meldung</b></td>
    </tr>';

    foreach($result as $row) {
    list($id, $time,$obj,$message) = $row;
    $time = date("d.m.y - H:i:s", $time);
    echo "<tr>
    <td>".$id."</td>
    <td>".$time."</td>
    <td>".$obj."</td>
    <td>".$message."</td>
    </tr>";
    }
    echo "</table></div>";

    ?>[/php]

    Zu guter letzt noch ein Link zu einem weiteren Tutorial welches nützlich sein könnte.

    [Tutorial] Autostart eines Python Script
    Das es sich um eine "Alarmanlage" handelt ist es ratsam, dass das Script automatisch nach dem Hochfahren gestartet wird.

    Ich hoffe ihr könnt mit diesem Tutorial etwas anfangen. Schaut gerne in meinem Projekt vorbei. Dort findet ihr zusätzlich Fotos und Screenshots wie ich das ganze umgesetzt habe
    Fragen und Verbesserungsvorschläge sind immer willkommen.

    ...ist mal wieder ein kompletter Tag für das Tutorial drauf gegangen.... :sleepy:

    Well in my humble opinion, of course without offending anyone who thinks differently from my point of view, but also by looking into this matter in a different way and without fighting and by trying to make it clear and by considering each and every one's opinion, I honestly believe that I completely forgot what I was going to say.

    Einmal editiert, zuletzt von ps915 (8. Januar 2014 um 18:06)

  • Alarmanlage - Magnetkontakte auslesen und speichern - Webserver Interface? Schau mal ob du hier fündig wirst!

    • Offizieller Beitrag

    Werde das Tutorial dementsprechend anpassen. Vielleicht schaffe ich es ja heute noch.

    Edit:
    Ersten Beitrag editiert. Siehe oben

    Well in my humble opinion, of course without offending anyone who thinks differently from my point of view, but also by looking into this matter in a different way and without fighting and by trying to make it clear and by considering each and every one's opinion, I honestly believe that I completely forgot what I was going to say.

    Einmal editiert, zuletzt von ps915 (8. August 2013 um 06:12)

  • Hallo Leute,

    ich will zwar nicht ins RPi Alarmanlagengeschäft einsteigen, möchte aber zu diesem Thema noch einen Vorschlag zu Optimierung machen. Ich würde die Aufgabe hardwaretechnisch etwas anders umsetzen. In die Reihenschaltung der Reedkontakte würde ich nach dem letzten Kontakt noch einen Widerstand in Reihe einbauen und an jedem Reedkontakt, je einen Widerstand mit jeweils unterschiedlichem Wert, parallel schalten. Mit dieser Schaltung wird dann in ein Spannungsteiler aufgebaut, dessen Ausgangsspannung man dann mit einem AD Wandler ( z.B. per I2C ) auswerten kann. Damit kann dann unterschieden werden, ob ein Kontakt oder mehrere offen sind, welche Kontakte offen ist und ob ein Sabotageversuch des Meldekreis vorliegt.

    • Offizieller Beitrag

    Nett Idee, kannst du dazu mal eine Schaltung hochladen?

    Well in my humble opinion, of course without offending anyone who thinks differently from my point of view, but also by looking into this matter in a different way and without fighting and by trying to make it clear and by considering each and every one's opinion, I honestly believe that I completely forgot what I was going to say.

    Einmal editiert, zuletzt von ps915 (20. August 2013 um 17:25)

  • Erstmal vielen Dank für dieses super Tutorial!

    Eine Anmerkung noch zum automatische Start beim Booten:

    Wenn der Autostart über einen Eintrag in der /etc/rc.local
    ausgelöst werden soll, z.B. mittels:

    python /var/www/doors.py &

    dann ist es notwendig, in der doors.py den absoluten Pfad
    zur database.db anzugeben, weil sie ansonsten nicht gefunden wird
    (da sie sich nicht im gleichen Arbeitsverzeichnis befindet).

    Zum Beispiel musste bei mir die Zeile:

    db = "database.db" (aus der doors.py)

    geändert werden zu:

    db = "/var/www/database.db"


    Vielen Dank nochmal.

    Gruß.
    Stullen

  • hallo,
    ich habe eine allgemeine frage ist es möglich an ein raspberrypi Magnetkontakte,eine Webcam,PIR bewegungsmelder anzuschließen und den status aller 10 sekunfen an eine website zu senden?
    und be bewegung eines Pir bewegungsmelder eine kamera solange eine bilderreinfolge (1bild pro sekunde) auf eine SD karte zu speichern und 1 bild pro 10 sek an die website zu senden ?
    und wenn die sd karte bzw eine us stick voll ist die videos darauf zu überschreiben?
    Das alles noch über einen Umts stick?
    also so das man von zuhause den staus des gebäudes abrufen kann und neben den meldungen ein stream von livebildern (1 bild pro 10 sek) hat?

    Ich wäre für antworten sehr
    dankbar:danke_ATDE:

    • Offizieller Beitrag

    Relativ einfach:

    Hier erfährst du wie er angesteuert wird:
    http://www.raspberrypi-spy.co.uk/2013/01/cheap-…erry-pi-part-1/

    Well in my humble opinion, of course without offending anyone who thinks differently from my point of view, but also by looking into this matter in a different way and without fighting and by trying to make it clear and by considering each and every one's opinion, I honestly believe that I completely forgot what I was going to say.

  • Habe mal versucht im code eine webcam (bilder hochladen auf ftp-server per bash-scipt) emailversand sms und pir sensensor mit einzubinden läuft soweit ganz gut der code ist wahrscheinlich noch saumäßig versuche
    aber auch erst seit 3 tagen etwas python zu lernen.
    Entschuldigung an den Author das ich sein Programm so verschändelt habe
    Würde gern noch eine Sirene (piezo) mit einbinden komme aber irgendwie nicht weiter
    vieleicht kann mir jemand etwas helfen...
    Hier das geänderte Programm


    Einmal editiert, zuletzt von inesa394 (18. Oktober 2013 um 20:37)

  • Danke für dieses tolle Tutorial und für die Erweiterung von ines395.
    Klappt alles wunderbar.
    :bravo2:


    Jetzt wollte ich eine Scharf/Unscharf Funktion mit einem einfachen Kippschalter dazubauen.
    Wenn der Schalter betätigt wird soll einfach der Status in ein .txt File geschrieben werden (1 oder 0).
    Im doors.py Skript würde ich dann gerne das File einlesen und als Scharf/Unscharf Status für die REEDS_01_on funktion hernehmen:

    f = open('armed.txt', 'r')
    REED_01_on = f.read()
    f.close()

    Wenn ich ein print REED_01_on mache schreibt er mir 1 oder 0 hin nur wird der Wert nicht im ganzen weiteren Skript verwendet.
    Hat wer ne idee warum?

    Danke vorab und lg
    mitchel1220


    EDIT:
    Ich schon wieder.
    Problem gelöst, und kommt gleich hier unten für alle die auch nicht so toll python können wie ich ;)

    # 1 = scharf gestellt = 1
    # 0 = nicht scharf gestellt
    with open("/home/pi/armed.txt", "r") as fo:
    fo.seek(0, 0)
    status = fo.read(1)
    fo.closed
    if (status == "1"):
    print "ALARMANLAGE IST SCHARF"
    REED_01_on = 1
    if (status == "0"):
    print "ALARMANLAGE ist unscharf"
    REED_01_on = 0


    lg und schöne Feiertage

    Einmal editiert, zuletzt von mitchel1220 (20. Dezember 2013 um 11:31)

    • Offizieller Beitrag


    Entschuldigung an den Author das ich sein Programm so verschändelt habe
    Würde gern noch eine Sirene (piezo) mit einbinden komme aber irgendwie nicht weiter
    vieleicht kann mir jemand etwas helfen...
    Hier das geänderte Programm


    Kein Problem. ;)

    Ich habe selber eine Piezo Sirene Zuhause.
    Die kannst du einfach an einen freien pin anschließen und dieses dann bei Bedarf auf high schalten. Das ist natürlich nicht sonderlich laut. Besser wäre es, ein Relais zu schalten, welches die Sirene einschaltet.
    Jeh höher die Spannung, desto lauter wird sie.
    Schau mal bei Conrad.de nach.

    Well in my humble opinion, of course without offending anyone who thinks differently from my point of view, but also by looking into this matter in a different way and without fighting and by trying to make it clear and by considering each and every one's opinion, I honestly believe that I completely forgot what I was going to say.

    Einmal editiert, zuletzt von ps915 (8. Januar 2014 um 18:07)

  • Hallo!

    Bin neu hier im Forum und habe das Projekt gleich mal durchgearbeitet.

    Echt super.

    Nur eins verstehe ich nicht, muß aber dazu sagen, dass ich keinen Plan von Python habe.
    Habe den Prog.Code erweitert und bekomme folgende Fehlermeldung:


    Code
    NameError: name `REED_03_on`is not defined


    Hier der von mir erweiterte Code:


  • GROSS-/kleinschreibung ist sehr sehr wichtig

    Du hast in deinem Script oben

    Code
    Reed_03_on = 1

    stehen, aber wesendlich weiter unten wird

    Code
    REED_03_on

    aufgerufen... Das kann so also nicht gehen - wie gesagt, Gross-/Kleinschreibung ist wichtig, also benenn ganz oben das "Reed_03_on" um in -> "REED_03_on"

  • Hallo Meigrafd.

    Danke für deine Hilfe. Wie kann man nur so blind sein. Hänge jetzt schon seit 3Std. an dem Problem.
    Aber das ich oben Reed geschrieben habe, ist mir nicht aufgefallen.


    Dank und Gruß

    Jojo

  • Hallo.

    Da ich glaube, das meine Frage auch andere Leser hier interessiert und ich keinen neuen Beitrag deshalb aufmachen möchte, frage hier.

    Habe das Tutorial abgearbeitet und konnte es dank Meigrafd auch erweitern. Jetzt möchte ich noch den I2C-Bus nutzen, damit ich mehr Eingänge zur Verfügung habe. Die notwendige Hardware ( MCP 23017) und einige andere Teile habe ich bestellt und der Anschluss an den Pi sollte Dank des Forums auch kein Problem sein.
    Aber wie fragt man die Eingänge am MCP 23017 jetzt ab?
    Hier im Forum gab es einen Post, in dem die Pinabfrage und alles rund um I2C sehr gut erklärt war. Leider kann ich diesen nicht wiederfinden.

Jetzt mitmachen!

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