2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-21 07:56:03 +00:00

- profile manufProfile, 00D (Eltako Shutter): functions extended and optimized

- profile roomSensorControl.[01|02|05|1F]: scaling function optimized
- switch mode pushbutton: command released is now sent with a delay

git-svn-id: https://svn.fhem.de/fhem/trunk@3227 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klaus-schauer 2013-05-30 05:49:25 +00:00
parent d9e2423452
commit 45d69b22dd

View File

@ -175,7 +175,6 @@ my %EnO_subType = (
my @EnO_models = qw ( my @EnO_models = qw (
other other
slats
FSB14 FSB61 FSB70 FSB14 FSB61 FSB70
FSM12 FSM61 FSM12 FSM61
FT55 FT55
@ -197,14 +196,14 @@ EnOcean_Initialize($)
$hash->{SetFn} = "EnOcean_Set"; $hash->{SetFn} = "EnOcean_Set";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 dummy:0,1 " . $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 dummy:0,1 " .
"showtime:1,0 loglevel:0,1,2,3,4,5,6 " . "showtime:1,0 loglevel:0,1,2,3,4,5,6 " .
"actualTemp " . "actualTemp angleMax:slider,-180,20,180 angleMin:slider,-180,20,180 " .
"dimTime dimValueOn " . "angleTime:0,1,2,3,4,5,6 dimValueOn " .
"model:" . join(",", @EnO_models) . " " . "model:" . join(",", @EnO_models) . " " .
"gwCmd:" . join(",", sort @EnO_gwCmd) . " " . "gwCmd:" . join(",", sort @EnO_gwCmd) . " " .
"manufID:" . join(",", keys %EnO_manuf) . " " . "manufID:" . join(",", keys %EnO_manuf) . " " .
"rampTime repeatingAllowed:yes,no " . "rampTime repeatingAllowed:yes,no " .
"scaleMax scaleMin " . "scaleDecimals:0,1,2,3,4,5,6,7,8,9 scaleMax scaleMin " .
"shutTime subDef subDef0 subDefI " . "shutTime shutTimeCloses subDef subDef0 subDefI " .
"subType:" . join(",", sort grep { !$subTypeList{$_}++ } values %EnO_subType) . " " . "subType:" . join(",", sort grep { !$subTypeList{$_}++ } values %EnO_subType) . " " .
"subTypeSet:" . join(",", sort grep { !$subTypeSetList{$_}++ } values %EnO_subType) . " " . "subTypeSet:" . join(",", sort grep { !$subTypeSetList{$_}++ } values %EnO_subType) . " " .
"switchMode:switch,pushbutton " . "switchMode:switch,pushbutton " .
@ -258,7 +257,6 @@ EnOcean_Set($@)
my $switchMode = AttrVal($name, "switchMode", "switch"); my $switchMode = AttrVal($name, "switchMode", "switch");
my $tn = TimeNow(); my $tn = TimeNow();
my $updateState = 1; my $updateState = 1;
shift @a; shift @a;
for(my $i = 0; $i < @a; $i++) { for(my $i = 0; $i < @a; $i++) {
@ -557,7 +555,7 @@ EnOcean_Set($@)
$updateState = 0; $updateState = 0;
$data = sprintf "A5%02X00%02X%02X", $gwCmdID, $controlVar, $setCmd; $data = sprintf "A5%02X00%02X%02X", $gwCmdID, $controlVar, $setCmd;
} else { } else {
return "Unknown argument, choose one of teach presence energyHoldOff controllerMode controllerState"; return "Unknown argument, choose one of teach presence:absent,present,standby energyHoldOff:holdoff,normal controllerMode:cooling,heating,off controllerState:auto,override";
} }
} elsif ($gwCmd eq "fanStage") { } elsif ($gwCmd eq "fanStage") {
@ -576,7 +574,7 @@ EnOcean_Set($@)
} }
shift(@a); shift(@a);
} else { } else {
return "Unknown argument, choose one of teach stage"; return "Unknown argument, choose one of teach stage:auto,0,1,2,3";
} }
} elsif ($gwCmd eq "blindCmd") { } elsif ($gwCmd eq "blindCmd") {
@ -745,82 +743,194 @@ EnOcean_Set($@)
} elsif ($st eq "manufProfile") { } elsif ($st eq "manufProfile") {
if ($manufID eq "00D") { if ($manufID eq "00D") {
# Eltako Shutter # Eltako Shutter
my $angleMax = AttrVal($name, "angleMax", 90);
my $angleMin = AttrVal($name, "angleMin", -90);
my $anglePos = ReadingsVal($name, "anglePos", undef);
my $angleTime = AttrVal($name, "angleTime", 0);
my $position = ReadingsVal($name, "position", undef); my $position = ReadingsVal($name, "position", undef);
my $shutTime = AttrVal($name, "shutTime", 255); my $shutTime = AttrVal($name, "shutTime", 255);
my $shutTimeCloses = AttrVal($name, "shutTimeCloses", $shutTime);
$shutTimeCloses = $shutTime if ($shutTimeCloses < $shutTimeCloses);
my $shutCmd = 0; my $shutCmd = 0;
$angleMax = 90 if ($angleMax !~ m/^[+-]?\d+$/);
$angleMax = 180 if ($angleMax > 180);
$angleMax = -180 if ($angleMax < -180);
$angleMin = -90 if ($angleMin !~ m/^[+-]?\d+$/);
$angleMin = 180 if ($angleMin > 180);
$angleMin = -180 if ($angleMin < -180);
($angleMax, $angleMin) = ($angleMin, $angleMax) if ($angleMin > $angleMax);
$angleMax ++ if ($angleMin == $angleMax);
$angleTime = 6 if ($angleTime !~ m/^[+-]?\d+$/);
$angleTime = 6 if ($angleTime > 6);
$angleTime = 0 if ($angleTime < 0);
$shutTime = 255 if ($shutTime !~ m/^[+-]?\d+$/); $shutTime = 255 if ($shutTime !~ m/^[+-]?\d+$/);
$shutTime = 255 if ($shutTime > 255); $shutTime = 255 if ($shutTime > 255);
$shutTime = 1 if ($shutTime < 1); $shutTime = 1 if ($shutTime < 1);
if ($cmd eq "teach") { if ($cmd eq "teach") {
$data = "A5FFF80D80"; $data = "A5FFF80D80";
$header = "000A0001";
Log $ll2, "EnOcean: set $name $cmd";
} elsif ($cmd eq "stop") { } elsif ($cmd eq "stop") {
# stop
# delete readings, as they are undefined
CommandDeleteReading(undef, "$name anglePos");
CommandDeleteReading(undef, "$name position");
readingsSingleUpdate($hash, "state", "stop", 1);
$shutCmd = 0; $shutCmd = 0;
} elsif ($cmd eq "opens") {
# opens >> B0
$anglePos = 0;
readingsSingleUpdate($hash, "anglePos", $anglePos, 1);
$position = 0;
readingsSingleUpdate($hash, "position", $position, 1);
$shutTime = $shutTimeCloses;
$shutCmd = 1;
$updateState = 0;
} elsif ($cmd eq "closes") {
# closes >> BI
$anglePos = $angleMax;
readingsSingleUpdate($hash, "anglePos", $anglePos, 1);
$position = 100;
readingsSingleUpdate($hash, "position", $position, 1);
$shutTime = $shutTimeCloses;
$shutCmd = 2;
$updateState = 0;
} elsif ($cmd eq "up" || $cmd eq "B0") { } elsif ($cmd eq "up" || $cmd eq "B0") {
# up
if(defined $a[1]) { if(defined $a[1]) {
if ($a[1] =~ m/^[+-]?\d+$/ && $a[1] > 0 && $a[1] <= 100) { if ($a[1] =~ m/^[+-]?\d+$/ && $a[1] >= 0 && $a[1] <= 255) {
$shutTime = $shutTime / 100 * $a[1]; $position -= $a[1] / $shutTime * 100;
$position -= $a[1]; if ($angleTime) {
if($position <= 0) { $position = 0; } $anglePos -= ($angleMax - $angleMin) * $shutTime / $angleTime;
if ($anglePos < $angleMin) {
$anglePos = $angleMin;
}
} else {
$anglePos = $angleMin;
}
if ($position <= 0) {
$anglePos = 0;
$position = 0;
}
$shutTime = $a[1];
shift(@a); shift(@a);
} else { } else {
return "Usage: $a[1] is not numeric or out of range"; return "Usage: $a[1] is not numeric or out of range";
} }
} else { } else {
$anglePos = 0;
$position = 0; $position = 0;
} }
readingsSingleUpdate($hash,"position",$position,1); readingsSingleUpdate($hash, "anglePos", sprintf("%d", $anglePos), 1);
readingsSingleUpdate($hash, "position", sprintf("%d", $position), 1);
$shutCmd = 1; $shutCmd = 1;
} elsif ($cmd eq "down" || $cmd eq "BI") { } elsif ($cmd eq "down" || $cmd eq "BI") {
# down
if(defined $a[1]) { if(defined $a[1]) {
if ($a[1] =~ m/^[+-]?\d+$/ && $a[1] >= 0 && $a[1] < 100) { if ($a[1] =~ m/^[+-]?\d+$/ && $a[1] >= 0 && $a[1] < 255) {
$shutTime = $shutTime / 100 * $a[1]; $position += $a[1] / $shutTime * 100;
$position += $a[1]; if ($angleTime) {
if($position > 100) { $position = 100; } $anglePos += ($angleMax - $angleMin) * $shutTime / $angleTime;
shift(@a); if ($anglePos > $angleMax) {
$anglePos = $angleMax;
}
} else {
$anglePos = $angleMax;
}
if($position > 100) {
$anglePos = $angleMax;
$position = 100;
}
$shutTime = $a[1];
shift(@a);
} else { } else {
return "Usage: $a[1] is not numeric or out of range"; return "Usage: $a[1] is not numeric or out of range";
} }
} else { } else {
$anglePos = $angleMax;
$position = 100; $position = 100;
} }
readingsSingleUpdate($hash,"position",$position,1); readingsSingleUpdate($hash, "anglePos", sprintf("%d", $anglePos), 1);
readingsSingleUpdate($hash, "position", sprintf("%d", $position), 1);
$shutCmd = 2; $shutCmd = 2;
} elsif ($cmd eq "position") { } elsif ($cmd eq "position") {
if (!defined $position) { if (!defined $position) {
return "Position unknown, please first open the blinds completely." return "Position unknown, please first opens the blinds completely."
} elsif ($angleTime > 0 && !defined $anglePos){
return "Slats angle position unknown, please first opens the blinds completely."
} else { } else {
my $anglePosLast = $anglePos;
my $shutTimeSet = $shutTime;
if (defined $a[2]) {
if ($a[2] =~ m/^[+-]?\d+$/ && $a[2] >= $angleMin && $a[2] <= $angleMax) {
$anglePos = $a[2];
} else {
return "Usage: $a[1] $a[2] is not numeric or out of range";
}
splice(@a,2,1);
} else {
$anglePos = $angleMax;
}
if (defined $a[1] && $a[1] =~ m/^[+-]?\d+$/ && $a[1] >= 0 && $a[1] <= 100) { if (defined $a[1] && $a[1] =~ m/^[+-]?\d+$/ && $a[1] >= 0 && $a[1] <= 100) {
if ($position < $a[1]) { if ($position < $a[1]) {
# down # down
$shutTime = $shutTime / 100 * ($a[1] - $position); ##
$angleTime = $angleTime * ($angleMax - $anglePos)/($angleMax - $angleMin);
$shutTime = $shutTime * ($a[1] - $position) / 100 + $angleTime;
$position = $a[1] + $angleTime / $shutTimeSet * 100;
if ($position >= 100) {
$position = 100;
}
$shutCmd = 2; $shutCmd = 2;
if ($angleTime) {
my @timerCmd = ($name, "up", $angleTime);
my %par = (hash => $hash, timerCmd => \@timerCmd);
InternalTimer(gettimeofday() + $shutTime + 1, "EnOcean_TimerSet", \%par, 0);
}
} elsif ($position > $a[1]) { } elsif ($position > $a[1]) {
# up # up
$shutTime = $shutTime / 100 * ($position - $a[1]); ##
$angleTime = $angleTime * ($anglePos - $angleMin) /($angleMax - $angleMin);
$shutTime = $shutTime * ($position - $a[1]) / 100 + $angleTime;
$position = $a[1] - $angleTime / $shutTimeSet * 100;
if ($position <= 0) {
$position = 0;
$anglePos = 0;
}
$shutCmd = 1; $shutCmd = 1;
if ($angleTime && $a[1] > 0) {
my @timerCmd = ($name, "down", $angleTime);
my %par = (hash => $hash, timerCmd => \@timerCmd);
InternalTimer(gettimeofday() + $shutTime + 1, "EnOcean_TimerSet", \%par, 0);
}
} else { } else {
# position ok if ($anglePosLast > $anglePos) {
$shutCmd = 0; # up
$shutTime = $angleTime * ($anglePosLast - $anglePos)/($angleMax - $angleMin);
$shutCmd = 1;
} elsif ($anglePosLast < $anglePos) {
# down
$shutTime = $angleTime * ($anglePos - $anglePosLast) /($angleMax - $angleMin);
$shutCmd = 2;
} else {
# position and slats angle ok
$shutCmd = 0;
}
} }
readingsSingleUpdate($hash,"position",$a[1],1); readingsSingleUpdate($hash, "anglePos", sprintf("%d", $anglePos), 1);
readingsSingleUpdate($hash, "position", sprintf("%d", $position), 1);
shift(@a); shift(@a);
} else { } else {
return "Usage: $a[1] is not numeric or out of range"; return "Usage: $a[1] is not numeric or out of range";
} }
} }
} else { } else {
return "Unknown argument " . $cmd . ", choose one of position:slider,0,5,100 up stop down teach" return "Unknown argument " . $cmd . ", choose one of closes down opens position:slider,0,5,100 stop teach up"
} }
if($shutCmd || $cmd eq "stop") { if($shutCmd || $cmd eq "stop") {
$updateState = 0; $updateState = 0;
$data = sprintf "A5%02X%02X%02X%02X", 0, $shutTime, $shutCmd, 8; $data = sprintf "A5%02X%02X%02X%02X", 0, $shutTime, $shutCmd, 8;
$header = "000A0001";
Log $ll2, "EnOcean: set $name $cmd";
} }
} else { $header = "000A0001";
return "Manufacturer Specific Application unknown. Set correct attr manufID."; Log $ll2, "EnOcean: set $name $cmd";
} }
} elsif ($st eq "contact") { } elsif ($st eq "contact") {
@ -868,7 +978,7 @@ EnOcean_Set($@)
return "Wrong parameter, choose RPS <data 1 Byte hex> [status 1 Byte hex]"; return "Wrong parameter, choose RPS <data 1 Byte hex> [status 1 Byte hex]";
} }
} else { } else {
return "Unknown argument $cmd, choose one of RPS 1BS 4BS timer"; return "Unknown argument $cmd, choose one of RPS 1BS 4BS";
} }
if ($a[2]) { if ($a[2]) {
if ($a[2] !~ m/^[\dA-F]{2}$/) { if ($a[2] !~ m/^[\dA-F]{2}$/) {
@ -967,6 +1077,8 @@ EnOcean_Set($@)
if ($switchMode eq "pushbutton") { if ($switchMode eq "pushbutton") {
$data = "F600"; $data = "F600";
$status = "20"; $status = "20";
# next commands will be sent with a delay
select(undef, undef, undef, 0.2);
Log $ll2, "EnOcean: set $name released"; Log $ll2, "EnOcean: set $name released";
$data = sprintf "%s%s%s", $data, $subDef, $status; $data = sprintf "%s%s%s", $data, $subDef, $status;
IOWrite ($hash, $header, $data); IOWrite ($hash, $header, $data);
@ -1373,7 +1485,7 @@ EnOcean_Parse($$)
push @event, "3:fan:$fspeed"; push @event, "3:fan:$fspeed";
push @event, "3:switch:$switch"; push @event, "3:switch:$switch";
push @event, "3:setpoint:$db_2"; push @event, "3:setpoint:$db_2";
EnOcean_ReadingScaled($hash, "setpoint", 0, 255); push @event, "3:setpointScaled:" . EnOcean_ReadingScaled($hash, $db_2, 0, 255);
} }
push @event, "3:temperature:$temp"; push @event, "3:temperature:$temp";
@ -1392,7 +1504,7 @@ EnOcean_Parse($$)
push @event, "3:switch:$switch"; push @event, "3:switch:$switch";
push @event, "3:setpoint:$db_2"; push @event, "3:setpoint:$db_2";
push @event, "3:temperature:$temp"; push @event, "3:temperature:$temp";
EnOcean_ReadingScaled($hash, "setpoint", 0, 255); push @event, "3:setpointScaled:" . EnOcean_ReadingScaled($hash, $db_2, 0, 255);
} elsif($st eq "roomSensorControl.02") { } elsif($st eq "roomSensorControl.02") {
# Room Sensor and Control Unit (A5-10-15 ... A5-10-17) # Room Sensor and Control Unit (A5-10-15 ... A5-10-17)
@ -1407,7 +1519,7 @@ EnOcean_Parse($$)
push @event, "3:presence:$presence"; push @event, "3:presence:$presence";
push @event, "3:setpoint:$setpoint"; push @event, "3:setpoint:$setpoint";
push @event, "3:temperature:$temp"; push @event, "3:temperature:$temp";
EnOcean_ReadingScaled($hash, "setpoint", 0, 63); push @event, "3:setpointScaled:" . EnOcean_ReadingScaled($hash, $setpoint, 0, 63);
} elsif($st eq "roomSensorControl.18") { } elsif($st eq "roomSensorControl.18") {
# Room Sensor and Control Unit (A5-10-18) # Room Sensor and Control Unit (A5-10-18)
@ -1644,7 +1756,7 @@ EnOcean_Parse($$)
push @event, "3:setpoint:$setpoint"; push @event, "3:setpoint:$setpoint";
push @event, "3:temperature:$temp"; push @event, "3:temperature:$temp";
push @event, "3:state:T: $temp F: $fanSpeed SP: $setpoint P: $presence"; push @event, "3:state:T: $temp F: $fanSpeed SP: $setpoint P: $presence";
EnOcean_ReadingScaled($hash, "setpoint", 0, 255); push @event, "3:setpointScaled:" . EnOcean_ReadingScaled($hash, $setpoint, 0, 255);
} elsif($st eq "tempHumiSensor.02") { } elsif($st eq "tempHumiSensor.02") {
# Temperatur and Humidity Sensor(EEP A5-04-02) # Temperatur and Humidity Sensor(EEP A5-04-02)
@ -2368,18 +2480,25 @@ EnOcean_TimerSet($)
sub sub
EnOcean_ReadingScaled($$$$) EnOcean_ReadingScaled($$$$)
{ {
my ($hash, $readingName, $readingMin, $readingMax) = @_; my ($hash, $readingVal, $readingMin, $readingMax) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $readingVal = ReadingsVal($hash->{NAME}, $readingName, undef); my $valScaled;
# my $readingVal = ReadingsVal($hash->{NAME}, $readingName, undef);
my $scaleDecimals = AttrVal($name, "scaleDecimals", undef);
my $scaleMin = AttrVal($name, "scaleMin", undef); my $scaleMin = AttrVal($name, "scaleMin", undef);
my $scaleMax = AttrVal($name, "scaleMax", undef); my $scaleMax = AttrVal($name, "scaleMax", undef);
if (defined $scaleMax && defined $scaleMin && if (defined $scaleMax && defined $scaleMin &&
$scaleMax =~ m/^[+-]?\d+(\.\d+)?$/ && $scaleMax =~ m/^[+-]?\d+(\.\d+)?$/) { $scaleMax =~ m/^[+-]?\d+(\.\d+)?$/ && $scaleMax =~ m/^[+-]?\d+(\.\d+)?$/) {
my $valScaled = ($readingMin*$scaleMax-$scaleMin*$readingMax)/ $valScaled = ($readingMin*$scaleMax-$scaleMin*$readingMax)/
($readingMin-$readingMax)+ ($readingMin-$readingMax)+
($scaleMin-$scaleMax)/($readingMin-$readingMax)*$readingVal; ($scaleMin-$scaleMax)/($readingMin-$readingMax)*$readingVal;
readingsSingleUpdate($hash, $readingName."Scaled", $valScaled, 1); # readingsSingleUpdate($hash, $readingName."Scaled", $valScaled, 1);
} }
if (defined $scaleDecimals && $scaleDecimals =~ m/^[0-9]?$/) {
$scaleDecimals = "%0." . $scaleDecimals . "f";
$valScaled = sprintf "$scaleDecimals", $valScaled;
}
return $valScaled;
} }
# Undef # Undef
@ -2776,17 +2895,17 @@ EnOcean_Undef($$)
<li>down td/s ta/s<br> <li>down td/s ta/s<br>
issue roll down command</li> issue roll down command</li>
<li>position position/% &alpha;/&#176<br> <li>position position/% &alpha;/&#176<br>
drive blinds to postion with angle value</li> drive blinds to position with angle value</li>
<li>stop<br> <li>stop<br>
issue blinds stops command</li> issue blinds stops command</li>
<li>runtimeSet tu/s td/s<br> <li>runtimeSet tu/s td/s<br>
set runtime parameter</li> set runtime parameter</li>
<li>angleSet ta/s<br> <li>angleSet ta/s<br>
set angle configuration</li> set angle configuration</li>
<li>positionMinMax positionMin/% positionMin/%<br> <li>positionMinMax positionMin/% positionMax/%<br>
set Min, Max values for position</li> set min, max values for position</li>
<li>angleMinMax &alpha;s/&#176 &alpha;o/&#176<br> <li>angleMinMax &alpha;o/&#176 &alpha;s/&#176<br>
set slat angle for Shut und Open position</li> set slat angle for open and shut position</li>
<li>positionLogic normal|inverse<br> <li>positionLogic normal|inverse<br>
set position logic</li> set position logic</li>
</ul><br> </ul><br>
@ -2798,7 +2917,7 @@ EnOcean_Undef($$)
Angle Time Range: ta = 0 s ... 25.5 s<br> Angle Time Range: ta = 0 s ... 25.5 s<br>
Runtime value for the sunblind reversion time. Select the time to revolve Runtime value for the sunblind reversion time. Select the time to revolve
the sunblind from one slat angle end position to the other end position.<br> the sunblind from one slat angle end position to the other end position.<br>
Slat Angle: &alpha;|&alpha;s|&alpha;o = -180 &#176 ... 180 &#176<br> Slat Angle: &alpha;|&alpha;o|&alpha;s = -180 &#176 ... 180 &#176<br>
Position Logic, normal: Blinds fully opens corresponds to Position = 0 %<br> Position Logic, normal: Blinds fully opens corresponds to Position = 0 %<br>
Position Logic, inverse: Blinds fully opens corresponds to Position = 100 %<br> Position Logic, inverse: Blinds fully opens corresponds to Position = 100 %<br>
The attr subType must be gateway and gwCmd must be blindCmd. The profile The attr subType must be gateway and gwCmd must be blindCmd. The profile
@ -2815,18 +2934,30 @@ EnOcean_Undef($$)
where <code>value</code> is where <code>value</code> is
<li>teach<br> <li>teach<br>
initiate teach-in mode</li> initiate teach-in mode</li>
<li>up [position/%]<br> <li>opens<br>
issue blinds opens command</li>
<li>up tu/s<br>
issue roll up command</li> issue roll up command</li>
<li>down [position/%]<br> <li>closes<br>
issue blinds closes command</li>
<li>down td/s<br>
issue roll down command</li> issue roll down command</li>
<li>position position/%<br> <li>position position/% [&alpha;/&#176]<br>
set shutter to position</li> drive blinds to position with angle value</li>
<li>stop<br> <li>stop<br>
issue stop command</li> issue stop command</li>
</ul><br> </ul><br>
Set attr subType to manufProfile, manufID to 00D and attr model to Runtime Range: tu|td = 1 s ... 255 s<br>
FSB14|FSB61|FSB70 manually.<br> Position Range: position = 0 % ... 100 %<br>
Use the sensor type "Szenentaster/PC" for Eltako devices. Slat Angle Range: &alpha; = -180 &#176 ... 180 &#176<br>
Angle Time Range: ta = 0 s ... 6 s<br>
The devive can only fully controlled if the attributes <a href="#angleMax">angleMax</a>,
<a href="#angleMin">angleMin</a>, <a href="#angleTime">angleTime</a>,
<a href="#shutTime">shutTime</a> and <a href="#shutTimeCloses">shutTimeCloses</a>,
are set correctly.
Set attr subType to manufProfile, manufID to 00D and attr model to
FSB14|FSB61|FSB70 manually.<br>
Use the sensor type "Szenentaster/PC" for Eltako devices.
</li> </li>
<br><br> <br><br>
@ -2855,18 +2986,26 @@ EnOcean_Undef($$)
<a name="EnOceanattr"></a> <a name="EnOceanattr"></a>
<b>Attributes</b> <b>Attributes</b>
<ul> <ul>
<ul> <ul>
<li><a name="actualTemp">actualTemp</a> t/&#176C<br> <li><a name="actualTemp">actualTemp</a> t/&#176C<br>
The value of the actual temperature, used when controlling MD15 devices. The value of the actual temperature, used when controlling MD15 devices.
Should by filled via a notify from a distinct temperature sensor. If Should by filled via a notify from a distinct temperature sensor. If
absent, the reported temperature from the MD15 is used. absent, the reported temperature from the MD15 is used.
</li> </li>
<li><a name="angleMax">angleMax</a> &alpha;s/&#176, [&alpha;s] = -180 ... 180, 90 is default.<br>
Slat angle end position maximum.<br>
angleMax is supported for shutter.<br>
</li>
<li><a name="angleMin">angleMin</a> &alpha;o/&#176, [&alpha;o] = -180 ... 180, -90 is default.<br>
Slat angle end position minimum.<br>
angleMin is supported for shutter.<br>
</li>
<li><a name="angleTime">angleTime</a> t/s, [angleTime] = 0 ... 6, 0 is default.<br>
Runtime value for the sunblind reversion time. Select the time to revolve
the sunblind from one slat angle end position to the other end position.<br>
angleTime is supported for shutter.<br>
</li>
<li><a href="#devStateIcon">devStateIcon</a></li> <li><a href="#devStateIcon">devStateIcon</a></li>
<li><a name="dimTime">dimTime</a> relative, [dimTime] = 1 is default.<br>
No ramping or for Eltako dimming speed set on the dimmer if [dimTime] = 0.<br>
Ramping time which fast to low dimming if [dimTime] = 1 ... 100.<br>
dimTime is supported for dimmer.
</li>
<li><a name="dimValueOn">dimValueOn</a> dim/%|last|stored, <li><a name="dimValueOn">dimValueOn</a> dim/%|last|stored,
[dimValueOn] = 100 is default.<br> [dimValueOn] = 100 is default.<br>
Dim value for the command "on".<br> Dim value for the command "on".<br>
@ -2898,6 +3037,9 @@ EnOcean_Undef($$)
EnOcean Repeater in the transmission range of Fhem may forward data messages EnOcean Repeater in the transmission range of Fhem may forward data messages
of the device, if the attribute is set to yes. of the device, if the attribute is set to yes.
</li> </li>
<li><a name="scaleDecimals">scaleDecimals</a> 0 ... 9<br>
Decimal rounding with x digits of the scaled reading setpoint
</li>
<li><a name="scaleMax">scaleMax</a> &lt;floating-point number&gt;<br> <li><a name="scaleMax">scaleMax</a> &lt;floating-point number&gt;<br>
Scaled maximum value of the reading setpoint Scaled maximum value of the reading setpoint
</li> </li>
@ -2911,6 +3053,12 @@ EnOcean_Undef($$)
or roller shutter needs to move from its end position to the other position.<br> or roller shutter needs to move from its end position to the other position.<br>
shutTime is supported for shutter. shutTime is supported for shutter.
</li> </li>
<li><a name="shutTimeCloses">shutTimeCloses</a> t/s, [shutTimeCloses] = 1 ... 255, [shutTime] is default.<br>
Set the attr shutTimeCloses to define the runtime used by the commands opens and closes.
Select a runtime that is at least as long as the value set by the delay switch of the actuator.
<br>
shutTimeCloses is supported for shutter.
</li>
<li><a name="subDef">subDef</a> &lt;EnOcean SenderID&gt;, <li><a name="subDef">subDef</a> &lt;EnOcean SenderID&gt;,
[subDef] = [def] is default.<br> [subDef] = [def] is default.<br>
SenderID (<a href="#TCM">TCM</a> BaseID + offset) to control a bidirectional switch or actor.<br> SenderID (<a href="#TCM">TCM</a> BaseID + offset) to control a bidirectional switch or actor.<br>
@ -3279,7 +3427,7 @@ EnOcean_Undef($$)
<li>temperature: t/&#176C (Sensor Range: t = 0 &#176C ... 40 &#176C)</li> <li>temperature: t/&#176C (Sensor Range: t = 0 &#176C ... 40 &#176C)</li>
<li>state: T: t/&#176C SPT: t/&#176C NR: t/&#176C</li><br> <li>state: T: t/&#176C SPT: t/&#176C NR: t/&#176C</li><br>
</ul><br> </ul><br>
The scaling of the setpoint knob is device- and vendor-specific. Set the The scaling of the setpoint adjustment is device- and vendor-specific. Set the
attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a> attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a>
for the additional scaled reading setpointScaled. Use attribut for the additional scaled reading setpointScaled. Use attribut
<a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br> <a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br>
@ -3300,7 +3448,7 @@ EnOcean_Undef($$)
<li>setpointScaled: &lt;floating-point number&gt;</li> <li>setpointScaled: &lt;floating-point number&gt;</li>
<li>state: T: t/&#176C H: rH/% SP: 0 ... 255 SW: 0|1</li> <li>state: T: t/&#176C H: rH/% SP: 0 ... 255 SW: 0|1</li>
</ul><br> </ul><br>
The scaling of the setpoint knob is device- and vendor-specific. Set the The scaling of the setpoint adjustment is device- and vendor-specific. Set the
attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a> attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a>
for the additional scaled reading setpointScaled. Use attribut for the additional scaled reading setpointScaled. Use attribut
<a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br> <a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br>
@ -3319,7 +3467,7 @@ EnOcean_Undef($$)
<li>setpointScaled: &lt;floating-point number&gt;</li> <li>setpointScaled: &lt;floating-point number&gt;</li>
<li>state: T: t/&#176C SP: 0 ... 63 P: absent|present</li> <li>state: T: t/&#176C SP: 0 ... 63 P: absent|present</li>
</ul><br> </ul><br>
The scaling of the setpoint knob is device- and vendor-specific. Set the The scaling of the setpoint adjustment is device- and vendor-specific. Set the
attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a> attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a>
for the additional scaled reading setpointScaled. Use attribut for the additional scaled reading setpointScaled. Use attribut
<a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br> <a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br>
@ -3436,7 +3584,7 @@ EnOcean_Undef($$)
<li>temperature: t/&#176C (Sensor Range: t = 0 &#176C ... 40 &#176C)</li> <li>temperature: t/&#176C (Sensor Range: t = 0 &#176C ... 40 &#176C)</li>
<li>state: T: t/&#176C F: 0|1|2|3|auto SP: 0 ... 255 P: absent|present|disabled</li> <li>state: T: t/&#176C F: 0|1|2|3|auto SP: 0 ... 255 P: absent|present|disabled</li>
</ul><br> </ul><br>
The scaling of the setpoint knob is device- and vendor-specific. Set the The scaling of the setpoint adjustment is device- and vendor-specific. Set the
attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a> attributes <a href="#scaleMax">scaleMax</a> and <a href="#scaleMin">scaleMin</a>
for the additional scaled reading setpointScaled. Use attribut for the additional scaled reading setpointScaled. Use attribut
<a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br> <a href="#userReadings">userReadings</a> to adjust the scaling alternatively.<br>