FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: deinmedium am 16 August 2019, 08:35:55

Titel: Relais (Gpio) schaltet immer wieder.
Beitrag von: deinmedium am 16 August 2019, 08:35:55
Hallo,

meine Regelung vergleicht zwei Temperatursensoren und steuert damit einen Lüfter über PWM. Der Lüfter kann mit PWM nicht auf null (Stillstand) geregelt werden und deswegen habe ich ein Relais vorgeschaltet was über die GPIOs vom Raspi angesprochen wird. Das Script überprüft alle 30 sec. die Temperaturwerte und stellt den gewünschten Wert am Lüfter ein. Bei jeder Überprüfung geht das Relais aber einmal kurz aus und wieder an. klickklack  :o
Kann man das umgehen?

So sieht der Code aus:
#Lüfterautomatik alle 30sec Temperaturvergleich
define LuefterAnAus at +*00:00:30 {\
my $tempsolar = ReadingsVal("GPIO4_DS18B20_000004a6b7e1","temperature",0);;\
my $tempunten = ReadingsVal("GPIO4_DS18B20_000004a6882c","temperature",0);;\
my $tempabstufung = ReadingsVal("Empfindlichkeit","state",99);;\
if ($tempsolar - 0.1 * $tempabstufung > $tempunten) {fhem("set Luefter 0;;set SchalterL off")};;\
if ($tempsolar - 0.2 * $tempabstufung > $tempunten) {fhem("set Luefter 10;;set SchalterL on")};;\
if ($tempsolar - 0.3 * $tempabstufung > $tempunten) {fhem("set Luefter 20")};;\
if ($tempsolar - 0.4 * $tempabstufung > $tempunten) {fhem("set Luefter 30")};;\
if ($tempsolar - 0.5 * $tempabstufung > $tempunten) {fhem("set Luefter 40")};;\
if ($tempsolar - 0.6 * $tempabstufung > $tempunten) {fhem("set Luefter 50")};;\
if ($tempsolar - 0.7 * $tempabstufung > $tempunten) {fhem("set Luefter 60")};;\
if ($tempsolar - 0.8 * $tempabstufung > $tempunten) {fhem("set Luefter 70")};;\
if ($tempsolar - 0.9 * $tempabstufung > $tempunten) {fhem("set Luefter 80")};;\
if ($tempsolar - 1.0 * $tempabstufung > $tempunten) {fhem("set Luefter 100")}}
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: MadMax-FHEM am 16 August 2019, 08:57:01
Ja lässt sich umgehen, indem die Bedingungen sauber programmiert werden.

Wenn:

Irgendwas - was Größeres > irgendwas Anderes
(deine Zeile 2 mit Einschalten)

wahr ist, dann ist:

Irgendwas - was Kleineres > irgendwas Anderes
(deine Zeile 1 mit Ausschalten)

erst recht wahr...

Daher wird IMMER erst kurz aus und (evtl.) wieder eingeschalten...
...oder es wird gar nichts ausgeführt, weil das if mit off das ist, was am öftesten "trifft"...

Also noch mal genau überlegen wann wie geschalten werden soll und dann richtig programmieren...

EDIT: weil wenn deine letzte Zeile wahr ist, waren alle davor auch schon wahr und du schaltest die ganze Kette: also Lüfter aus, Lüfter auf 10 und ein, Lüfter auf 20, Lüfter auf 30, ..., Lüfter auf 100

Gruß, Joachim
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: Otto123 am 16 August 2019, 09:13:31
Moin,

wenn ich mir das Regelwerk so anschaue: Lässt sich das nicht einfach in einen Ausdruck mit Formel fassen?
Dann braucht man nur noch einmal set Luefter {Ergebnis der Berechnung} und kann sich diese if Schlange sparen..

Nur so als alternative Überlegung.

Gruß Otto
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: deinmedium am 16 August 2019, 12:02:32
Danke!

Ich habe bei Tipps berücksichtig und die ganzen if´s entfernt und mein gewünschtes ziel überdacht.
So sieht es jetzt aus:
#Variable für den Schwellwert
define Schwellwert dummy
attr Schwellwert fp_iPad 401,675,2,Schwellwert,
attr Schwellwert setList state:0,1,2,3,4,5,6,7,8,9,10,20,30,40
attr Schwellwert webCmd state

#Lüfterautomatik alle 10sec Temperaturvergleich
define LuefterAnAus at +*00:00:03 {\
my $tempsolar = ReadingsVal("GPIO4_DS18B20_000004a6b7e1","temperature",0);;\
my $tempunten = ReadingsVal("GPIO4_DS18B20_000004a6882c","temperature",0);;\
my $tempabstufung = ReadingsVal("Schwellwert","state",99);;\
my $tempmultiplikator = $tempsolar - $tempunten;;\
if ($tempsolar - $tempabstufung > $tempunten) {fhem("set Luefter " .$tempmultiplikator * 15 . ";; set SchalterL on")}\
else {fhem("set Luefter 0;; set SchalterL off")}}


Funktioniert auch fast gut. ;)

in der Berechnung: .$tempmultiplikator * 15 . ist ein theoretischer Wert über 100 möglich. Den kann ich aber nicht gebrauchen. Man kann doch bestimmt sagen, das man nur einen Maximalwert von 100 erreichen möchte, oder?

Wenn ja, wie geht das?

Ich sag schon mal danke.

Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: Byte09 am 16 August 2019, 12:09:21
$tempmultiplikator = 100 if $tempmultiplikator > 100;

gruss Byte09

edit rechne es vor der ifabfrage aus, schreibe es in eine seperate variable und prüfe diese wie oben geschrieben. geht auch im if aufruf direkt, bleibt aber übersichtlicher denke ich
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: frank am 16 August 2019, 12:12:49
.(($tempmultiplikator * 15)>99?100:$tempmultiplikator).
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: Byte09 am 16 August 2019, 12:13:41
Zitat von: frank am 16 August 2019, 12:12:49
.(($tempmultiplikator * 15)>99?100:$tempmultiplikator).

ja, oder so  :)
Titel: Antw:Relais (Gpio) schaltet immer wieder.
Beitrag von: deinmedium am 16 August 2019, 12:37:11
Ich habe es so gelöst.  ;)

#Variable für den Schwellwert
define Schwellwert dummy
attr Schwellwert fp_iPad 401,675,2,Schwellwert,
attr Schwellwert setList state:0,1,2,3,4,5,6,7,8,9,10,20,30,40
attr Schwellwert stateFormat {sprintf "%.0f°C", ReadingsVal($name, "state", 0)}
attr Schwellwert webCmd state

#Lüfterautomatik alle 10sec Temperaturvergleich
define LuefterAnAus at +*00:00:03 {\
my $tempsolar = ReadingsVal("GPIO4_DS18B20_000004a6b7e1","temperature",0);;\
my $tempunten = ReadingsVal("GPIO4_DS18B20_000004a6882c","temperature",0);;\
my $tempabstufung = ReadingsVal("Schwellwert","state",99);;\
my $tempmultiplikator = $tempsolar - $tempunten;;\
my $tempmultiplikator15 = $tempmultiplikator * 15;;\
if ($tempmultiplikator15 > 100) {$tempmultiplikator15 = 100};;\
if ($tempsolar - $tempabstufung > $tempunten) {fhem("set Luefter " .$tempmultiplikator15 . ";; set SchalterL on")}\
else {fhem("set Luefter 0;; set SchalterL off")}}


Vielen Dank!!!