Seite 2 von 2

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 10:34
von Zizibee
Melewo hat geschrieben:Ich denke eher das von DeaD_EyE.
Wo liegt der Unterschied zwischen den Programmen von DeaD_EyE und kbr? Machen die nicht das gleiche?

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 10:37
von Melewo
Zizibee hat geschrieben:
Melewo hat geschrieben:Wo liegt der Unterschied zwischen den Programmen von DeaD_EyE und kbr? Machen die nicht das gleiche?
Es wird nur die Temperatur verglichen, nicht ob die Heizung läuft oder nicht.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 10:54
von Melewo
Habe jetzt nicht alle Varianten durchgespielt, eigentlich nur eine probiert, doch so könnte ich mir das eher vom Prinzip vorstellen.

Code: Alles auswählen

class Hysterese:
    def __init__(self, temp_heizmatte_min, temp_heizmatte_max):
        self.state = False
        self.temp_heizmatte_min = temp_heizmatte_min
        self.temp_heizmatte_max = temp_heizmatte_max
        
    def update(self, temp_heizmatte, status):
        #          24               25
        if temp_heizmatte <= self.temp_heizmatte_min:
            self.state = True
            return self.state
        #          31               30
        elif temp_heizmatte >= self.temp_heizmatte_max:
            self.state = False
            return self.state
        #          25                   von 26 bis 29            30
        elif self.temp_heizmatte_min < temp_heizmatte < self.temp_heizmatte_max:
            if status is "on":
                self.state = True
            elif status is "off":
                self.state = False
            return self.state
 
status = "on"
# status = "off"
hyst = Hysterese(25, 30)
print(hyst.update(27, status)) # False bei 27 und "off" | # True bei 27 und "on"

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 11:07
von BlackJack
@Melewo: Die Heizung weiss ja selber ob sie läuft oder nicht beziehungsweise das ist `state`. Deins wird immer komplizierter — unnötig. Zumal Du jetzt auch noch mit globalen Variablen anfängst. Was genau funktioniert denn an kbr's letzter Lösung nicht?

Oh, und Deins hat einen Riesenfehler: ``is``. Das ist nicht das selbe wie ``==``.

Code: Alles auswählen

In [13]: a == b
Out[13]: True

In [14]: a is b
Out[14]: False

In [15]: a
Out[15]: 'böse Falle'

In [16]: b
Out[16]: 'böse Falle'

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 11:08
von kbr
@Melewo: Die Information, ob die Heizung laufen soll oder nicht, steckt in der Instance-Variablen 'state'. Der ursprüngliche, und von mir übernommene, Methoden-Name 'update' ist irreführend und sollte besser in etwas wie 'should_heat' umbenannt werden, was mit dem boolschen Rückgabewert sinnvoll in Beziehung gebracht werden kann.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 11:23
von Melewo
Genau ob sie laufen soll oder nicht, ist für mich auch in state, so sehe ich das auch. Doch ob sie gerade läuft oder nicht, ist doch nicht in state, sondern in der Datenbank als letzter Wert oder soll abgefragt werden und das sollte zwischen 26 und 29 berücksichtigt werden.
schneiderre hat geschrieben:Die Werte kommen aus einer DB.
Was kommt da sonst aus der DB?

Bei 27 Grad, Heizung läuft, dann laufe weiter.
Bei 27 Grad, Heizung läuft nicht, dann bleibe aus.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 11:48
von BlackJack
@Melewo: Aus der Datenbank kommen die Werte wann geschaltet werden sollte.

Noch mal: Ob sie gerade läuft weiss die Heizung selbst und das ist völlig egal, weil das zur Entscheidung nicht benötigt wird. Noch mal: Was an kbr's Lösung funktioniert denn Deiner Meinung nach nicht? Gib mal einen Beispielverlauf der nicht das macht was er soll!

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 12:01
von Zizibee
@ Melewo: Da "state" nicht vom Threadersteller sondern von DeaD_EyE eingeführt wurde, ist es wenig wahrscheinlich, dass sie in der ursprünglichen Datenbank auftaucht...

