- 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.
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.
# https://www.forum-raspberrypi.de
import time
import RPi.GPIO as GPIO
import sqlite3 as lite
import sys
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
# Eingaenge fuer Tuer Kontakte
REED_01 = 19
REED_02 = 21
# 1 = scharf gestellt = 1
# 0 = nicht scharf gestellt
REED_01_on = 1
REED_02_on = 0
# Tuer Kontakte als INPUT einstellen
GPIO.setup(REED_01, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(REED_02, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# cs = Current State
# ps = Previous Stade
cs_01 = 0 # REED 01
ps_01 = 0
cs_02 = 0 # REED 02
ps_02 = 0
while True:
ts = time.time()
#Pfad zu SQlite 3 Datenbank
db = "database.db"
# REED 01 START
cs_01 = GPIO.input(REED_01)
# KONTAKT -> GEOEFFNET
if cs_01 == 1 and ps_01 == 0 and REED_01_on != 1:
print "Tuer 1 offen"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 1','geoeffnet')" % (ts) )
ps_01=1
# KONTAKT -> ALARM
elif cs_01 == 1 and ps_01 == 0 and REED_01_on == 1:
print "Tuer 1 ALARM"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 1','Alarm')" % (ts) )
#Email,SMS,Anruf,Sirene,Foto oder Video aufnehmen
ps_01=1
# KONTAKT -> geschlossen
elif cs_01==0 and ps_01 == 1:
print "Tuer 1 geschlossen"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 1','geschlossen')" % (ts) )
ps_01=0
# REED 01 ENDE
# REED 02 START
cs_02 = GPIO.input(REED_02)
# KONTAKT -> GEOEFFNET
if cs_02 == 1 and ps_02 == 0 and REED_02_on != 1:
print "Tuer 2 offen"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 2','geoeffnet')" % (ts) )
ps_02=1
# KONTAKT -> ALARM
elif cs_02 == 1 and ps_02 == 0 and REED_02_on == 1:
print "Tuer 2 ALARM"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 2','Alarm')" % (ts) )
#Email,SMS,Anruf,Sirene,Foto oder Video aufnehmen
ps_02=1
# KONTAKT -> geschlossen
elif cs_02==0 and ps_02 == 1:
print "Tuer 2 geschlossen"
con = lite.connect(db)
with con:
cur = con.cursor()
cur.execute("INSERT INTO tbl_log values(null, %d, 'Tuer 2','geschlossen')" % (ts) )
ps_02=0
# REED 02 ENDE
# massive CPU-Auslastung verhindern
time.sleep(0.01)
Alles anzeigen
Wir wechseln also nun in das Verzeichnis /var/www , erstellen eine neue Datei mit dem Editor und fügen das Script von oben ein.
Als nächstes benötigen wir eine Datenbank: Ich habe diese bereits vorbereitet. Ihr könnt die leere Datenbank via wget runter laden.
database.db.txt
Nun können wir das PythonScript testen.
Schließt eure beiden Magnetkontakte und führt das Programm aus.
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.
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
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....