Rollladensteuerung: Alternativen zu DOIF

Begonnen von spi3845, 27 März 2017, 13:28:59

Vorheriges Thema - Nächstes Thema

Beta-User

#60
@spi: Danke für die Code-Analyse, die (alle berechtigten) Anmerkungen sind auf github verarbeitet.

winOpenShutterTester($$) ist tatsächlich im Moment rein ereignisorientiert und wird immer aufgerufen, wenn ein Rolladen hält oder ein Tür-/Fensterkontakt ein Ereignis meldet (tilted@github ist noch nicht getestet). Mit der Zeitsteuerung hat es (noch) nichts zu tun (das macht bei mir noch je Gruppe ein DOIF, deren Parametrierung ich nicht verstehe und die ich daher loswerden will), das wäre dann aber nach meiner bisherigen Idee einfach ein weiterer Aufrufparameter (vielleicht mit dem von einem Timer mitgelieferten Ziellevel, bei dem dann geprüft wird, ob das so "durchgewunken" werden kann oder ein neuer onHoldLevel-Wert geschriebenen wird und der zulässige max-Wert angefahren?).

Erkenntnisse noch:
- setreading (und wohl auch setstate) kann man verwenden, um Werte in den userattr zu setzen. Dann hat man nicht mehr das Problem, dass es als Änderung mit einem roten Fragezeichen interpretiert wird. (EDIT: Danke an Thorsten Pferdekaemper, der darauf schon vor einiger Zeit hier hingewiesen hat.) Das sollte das Setzten der Parameter über readingsgroup deutlich vereinfachen (?).
- Man kann ja auch .5-er Level ansteuern (also 87.5). Da man das über die Oberfläche in der Regel nicht macht und sich solche Zwischenwerte auch nicht bei manuellem Schalten am Taster zu ergeben scheinen, könnte man darüber unterscheiden, ob es sich um einen automatischen Wert handelt (erstmal nur als Merkposten). 

Das mit der userattr-Werteinitialisierung hat sich nach code-Analyse erledigt, nehme ich an? (sonst müßte man auf den HM-Maintainer zugehen, oder? ;))

@Hugo: Danke für dieses wundervollen Codebeispiel! Hat mich sehr ermutigt, das endlich mal anzugehen :).
 
Zu dem Jalousie-Thema:
Zum Drehen nach dem Hochfahren muß man wieder nach unten. Damit wäre man dann wieder unterhalb des Mindestlevels, also: Spiel von vorne => geht so nicht. Ansatz dazu wäre, den weiteren Parameter gleich dazu zu nutzen, erst einen Ticken in Höhe des Parameters zu weit nach oben zu fahren und dann erst wieder (automatisch wegen "stop" ;)) auf den eigentlichen Ziellevel. Dann muß man nur verhindern, dass der onHoldLevel gelöscht wird. Andere Ideen oder Anregungen?

Zu "motor:down" und "set_xx":
motor:down sollte sowohl bei manueller Steuerung über einen Taster wie auch bei FHEM-Kommandos kommen, set_xx nur, wenn FHEM-seitig angestoßen. Wenn wir auch FHEM-seitige Kommandos modifizieren, bleibt die Zwangsöffnung unabhängig von der Zeitsteuerung und man kann nichts falsch machen, wenn man andere als "unsere" Bausteine zur Steuerung verwendet. Daher halte ich es für gut, das gleich auch noch mit abzufangen. Nachvollziehbar oder zu sehr um's Eck gedacht?

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Joker

Zitat von: spi3845 am 06 April 2017, 00:48:28
Damit die auf github liegende "99_myShutter.pm" in fhem unter "Edit files" angezeigt wird, muss sie "99_myShutterUtils.pm" heißen. Alles was auf Utils endet, wird angezeigt... Die initialize-Funktion muss "myShutterUtils_Initialize($$)" heißen (und damit dem Dateinamen entsprechen).
Kurze Anmerkung dazu: Dass sie auf Utils enden muss stimmt so nicht, scheinbar muss Utils irgendwo im Namen vorkommen (weiß es aber auch nicht näher). Meine Dateien heißen z.B. 99_myUtilsWindows, 99_myUtilsBlinds etc. und die werden auch unter "Edit files" angezeigt.

spi3845

Zitat von: Beta-User am 06 April 2017, 07:45:11
winOpenShutterTester($$) ist tatsächlich im Moment rein ereignisorientiert und wird immer aufgerufen, wenn ein Rolladen hält oder ein Tür-/Fensterkontakt ein Ereignis meldet (tilted@github ist noch nicht getestet). Mit der Zeitsteuerung hat es (noch) nichts zu tun (das macht bei mir noch je Gruppe ein DOIF, deren Parametrierung ich nicht verstehe und die ich daher loswerden will), das wäre dann aber nach meiner bisherigen Idee einfach ein weiterer Aufrufparameter (vielleicht mit dem von einem Timer mitgelieferten Ziellevel, bei dem dann geprüft wird, ob das so "durchgewunken" werden kann oder ein neuer onHoldLevel-Wert geschriebenen wird und der zulässige max-Wert angefahren?).
Klar, macht Sinn. Willst Du dann das Anfahren der unterschiedlichen Positionen aber nur im Zeitfenster durchführen, wenn die Rollläden per Timer runtergefahren wurden oder auch zu anderen Zeiten (z.B. Rollladen wurde tagsüber komplett runtergefahren und es macht jemand ein Fenster auf --> Rollladen fährt in Lüften-Position)?

Zitat von: Beta-User am 06 April 2017, 07:45:11
Das mit der userattr-Werteinitialisierung hat sich nach code-Analyse erledigt, nehme ich an? (sonst müßte man auf den HM-Maintainer zugehen, oder? ;))
Symbolischer Haken dran...

Zitat von: Beta-User am 06 April 2017, 07:45:11
Zum Drehen nach dem Hochfahren muß man wieder nach unten. Damit wäre man dann wieder unterhalb des Mindestlevels, also: Spiel von vorne => geht so nicht. Ansatz dazu wäre, den weiteren Parameter gleich dazu zu nutzen, erst einen Ticken in Höhe des Parameters zu weit nach oben zu fahren und dann erst wieder (automatisch wegen "stop" ;)) auf den eigentlichen Ziellevel. Dann muß man nur verhindern, dass der onHoldLevel gelöscht wird. Andere Ideen oder Anregungen?
Klingt gut. Etwas höher fahren, dann x Sekunden nach unten, dann erst onHoldLevel ändern.
Oder Jalousie höher fahren, x Sekunden nach unten und weitere Ausführung des Skripts innerhalb von z.B. 3 Sekunden verhindern - damit würde man auch Stottern der Jalousien/Rollläden vermeiden.

Zitat von: Beta-User am 06 April 2017, 07:45:11
Zu "motor:down" und "set_xx":
motor:down sollte sowohl bei manueller Steuerung über einen Taster wie auch bei FHEM-Kommandos kommen, set_xx nur, wenn FHEM-seitig angestoßen. Wenn wir auch FHEM-seitige Kommandos modifizieren, bleibt die Zwangsöffnung unabhängig von der Zeitsteuerung und man kann nichts falsch machen, wenn man andere als "unsere" Bausteine zur Steuerung verwendet. Daher halte ich es für gut, das gleich auch noch mit abzufangen. Nachvollziehbar oder zu sehr um's Eck gedacht?
Ganz klar Bahnhof  ;). Ich versuche mal zu interpretieren:
Zitatset_xx nur, wenn FHEM-seitig angestoßen
Ja, wenn ich auf den Taster direkt drücke, sehe ich beim Aktor kein set_xx
ZitatWenn wir auch FHEM-seitige Kommandos modifizieren
Hm, was meinst Du mit modifizieren?

Warum wollen wir die Bewegung erkennen? Um während der Abwärts-Bewegung eines Rollladens diesen beim Öffnen einer Tür oder eines Fensters anzuhalten? Also Einklemm- und Aussperrschutz? Wäre es dann nicht egal, ob der Rollladen von fhem oder per Taster abwärts gefahren wird? Ich denke da an spielende Kinder, der eine drückt auf den Taster und der andere macht das Fenster auf und hängt den Rüssel raus  ???

Benni

Zitat von: Joker am 06 April 2017, 15:31:34
Kurze Anmerkung dazu: Dass sie auf Utils enden muss stimmt so nicht, scheinbar muss Utils irgendwo im Namen vorkommen (weiß es aber auch nicht näher). Meine Dateien heißen z.B. 99_myUtilsWindows, 99_myUtilsBlinds etc. und die werden auch unter "Edit files" angezeigt.

Noch eine kurze Anmerkung dazu: Das ganze kann man sogar (mit ein paar Einschränkungen) über das FHEMWEB-Attribut editFileList anpassen. Ansonsten entspricht das zuvor genannte Verhalten aber der Voreinstellung.

Beta-User

#64
Zu dem notify: m.E. sollte das immer und zu jeder Uhrzeit reagieren.
Wer das nicht möchte (z.B. keine automatische Rolladenfahrt in der Nacht), müßte die notif...s ( ::)) halt in dem Zeitraum per attr auf disable-for-... setzen. Ich finde es aber logischer, wenn der Rolladen wirklich immer "auf Linie" gezwungen wird, also auch in dem von Dir genannten Beispiel des manuellen Schließens mit anschließender Fensteröffnung.

Die Jalousiedrehung würde ich nicht blockierend gestalten (geht das überhaupt?), sondern durch einen erneuten Durchlauf des scripts (das ja durch den Zwischen-stop sowieso getriggert wird ;)). Das muß dann nur merken, dass der erreichte stop-Level genau dem "Mach-ein-Wendemanöver"-Level entspricht. Konzept dazu: ein numerisches Jalousie-Attribut kann gesetzt werden (Beispiel: "3"), der Rolladen soll beim ersten Durchlauf auf {WindowContactOpenMaxClosed-3.5} geschickt werden. Stoppt er dann auf genau diesem Wert, darf er wieder auf WindowContactOnHoldState zurück (neuer Fall für das perl-script, nur dass in diesem Fall die onHoldPosition nicht gelöscht werden soll). Durch den Zwischenziellevel (-3.5 statt -3) ist es praktisch ausgeschlossen, dass jemand mittels Taster oder FHEMWEB die Jalousie dahin geschickt hat ;).

Zitat von: spi3845 am 06 April 2017, 15:34:47
Ganz klar Bahnhof  ;). Ich versuche mal zu interpretieren: Ja, wenn ich auf den Taster direkt drücke, sehe ich beim Aktor kein set_xx Hm, was meinst Du mit modifizieren?
Warum wollen wir die Bewegung erkennen? Um während der Abwärts-Bewegung eines Rollladens diesen beim Öffnen einer Tür oder eines Fensters anzuhalten? Also Einklemm- und Aussperrschutz? Wäre es dann nicht egal, ob der Rollladen von fhem oder per Taster abwärts gefahren wird? Ich denke da an spielende Kinder, der eine drückt auf den Taster und der andere macht das Fenster auf und hängt den Rüssel raus  ???
Erklärungsversuch:
Gibt jemand irgendwie das Kommando, dass der Rolladen nach unten soll, soll er an der "richtigen" Stelle anhalten, ist das Fenster offen, also an der offen-Position, aber eben nur wenn diese unterhalb des Ziellevels liegt (oder dieses nicht angegeben wurde=Taster). Allerdings könnte es sein, dass wir z.B. durch unsere zeitgesteuerte Automatikfunktion ja wollen, dass das Fenster am Ende (irgendwann, ausgelöst durch Schließen des Fensters) dann weiterfährt. Dann muß einfach der Ziellevel des trigger-Ereignisses als neue onHoldPosition gesetzt werden...
Die Modifikation des triggernden "motor:down" würde also aus einem "set 20" ein "set 60" machen (bei WindowContactOpenMaxClosed=60) und die onHoldPosition auf 20 setzen.
Jetzt nachvollziehbar?
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

spi3845

#65
Zitat von: Beta-User am 05 April 2017, 17:45:08
Einen (ungetesteten) update der Bausteine habe ich übrigens auf github liegen, da gäbe es dann auch den "Tilted"-Level (wenn es klappt ;)).
Hallo Beta-User,

habe deinen Code mit Dummies nachgebildet und noch folgendes gefunden:

WindowContactOnHoldState muss initial auf none gesetzt werden, sonst fahren die Rollläden bei "Tür zu" immer in Position 100 (also offen).

In der Funktion winOpenShutterTester($$)muss meiner Meinung nach die Zeile
elsif ($event eq "Window" && $winState eq "closed" && $maxPosition ne "none") {
ersetzt werden durch
elsif ($event eq "Window" && $winState eq "closed" && $onHoldState ne "none") {
Ansonsten wird die alte (gemerkte) Position in WindowContactOnHoldState nicht angefahren nach dem Schließen der Tür.

Der Aufruf fhem("setreading $shutter:WindowContactOnHoldState none"); schreibt ein Reading, die Funktion winShutterAssociate($$$$) erstellt aber Attribute (zum Doppelpunkt siehe weiter unten). winOpenShutterTester($$) liest auch Attribute, z.B.
my $onHoldState = AttrVal($shutter,'WindowContactOnHoldState',"none");
Das kollidiert, damit funktionieren die if-Abfragen in winOpenShutterTester($$) nicht, z.B.
if($onHoldState eq "none") { fhem("setreading $shutter:WindowContactOnHoldState $position");}
da die Abfrage auf ein Attribut testet, aber ein reading schreibt... D.h.
my $onHoldState = AttrVal($shutter,'WindowContactOnHoldState',"none");
sollte geändert werden in
my $onHoldState = ReadingsVal($shutter,'WindowContactOnHoldState',"none");

Dann sind noch die Doppelpunkte aus allen setreading Befehlen zu entfernen, statt
fhem("setreading $shutter:WindowContactOnHoldState none");
sollte geschrieben werden
fhem("setreading $shutter WindowContactOnHoldState none");

Hoffe, die Änderungen machen Sinn... Meinen Dummies hat's gefallen  ;)

Eine Frage:
Ich finde Attribute insofern geschickt, als sich diese einfach über die Weboberfläche setzen lassen. Readings nicht, da muss man immer einen Befehl absetzen. Der Vorteil von Readings ist, dass nicht das Fragezeichen neben "Save config" auftaucht. Kann man die Vorteile irgendwie kombinieren? Also einfach editieren ohne das Fragezeichen zu bekommen?

Grüße,
spi

Nachtrag: Es würde reichen, nur WindowContactOnHoldState als Reading zu speichern, da das der einzige Parameter ist, der von dem Skript winOpenShutterTester($$) geschrieben wird. Damit verhindert man das Fragezeichen neben "Save config". Die anderen Parameter kann man als Attribute lassen, damit kann man sie leicht über die Weboberfläche editieren...

spi3845

Zitat von: Beta-User am 06 April 2017, 16:33:04
Die Jalousiedrehung würde ich nicht blockierend gestalten (geht das überhaupt?)
Bestimmt  :) Rudimentär würde mir ein locked Attribut einfallen (nennt man das Semaphore?), das dann von einem at nach z.B. 3 Sekunden wieder gelöscht würde. Solange es gesetzt ist, würde das Skript sich gleich wieder beenden (oder irgend etwas anderes tun). Das würde in etwa dem entsprechen, 3 Sekunden lang nicht auf Ereignisse motor:stop|up|down zu reagieren (vielleicht kann man auch das anders erreichen). Das Skript wird hier nicht blockiert, reagiert einfach nur auf bestimmte Ereignisse nicht.

Zitat von: Beta-User am 06 April 2017, 16:33:04
Konzept dazu: ein numerisches Jalousie-Attribut kann gesetzt werden (Beispiel: "3"), der Rolladen soll beim ersten Durchlauf auf {WindowContactOpenMaxClosed-3.5} geschickt werden. Stoppt er dann auf genau diesem Wert, darf er wieder auf WindowContactOnHoldState zurück (neuer Fall für das perl-script, nur dass in diesem Fall die onHoldPosition nicht gelöscht werden soll). Durch den Zwischenziellevel (-3.5 statt -3) ist es praktisch ausgeschlossen, dass jemand mittels Taster oder FHEMWEB die Jalousie dahin geschickt hat ;).
Können alle Aktoren Rollläden/Jalousien auf x.5 Werte fahren?

Zitat von: Beta-User am 06 April 2017, 16:33:04
Erklärungsversuch:
Gibt jemand irgendwie das Kommando, dass der Rolladen nach unten soll, soll er an der "richtigen" Stelle anhalten, ist das Fenster offen, also an der offen-Position, aber eben nur wenn diese unterhalb des Ziellevels liegt (oder dieses nicht angegeben wurde=Taster). Allerdings könnte es sein, dass wir z.B. durch unsere zeitgesteuerte Automatikfunktion ja wollen, dass das Fenster am Ende (irgendwann, ausgelöst durch Schließen des Fensters) dann weiterfährt. Dann muß einfach der Ziellevel des trigger-Ereignisses als neue onHoldPosition gesetzt werden...
Die Modifikation des triggernden "motor:down" würde also aus einem "set 20" ein "set 60" machen (bei WindowContactOpenMaxClosed=60) und die onHoldPosition auf 20 setzen.
Jetzt nachvollziehbar?
Hoffentlich verstanden  ???. Das ist dann eine Art Übersteuern des Zielwerts beim Schließen der Rollläden und Öffnen des Fensters. Also so?

  • Rollläden per Timer noch offen
  • Jemand gibt das Kommando, Rollladen auf Position 20 zu fahren
  • Das Fenster wird während der Fahrt geöffnet, Rollladen fährt auf Position 60
  • Fenster wird geschlossen, Rollladen fährt auf Position 20
  • Timer schlägt zu und schließt Rolladen (Position 0)
  • Sollte der Timer zum Schließen der Rollläden zuschlagen, bevor Fenster geschlossen wird (Timer schlägt zu nach dem Schritt 3), würde der Rolladen erst einmal verharren und nicht weiterfahren. Beim Schließen des Fensters fährt er dann zu (Position 0)

Gute Nacht,
spi

Beta-User

#67
Zitat von: spi3845 am 09 April 2017, 00:42:11
Hoffe, die Änderungen machen Sinn... Meinen Dummies hat's gefallen  ;)
...definitiv, Danke für die Code-Analyse! Ich hoffe, mein perl-Verständnis, wird irgendwann besser ::).

Deinen Input und meine zwischenzeitlichen Erkenntnisse sollten in der aktuellen Github-Version soweit verarbeitet sein, dass man das als ganz frühe Beta bezeichnen könnte. Dabei habe ich auch min einen Attribut-Namen teilweise angepasst, das war nicht ganz stimmig.

Die jetzige Version sollte
- beide Level (open/tilted) ansteuern und dabei den onHold-Wert nicht zu sehr durcheinanderbringen (noch nicht ausgiebig getestet, will meine Familie jetzt nicht wecken ::))
- mit Jalousien umgehen können (getestet nur mit open, da aber der code sonst gleich ist, müßte auch tilted passen ;)
- per Automatik immer die Zwischenlevel anfahren (.5), (Aunahme: onHold-State soll angefahren werden). Ich gehe davon aus, dass das alle HM-Aktoren können, für andere Typen wären das zwei kleine Code-Eingriffe...

Was wirklich verwirrend ist, ist das mit ReadingsVal und AttrVal, es scheint aber jetzt so zu funktionieren. Ein paar Mal hatte ich den Effekt, dass die Jalousie ganz nach oben gefahren war, jetzt habe ich die Vermutung, dass das damit zusammenhing, dass das Reading noch nicht gefüllt war. Die Initialisierungsfunktion ist entsprechend angepasst, hoffe das geht jetzt so.

Zu den Jalousien: Der Code ist non-Blocking und triggert sich implizit selbst. Ich fand das charmanter, als irgendwo noch eine Info zwischenzuspeichern oder auf irgendwas zu warten (wie lange?), aber wer bessere Konzepte hat: her damit!

Weitere Neuerungen:
Es gibt eine weitere Sub, um die Jalousie-Eigenschaft festlegen zu können.

Dann habe ich noch eine Readingsgroup gebastelt, mit der man die Maximallevel einfach einstellen kann; ist noch nicht hübsch, aber geht...:
defmod rg_Rolladen_Auto_Oeffnen readingsGroup <Gerät>,<Offen-Pos.>,<Gekippt-Pos.>,<Jalousie>,<On-Hold> (Rolladen_.*|Jalousie_.*)..:level,?WindowContactOpenMaxClosed,?WindowContactTiltedMaxClosed,?JalousieTurnLevel,?WindowContactOnHoldState,
attr rg_Rolladen_Auto_Oeffnen commands { 'WindowContactOpenMaxClosed' => 'WindowContactOpenMaxClosed:10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100','WindowContactTiltedMaxClosed' => 'WindowContactTiltedMaxClosed:10,20,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100',}


Zitat von: spi3845 am 09 April 2017, 01:10:06
Hoffentlich verstanden  ???. Das ist dann eine Art Übersteuern des Zielwerts beim Schließen der Rollläden und Öffnen des Fensters. Also so?
Ganz genau. Das wird dann aber wieder eine größerer Aufwand werden (jedenfalls mit meinen bescheidenen Kenntnissen), mal schauen, ob ich da heute Mittag auf der Terrasse ein paar Eingebungen habe ;). Ideen: wie immer willkommen...

