Nachdem der Webserver meiner nahegelegenen Wetterstation vermutlich aufgrund Log4j mehrere Tage ausgeschaltet war, kam die Idee die Lichtstunden am Tag selbst zu messen.
Als Sensor habe ich dann schnell den G5516 Fotowiederstand mit einem fertigen Sensor Modul LM393 gefunden. Dieser hat 4 Anschlüsse. VCC, GND, Digital Out, Analog Out. Es gibt solche Module auch mit 3 Anschlüssen, dort fehlt dann der analoge Ausgang. Den benötigen wir hier in der Tat nicht.
Den Sensor bekommt man eigentlich überall, einfach im Internet danach suchen. So sieht er aus:

Das kleine Potentiometer kann mit einem kleinen Kreuzschraubendreher eingestellt werden. Dieser entscheidet über den Grenzwert ab welcher Lichthelligkeit am digitalen Eingang ein Signal ausgegeben wird.
Das schöne ist, dass eine 2. LED (auch grün) auf dem Modul angeht, sobald die Lichtgrenze überschritten wird. Daher kann man den Grenzwert sehr bequem direkt am Modul einstellen.
Anschluss RaspberryPi GPIO Leiste:
VCC kommt auf den 3,3V GPIO Pin
GND kommt auf einen Masse GPIO Pin
DO kommt an einen freien GPIO Port Ich hab mich für den GPIO Pin 7 (GPIO 4) entschieden.


Die RaspberryPi Pin Belegung findet Ihr auch bei Wikipedia, wer sich da noch nicht sicher ist.
https://commons.wikimedia.org/wiki/File:Raspberry-pi-gpio.png
Ich habe den Sensor also bei Sonnenlicht mit dem Poti eingestellt, somit ist die Hardware startklar. Also weiter auf dem RaspberryPi mit der Software. 🙂
Auf meinem RaspberryPi kommt Raspbian in der Version 9.13 (stretch) zum Einsatz. Ältere oder neuere Versionen sollten auch funktionieren.
Zudem muss wiringpi installiert sein. (apt install wiringpi)
Nun kann man sich den Status schon mal von allen GPIOs anschauen mit

Hier sehen wir, dass aktuell der GPIO 4 (Pin 7) auf 1 steht. Aktuell ist es finstere Nacht draußen. Der Sensor liefert eine 1 bei unterschreiten des Schwellwertes und eine 0 bei überschreiten dessen. Sprich der Wert ist logisch invers.
0 = Licht/Sonne An
1 = Licht/Sonne Aus
Grundsätzlich sollte man den GPIO immer vorher in einen definierten Modus schalten. IN steht dabei für INPUT Sensor, sprich dieser liefert Daten. UP ist der PullUp-Widerstand. Der Pullup-Widerstand wird hier dazu verwendet, den Eingang auf einen definierten Wert (hier 1) zu „ziehen“.
pi@raspberrypi ~ $ gpio -g mode 4 in pi@raspberrypi ~ $ gpio -g mode 4 up
Auslesen kann man den GPIO dann einfach mit dem folgenden Befehl. Dieser liefert 1 zurück. Wie gesagt, aktuell ist Nacht.
pi@raspberrypi ~ $ gpio -g read 4 1
Daher nutze ich dann ein ganz einfaches Shell Script, dass die Werte dann gleich invertiert.
pi@raspberrypi ~ $ cat /usr/local/bin/lightsensor.sh
#!/bin/bash
gpio -g mode 4 in
gpio -g mode 4 up
# kein Licht heisst 1
# Licht an heisst 0
# daher invert it
wert=$(gpio -g read 4)
case $wert in
0)
echo "1";
;;
1)
echo "0";
;;
esac
Diese Abfrage habe ich dann einfach in mein Zabbix als Item integriert.

Das Ganze sieht dann als Graph wie folgt aus. (War ein recht sonniger Tag trotz Winter)


