Abbildung eines Stromstoßrelais

Begonnen von Oliver Vallant, 19 Februar 2017, 14:33:08

Vorheriges Thema - Nächstes Thema

Oliver Vallant

Hallo liebe Freunde der Hausautomatisierung,

für lange eingeschaltete und Lasten bei 2kW bietet sich ein 16A Stromstoßrelais an, sowie weil man dieses auch zur Not manuell im Verteilerschank schalten kann. Den Nachteil, dass das Relais mit einem Impuls ein- sowie ausgeschalten wird und FHEM damit den Zustand wechseln kann, aber den aktuellen Schaltzustand nicht kennt, habe ich durch ein zweikanaliges Finder Stromstroßrelais gelöst, sodass am ersten Kanal über einen Input der Zustand abgefragt wird und am zweiten Kanal die eigentliche Last geschalten wird.
Gesteuern/Ausgelesen wird über 1-wire und zweier DS2408. Dh. mit dem ersten DS2408 (Sensor) frage ich den Zustand des Relais mit sensed.0 ab und am zweiten DS2408 (Relais) sende ich einen Schaltimpuls auf PIO.0 zum Wechsel von on auf off und umgekehrt.

Und jetzt stehe ich an. Mit welchen Elemente (zB. readingsProxy, dummy) kann man jetzt die beiden Einzelkanäle elegant zu einem schaltbaren Element zusammenfassen.
Folgendes habe ich mittels eines readingsProxy versucht:
DEF Sensor:sensed.0
attr setFn {
my $cur = ReadingsVal("Sensor","sensed.0",0);
if ((($CMD eq "on") && ($cur == 1)) || (($CMD eq "off") && ($cur == 0))) {
  fhem("set Relais PIO.0 11");
  sleep 1 ;
  fhem("set Relais PIO.0 10"); }
}

..funktioniert aber leider nicht.

viegener

Zitat von: vallant am 19 Februar 2017, 14:33:08

..funktioniert aber leider nicht.

Kannst Du uns erhellen, was nicht funktioniert?


Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Oliver Vallant

Ich bekomme die Fehlermeldung:

"Unknown argument on, choose one of interval LCD_H/clear LCD_H/home LCD_H/message LCD_H/onoff LCD_H/screen LCD_H/screenyc LCD_M/clear LCD_M/home LCD_M/message LCD_M/onoff LCD_M/screen LCD_M/screenyc PIO.0 PIO.1 PIO.2 PIO.3 PIO.4 PIO.5 PIO.6 PIO.7 PIO.ALL PIO.BYTE latch.0 latch.1 latch.2 latch.3 latch.4 latch.5 latch.6 latch.7 latch.ALL latch.BYTE por set_alarm strobe"

Danke viegener für deine Unterstützung!

Es scheint das grundsätzliche Problem zu sein, dass der Steuerkanal eben nicht on oder off ist, sondern ständig off, bis auf die eine Sekunde on des Zustandswechsels. Gibt es ein verwendbares Element/Modul welches diese T-Flipflop-Charakteristik abbildet?  Im Ergebnis wäre ein Element, welches on:off verstehen würde optimal.

viegener

Annahme 1 - ich nehme an setList hast Du gesetzt? - Korrekt?

Generell müsste ja das Ergebnis Deiner setFn ein Ausdruck sein, der an das target device (also Sensor) weitergeleitet wird. Das passiert in Deiner setFn schonmal nicht. Dann wird wahrscheinlich der Originalwert weitergeleitet (Vermutung !).

Annahme 2: Du hast zwei 1-Wire devices einer heisst Sensor (gibt den Schlatzustand wieder) und einer heisst Rellais (mit dem wird das Relais geschaltet) - so entnehme ich das den verschiedenen Codes hier. - Korrekt ?

Weitere Annahme (3) - Du hast die Befehle set Relais PIO.0 11 etc ausprobiert und sie schalten das Relais? - Korrekt?

Anmerkung - Deinn Sleep hält das gesamte FHEm an (der ist blocking) und damit ein grundsätzliches Probelm

Problem 2 - Du musst in der setFn ja einen Befehl an Dein One-wire-Sensor-Device weitergeben, der braucht aber eigentlich gar keinen set-Befehl?

Was passiert denn wenn Du folgendes machst:

attr setFn {
my $cur = ReadingsVal("Sensor","sensed.0",0);
if ((($CMD eq "on") && ($cur == 1)) || (($CMD eq "off") && ($cur == 0))) {
  fhem("set Relais PIO.0 11; sleep 1; set Relais PIO.0 10");
}
}
return "interval 10"


Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Oliver Vallant

ad A1: setList = "on off"
ad A2/3: ja genau so
ad Anmerkung) Gibt es da eine Alternative? Ist die Funktion "on-for-time 1" blocking
ad P2) Würde der notwendige set-Befehl mit einem (Device-unabhängigen) Dummy-Element entfallen? Kann man sonst irgendwie geräteunabhängig ein on,sleep,off absetzen?
ad Code) Liefert leider die idente Meldung:
"Unknown argument on, choose one of interval LCD_H/clear LCD_H/home LCD_H/message LCD_H/onoff LCD_H/screen LCD_H/screenyc LCD_M/clear LCD_M/home LCD_M/message LCD_M/onoff LCD_M/screen LCD_M/screenyc PIO.0 PIO.1 PIO.2 PIO.3 PIO.4 PIO.5 PIO.6 PIO.7 PIO.ALL PIO.BYTE latch.0 latch.1 latch.2 latch.3 latch.4 latch.5 latch.6 latch.7 latch.ALL latch.BYTE por set_alarm strobe"

Thorsten Pferdekaemper

Hi,
mir ist das hier alles etwas kompliziert. Kann man denn nicht einfach das Device "Relais" zum Schalten nehmen und an das Device "Sensor" ein notify hängen, dass mit setreading ein neues Reading ins Device "Relais" setzt, das den tatsächlichen Schaltzustand anzeigt?
Also in etwa so:

define blabla notify Sensor:sensed.* setreading Relais schaltzustand $EVENT

Gruß,
  Thorsten
FUIP

viegener

Zitat von: vallant am 19 Februar 2017, 17:09:13
ad A1: setList = "on off"
ad A2/3: ja genau so
ad Anmerkung) Gibt es da eine Alternative? Ist die Funktion "on-for-time 1" blocking
ad P2) Würde der notwendige set-Befehl mit einem (Device-unabhängigen) Dummy-Element entfallen? Kann man sonst irgendwie geräteunabhängig ein on,sleep,off absetzen?
ad Code) Liefert leider die idente Meldung:
"Unknown argument on, choose one of interval LCD_H/clear LCD_H/home LCD_H/message LCD_H/onoff LCD_H/screen LCD_H/screenyc LCD_M/clear LCD_M/home LCD_M/message LCD_M/onoff LCD_M/screen LCD_M/screenyc PIO.0 PIO.1 PIO.2 PIO.3 PIO.4 PIO.5 PIO.6 PIO.7 PIO.ALL PIO.BYTE latch.0 latch.1 latch.2 latch.3 latch.4 latch.5 latch.6 latch.7 latch.ALL latch.BYTE por set_alarm strobe"

Irgendwas ist mit Deinen settings so nicht in Ordnung. Generell sollte der Ansatz so ja funktionieren, denn Dein Readingsproxy sollte ja korrekt den Schaltzustand wiedergeben und die Befehle sollten nur an das Relais durchgereicht werden.

kannst Du mal einen "list" von Deinem Readingsproxy machen und das Ergebnis in code tags hier posten.

Ausserdem wäre es vielleicht mal interessant zu schauen, ob da noch was anderes im log auftaucht, wenn die am Readingsproxy und an den anderen beiden Devices mal verbose auf 5 setzt.

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

viegener

Zitat von: Thorsten Pferdekaemper am 19 Februar 2017, 17:28:48
Hi,
mir ist das hier alles etwas kompliziert. Kann man denn nicht einfach das Device "Relais" zum Schalten nehmen und an das Device "Sensor" ein notify hängen, dass mit setreading ein neues Reading ins Device "Relais" setzt, das den tatsächlichen Schaltzustand anzeigt?
Also in etwa so:

define blabla notify Sensor:sensed.* setreading Relais schaltzustand $EVENT

Gruß,
  Thorsten

Das Problem ist ja nicht den Schaltzustand zu erkennen das erfolgt ja im Sensor, sondern dass Einschalten des Stroms heisst das Relais erst auf on und dann sofort wieder auf off zu setzen (also sozusagen einen Taster zu simulieren). Das ginge auch mit einem Befehl "on-for-timer" aber das eigentliche Problem ist ja, dass hier die setFn nicht richtig läuft..
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Thorsten Pferdekaemper

Ach so...
Ja dann dürfte das ursprüngliche Problem daran liegen, dass die setFn einen Rückgabewert haben muss, der ein erlaubtes "set"-Kommando ergibt.
Müsste es dann nicht in etwa so gehen (unter der Annahme, dass das readingsProxy zum Relais gehört):

attr setFn {
my $cur = ReadingsVal("Sensor","sensed.0",0);
if ((($CMD eq "on") && ($cur == 1)) || (($CMD eq "off") && ($cur == 0))) {
  fhem("set Relais PIO.0 11; sleep 1");
}
}
return "PIO.0 10";

...oder aber ein notify auf Relais.PIO.0 (wenn das geht), das ein at erzeugt, dass das Ding nach 1 Sekunde oder so wieder abschaltet.

Gruß,
   Thorsten
FUIP

viegener

@Thorsten: Ja so ähnlich, deshalb hatte ich den zweiten Ansatz gepostet, der am Ende:
return "interval 10" sendet.

Allerdings kommt danach immer noch "Unknown argument on... das passt nicht, denn es wird ja eigentlich kein "on" mehr weitergeleitet, deshalb hatte ich vermutet, dass etwas anderes gerade nicht passt
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Oliver Vallant

Hallo viegener,

Klammerfehler, das "return()" war bereits außerhalb des "}"-Blocks, ich bekomme jetzt: "new interval is equal to old interval.", dh das Kommando wird an das Device darunter durchgereicht. Habe jetzt eines gefunden - hoffentlich ohne Auswirkungen: por (power on reset) ist true bei Neustart und meldet sich dann bei einem full-bus-scan und sollte dann auf false gehen und bleiben. Weist du noch eine Lösung für das blocking beim sleep? Habe einfach den Impuls mal auf ein min reduziert auf 300ms, ist aber keine Lösung des Problems.

Gesamtlösung funktioniert jetzt wie folgt:

Erster DS2408 "Relais" für 12V Relais-Output:

Internals:
   DEF        29.D61909000000 1
   IODev      iBUS
   NAME       Relais
   STATE      sensed.0: 1  sensed.1: 1  sensed.2: 1  sensed.3: 1  sensed.4: 1  sensed.5: 1  sensed.6: 1  sensed.7: 1  alarm: 0
   TYPE       OWDevice
   Fhem:
     address    29.D61909000000
     alerting   1
     bus        bus.0
     interfaces state
     interval   1
Attributes:
   IODev      iBUS
   group      Relais
   model      DS2408
   polls      sensed.0,sensed.1,sensed.2,sensed.3,sensed.4,sensed.5,sensed.6,sensed.7


Zweiter DS2408 "Sensor" für Rückkanal am Stromstoßrelais:

Internals:
   DEF        29.B73009000000 1
   IODev      iBUS
   NAME       Sensor
   STATE      sensed.0: 1  sensed.1: 0  sensed.2: n/a  sensed.3: n/a  sensed.4: n/a  sensed.5: n/a  sensed.6: n/a  sensed.7: n/a  alarm: 0
   TYPE       OWDevice
   Fhem:
     address    29.B73009000000
     alerting   1
     bus        bus.0
     interfaces state
     interval   1
Attributes:
   IODev      iBUS
   group      Relais
   model      DS2408
   polls      latch.4,sensed.0,sensed.1


Device für das Stromstoßrelais am PIO.0:

Internals:
   DEF        Sensor:sensed.0
   DEVICE     Sensor
   NAME       Licht0
   READING    sensed.0
   STATE      on
   TYPE       readingsProxy
   Content:
     Sensor     1