Solche Text-Übungen, wie ein "set_off" zu trennen und dann aus "off" ein "0" zu machen, sind sicher nicht schwer. Wenn jemand dazu bereits fertigen code hat, den ich mir erst mühsam erarbeiten muß: Gerne her damit!

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Beta-User

Beim Testen war leider der Teil mit tilted und Zwischenständen noch nicht ganz so in der Reaktion wie erhofft, neueste Version auf github sollte das jetzt besser können...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

spi3845

Zitat von: Beta-User am 09 April 2017, 11:49:44
Beim Testen war leider der Teil mit tilted und Zwischenständen noch nicht ganz so in der Reaktion wie erhofft, neueste Version auf github sollte das jetzt besser können...
Morgähn,
was hat bei Dir nicht funktioniert? Nach den von mir vorgeschlagenen Änderungen lief tilteld/open mit den Dummies ohne erkennbare Probleme.

Ich hatte mir noch Gedanken zu einer Timersteuerung gemacht. Das wäre eine weitere Abfrage in dem Skript - statt Window oder Rollo z.B. Timer. Wenn der Timer zuschlägt und onHold ist != none, dann müsste onHold auf 0 gesetzt werden. Korrekt?

Grüße,
spi

Beta-User

Er hat die Position nicht sauber angefahren, wenn der onHold-Wert zwischen open und tilted lag (beim Wechsel von open nach tilted).

Da ich zwischenzeitlich den Code auch im Hinblick auf Jalousien umgebaut hatte, waren Deine Anmerkungen nicht mehr 1:1 umsetzbar. Da war vermutlich mit der Jalousiefunktion ein Logikfehler reingekommen. Für Jalousien muß man ein weiteres Attribut setzen (lassen), das dann angibt, um wieviel zuerst zu weit nach oben gefahren werden soll (bei mir scheint 3 ein guter Wert zu sein).

Bastle grade noch an "motor:down", wird noch ein Weilchen dauern, aber die erste Vorverarbeitung der erforderlichen Werte sollte demnächst fertig sein. Das Einbauen in die Gesamtstruktur wird dann der spannende Teil 8).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Cluni

Zitat von: Beta-User am 09 April 2017, 07:46:17
Solche Text-Übungen, wie ein "set_off" zu trennen und dann aus "off" ein "0" zu machen, sind sicher nicht schwer. Wenn jemand dazu bereits fertigen code hat, den ich mir erst mühsam erarbeiten muß: Gerne her damit!

Mojn!

Ich habe zwar keinen fertigen Code dafür, aber du müsstest relativ einfach Teile vom String ersetzen können. Hab mal gegoogelt:

my $str = "The black cat climbed the green tree";
my $z = substr $str, 14, 7, "jumped from";
say $z;                                                     # climbed
say $str;                  # The black cat jumped from the green tree



Gesendet von iPhone mit Tapatalk

spi3845

#72
Zitat von: Beta-User am 09 April 2017, 12:54:40
Er hat die Position nicht sauber angefahren, wenn der onHold-Wert zwischen open und tilted lag (beim Wechsel von open nach tilted).

Da ich zwischenzeitlich den Code auch im Hinblick auf Jalousien umgebaut hatte, waren Deine Anmerkungen nicht mehr 1:1 umsetzbar. Da war vermutlich mit der Jalousiefunktion ein Logikfehler reingekommen. Für Jalousien muß man ein weiteres Attribut setzen (lassen), das dann angibt, um wieviel zuerst zu weit nach oben gefahren werden soll (bei mir scheint 3 ein guter Wert zu sein).

Bastle grade noch an "motor:down", wird noch ein Weilchen dauern, aber die erste Vorverarbeitung der erforderlichen Werte sollte demnächst fertig sein. Das Einbauen in die Gesamtstruktur wird dann der spannende Teil 8).
Jalousie kann ich in Ermangelung an Hardware nicht testen. Habe den Code an Rollläden getestet und habe dazu zwei Fragen:

Es gibt folgende Abfrage in winOpenShutterTester
elsif ($event eq "Rollo")
Dieser Codeblock reagiert auf das notify n_Rolladen_Stop.

