Bewegende Momente

Bewegungsmelder an einen Wi-Fi RGB(WW/CW) LED-Controller anbinden

Für mein Badezimmer finde ich doch mein normales Licht etwas hell, weshalb eine indirekte LED Beleuchtung her musste die auch in der Farbe variabel einstellbar ist. Alles kein Hexenwerk aber es sollte auch mit meiner bestehenden OpenHAB 3 über alle Inputs steuerbar sein und ein schönes Nachlicht hergeben damit man auch Nachts sicher unterwegs ist ohne zu stark aufzuwachen.

Somit waren die Anforderungen recht schnell klar:

  • Gute Anbindung an OpenHAB (3)
  • Viel Power um auch lange LED Strips verwenden zu können
  • Möglichst gutes Privacy Verhalten (schließt das China-Zeugs aus)
  • Es sollte nur bei Bedarf leuchten (z.B. mit Bewegungsmelder)

Nun gibt es bei Amazon einige Wi-Fi RGB LED Controller die alle vielversprechend aussahen. All diese Controller basieren auf mehr oder weniger dem gleichen Chipsatz ESP8266 auf welchem es eine breite Masse an alternativer Firmware gibt. Für mich ist der Tasmota die Wahl der Dinge, aber es gibt bestimmt auch andere gute Derivate. Mit ESPurna habe ich jedoch keine gute Erfahrung gemacht.

Mit dieser alternativen Firmware ist bereits der erste große Schritt gemeistert und die No-Privacy China-Firmware kann entfernt werden. Zudem bietet diese Firmware die Möglichkeit für eigene Erweiterungen („Rules“ / Scripting) und kann über MQTT angesteuert werden.

Für meine Verwendung habe ich einen größeren Controller ausgewählt, da dieser viel Power bietet, Schraubterminals besitzt und im Gehäuse genügend Platz zum basteln und. tüfteln ist.

Nun kommen wir aber zum interessanten Teil der Arbeit: Und zwar soll das Licht ja auch nicht die ganze Nacht leuchten und nur bei Bedarf angehen. Und zwar das nur für die Nacht.

Dazu kommen ein paar zusätzliche Anpassungen dazu:

  • Ein Bewegungsmelder muss an den LED Controller angebunden werden um Bewegungen in der Umgebung wahrzunehmen
  • Die Controllersoftware muss erweitert werden um die LEDs bei Bewegung einzuschalten und für eine bestimmte vorkonfigurierte Zeitspanne eingeschaltet. Dieser Teil sollte auch deaktivierbar (Tag/Nacht) sein.
  • In OpenHAB gibt es über das Astro Binding für den aktuelle Standort minutengenaue Angaben zum Sonnenunter- und -aufgang. OpenHAB soll so erweitert werden, so dass dieses die Steuerung im Controller zum richtigen Zeitpunkt aktiviert (Sonnenuntergang) und deaktiviert (Sonnenaufgang) wird.

PIR Sensor an den Wi-Fi RGB LED-Controller anbinden

TODO

Ich habe mich für die PIR-Sensoren AM312 (z.B. als 5er-Pack bei Amazon) entschieden das diese mit 3,3 V ausreichend versorgt werden und einfach einen Schließerkontakt bei Bewegung haben. Nachteil gegenüber einigen anderen ist, dass diese nicht einstellbar sind. Für diesen Use-Case sollte dies aber nicht von belang sein.

Belegung AM312

Auf der Unterseite des LED-Controllers befinden sich einige Pins die zum flashen aber auch zum herausführen der Stromversorgung genutzt werden können

Abzwacken der Stromversorgung für den PIR-Sensor + temporäre Stiftleiste zum Flashen

Die Stiftleiste die auf IO, RX und TX geht ist ausschließlich temporär zum erstmaligen Flashen der Tasmota Firmware gedacht und wird anschließend wieder entfernt.

Nun muss noch ein Plätzchen für den Sense-PIN des PIR Moduls gefunden werden. Hierfür habe ich den GPIO 4 ausgewählt da dieser anscheinend noch nicht belegt ist (siehe Grafik)

