Idee für neues Modul RolloPos - Anregungen zur Umsetzung gesucht

Begonnen von C_Herrmann, 18 Februar 2014, 22:04:36

Vorheriges Thema - Nächstes Thema

C_Herrmann

Hallo,

bei der Überarbeitung des Moduls UNIRoll wollte ich eine erweiterte Steuerung einbauen, um die Rolloposition erfassen und steuern zu können. Da ich auch ein Rollo mit FS20rsu habe, kam mir die Idee, die Funktion in ein generisches Modul für alle Geräte - egal ob FS20, HM, UNIRoll, 1-wire oder sonstige - auszulagern.

Meine Gedanken dazu habe ich unten zusammengetragen. Der Programmablauf ist eigentlich simpel. Ich habe das ansatzweise mal mit einem Notify (s.u.) für ein Rollo nachgestellt.

Hier sind nun einige Fragen zur möglichen Umsetzung:

  • Hat jemand etwas ähnliches schon mal probiert?
  • Welches bestehende Modul kann ich als Vorlage benutzen?
  • Ist es möglich, Kommandos für ausgewählte Geräte abzufangen und auf das Modul umzuleiten? Ich könnte mir z.B vorstellen, dass es ein Attribut "geraeteKlasse" geben könnte. Wenn "geraeteKlasse = Rollo" ist, wird der Befehl auf das entsprechende Modul umgeleitet. Ein Notify reagiert ja nur auf bereits ausgeführte Befehle. Hiermit möchte ich aber ggf. die Fahrtdauer des Rollos beeinflussen. Sonst müssten dummy-Geräte für die zu steuernden Rollos verwendet werden. Das würde aber die fhem.cfg unnötig aufblähen.
  • Wie lassen sich die Zeitwerte in der Room-Ansicht bei den entsprechenden Geräten einfügen?
  • Sind meine Vorstellungen mit den bestehenden Möglichkeiten von fhem überhaupt umsetzbar?

---------------------------------------------------------------------------------------------------------
RolloPos - Modul zur Erfassung der Lage und Steuerung von Rollos

Voraussetzungen:

  • Fahrtdauer für jedes Rollo muss von Hand gemessen und in gerätespezifisches Attribut geschrieben werden.
  • Mögliche Befehle für "auf"/"ab" je Gerät (z.B. on = auf bei FS20rsu) in Varibalen schreiben. Dies kann durch einheitliche Verwendung von eventMap geschehen.

Modul:

  • Zeit für jede Fahrt auf/ab registrieren einschl. "on/off-for-timer x" bzw. "up/down x" bei UNIRoll.
  • Attribut für Position entsprechend der Fahrtdauer erhöhen/vermindern.
  • Ein explizites "auf"/"ab" setzt Attribut auf minimalen/maximalen Wert.
  • Ein "auf"/"ab" würde z.B. nach manueller Fahrt oder Fehler Rollo und Attribut in eindeutigen Zustand zurücksetzen.
  • Anfahren von jeder beliebigen Position auf jede andere Position.
  • Anzeige der Position im GUI als Zahlenwert.
  • Icons für Zwischenpositionen anzeigen. Ggf. "halboffen" für alle Zwischenpositionen. Ansonsten existieren icons bereits als shutter_x.png.

Probleme:

  • Manuelle Fahrten bleiben unberücksichtigt.
  • Speichern der Position beim Absturz/Neustart? Save nach jeder Änderung? Separate config-Datei?
  • Die Zeiten und der Öffnungsgrad sind nicht linear. Am Anfang der Abwärtsfahrt wird viel mehr Weg zurückgelegt als am Ende. Wenn die Unterkante des Rollo unten angekommen ist, benötigt es noch einige Zeit bis die Lamellen zusammengefahren sind. Eine Umrechnung könnte aber durch ein Array Sekunden - %Stellung erfolgen.

Variablen/Attribute pro Gerät:

  • rMin = 0 für auf, bei Bedarf größerer Wert
  • rMax = <Zeit in Sekunden> bis zum vollständigen Schließen
  • rPos = aktuelle Position in Sekunden
  • auf = auf-Befehle (on, on-for-timer, up, ...) müssen mit eventMap definiert sein
  • ab = ab-Befehle (off, off-for-timer, down, ...) müssen mit eventMap definiert sein
  • zPos = Zwischenpositionen (/ab20:5/ab50:12/ab80:20/ ...) ähnlich eventMap

Programmablauf:
Befehle abhören - wie ? - Notify?
  |
Ist es ein Rollo? -> nein -> tschüss
  |
ja
  |
