Crontab funktioniert nicht

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

ok alles klar.

Ich habe jetzt hier geschaut wie man wait_for_edge einsetzt.
Ich verstehe nicht woher channel kommt. Ist der Channel nun GPIO.input(pinNummer) oder nur die Pinnummer?

Bei diesem Code kommt nun folgene Fehlermeldung:
Traceback (most recent call last):
File "programme/ofen.py", line 23, in <module>
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout = None)
NameError: name 'GPIO_RISING' is not defined

Wie kann es sein?

Code:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf8 -*-

import RPi.GPIO as GPIO
import time
import logging
from marrow.mailer import Message, Mailer
logging.basicConfig(level=logging.INFO)


# Benötigte Werte:
# GPIO.LOW (alles ok)
# GPIO.HIGH (fehler)

# Pin-Nummern aus dem Layout benutzen (siehe gpio.jpg)
GPIO.setmode(GPIO.BOARD) 


# input setzen auf Pin-Nummer: 7 = GPIO 4
GPIO.setup(7, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

channel = 7
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout = None)	

#while True:

if channel is None :
	print "Alles gut"
else:
		# Mailversand
	mail = Mailer({
		'manager.use': 'futures',
		'transport.use': 'smtp',
		'transport.host': 'smtp.gmail.com', # smtp server deines emailanbieters
		'transport.tls': 'ssl', # protokoll
		'transport.username': '', # deine email adresse
		'transport.password': '', # dein password
		'transport.max_messages_per_connection': 5
	})

	mail.start()

	#message = Message([('test', '')], [('Ich', '')], "Warnung!", plain="test")
	message = Message([('Heizungsfehlerinformation ( = Titel der E-Mail)', '')], [('Ich', '')], "Warnung! (= Betreff der E-Mail)", plain="Die Heizung im EG gibt ein Highsignal zurück. Das heißt irgendwas stimmt nicht! ( = E-Mail Text)")

	mail.send(message)
	mail.stop()

	print "Fertig"
	time.sleep(1)
		
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Moon: weil Du GPIO_RISING nicht definiert hast, das ist nur im Modul GPIO.
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Wie soll ich es denn definieren? Verstehe nicht.

Das Modul GPIO habe ich bereits auf meinem Pi installiert.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schau dir mal gaaaaaaanz genau an was du geschrieben hast, und wie die anderen Dinge mit GPIO aussehen....
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

GPIO und die Optionen (Rising, Both, ..) wurden mit nem . verbunden? Meinst du das?

Wenn ich es so mache dann kommt folgende Fehlermeldung:
Traceback (most recent call last):
File "programme/ofen.py", line 23, in <module>
channel = GPIO.wait_for_edge(channel, GPIO.RISING, timeout = None)
TypeError: an integer is required
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und welche deiner Argumente ist KEIN Integer?
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Ach ja. Das Timeout erwartet ein Integer. Timeout ist ja nur ein optionaler Parameter für die Funktion. Danke.

Nun habe ich es nochmal getestet und der Mailversand funktioniert. Jedoch nur wenn ich die python-file in putty mit python programme/ofen.py ausführe.

Nun kommen wir zum Punkt zurück, für welchen ich dieses Thema erstellt habe. Nämlich wie führe ich denn das Script dauerhaft im Hintergrund aus ohne es mit python programme/ofen.py zu starten. Wie bekomme ich dies denn hin?

Moon
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

über eine systemd Service Unit. Die kann dein Skript auch bei Bedarf neu starten, falls es crasht.

Gruß, noisefloor
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

ok alles klar. Danke.

Habe nun nach diesem Tutorial einen service für mein Script erstellt.

Wenn ich nun aber

Code: Alles auswählen

sudo systemctl enable ofen.service
ausführe dann kommt folgende Fehlermeldung:
Failed to execute operation: Invalid argument.

Ich habe den service in folgendem Verzeichnis erstellt: /lib/systemd/system/ofen.service

Ofen.service sieht wie folgt aus:

Code: Alles auswählen

