Einbinden Pythonprogramm in Qt Oberfläche

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

Hallo Zusammen,
ich habe ein Pythonprogramm (Regler.py) erstellt, dem ich jetzt über eine Oberfläche Sollwerte zur Initialisierung geben möchte und die laufenden Istwerte anzeigen will, dazu habe ich mit dem Qt-Designer mir die Oberfläche erstellt und compiliert (Stufensteuerung).
Ich möchte das Reglerprogramm jetzt in die Stufensteuerung einbinden und scheitere daran. Könnt ihr mir weiterhelfen?
Regler.py

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue May  5 04:07:56 2020
@author: pi
"""

import time




def Temperatur():
          
    file = open('/mnt/1wire/10.D0DAB4020800/temperature','r')
    Temp_ist = file.read()
    file.close()
    T=float(Temp_ist)
    print(T)
    return (T)

def Relais1(R1_EA):
    
      file = open('/mnt/1wire/29.85610C000000/PIO.0','w')    
      file.write(R1_EA)
      file.close()
      


def Stufe(Gw,Zt,S):        
    GwT=Gw
    Zw=Zt
    T=Temperatur()
    Lt=Zt
    
    while T < GwT:
       Ein="1" 
       Relais1(Ein)
       T=Temperatur()
       print(T,Lt,Ein,S)
       #return (T,Lt)        
    else:
        start = time.time()
        stop = start + Zw*60
        T=Temperatur()
        #print(T,Lt,Ein)
        #return (T,Lt)
        while time.time() < stop:
                Lt = stop-time.time()
                T=Temperatur()
                print(T,Lt,Ein,S)
                #return (T,Lt)
                if T < GwT:
                   Ein="1" 
                   Relais1(Ein)
                   print(T,Lt,Ein,S)
                   #return (T,Lt)
                else:
                    T=Temperatur()
                    Ein = "0"
                    Relais1(Ein)
                    print(T,Lt,Ein,S)
                    #return (T,Lt)
                b=S+1
        print(T,Lt,Ein,S)
        return(b,T)
          
#Initwerte
b=0

Ein="0"                            
                        
Gw1 = 25    # °C
Zt1 = 2.5     # min

Gw2 = 28    # °C
Zt2 = 3.0    # min

Gw3 = 31    # °C
Zt3 = 3.5     # min
                          


while b <=4:
    b=b+1
    if b==1:                        
        Stufe(Gw1,Zt1,b)
    if b==2:
        Stufe(Gw2,Zt2,b)
    if b==3:
        Stufe(Gw3,Zt3,b)
    if b==4:
        Ein = "0"
        Relais1(Ein)
        print("Alle Stufen fertig")
Stufensteuerung.py

Code: Alles auswählen

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Stufensteuerung.ui'
#
# Created by: PyQt5 UI code generator 5.14.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(665, 574)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(350, 400, 87, 112))
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.pushButtonStart = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButtonStart.setObjectName("pushButtonStart")
        self.verticalLayout.addWidget(self.pushButtonStart)
        self.pushButtonStop = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButtonStop.setObjectName("pushButtonStop")
        self.verticalLayout.addWidget(self.pushButtonStop)
        self.layoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget1.setGeometry(QtCore.QRect(40, 230, 513, 114))
        self.layoutWidget1.setObjectName("layoutWidget1")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.layoutWidget1)
        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.verticalLayout_7 = QtWidgets.QVBoxLayout()
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.Z1soll = QtWidgets.QLabel(self.layoutWidget1)
        self.Z1soll.setObjectName("Z1soll")
        self.verticalLayout_7.addWidget(self.Z1soll)
        self.Z2soll = QtWidgets.QLabel(self.layoutWidget1)
        self.Z2soll.setObjectName("Z2soll")
        self.verticalLayout_7.addWidget(self.Z2soll)
        self.Z3soll = QtWidgets.QLabel(self.layoutWidget1)
        self.Z3soll.setObjectName("Z3soll")
        self.verticalLayout_7.addWidget(self.Z3soll)
        self.horizontalLayout_3.addLayout(self.verticalLayout_7)
        self.verticalLayout_8 = QtWidgets.QVBoxLayout()
        self.verticalLayout_8.setObjectName("verticalLayout_8")
        self.spinBoxZ1soll = QtWidgets.QSpinBox(self.layoutWidget1)
        self.spinBoxZ1soll.setSpecialValueText("")
        self.spinBoxZ1soll.setMinimum(1)
        self.spinBoxZ1soll.setMaximum(60)
        self.spinBoxZ1soll.setObjectName("spinBoxZ1soll")
        self.verticalLayout_8.addWidget(self.spinBoxZ1soll)
        self.spinBoxZ2soll = QtWidgets.QSpinBox(self.layoutWidget1)
        self.spinBoxZ2soll.setSpecialValueText("")
        self.spinBoxZ2soll.setMinimum(1)
        self.spinBoxZ2soll.setMaximum(60)
        self.spinBoxZ2soll.setObjectName("spinBoxZ2soll")
        self.verticalLayout_8.addWidget(self.spinBoxZ2soll)
        self.spinBoxZ3soll = QtWidgets.QSpinBox(self.layoutWidget1)
        self.spinBoxZ3soll.setSpecialValueText("")
        self.spinBoxZ3soll.setMinimum(1)
        self.spinBoxZ3soll.setMaximum(60)
        self.spinBoxZ3soll.setObjectName("spinBoxZ3soll")
        self.verticalLayout_8.addWidget(self.spinBoxZ3soll)
        self.horizontalLayout_3.addLayout(self.verticalLayout_8)
        self.horizontalLayout_5.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.verticalLayout_9 = QtWidgets.QVBoxLayout()
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.Z1ist = QtWidgets.QLabel(self.layoutWidget1)
        self.Z1ist.setObjectName("Z1ist")
        self.verticalLayout_9.addWidget(self.Z1ist)
        self.Z2ist = QtWidgets.QLabel(self.layoutWidget1)
        self.Z2ist.setObjectName("Z2ist")
        self.verticalLayout_9.addWidget(self.Z2ist)
        self.Z3ist = QtWidgets.QLabel(self.layoutWidget1)
        self.Z3ist.setObjectName("Z3ist")
        self.verticalLayout_9.addWidget(self.Z3ist)
        self.horizontalLayout_4.addLayout(self.verticalLayout_9)
        self.verticalLayout_10 = QtWidgets.QVBoxLayout()
        self.verticalLayout_10.setObjectName("verticalLayout_10")
        self.lineEditZ1ist = QtWidgets.QLineEdit(self.layoutWidget1)
        self.lineEditZ1ist.setObjectName("lineEditZ1ist")
        self.verticalLayout_10.addWidget(self.lineEditZ1ist)
        self.lineEditZ2ist = QtWidgets.QLineEdit(self.layoutWidget1)
        self.lineEditZ2ist.setObjectName("lineEditZ2ist")
        self.verticalLayout_10.addWidget(self.lineEditZ2ist)
        self.lineEditZ3ist = QtWidgets.QLineEdit(self.layoutWidget1)
        self.lineEditZ3ist.setObjectName("lineEditZ3ist")
        self.verticalLayout_10.addWidget(self.lineEditZ3ist)
        self.horizontalLayout_4.addLayout(self.verticalLayout_10)
        self.horizontalLayout_5.addLayout(self.horizontalLayout_4)
        self.layoutWidget2 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget2.setGeometry(QtCore.QRect(80, 20, 413, 114))
        self.layoutWidget2.setObjectName("layoutWidget2")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.layoutWidget2)
        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.Temp1soll = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp1soll.setObjectName("Temp1soll")
        self.verticalLayout_2.addWidget(self.Temp1soll)
        self.Temp2soll = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp2soll.setObjectName("Temp2soll")
        self.verticalLayout_2.addWidget(self.Temp2soll)
        self.Temp3soll = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp3soll.setObjectName("Temp3soll")
        self.verticalLayout_2.addWidget(self.Temp3soll)
        self.horizontalLayout_2.addLayout(self.verticalLayout_2)
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.doubleSpinBoxT1soll = QtWidgets.QDoubleSpinBox(self.layoutWidget2)
        self.doubleSpinBoxT1soll.setSpecialValueText("")
        self.doubleSpinBoxT1soll.setMinimum(0.5)
        self.doubleSpinBoxT1soll.setMaximum(101.0)
        self.doubleSpinBoxT1soll.setSingleStep(0.5)
        self.doubleSpinBoxT1soll.setProperty("value", 0.5)
        self.doubleSpinBoxT1soll.setObjectName("doubleSpinBoxT1soll")
        self.verticalLayout_6.addWidget(self.doubleSpinBoxT1soll)
        self.doubleSpinBoxT2soll = QtWidgets.QDoubleSpinBox(self.layoutWidget2)
        self.doubleSpinBoxT2soll.setSpecialValueText("")
        self.doubleSpinBoxT2soll.setMinimum(0.5)
        self.doubleSpinBoxT2soll.setMaximum(101.0)
        self.doubleSpinBoxT2soll.setSingleStep(0.5)
        self.doubleSpinBoxT2soll.setObjectName("doubleSpinBoxT2soll")
        self.verticalLayout_6.addWidget(self.doubleSpinBoxT2soll)
        self.doubleSpinBoxT3soll = QtWidgets.QDoubleSpinBox(self.layoutWidget2)
        self.doubleSpinBoxT3soll.setSpecialValueText("")
        self.doubleSpinBoxT3soll.setMinimum(0.5)
        self.doubleSpinBoxT3soll.setMaximum(101.0)
        self.doubleSpinBoxT3soll.setSingleStep(0.5)
        self.doubleSpinBoxT3soll.setObjectName("doubleSpinBoxT3soll")
        self.verticalLayout_6.addWidget(self.doubleSpinBoxT3soll)
        self.horizontalLayout_2.addLayout(self.verticalLayout_6)
        self.horizontalLayout_6.addLayout(self.horizontalLayout_2)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.Temp1ist = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp1ist.setObjectName("Temp1ist")
        self.verticalLayout_5.addWidget(self.Temp1ist)
        self.Temp2ist = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp2ist.setObjectName("Temp2ist")
        self.verticalLayout_5.addWidget(self.Temp2ist)
        self.Temp3ist = QtWidgets.QLabel(self.layoutWidget2)
        self.Temp3ist.setObjectName("Temp3ist")
        self.verticalLayout_5.addWidget(self.Temp3ist)
        self.horizontalLayout.addLayout(self.verticalLayout_5)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.lineEditT1ist = QtWidgets.QLineEdit(self.layoutWidget2)
        self.lineEditT1ist.setObjectName("lineEditT1ist")
        self.verticalLayout_3.addWidget(self.lineEditT1ist)
        self.lineEditT2ist = QtWidgets.QLineEdit(self.layoutWidget2)
        self.lineEditT2ist.setObjectName("lineEditT2ist")
        self.verticalLayout_3.addWidget(self.lineEditT2ist)
        self.lineEditT3ist = QtWidgets.QLineEdit(self.layoutWidget2)
        self.lineEditT3ist.setObjectName("lineEditT3ist")
        self.verticalLayout_3.addWidget(self.lineEditT3ist)
        self.horizontalLayout.addLayout(self.verticalLayout_3)
        self.horizontalLayout_6.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButtonStart.setText(_translate("MainWindow", "Start"))
        self.pushButtonStop.setText(_translate("MainWindow", "Stop"))
        self.Z1soll.setText(_translate("MainWindow", "Z1[min]"))
        self.Z2soll.setText(_translate("MainWindow", "Z2[min]"))
        self.Z3soll.setText(_translate("MainWindow", "Z3[min]"))
        self.Z1ist.setText(_translate("MainWindow", "Z1_ist"))
        self.Z2ist.setText(_translate("MainWindow", "Z2_ist"))
        self.Z3ist.setText(_translate("MainWindow", "Z3_ist"))
        self.Temp1soll.setText(_translate("MainWindow", "T1_soll"))
        self.Temp2soll.setText(_translate("MainWindow", "T2_soll"))
        self.Temp3soll.setText(_translate("MainWindow", "T3_soll"))
        self.Temp1ist.setText(_translate("MainWindow", "T1_ist"))
        self.Temp2ist.setText(_translate("MainWindow", "T2_ist"))
        self.Temp3ist.setText(_translate("MainWindow", "T3_ist"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
    
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Loesung fuer so ein Problem besteht in der Nutzung von QTimern. Damit definierts du dir einen Timer, der zB jede Sekunde eine Methode aufruft. Darin pruefst du dann, was gerade zu tun ist, und machst das dann.
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__deets__
Hallo Zusammen,

Danke für die Antwort, jedoch bin ich damit überfordert, da ich Anfänger bin und noch nicht so tief in der Materie bin.
Mein Problem geht noch etwas tiefer, ich weiß nicht wie die Eingaben aus dem Programm "Stufensteuerung" aus zulesen sind z.B. " self.doubleSpinBoxT1soll. ..." damit ich diese für "Zt1" im Programm "Regler" nutzen kann.

Dann muss ja der Programmcode "Regler" noch in den der Stufensteuerung als Funktion eingebunden werden.
Könnt ihr mir ggf. das in einenm Beispiel aufzeigen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast dir mit GUI-Programmierung und einem nebenlaeufigen Problem halt zwei sehr komplexe Themen gesucht. Als Bergsteiger gleich als erstes auf den K2 zu wollen, stellt nunmal eine Ueberforderung dar.

Code: Alles auswählen

from PyQt5.QtCore import QTimer, QObject
from PyQt5.QtWidgets import QSlider, QApplication


class SliderAndTimerTest(QObject):

    def __init__(self):
        super().__init__()
        self._slider = QSlider()
        self._slider.show()
        self._timer = QTimer(self)
        self._timer.timeout.connect(self._timer_fired)
        self._timer.start(500)

    def _timer_fired(self):
        print(self._slider.value())



def main():
    app = QApplication([])
    gui = SliderAndTimerTest()
    app.exec_()


if __name__ == '__main__':
    main()
Dieses minimale Beispiel zeigt die Verwendung eines Timers, und wie man auf Werte aus einem Widget zugreifen kann.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und noch ein Nachtrag: die Qt-Designer-Datei da oben solltest du gar nicht generieren, sondern mittels loadUI laden. Der dicke Kommentar gleich zu Beginn begruendet das. Hier im Forum wird auch das regelmaessig diskutiert, und es findet sich Code, wie man mit loadUI arbeitet.
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__deets__
Hallo

danke für die schnelle Antwort ich sehe schon, das ohne die richtige Ausrüstung und Übung der K2 nicht zu Schaffen ist.

Mit welchem Werkzeug kann ich es dennoch schaffen den " Feldberg " zu erwandern (als Etappe), um eine Ein- und Ausgabe des Regler.py über eine Benutzeroberfläche zu erreichen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich verstehe die Frage nicht. Du hast das Problem ja noch nicht veraendert. Du willst immer noch das gleiche erreichen. Dann wirst du die gleichen Massnahmen treffen muessen.

Dein Regler.py Code muss so veraendert werden, dass er

- keine einzige while-Schleife hat.
- seinen Zustand in einem Objekt speichert.
- durch einen regelmaessigen Aufruf einer Methode auf diesem Objekt, abhaengig von GUI-Zustand (Reglern etc.), Zeit die vergangen ist, und den Eingaben aus den Sensoren eine Entscheidung getroffen wird, was passieren soll mit den Relais.

Ich weiss nicht was du hier als ganzes erreichen willst, aber wie schon gesagt: das ist mit einer Programmiersprache/Umgebung wie Python (oder C++, Java etc) konzeptionell herausfordernd. Es kann sein, dass du hier deutlich besser faehrst, wenn du mit einer SPS oder Software wie CODESYS arbeitest.
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__deets__
Das Regler.py funktioniert.
Ich wollte eine Oberfläche in der ich die Zeitwerte und Tempeaturen vorgebe ohne dass ich im Programm diese Werte ändere und die Istwerte direkt im Blick habe. Ich dachte es ist mit einer Art Schnittstelle zu bewerkstelligen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist mir schon klar. Und ich beschreibe dir, wie du den notwendigen Umbau taetigst. Was sonst denkst du erklaere ich dir hier?

Eine GUI ist ereignisbasiert. Code, der dauerhaft laeuft, vertraegt sich prinizpbedingt damit nicht. Entweder baust du den also so um, das er timer-basiert arbeitet. Oder du benutzt Threads, aber bekommst dann das Problem, dass du keine GUI-Elemente aus dem Thread ansprechen darfst. Du kannst also ohne Inter-Thread-Kommunikation keine Daten austauschen. Das ist schlussendlich auch nicht einfacher. Und bei deinem dreifach verschachtelten while-Schleifen auch nicht klar, wo und wie genau diese Nachrichten abgegriffen werden sollen.
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__deets__
Ok, dann muss ich mich erst noch in die GUI Programmierung einlesen und einarbeiten, wie Qtimer funktionieren und ob ich meinen Steuerungsablauf dann wieder so hin bekomme.
Danke für die Unterstützung.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ruesch: Das Regler-Programm mag funktionieren, aber da gäbe es schon ein paar Anmerkungen die man machen sollte.

Eingerückt wird mit vier Leerzeichen pro Ebene.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Namen sollten keine kryptischen Abkürzungen enthalten, und schon gar nicht nur aus kryptischen Abkürzungen bestehen. Funktionen und Methoden werden nach Tätigkeiten benannt, damit der Leser weiss was sie tun und um sie von eher passiven Werten unterscheiden zu können. `Temperatur` ist beispielsweise ein Name für eine Temperatur, nicht für eine Funktion die eine Temperatur ermittelt.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Die erste Zuweisung an `Ein` im Hauptprogramm wird nie irgendwo verwendet und kann weg. Die zweite wird nur einmal im Aufruf in der darauffolgenden Zeile verwendet. Das braucht man nicht an einen Namen zu binden.

``return`` ist keine Funktion, also sollte man das auch nicht so schreiben als wäre es eine. Die Klammern um den Rückgabewert sind überflüssig.

Der Rückgabewert von `Stufe()` wird nirgends verwendet, es braucht also nichts zurückgegeben werden. Dann wird `b` in `Stufe` nicht mehr verwendet. Und folgend darauf auch das Argument `S` nicht.

Das die anderen beiden Argumente von `Stufe()` als erstes in der Funktion an andere Namen gebunden werden und ansonsten nicht verwendet werden macht überhaupt keinen Sinn. Warum diese Umbenennung?

Das ``else`` zum ``while`` macht keinen Sinn. Der Schleifenkörper enthält kein ``break``, also wird das ``else`` *immer* ausgeführt. Dafür wäre es aber einfacher den Code davon einfach nach der Schleife zu schreiben.

Die Zeile zum Auslesen der Temperatur steht viel zu oft in der Funktion. Zweimal sogar völlig umsonst, weil das Ergebnis von dem Aufruf gar nicht verwendet wird. Ansonsten kann man noch zwei Aufrufe im Code einsparen in dem man den Wert nicht unnötig an einen Namen bindet.

`schalte_relais()` sollte einen Wahrheitswert als Argument bekommen und nicht die Zeichenketten "0" und "1". Das ist ein Detail der Implementierung das man so nicht nach aussen tragen sollte.

Statt `time.time()` sollte man `time.monotonic()` verwenden.

Von `Stufe()` bleiben letztendlich fünf bis sechs Zeilen Code übrig.

Das mit `b` im Hauptprogramm ist unsinnig. Da werden doch nur die Schritte in den ``if``-Zweigen nacheinander ausgeführt. Warum steht das in einer Schleife die immer nur einen Zweig ausführt, statt einfach die Schritte nacheinander in den Code zu schreiben?

Wenn man Namen durchnummeriert will man in der Regel bessere Namen wählen, oder gar keine Einzelnamen sondern eine Datenstruktur. Oft, und auch in diesem Fall eine Liste. Und da kommt dann auch wieder eine Schleife ins Spiel.

Dateien sollte man wo möglich mit der ``with``-Anweisung öffnen. Und bei Textdateien immer eine explizite Kodierung angeben.

Überarbeitete Version (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import time


def lese_temperatur():
    with open(
        "/mnt/1wire/10.D0DAB4020800/temperature", "r", encoding="ascii"
    ) as file:
        return float(file.read())


def schalte_relais(state):
    with open(
        "/mnt/1wire/29.85610C000000/PIO.0", "w", encoding="ascii"
    ) as file:
        file.write(str(int(state)))


def regele_temperatur(temperaturgrenzwert, dauer):
    while lese_temperatur() < temperaturgrenzwert:
        schalte_relais(True)

    stop = time.monotonic() + dauer * 60
    while time.monotonic() < stop:
        schalte_relais(lese_temperatur() < temperaturgrenzwert)


def main():
    for temperaturgrenzwert, dauer in [(25, 2.5), (28, 3), (31, 3.5)]:
        regele_temperatur(temperaturgrenzwert, dauer)
    schalte_relais(False)
    print("Alle Stufen fertig")


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__blackjack__
Danke für die konstruktiven Anmerkungen, ich bin gerade beim Austesten der überarbeiteten Version.
"encoding" musste ich weglassen kam die Fehlermeldung "TypeError: 'encoding' is an invalid keyword argument for this function "
Das Programm lief bis dann zu "time.monotonic()" hier kommt der Fehler "AttributeError: 'module' object has no attribute 'monotonic' "
Ich habe nach gelesen das time.monotonic() Python 2 ggf. nicht kennt. Ich habe beides installiert python 2 und 3 und rufe im Programm ja python 3 auf.
Was kann die Ursache sein?
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Im Programm rufst Du gar nichts auf. Wie rufst Du denn das Programm auf?

Code: Alles auswählen

python3 programm.py
oder

Code: Alles auswählen

./programm.py
?
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

Ich meinte damit:

#!/usr/bin/env python3

ich hatte mit Visual Studio getestet jetzt habe ich dirrekt mit python3 das Programm auf gerufen hier kommt dieser Fehler nicht
Zuletzt geändert von ruesch am Dienstag 26. Mai 2020, 09:29, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ruesch: Aus irgendwelchen Gründen scheinst Du das mit Python 2 auszuführen. Das solltest Du halt nicht machen. Die She-Bang-Zeile sollte Python 3 nehmen, was natürlich nur funktioniert wenn die auch verwendet wird.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__blackjack__
Es war mein Fehler ich verwende neu Visual Studio dort läst sich einstellen mit welchem Python das ausgeführt wird, dort war python2.7 eingestellt. Nach Umstellung auf python 3.7 kam keine Fehlermeldung mehr.
Da ich die Eingaben "temperaturgrenzwert, dauer in [(25, 2.5), (28, 3), (31, 3.5)" und die Ausgaben(Temperatur , Ablaufende Zeit) über eine Oberfläche eingeben/darstellen möchte, mit welchem Werkzeug könnte das für mich als Anfänger das leichteste sein (TK, QT oder Weboberfläche)?
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die GUI-Rahmenwerke nehmen sich da nicht viel. In jedem wirst Du die Funktion so nicht verwenden können sondern wirst das in eine objektorientierte Lösung umbauen müssen, wie __deets__ das ja schon beschrieben hat.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
ruesch
User
Beiträge: 9
Registriert: Sonntag 24. Mai 2020, 08:20

@__blackjack__
Ok, Danke
Antworten