Relais (Gpio) schaltet immer wieder.

Begonnen von deinmedium, 16 August 2019, 08:35:55

Vorheriges Thema - Nächstes Thema

deinmedium

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")}}

MadMax-FHEM

#1
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
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Otto123

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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

deinmedium

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.


Byte09

#4
$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

frank

#5
.(($tempmultiplikator * 15)>99?100:$tempmultiplikator).
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

Byte09

Zitat von: frank am 16 August 2019, 12:12:49
.(($tempmultiplikator * 15)>99?100:$tempmultiplikator).

ja, oder so  :)

deinmedium

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!!!