Der erste Block (für das notify n_Rolladen_Window) wird nicht von einem
if ($event eq "Window")
eingeleitet. In dem letzten elsif vor dem Rollo-Block findet sich eine Abfrage nach dem event "Window". Das ist im Moment nicht schlimm, könnte aber zu Seiteneffekten führen, sollten noch weitere Ereignisse hinzukommen (z.B. Timer). Oder sehe ich das falsch?


Die zweite Frage bezieht sich auf quasi-parallele Ereignisse, wenn mehrere notifys feuern. Wie handhabt fhem die Ausführung dann einer Funktion, die von unterschiedlichen notifys fast zeitgleich aufgerufen wird? Werden die Ereignisse nacheinander abgearbeitet und wartet fhem mit der erneuten Ausführung einer Funktion bis die Funktion zuvor beendet wurde? Oder wird eine Funktion (für das gleiche Device) mehrmals (fast) parallel aufgerufen? Das "fast" bezieht sich auf die Laufzeit, d.h. zur Laufzeit eines Aufrufs wird die Funktion ein weiteres mal aufgerufen...

Sollte eine Funktion tatsächlich mehrmals parallel aufgerufen werden, könnten sich die Kommandos in die Quere kommen. Dann bräuchten wir hier noch irgend etwas, um das zu erkennen und entweder zu unterbinden oder einen kontrollierten Zustand (z.B. eine priorisierte Aktion) herbeizuführen.

Grüße,
spi

Nachtrag:
Beim Testen konnte ich auf die schnelle die Abfrage
elsif ($maxPosTilted < $onHoldState) { $maxPosTilted = $onHoldState; }
nicht zum Feuern bringen. Sind
WindowContactOpenMaxClosed 30
WindowContactTiltedMaxClosed 10
WindowContactOnHoldState 20

dann wird beim Kippen das Rollo auf Position 10 gefahren und nicht 20. Hm.

Beta-User

Ziemlich tricky, das ganze...

Habe zwischenzeitlich eine aktualisierte Version auf Github, ist aber ausdrücklich development, da nicht in allen Belangen funktional, zu den Problemen s.u.

Vorab zu den Fragen und Anmerkungen:
- das elsif ist nur relevant, wenn eine Jalousie an einer Wendeposition hält. Das ist ein Sonderfall, den man im Auge behalten sollte, um keine Seiteneffekte auszulösen, im Moment sehe ich da aber noch keine große Gefahr.
- Was timer und quasi-parallele Ereignisse angeht, sehe ich das so:
-- FHEM sollte alles sequenziell abarbeiten, eine Parallelisierung von threads ist nicht vorgesehen. Bislang habe ich den Eindruck, dass es genau so ist. Damit liegt die eigentliche Schwierigkeit darin, vorab  sinnvolle Eingangsprüfungen zu machen, ob denn überhaupt etwas zu tun ist. Weil: UU. sind bestimmte Werte, von denen man annehmen würde, dass sie zusammen mit dem triggernden Ereignis aktualisiert werden noch nicht auf dem erwarteten Stand (Gerätestatus wird z.B. immer als letztes aktualisiert).
-- Bei der bisherigen Fassung des "testers" war das solange kein Problem, wie genug Zeit war, dass sich die Zustände alle wieder sauber dargestellt haben (während der Rolladenfahrt). Weiteres s.u..
-- interne Timer setzen (wie ginge das überhaupt?), dürfte nach meinem Gefühl eher zu noch mehr Durcheinander führen, im Moment glaube ich, dass bessere Abfragen (ua. nach ReadingsAge()) die meisten Rätsel lösen könnten, über die ich gestern noch gestolpert bin (braucht aber noch Tests).
- Das mit der Tilted-Position ist mir auch aufgefallen, habe da wieder was geändert, ganz gelöst ist es aber noch nicht.

Im Moment hat der dev-Code nämlich (mind.) dieses Problem, was genau damit zusammenzuhängen scheint:
Er triggert sich in bestimmten Positionen/Situationen ständig selbst. Die, bei der mir das aufgefallen ist: Rolladen fährt bei Wechsel des Fensters von "open" zu "tilted" die entsprechende Position an. Dann sieht man im Ereignissmonitor, dass nach Erreichen dieser Position für "level" ständig ein "set_<tiltedPos>" ausgeführt wird. Da aber der Motor nix tut außer ein "stop" zu melden,  geht das im Sekundentakt gerade so weiter, bis man öffnet, schließt oder den Rolladen manuell hochfährt. Vermute, dass "set_xxx" immer kleiner als eine der abgefragten Mindestlevel ist (nämlich als "0" interpretiert wird). Das muß ich mir nochmal genauer ansehen, bin gestern erst spät darauf gekommen, dass manche komischen Effekte, die ich der neuen "MovementCheck"-Funktion zugeschrieben hatte, gar nicht (nur?) aus der Ecke kommen, sondern vom "tester".

