Webseite zum steuern einer Alarmanlage

  • Hallo zusammen,


    ich bin jetzt mittlerweile an dem Punkt, wo ich lieber selbst schreibe als noch weiter zu suchen.
    Bisher habe ich leider nichts gefunden, was mir zum jetzigen Zeitpunkt weiterhilft.


    Zuallererst sei gesagt, dass ich vom programmieren (sei es python, html, php oder sonstwas)
    echt keine Ahnung habe. Ich kann in VBA ein wenig, weshalb ich mir die eine oder andere
    Fuktion von Scripten denken kann, aber da hörts dann auch schon auf.


    Mein Vorhaben ist es eine Alarmanlage (am Pi) über ein Webinterface zu steuern.
    Ich habe eine Index.html welche mich per Klick auf den Button auf eine Statusseite bringen soll.


    Auf der Statusseite (bin mir noch nicht sicher, ob php oder html besser ist) möchte ich im Grunde folgendes haben:


    Mir soll also angezeigt werden, ob die Anlage an oder aus ist.
    Um sie zu schalten habe ich mir die Scripte aus dem Semper-Video zu Nutze gemacht.
    Das entsprechende Script soll aktiviert werden, wenn man auf den Switch klickt.



    Einschalten:
    [code=php]<?php
    shell_exec ("rm /var/www/html/alarm.aus");
    exec ("touch /var/www/html/alarm.an");
    header("Location:status.html");
    ?>[/php]



    Ausschalten:
    [code=php]<?php
    shell_exec ("rm /var/www/html/alarm.an");
    exec ("touch /var/www/html/alarm.aus");
    header("Location:status.html");
    ?>[/php]


    Habt ihr eine Ahnung, wie ich eine Abfrage realisieren kann, welche Datei in dem Verzeichnis liegt?
    Oder eine Idee, wie ich das ganz anders lösen kann?


    Wenn ihr noch irgendwelche Infos braucht, bitte einfach fragen.

  • Hallo Shendayan!



    ich bin jetzt mittlerweile an dem Punkt, wo ich lieber selbst schreibe als noch weiter zu suchen.
    ...
    dass ich vom programmieren (sei es python, html, php oder sonstwas) echt keine Ahnung habe.


    Ich kann mir nicht vorstellen, daß man Dir hier eine fertige Lösung präsentiert. :-/
    Du solltest schon selber etwas dafür tun, denn Deine Codeschnipsel sind gelinde gesagt nicht nur gefährliches Halbwissen sondern schon fast grenzwertig. :@

    So, genug gemeckert. :stumm:


    Um Deinem Grundverständnis von PHP + HTML auf die Sprünge zu helfen hier mal zwei Links zum Einstieg:
    PHP
    HTML



    Habt ihr eine Ahnung, wie ich eine Abfrage realisieren kann, welche Datei in dem Verzeichnis liegt?


    Das Zauberwort ist: "file_exists" http://php.net/manual/de/function.file-exists.php


    PHP
    <?php
    $filename = '/path/to/foo.txt';
    if (file_exists($filename)) {
    echo "Die Datei $filename existiert";
    } else {
    echo "Die Datei $filename existiert nicht";
    }
    ?>


    Aber ich würde mir an Deiner Stelle erst den oben genannten PHP-Link ansehen. ;)

  • Mal andersrum gefragt: Über was schaltest du die Alarmanlage?
    Hat das zufällig etwas mit den GPIO zu tun?
    Wenn ja würde ich an deiner Stelle den Webserver lieber in Python umsetzen - das ist eigentlich recht einfach und ermöglicht einen weitaus bessere/einfacheren Umgang mit den GPIO's.


    Eine temporäre Datei zu schreiben um zu ermitteln ob die Alarmanlage an oder aus ist, wäre auch nicht sooo optimal. Wenn man solch einen Weg wählt sollte man aber lieber eine Umsetzung in der jeweiligen Sprache bevorzugen, also nicht shell_exec(); oder exec(); verwenden sondern nativ in PHP.... Wobei ich ebenfalls kein Freund von shell_exec(); bin - wieso kannst du hier nachlesen: FAQ => Nützliche Links / Linksammlung => Befehle über PHP mit root Rechten ausführen (sudo webscript)


    Eine Anleitung mit Codebeispielen zum oben erwähnten, also Umsetzung über Python komplett ohne apache2 und PHP, findest du hier: FAQ => Nützliche Links / Linksammlung => [Python] Webserver, Websocket und ein bisschen AJAX


    Falls du es aber dennoch unbedingt über PHP realisieren willst solltest du dir folgendes durchlesen: FAQ => Nützliche Links / Linksammlung => PHP: Anleitung zum schalten von GPIO

  • Hallo zusammen,


    ersteinmal danke für eure Antworten!


    Quote from hyle

    Ich kann mir nicht vorstellen, daß man Dir hier eine fertige Lösung präsentiert.
    Du solltest schon selber etwas dafür tun, denn Deine Codeschnipsel sind gelinde gesagt nicht nur gefährliches Halbwissen sondern schon fast grenzwertig.


    Ich habe auch keine fertige Lösung erwartet. Habe mich vielleicht dahingehend etwas blöd ausgedrückt. Ich wollte lieber selbst einen Thread starten, anstelle mich weiter doof zu googlen ;) So war es gemeint.


    Vielen Dank schonmal für deine beiden Links, die werde ich mir mal zu Gemüte führen!
    Und der Code war auch hilfreich! Ich habe jetzt quasi eine Abfrage, die wie folgt aussieht:


    [code=php]<?php
    $filename = 'var/www/html/alarm.an';


    if (file_exists($filename)) {
    header("Location:status-an.html");
    } else {
    header("Location:status-aus.html");
    }
    ?>[/php]


    Warum auch immer leitet der mich aber immer auf die Status-aus.php... Egal, ob die Datei existiert oder nicht. Hast du eine Ahnung, woran das liegen kann?
    Die alarm.an wird mit der entsprechenden Seite erstellt. Da gibt es also kein Problem. Aber irgendwie scheint die Abfrage die Datei zu ignorieren... :(


    Quote from meigraf


    Mal andersrum gefragt: Über was schaltest du die Alarmanlage?
    Hat das zufällig etwas mit den GPIO zu tun?
    Wenn ja würde ich an deiner Stelle den Webserver lieber in Python umsetzen - das ist eigentlich recht einfach und ermöglicht einen weitaus bessere/einfacheren Umgang mit den GPIO's.


    Also die Alarmanlage (PIR-Sensor, Lautsprecher und Mailversand) wird über ein Python-Script gesteuert, dass auf meinem Pi liegt.
    Der PIR ist natürlich an die GPIO angeschlossen. Lautsprecher ist an dem Klinke Anschluss.


    Quote from meigraf


    Eine temporäre Datei zu schreiben um zu ermitteln ob die Alarmanlage an oder aus ist, wäre auch nicht sooo optimal. Wenn man solch einen Weg wählt sollte man aber lieber eine Umsetzung in der jeweiligen Sprache bevorzugen, also nicht shell_exec(); oder exec(); verwenden sondern nativ in PHP.... Wobei ich ebenfalls kein Freund von shell_exec(); bin - wieso kannst du hier nachlesen: FAQ => Nützliche Links / Linksammlung => Befehle über PHP mit root Rechten ausführen (sudo webscript)


    Eine Anleitung mit Codebeispielen zum oben erwähnten, also Umsetzung über Python komplett ohne apache2 und PHP, findest du hier: FAQ => Nützliche Links / Linksammlung => [Python] Webserver, Websocket und ein bisschen AJAX


    Falls du es aber dennoch unbedingt über PHP realisieren willst solltest du dir folgendes durchlesen: FAQ => Nützliche Links / Linksammlung => PHP: Anleitung zum schalten von GPIO


    Was wäre denn deiner Meinung nach besser, als eine temp-Datei zu erstellen, um den Status der Anlage zu überprüfen?
    Ein dauerhaft laufendes Script, wo eine Variable geändert wird? Kam mir jetzt so spontan in den Kopf.


    Die Geschichte mit shell_exec() habe ich noch nicht so ganz verstanden. Klar soll niemand anderes auf meinem Pi root Rechte haben, aber wie soll jemand daran kommen?
    Das erschließt sich mir noch nicht so richtig?


    Okay, ein Webserver komplett in python ist auch eine interessante Möglichkeit. Schaue ich mir mal in Ruhe an.
    Mir geht es nicht darum, auf Biegen und Brechen PHP zu nutzen. Das war nur der erstbeste (halbwegs funktionierende) Weg, den ich gefunden habe.

  • Naja basierend darauf das du bereits Python Scripts verwendest würde ich direkt dazu übergehen und den Webserver ebenfalls in Python umsetzen. Somit kannst du auf solch exec(); Sachen von PHP nämlich völlig verzichten und wie bereits erwähnt weitaus einfacher mit GPIO usw umgehen. Auch ob die Alarmanlage an ist usw lässt sich damit ganz einfach in einem Dictionary ablegen. Wenn die Alarmanlage über einen GPIO geschaltet wird bräuchtest du aber nicht mals das sondern fragst einfach nur den GPIO ab.
    Mir fehlen da aber weitere Details um da spezifischer drauf einzugehen...


  • Naja basierend darauf das du bereits Python Scripts verwendest würde ich direkt dazu übergehen und den Webserver ebenfalls in Python umsetzen. Somit kannst du auf solch exec(); Sachen von PHP nämlich völlig verzichten und wie bereits erwähnt weitaus einfacher mit GPIO usw umgehen. Auch ob die Alarmanlage an ist usw lässt sich damit ganz einfach in einem Dictionary ablegen. Wenn die Alarmanlage über einen GPIO geschaltet wird bräuchtest du aber nicht mals das sondern fragst einfach nur den GPIO ab.
    Mir fehlen da aber weitere Details um da spezifischer drauf einzugehen...


    Okay, ich hoffe hier kann ich dir die Details geben, die du brauchst :)


    Ich habe einen Pi, an welchen ein PIR-Sensor angeschlossen ist.
    Auf dem Pi habe ich ein Python-Script, welches folgende Zeilen beinhaltet:


    Dann habe ich einen Webserver, welcher durch den Aufruf einer Seite eben diese Datei erstellen soll.
    Die Alarmanlage ist also nur dann wirklich scharf, wenn das Script läuft UND der Webserver die Datei erstellt hat.

  • Das sind nicht unbedingt die Details die ich meinte ;)


    Was bezifferst du als Alarmanlage? Woraus besteht die? Was macht die? Wie steuerst du die?


    Nur ein PIR ist für mich keine Alarmanlage...




    PS: Bitte nicht Beiträge vollständig quoten/zitieren, vor allem wenn diese genau da drüber stehen.

  • Naja, als Alarmanlage bezeichne ich das System aus Pi, PIR, Lautsprecher (Sirene) und Mailversand. Wenn ich die Anlage scharf geschaltet habe, informiert Sie mich,dass sich Zuhause was bewegt, obwohl niemand da sein sollte. Es soll später noch eine PiCam dazukommen, welche mir ein Bild an die Mailadresse schickt und einen Livestream des Eingangsbereiches ermöglichen soll. Das fand ich für den Start aber etwas zu ambitioniert und habe mich daher bis jetzt auf den PIR mit Ton und Mail beschränkt.
    Steuern möchte ich die vom Handy aus, bzw möchte ich evtl. noch einen 3" Touchscreen mit verbauen, der das selbe Webinterface zeigt, wie ich es am Handy gerne hätte.
    Klappt mit dem Interface auch bisher ganz gut, auch außerhalb des WLAN. Natürlich soll das alles noch passwortgeschützt werden.


    Gesendet von meinem SM-G920F mit Tapatalk

  • Naja, dann fange doch erst mal damit an "Abschnitt 1" aus obiger Anleitung umzusetzen bzw bis dahin alles durchzulesen.


    Da ich 'bottle' bevorzuge gehe ich hier jetzt auch nur darauf ein.


    Du hast dann folgende Struktur:


    /home/pi/web_bottle.py
    /home/pi/templates/index.html
    /home/pi/static/jquery.min.js


    web_bottle.py ist dabei das Herzstück. Dort wird quasi alles weitere abgehandelt.


    Vorab aber noch eine Besonderheit:


    Das Script selbst (allgemein jedes, auch bash oder php Scripte) läuft in einem Thread. Scripts werden generell von oben nach unten, Zeile für Zeile, abgearbeitet.
    Setzt man jetzt im Script irgendwo ein sleep wird das Script angehalten und blockiert. In der Zeit kann das Script auf nichts anderes reagieren.... Kann man sich so vorstellen als würdest du von oben nach unten, Zeile für Zeile, mit dem Finger an einem Text entlang zeigen und sobald du ein 'sleep' liest bleibt dein Finger für die entsprechende Zeit stehen.


    Für einen PIR empfehle ich einen sog. Interrupt zu verwenden. Dadurch wird sofort auf ein Flankenwechsel reagiert. Dieser Interrupt wiederum wird quasi abgespalten und läuft in einem separaten Thread, kann also nicht von einem 'sleep' im Script beeinflusst werden. Und das hat eben zur Folge das ein Interrupt nahezu in Echtzeit auf eine Pegeländerung (von LOW auf HIGH, oder von HIGH auf LOW - jenachdem wie mans konfiguriert hat) reagiert.
    Ein Interrupt kann auf Steigende oder Fallende Flanke reagieren, oder auf beides. In Deinem Fall möchtest du aber ja nur eine Reaktion wenn Bewegung erkannt wurde, also kann man den anderen Fall, wenn Bewegungsende, eigentlich ignorieren. Ich bau hier jetzt aber trotzdem mal beides ein.


    Sobald 'bottle' gestartet wird ( über bottle.run() ) blockiert es das Script. Die Funktionen im Script können aber natürlich weiterhin aufgerufen werden, nur wenn eine Funktion dann das Script blockiert siehts schlecht aus...


    bottle (und auch tornado / Flask / Django usw) haben den Vorteil, das sie mit sog. Templates arbeiten und wenn ein Client diese ansurft wird die Webseite bzw html Seite jedes mal neu generiert/gerendert. Das ermöglicht es Python Variablen in den HTML Code einzufügen ähnlich wie bei PHP. Auch Python Code selbst kann man ins Template einfügen und kleineres verarbeiten lassen.


    In meiner Anleitung gehe ich aber noch einen Schritt weiter: Mithilfe einer permanenten Kommunikation über WebSocket kann man im Hintergrund Informationen abrufen und auf der Seite aktualisieren ohne die Seite neuladen zu müssen. Das funktioniert aber auch ohne WebSocket wie es in "Abschnitt 3" beschrieben wird.


    Aber Du musst ja nicht gleich von 0 auf 100 durchstarten ;)


    Mit bottle kannst du deine *.html und *.js sowie *.css Dateien weiterhin nutzen, einzig *.php musst du auf python umschreiben bzw eben weg lassen.


    Die Basis der web_bottle.py sieht also wie folgt aus => http://codepad.org/ieQc34zG


    Nun gehen wir daher und erweitern uns dieses Script ein bisschen: PIR Interrupt einfügen sowie ein globales Dictionary anlegen in dem wir abrufbare Informationen hinterlegen können.
    Eine PIR auf Basis von Interrupt sieht zum Beispiel so aus:
    [code=php]
    #!/usr/bin/python
    import time
    import signal
    from RPi import GPIO


    PIR_PIN = 24
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIR_PIN, GPIO.IN)


    def interrupt_event(pin):
    zeit = time.strftime('%d.%m.%Y %H:%M:%S')
    print '{} -> GPIO {} ausgeloest! Motion detected'.format(zeit, pin)


    def main():
    try:
    GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=interrupt_event, bouncetime=100)
    #keep script running
    signal.pause()
    except KeyboardInterrupt: # does not work if it runs in background.
    print "Quit"


    if __name__ == '__main__':
    main()
    GPIO.cleanup()
    print "Ende des Scripts"
    [/php]


    Davon brauchen wir aber nicht alles. Wir nehmen uns nur die GPIO Geschichte sowie die interrupt_event Funktion und fügen das entsprechend in die web_bottle.py ein - ich schreib das aber auch noch ein kleines bisschen mehr um, auch ich lerne selbstverständlich stetig neues ;)


    => http://codepad.org/E8Pk1Jnq
    [code=php]
    #!/usr/bin/python2
    from __future__ import print_function
    import os.path
    import bottle
    import time
    import json
    from RPi import GPIO


    #------------------------------------------------------------------------


    setting=dict()
    setting["page_title"] = "Alarmanlage"
    setting["no_motion_delay"] = 60
    setting["DEBUG"] = True


    PIR_PIN = 24
    GPIO.setmode(GPIO.BCM)


    #------------------------------------------------------------------------



    def printD(message):
    if setting["DEBUG"]:
    print(message)



    @bottle.route("/")
    def IndexHandler():
    values = {
    "debug": setting["DEBUG"],
    "setting": setting,
    }
    return bottle.template("index.html", values)



    @bottle.route("/cmd")
    def CommandHandler():
    setting["armed"] = bottle.request.query.armed or setting["armed"]
    return bottle.redirect("/")



    @bottle.route("/data/")
    def TelemetryHandler():
    printD("Data Request.")
    bottle.response.content_type = "application/json"
    data=dict()
    data["ARMED"] = setting["armed"]
    if setting["motion"]:
    data["MOTION"] = setting["motion"]
    if setting["last_motion_time"]:
    data["MOTION_TIME"] = time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(int(setting["last_motion_time"])))
    return json.dumps(data)



    @bottle.route("/static/<filename:path>")
    def StaticHandler(filename):
    if filename.endswith(".css"):
    bottle.response.content_type = "text/css"
    elif filename.endswith(".js"):
    bottle.response.content_type = "text/javascript"
    elif filename.endswith(".png"):
    bottle.response.content_type = "image/png"
    return bottle.static_file(filename, root=os.path.join(os.path.dirname(__file__), "static"))



    @bottle.error(404)
    def error404(error):
    return "Error 404: Nothing here, sorry."



    def interrupt_event(pin):
    if setting["armed"] == "Yes":
    zeit = time.strftime("%d.%m.%Y %H:%M:%S")
    if GPIO.input(PIR_PIN):
    setting["last_motion_time"] = time.time()
    if not setting["motion"] == "Yes":
    setting["motion"] = "Yes"
    print("{} -> Motion detected!".format(zeit))
    else:
    if setting["motion"] == "Yes" and time.time() > (setting["last_motion_time"] + setting["no_motion_delay"]):
    setting["motion"] = "No"



    try:
    setting["motion"] = "No"
    setting["last_motion_time"] = None
    setting["armed"] = "No"
    GPIO.setup(PIR_PIN, GPIO.IN)
    GPIO.add_event_detect(PIR_PIN, GPIO.BOTH, callback=interrupt_event, bouncetime=100)
    bottle.TEMPLATE_PATH.insert(0, os.path.join(os.path.dirname(__file__), "templates"))
    bottle.run(host="0.0.0.0", port=8080, quiet=False, debug=bool(setting["DEBUG"]))
    except (KeyboardInterrupt, SystemExit):
    GPIO.cleanup()
    print("\nQuit\n")


    #EOF
    [/php]


    Sieht vielleicht etwas wild aus... Das besondere hieran ist eigentlich nur folgendes:

    • Die von apache2 & Co bekannte index.* wird in der Funktion IndexHandler behandelt.
      Hier wird der index.html (die ich hiernach zeige) quasi mit den Python Variablen gerendert und für den Client vorbereitet bzw übergeben.
    • Die Alarmanlage wird durch aufrufen der URL " /cmd?armed=Yes " scharf geschaltet.
      Nur wenn die Alarmanlage scharf geschaltet ist wird der Code innerhalb der Interrupt Callback ausgeführt; sprich, der Timestamp der letzten Bewegung wird gespeichert und auch setting["motion"] auf Yes gestellt.
    • Angenommen, jemand betritt den Raum und die Anlage ist Scharf, dann wird setting["motion"] = "Yes" eingestellt. Bewegt derjenige sich jetzt für 60 Sekunden wird ja immer wieder ein neuer Interrupt ausgelöst, dann wird aber nur die Zeit aktualisiert. Hört der Eindringling dann auf sich zu bewegen wird setting["motion"] = "No" gestellt, aber eben nur dann, dafür ist "no_motion_delay" ... Das war jetzt nur sone spontane Idee von mir - ob das auch wirklich so funktioniert weiß ich aber nicht :blush:
    • Die Webseite kann permanent Daten abrufen bzw aktualisieren, über die URL /data/. Das wird über die control.js geregelt, die läuft dann ja auf dem Client.


    Die templates/index.html sieht dann so aus => http://codepad.org/vdbPItcG
    [code=php]
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="de">
    <head>
    <title>{{ setting["page_title"] or "Alarm" }}</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="robots" content="DISALLOW">
    <script src="static/jquery.min.js"></script>
    <script src="static/control.js" type="text/javascript"></script>
    <link href="static/stylesheet.css" rel="stylesheet">
    </head>
    <body>
    <div id="header"> </div>
    <div id="content">
    % if setting["motion"] == "Yes":
    % MOTION_TIME = time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(int(setting["last_motion_time"])))
    % else:
    % MOTION_TIME = ""
    % end
    <p>Armed: <span id="ARMED">{{ ARMED }}</span></p>
    <a href="/cmd?armed=Yes" title="Alarmanlage scharfschalten">Arm</a>&nbsp;
    <a href="/cmd?armed=No" title="Alarmanlage ausschalten">Disarm</a><br/>
    <p>
    Motion detected: <span id="MOTION">{{ MOTION }}</span><br/>
    Last Motion Time: <span id="MOTION_TIME">{{ MOTION_TIME }}</span>
    </p>
    <br/>
    <p><div id="Log" style="text-align:left; width:100%;">&nbsp;</div></p>
    </div>
    <div id="footer"> </div>
    </body>
    </html>
    [/php]


    Hier sind 3 Besonderheiten:
    1) Ich hab da direkt Python Code eingefügt, die Zeilen beginnen mit % und werden von bottle vorher verarbeitet bzw während des renderns des Templates. Siehe dazu auch https://bottlepy.org/docs/dev/stpl.html#embedded-python-code
    2) Auch werden Python Variablen direkt eingebettet bzw eingefügt - das sind die {{ bla }} Teile ;)
    3) Die <span> Teile werden später von jQuery aktualisiert, mithilfe von AJAX.


    Die static/control.js sieht so aus => http://codepad.org/DtW4YGPY
    [code=php]
    if (typeof(String.prototype.strip) === "undefined") {
    String.prototype.strip = function() {
    return String(this).replace(/^\s+|\s+$/g, '');
    };
    }


    function isset(strVariableName) {
    try {
    eval( strVariableName );
    } catch( err ) {
    if ( err instanceof ReferenceError )
    return false;
    }
    return true;
    }


    function sleep(millis, callback) {
    setTimeout(function() { callback(); } , millis);
    }


    //source of: http://www.html5tutorial.info/html5-range.php
    function printValue(sliderID, textbox) {
    var x = document.getElementById(textbox);
    var y = document.getElementById(sliderID);
    x.value = y.value;
    }


    //----------------------------------------------------------------



    var telemetryTimer;
    $(document).ready(function() {
    // start Main Timers
    telemetryTimer = setTimeout(get_telemetry, 1000);
    });



    function get_telemetry() {
    $.getJSON("/data/")
    .fail(function() {
    console.log("Error processing get_telemetry");
    clearTimeout(telemetryTimer);
    })
    .done(function(data) {
    $.each(data, function(id,val) {
    if (document.getElementById(id) !== null) {


    if (id == "ARMED") {
    document.getElementById(id).innerHTML = val;
    } else if (id == "MOTION") {
    document.getElementById(id).value = val;


    } else {
    document.getElementById(id).innerHTML = val;
    }
    }
    })
    telemetryTimer = setTimeout(get_telemetry, 2000);
    });
    }
    [/php]
    ...Details dazu siehe besagte Anleitung.



    Vorsichtshalber hab ich dir die ganze Dateien inkl. Verzeichnisstruktur aber auch noch an den Beitrag angehängt :angel:


    EMail Versenden und Sound abspielen kannst du ebenfalls über Python realisieren.
    Für eMail zum Beispiel:
    [code=php]
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    # v0.1 by meigrafd 02.2015
    #
    import smtplib


    mailServer = 'pop.gmail.com'
    mailPort = 587
    mailLogin = 'xxx@gmail.com'
    mailPass = 'xyz'
    mailSendFrom = mailLogin
    mailSendTo = 'target@email.com'
    mailTLS = True
    mailDebug = False


    def sendemail(from_addr, to_addr, subject, message):
    try:
    header = 'From: %s\n' % from_addr
    header+= 'To: %s\n' % to_addr
    header+= 'Subject: %s\n\n' % subject
    message = header + message
    conn = smtplib.SMTP(mailServer, mailPort)
    if mailDebug:
    conn.set_debuglevel(True) #show communication with the server
    if mailTLS:
    conn.starttls()
    conn.login(mailLogin, mailPass)
    error = conn.sendmail(from_addr, to_addr, message)
    if not error:
    print "Successfully sent email"
    except Exception, e:
    print "\nSMTP Error: " + str(e)
    finally:
    if conn:
    conn.quit()


    if __name__ == '__main__':
    sendemail(mailSendFrom, mailSendTo, 'Bla!', 'Hallo!\nGruesse vom PI')
    [/php]


    Und beim Sound abspielen sprachst du von einer Sirene, da spielst du aber doch nichts ab oder? :s



    Naja. Viel Erfolg!



    //EDIT: Der Code liegt nun auch hier: https://github.com/meigrafd/Sa…aster/_bottle/Alarmanlage

  • Oh wow, was für ein Buch als Antwort :) Da arbeite ich mich erstmal durch. Beim ersten überfliegen, klingt es schon ziemlich gut. Jedenfalls das, was ich bisher verstanden habe xD
    Die "Sirene" ist aktuell eine .wav Datei, welche auf dem Pi liegt. Daher habe ich abspielen geschrieben. Weiß noch nicht genau, wie das später in der finalen Version realisiert wird.
    Danke dir auf jeden Fall schon mal für deine Zeit! Ich melde mich wieder :)

  • So, ich habe jetzt ein komplett neues Jesse mit Pixel aufgesetzt und quasi jungfräulich gestartet.
    Alle deine Dateien kopiert und die web_bottle.py ausgeführt.
    Wenn ich dann auf localhost:8080 gehen möchte, bekomme ich folgende Fehlermeldung:


    Ich weiß nicht, ob es damit zusammenhängt, dass ich den PIR nicht an die GPIOs angeschlossen habe.
    Ist hier auf der Arbeit nicht so cool, seinen ganzen Versuchsstand mitzubringen :D


    Generell den Server aufsetzen klappt bisher mit der Test-Variante aus deiner Anleitung. Es wird immer eine andere "Random"-Zahl angezeigt.

  • Klasse! Das funktioniert schonmal. Danke dir! Jetzt probiere ich das noch mit dem PIR und versuche mal die Seite etwas nach meinen Wünschen zu verschönern :bravo2:


    Ich habe jetzt einiges geändert und habe nun folgenden Code in der web_bottle.py:



    Ich musste hier tatsächlich mit einem sleep im Code arbeiten, da sonst die entdeckte Bewegung bei setting["motion"] sich nicht zurückgesetzt hat. Das Problem an meigrafd's Code war, dass die Variable nur zurückgesetzt würde, wenn der Sensor ausgelöst wird. Also in der interrupt_event(pin): Funktion.


    Die index.html sieht bisher so aus:




    Was mir jetzt aber noch immer fehlt, ist die Möglichkeit mit ein und demselben Button den Status von armed auf disarmed zu wechseln. Da habe ich auch noch keine Lösung für gefunden :(


  • Was mir jetzt aber noch immer fehlt, ist die Möglichkeit mit ein und demselben Button den Status von armed auf disarmed zu wechseln. Da habe ich auch noch keine Lösung für gefunden :(


    Probier einfach mal eine Abfrage in der index.html einzubinden - also Python. Je nachdem ob setting["armed"] auf "Ja"steht oder eben nicht änderst du den HTML Code ;)


    Du hast aber auch ein paar Fehler im index.html:
    - Im head Abschnitt hat <h1> o.ä. nichts zu suchen
    - Du hast zwei <body>
    - Wofür hat du "import time" hinzugefügt?


  • Quote from meigrafd


    Du hast aber auch ein paar Fehler im index.html:
    - Im head Abschnitt hat <h1> o.ä. nichts zu suchen
    - Du hast zwei <body>
    - Wofür hat du "import time" hinzugefügt?


    Das kann sehr gut sein, ist ja auch mein erstes html Projekt :)


    Ich hatte jetzt gedacht Head wäre der bereich für Überschriften.
    Gibt es einen Grund, warum die da nicht hingehört? Tut ja der Funktionalität keinen Abbruch.


    Meinst du einmal das <body> und in der nächsten Zeile <body style="backgroud......> ?
    Ich hatte für das Hintergrundbild der Seite diesen Befehl ergoogelt und den einfach eingefügt.
    Ist es schlimm, dass ich den body nur ein mal schließe?


    Import time brauchte ich, weil ich eine Fehlermeldung bekommen habe.
    Schade, dass ich meine eigene Änderungshistorie nicht ansehen kann, dann könnte ich noch nachschauen, was genau es war.
    Ich meine der Fehler kam, wenn sich setting["motion"] auf "ja" gesetzt hat. Dann wird ja diese Zeile angesprochen.

    Code
    %    MOTION_TIME = time.strftime("%d.%m.%Y %H:%M:%S", time.localtime(int(setting["last_motion_time"])))


    Und die löste einen Fehler aus, weil "time.strftime" nicht definiert war. Nach dem import von time im index ging es.


    Boah genail! Ich hab so rumprobiert mit ner Abfrage, hab es aber absolut nicht hinbekommen!
    Jetzt funktioniert es! Vielen Lieben Dank für die Hilfe! :bravo2: :danke_ATDE: :bravo2:


    Ich bin mir aber sicher, dass ich mich nochmal melden werde, sobald es an die Kamera und den Ton geht =)

  • So, nach einer längeren Kunstpause hab ich in den letzten Tagen wieder Zeit gefunden um hier weiter zu machen.


    Die Funktionen sind nun folgende:


    - Webinterface zur Steuerung
    - Livestream mit Passwort über Webinterface
    - Scharf schalten & deaktivieren über Webinterface oder am Gerät per Knopfdruck
    - Alarm eingeschaltet -> bei Bewegungserkennung wird ein Foto per Mail verschickt
    - letzte Bewegung (bei eingeschaltetem Alarm) wird im Webinterface angezeigt
    - Neustart des Pi über Webinterface
    - Display zeigt an, wenn Livestream aktiviert oder deaktiviert wird
    - Display zeigt an, wenn Alarmanlage aktiviert oder deaktiviert wird
    - Display zeigt an, wenn ein Foto gemacht wurde (wann es erstellt wurde und eine Info, dass es per Mail verschickt wurde)
    - Display zeigt an, wenn der Pi rebooted wird


    Der Schaltplan sieht wie folgt aus: