Abfrage einbauen : Sensor vorhanden?

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Hallo,.
habe mit raspberry 3b eine Heizungkreispumpenssteuerung mit 10Stück 18BS20 Sensoren programmiert. Läuft so wie ich mir das vorstelle
Problem immer wieder werden Sensoren nicht gefunden. Dann Programmstopp und Relais bleiben in Schaltstellung stehen.

würde gerne in die def eine Abfrage einbauen und die def relais_stromlos aufrufen.

def grad_lesen3():
datei = open('/sys/bus/w1/devices/28-3c01e07608a7/w1_slave')
zeilen = datei.readlines()
datei.close()
while zeilen[0].strip()[-3:] != 'YES':
time.sleep(0.2)
zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
temp_string = zeilen[1][equals_pos+2:]
temp_c = float(temp_string) / 100.0
return temp_c

Aufruf:
grad_lesen3()
tf3 = (int ((grad_lesen3()))/10)
time.sleep(1)

Bitte einfache oder nachvollzeihbare Vorschläge.
Danke. weitere Infos gerne erfragen
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Umulmer: Wenn Du Code in entsprechenden Code-Tags postest, bleibt die Einrückung sichtbar, was ja bei Python nicht ganz unwichtig ist.

Eingerückt wird per Konvention vier Leerzeichen pro Ebene.

Was soll die 3 am Ende vom Funktionsnamen? Namen nummerieren ist ein Warnzeichen. Du hast hier nicht die Funktion mehrfach kopiert und leicht angepasst‽

Warum wird in `grad_lesen3()` die Funktion `temperatur_lesen()` aufgerufen? Was macht *die* denn? Da muss ja irgendwie das gleiche drin stehen wie vor der Schleife stehen, damit die an der Stelle wo sie aufgerufen wird, Sinn macht. Oder ist das ein Fehler und dort wird ein anderer Sensor abgefragt als der für den `grad_lesen3()` eigentlich gedacht war?

Dateien sollte man wo es geht mit der ``with``-Anweisung verwenden.

Wenn man wissen will ob eine Zeichenkette mit etwas bestimmten endet, gibt es die `endswith()`-Methode.

Falls das mit dem `temperatur_lesen()` ein Fehler ist, was ich sehr stark vermute, würde man die Schleife anders strukturieren. Und zwar als ”Endlosschleife” die bei der passenden Bedingung dann mit ``break`` verlassen wird. Dann wiederholt man keinen Code vor und in der Schleife.

Anstelle von `find()` würde man besser gleich die Zeile mit `partition()` zerlegen. Der Code wird damit einfacher und leichter verständlich.

Das Teilen durch 100 ist falsch, denn man muss durch 1000 teilen, damit die Funktion tatsächlich Grad und nicht Dekagrad liefert.

Wenn eine Funktion auch `None` zurückgeben soll, dann macht man das *explizit*, damit der Leser das a) sofort sieht, und b) auch weiss, dass das Absicht ist, und nicht ein Fehler oder eine unfertige Funktion.

Die Funktion sieht dann so aus:

Code: Alles auswählen

def grad_lesen():
    with open(
        "/sys/bus/w1/devices/28-3c01e07608a7/w1_slave", encoding="ascii"
    ) as datei:
        zeilen = datei.readlines()

    while not zeilen[0].rstrip().endswith("YES"):
        time.sleep(0.2)
        zeilen = temperatur_lesen()  # TODO Riecht sehr komisch!

    _, _, temperature_text = zeilen[1].partition("t=")
    if temperature_text:
        return float(temperature_text) / 1000

    return None
Sie berücksichtigt nicht falls keine zwei Zeilen gelesen werden und falls der Teil nach "t=" nicht in eine Zahl umwandelbar ist. Darum, und um das `None` muss sich der Aufrufer kümmern.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

ich wollte diese Fehlermeldung vermeiden sobald der sensor nicht gefunden wird. (habe absichtlich aus der Sensorkennung eine 2 entfernt). ,
Bei Sensor nicht vorhanden, wie in diesem Fall sollte das auslesen übersprungen(abgebrochen) werden.

