36_Shelly.pm: Version 1.3 mit erweiterten Attributen

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@17402 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
phenning 2018-09-25 18:41:48 +00:00
parent 07bb4c388f
commit 568b10ea8e

View File

@ -38,7 +38,7 @@ use vars qw{%attr %defs};
sub Log($$); sub Log($$);
#-- globals on start #-- globals on start
my $version = "1.21"; my $version = "1.3";
#-- these we may get on request #-- these we may get on request
my %gets = ( my %gets = (
@ -61,7 +61,7 @@ my %setsrol = (
"closed:noArg" => "C", "closed:noArg" => "C",
"open:noArg" => "O", "open:noArg" => "O",
"stop:noArg" => "S", "stop:noArg" => "S",
"pct" => "P" "pct:slider,0,1,100" => "P"
); );
my %shelly_models = ( my %shelly_models = (
@ -100,7 +100,7 @@ sub Shelly_Initialize ($) {
#$hash->{NotifyFn} = "Shelly_Notify"; #$hash->{NotifyFn} = "Shelly_Notify";
#$hash->{InitFn} = "Shelly_Init"; #$hash->{InitFn} = "Shelly_Init";
$hash->{AttrList}= "verbose model:".join(",",(keys %shelly_models))." mode:relay,roller defchannel maxtime maxpower interval ". $hash->{AttrList}= "verbose model:".join(",",(keys %shelly_models))." mode:relay,roller defchannel maxtime maxpower interval pct100:open:closed ".
$readingFnAttributes; $readingFnAttributes;
} }
@ -248,6 +248,13 @@ sub Shelly_Attr(@) {
} }
Shelly_configure($hash,"settings?maxtime=".$attrVal); Shelly_configure($hash,"settings?maxtime=".$attrVal);
#---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName eq "pct100") ) {
if( ($model ne "shelly2") || ($mode ne "roller" ) ){
Log3 $name,1,"[Shelly_Attr] setting the pct100 attribute only works for model=shelly2 and mode=roller";
return
}
#--------------------------------------- #---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName eq "interval") ) { }elsif ( ($cmd eq "set") && ($attrName eq "interval") ) {
#-- update timer #-- update timer
@ -400,6 +407,7 @@ sub Shelly_Set ($@) {
#-- we have a Shelly 2 roller type device #-- we have a Shelly 2 roller type device
}elsif( ($model eq "shelly2") && ($mode eq "roller") ){ }elsif( ($model eq "shelly2") && ($mode eq "roller") ){
my $channel = $value; my $channel = $value;
my $max=AttrVal($name,"maxtime",undef);
#-- WEB asking for command list #-- WEB asking for command list
if( $cmd eq "?" ) { if( $cmd eq "?" ) {
$newkeys = join(" ", sort keys %setsrol); $newkeys = join(" ", sort keys %setsrol);
@ -414,26 +422,39 @@ sub Shelly_Set ($@) {
if( $cmd eq "closed" ){ if( $cmd eq "closed" ){
Shelly_updown($hash,"?go=close"); Shelly_updown($hash,"?go=close");
$hash->{DURATION} = $max;
}elsif( $cmd eq "open" ){ }elsif( $cmd eq "open" ){
Shelly_updown($hash,"?go=open"); Shelly_updown($hash,"?go=open");
$hash->{DURATION} = $max;
}elsif( $cmd eq "stop" ){ }elsif( $cmd eq "stop" ){
Shelly_updown($hash,"?go=stop"); Shelly_updown($hash,"?go=stop");
$hash->{DURATION} = 0;
}elsif( $cmd eq "pct" ){ }elsif( $cmd eq "pct" ){
my $tpct = $value; my $tpct = $value;
my $pos = ReadingsVal($name,"position",""); my $pos = ReadingsVal($name,"position","");
my $pct = ReadingsVal($name,"pct",undef); my $pct = ReadingsVal($name,"pct",undef);
my $max=AttrVal($name,"maxtime",undef);
if( !$max ){ if( !$max ){
$msg = "Error: pct value can be set only if maxtime attribute is set properly"; $msg = "Error: pct value can be set only if maxtime attribute is set properly";
Log3 $name,1,"[Shelly_Set] ".$msg; Log3 $name,1,"[Shelly_Set] ".$msg;
return $msg return $msg
} }
my $normal = (AttrVal($name,"pct100","open") eq "open");
if( $pos eq "open" ){ if( $pos eq "open" ){
#-- 100% = open
if($normal){
$time = int(($max*(100-$tpct))/10)/10; $time = int(($max*(100-$tpct))/10)/10;
}else{
$time = int(($max*$pct)/10)/10;
}
$cmd = "?go=close&duration=".$time; $cmd = "?go=close&duration=".$time;
}elsif( $pos eq "closed" ){ }elsif( $pos eq "closed" ){
#-- 100% = open
if($normal){
$time = int(($max*$tpct)/10)/10; $time = int(($max*$tpct)/10)/10;
}else{
$time = int(($max*(100-$tpct))/10)/10;
}
$cmd = "?go=open&duration=".$time; $cmd = "?go=open&duration=".$time;
}else{ }else{
if( !defined($pct) ){ if( !defined($pct) ){
@ -443,11 +464,21 @@ sub Shelly_Set ($@) {
} }
if( $tpct > $pct ){ if( $tpct > $pct ){
$time = int(($max*($tpct-$pct))/10)/10; $time = int(($max*($tpct-$pct))/10)/10;
#-- 100% = open
if($normal){
$cmd = "?go=open&duration=".$time; $cmd = "?go=open&duration=".$time;
}else{ }else{
$time = int(($max*($pct-$tpct))/10)/10;
$cmd = "?go=close&duration=".$time; $cmd = "?go=close&duration=".$time;
} }
}else{
$time = int(($max*($pct-$tpct))/10)/10;
#-- 100% = open
if($normal){
$cmd = "?go=close&duration=".$time;
}else{
$cmd = "?go=open&duration=".$time;
}
}
} }
$hash->{MOVING} = 1; $hash->{MOVING} = 1;
$hash->{DURATION} = $time; $hash->{DURATION} = $time;
@ -621,10 +652,11 @@ sub Shelly_Set ($@) {
my $pct; my $pct;
#-- renormalize position #-- renormalize position
my $normal = (AttrVal($name,"pct100","open") eq "open");
if( $rstate eq "open" ){ if( $rstate eq "open" ){
$pct = 100; $pct = $normal?100:0;
}elsif( $rstate eq "closed" ){ }elsif( $rstate eq "closed" ){
$pct = 0; $pct = $normal?0:100;
}else{ }else{
$pct = ReadingsVal($name,"pct",undef); $pct = ReadingsVal($name,"pct",undef);
$pct = "unknown" $pct = "unknown"
@ -728,31 +760,55 @@ sub Shelly_Set ($@) {
} }
} }
my ($rstate,$rpower,$rstopreason,$rlastdir,$pct); my ($rstate,$rpower,$rstopreason,$rlastdir,$pct,$normal,$pctopen,$pctclose);
#-- immediately after moving blind #-- immediately after moving blind
if( $cmd ne ""){ if( $cmd ne ""){
$rstate = "moving"; $rstate = "moving";
$pct = ReadingsVal($name,"pct",undef); $pct = ReadingsVal($name,"pct",undef);
$normal = (AttrVal($name,"pct100","open") eq "open");
$pctopen = ($normal && ($pct == 100)) || (!$normal && ($pct == 0));
$pctclose= ($normal && ($pct == 0)) || (!$normal && ($pct == 100));
#-- timer command #-- timer command
if( index($cmd,"&") ne "-1"){ if( index($cmd,"&") ne "-1"){
my $max = AttrVal($name,"maxtime",undef); my $max = AttrVal($name,"maxtime",undef);
my $dir = substr($cmd,4,index($cmd,"&")-4); my $dir = substr($cmd,4,index($cmd,"&")-4);
my $dur = substr($cmd,index($cmd,"&")+10); my $dur = substr($cmd,index($cmd,"&")+10);
if( (!defined($pct) && ($dir eq "close")) || ($pct == 100) ){ if( (!defined($pct) && ($dir eq "close")) || $pctopen ){
#-- 100% = open
if( $normal ){
$pct = 100-int((100*$dur)/$max); $pct = 100-int((100*$dur)/$max);
}else{
$pct = int((100*$dur)/$max);
}
}elsif( $dir eq "close" ){ }elsif( $dir eq "close" ){
#-- 100% = open
if( $normal ){
$pct = $pct-int((100*$dur)/$max); $pct = $pct-int((100*$dur)/$max);
}else{
$pct = $pct+int((100*$dur)/$max);
}
}elsif( (!defined($pct) && ($dir eq "open")) || $pctclose ){
#-- 100% = open
if( $normal ){
$pct = int((100*$dur)/$max);
}else{
$pct = 100-int((100*$dur)/$max);
}
}elsif( $dir eq "open" ){
#-- 100% = open
if( $normal ){
$pct = $pct+int((100*$dur)/$max);
}else{
$pct = $pct-int((100*$dur)/$max);
}
}
}
$pct = 0 $pct = 0
if( $pct < 0); if( $pct < 0);
}elsif( (!defined($pct) && ($dir eq "open")) || ($pct == 0) ){
$pct = int((100*$dur)/$max);
}elsif( $dir eq "open" ){
$pct = $pct+int((100*$dur)/$max);
$pct = 100 $pct = 100
if( $pct > 100); if( $pct > 100);
}
}
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"state","OK"); readingsBulkUpdate($hash,"state","OK");
readingsBulkUpdate($hash,"position",$rstate); readingsBulkUpdate($hash,"position",$rstate);
@ -1004,6 +1060,8 @@ sub Shelly_Set ($@) {
<ul> <ul>
<li><a name="shelly_maxtime"><code>attr &lt;name&gt; maxtime <float> </code></a> <li><a name="shelly_maxtime"><code>attr &lt;name&gt; maxtime <float> </code></a>
<br />time needed for a complete drive upward or downward</li> <br />time needed for a complete drive upward or downward</li>
<li><a name="shelly_pct100"><code>attr &lt;name&gt; pct100 open|closed (default:open) </code></a>
<br />is pct=100 open or closed ? </li>
</ul> </ul>
<br/>Standard attributes <br/>Standard attributes
<ul> <ul>