FS20 Toggle Events auf On/Off umsetzen

Aus FhemWiki
Wechseln zu: Navigation, Suche
  • Situation: Ein Wandschalter (z.B. FS20S4A), der so belegt ist, dass jede Taste einen einzelnen Kanal schaltet.
  • Problem: Der Schalter senden toggle events aus, die zwar an einen Empfänger weitergeleitet werden können, allerdings kann man dann nicht

abfragen, ob der Empfänger (z.B. FS20ST) an oder aus ist.

  • Lösung: Das toggle event auf on oder off umsetzen:

Inhaltsverzeichnis

Version für direkte Kopplung von Sender und Aktor

Implementierung

Den folgenden code im Verzeichnis /FHEM in die Datei 99_myUtils.pm kopieren. (Falls es diese Datei noch nicht gibt: /FHEM/99_Utils.pm kopieren, Kopie in 99_myUtils.pm umbenennen und aus dieser Kopie alle vorhandenen Routinen löschen - aber die Definitionen vor dem ersten "sub" und die "1;" am Ende stehen lassen).

Ausserdem bedient sich Untoggle der neuen Funktionen Value() und OldValue(), die zu fhem 5.1 bereitgestellt wurden.

Danach fhem mit dem Befehl 'shutdown' beenden und dann NEU STARTEN.

Code

sub Untoggle($) {
 my ($obj) = @_;
 if (Value($obj) eq "toggle"){
   if (OldValue($obj) eq "off") {
     {fhem ("setstate ".$obj." on")}
   }
   else {
     {fhem ("setstate ".$obj." off")}
   }
 }
 else {
   {fhem "setstate ".$obj." ".Value($obj)}
 }  
}

Aufruf

define <name> notify <Sensor> {Untoggle("<Sensor>")}

Hinweise

  • Der <Sensor> muss sich anfangs einmal im state ON oder OFF befnden.
  • Die Änderung des Status nach toggle wird auf dem Webfrontend erst nach einem manuellen refresh (F5) sichtbar, sofern bei der Definition des fhemweb nicht der Parameter refresh angegeben ist, siehe [1]

Mögliche Probleme

Der obige Code eignet sich nur für direkte Kopplung von Sender und Aktor, das heißt der Sender steuert den Aktor direkt und FHEM „lauscht“ nur und protokolliert den Status, der sich aus dem toggle-Befehl ergibt. Sobald ein einziges Mal ein Fehler auftritt (das heißt nur entweder der Aktor oder FHEM empfangen den toggle-Befehl, der jeweils andere aber nicht), geht der synchrone Status dauerhaft verloren, das heißt ab nun schaltet bei einem von Aktor und FHEM empfangenen toggle-Befehl jeweils einer der beiden in den Status on und der andere in den Status off. Dieser asnchrone Zustand wird erst behoben, wenn derselbe Fehler (nur entweder der Aktor oder FHEM empfangen den toggle-Befehl, der jeweils andere aber nicht) ein zweites Mal auftritt.

Die Statusabfrage ist daher nicht besonders zuverlässig. Die Zuverlässigkeit kann durch eine Untoggle-Version für indirekte Kopplung verbessert werden.

Version für indirekte Kopplung von Sender und Aktor

Implementierung

Bei dieser Version triggert der Sender lediglich den Untoggle-Befehl, der seinerseits den Aktor auf on oder off schaltet. Zwar kann auch in dieser Version die Synchronizität zwischen Aktor und FHEM-Status verloren gehen (wenn zwar FHEM den Sender-Befehl empfängt, aber der Aktor beim Empfang des als Konsequenz von FHEM gesendeten Befehls gestört ist), aber dieser Fehler wird mit dem nächsten ungestörten Steuerbefehl sofort wieder behoben, weil FHEM ja stets den zu seinem Status passenden Befehl an den Aktor sendet.

Allerdings funktioniert bei indirekter Kopplung zur Zeit das Dimmen von FS20-Aktoren nicht. Als Workaround setzt der folgende Code FS20-Dimm-Befehle so um, dass zu einer definierten Zwischenhelligkeit umgeschaltet wird, deren Wert als dritter Parameter an die Funktion übergeben wird. (Die verwendete Heuristik funktioniert allerdings nicht immer; siehe Kommentar im Code.)

Der folgende Code muss wiederum im Verzeichnis /FHEM in die Datei 99_myUtils.pm kopiert werden.

Code

sub UntoggleNotify($;$;$)
{
  my ($sender, $actor, $dimvalue) = @_;

  if (Value($sender) eq "toggle")
  {
    if (Value($actor) eq "off") {fhem ("set ".$actor." on")}
    else {fhem ("set ".$actor." off")}
  }
  ## workaround for dimming currently not working with indirect pairing
  ## (http://culfw.de/commandref.html: "TODO/Known BUGS - FS20 dim commands should not repeat.")
  elsif (Value($sender) eq "dimup") {fhem ("set ".$actor." dim100%")}
  elsif (Value($sender) eq "dimdown") {fhem ("set ".$actor." ".$dimvalue)}
  elsif (Value($sender) eq "dimupdown")
  {
    if (Value($actor) eq $dimvalue) {fhem ("set ".$actor." dim100%")}
       ## Heuristic above doesn't work if lamp was dimmed, then switched off, then switched on, because state is "on", but the lamp is actually dimmed.
    else {fhem ("set ".$actor." ".$dimvalue)}
    sleep 1;
  }
  ## end of workaround
  else {fhem ("set ".$actor." ".Value($sender))}

  return;
}

Aufruf

define <name> notify <Sender> {UntoggleNotify("<Sender>","<Aktor>","<Dimm_Wert>")}

Beim Dimm-Wert ist zu beachten, dass „%“ als Variable interpretiert wird, so dass stattdessen „%%“ anzugeben ist.

Beispiel:

define Wohnzimmerlampe_PAIR notify Wohnzimmerlampe_SENDER {UntoggleNotify("Wohnzimmerlampe_SENDER","Wohnzimmerlampe","dim12%%")}
Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge