[gelöst] Shelly Plus 2pm für die Winkelsteuerung von Raffstore Lamellen

Begonnen von alkazaa, 13 Juli 2023, 21:00:27

Vorheriges Thema - Nächstes Thema

alkazaa

Ich habe heute ein Shelly Plus 2pm installiert, um ein Raffstore zu steuern.
Es funktioniert hervorragend, bis auf die fehlende Steuerung des Lamellenwinkels. Das hat der Hersteller seinen Shellies immer noch nicht beigebracht.

In FHEM habe ich es über MQTT2 eingebunden, und auch das funktioniert. Es müsste nun ein Leichtes sein (dachte ich), dem verwendeten template (Shelly Plus 2PM Rollo Invert_0) auch die Befehle für ein kurzzeitiges Fahren des Raffstores beizubringen, um damit den Lamellenwinkel zu verstellen.

Manuell bekomme ich das schon hin, indem ich testweise den setlist-Befehl
close:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Close","params": {"id":0}}so abgeändert habe:
close:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Close","params": {"id":0,"duration":0.8}}
Dann fährt er 0.8 sec in die close-Richtung. Das entspricht bei mir einer waagerecht gestellten Lamelle. Man müsste natürlich die 0.8 parametriert in den per setlist erzeugten MQTT Befehl kriegen, und auch die Abhängigkeit von der letzten Fahrtrichtung muss man unterbringen.

Da die von mir verwendete allerneueste Shelly firmware 1.0.0-beta5 nun auch die letzte Fahrtrichtung im Attribut 'status_last_direction' liefert, könnte man jetzt die Lamellenverstellung realisieren wenn (Ja, WENN) es möglich wäre, bei den setlist-Definitionen die erwähnte Flexibilität hinzukriegen.

Idealerweise mit perl-code wie beim DOIF...

Geht sowas? Oder wie könnte man es sonst lösen?

rudolfkoenig

ZitatMan müsste natürlich die 0.8 parametriert in den per setlist erzeugten MQTT Befehl kriegen, und auch die Abhängigkeit von der letzten Fahrtrichtung muss man unterbringen.
Siehe https://fhem.de/commandref.html#MQTT2_DEVICE-attr-setList
Parametrisierung geht mit $EVTPARTx, fuer die Abhaengigkeit von der Fahrtrichtung muss man die Perl-Variante verwenden, und "topic message" zurueckliefern. Am besten in einer Funktion im 99_myUtils.pm, was aus setList aufgerufen wird.

ZitatIdealerweise mit perl-code wie beim DOIF...
Ist nicht das, was ich fuer ideal halte, man muss deswegen hier beim "normalen" perl bleiben.

alkazaa

Super, danke, damit werd ich's hinkriegen, denk ich.

Fürs erste habe ich jetzt das 'mitverfolgen' des aktuellen Lamellenwinkels implementiert. Es funktioniert mit der firmware 1.0.0-beta5 des Shelly Plus 2pm.
Hier die relevanten Zeilen aus dem device listing:

   2023-07-15 18:01:59   slat_angle      100
   ...
   ...
   full_slat_time 0.8
   ...
   ...
   userReadings slat_angle:status_move_started_at.* {
my $angle_now   = ReadingsVal("$NAME","slat_angle",0);
my $movedir     = ReadingsVal("$NAME","status_last_direction","");
my $movetime    = ReadingsVal("$NAME","status_move_timeout",60);
my $slatchange = 100*$movetime/AttrVal("$NAME","full_slat_time",1);
min(100,max(0,$angle_now + ($movedir eq "open"?1:-1) * $slatchange));
}
   userattr   full_slat_time

Die Implementierung von 'set <device> slat_angle <nnn>' geh ich als nächstes an.

-Franz

alkazaa

ZitatDie Implementierung von 'set <device> slat_angle <nnn>' geh ich als nächstes an.
Ich versuche mich gerade da ran zu tasten. In setlist habe ich folgende Kommando definiert:
slat:1,-1 $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":$EVTPART1}}Das funktioniert.
Mein nächster tastender Schritt war jetzt, das mit Perl zu reproduzieren. Erstmal habe ich, um es noch einfacher zu machen, $EVTPART1 durch die Konstante 1 ersetzt und das Kommando so definiert:
slat:1,-1 {'$DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":1}}';}Das funktioniert nicht (auch nicht mit doppeltem ;; ), obwohl ich, wenn ich den Befehl
{'$DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":1}}';;}in der FHEM-Kommandozeile ausführe, korrekterweise den string
$DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":1}}
angezeigt bekomme.

Auf welchem Schlauch steh ich hier ?

rudolfkoenig

ZitatAuf welchem Schlauch steh ich hier ?
perl ersetzt in einem Single-Quote-String ('...') keine Variablen, nur in einem Double-Quote-String ("...").
In einem {} Ausdruck muss der letzte (bzw. einzige) Befehl nicht mit ; abgeschlossen sein.
In der FHEMWEB Attribut-Editor wird ; automatisch zu ;; gewandelt. Wenn man das Raw-Definition Fenster verwendet oder fhem.cfg direkt editiert, dann muss man ;; eingeben.
In der Detailansicht von MQTT2_CLIENT oder MQTT2_SERVER kann man alle gesendeten und empfangenen Nachrichten anschauen (Show MQTT traffic).