[Unit]
Description=Ofen Script Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python /home/pi/programme/ofen.py > /home/pi/programme/ofen.log 2>&1

[Install]
WantedBy=multi-user.targ
Und wenn ich mir den status der ofen.service ausgeben lasse kommt folgendes:

Code: Alles auswählen

sudo systemctl status ofen.service
● ofen.service - Ofen Script Service
   Loaded: loaded (/lib/systemd/system/ofen.service; disabled)
   Active: inactive (dead)

Habe mich über den Fehler informiert und wie man ihn denn beheben kann. Habe dann gelesen, dass systemd einen symlink in /etc/systemd/system/ mit dem namen xxx.target.wants erstellt. Wenn man diesen symlink löscht sollte es funktionieren.

Nun finde ich/habe ich keinen systemd ordner auf meinem pi. Kann den mit Filezille nicht finden. Wie kann ich nun den symlink löschen? Woher will ich wissen wie der symlink bei mir heißt?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

IMHO ist `multi-user.target`keine gütlige Direktive für `After`(macht auch wenig Sinn...) und `multi-user.targ` bei `WantedBy` gibt es nicht - da fehlt ein `et`.
Wenn man diesen symlink löscht sollte es funktionieren.
Ziemlich sicher nicht - siehe oben.

Und nimm' nicht FileZilla, dass ist für sowas nicht gemacht. Log' dich via SSH ein und mach' das auf der Kommandozeile.

Gruß, noisefloor
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

ok. Was ist denn eine gültige Direktive für After? Denn die bisher gefundenen Tutorials benutzen nur multi-user.target.

Nun dazu:
Habe jetzt die Servicedatei geändert. Habe ein Restart hinzugefügt mit on-abnormal. Bei install die fehlenden Buchstaben et hinzugefügt und das Anlegen eines Logs entfernt. Nun geht das aktivieren ohne Probleme. Nur wenn ich den Status überprüfe kommt, dass das Starten fehlerhaft war.

Der Marrow Mailer ist vorhanden. Habe dies schon überprüft.

Meldung:

Code: Alles auswählen

● ofen.service - Ofen Script Service
   Loaded: loaded (/lib/systemd/system/ofen.service; enabled)
   Active: failed (Result: exit-code) since Do 2018-01-11 15:53:54 CET; 1min 22s ago
  Process: 1039 ExecStart=/usr/bin/python /home/pi/programme/ofen.py (code=exited, status=1/FAILURE)
 Main PID: 1039 (code=exited, status=1/FAILURE)

Jan 11 15:53:53 raspberrypi systemd[1]: Starting Ofen Script Service...
Jan 11 15:53:53 raspberrypi systemd[1]: Started Ofen Script Service.
Jan 11 15:53:54 raspberrypi python[1039]: Traceback (most recent call last):
Jan 11 15:53:54 raspberrypi python[1039]: File "/home/pi/programme/ofen.py",...>
Jan 11 15:53:54 raspberrypi python[1039]: from marrow.mailer import Message,...r
Jan 11 15:53:54 raspberrypi python[1039]: ImportError: No module named marro...r
Jan 11 15:53:54 raspberrypi systemd[1]: ofen.service: main process exited, c...E
Jan 11 15:53:54 raspberrypi systemd[1]: Unit ofen.service entered failed state.
Hint: Some lines were ellipsized, use -l to show in full.

Nun sieht der Sevice so aus:

Code: Alles auswählen


[Unit]
Description=Ofen Script Service
After=multi-user.target

[Service]
Type=idele
ExecStart=/usr/bin/python /home/pi/programme/ofen.py
Restart=on-abnormal

[Install]
WantedBy=multi-user.target
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@Moon: Wie aus der `systemctl`-Ausgabe ersichtlich ist, kann dein Programm das Modul `marro...` nicht finden. `marrow` scheint also nicht richtig installiert zu sein. Eventuell auch nochmal den Hint befolgen: “Hint: Some lines were ellipsized, use -l to show in full.”