Mal eine Frage, die etwas OT ist:
Sehe ich das anhand der Beispiele richtig, das einfache get- und set- Methoden in Python nicht benutzt werden, da sie schlicht nicht gebraucht werden, da die Objektvariablen nicht privat sind?

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 12:02
von Melewo
Da ich nichts hier habe, um das im praktischen Einsatz nachvollziehen zu können, überlasse ich die praktischen Tests schneiderre.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 12:09
von BlackJack
@Melewo: Mehr als einen Rechner und Python brauchst Du nicht um das auszuprobieren. Der Zustand der Heizung ist immer der von `state`, denn nach `state` richtet sich ja der Pin für den Schalter — der hat immer den gleichen Wert, also reicht die Klasse alleine zum Testen völlig aus.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 12:54
von Melewo
Ja Ok, mein Denkfehler war jetzt, dass ich die Anwendung nicht als Dauerläufer betrachtet hatte.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 13:53
von Sr4l
Ich möchte hier auch nochmal meinen Senf dazugeben, auch wenn ich nicht weiß ob der TE mittlerweile aufgegeben hat :D .

Das was du machst nennt sich "Zweipunktregler" und ist absolut üblich bei allem was mit Temperatur zutun hat.

Ich habe zwei "Raspberry PI 1"s im Dauereinsatz. Der eine ist nach ~2Jahre Betrieb immer mal wieder ausgefallen, Übertakten von "Modest" auf "None", hat das Problem gelöst. Ein Netzteil ist mir in den 3 Jahren kaputt gegangen. Und der Andere hat diesen Sommer immer wieder mal ein Temperatur Schock bekommen, behoben durch bessere Luftzufuhr und Kühlkörper. Also es ist alles recht stabil, aber es passiert gelegentlich auch mal etwas.

Ich würde für alle Regelungsaufgaben einen Mikrocontroller einsetzen. Und wenn bei der ganzen Sache auch noch Strom im Spiel ist der mir die Bude abfackeln kann, einen zweiten der nur Überwacht und der sollte dann einen Alarm erzeugen können und z.B alles Stromlos schalten.

Das ganze sollte dann auch nicht nur theoretisch funktionieren sondern getestet werden.

PS: Ich hatte es schon häufiger das sich Schalter oder Relais "fest gebacken" haben und obwohl Stromlos oder Geschaltet nicht mehr gelöst haben. An so etwas sollte man denken, wenn man etwas unüberwacht arbeiten lässt.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 17:04
von DeaD_EyE
kbr hat geschrieben: Kompakt und richtig wäre:

Code: Alles auswählen

def update(self, temp_heizmatte):
    if temp_heizmatte <= self.temp_heizmatte_min:
        self.state = True
    elif temp_heizmatte >= self.temp_heizmatte_max:
        self.state = False
    return self.state
Das liebe ich so. Man nimmt bestehenden Code, verbessert ihn um am Ende kommt etwas elegantes bei raus.
Wenn keine der beiden Bedingungen erfüllt ist, wird einfach nur der letzte Status zurückgegeben, ohne die Variable vorher zu setzen.

Wenn eine der beiden Bedingungen erfüllt ist, wird die Variable gesetzt.
Ausgegeben wird der Status immer.

Re: Temperatursteuerung

Verfasst: Mittwoch 26. Juli 2017, 22:25
von BlackJack
@Zizibee: Triviale Getter und Setter machen ein Attribut ja letztlich public, auch wenn das eigentliche Attribut private wäre. Man benutzt diese Methoden in Python nicht weil man jederzeit `property()`\s aus den Attributen machen kann. Was zum Beispiel in Java nicht geht. Da müsste man dann jeden Zugriff ändern wenn man nicht über Accessor-Methoden gegangen ist. In Python ändert sich die API dagegen nicht durch so eine Änderung also sind triviale Getter/Setter einfach nur unnötige Schreibarbeit.

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 10:06
von Zizibee
@BlackJack: Ich habe mir jetzt durchgelesen was `property()` macht bzw. wozu man es benutzt. Das ist echt interessant und mir ist dadurch einiges klarer geworden. Danke mal wieder für die Info!

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 12:53
von BlackJack
@Zizibee: Mal als (leicht konstruiertes) Beispiel eine abstrakte Basisklasse welche die `update()`-Methode bereit stellt und eine Bereitstellung von Unter- und Obergrenze von abgeleiteten Klassen erwartet, und zwei Varianten dies zu tun in Java, wo man die Getter benötigt, und zum Vergleich in Python wo man direkt auf die Attribute zugreifen kann oder Properties zur Verfügung stellt:

Code: Alles auswählen

abstract public class AbstractHysteresis {

    private boolean state = false;

    abstract public double getLow();
    abstract public double getHigh();

    public boolean update(double value) {
        if (value <= getLow()) {
            state = true;
        } else if (value > getHigh()) {
            state = false;
        }
        return state;
    }
}

public class Hystersis extends AbstractHysteresis {

    private final double low;
    private final double high;

    public Hystersis(double low, double high) {
        this.low = low;
        this.high = high;
    }