Befehl mit Zeitwert? -> nein -> wenn auf-Befehl -> rPos = rMin, set Rollo auf
  |                         '-> wenn ab-Befehl  -> rPos = rMax, set Rollo ab
  |                         '-> wenn zPos-Befehl -> zPos = rPos -> return
  |                                             |-> zPos > rPos -> set Rollo ab (zPos - rPos), rPos = zPos
  |                                             '-> zPos < rPos -> set Rollo auf (rPos - zPos), rPos = zPos
  ja
  |
auf-Befehl -> Zeitwert > rPos -> rPos = rMin, set Rollo auf
          '-> Zeitwert <= rPos -> rPos = (rPos - Zeitwert), Original-Befehl ausführen
ab-Befehl  -> Zeitwert > (rMax - rPos) -> rPos = rMax, set Rollo ab
          '-> Zeitwert <= (rMax - rPos) -> rPos = (rPos + Zeitwert), Original-Befehl ausführen

---------------------------------------------------------------------------------------------------------

Notify:
uniroll_test.* {
  my $rPos = AttrVal("uniroll_test", "rPos", "0");
  my $rMin = AttrVal("uniroll_test", "rMin", "0");
  my $rMax = AttrVal("uniroll_test", "rMax", "0");
  my $ep0 = $EVTPART0;
  my @para1 = split(/ /, $EVENT);
  my $ep1 = $para1[1];

  if(!defined($ep1)) {
    if($ep0 eq "Ab") {
      fhem("set uniroll_test Ab");
      fhem("attr uniroll_test rPos $rMax");
    } elsif($ep0 eq "Auf") {
      fhem("set uniroll_test Auf");
      fhem("attr uniroll_test rPos $rMin");
    }
    return;
  }

  if($ep1 =~ m/^\d*\.?\d*$/) {
    if($ep0 eq "Ab") {
      $rPos = ($rPos + $ep1);
      if($rPos >= $rMax) {
        $rPos = $rMax;
        fhem("set uniroll_test Ab");
      } else {
        fhem("set uniroll_test Ab $ep1");
      }
    }
    if($ep0 eq "Auf") {
      $rPos = ($rPos - $ep1);
  if($rPos <= $rMin) {
        $rPos = $rMin;
        fhem("set uniroll_test Auf");
      } else {
        fhem("set uniroll_test Auf $ep1");
      }
    }
  fhem "attr uniroll_test rPos $rPos";
  fhem("setstate uniroll_test teil") if($rPos > $rMin && $rPos < $rMax);
  }
}


Definition UNIRoll in der fhem.cfg:
define uniroll_test UNIRoll 5432 6
attr uniroll_test IODev CUL1
attr uniroll_test eventMap /down 11:Ab80/down:Ab/up:Auf/stop:Stop/
attr uniroll_test model R_23700
attr uniroll_test rMax 35
attr uniroll_test rMin 0
attr uniroll_test rPos 0
attr uniroll_test sendStopBeforeCmd 0
attr uniroll_test webCmd Auf:Stop:Ab80:Ab



Da das UNIRoll-Modul aus dem SVN noch keine Zeitbefehle unterstützt, habe ich meine geänderte Version angehängt. Die Attribute rMax, rMin und rPos sind enthalten. Sonst müssen sie als userattr definiert werden.

Was haltet Ihr von der Idee?

Gruß,
Christian

Anhang:
10_UNIRoll.pm

FHEM auf RPi, CUL868, FHT, UNIRoll, verschiedene FS20 Komponenten, IT, Zigbee zum Testen

eldrik

Hi,

ich finde die Idee gut wenngleich ich wahrscheinlich nicht viel zur weiteren Umsetzung beitragen kann, ich habe folgende 1Wire Rollladenmodule mit denen ich höchstens testen könnte.

http://www.eservice-online.de/1-Wire-Bus/1-Wire-Fertigmodule/Digital-Ein-und-Ausgang-Analog-Eingang-Zaehler/1-Wire-Shutter-Rolladensteuerung.html

Die manuelle Bedienung über die Tastereingänge des Moduls kann leider vom Modul nicht erfasst werden.

Greetz
Eldrik


Tobias

Zitat von: eldrik am 19 Februar 2014, 11:20:35
Die manuelle Bedienung über die Tastereingänge des Moduls kann leider vom Modul nicht erfasst werden.
OT: deswegen habe ich mich gegen die 1wire Module und für die Homematic Module entschieden ;)
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

lukasbastelpeter

# Raspberry Pi
# Homematic, Z-Wave
# HUE, Tradfri
# Harmony
# ESP8266  Basteleien per MQTT

C_Herrmann

Hallo,

ich antworte mal hier auf beide Beiträge.

