Python Script und Crontab @reboot

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
BenFocus
User
Beiträge: 3
Registriert: Montag 3. März 2014, 01:49

Hallo Leute,
bin neu hier im Forum und habe mich nach mehreren hilfreichen Themen auch mal direkt hier angemeldet :)

Nun schon mal zu meinem Problem:

Ich habe einen Raspberry Pi mit Raspbmc und habe dafür ein Python Script programmiert, welches eine Lüftersteuerung realisiert.
Nun möchte ich das Script automatisch per Crontab @reboot starten lassen, aber es funktioniert nicht so recht.

Hier der Code des Scriptes:

Code: Alles auswählen

#!/usr/bin/env python
#
#
import time
import os
import RPIO
#
RPIO.setwarnings(False)
RPIO.setup(4, RPIO.OUT)
#
##############
# Funktionen #
##############
#
def CPUtemp():
        res = os.popen('vcgencmd measure_temp').readline()
        return(res.replace("temp=","").replace("'C\n",""))
#
#############
# Variablen #
#############
#
Kritisch = 52.0                         # Warntemperatur
Safe = 45.0                             # sichere Temperatur
lt = time.localtime()                   # Zeiterfassung
#
#
#
while True:
        CPUtemp()                               # Aufruf der Funktion    
        CPUrech = float(CPUtemp())              # Konvertierung str in float
        CPUkrit = CPUrech - Kritisch            # Differenz zwischen Warntemperatur und aktueller Temperatur
        if (CPUkrit > 0):
                while (CPUrech >= Safe):
#        Hier wird der Luefter aktiviert
                                CPUtemp()
                                CPUrech = float(CPUtemp())
                                RPIO.output(4, True)
                                time.sleep(10)
        else:
               CPUtemp()               # Ermittlung CPU-Temp
                RPIO.output(4, False)   # Luefter abschalten
                time.sleep(10)          # Wartedauer bis Funktion weiter laeuft
Das Problem ist nun, dass das Script beim Booten kurz ausgeführt, aber direkt wieder beendet wird.

Folgenden Code konnte ich mit "ps -ef | grep python" sehen:

Code: Alles auswählen

pi        1723  1361  0 01:42 pts/0    00:00:00 grep python
root      1724  1720  0 01:42 ?        00:00:00 python /home/pi/luefter.py
Kann mir einer sagen, wodurch der Fehler eventuell verursacht wird und wie ich das Problem lösen kann?
Habe auch schon versucht das ganze mit "/etc/init.d" auszuführen, aber das funktioniert auch nicht...
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@BenFocus: läuft das Programm überhaupt, wenn Du es von Hand startest? Zeile 41 ist zum Beispiel falsch eingerückt.
»if« und »while« sind keine Funktionen, haben also auch keine Argumente die man in Klammern setzen müßte. Deine Kommentare sind zum Großteil sinnfrei. Was fängt man mit "Aufruf der Funktion" an? Die Zeilen 30, 36 und 41 sind übrigens nutzlos, da sie den Rückgabewert gar nicht verwenden.
Bei »popen« ist es übrigens noch wichhtiger, die Datei wieder zu schließen, da sonst Zombiprozesse die Prozesstabelle vollmüllen.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ein Lüfter auf einem Raspi? Erzeugt der wirklich soviel Abwärme? Welche Leistungsaufnahme hat denn so ein Raspi? Unter 3W sollte ein passiver Kühler reichen...
BlackJack

@BenFocus: Noch ein paar Anmerkungen:

Einrücktiefe ist per Konvention vier Leerzeichen pro Ebene. Und die Namensgebung hält sich bei der Schreibweise auch nicht an den Style Guide for Python Code.

Alle möglichen Arten externe Programme zu starten, sind mittlerweile durch das `subprocess`-Modul ersetzt worden.

Funktionsnamen beschreiben üblicherweise eine Tätigkeit, weil Funktionen etwas tun, und man am Namen ablesen können sollte was das ist. Also zum Beispiel `get_cpu_temperature()` statt `CPUtemp()`. Die Funktion sollte ausserdem auch die Umwandlung in eine Gleitkommazahl vornehmen, denn eine Temperatur ist ein Zahlwert und keine Zeichenkette.

Für „magische” Zahlen sollten Konstanten verwendet werden, damit der Quelltext leichter zu verstehen und zu ändern ist. Die Pin-Nummer für die Lüftersteuerung ist hier so ein Fall.

