Idee für eine Steuerung der Arbeitsplatzleuchte per Bewegungsmelder über 433 MHz
Auf dem Schreibtisch, mit Laptop und Raspberry Pi, steht eine Arbeitsplatzleuchte, die je nach Tageszeit und Helligkeit zum Einsatz kommt. Häufig ist es der Fall, dass ich den Platz verlasse und nach unbestimmter Zeit wieder zurückkehre. Mache ich solange die Lampe aus oder nicht?
Dabei ist die Idee entstanden, die Arbeitsplatzleuchte per Bewegungsmelder und Funksteckdose zu steuern. Die Steuerung muß natürlich abhängig von der Helligkeit im Raum erfolgen. Außerdem soll sie nicht gleich ausgehen, wenn ich nur wenige Minuten weg bin.
Im Internet gibt es zu diesem Thema eine ganze Reihe von Veröffentlichungen, von denen aber keine meine Vorstellungen 1:1 erfüllt.
https://tutorials-raspberrypi.de/raspberry-pi-funksteckdosen-433-mhz-steuern/
https://www.einplatinencomputer.com/raspberry-pi-433-mhz-funksteckdose-schalten/
https://tutorials-raspberrypi.de/raspberry-pi-openhab-funksteckdosen-433-mhz-schalten/
sind einige Beispiele, deren Prinzip ich mir zum Vorbild genommen habe. In den Beiträgen sind die Steuerung der Steckdosen und deren Einstellungen gut beschrieben.
In keinem Beitrag wird aber auf die Steuerung per Pythonscript eingegangen. Nach längerem Suchen bin ich dann bei https://pastebin.com/aRipYrZ6 und https://github.com/steffenschroeder/tarnow/issues/4 gelandet. Hier wird die Klasse "RemoteSwitch" in Python beschrieben und dokumentiert.
Nach einem Probeprogramm funktioniert die Klasse perfekt für meine Steuerung.
Über einen Fotowiderstand soll die Helligkeit im Raum ermittelt werden. Beim Eintreten eines gewählten Wertes und Feststellung einer Bewegung geht ein Signal an die Funktsteckdose, damit die Arbeitsplatzleuchte eingeschaltet wird.
Gleichzeitig wird ein Zähler auf 10 Minuten gestellt. Sobald wieder eine Bewegung erkannt ist, stellt sich der Zähler wieder auf 10 Minuten. Kommt aber 10 Minuten keine Bewegungsmeldung, dann wird die Arbeitsplatzleuchte ausgeschaltet. Außerdem wird ständig die Helligkeit geprüft, so dass beim Über- oder Unterschreiten des Helligkeitswertes (700 OHM) die Arbeitsplatzleuchte entsprechend aus- oder eingeschaltet wird.
Die 10 Minuten habe ich für mich als günstigsten Wert herausgefunden, denn innerhalb der 10 Minuten bewegt man sich am Schreibtisch so, dass der Bewegungsmelder den Zähler wieder hoch setzt.
Die Kontroll-LED ist direkt an dem HC-SR501 angeschlossen und funktioniert, unabhängig von der Helligkeit, sobald die Versorgungsspannung an der Schaltung angeschlossen ist. Die Einstellung des Empfindlichkeitsreglers am HC-SR501 habe ich vorher auf einem Breadboard vorgenommen. Den zweiten Reglers am HC-SR501 habe ich auf ca. 20 sek. eingestellt. Die Steckbrücke ist auf die inneren Pins gesteckt. Damit wird der Zähler im Programm frühestens nach 20 Sekunden wieder auf 10 Minuten hochgesetzt.
Das bedeutet, bei Bewegungserkennung wechselt das Data-Signal am HC-SR501 von 0 auf 1 und nach 20 Sekunden wieder auf 0. Dann ist der Weg für die nächste Bewegungserkennung frei. Im Programm realisiert die Zeile "GPIO.add_event_detect(GPIO_PIR, GPIO.RISING, callback=MOTION)" die Auswertung der Bewegungserkennung.
Damit die Funksteckdose ihr Signal erhält, sendet der Raspberry Pi Zero über das Modul HFY-FST per 433MHz eine Sequenz für das Ein- oder Ausschalten des Stromkreises.
Die Funktsteckdosen und das Netzteil vom Raspberry Pi sollten entsprechende Sicherheitkennzeichen haben, damit eine gefahrlose Verwendung möglich ist.
Die Schaltung