    @Override
    public double getLow() {
        return low;
    }

    @Override
    public double getHigh() {
        return high;
    }
}

public class Hysteresis2 extends AbstractHysteresis {

    private final double value;
    private final double margin;

    public Hysteresis2(double value, double margin) {
        this.value = value;
        this.margin = margin;
    }

    @Override
    public double getLow() {
        return value - margin;
    }

    @Override
    public double getHigh() {
        return value + margin;
    }
}

Code: Alles auswählen

class BaseHysteresis(object):

    def __init__(self):
        self.state = False

    def update(self, value):
        if value <= self.low:
            self.state = True
        elif value > self.high:
            self.state = False
        return self.state


class Hysteresis(BaseHysteresis):

    def __init__(self, low, high):
        BaseHysteresis.__init__(self)
        self.low = low
        self.high = high


class Hysteresis2(BaseHysteresis):

    def __init__(self, value, margin):
        BaseHysteresis.__init__(self)
        self.value = value
        self.margin = margin

    @property
    def low(self):
        return self.value - self.margin
    
    @property
    def high(self):
        return self.value + self.margin

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 14:50
von Zizibee
Dazu hätte ich jetzt zwei Fragen:
Ist es ein Unterschied, ob man

Code: Alles auswählen

class BaseHysteresis(object):
oder

Code: Alles auswählen

class BaseHysteresis:
schreibt?
Warum ist welche Schreibweise vorzuziehen?

Ich habe mich auf python-kurs.eu über property() informiert und da wird das irgendwie anders benutzt. Sind die Zeilen 29 - 31 von der Arbeitsweise so ähnlich wie das hier

Code: Alles auswählen

def __get_low(self):
    return self.value - self.margin

low = property(__get_low)
nur etwas kürzer?

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 15:32
von BlackJack
@Zizibee: In Python 2 muss man von `object` erben damit unter anderem Properties richtig funktionieren, weil man ohne von `object` abzuleiten eine „old style class“ bekommt. In Python 3 gibt es nur noch „new style classes“.

Der verlinkte Kurs kennt auch private Attribute (die es in Python so nicht gibt) und missbraucht das „name mangling“ bei zwei führenden Unterstrichen dazu. Und verwendet auch nicht die Python-Namenskonvention. Das sieht alles sehr nach Java oder C++ aus. Und durch die trivialen Getter/Setter ist das Attribut de fakto dann doch öffentlich, also ist das insgesamt viel unnötige Schreibarbeit. Wenigstens das sagt der Kurs, aber erst nach dem dieser ganze unnötige Zirkus präsentiert wird.

Die Schreibweise als Decorator mit @ ist seit Python 2.4, also seit 2004 = 13 Jahren, möglich. Ich würde das auch nicht mehr anders schreiben wollen.

Decorator sind eigentlich nur syntaktischer Zucker. Das hier:

Code: Alles auswählen

@(some_expression)
def spam():
    pass
ist äquivalent zu dem hier:

Code: Alles auswählen

def spam():
   pass

spam = (some_expression)(spam)
Und es geht nicht unbedingt um kürzer sondern eher um die Reihenfolge in der man das liest. Wenn der Funktionskörper von `spam()` zig Zeilen lang ist, sieht man erst viel später das `spam` noch mal umdefiniert wird, während man mit der Decorator-Syntax gleich ganz am Anfang sieht, das mit der Funktion danach noch etwas gemacht wird und das Ergebnis davon wieder an den Namen `spam` gebunden wird.

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 19:37
von Zizibee
@BlackJack: Und wieder einmal vielen Dank für die Erklärung!
Dann werde ich mir wohl mal ein anderes Nachschlagewerk suchen müssen.

Re: Temperatursteuerung

Verfasst: Donnerstag 27. Juli 2017, 20:57
von schneiderre
Hallo @all, sorry das ich mich jetzt erst melde, hatte ziemlich viel um die Ohren. Erst einmal herzlichen Danke für eure Unterstützung und die rege Diskussion zu meiner Frage. Ich habe bis gestern Abend bis spät in die Nacht eure Vorschläge getestet. Zum Schluss hatte ich dann eine Kombination aus dem Vorschlag von Melewo und DeaD_EyE. Damit läuft es so wie ich es mir vorgestellt hatte. Vielen Dank dafür. Ich habe es heut den ganzen Tag laufen lassen und die Ergebnisse in ein Log schreiben lassen. Alles bestens. Auf euch ist eben verlass. Ich werde es jetzt noch ein wenig anpassen um die Ergebnisse in die DB zu bekommen und dann ist alles super.
Schönen Abend an @all