Traceback (most recent call last):
File "/home/pi/mu_code/min_temp.py", line 27, in <module>
grad_lesen()
File "/home/pi/mu_code/min_temp.py", line 14, in grad_lesen
"/sys/bus/w1/devices/8-3c01e07608a7/w1_slave", encoding="ascii"
FileNotFoundError: [Errno 2] No such file or directory: '/sys/bus/w1/devices/8-3c01e07608a7/w1_slave'
>>>
KeyboardInterrupt
>>>
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nachdem die Sensor-Datei verschwindet, was passiert denn dann? Du hast dann doch keine Messung mehr, also ist die Funktion erstmal nicht mehr erfüllbar. Da einen Fehler zu behandeln bringt ja nur was, wenn dieser Zustand sich wieder korrigiert. Tut der das? Wenn ja, wie, und wann? Denn da in hängt ja ab, wie das Programm arbeiten muss. Und wenn es einen Fehler gibt, was soll die Funktion dann zurückgeben? Kommt das restliche Programm mit None klar? Oder sollte irgendwo der letzte Temperaturwert gespeichert und dann geliefert werden, damit der Rest der Logik wie erwartet funktioniert?
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Falls die Sensoren nicht erkannt werden sollten die 6 Relais (GPIO.output(XX, GPIO.LOW)geschaltet werden. Es übernimmt ein mechanischer Thermoschalter den Notbetrieb der am stromlosen Relais angeschlossen ist.
Also Abfrage Sensor bist du vorhanden (hast Du einen Wert), wenn nein dann zum Ausgang.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann würde ich da gar keine Fehlerbehandlung machen, sondern ganz außen ums Programm rum in einem finally clause einfach alles ausschalten.

Code: Alles auswählen

def main():
    …
    try:
         haupschleife()
    finally:
        alles_aus()
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

"/sys/bus/w1/devices/8-3c01e07608a7/w1_slave", encoding="ascii"
FileNotFoundError: [Errno 2] No such file or directory: '/sys/bus/w1/devices/8-3c01e07608a7/w1_slave'

es geht genau um diesen Fehler. Wenn dieser auftritt mochte ich zur def alles_aus()
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Habe ich doch gezeigt.
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Was evt. bei meiner Erklärung noch fehlt. Das ganze Programm wird derzeit jede Minute mit auslesen aller 10 Sensoren und Rechenoperationen für die Relaissteuerung wiederholt.
ich brauche den Ausgang aus der Def grad_lesenX()

def grad_lesenX():
datei = open('/sys/bus/w1/devices/28-3c01e0762d25/w1_slave')
zeilen = datei.readlines()
datei.close()
while zeilen[0].strip()[-3:] != 'YES':
time.sleep(0.2)
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
temp_string = zeilen[1][equals_pos+2:]
temp_c = float(temp_string) / 100.0
return temp_c

oder einer anderen def mit temperaturausgabe und abfrage sensor vorhanden
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie wäre es, wenn du mal das ganze Programm zeigst, statt nur davon zu erzählen? Das problem scheint mir, dass du dich in eine bestimmte Richtung verrannt hast, wie dein Problem zu lösen sei. Und ob diese Einschätzung stimmt, kann man nur am Gesamtkunstwerk beurteilen. Und das bitte - wie schon von __blackjack__ erwähnt - in den Code Tags. Sonst ist es unlesbar.
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

#!/usr/bin/python cd /sys/bus/w1/devices
import time
import datetime
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.OUT)# P1 pww
GPIO.setup(22, GPIO.OUT)# p2 pug
GPIO.setup(5, GPIO.OUT)# p3 pog
GPIO.setup(6, GPIO.OUT)# p4 pfb
GPIO.setup(19, GPIO.OUT)# Notfallschaltung UG
GPIO.setup(26, GPIO.OUT)# Notfallschaltung OG
GPIO.setup(13, GPIO.OUT)# LED rot
GPIO.setup(21, GPIO.OUT)# LED grün

a=0
wohnzimmer_max_temperatur = 22.1
wahl_ug = 2
wahl_og = 3
wahl_fb = 2
wahl_wawa =
#####28-3c01e0768414 tf1 hoke.txt
print("gestartet UG",wahl_ug," /OG",wahl_og," /FB",wahl_fb," /Warmwasser",wahl_wawa)
GPIO.output(26, GPIO.HIGH)
def grad_lesen1():
.datei = open('/sys/bus/w1/devices/28-3c01e0768414/w1_slave')
.zeilen = datei.readlines()
datei.close()
while zeilen[0].strip()[-3:] != 'YES':
. time.sleep(0.2)
.zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
.. temp_string = zeilen[1][equals_pos+2:]
..temp_c = float(temp_string) / 100.0
..return temp_c

