diff --git a/FHEM/10_EnOcean.pm b/FHEM/10_EnOcean.pm index 1a0fca4d1..100c07852 100755 --- a/FHEM/10_EnOcean.pm +++ b/FHEM/10_EnOcean.pm @@ -65,10 +65,11 @@ EnOcean_Initialize($) $hash->{DefFn} = "EnOcean_Define"; $hash->{ParseFn} = "EnOcean_Parse"; $hash->{SetFn} = "EnOcean_Set"; + $hash->{AttrFn} = "EnOcean_Attr"; $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 " . "showtime:1,0 loglevel:0,1,2,3,4,5,6 model " . - "subType:switch,contact,sensor,windowHandle,SR04,MD15,". - "eltakoDimmer subId actualTemp"; + "subType:switch,contact,sensor,windowHandle,SR04,MD15," . + "eltakoDimmer,eltakoRoll subId actualTemp, dimTime"; for(my $i=0; $i<@ptm200btn;$i++) { $ptm200btn{$ptm200btn[$i]} = "$i:30"; @@ -77,6 +78,27 @@ EnOcean_Initialize($) return undef; } +# --------------------------------------------- + +sub EnOcean_Attr($) +{ + my @a = @_; + + my $name= $a[1]; + my $ll2 = GetLogLevel($name, 2); + + if($a[2] eq "subType") { + Log $ll2, "EO_Attr subtype"; + + if($a[3] eq "eltakoDimmer") { + Log $ll2, "EO_Attr subtype dimmer"; + $attr{$name}{eventMap}="B0:on B1:off" + } + } + return undef; + +} + ############################# sub EnOcean_Define($$) @@ -142,6 +164,12 @@ EnOcean_Set($@) $hash->{READINGS}{$cmd}{VAL} = $arg; } elsif($st eq "eltakoDimmer") { + my $sendDimCmd=0; + my $time=AttrVal($name, "dimTime", 0); + my $onoff=1; + my $dimVal=100; + $dimVal=$hash->{VALUE} if(defined $hash->{VALUE}); + if($cmd eq "teach") { my $idSrc=EnOcean_GetMyDeviceId($hash); my $data=sprintf("A502000000%s00", $idSrc); @@ -149,25 +177,67 @@ EnOcean_Set($@) IOWrite($hash, "000A0001", $data); # len:000a optlen:00 pakettype:1(radio) } elsif($cmd eq "dimto") { - return "Usage: $cmd percent [time 01-FF FF:slowest] [on/off]" if(@a<2); - my $time=0; - my $onoff=1; + return "Usage: $cmd percent" if(@a<2); # for eltako relative (0-100) (but not compliant to EEP because DB0.2 is 0) - my $dimVal=$a[1]; + $dimVal=$a[1]; shift(@a); if(defined($a[1])) { $time=$a[1]; shift(@a); } if(defined($a[1])) { $onoff=($a[1] eq "off") ? 0 : 1; shift(@a); } - # EEP: A5/38/08 Central Command ->Typ 0x02: Dimming - my $idSrc=EnOcean_GetMyDeviceId($hash); - #my $data=sprintf("A502%02X%02X%02X%s00", $dimVal, $time, $onoff|0x08, $hash->{DEF}); - my $data=sprintf("A502%02X%02X%02X%s00", $dimVal, $time, $onoff|0x08, $idSrc); - IOWrite($hash, "000A0001", $data); - Log $ll2, "$st.$cnd: " . $data; + $sendDimCmd=1; + + } elsif($cmd eq "dimup") { + return "Usage: $cmd percent" if(@a<2 or $a[1]>100); + $dimVal+=$a[1]; + Log $ll2, "$st.$cmd val:" . $hash->{VALUE} . " par:" . $a[1] . " val:" . $dimVal; + shift(@a); + $sendDimCmd=1; + + } elsif($cmd eq "dimdown") { + return "Usage: $cmd percent" if(@a<2 or $a[1]>100); + $dimVal-=$a[1]; + shift(@a); + $sendDimCmd=1; + + } elsif($cmd eq "on" or $cmd eq "B0") { + $sendDimCmd=1; + + } elsif($cmd eq "off" or $cmd eq "B1") { + $onoff=0; + $sendDimCmd=1; } else { - return "Unknown argument $cmd, choose one of: teach, dimto" + return "Unknown argument $cmd, choose one of: teach, dimto, dimup, dimdown, on ,off"; } + if($sendDimCmd) { + if($dimVal > 100) { $dimVal=100; } + if($dimVal <= 0) { $dimVal=0; $onoff=0; } + # EEP: A5/38/08 Central Command ->Typ 0x02: Dimming + my $idSrc=EnOcean_GetMyDeviceId($hash); + my $data=sprintf("A502%02X%02X%02X%s00", $dimVal, $time, $onoff|0x08, $idSrc); + IOWrite($hash, "000A0001", $data); + Log $ll2, "$st.$cmd: " . $data; + } + + ########################### + } elsif($st eq "eltakoRoll") { + if($cmd eq "teach") { + my $data=sprintf("A5FFF80D80%s00", $hash->{DEF}); + Log $ll2, "eltakoRollCtrl.Teach: " . $data; + IOWrite($hash, "000A0001", $data); # len:000a optlen:00 pakettype:1(radio) + } else { + my %eltakoRollCtrlCommands = ( down=>0x02, up=>0x01, stop=>0x00 ); + my $usage = "Usage: (" . join("|", sort keys %eltakoRollCtrlCommands) . ") [time 0-255 sek]"; + my $rollcmd= $eltakoRollCtrlCommands{$cmd}; + return $usage if( (!defined($rollcmd)) or (@a<1) ); + my $time=0; + if(defined($a[1])) { $time=$a[1]; shift(@a); } # time + # EEP: A5/3F/7F Universal ??? + my $idSrc=EnOcean_GetMyDeviceId($hash); + my $data=sprintf("A5%02X%02X%02X%02X%s00", 0, $time, $rollcmd, 0x08, $idSrc); + IOWrite($hash, "000A0001", $data); + Log $ll2, "eltakoRoll.$cmd" . $data; + } ########################### } else { # Simulate a PTM @@ -180,14 +250,14 @@ EnOcean_Set($@) my ($db_3, $status) = split(":", $ptm200btn{$c1}, 2); $db_3 <<= 5; $db_3 |= 0x10 if($c1 ne "released"); # set the pressed flag - if($c2) { - my ($d2, undef) = split(":", $ptm200btn{$c2}, 2); - $db_3 |= ($d2<<1) | 0x01; - } - IOWrite($hash, "", - sprintf("6B05%02X000000%s%s", $db_3, $hash->{DEF}, $status)); + if($c2) { + my ($d2, undef) = split(":", $ptm200btn{$c2}, 2); + $db_3 |= ($d2<<1) | 0x01; + } + IOWrite($hash, "", + sprintf("6B05%02X000000%s%s", $db_3, $hash->{DEF}, $status)); - } + } select(undef, undef, undef, 0.1) if($i < int(@a)-1); } @@ -275,6 +345,8 @@ EnOcean_Parse($$) } } + # eltakoRoll: BI: unten / B0: oben / released:running/stopped + # released events are disturbing when using a remote, since it overwrites # the "real" state immediately @@ -402,10 +474,11 @@ EnOcean_Parse($$) if($vn eq "state") { $hash->{STATE} = $vv; push @changed, $vv; - + } elsif($vn eq "value") { + $hash->{VALUE} = $vv if($vv>0); + push @changed, "$vn: $vv"; } else { push @changed, "$vn: $vv"; - } }