Zeig’ mal die Ausgabe von `print(sys.path)`, wenn du das Programm manuell und mit systemd startest.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn du E-Mails verschicken willst, dann macht z.B. das `network.target` oder `network-online.target`Sinn. Link: https://www.freedesktop.org/wiki/Softwa ... orkTarget/
Der Marrow Mailer ist vorhanden.
Offensichtlich nicht - sonst wäre der Fehlermeldung nicht da. Wie hast du den wo installiert?

Gruß, noisefloor
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

Der Marrow Mailer ist installiert und auch schon auf neustem Stand. Wenn ich ofen.py manuell mit python programme/ofen.py ausführe dann wird bei steigender Flanke auch eine Mail gesendet. Dann verstehe ich nicht warum nun gesagt wird, dass der marrow mailer nicht vorhanden ist.

Wenn ich folgenden Befehl ausführe : python -m pip install marrow.mailer
kommt folgende Meldung: Requirement already satisfied (use --upgrade to upgrade): marrow.mailer in ./.local/lib/python2.7/site-packages
Cleaning up...


@narpfel: Ja wenn ich -l hinzufüge wird aber auch nicht mehr angezeigt. Bei der ausgabe sys.path kommt die Fehlermeldung das dies nicht definiert ist:

Traceback (most recent call last):
File "programme/ofen.py", line 25, in <module>
print(sys.path)
NameError: name 'sys' is not defined

@noisefloor:

Ok. Alles klar danke für den Link. Werde ich mir durchlesen.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast den nur für deinen User, und nicht global installiert. Ich kenne die pip Funktionalität nicht, vermute aber mal du kannst das lösen indem du als Root installierst. Achte auf die ausgegebene Pfade.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

Du hast `marrow` nur für deinen Benutzer installiert und nicht global.

Wenn du `sys.path` verwendest, muss `sys` natürlich auch importiert werden. Das hab ich nicht extra dazu geschrieben, ein bisschen selbst mitdenken ist schließlich immer hilfreich.

Wenn du, wie __deets__ vorschlägt, marrow nochmal als root installierst, hast du am Ende zwei parallele Installationen. Ich würde also zuerst die benutzerspezifische Installation deinstallieren (`python -m pip uninstall marrow.mailer`) und marrow dann als root wieder installieren: `sudo python -m pip install marrow.mailer`.
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Hey,

aso ok. Ich dachte, dass man mit python global es installiert. Habe ich mich wohl geirrt.

@narpfel:
Ich kenne mich mit Python kaum aus. Brauche dies momentan nur für einen kleinen Zweck und wusste nicht, dass man dies importieren muss.
Das importieren verschiedener Module finde ich nicht so toll. Da sucht man z.b. ein Modul für was und findet es nicht. Bzw. ist Anfänger/Einsteiger und kapiert dabei nix. Das war ganz am Anfang für mich ein sehr großes Problem.

Nun läuft es so wie erhofft. Musste nurnoch eine while-schleife hinzufügen welche während es true ist überprüft ob beim Channel eine steigende Flanke ansteht und dann den Mailversand auslöst.

Mal ne generelle Frage zu wait_for_edge():

Wie funktioniert diese Funktion eigentlich?
Meine Sicht: Die Funktion erwartet je nach mitgegebenem Parameter eine fallende oder/und steigende Flanke. Und wenn diese nicht zutreffen wird None zurückgegeben. Und dann bei der Abfrage überprüfen wir ob die Funktion None zurückgibt, wenn ja liegt keines der Fälle vor wenn ja springt es in den else-block und führt die Aktion aus.

Ist dies so richtig?

Eine weitere Frage:
Wenn ich im ersten if statement nichts ausführen möchte kann ich ja auch break reinschreiben gel?

Mein Script:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf8 -*-

import RPi.GPIO as GPIO
import time
import logging
from marrow.mailer import Message, Mailer
logging.basicConfig(level=logging.INFO)

# Benötigte Werte:
# GPIO.LOW (alles ok)
# GPIO.HIGH (fehler)

# Pin-Nummern aus dem Layout benutzen (siehe gpio.jpg)
GPIO.setmode(GPIO.BOARD) 