Den Sensor hab ich dann in ein noch rumliegendes Gehäuse, was vorher einen Bewegungssensor inne hatte, transferiert. Die Öffnung habe ich dann mit Tesa verschlossen, braucht ja nur Licht, aber besser kein Wasser. 🙂
Standort gewählt, wo kaum Verschattung auftritt, das ist gar nicht so einfach, aber für meine Bedürfnisse passt das an der Südseite meiner Garage und dort am Dach.
Da es natürlich Situationen geben kann, wo es sehr wolkig ist und das Sonnenlicht innerhalb 1 Minute durchaus mal aus/an/aus/an … gehen kann, hab ich noch ein 2. Script geschrieben. Dies ermittelt somit das Sonnenlicht innerhalb einer Minute und misst sekündlich. Dadurch ergibt sich dann ein Maxwert von 60, wenn die Sonne die ganze Minute scheint. Sollte sie nur teilweise in der Minute dagewesen sein, ergibt sich ein Wert kleiner 60 z.b 35.
Der Wert wird dann nach 1 Minute in eine Datei /tmp/light geschrieben, den ich wiederum dann mit Zabbix regelmäßig auslese. Hier das Script
pi@raspberrypi /usr/local/bin $ cat lightsensor2.sh
#!/bin/bash
DEBUG=0
gpio -g mode 4 in
gpio -g mode 4 up
# kein Licht heisst 1
# Licht an heisst 0
# daher invert it
lightsum=0
i=0
while true
do
wert=$(gpio -g read 4)
case $wert in
0)
if [ $DEBUG -eq 1 ]; then echo "licht an $i"; fi
wert=1;
;;
1)
if [ $DEBUG -eq 1 ]; then echo "licht aus $i"; fi
wert=0
;;
esac
let lightsum=$lightsum+$wert
let i=$i+1
sleep 1;
if [ $i -eq 60 ]; then
echo $lightsum > /tmp/light
if [ $DEBUG -eq 1 ]; then echo "lighsum = $lightsum";fi
i=0;
lightsum=0;
if [ $DEBUG -eq 1 ]; then echo "60s um ... reset"; fi
fi
done;
So sieht das dann im Zabbix Graph aus.

So die Config im Zabbix.

Die Daten lassen sich dann nach einem Jahr sicherlich auch gut für die Berechnung einer Fotovoltaik Anlage nutzen, sprich womit so ungefähr zu rechnen ist. Denn der Standort einer solchen Anlage ist eben auch stark von Verschattung abhängig und wie oft man in seinem Dorf/Stadt/Standort überhaupt Sonne hat. Ich habe die Sonnenstunden schon oft gebraucht, um festzustellen, warum im Haus die Temperatur steigt, obwohl nicht mehr geheizt wird. Sprich man kann damit die solaren Gewinne feststellen und wie lange diese im Haus bleiben. Zumindest dann wenn man gleichzeitig die Temperatur im Haus sowie Außen und den Gasverbrauch misst. 😉
Andere Anwendungsfälle sind z.B. Rolladenschaltung bei Lichteinfall, Auswertungen in welchen Zimmern wie oft und lange das Licht eingeschaltet wird usw.
Verteilung per Ansible gewünscht?
# cat /etc/ansible/lightsensor.yml
---
- name: Transfer lightsensor Scripts
hosts: raspberrypi.home
become: yes
tasks:
- name: Transfer the lightsensor script
copy: src=/etc/ansible/lightsensor/lightsensor.sh dest=/usr/local/bin/lightsensor.sh owner=root group=root mode=0755
- name: Transfer the lightsensor2 script
copy: src=/etc/ansible/lightsensor/lightsensor2.sh dest=/usr/local/bin/lightsensor2.sh owner=root group=root mode=0755
- name: Transfer the check_lightsensor2 script
copy: src=/etc/ansible/lightsensor/check_lightsensor2.sh dest=/usr/local/bin/check_lightsensor2.sh owner=root group=root mode=0755
- name: Transfer cron.d Entry for automatic start at reboot
copy: src={{ item }} dest=/etc/cron.d/
with_fileglob:
- cron.d/lightsensor
- name: kill all running lightsensor2 process
shell: "killall lightsensor2.sh --wait"
ignore_errors: true # In case there is no process
- name: kill all running gpio 4 process
shell: "killall -r 'gpio*4*' --wait"
ignore_errors: true # In case there is no process
- name: Start lightsensor2 in Backgroud
become_user: pi
shell: "(/usr/local/bin/lightsensor2.sh >/dev/null 2>&1 &)"
async: 10
poll: 0
Das Ganze transferiert die beiden lightsensor Scripte, beendet evtl. laufende lightsensor Prozesse und GPIO Prozesse, um dann das lightsensor2 Script im Hintergrund zu starten. Im cron.d wird der Start des lightsensor2 Scripts nach einem Reboot hinterlegt. Daneben wird ein check_lightsensor2 Script hinterlegt, dies prüft per Cron einmal in der Nacht, ob das Script noch läuft und startet es notfalls nach.
# cat /etc/ansible/lightsensor/check_lightsensor2.sh
#!/bin/bash
if [ $(pidof -x lightsensor2.sh | wc -w) -lt 1 ]; then
/usr/local/bin/lightsensor2.sh &
/usr/bin/logger "$date Restart ligtsensor2.sh (lightsensor2:check)"
fi
# cat /etc/ansible/cron.d/lightsensor
PATH=/bin:/usr/bin:/sbin:/usr/sbin
# at reboot lightsensor2.sh
@reboot pi /usr/local/bin/lightsensor2.sh &
0 0 * * * pi /usr/local/bin/check_lightsensor2.sh
Anmerkungen und Fragen gerne per E-Mail an -> info AT svenczaja.de