Ich wuerde Folgendes versuchen:
slat:1,-1 {"$DEVICETOPIC/rpc ".'{"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":'.$EVTPART1.'}}'}

alkazaa

#5
Super, vielen Dank!
Zitat von: rudolfkoenig am 15 Juli 2023, 22:46:16perl ersetzt in einem Single-Quote-String ('...') keine Variablen, nur in einem Double-Quote-String ("...").
Das war der Teil der mir fehlte.
So habe ich es jetzt umgesetzt:
pct_slat:slider,0,50,100 {my $slatchange = floor(0.5 + 0.02 * ($EVTPART1 - ReadingsVal("$NAME","slat_angle",0)));"$DEVICETOPIC/rpc ".'{"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"rel":'.$slatchange.'}}'}Die Begrenzung auf Prozentwerte 0,50,100 ist der Tatsache geschuldet, dass die benutzte Shelly-beta-firmware im Moment nur integer für die relative Positionsänderung erlaubt. Ob sich das ändert, muss man abwarten, aber das ist kein FHEM Problem mehr.

Nochmals vielen Dank!

-Franz

NACHTRAG:
Hab gerade beim Lesen meines ersten Beitrags gesehen, dass man die Begrenzung auf integer bei der Cover.GoToPosition Methode ja umgehen kann, indem man Cover.Close (bzw. Open) mit duration parameter verwendet. Der pct_slat Befehl sieht dann so aus:
pct_slat:slider,0,25,100 {my $slatchange = 0.1*floor(0.5 + 0.1 * ($EVTPART1 - ReadingsVal("$NAME","slat_angle",0)) * AttrVal("$NAME","full_slat_time",0)); my $dir = "Open"; if ($slatchange < 0) {$dir="Close"}; "$DEVICETOPIC/rpc ".'{"id":0,"src":"fhem2shelly","method":"Cover.'.$dir.'","params": {"id":0,"duration":'.abs($slatchange).'}}'}Allerdings muss man beachten, dass durch die begrenzte Reproduzierbarkeit und die schlechte Zeitauflösung der Shellies keine zuverlässige Winkeleinstellung mehr gegeben ist, wenn man den Winkel, selbst nur wenige Male, um kleine Beträge ändert. Die Fehler akkumulieren dann sehr schnell. Ist in der Praxis aber meistens irrelevant, da beim Ändern der Höhe des Raffstores um mindestens +- 2% der Winkel sich dann sowieso auf 0 oder 100% neu einstellt. Für Winkelstellungen von 0 bis 100 % in 25% Schritten könnte es gerade reichen.

NACHTRAG 2:
Um die schlechte Reproduzierbarkeit der Shellies im Zehntelsekundenbereich zumindest etwas auszutricksen, habe ich die 'setlist' nochmals geändert. Im wesentlichen mache ich es jetzt so, das zur Einstellung eines anderen Lamellenwinkels zunächst 'Lamellen offen', bzw. 'Lamellen geschlossen' angesteuert wird (abhängig davon, ob der neue Lamellenwinkel < oder > 50% ist). Von dort wird dann der neue Soll-Winkel angefahren.
Hier die setlist-Kommandos, die ich der 'setlist' des templates hinzugefügt habe:
  open_step:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Open","params": {"id":0,"duration":0.1}}
 
  close_step:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Close","params": {"id":0,"duration":0.1}}

  open_for:textField $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Open","params": {"id":0,"duration":$EVTPART1}}
 
  close_for:textField $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.Close","params": {"id":0,"duration":$EVTPART1}}
 
  pct_slat:slider,0,25,100 {my $slat_then=$EVTPART1; my $slat_now = ReadingsVal("$NAME","slat_angle",0); my $slat_full_time = AttrVal("$NAME","full_slat_time",0); my $dir1 = "close_for"; my $slatmovtime1 = 0.1*floor(0.5 + 0.1 * $slat_now * $slat_full_time); my $dir2 = "open_for"; my $slatmovtime2 = 0.1*floor(0.5 + 0.1 * $slat_then * $slat_full_time); if ($slat_then<50) {($dir1,$dir2,$slatmovtime1,$slatmovtime2)=($dir2,$dir1,$slat_full_time-$slatmovtime1,$slat_full_time-$slatmovtime2)}; my $sleeptime=0.5+$slatmovtime1; fhem(qq(set $NAME $dir1 $slatmovtime1; sleep $sleeptime; set $NAME $dir2 $slatmovtime2))}



alkazaa

Inzwischen gibt es für das Shelly Plus 2pm die firmware 1.5.0 beta1. Da ist nun auch die Lamellenwinkelsteuerung integriert.

Wenn man mit MQTT2 arbeitet und das attrTemplate shellyPlus_2pm_roller_invert_0 benutzt, sollte man die setlist um die Zeile   pct_slat:slider,0,25,100 $DEVICETOPIC/rpc {"id":0,"src":"fhem2shelly","method":"Cover.GoToPosition","params": {"id":0,"slat_pos":$EVTPART1}} ergänzen und das Attribut jsonMap entsprechend erweitern:
attr DEVICE status_state:state status_slat_pos:pct_slat status_current_pos:pct status_temperature_tC:temperature