Ein universelles Modul wäre viel zu aufwändig zu programmieren gewesen. Die Zeitsteuerung ist dabei recht simpel, aber es hätte Schnittstellen in allen betroffen Modulen erfordert. Daher hatte ich die Steuerung zunächst als Notify ausprobiert und dann ins UniRoll-Modul eingebaut.

Es gibt keine Schnittstelle, mit der die Zeitsteuerung des UniRoll-Moduls von außen verwendet werden kann.

Das obenstehende Notify müsste eigentlich auch mit anderen Modulen funktionieren. Probiere es mal mit Deinem Modul aus.
FHEM auf RPi, CUL868, FHT, UNIRoll, verschiedene FS20 Komponenten, IT, Zigbee zum Testen

lukasbastelpeter

Mein Modul gibt es nicht ;)
Es ist ein Notify-Konstrukt:

Notify "überwacht" Dummy, wird dieser:
- up, setreading Rollodummy lastCmd up; set Rolloschalter.up on; sleep1; set Rolloschalter.up off
-down,  setreading Rollodummy lastCmd down; set Rolloschalter.down on; sleep1; set Rolloschalter.down off

-stop, If lastCmd=up: set Rolloschalter.down on; sleep1; set Rolloschalter.down off,  If lastCmd=down: set Rolloschalter.up on; sleep1; set Rolloschalter.up off


technisch steckt da ein Homematic Empfänger hinter, der die tasten der original Gurtwickler Fernbedienung drückt...
Die dadurch entstehende Latenz lasse ich bei den Überlegungen mal außen vor, sollte ja maximal +/- 1,5s ausmachen....

Mir fehlt hier völlig die zeitliche ebene...

Eine Überlegung wäre in einem reading nicht nur den lastCmd sonder auch in time_lastCmd den Timestamp des cmds zu speichern, und dann bei jedem neuen Befehl auszuwerten ob die oberste/unterste position schon erreicht sein müsste weil kein weiterer Befehl gefolgt ist,

oder aber bei "stop" die Differenz des timestamps des letzten comands und des timestamps des aktuellen als bewegungsänderung festzuhalten....

Aber all das hast du ja schon in dem UniRoll Modul gelöst oder?

Hast du vielleicht einen Tipp für mich wie/an welcher stelle/ ich entweder in deinem Modul "einfach" die Schnittstelle selber erstellen kann,

oder kannst du mir vielleicht den oben beschriebenen. Algorithmus mit allen Fallstricken die du da sicher schon ausgebügelt hast zur verfügung stellen?
# Raspberry Pi
# Homematic, Z-Wave
# HUE, Tradfri
# Harmony
# ESP8266  Basteleien per MQTT

C_Herrmann

Hallo,

ich fürchte, ich werde Dir bei Deinem Vorhaben kaum weiterhelfen können.

Die Idee mit einer Schnittstelle solltest Du begraben. Sie wäre nur nötig, um das UniRoll-Modul von außen zu steuern - nicht anders herum. Die Zeitsteuerung ist aber komplett in das Modul integriert. Du kannst natürlich gerne den Code aus dem Modul für eine eigene Entwicklung übernehmen. Ich habe alles damals mehr oder weniger ausführlich im Modul kommentiert. Für die Auf/Ab-Befehle habe ich die InternalTimer Funktion aus fhem.pl benutzt. Die Erkennung der tatsächlichen Position bei einem Stop wird aus der Differenz letzter Befehl/Zeitangabe und ReadingsTimestamp berechnet.

Ich würde Dir empfehlen, einen Ablaufplan - wie hier im Ausgangsbeitrag - für Deine Installation zu erstellen und daraus einen Notify oder eine Funktion unter Verwendung meines Codes zu programmieren. So habe ich es letztlich auch gemacht.

FHEM auf RPi, CUL868, FHT, UNIRoll, verschiedene FS20 Komponenten, IT, Zigbee zum Testen

viegener

Im SOMFY-Modul gibt es eine entsprechende Umsetzung, die die Position für Rolläden 0-100 zwischen auf und unten sowie 200 für ganz geschlossen umfasst. Die Timingwerte werden als Attribute eingestellt.

Über ein Empfängermodul per fhemduino funktioniert das auch bei paralleler manueller Bedienung. Also wenn Wandschalter für Auf/Ab/Halt verwendet werden.

Das sind die Module:
10_SOMFY und 14_FHEMduino_SomfyR

Allerdings ist die Implementierung nicht getrennt von der Steuerung, da es damals bereits Teile der Implementierung in 10_SOMFY gab. Ich bin mir nicht klar, wie man das herauslösen könnte. Allerdings wäre es gut, wenn man zumindest die Attribute und Readings vereinheitlichen würde

Ich kann sicher auch mehr im Detail erzählen was gemacht wurde,
Johannes
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können