def grad_lesen2():
. datei = open('/sys/bus/w1/devices/28-3c01e076b2b0/w1_slave')
. zeilen = datei.readlines()
.datei.close()
. while zeilen[0].strip()[-3:] != 'YES':
.. time.sleep(0.2)
. . zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
.. temp_string = zeilen[1][equals_pos+2:]
.. temp_c = float(temp_string) / 100.0
.. return temp_c
### #28-3c01e07608a7 tf3 pubo
def grad_lesen3():
. datei = open('/sys/bus/w1/devices/28-3c01e07608a7/w1_slave')
. zeilen = datei.readlines()
. datei.close()
. while zeilen[0].strip()[-3:] != 'YES':
.. time.sleep(0.2)
.. zeilen = temperatur_lesen()
. equals_pos = zeilen[1].find('t=')
.if equals_pos != -1:
.. temp_string = zeilen[1][equals_pos+2:]
.. temp_c = float(temp_string) / 100.0
.. return temp_c
### 6 tevo temperatur vorlauf
def grad_lesen6():
datei = open('/sys/bus/w1/devices/28-3c01e0762d25/w1_slave')
zeilen = datei.readlines()
datei.close()
while zeilen[0].strip()[-3:] != 'YES':
time.sleep(0.2)
zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
temp_string = zeilen[1][equals_pos+2:]
temp_c = float(temp_string) / 100.0
return temp_c
####28-3c01e076f457 tf9 aute
def grad_lesen9():
datei = open('/sys/bus/w1/devices/28-3c01e076f457/w1_slave')
zeilen = datei.readlines()
datei.close()
while zeilen[0].strip()[-3:] != 'YES':
time.sleep(0.2)
zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
temp_string = zeilen[1][equals_pos+2:]
temp_c = float(temp_string) / 100.0
return temp_c
## tf10 wozi
def grad_lesen10():
. datei = open('/sys/bus/w1/devices/28-3c01d607a1b6/w1_slave')
. zeilen = datei.readlines()
. datei.close()
. while zeilen[0].strip()[-3:] != 'YES':
.. time.sleep(0.2)
.. zeilen = temperatur_lesen()
. equals_pos = zeilen[1].find('t=')
. if equals_pos != -1:
.. temp_string = zeilen[1][equals_pos+2:]
.. temp_c = float(temp_string) / 100.0
.. return temp_c
pumpeug = wahl_ug + 10 #prg 2 PuO >37 vs un hs programm 2
pumpeog = wahl_og + 20 #(prg 2 =VL>32) vs = programm 3 hs = programm 2
pumpefb = wahl_fb + 30
pumpewawa = wahl_wawa +40
pru = 0
pug=0
pog=0
pfb=0
pww=0
mogb=0
nog=0
nug=0
div=0
pogtimea = 0
pogtimeb = 0
pogtimec = 0
pogtimed = 0
pogtimee = 0
pogtimef = 0
pogges = 0
tmerk = 300
tmerkmax = 1
GPIO.output(19, GPIO.LOW)
GPIO.output(26, GPIO.LOW)
try:
. while True:
.. grad_lesen1() ###################Vorlauf tf6 > 58 C und Wawa tf2 < 50 / max 56
.. tf1 = (int ((grad_lesen1()))/10)
.. time.sleep(1)
.. grad_lesen2()
.. tf2 = (int ((grad_lesen2()))/10)
.. time.sleep(1)
.. grad_lesen3()
.. tf3 = (int ((grad_lesen3()))/10)
.. time.sleep(1)
.. grad_lesen6()
.. tf6 = (int ((grad_lesen6()))/10)
. . time.sleep(1)
.. grad_lesen9()
.. tf9 = (int ((grad_lesen9()))/10)
.. time.sleep(1)
.. grad_lesen10()
.. tf10 = (int((grad_lesen10()))/10)
.. time.sleep(1)
.. current = datetime.datetime.now().time()
.. GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
.. GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
.. mogb=0
.. if GPIO.input(23) == GPIO.HIGH:
... mogb=1
.. if GPIO.input(24) == GPIO.HIGH:
... mogb=2
.. if pumpeug == 10:
... #print (" Pumpe UG Dauer aus ").
... pug = 0
.. if pumpeug == 11:.
... #print (" Pumpe UG Dauer ein ")
... pug = 1
.. if pumpeug == 12:
... if tf3 > 37:
..... if tf10 > wohnzimmer_max_temperatur:
...... #print("pug aus Wohnzimmer,einstellwert erreicht =",tf10)
... if tf3 > 42:
..... nug = 1
..... #print (" Pumpe OG puob > 37 ein ")
... else:
.... nug = 0
... pug = 0
.... if tf10 < wohnzimmer_max_temperatur:
..... pug = 1
..... #print (" Pumpe UG puug ein PO > 37 WZ",tf10)
..... else:
.... pug = 0
.... nug = 0
... #print (" Pumpe UG puug > 37 aus , else")
.. if pumpeog == 20:.
... #print (" Pumpe OG Dauer aus ")
... pog = 0
.. else:
... pog = 0
.. if pumpeog == 21:
... #print (" Pumpe OG Dauer ein ")
.... pog = 1
.. if pumpeog == 22:
... if tf3 > 37:
pog = 1
#print (" Pumpe OG puob > 37 ein ")
else:
pog = 0
if pumpeog == 23: #mit zeizschALTschaltuhr
if tf3 > 42:
nog = 1
#print (" Pumpe OG puob > 37 ein ")
else:
nog = 0
if tf3 > 37:
#print (" Pumpe OG puob > 37 ein ")
if datetime.time(21, 20) <= current <= datetime.time(21, 45):
pogtimea = 1
#print("geht")
else:
pogtimea = 0
if datetime.time(23, 20) <= current <= datetime.time(23, 40):
pogtimeb = 1
#print("geht")
else:
pogtimeb = 0
if datetime.time(1, 21) <= current <= datetime.time(1, 31):
pogtimec = 1
#print("geht")
else:
pogtimec = 0
if datetime.time(3, 21) <= current <= datetime.time(3, 31):
pogtimed = 1
#print("geht")
else:
pogtimed = 0
if datetime.time(5, 10) <= current <= datetime.time(5, 25):
pogtimee = 1
else:
pogtimee = 0
if datetime.time(7, 10) <= current <= datetime.time(7, 30):
pogtimef = 1
else:
pogtimef = 0
pogges = pogtimea + pogtimeb + pogtimec + pogtimed + pogtimee +pogtimef
if pogges > 0:
pog = 1
#print(pogges,"ges ist
else:
pog = 0
else:
pog = 0
if pumpefb == 30:
#print (" Pumpe Fussboden Dauer aus ")
pfb = 0
if pumpefb == 31:
#print (" Pumpe Fussboden Dauer ein ")
pfb = 1
if pumpefb == 32:
if tf6 > 32:
pfb = 1
#print (" Pumpe Fb pfb >VL 32 ein ")
else:
pfb = 0
#print (" Pumpe Fb pfb >VL 32 aus ")
if pumpewawa == 40:
#print (" Pumpe Wawa Dauer aus ")
pww = 0
if pumpewawa == 41:
#print (" Pumpe Wawa Dauer ein ")
pww = 1
#print (pumpewawa)
if pumpewawa == 47:
###################Vorlauf tf6 > dif und Wawa tf2 < 44 / max 46 C
dif = tf2 + 8
if tf6 > dif:
#print(dif," ",tf6,">",dif)
if tf2 < 44:
pww = 1
#print("ok")
if tf2 > 46:
pww = 0
#print(" Pumpe Wawa aus Puffer über 46 C ",tf2)
else:
pww = 0
#print(" Pumpe Wawa aus VL",tf6,"div kleiner 8° / Warmwasser ",tf2)
if pumpewawa == 49:
###################Vorlauf tf6 > dif und Wawa tf2 < 50 / max 55 C
dif = tf2 + 8
if tf6 > dif:
if tf2 < 50:
pww = 1
if tf2 > 55:
pww = 0
... #print(" Pumpe Wawa aus Puffer über badetemp 55 C ",tf2)
.. . else:
... . pww = 0
.. if pww == 1:
... GPIO.output(27, GPIO.HIGH)
.. else:
... GPIO.output(27, GPIO.LOW)
.. if pug == 1:
... GPIO.output(22, GPIO.HIGH)
.. else:
... GPIO.output(22, GPIO.LOW)
.. if pog == 1:
.... GPIO.output(5, GPIO.HIGH)
.. else:
... GPIO.output(5, GPIO.LOW)
.. if pfb == 1:
... GPIO.output(6, GPIO.HIGH)
.. else:
... GPIO.output(6, GPIO.LOW)
.. if nog == 1:
... . GPIO.output(26, GPIO.HIGH)
.. else:
... GPIO.output(26, GPIO.LOW)
.. if nug == 1:
... GPIO.output(19, GPIO.HIGH)
.. else:
... GPIO.output(19, GPIO.LOW) ..
.. if tf9 < tmerk:
... tmerk = tf9
.. if tf9 > tmerkmax:
... tmerkmax = tf9
.. print ("pug ",pug,"PO",tf3,"/pog",pog,"ZsU",pogges,"/pfb",pfb," VL",tf6,"/pww",pww," Wawa",tf2," /AT",tf9,"(",tmerk,tmerkmax,")/HoK",tf1," /Gbl",mogb,"/Wozi",tf10," ",time.strftime("%d.%m.%Y %H:%M:%S"),"NOGÜ",nog,"NUGÜ",nug)
.. time.sleep(39)

