Der NESPI: Tutorial Teil III - die Software

Software für die temperaturabhängige Lüftersteuerung:

Die Software für die temperaturgesteuerte Lüftersteuerung basiert auf mehreren Skripten, die ich aus unterschiedlichen Quellen zusammengefasst habe.

Die Schritte, die zur Implementierung notwendig sind, kann man in X Schritte unterteilen:

1. Python-Script aktualisieren
2. GPIO-Steuerung über Python ermöglichen mit RPIO
3. Anlegen der Verzeichnisse und Kopieren der Scripte/ Berechtigung setzen
4. Test der Hardware mit Software mit Hilfsscripts für direkte Ansteuerung
5. Verankerung der Software als Autostart (Cronjob)/ Gewährleistung des Programmlaufs
6. Programmtest durch Belastung Stresstest/ Abbruch nach Direktansteuerung

1. Python Unterstützung aktualisieren
Zunächst wird durch folgende Befehle gewährleistet, dass die Python-Enwticklungsumgebung installiert wird:
Folgende Befehle in der Konsole ausführen oder per SSH auf den Pi schalten:

$ sudo apt-get install python3-pip
$ sudo apt-get install python-pip 

2. Installation RPIO (Ansteuern der GPIO Pins durch Python-Scripte)
Durch die Verwendung eines älteren RPI.GPIO Standes wie hier beschrieben erhielt ich Fehlermeldungen, daher rate ich zum Gebrauch dieses frischen Scripts bei einem Pi3.

$ git clone https://github.com/limuxy/RPIO.git
$ cd RPIO
$ sudo python setup.py install

3. Verzeichnisse und Daten anlegen
Durch folgende Befehle wir im /home Verzeichnis der Ordner für das Lüfter-Script erzeugt:

$ sudo mkdir /home/luefterscript
$ cd /home/luefterscript

Was macht das Script?

Zunächst erfolgt eine Abfrage, ob das Script bereits ausgeführt wird. Wird es bereits ausgeführt, wir der Neustart des Scripts abgebrochen. Es soll ja nur ein Mal gleichzeitig laufen.
Die Temperatur wird derzeitig alle 20 Sekunden abgefragt. Ist die Temperatur über 60° wird der Start des Lüfters initiiert. Der Lüfter läuft dann so lange, wie die 20 sekündliche Abfrage zurückmeldet, dass 55° noch nicht unterschritten sind.
Der Lüfter startet also über 60° und kühlt solange, bis 55° wieder unterschritten werden. Trotzdem läuft der Lüfter erst bei Überschreiten der 60° an, also nicht wundern, warum der Lüfter bei bsw. 58° nicht arbeitet.
Alle Aktivitäten werden in einem Logfile abgelegt:

/home/luefterscript/control_fan.log

Jetzt die fertige Scriptdatei: temperaturscript.sh  herunterladen und per WinSCP auf euren Pi in das Zielverzeichnis:

/home/luefterscript/

kopieren.

ODER:
An dieser Stelle die Datei temperaturscript.sh selbst anlegen und folgendes Script einfügen (Markieren und per Rechtsklick in der Konsole einfügen, speichern und beenden):

$ sudo nano /home/luefterscript/temperaturscript.sh
  
 


#!/usr/bin/env bash

# ~ RaspBerry PI ~
# fan control script
# -----------------------------------------
# Author:      Bagheera
# Created:     28.12.2013
# Last change: 31.12.2013
# Version      1.2
# -----------------------------------------
# 1.2: 31.12.2013
#      - traps for common signals added
#      - commentary
#      - logfile beautification
#
# 1.1: 30.12.2013
#      - logfile changed
#      - logturn added
#      - verbose by global setting
#
# 1.0: 28.12.2013
#      - control_fan.sh created
# -----------------------------------------
# 1.3: Author: Snydeaps
# Aenderung des GPIO von 14 auf 21
# Aenderung Logfile Ordner auf luefterscript
#------------------------------------------
# 1.4: Author: Snydeaps
#       Aenderung Verhindern des Parallellaufs mehrerer Prozesse

test -n "$DEBUG" && set -x

cmd="$(basename "$0")"
lockfile="/var/run/$cmd"

exec 9<>"$lockfile"

flock -n 9 || {
  echo "ERROR: already running $(cat <&9) - exiting." >&2
  exit 1
}