Dafür hat die neue Funktion schon ein paar Bausteine drin, die das debuggen und das Ausfiltern der unnötigen "set_xxx" vollends erleichtern sollten:
- Ausgabe div. Infos über Zeile 58. Die deaktiviert die set-Funkionen im Moment mal noch und spuckt nur über einen Dummy die set-Werte aus, zum Testen sollte man das aber bereits auskommentieren können.
- Textfunktionen, um aus "set_xxx" was sinnvolles numerisches machen zu können. (Nächste Aktionen im "Tester", zusammen mir Ausgabe in Dummy)

Wenn das alles funktioniert, sollte eigentlich in der neuen "dynamischen" Version nur noch der Fall nicht abgedeckt sein, dass jemand während der Fahrt nach unten das Fenster aufmacht. Hier könnte uU. ein weiteres Attribut helfen (downTargetPosition (?) gesetzt in der "MovementCheck", falls nicht direkt andere set-Werte angewandt werden, gelöscht dann über den "stop"-Fall im "Tester". Aber eines nach dem anderen 8)...

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

spi3845

Zitat von: Beta-User am 10 April 2017, 10:27:37
Ziemlich tricky, das ganze...
Ist es.

Ich habe mal folgendes gemacht - vielleicht will ja jemand mittesten:
Die Funktion von github (ohne Jalousienlogik) habe ich reduziert auf die Logik allein, ergänzt um print-Anweisungen.

          #Wir speichern ein paar Infos, damit das nicht zu unübersichtlich wird
          my $event = "Window";
          my $windowcontact = "Fenster1";
          my $position = 5; # Werte 0-100
          my $winState = "open"; # Werte open, tilted oder closed
          my $maxPosOpen = 30; # Lüften-Position bei winstate=open
          my $maxPosTilted = 10;  # Lüften-Position bei winstate=tilted
          my $onHoldState = "none"; # "none" oder alte Position
 
          #Jetzt können wir nachsehen, ob der Rolladen zu weit unten ist (Fenster offen)...
          if($position < $maxPosOpen && $winState eq "open" && $windowcontact ne "none") {
      print "fhem(\"set $shutter $maxPosOpen\")\n";
              if($onHoldState eq "none") { print "fhem(\"setreading $shutter WindowContactOnHoldState $position\")\n"; }
          }
          #...(gekippt)...
          elsif($winState eq "tilted" && $windowcontact ne "none") {
              if($position < $maxPosTilted && $onHoldState eq "none") { print "fhem(\"setreading $shutter WindowContactOnHoldState $position\")\n"; }
  elsif ($maxPosTilted < $onHoldState) { $maxPosTilted = $onHoldState; }
  print "fhem(\"set $shutter $maxPosTilted\")\n";
          }
          #...oder ob eine alte Position wegen Schließung des Fensters angefahren werden soll...
          elsif ($event eq "Window" && $winState eq "closed" && $onHoldState ne "none") {
              print "fhem(\"set $shutter $onHoldState\")\n";
              print "fhem(\"setreading $shutter WindowContactOnHoldState none\")\n"; 
          }
          #...oder ob es sich um einen Stop zum Drehen der Jalousielamellen handelt...
  elsif ($event eq "Rollo") {
  #...oder die Positionsinfo wegen manueller Änderung gelöscht werden kann.
    if ($position != $maxPosOpen && $position != $maxPosTilted && $onHoldState ne "none") {
                        print "fhem(\"setreading $shutter WindowContactOnHoldState none\")\n";
                    }
}


Das ganze kann man z.B. auf https://www.tutorialspoint.com/execute_perl_online.php einkopieren und testen. Dazu die Variablen entsprechend setzen. Möchte man nach einem Lauf aus der Position  in eine andere fahren und testen, ob sich der Rollladen richtig verhält, setzt man die Variablen auf die Ausgabewerte...

So sieht man, ob der Rolladen beim Öffnen des Fensters in die richtigen Positionen fahren würde - ohne einen Rollladen tatsächlich fahren zu lassen.

Grüße,
spi