image
Belegung ESP Wi-Fi Chipsatz auf dem LED Controller

Dieser wird auf der Vorderseite direkt an das ESP Breakout-Board angelötet

Anlöten an den GPIO 4 des ESP Breakout-Boards auf der Vorderseite

GPIO Konfiguration in Tasmota mit Mapping von GPIO4 (PIR) auf Switch_1

Falls nicht nur RGB sondern auch WW (Warm White) bzw. CW (Cold White) angebunden werden soll, müssen diese GPIOs auch noch konfiguriert werden. Es empfiehlt sich aber nur die benötigten Ausgänge zu konfigurieren, da Tasmota anhand der Konfiguration die Farben mischt.

Anpassung Software auf dem Controller

Die Anpassung auf dem LED Controller habe ich in zwei Rules aufgeteilt. Dies kommt daher dass sich Rules einfach ein- und ausschalten lassen und ich damit die ganze Funktion („schalte Licht bei Bewegung an“) ausschalten kann während noch notwendige Funktionalitäten in der anderen Rule aktiv sind. Eine Rule setze ich also zur Beobachtung des Status, wie z.B. Events/Veränderungen die über MQTT oder des ablaufenden Timers ein, also die Funktionen die immer aktiv sein sollen.

RULE2
ON event#PIR1-STATE==?
DO
 VAR1 %value%
ENDON
ON event#PIR1-TIMEOUT>0
DO
 VAR2 %value%
ENDON
ON VAR1#State==?
DO BACKLOG
 RULE3 %value%;
 Publish stat/%topic%/PIR1-STATE %value%
ENDON
ON VAR2#State>0
DO
 Publish stat/%topic%/PIR1-TIMEOUT %value%
ENDON
ON Rules#Timer==3
DO
 Power1 OFF
ENDON

Man sieht hier gut dass die Rule3 je nach Zustand von Var1 gesetzt wird. Var1 nutze ich somit zum (de)aktivieren der Bewegungsmelderfunktion. Diese Variable wird wiederum von dem MQTT Event „PIR1-STATE“ verändert. Zudem wird das Licht ausgeschalten wenn der Timer 3 abläuft.

Eine weitere Rule soll rein auf die Bewegungen lauschen und somit auf Veränderungen an dem GPIO 4, welcher durch die vorige Konfiguration auf „Switch1“ gemapped wurde. Die Veränderungen werden auch über MQTT announced und wenn der Switch1 auf ON geht (== Bewegung erkannt) wird zusätzlich Timer 3 auf die in Var2 festgelegte Zeit gesetzt. Dadurch kann man einen Nachlauf nach der zuletzt erkannten Bewegung sicherstellen.

RULE3
ON Switch1#State==ON
DO BACKLOG
 Power1 %value%;
 RuleTimer3 %VAR2%;
 Publish stat/%topic%/PIR1-MOTION %value%
ENDON
ON Switch1#State==OFF
DO
 Publish stat/%topic%/PIR1-MOTION %value%
ENDON

Im folgenden noch einige Standardwerte die einmalig definiert werden sollten. Der Rest kann dann über MQTT gesteuert werden.

BACKLOG
 RULE2 ON;
 RULE3 OFF;
 VAR1 OFF;
 VAR2 300;

Um zu verhindern dass Switch_1 den zugeordneten Output (Power) ansteuert und dass der Switch nur unserer Rule zur Verfügung steht muss die folgenden Option gesetzt werden:

SetOption114 1

Da standardmäßig die Konfiguration für einen Switch auf „Toggle“ gestellt ist, wir aber in unserer Rule ein ON/OFF erwarten muss das Switch-Verhalten umgestellt werden:

SwitchMode 1

(De-)Aktivierung des Bewegungsmelders bei Sonnenuntergang / Sonnenaufgang

TODO

val String loggerName = "SunsetSunriseRules"

rule "Sunrise handler"
when
  Channel "astro:sun:local:rise#event" triggered START
then
    //bad_led_motion_detection.postUpdate(OFF)
    bad_led_motion_detection.sendCommand(OFF)
    logError(loggerName, "Run sunrise handler")
