Schildkrötenüberwachung - Vorstellung des aktuellen Stands

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

    in letzter Zeit habe ich doch einige Fragen hier gestellt und jetzt will ich euch mal zeigen, mit was ich mich die letzten Wochen beschäftigt habe.

    Ziel und Problemstellung:

    Bei den Eltern meiner Freundin haben wir im Garten ein Schildkrötengehege gebaut. Es besteht aus einem großen Außenbereich und einem kleineren, beheizten "Wohnbereich", der mit einer Türe vom Rest abgetrennt werden kann. In der Jahreszeit, in der sich Nachts die Temperaturen unter 10°C bewegen können, die Schildkröten aber noch nicht in den Winterschlaf gehen, müssen wir danach schauen, dass sie Abends in ihrem beheizten Wohnbereich sind. Geheizt wird mit speziellen Wärmelampen, die über Temperaturfühler gesteuert sind. Doch was ist wenn so eine Lampe kaputt geht? Wann ist die Zeit erreicht, in der die Lampen das Gehege nicht mehr genügend heizen können und die Schildkröten umziehen müssen in ihre Wintersuit? Naja ich war nicht so begeistert davon, das ich morgens um halb 7 bei den Schildkröten halten musste um zu sehen wie die Temperatur ist. Also beschloss ich einen Raspberry mit Temperatursensor zu bestücken und diesen die Arbeit erledigen zu lassen. Das ganze sollte auf einer App angesehen werden können. Davon bin ich mit meinem Wissen noch weit entfernt, deswegen haben wir uns auf eine Webseite geeinigt. Die aktuelle Temperatur so wie ein 12 stündiger Temperaturverlauf soll angezeigt werden. Beim unterschreiten einer minimalen Temperatur wäre es schön, wenn sie eine Benachrichtigung bekommt. Das Problem war überschaubar.

    Wenn es kälter wird essen die Schildkröten nicht mehr soviel, muss man dann täglich hinfahren und nachsehen ob noch Essen drin ist oder muss man immer die Schwiegermutter darum bitten? Ne, die Kamera für den Pi ist ja nicht teuer und es genügt wenn diese Fotos aufnimmt von denen immer das aktuelle auf der Webseite zu sehen ist. Nächstes Problem abgehackt, sie war zufrieden, ich nicht mehr. ich habe an der Geschichte richtig Spass gefunden. Schnell war mit auch klar, das es nicht zumutbar ist, dass die Schwiegermutter morgens immer die Türe in den Außenbereich öffnen muss, weil wir arbeiten sind. Das soll ein Servomotor erledigen. Da ich an den Schildkröten keinen GPS-Tracker anbringen durfte um die Türe automatisch zu schließen, wenn Abends alle drin sind, haben wir uns auf einen Taster geeinigt, der die Türe wieder schließt.

    Zum Schluss kam noch die Idee auf, die Vorbereitungen die für den Winterschlaf nötig sind, in einem Art News-Ticker auf der Webseite darzustellen.

    Hardware:

    -Raspberry Pi Zero WH

    -DHT22 Temperatursensor

    -Raspberry Pi Camera V2

    -Jamara Q7 Standard Servomotor

    -USB-Stick auf dem die Sensordaten und Kamerabilder gespeichert werden

    Problemlösung:

    Die Arbeiten an den Programmen und Webseiten sind soweit abgeschlossen, das sie funktionieren.

    Die Webseite sieht so aus:

    Das "Lampen-Bild" ist das Foto, dass die Kamera macht. Das Bild der Schildkröte mit "Zu" wechselt, je nach dem ob das Gehege auf oder zu ist.

    Die *.php Datei sieht so aus:

    Spoiler anzeigen

    <!DOCTYPE html>

    <html lang="de">

    <head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Schildi-Land</title>

    <style>


    media only screen

    and (min-device-width: 320px)

    and (max-device-width: 759px)

    and (-webkit-min-device-pixel-ratio: 2) {


    div#tortoise { width: 4em; margin: auto; display: grid; grid-template-columns: auto auto auto auto; justify-content: center; }

    div#hello { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#campicture { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#statustemp { width: 6em; margin: auto; display: grid; grid-template-columns: auto auto; justify-content: center; }

    div#dia { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#ticker { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    img#selfie { display: block; width: 5em; height: 3.5em; margin: auto; }

    img#welcome { display: block; width: 20em; height: 2em; margin: auto; padding-top: 1em; }

    img#cam { display: block; width: 12em; height: 12em; margin: auto; padding-top: 1em; }

    img#status { display: block; width: 7em; height: 10em; margin: auto; }

    iframe#temperature { display: block; width: 12em; height: 10em; margin: auto; }

    iframe#diagram { display: block; width: 19.5em; height: 10em; margin: auto; }

    iframe#news { display: block; width: 19.5em; height: 40em; margin: auto; }

    }


    media only screen

    and (min-device-width: 760px)

    and (max-device-width: 1000px)

    and (-webkit-min-device-pixel-ratio: 2) {

    div#tortoise { width: 4em; margin: auto; display: grid; grid-template-columns: auto auto auto auto; justify-content: center; }

    div#hello { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#campicture { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#statustemp { width: 6em; margin: auto; display: grid; grid-template-columns: auto auto; justify-content: center; }

    div#dia { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#ticker { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    img#selfie { display: block; width: 7em; height: 5.5em; padding-right: 3.3em; padding-left: 3.3em; }

    img#welcome { display: block; width: 48em; height: 5em; margin: auto; padding-top: 1em;}

    img#cam { display: block; width: 24em; height: 24em; margin: auto; padding-top: 1em;}

    img#status { display: block; width: 9em; height: 12em; margin: auto; }

    iframe#temperature { display: block; width: 14em; height: 14em; margin: auto; }

    iframe#diagram { display: block; width: 45em; height: 14em; margin: auto; justify-content: center;}

    iframe#news { display: block; width: 45em; height: 42em; margin: auto; }

    }

    media screen

    and (min-width: 1410px) {

    div#tortoise { width: 4em; margin: auto; display: grid; grid-template-columns: auto auto auto auto; justify-content: center; }

    div#hello { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#campicture { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#statustemp { width: 6em; margin: auto; display: grid; grid-template-columns: auto auto; justify-content: center; }

    div#dia { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    div#ticker { width: auto; margin: 0; display: grid; grid-template-columns: auto; justify-content: center; }

    img#selfie { display: block; width: 15em; height: 12em; padding-right: 1.5em; padding-left: 1.5em; }

    img#welcome { display: block; width: 70em; height: 5em; margin: auto; padding-top: 5em;}

    img#cam { display: block; width: 35em; height: 35em; margin: auto; padding-top: 5em;}

    img#status { display: block; width: 20em; height: 20em; margin: auto; padding-right: 2em; padding-top:5em; }

    iframe#temperature { display: block; width: 35em; height: 35em; margin: auto; padding-left: 2em; }

    iframe#diagram { display: block; width: 120em; height: 30em; margin: auto; }

    iframe#news { display: block; width: 60em; height: 40em; margin: auto; padding-top: 10em; }


    </style>

    </head>

    <body>

    <div id="tortoise">

    <img id="selfie" src="Spike.png">

    <img id="selfie" src="Whisky.png">

    <img id="selfie" src="Willy.png">

    <img id="selfie" src="Rosi.png">

    </div>

    <div id="hello">

    <img id="welcome" src="welcome.png" alt="Begrüßung">

    </div>

    <div id="campicture">

    <img id="cam" src="cam.jpg" alt="Kamerabild">

    </div>

    <div id="statustemp">

    <img id="status" src="status.png" alt="Aktuelle_Temperatur">

    <iframe id="temperature" src="http://192.168.0.67:3000/d-solo/2qYQh4z…h=10s&panelId=4"

    frameborder="0"></iframe>

    </div>

    <div id="dia">

    <iframe id="diagram" src="http://192.168.0.67:3000/d-solo/2qYQh4z…h=10s&panelId=8" frameborder="0"></iframe>

    </div>

    <div id="ticker">

    <iframe id="news" src="http://192.168.0.67:3000/d-solo/2qYQh4z…=10s&panelId=10" frameborder="0"></iframe>

    </div>

    </body>

    </html>

    Visualisiert wurde mit Grafana. Die Sensordaten werden in eine MySQL-Datenbank geschrieben und von dort dann wieder abgerufen.


    Für die Funktionalität sind zwei Python-Programme entstanden. Beide werden über systemd-Units gesteuert. Jeden Morgen startet das "erste" Programm zu einer definierten Uhrzeit und bewegt den Servomotor um die Türe zu öffnen. Da ich keine passende Lösung gefunden habe, wie ich das Bild "Zu" und "Offen" in Abhängigkeit des Servomotos ändern kann, habe ich beide Bilder in einem Ordner und je nach Position werden die Bilder entsprechend umbenannt. An dieser Stelle wäre ich euch für eine ordentlichere Lösung dankbar. Dieses Programm sieht so aus:

    Das nächste Programm, dass die Kamera und den Sensor steuert und je nach Temperaturdaten E-mails versendet, wird jede viertel Stunde aufgerufen und sieht so aus:

    Es wird nur einmal eine E-mail gesendet. Das heißt fällt der Wert unter die minimale Temperatur oder steigt über die Maximale, dann schaut Python erst in die Datenbank ob der Wert davor auch schon außerhalb der Grenzen war, wenn nicht wird die E-mail gesendet, wenn ja ist eine erneute E-mail nicht notwendig. So meine Gedankengänge.

    Was noch zu tun ist:

    -Die Kamerabilder werden noch in '/var/www/html/' gespeichert, ich muss noch rausfinden, wie ich dem Pi sagen kann, dass er das Bild von einem anderen Pfad abrufen soll.

    -Eine Lösung für das Auf-Geschlossen-Problem finden.

    -DIe Mechanik für das Türe öffnen konstruieren und bauen.

    -Mein für mich größtes Problem wird sein, das Ganze über einen VPN-Tunnel so öffentlich zu machen, das wir die Webseite von überall sehen können.

    Was das ganze Projekt kippen könnte:

    Durch meine Begeisterung und Freude habe ich glatt vergessen, dass der W-lan Empfang am Schildkrötengehege sehr schlecht sein könnte. Eventuell gibt es irgendwelche Verstärker :conf:

    Habe jetzt ziemlich viel geschrieben und weis gar nicht mehr ob ich alles erwähnt habe, was ich wollte :shy:

    Wer sich das bis hier her durchgelesen hat und Kritik/Verbesserungen aller Art hat, auch wenn es nur ein unbedeutender Schönheitsfehler im Programm ist, der darf mir das sehr gerne sagen. Bin nach bestem Wissen und Gewissen vorgegangen und hoffe das ich alle Konvektionen eingehalten habe und die aktuellen "Programmbefehle" verwendet habe.

    Ansonsten wenn keiner was schreibt, lebe ich nach dem Mottto: "NIchts gesagt ist genügend gelobt" :lol:

    Wenn die Mechanik fertig ist, gibt es einen Testaufbau. Ich werde berichten.

    Grüße

    Dennis

    Edit am 20.11: Absolute Pfade in die E-mail Abfrage hinzugefügt.

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

    3 Mal editiert, zuletzt von Dennis89 (20. November 2020 um 19:04) aus folgendem Grund: Schönheitsfehler

  • Schildkrötenüberwachung - Vorstellung des aktuellen Stands? Schau mal ob du hier fündig wirst!

  • Cool, hast ja doch PiGPIOFactory verwendet! :cool:

    Ja, ansonsten hätte ich 'servo' zweimal erzeugen müssen, da der Motor im Stillstand gezittert hat. Nach etwas googln war es dann auch gar nicht mehr so wild :thumbup:Wusste bei meinem ersten Versuch nicht, das ich 'pigpiod' aktivieren muss.


    :wink: Da hat es im ersten Skript am Ende von Zeile 16 ein kleines Stück abgeschnitten.

    Danke, wurde verbessert :thumbup: Eine '#' hatte im Shebang auch gefehlt :stumm:

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

    • Offizieller Beitrag

    Ich bin mir gerade nicht sicher, ob ich es richtig im Hinterkopf habe, aber

    Python
    factory = PiGPIOFactory(host='192.168.0.67')

    die Angabe von host=... bezieht sich imho auf einen RPi, der remote gesteuert werden soll und dürfte hier lokal nicht nötig sein. Die Klammern müssen aber sein, also so:

    Python
    factory = PiGPIOFactory()

    Wie gesagt, bin gerade nicht sicher, aber versuchs mal. Dann wäre imho die Aktivierung von Remote-GPIO, die Du vermutlich gemacht hast um den PiGPIO-ServerDaemon zu starten auch nicht nötig.

  • Du hast fast recht :)

    Habe die IP entfernt, Remote-GPIO in 'raspi-config' wieder deaktiviert und 'systemctl disable pigpiod' ausgeführt. Pi neugestartet und es funktionierte nicht.

    Die Fehlermeldung fragte mich ob ich 'pigpiod' aktiviert habe. Nach der Aktivierung von 'pigpiod' funktionierte es dann.

    Danke:)

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

    • Offizieller Beitrag

    Du hast fast recht

    Immerhin 75% Trefferquote! :lol: Aber das ist auch schon länger her, als ich mit pigpio gespielt hatte und damit auch hauptsächlich die Remotefunktion.


    Linus Danke! Ich hatte die Doku überflogen, das konkrete Beispiel aber nicht gesehen und deshalb kam Prosa raus. ;)

  • Nach den letzten Tagen brauchte mein Hirn mal etwas Pause von Pixel und Array's :X :lol:

    Da ich bestimmt nicht gelobt werde, wenn das Schildkrötengehege 10 Bohrlöcher hat von denen nur 2 passen, habe ich heute mal die Anbindung vom Servomotor zur Türe konstruiert. Nach dem es im CAD gut aussah, habe ich mich gleich mal ran gemacht und einen Versuch aufgebaut. Zwei Holzstücke, ein Schanier und eine provisorische Motorbefestigung stellen das Gehege dar. Mit etwas Rest-Aluminium das ich noch in der Werkstatt habe, habe ich den Prototyp der Anbindung gebaut. Und es funktioniert :bravo2:

    Hab mich dieses Mal für ein Video entschieden, mit Bildern kann jeder sagen, das es funktioniert ^^

    https://www.dropbox.com/s/7nhm3x4691uc…-00-13.mp4?dl=0

    Da ich die Maße jetzt habe, kann ich mir noch überlegen, ob die Anbindung aus 1.4301 gelasert wird oder ob ich es mit 3D-Druck realisiere.


    Ach übrigends, der Raspberry Pi lieferte nebenher super Unterhaltung dank RadioBob und dem DAB+ Modul 8)

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

Jetzt mitmachen!

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