Namen sollten nicht abgekürzt werden solange die Abkürzung nicht allgemein bekannt ist. Bei `temp` hat man zum Beispiel das Problem, dass es häufig auch als Abkürzung für `temporary` verwendet wird. Und bei `CPUrech` habe ich auch nach intensivem Nachdenken nicht herausfinden können was der Name selbst mir sagen will. Die Bedeutung habe ich nur duch den Kontext im Programm erkannt.

`lt` wird definiert, aber nirgends verwendet.

Warum berechnest Du `CPUkrit`? Man könnte doch ganz einfach vergleichen ob die aktuelle Temperatur grösser als die Kritische ist, anstatt das über diesen Zwischenwert zu machen‽

Ich würde das ganze vom Ablauf einfacher gestalten und nur eine Schleife schreiben und anstelle der inneren Schleife ein Flag einführen ob dr Lüfter läuft oder nicht. Dann muss man nur an einer Stelle die Temperatur auslesen und auch nur an einer Stelle „schlafen”. Ich komme dann ungefähr bei so etwas heraus (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python
import time
from subprocess import PIPE, Popen
import RPIO

FAN_PIN = 4
CRITICAL_TEMPERATURE = 52.0
SAFE_TEMPERATURE = 45.0


def get_cpu_temperature():
    process = Popen(['vcgencmd', 'measure_temp'], stdout=PIPE)
    output, _error = process.communicate()
    return float(output[output.index('=') + 1:output.rindex("'")])


def main():
    RPIO.setwarnings(False)
    RPIO.setup(FAN_PIN, RPIO.OUT)
    is_fan_running = False
    while True:
        cpu_temperature = get_cpu_temperature()
        if is_fan_running:
            is_fan_running = cpu_temperature < SAFE_TEMPERATURE
        else:
            is_fan_running = cpu_temperature > CRITICAL_TEMPERATURE
        RPIO.output(FAN_PIN, is_fan_running)
        time.sleep(10)


if __name__ == '__main__':
    main()
@jerch: Eigentlich ist die Abwärme kein Problem, ausser wenn man den irgendwo verbaut wo sich die Wärme staut. Dann kann ein Lüfter nützlich bis nötig sein.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJacko: in Zeile 224 sollte wohl "is_fan_running = cpu_temperature > SAFE_TEMPERATURE" heißen
BenFocus
User
Beiträge: 3
Registriert: Montag 3. März 2014, 01:49

Danke erstmal für die hilfreichen Antworten!

Das eingerückte in Zeile 41 kommt nur durch das Reinkopieren in den Code-Editor. ;)
"lt" ist noch aus einer früheren Version übrig geblieben. Hat natürlich keine Bewandtnis mehr.

Die anderen Tipps werde ich natürlich auch umsetzen.
Habe den neuen Quelltest mal kopiert und teste gerade...
Das Problem ist, dass der Lüfter nur eingeschaltet wird, wenn die kritische Temperatur erreicht ist.
Bei unterschreiten der kritischen Temperatur schaltet er sofort wieder ab.
Erreicht werden soll aber eine Hysterie, also das Ausschalten soll erst bei unterschreiten den SAFE_TEMPERATURE erfolgen!

EDIT: Es lebe die Autokorrektur. Das soll natürlich Hysterese heißen ;)
Zuletzt geändert von BenFocus am Montag 3. März 2014, 13:32, insgesamt 1-mal geändert.
BlackJack

@BenFocus: „Hysterie” ist lustig. ;-) Eine Hysterese sollte es eigentlich geben bei meinem Quelltext. Hast Du die Korrektur von Sirius3 berücksichtigt?
BenFocus
User
Beiträge: 3
Registriert: Montag 3. März 2014, 01:49

Die nur Datei läuft jetzt, wie sie soll.
Hysterese passt mit der angesprochenen Änderung von Sirius3!

Werde jetzt versuchen, ob das Programm auch beim Start ausgeführt wird...


EDIT:
Gleiches Problem wie vorher. Das Programm wird kurz gestartet und ist dann direkt wieder weg...

Code: Alles auswählen

pi@NAS-XBMC:~$ ps -ef | grep python
root      1707     1 37 13:39 ?        00:00:00 python /home/pi/luefter2.py
root      1708     1 32 13:39 ?        00:00:00 python /home/pi/shutdown.py
pi        1713  1228  0 13:39 pts/0    00:00:00 grep python
pi@NAS-XBMC:~$ ps -ef | grep python
root      1708     1 16 13:39 ?        00:00:00 python /home/pi/shutdown.py
pi        1716  1228  0 13:39 pts/0    00:00:00 grep python
Antworten