Nein, du solltest die Variablen in " setzen, sie damit umschließen.
Nein, nicht zu dem Zeitpunkt wo du es abrufst. Mit $bla möchte man den Wert/Inhalt der Variable 'bla' abrufen/auslesen, aber zu dem Zeitpunkt wo du $OPEN gesetzt hat wurde vorher nichts in diese Variable rein geschrieben.
Das selbe Problem hat du auch bei deiner letzten Version:
Auch hier versuchst du den Wert von $alt auszulesen und in 'vorher' rein zu schreiben, aber 'alt' wurde da drüber nirgends gesetzt.
Wie gesagt werden Scripts immer von oben nach unten abgearbeitet (auch Python) - das hüpft nicht willkürlich in den Zeilen umher und sucht sich irgendwas zusammen..
Auch setzt du zB PORT aber verwendest das nirgends.
Deine beiden if Schleifen bringen so jedenfalls nichts, da $neu zu dem Zeitpunkt immer 1 enthält und $alt immer 0.
'date' brauchst du auch nicht in eine Variable schreiben um diese später abzurufen, du kannst den Befehl auch direkt in der echo Zeile einfügen und die Rückgabe verwenden..
Ich würde dir auch empfehlen anstatt einen Befehl mit `ls` zu umschließen um dessen Rückgabe zu verwenden, lieber $(ls) zu nutzen, das macht es wie ich finde einfacher und übersichtlicher.
Also wenn, dann sollte/könnte das bash Script wie folgt aussehen:
#!/bin/bash
PORT=4
previous_state=-1
while true; do
current_state=$(gpio -g read $PORT)
[ "$previous_state" = -1 ] && previous_state=$current_state
if [ "$current_state" != "$previous_state" ]; then
if [ "$current_state" = 1 ]; then
echo "Tuer geoeffnet"
echo "<<<$(date)>>> Tuer geoeffnet" >> /home/pi/log.log
python /home/pi/mailpositive.py
fi
if [ "$current_state" = 0 ]; then
echo "Tuer geschlossen"
echo "<<<$(date)>>> Tuer geschlossen" >> /home/pi/log.log
fi
fi
previous_state=$current_state
sleep 5
done
Alles anzeigen
Was da Zeile-für-Zeile passiert ist im Prinzip folgendes:
-
PORT beinhaltet den GPIO pin der abgefragt werden soll
- Da beim starten des Scripts der vorherige Status noch nicht bekannt ist, wird previous_state auf -1 gesetzt um eindeutiger zu sein, denn 0 könnte missverstanden werden...
-
while true .. ist eine Schleife die sich so lange im Kreis dreht bis ein Fehler innerhalb der Schleife auftritt, oder diese mit break unterbrochen wird.
- Der aktuelle Status des GPIOs wird in current_state hinterlegt
- Die nächste Zeile ist eine verkürze if Schleife die man als 'Einzeiler' so schreiben kann, ohne 'if' am Anfang oder 'fi' am Ende. Dort wird geprüft ob previous_state noch -1 enthält, was eben ein Hinweis auf den ersten Durchlauf ist, und wenn das der Fall ist wird die Variable mit $current_state befüllt.
- Dann wird geprüft ob $current_state nicht-gleich $previous_state ist, nur wenn dem so ist wird das innerhalb der if Schleife abgearbeitet.
- Trifft die erste if-Bedingung zu, wird geprüft ob $current_state gleich 1 ist, was anzeigen sollte das der Kontakt geschlossen, beziehungsweise ein Reedswitch geöffnet ist. Ist das der Fall wird etwas ausgeben usw - das zu erklären erspar ich mir jetzt
- Wenn $current_state gleich 0 ist, wird der Spies halt umgedreht verarbeitet... Besser wäre hier aber ein " if ... elif " zu nutzen denn wenn die Bedingung bereits bei der ersten Schleife zu traf brauch man diesen nicht noch mal prüfen:
if [ "$current_state" = 1 ]; then
echo "Tuer geoeffnet"
elif [ "$current_state" = 0 ]; then
echo "Tuer geschlossen"
fi
- Am Ende der while-Schleife wird der Wert von $current_state in die Variable previous_state gesetzt damit dies beim nächsten Durchlauf verwertet werden kann.
- Die Schleife pausiert für 5 Sekunden. Nach Ablauf der Zeit beginnt die Schleife wieder von vorne.
- Ende der while-Schleife-Markierung
Es gibt aber wie immer mehrere Möglichkeiten - auch das hier kann man noch besser/schöner/effektiver machen..
Ich würde auch eher dazu tendieren auf wiringPI zu verzichten und stattdessen den GPIO-Wert direkt aus /sys/class/gpio/ auszulesen:
"bash"
#!/bin/bash
PORT=4
previous_state=-1
## init GPIOpin
if [ ! -f /sys/class/gpio/gpio${PORT}/value ]; then
echo $PORT > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio${PORT}/direction
fi
while true; do
current_state=$(cat /sys/class/gpio/gpio${PORT}/value)
[ "$previous_state" = -1 ] && previous_state=$current_state
if [ "$current_state" != "$previous_state" ]; then
if [ "$current_state" = 1 ]; then
echo "Tuer geoeffnet"
echo "<<<$(date)>>> Tuer geoeffnet" >> /home/pi/log.log
python /home/pi/mailpositive.py
fi
if [ "$current_state" = 0 ]; then
echo "Tuer geschlossen"
echo "<<<$(date)>>> Tuer geschlossen" >> /home/pi/log.log
fi
fi
previous_state=$current_state
sleep 5
done
Alles anzeigen
Allerdings sorgt das sleep dafür das innerhalb dieser Zeit keine Änderung festgestellt werden kann, das Script also genau so wie in Python blockiert wird. Öffnet und schließt sich die Tür innerhalb 5 Sekunden kann das nicht erfasst werden. Den sleep aber tiefer zu stellen verursacht mehr CPU-Last. Deshalb würde ich das eher über Python mit Interrupt umsetzen...
Aber wie gesagt frag ich mich wieso du das nicht direkt in dem /home/pi/mailpositive.py machst
Du hast doch >> hier << das Script gepostet, oder nicht? Und dein Ziel ist jetzt nur dann eine Email zu verschicken wenn sich der Zustand des GPIO's verändert? Das könnte man ziemlich einfach direkt in dem Python Script realisieren:
"python"
[code=php]
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# v0.1 by meigrafd 04.2015
#
import smtplib
import time, sys, signal
import RPi.GPIO as GPIO
#---------------------------------------------------------------------
GPIOpin = 4
# only one of following:
PULL = GPIO.PUD_DOWN #GPIO -> GND
#PULL = GPIO.PUD_UP #GPIO -> 3V3
mailServer = 'pop.gmail.com'
mailPort = 587
mailLogin = 'xxx@gmail.com'
mailPass = 'xyz'
mailSendFrom = mailLogin
mailSendTo = 'target@email.com'
mailTLS = True
mailDebug = False
#---------------------------------------------------------------------
def sendemail(from_addr, to_addr, subject, message):
try:
header = 'From: %s\n' % from_addr
header+= 'To: %s\n' % to_addr
header+= 'Subject: %s\n\n' % subject
message = header + message
conn = smtplib.SMTP(mailServer, mailPort)
if mailDebug:
conn.set_debuglevel(True) #show communication with the server
if mailTLS:
conn.starttls()
conn.login(mailLogin, mailPass)
error = conn.sendmail(from_addr, to_addr, message)
if not error:
print "Successfully sent email"
except Exception, e:
print "\nSMTP Error: " + str(e)
finally:
if conn:
conn.quit()
def interrupt_event(pin):
zeit = time.strftime('%d.%m.%Y %H:%M:%S')
if GPIO.input(pin): # if gpioPin == 1
print "{} Rising edge detected on {}".format(zeit, pin)
msg='Ihr Raspberry Pi hat den Status 1 , was soviel bedeutet wie das die Tür offen ist. Eventuell sind Ninjas in ihr Haus eingebrochen und vergreifen sich jetzt an ihren Oreo Keksen.'
sendemail(mailSendFrom, mailSendTo, 'Türbenachrichtigung', msg)
else:
print "{} Falling edge detected on {}".format(zeit, pin)
if __name__ == '__main__':
try:
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIOpin, GPIO.IN, pull_up_down = PULL)
GPIO.add_event_detect(GPIOpin, GPIO.BOTH, callback=interrupt_event, bouncetime=100)
#keep script running
signal.pause()
except (KeyboardInterrupt, SystemExit):
print 'Quit'
GPIO.cleanup()
[/php]
..fraglich wär nur ob du gewillt bist zu verstehen was da passiert um dabei auch was zu lernen :s