added smooth volume change feature

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@2056 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
markusbloch 2012-11-02 12:24:27 +00:00
parent 6fffb5c4ac
commit 191a693bc0
2 changed files with 62 additions and 11 deletions

View File

@ -22,12 +22,13 @@ package main;
use strict; use strict;
use warnings; use warnings;
#use Time::HiRes qw(gettimeofday); use Time::HiRes qw(gettimeofday sleep);
sub YAMAHA_AVR_Get($@); sub YAMAHA_AVR_Get($@);
sub YAMAHA_AVR_Define($$); sub YAMAHA_AVR_Define($$);
sub YAMAHA_AVR_GetStatus($); sub YAMAHA_AVR_GetStatus($);
sub YAMAHA_AVR_Undefine($$);
@ -43,16 +44,17 @@ YAMAHA_AVR_Initialize($)
$hash->{DefFn} = "YAMAHA_AVR_Define"; $hash->{DefFn} = "YAMAHA_AVR_Define";
$hash->{UndefFn} = "YAMAHA_AVR_Undefine"; $hash->{UndefFn} = "YAMAHA_AVR_Undefine";
$hash->{AttrList} = "loglevel:0,1,2,3,4,5 subType event-on-update-reading event-on-change-reading"; $hash->{AttrList} = "loglevel:0,1,2,3,4,5 volume-smooth-change:0,1 volume-smooth-time:0,1,2,3,4,5 volume-smooth-steps:1,2,3,4,5,6,7,8,9,10 event-on-update-reading event-on-change-reading";
} }
################################### ###################################
sub sub
YAMAHA_AVR_GetStatus($) YAMAHA_AVR_GetStatus($$)
{ {
my ($hash) = @_; my ($hash, $local) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $power; my $power;
$local = 0 if(!defined($local));
return "" if(!defined($hash->{ADDRESS}) or !defined($hash->{INTERVAL})); return "" if(!defined($hash->{ADDRESS}) or !defined($hash->{INTERVAL}));
@ -89,7 +91,7 @@ YAMAHA_AVR_GetStatus($)
readingsEndUpdate($hash, 1); readingsEndUpdate($hash, 1);
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "YAMAHA_AVR_GetStatus", $hash, 1); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "YAMAHA_AVR_GetStatus", $hash, 1) unless $local == 0;
Log GetLogLevel($name,4), "YAMAHA_AVR $name: $hash->{STATE}"; Log GetLogLevel($name,4), "YAMAHA_AVR $name: $hash->{STATE}";
@ -109,7 +111,7 @@ YAMAHA_AVR_Get($@)
if($what =~ /^(power|input|volume|mute)$/) if($what =~ /^(power|input|volume|mute)$/)
{ {
YAMAHA_AVR_GetStatus($hash); YAMAHA_AVR_GetStatus($hash, 1);
if(defined($hash->{READINGS}{$what})) if(defined($hash->{READINGS}{$what}))
{ {
return $a[0]." ".$what." => ".$hash->{READINGS}{$what}{VAL}; return $a[0]." ".$what." => ".$hash->{READINGS}{$what}{VAL};
@ -229,9 +231,46 @@ YAMAHA_AVR_Set($@)
{ {
if($hash->{STATE} eq "on") if($hash->{STATE} eq "on")
{ {
if(AttrVal($name, "volume-smooth-change", "0") eq "1")
{
my $diff = int(($a[2] - $hash->{READINGS}{volume_level}{VAL}) / AttrVal($hash->{NAME}, "volume-smooth-steps", 5) / 0.5) * 0.5;
my $steps = AttrVal($name, "volume-smooth-steps", 5);
my $current_volume = $hash->{READINGS}{volume_level}{VAL};
my $time = AttrVal($name, "volume-smooth-time", 0);
my $sleep = $time / $steps;
if($diff > 0)
{
Log GetLogLevel($name, 4), "YAMAHA_AV: use smooth volume change (with $steps steps of +$diff volume change each ".sprintf("%.3f", $sleep)." seconds)";
}
else
{
Log GetLogLevel($name, 4), "YAMAHA_AV: use smooth volume change (with $steps steps of $diff volume change each ".sprintf("%.3f", $sleep)." seconds)";
}
# Only if smoohing is really needed (step difference is not zero)
if($diff != 0)
{
for(my $step = 1; $step <= $steps; $step++)
{
Log GetLogLevel($name, 4), "YAMAHA_AV: set volume to ".($current_volume + ($diff * $step))." dB";
SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>".(($current_volume + ($diff * $step))*10)."</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>");
sleep $sleep unless ($time == 0);
}
}
# After complete smoothing, set the real wanted volume
Log GetLogLevel($name, 4), "YAMAHA_AV set volume to ".$a[2]." dB";
SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>".($a[2]*10)."</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>"); SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>".($a[2]*10)."</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>");
} }
else else
{
SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>".($a[2]*10)."</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>");
}
}
else
{ {
return "volume can only be used when device is powered on"; return "volume can only be used when device is powered on";
} }
@ -247,7 +286,7 @@ YAMAHA_AVR_Set($@)
} }
readingsEndUpdate($hash, 1); readingsEndUpdate($hash, 1);
YAMAHA_AVR_GetStatus($hash); YAMAHA_AVR_GetStatus($hash, 1);
return undef; return undef;
} }
@ -312,6 +351,7 @@ YAMAHA_AVR_Define($$)
{ {
$hash->{INTERVAL}=30; $hash->{INTERVAL}=30;
} }
$attr{$name}{"volume-smooth-change"} = "1";
InternalTimer(gettimeofday()+2, "YAMAHA_AVR_GetStatus", $hash, 0); InternalTimer(gettimeofday()+2, "YAMAHA_AVR_GetStatus", $hash, 0);

View File

@ -10101,7 +10101,8 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
<br> <br>
</ul> </ul>
<a name="YAMAHA_AVR"></a> <a name="
YAMAHA_AVR"></a>
<h3>YAMAHA_AVR</h3> <h3>YAMAHA_AVR</h3>
<ul> <ul>
@ -10174,7 +10175,17 @@ volume</pre>
<li><a href="#loglevel">loglevel</a></li> <li><a href="#loglevel">loglevel</a></li>
<li><a href="#event-on-update-reading">event-on-update-reading</a></li> <li><a href="#event-on-update-reading">event-on-update-reading</a></li>
<li><a href="#event-on-change-reading">event-on-change-reading</a></li> <li><a href="#event-on-change-reading">event-on-change-reading</a></li>
<li><a name="volume-smooth-change">volume-smooth-change</a><li><br>
Optional attribute to activate a smooth volume change.
<br><br>
Possible values: 0 => off , 1 => on
<li><a name="volume-smooth-steps">volume-smooth-steps</a></li><br>
Optional attribute to define the number of volume changes between the
current and the desired volume. Default value is 5 steps
<li><a name="volume-smooth-time">volume-smooth-time</a></li><br>
Optional attribute to define the time window for the volume smoothing in seconds.
For example the value 2 means the smooth process in general should take 2 seconds.
The value 0 means "as fast as possible". Default value is 0.
</ul> </ul>
<br> <br>
<b>Implementator's note</b> <b>Implementator's note</b>