end

rule "Sunset handler"
when
    Channel "astro:sun:local:set#event" triggered START
then
    //bad_led_motion_detection.postUpdate(ON)
    bad_led_motion_detection.sendCommand(ON)
    logError(loggerName, "Run sunset handler")
end

Damit die zuvor definiert Rule funktioniert, müssen natürlich die Things und Items entsprechend in OpenHAB definiert sein.

Passbilder am Drogerie/Discounter Fotodrucker

Immer wieder ärgere ich mich wenn ich neue Passbilder brauche. Zwar ist eine Foto selbst schnell gemacht, aber die Vorbereitung für das Drucken ist immer wieder eine nervige Angelegenheit. Wie groß muss das Foto gleich wieder sein? Wie bekomme ich es hin das am Fotodrucker genau diese Größe am Ende rauskommt? Macht der Fotodrucker mein Foto etwas größer und in welchem Maße?

Bislang bemühte ich dazu Gimp und einen Taschenrechner. Nachdem ich nun das Tool montage kenne, habe ich ein kleines wrapper script geschrieben um diese Schritte automatisiert zu machen.

Manuelle Schritte:

  1. Foto machen und auswählen
  2. Foto zuschneiden nach der Maske für Passfotos (kinder) und dem Verhältnis 35:45
  3. Evtl. Lichtverhältnisse (Helligkeit/Kontrast/…) optimieren
  4. Bestimmen der Druckgröße. Bei dm ist z.B. das Standardformat am Fotodrucker 10x15cm

Schritte die das Programm übernimmt:

  1. Auslesen der Auflösung und Maße aus dem Foto / der Quelldatei
  2. Bestimmen der Auflösung der Zieldatei so dass das Foto mit der optimalen Qualität eingefügt wird.
  3. Berechnung der horizontalen und vertikalen Rahmen so genau 2 auf 2 Passfotos auf das Zielfoto passen.
  4. Einfügen der Fotos mittels dem Tool montage

Hier das Script für MacOS / ZSH:

#!/usr/bin/env zsh

# Groesse in cm des Zielformats
PHOTO_W=10
PHOTO_H=15

WORK_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname $0) && pwd)

if [[ -z "$1" ]]; then
  echo "No input file given. Usage: $0 <IMG>"
  exit 1
fi

IMAGE_IN_PATH=$(cd $SCRIPT_DIR && cd $(dirname $1) && pwd)/$(basename $1)
IMAGE_OUT_PATH=$(cd $SCRIPT_DIR && cd $(dirname $1) && pwd)/out-${PHOTO_W}x${PHOTO_H}.jpg

if [[ ! -f "${IMAGE_IN_PATH}" ]]; then
  echo "File not found: ${IMAGE_IN_PATH}"
  exit 1
fi

# Auslesen des Formats der Quelldatei
eval $(identify -format 'IMG_WIDTH=%w\nIMG_HIGHT=%h\n' ${IMAGE_IN_PATH})
echo "Using file ${IMAGE_IN_PATH} with size ${IMG_WIDTH}x${IMG_HIGHT}"

# Berechnung der horizontalen und vertikalen Rahmen
BORDER_VERT="$(echo $(( (( ${IMG_WIDTH} / 3.5 * ${PHOTO_W} ) - ( 2 * ${IMG_WIDTH} )) / 4 )) | awk '{ print int($1) }')"
BORDER_HORT="$(echo $(( (( ${IMG_HIGHT} / 4.5 * ${PHOTO_H} ) - ( 2 * ${IMG_HIGHT} )) / 4 )) | awk '{ print int($1) }')"

# Anwendung des Tools montage
montage \
  ${IMAGE_IN_PATH} ${IMAGE_IN_PATH} ${IMAGE_IN_PATH} ${IMAGE_IN_PATH} \
  -geometry ${IMG_WIDTH}x${IMG_HIGHT}+${BORDER_VERT}+${BORDER_HORT} \
  -quality 100 \
  ${IMAGE_OUT_PATH}

Das Script kann in diesem Repo gefunden werden: https://github.com/MichaelKlemm/passphoto-tools