Attributes:
   setFn      {
       my $cur = ReadingsVal("Sensor","sensed.0",0);
       if ((($CMD eq "on") && ($cur == 0)) || (($CMD eq "off") && ($cur == 1)) || ($CMD eq "toggle") ) {
           fhem("set Relais PIO.0 11");
           sleep 0.3 ;
           fhem("set Relais PIO.0 10");
      }
      return "por 0"
}
   setList    on off toggle
   valueFn    {($VALUE == 1)?"on":"off"}
   webCmd     on:off:toggle


Damit ist das SSRelais mit on, off und toggle bedienbar.
Will man es mit einem Taster an der Wand (ebenfalls am Sensor Kanal 4) toggeln fügt man folgendes hinzu:

Device für den Taster "White" am Kanal 4 des Sensor:
Das Gerät muss latch.4 abfragen und nicht sensed.4, da der Taster nur wenige ms am DS2408 durch das Drücken des Tasters das sensed.4 auf high gibt. Hierfür hat DalSemi das Alarming für die einzelnen Kanäle einführt und durch kurzes high-tasten geht latch.4 high und bleibt bis zum bewussten low-setzen (set senWhite reset) dort, dh. wenn das Stromstoßrelais fertig geschalten hat.


Internals:
   DEF        Sensor:latch.4
   DEVICE     Sensor
   NAME       senWhite
   NR         42
   NTFY_ORDER 50-senWhite
   READING    latch.4
   STATE      off
   TYPE       readingsProxy
Attributes:
   group      Sensors
   room       Büro
   setFn      { if ($CMD eq "reset") { "latch.4 10" } }
   setList    reset
   valueFn    {($VALUE == 0)?"off":"on"}
   webCmd     reset


Notify verbindet senWhite mit Licht0:
Wird der Taster gedrückt geht Sensor:latch.0 auf 1, löst das Notify aus, dieses toggelt das SSRelais und resetet das Sensor:latch.4 auf 0. Auch wenn viele Taster im Haus gleichzeitig gedrückt werden, wird damit kein Event "vergessen".

Internals:
   CFGFN
   DEF        senWhite.on set Licht0 toggle ; set senWhite reset
   NAME       onWhite
   REGEXP     senWhite.on
   TYPE       notify
Attributes:
   group      Sensors


Bleibt nur zu hoffen, dass meine 80 Stk. DS2408 (für Taster) im Haus vom darunter liegenden OWFS in unter 1sek ausgelesen werden können. Länger warten auf das Licht bei betreten eines Raumes wäre mau.

Danke nochmals viegener!

Oliver Vallant

@Thorsten:
readingProxy Licht0 hängt auf Sensor um den Status des Rückkanals abfragen zu können. Aber das return("PIO.0 10") ist die saubere Lösung statt por, da am Sensor der Steuerausgang bei Beschaltung als Eingang naturgemäß ohnedies 0 sein muss. Das mit "at" schaue ich mir genauer an, ob es etwas 300ms schalten kann. Das SSRelais nimmt etwa 90mA vom Bus wenn der Magnet anzieht, die Zeit ist demnach bei vielen Geräten schon relevant - ist aber die Lösung für das Blocking des sleep().

Thorsten Pferdekaemper

Hi,
das at kann wahrscheinlich nur minimal 1 Sekunde. Es gibt aber noch die Funktion InternalTimer, die Du vielleicht verwenden kannst. Die kann auch Millisekunden.
Gruß,
   Thorsten
FUIP

viegener

@vallant: Die Lösung beim sleep ist eigentlich ganz einfach, wie oben bereits im ersten Vorschlag:

Zitatfhem("set Relais PIO.0 11; sleep 1; set Relais PIO.0 10");

Wenn der sleep in einer FHEM-Befehlssequenz auftaucht, wird er das System nicht blockieren.
Dann ist es ein FHEM-Sleep und kein perl-sleep -> das findest Du auch in der commandref



Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Thorsten Pferdekaemper

...außerdem geht mit sleep auch 300ms:
Zitat
The unit is seconds, with millisecond accuracy, as you can specify decimal places.
Ich glaube, dass am Ende "return undef" das richtige wäre. Die setFn handelt ja schon alles ab und laut Commandref scheint mir das zu sagen "tue (ansonsten) nichts".
Gruß,
   Thorsten
FUIP