# input setzen auf Pin-Nummer: 7 = GPIO 4
GPIO.setup(7, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)

channel = 7
	
while True:

	channel = GPIO.wait_for_edge(channel, GPIO.RISING)

	if channel is None :
		print "Alles gut"
	else:
			# Mailversand
		mail = Mailer({
			'manager.use': 'futures',
			'transport.use': 'smtp',
			'transport.host': 'smtp.gmail.com', # smtp server deines emailanbieters
			'transport.tls': 'ssl', # protokoll
			'transport.username': '', # deine email adresse
			'transport.password': '', # dein password
			'transport.max_messages_per_connection': 5
		})

		mail.start()

		#message = Message([('test', '')], [('Ich', '')], "Warnung!", plain="test")
		message = Message([('Heizungsfehlerinformation ( = Titel der E-Mail)', '')], [('Ich', '')], "Warnung! (= Betreff der E-Mail)", plain="Die Heizung im EG gibt ein Highsignal zurück. Das heißt irgendwas stimmt nicht! ( = E-Mail Text)")

		mail.send(message)
		mail.stop()

		print "Fertig"
		time.sleep(1)
Zuletzt geändert von Moon am Donnerstag 11. Januar 2018, 18:28, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Moon hat geschrieben: @narpfel:
Ich kenne mich mit Python kaum aus. Brauche dies momentan nur für einen kleinen Zweck und wusste nicht, dass man dies importieren muss.
Das importieren verschiedener Module finde ich nicht so toll. Da sucht man z.b. ein Modul für was und findet es nicht. Bzw. ist Anfänger/Einsteiger und kapiert dabei nix. Das war ganz am Anfang für mich ein sehr großes Problem.
Nennt sich "programmieren". Wenn man nicht in einem sehr speziellen Kontext (zB PHP fuer Web, das ist aber auch das einzige, was man damit machen kann, oder VBA in Excel oder so) arbeitet, braucht man ueblicherweise Bibliotheken, und die muss man installieren und benutzen. So isses halt.
Moon hat geschrieben: Mal ne generelle Frage zu wait_for_edge():

Wie funktioniert diese Funktion eigentlich?
Meine Sicht: Die Funktion erwartet je nach mitgegebenem Parameter eine fallende oder/und steigende Flanke. Und wenn diese nicht zutreffen wird None zurückgegeben. Und dann bei der Abfrage überprüfen wir um die Funktion None ist, wenn ja liegt keines der Fälle vor wenn ja springt es in den else-block und führt die Aktion aus.

Ist dies so richtig?
Nein. wait_for_edge *WARTET*, wie der Name schon sagt, darauf, das eine Flanke auftritt. Der Rueckgabewert ist wieder der Kanal auf den gewartet wurde, wozu genau das gut ist erschliesst sich mir nicht. Das *None* auftritt hat dann aber wiederum damit zu tun, dass du mal mit timeouts rumgespielt hast. Und irgendwie muss du ja unterscheiden koennen, ob du tatsaechlich eine Flanke bekommen hast, oder einen Timeout. None kommt beim Timeout. Steht - trommelwirbel - auch in der Anleitung: https://sourceforge.net/p/raspberry-gpi ... ki/Inputs/
Moon
User
Beiträge: 37
Registriert: Mittwoch 20. Dezember 2017, 15:21

Ok. Ja dann muss ich dies berücksichtigen.Ich habe bisher nur mit PHP und Javascript programmiert. Hauptsächlich fürs Web. Aber ich möchte auch andere Programmiersprachen noch erlernen. Z.b. was mir sehr viel Spaß macht sind Spiele zu programmieren. Aber dazu braucht man schon ein gewisses Know-How in der Programmiersprache welche man verwendet. Das man mit Python auch Webseiten erstellen kann wusste ich garnicht. Ist auf alle Fälle auch intressant.

Aso ok. Alles klar.

Nochmals vielen vielen Dank für die sehr gute Hilfestellungen an alle Hilfeleistenden.
Antworten