Das Programm
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ Einschalten einer Lampe, wenn es dunkel genug ist und eine Bewegung erkannt wird; Mit einem Fotowiderstand prüfen, ob es dunkel ist (Ohmwert ermitteln); Zeitschleife, die durch PIR immer wieder auf max_zeit gesetzt wird; Wenn innerhalb einer bestimmten Zeit (10 min) keine Bewegung erkannt wurde oder es hell genug ist, wird die Lampe ausgeschaltet; """ import RPi.GPIO as GPIO import time import datetime from gpiozero import MCP3008 from elropi import RemoteSwitch # BCM GPIO-Referenen verwenden (anstelle der Pin-Nummern) und GPIO-Eingang definieren GPIO.setmode(GPIO.BCM) GPIO_PIR = 4 # Bewegungsmelder an GPIO4 zeit = 600 # 10 min ldr = MCP3008 (channel = 0) Zaehler = 0 GPIO.setwarnings(False) default_key = [1,0,1,0,0] # Einstellung von der Fernbedienung der Steckdosen default_pin = 18 # GPIO 18 # Device 8 bedeutet Steckdose D auf der Fernbedienung steckdose = RemoteSwitch(device= 8, key=default_key, pin=default_pin) def dunkel(): global wert wert = int((ldr.raw_value / 1023) * 1000) # Helligkeitswert in OHM if wert > 700: # dunkel return (True) return (False) # hell # Callback-Funktion wenn Bewegung erkannt wird def MOTION(PIR_GPIO): global wert global Zaehler Zaehler = 0 # Zähler 10 min wieder auf 0 setzen if dunkel(): steckdose.switchOn() # EIN else: steckdose.switchOff() # AUS # Set pin as input beim Bewegungsmelder GPIO.setup(GPIO_PIR,GPIO.IN) # Schleife, bis PIR == 0 ist while GPIO.input(GPIO_PIR) != 0: time.sleep(0.1) try: # Ereignis definieren: steigende Flanke GPIO.add_event_detect(GPIO_PIR, GPIO.RISING, callback=MOTION) # Callback wird durch die Flanke aktiviert while True: # AUS, wenn 10 Minuten keine Bewegung war time.sleep(1) # 1 Sekunde Zaehler +=1 # maximum 600 if Zaehler == zeit: steckdose.switchOff() except RuntimeError: # Programm beenden steckdose.switchOff() GPIO.cleanup() finally: steckdose.switchOff() GPIO.cleanup()
elropi.py mit der Klasse RemoteSwitch
#!/usr/bin/env python # -*- coding: utf-8 -*- """ "elropi.py" for switching Elro devices using Python on Raspberry Pi by Heiko H. 2012 https://github.com/steffenschroeder/tarnow/issues/4 https://pastebin.com/aRipYrZ6 This file uses RPi.GPIO to output a bit train to a 433.92 MHz transmitter, allowing you to control light switches from the Elro brand. Credits: This file is mostly a port from C++ and Wiring to Python and the RPi.GPIO library, based on C++ source code written by J. Lukas: http://www.jer00n.nl/433send.cpp and Arduino source code written by Piepersnijder: http://gathering.tweakers.net/forum/view_message/34919677 Some parts have been rewritten and/or translated. This code uses the Broadcom GPIO pin naming by default, which can be changed in the "GPIOMode" class variable below. For more on pin naming see: http://elinux.org/RPi_Low-level_peripherals Version 1.0 TEST mit GPIO 18, Pin 12 Aufruf python ./elropi.py 8 1 # Steckdose D EIN python ./elropi.py 8 0 # Steckdose D AUS """ import time import RPi.GPIO as GPIO class RemoteSwitch(object): repeat = 10 # Number of transmissions pulselength = 300 # microseconds GPIOMode = GPIO.BCM def __init__(self, device, key=[1,1,1,1,1], pin=18): ''' devices: A = 1, B = 2, C = 4, D = 8, E = 16 key: according to dipswitches on your Elro receivers pin: according to Broadcom pin naming ''' self.pin = pin self.key = key self.device = device GPIO.setmode(self.GPIOMode) GPIO.setup(self.pin, GPIO.OUT) def switchOn(self): self._switch(GPIO.HIGH) def switchOff(self): self._switch(GPIO.LOW) def _switch(self, switch): self.bit = [142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 136, 128, 0, 0, 0] for t in range(5): if self.key[t]: self.bit[t]=136 x=1 for i in range(1,6): if self.device & x > 0: self.bit[4+i] = 136 x = x<<1 if switch == GPIO.HIGH: self.bit[10] = 136 self.bit[11] = 142 bangs = [] for y in range(16): x = 128 for i in range(1,9): b = (self.bit[y] & x > 0) and GPIO.HIGH or GPIO.LOW bangs.append(b) x = x>>1 GPIO.output(self.pin, GPIO.LOW) for z in range(self.repeat): for b in bangs: GPIO.output(self.pin, b) time.sleep(self.pulselength/1000000.) if __name__ == '__main__': import sys GPIO.setwarnings(False) if len(sys.argv) < 3: print ("usage:sudo python %s int_device int_state (e.g. '%s 2 1' switches device 2 on)" % (sys.argv[0], sys.argv[0])) sys.exit(1) # Change the key[] variable below according to the dipswitches on your Elro receivers. # default_key = [1,0,0,0,1] default_key = [1,0,1,0,0] # change the pin accpording to your wiring default_pin =18 device = RemoteSwitch( device= int(sys.argv[1]), key=default_key, pin=default_pin) if int(sys.argv[2]): device.switchOn() else: device.switchOff()
Im Bild ist der DIP-Schalter der Steckdose und der Fernbedienung sichtbar. Der linke Teil von 1-5 ist die Codierung des Funkkanals und die Codierung A-E gehört zum Namen der Steckdose auf der Fernbedienung.
Steckdose = Wert: A = 1, B = 2, C = 4, D = 8, E = 16