echo $$ >&9

echo "running as $$"
sleep 5
echo "finished $$"

VERBOSE=1;             # show info on console (0=no; 1=yes)

MAX_THRESH=60;         # start above xx degrees
MIN_THRESH=55;         # stop below xx degrees

SLEEPER=20;            # scan every xx seconds
LOGTURN=6;             # log temp every LOGTURN * SLEEPER seconds

# logfile destination
LOGFILE="/home/luefterscript/control_fan.log";


# prepare signal trap function
function finish  {
    echo $(date '+%F %T %Z') "##     0:CONTROL:       Script about to stop" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     2:GPIO_INIT:     Stopping fan" >> $LOGFILE
    echo "0" > /sys/class/gpio/gpio21/value
    echo $(date '+%F %T %Z') "##     2:GPIO_INIT:     Unexport of GPIO port 21" >> $LOGFILE
    echo "21" > /sys/class/gpio/unexport
    echo $(date '+%F %T %Z') "##     0:CONTROL:       Going down... bye bye" >> $LOGFILE
    exit;
}

# trap exit
trap finish EXIT

# initialize GPIO port 21
if [ ! -e "/sys/class/gpio/gpio21" ]; then
    echo $(date '+%F %T %Z') "##     ==================================================================" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     0:CONTROL:       Starting up..." >> $LOGFILE
    echo $(date '+%F %T %Z') "##     1:CONFIG:        Maximum threshold $MAX_THRESH C" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     1:CONFIG:        Minimum threshold $MIN_THRESH C" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     1:CONFIG:        Scan interval $SLEEPER sec" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     1:CONFIG:        Log temperature interval $(($SLEEPER*$LOGTURN)) sec" >> $LOGFILE
    echo $(date '+%F %T %Z') "##     2:GPIO_INIT:     Export of GPIO port 21" >> $LOGFILE
    echo "21" > /sys/class/gpio/export
    echo $(date '+%F %T %Z') "##     2:GPIO_INIT:     Direction: out" >> $LOGFILE
    echo "out" > /sys/class/gpio/gpio21/direction
    echo $(date '+%F %T %Z') "##     2:GPIO_INIT:     Port 21: init value 0" >> $LOGFILE
    echo "0" > /sys/class/gpio/gpio21/value
fi

i=0;
while [ true ]; do

    # get current recalculated temperature and fan status
    cpuTemp=$(cat /sys/class/thermal/thermal_zone0/temp)
    cpuTemp=$(($cpuTemp/1000))
    fanState=$(cat /sys/class/gpio/gpio21/value)

    # echo current temperature to logfile if logturn met
    i=$(($i+1))
    if [ $i -eq $LOGTURN ]; then
        echo $(date '+%F %T %Z') "##     0:CONTROL:       Current temperature: $cpuTemp C" >> $LOGFILE
        i=0;
    fi

    # do some info stuff
    [ $VERBOSE -eq 1 ] && echo -e "CPU: \033[36m$cpuTemp\033[0mC  |  FAN: $fanState  |  THRESHOLD: $MIN_THRESH-$MAX_THRESH"

    # too hot and fan not running? start!
    if [ $cpuTemp -gt $MAX_THRESH ] && [ $fanState -eq 0 ]; then
        echo "1" > /sys/class/gpio/gpio21/value
        [ $VERBOSE -eq 1 ] && echo -e "====> [ \033[32mON\033[0m ]"
        echo $(date '+%F %T %Z') "##     0:CONTROL:       Starting fan ($cpuTemp C)" >> $LOGFILE
    fi

    # everything cool and fan running? stop!
    if [ $cpuTemp -lt $MIN_THRESH ] && [ $fanState -eq 1 ]; then
        echo "0" > /sys/class/gpio/gpio21/value
        [ $VERBOSE -eq 1 ] && echo -e "====> [ \033[31mOFF\033[0m ]"
        echo $(date '+%F %T %Z') "##     0:CONTROL:       Stopping fan ($cpuTemp C)" >> $LOGFILE
    fi

    sleep $SLEEPER

done
 

4. Test der Hardware
Der Test der Hardware erfolgt durch direkte Ansteuerung des GPIO Pins 21 durch ein Python Script. Die beiden Dateien: gpio21on.py und gpio21off.py können wieder heruntergeladen und in /home/luefterscript abgelegt werden, oder händisch erzeugt werden:

Anschalten des Lüfters mit eigenem Script für Testlauf:

$ cd /home/luefterscript
$ sudo nano gpio21on.py
 
In die gpio21on.py hinein: 

#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)
GPIO.output(21, False)


speichern und beenden des Scripts.

Abschalten des Lüfters nach Testlauf:

$ sudo nano gpio21off.py

#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)
GPIO.output(21, True)
 


Den Scripts werden die ausreichenden Rechte zugewiesen durch:
 
$ sudo chmod +x gpio21on.py
$ sudo chmod +x gpio21off.py 

Lüfter anschalten:

$ sudo python gpio21on.py

Lüfter abchalten:

$ sudo python gpio21off.py

Sollte bis dahin der Testlauf erfolgreich sein, ist die Hardware richtig konfiguriert und das automatische Script kann nach der Ausstattung mit ausreichenden Rechte in die Automatisierung gehen.

Wir geben der temperaturabhängigen Lüftersteuerung die ausreichenden Rechte durch:

$ sudo chmod +x /home/luefterscript/temperaturscript.sh 

Nun ein Test, ob das Script läuft durch:

$ sudo su
$ sudo env -i SHELL=/bin/sh PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin HOME=/home/dru LOGNAME=dru /home/luefterscript/temperaturscript.sh

Sollte das Script bereits laufen erscheint folgerichtig:

root@retropie:/home/pi# ERROR: already running 510 - exiting.
 
 
Ist dies jedoch der erste Test, so läuft das Script an und das Logfile wird erstellt. Alle 20 Sekunden bekommt man nun einen neuen Temperaturwert.

Beenden kann man die Funktion nun mit STRG+z

5. Automatisierten Start und Kontrollfunktion des Programmlaufs


In meiner häufig zitierten Quelle wird der Autostart mit /etc/inittab beschrieben, was aber aufgrund der aktuellen Raspbian Version nicht mehr funktioniert. Daher habe ich weitere Möglichkeiten in betracht gezogen und folgende gewählt:

$ sudo su 
$ sudo nano /etc/crontab

Inhalt:

 /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --repo$
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --repo$
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --repo$
#
*/10 * * * *    root    /home/luefterscript/temperaturscript.sh
@reboot         root    /home/luefterscript/temperaturscript.sh
# Luefterautomatik


Wichtig sind die am Ende eingefügten Zeilen zum Luefterscript. Die */10 * * * * .. Zeile sorgt dafür, dass alle zehn Minuten eine erneuter Start des Scripts eingeleitet wird. Das Script selbst ist mit einem Schutz versehen, das checkt, wenn es bereits läuft und dann keinen Neustart ausführt.
Die weitere Zeile mit @reboot sorgt für einen Initialstart beim Booten des Systems. Damit ist ein Erststart angelegt und eine Abfrage, falls unter irgendwelchen Umständen dass Script beendet wird ein Neustart des Scripts alle 10 Minuten abgefragt wird.


6. Belastungstest
Wenn das Script ordnungsgemäß arbeitet wir der Lüfter bei über 60° anspringen. Da der Pi3 aber nur unter bestimmten Belastungen die 60° übersteigt versuchen wir mit einem Stresstest die Belastung zu erhöhen und einen Temperaturanstieg herbeizuführen.

Dazu solltet ihr euch sysbench wie hier beschrieben besorgen und dann folgenden Stresstest ausführen:

$ apt-get install sysbench 

sysbench --test=cpu --cpu-max-prime=20000 run


Das sollte möglichst aus einer SSH Konsole heraus passieren. Bei Bedarf auch mehrere parallel.
In einer weiteren Konsole könnt ihr dann mit folgendem Befehl die Temperatur auslesen, damit ihr wisst, ob euer Lüfter bereits laufen sollte:

$ vcgencmd measure_temp
 
Ist die Temperatur über 60° sollte der Lüfter laufen und erreicht die Temperatur wieder unter 55° sollte der Lüfter stoppen.  

Keine Kommentare:

Baumscheibenradio - Internetradio mit den Raspberry Pi Zero W

Ein neues Projekt ist gerade fertig dokumentiert worden. Das Baumscheiben-Radio :