except KeyboardInterrupt:#Strg+c
. #gpio.cleanup()
. GPIO.output(5, GPIO.LOW)
. GPIO.output(6, GPIO.LOW)
. GPIO.output(21, GPIO.LOW)
. GPIO.output(13, GPIO.LOW)
. GPIO.output(19, GPIO.LOW)
. GPIO.output(26, GPIO.LOW)
. pru = 0
. pug = 0
. pog = 0.
. pfb = 0
. pww = 0
. print (" bye")
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Code Tags sind der </>-Knopf im vollständigen Editor.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Umulmer: Du könntest vielleich mal vorher auch die angesprochenen Punkte berücksichtigen. Eine Funktion `temperatur_lesen()` gibt es auch überhaupt gar nicht, in dem Fall würde jede dieser kopierten Funktionen also in einen `NameError` laufen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Im Grunde ist der Code aber auch schon fast da. Statt dem except KeyboardError einfach das finally hinschreiben, und egal warum das Ding abschmiert, es wird zurück gesetzt. Das es daneben viel zu verbessern gäbe, steht auf einem anderen Blatt. Angefangen von der Hardware, die 1-wire Sensoren sind leider notorisch unrobust.
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Code: Alles auswählen

def grad_lesen():
    with open(
        "/sys/bus/w1/devices/28-3c01e07608a7/w1_slave", encoding="ascii"
    ) as datei:
        zeilen = datei.readlines()

    while not zeilen[0].rstrip().endswith("YES"):
        time.sleep(0.2)
        zeilen = temperatur_lesen()  # TODO Riecht sehr komisch!

    _, _, temperature_text = zeilen[1].partition("t=")
    if temperature_text:
        return float(temperature_text) / 1000

    return None
