Alarmanlage - Magnetkontakte auslesen und speichern - Webserver Interface

    • Official Post

    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 (Affiliate-Link) aufgebaut und nutzte zusätzlich den T-Cobbler von Adafruit (Affiliate-Link)
    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:


    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.


    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):



    [code=php]<?php
    // http://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
    // http://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.

    Edited once, last by ps915 ().

  • und wie lässt man es am betsen nach dem reboot automatisch starten? crontab, rc.local, init.d ?


    hab schon alles versucht aber irgendwie klappt es nicht :(

    • Official Post

    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.

    Edited once, last by ps915 ().

  • 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.

    • Official Post

    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.

    Edited once, last by ps915 ().

  • 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:

  • Hallo
    Super dein Tutorial habe das gleich mal nachgebaut. Eine Frage hätte ich
    wie würde die Schaltung mit einen zusätzlichen PIR Sensor aussehen würde das gern noch
    mit integrieren.


    Gruß Inesa

  • (sofern ich mich richtig erinnere...)


    Habe einen Reed Sensor und einen PIR Sensor gleichzeitig angeschlossen.


    Ich verwende diesen Sensor gemäß dieser Anleitung.


    Die Skripten aus diesem Thread habe ich entsprechend angepasst.



    Gruß.
    Stullen

    • Official Post

    Relativ einfach:


    Hier erfährst du wie er angesteuert wird:
    http://www.raspberrypi-spy.co.…-the-raspberry-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




    Edited once, last by inesa394 ().

  • 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

    • Official Post


    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.

    Edited once, last by ps915 ().

  • 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.