Danke für alle Anregungen, versuch Sie umzusetzen.
hallo blackjack,
bekomme aus der Def grad_lesen keine Werte.
entschuldigt wenn ich mich unerfahren anstelle bin ich ja auch.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Umulmer: Was heisst Du bekommst keine Werte? Das könnte nur passieren wenn `temperatur_lesen()` jetzt doch irgendwie definiert ist und das eine Endlosschleife ist. Ansonsten hat die Funktion garantiert irgend einen Rückgabewert, oder löst eine Ausnahme aus.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Bitte schreib doch noch einige Zeilen um Werte über print() anzuzeigen. Bei meinen Versuchen läuft das Programm ohne Ausgabe durch.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das Programm ist doch nur eine Funktion. Da wird nichts aufgerufen. Das musst du dann schon selbst einbauen.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Um noch mal klar zu machen, was mein Vorschlag war:

Code: Alles auswählen

except KeyboardInterrupt:
ist durch

Code: Alles auswählen

finally:
zu ersetzen, und dann stellt sich, wenn alles andere so bleibt wie bisher, der gewuenschte Effekt ein: egal warum das Programm abschmiert (und eben nicht nur, wenn man C-c drueckt!), wird alles ausgeschaltet.

Der ganze Rest ist wirklich sehr schlecht programmiert (jaja, ich weiss, Anfaenger, aber so ist es halt trotzdem), und da wuerde ich, wenn das sonst so tut, am besten gar nichts dran rumdrehen.
Umulmer
User
Beiträge: 11
Registriert: Samstag 20. November 2021, 12:27

Hallo deets,
einbau finally: erfolgreich. Danke
Frage : wie kann ich im laufende Programm ein Input aufrufen um die Vorgabe der Wohnzimmertemperatur zu ändern ?
Antworten