mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
new module YAMAHA_AVR added
git-svn-id: https://svn.fhem.de/fhem/trunk@2053 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
fcbb32c8d4
commit
e597893258
344
fhem/FHEM/71_YAMAHA_AVR.pm
Executable file
344
fhem/FHEM/71_YAMAHA_AVR.pm
Executable file
@ -0,0 +1,344 @@
|
||||
#
|
||||
# Module: YAMAHA_AVR
|
||||
#
|
||||
# An FHEM Perl module for controlling Yamaha AV-Receivers
|
||||
# via network connection. As the interface is standardized
|
||||
# within all Yamaha AV-Receivers, this module should work
|
||||
# with any receiver which has an ethernet or wlan connection.
|
||||
#
|
||||
# Currently supported are: power (on|off)
|
||||
# input (hdmi1|hdmi2|...)
|
||||
# volume (-50 ... 10)
|
||||
# mute (on|off)
|
||||
#
|
||||
# Of course there are more possibilities than these 4 commands.
|
||||
# But in my oppinion these are the most relevant usecases within FHEM.
|
||||
#
|
||||
# For more commands, please email me.
|
||||
#
|
||||
# Written by Notausstieg (Notausstieg0309[at]googlemail[dot]com)
|
||||
#
|
||||
# 29.10.2012
|
||||
#
|
||||
###################################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
#use Time::HiRes qw(gettimeofday);
|
||||
|
||||
|
||||
sub YAMAHA_AVR_Get($@);
|
||||
sub YAMAHA_AVR_Define($$);
|
||||
sub YAMAHA_AVR_GetStatus($);
|
||||
|
||||
|
||||
|
||||
|
||||
###################################
|
||||
sub
|
||||
YAMAHA_AVR_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{GetFn} = "YAMAHA_AVR_Get";
|
||||
$hash->{SetFn} = "YAMAHA_AVR_Set";
|
||||
$hash->{DefFn} = "YAMAHA_AVR_Define";
|
||||
$hash->{UndefFn} = "YAMAHA_AVR_Undefine";
|
||||
|
||||
$hash->{AttrList} = "loglevel:0,1,2,3,4,5 subType event-on-update-reading event-on-change-reading";
|
||||
}
|
||||
|
||||
###################################
|
||||
sub
|
||||
YAMAHA_AVR_GetStatus($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $power;
|
||||
|
||||
return "" if(!defined($hash->{ADDRESS}) or !defined($hash->{INTERVAL}));
|
||||
|
||||
my $device = $hash->{ADDRESS};
|
||||
my $return = SendCommand($device,"<YAMAHA_AV cmd=\"GET\"><Main_Zone><Basic_Status>GetParam</Basic_Status></Main_Zone></YAMAHA_AV>");
|
||||
|
||||
|
||||
return "Can't submit command. please see fhem logfile for further information" if(not defined($return) or length($return) == 0);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
|
||||
if($return =~ /<Power>(.+)<\/Power>/)
|
||||
{
|
||||
$power = $1;
|
||||
readingsUpdate($hash, "power", lc($power));
|
||||
if($power eq "Standby")
|
||||
{
|
||||
$power = "Off";
|
||||
}
|
||||
|
||||
$hash->{STATE} = lc($power);
|
||||
|
||||
}
|
||||
if($return =~ /<Volume><Lvl><Val>(.+)<\/Val><Exp>(.+)<\/Exp><Unit>.+<\/Unit><\/Lvl><Mute>(.+)<\/Mute><\/Volume>/)
|
||||
{
|
||||
readingsUpdate($hash, "volume_level", ($1 / 10 ** $2));
|
||||
readingsUpdate($hash, "mute", lc($3));
|
||||
}
|
||||
|
||||
if($return =~ /<Input_Sel>(.+)<\/Input_Sel>/)
|
||||
{
|
||||
readingsUpdate($hash, "input", lc($1));
|
||||
}
|
||||
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "YAMAHA_AVR_GetStatus", $hash, 1);
|
||||
|
||||
Log GetLogLevel($name,4), "YAMAHA_AVR $name: $hash->{STATE}";
|
||||
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
###################################
|
||||
sub
|
||||
YAMAHA_AVR_Get($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $what;
|
||||
|
||||
return "argument is missing" if(int(@a) != 2);
|
||||
$what = $a[1];
|
||||
|
||||
|
||||
if($what =~ /^(power|input|volume|mute)$/)
|
||||
{
|
||||
YAMAHA_AVR_GetStatus($hash);
|
||||
if(defined($hash->{READINGS}{$what}))
|
||||
{
|
||||
return $a[0]." ".$what." => ".$hash->{READINGS}{$what}{VAL};
|
||||
}
|
||||
else
|
||||
{
|
||||
return "no such reading: $what";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Unknown argument $what, choose one of param power input volume mute get";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
sub
|
||||
YAMAHA_AVR_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $address = $hash->{ADDRESS};
|
||||
my $result = "";
|
||||
my $inputs_piped = $hash->{INPUTS};
|
||||
|
||||
return "No Argument given" if(!defined($a[1]));
|
||||
|
||||
my $what = $a[1];
|
||||
my $usage = "Unknown argument $what, choose one of on off volume:slider,-80,1,16 input:".$hash->{INPUTS}." mute:on,off statusRequest";
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
if($what eq "on")
|
||||
{
|
||||
$result = SendCommand($address, "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>");
|
||||
if($result =~ /RC="0"/ and $result =~ /<Power><\/Power>/)
|
||||
{
|
||||
# As the receiver startup takes about 5 seconds, the status will be already set, if the return code of the command is 0.
|
||||
readingsUpdate($hash, "power", "on");
|
||||
$hash->{STATE} = "on";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
elsif($what eq "off")
|
||||
{
|
||||
SendCommand($address, "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>");
|
||||
}
|
||||
elsif($what eq "input")
|
||||
{
|
||||
if(defined($a[2]))
|
||||
{
|
||||
if($hash->{STATE} eq "on")
|
||||
{
|
||||
$inputs_piped =~ s/,/|/g;
|
||||
|
||||
if($a[2] =~ /^($inputs_piped)$/)
|
||||
{
|
||||
if($a[2] eq "netradio")
|
||||
{
|
||||
$result = SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>NET RADIO</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
|
||||
}
|
||||
elsif($a[2] eq "airplay")
|
||||
{
|
||||
$result = SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>AirPlay</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = SendCommand($address,"<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>".uc($a[2])."</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
|
||||
}
|
||||
|
||||
if(not $result =~ /RC="0"/)
|
||||
{
|
||||
# if the returncode isn't 0, than the command was not successful
|
||||
return "Could not set input to ".$a[2].". Please use only available inputs on your specific receiver";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $usage;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "input can only be used when device is powered on";
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($what eq "mute")
|
||||
{
|
||||
if(defined($a[2]))
|
||||
{
|
||||
if($hash->{STATE} eq "on")
|
||||
{
|
||||
if( $a[2] eq "on")
|
||||
{
|
||||
SendCommand($address, "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Mute>On</Mute></Volume></Main_Zone></YAMAHA_AV>");
|
||||
}
|
||||
elsif($a[2] eq "off")
|
||||
{
|
||||
SendCommand($address, "<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Mute>Off</Mute></Volume></Main_Zone></YAMAHA_AV>");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return $usage;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "mute can only used when device is powered on";
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($what eq "volume")
|
||||
{
|
||||
if(defined($a[2]) && $a[2] >= -80 && $a[2] < 16)
|
||||
{
|
||||
if($hash->{STATE} eq "on")
|
||||
{
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($what eq "statusRequest")
|
||||
{
|
||||
# Will be executed on the end of this function anyway, so no need to call it specificly
|
||||
}
|
||||
else
|
||||
{
|
||||
return $usage;
|
||||
}
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
YAMAHA_AVR_GetStatus($hash);
|
||||
return undef;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
sub
|
||||
YAMAHA_AVR_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $name = $hash->{NAME};
|
||||
my @inputs;
|
||||
|
||||
if(! @a >= 3)
|
||||
{
|
||||
my $msg = "wrong syntax: define <name> YAMAHA_AVR <ip-or-hostname> [<statusinterval>]";
|
||||
Log 2, $msg;
|
||||
return $msg;
|
||||
}
|
||||
|
||||
|
||||
my $address = $a[2];
|
||||
|
||||
my $response = GetFileFromURL("http://".$address."/YamahaRemoteControl/desc.xml");
|
||||
if($response =~ /<Unit_Description.* Unit_Name="(.+?)">/)
|
||||
{
|
||||
$hash->{MODEL} = $1;
|
||||
}
|
||||
|
||||
$hash->{ADDRESS} = $address;
|
||||
|
||||
$response = SendCommand($address, "<YAMAHA_AV cmd=\"GET\"><Main_Zone><Input><Input_Sel_Item>GetParam</Input_Sel_Item></Input></Main_Zone></YAMAHA_AV>");
|
||||
$response =~ s/></>\n</g;
|
||||
@inputs = split("\n", $response);
|
||||
|
||||
foreach (sort @inputs)
|
||||
{
|
||||
if($_ =~ /<Param>(.+?)<\/Param>/ and not $1 =~ /iPod/)
|
||||
{
|
||||
if(defined($hash->{INPUTS}) and length($hash->{INPUTS}) > 0)
|
||||
{
|
||||
$hash->{INPUTS} .= ",";
|
||||
}
|
||||
if($1 eq "NET RADIO")
|
||||
{
|
||||
$hash->{INPUTS} .= "netradio";
|
||||
}
|
||||
else
|
||||
{
|
||||
$hash->{INPUTS} .= lc($1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(defined($a[3]) and $a[3] > 0)
|
||||
{
|
||||
$hash->{INTERVAL}=$a[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
$hash->{INTERVAL}=30;
|
||||
}
|
||||
|
||||
InternalTimer(gettimeofday()+2, "YAMAHA_AVR_GetStatus", $hash, 0);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#############################
|
||||
sub
|
||||
SendCommand($$)
|
||||
{
|
||||
my($address, $command) = @_;
|
||||
|
||||
# In case any URL changes must be made, this part is separated in this function".
|
||||
return GetFileFromURL("http://".$address."/YamahaRemoteControl/ctrl", 10, "<?xml version=\"1.0\" encoding=\"utf-8\"?>".$command);
|
||||
}
|
||||
|
||||
#############################
|
||||
sub
|
||||
YAMAHA_AVR_Undefine($$)
|
||||
{
|
||||
my($hash, $name) = @_;
|
||||
RemoveInternalTimer($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
@ -136,7 +136,7 @@
|
||||
<a href="#SISPM">SISPM</a>
|
||||
<a href="#SIS_PMS">SIS_PMS</a>
|
||||
<a href="#SML">SML</a>
|
||||
<a href="#STV">STV</a>
|
||||
<a href="#STV">STV</a>
|
||||
<a href="#TCM">TCM</a>
|
||||
<a href="#TellStick">TellStick</a>
|
||||
<a href="#TRX">TRX</a>
|
||||
@ -158,6 +158,7 @@
|
||||
<a href="#WS3600">WS3600</a>
|
||||
<a href="#X10">X10</a>
|
||||
<a href="#xxLG7000">xxLG7000</a>
|
||||
<a href="#YAMAHA_AVR">YAMAHA_AVR</a>
|
||||
<a href="#ZWDongle">ZWDongle</a>
|
||||
<a href="#ZWave">ZWave</a>
|
||||
|
||||
@ -10100,6 +10101,91 @@ KlikAanKlikUit, NEXA, CHACON, HomeEasy UK. <br> You need to define an RFXtrx433
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="YAMAHA_AVR"></a>
|
||||
<h3>YAMAHA_AVR</h3>
|
||||
<ul>
|
||||
|
||||
<a name="YAMAHA_AVRdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> YAMAHA_AVR <ip-address> [<status_interval>]</code>
|
||||
<br><br>
|
||||
|
||||
This module controls AV receiver from Yamaha via network connection. You are able
|
||||
to power your AV reveiver on and off, query it's power state,
|
||||
select the input (HDMI, AV, AirPlay, internet radio, Tuner, ...), select the volume
|
||||
or mute/unmute the volume.<br><br>
|
||||
Defining a YAMAHA_AVR device will schedule an internal task (interval can be set
|
||||
with optional parameter <status_interval> in seconds, if not set, the value is 60 seconds), which periodically reads
|
||||
the status of the AV receiver (power state, selected input, volume and mute status)
|
||||
and triggers notify/filelog commands.<br><br>
|
||||
|
||||
Example:
|
||||
<ul>
|
||||
<code>define AV_Receiver YAMAHA_AVR 192.168.0.10</code><br>
|
||||
</ul>
|
||||
<a name="YAMAHA_AVRset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<code>set <name> <command> [<parameter>]</code>
|
||||
<br><br>
|
||||
Currently, the following commands are defined; the available inputs are depending on the used receiver.
|
||||
The module only offers the real available inputs. The following input commands are just an example and can differ.
|
||||
|
||||
<pre>on
|
||||
off
|
||||
input hdmi1
|
||||
input hdmi2
|
||||
input hdmi3
|
||||
input hdmi4
|
||||
input av1
|
||||
input av2
|
||||
input av3
|
||||
input av3
|
||||
input av4
|
||||
input av5
|
||||
input av6
|
||||
input usb
|
||||
input airplay
|
||||
input tuner
|
||||
input v-aux
|
||||
input audio
|
||||
input server
|
||||
volume -80..16 (volume between -80 and +16 dB)
|
||||
mute on
|
||||
mute off</pre>
|
||||
</ul>
|
||||
|
||||
<a name="YAMAHA_AVRget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<code>get <name> <what></code>
|
||||
<br><br>
|
||||
Currently, the following commands are defined and return the current state of the receiver.
|
||||
<pre>power
|
||||
input
|
||||
mute
|
||||
volume</pre>
|
||||
</ul>
|
||||
<a name="YAMAHA_AVRattr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
|
||||
<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-change-reading">event-on-change-reading</a></li>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
<b>Implementator's note</b>
|
||||
<ul>
|
||||
The module is only usable if you activate "Network Standby" on your receiver.<br><br>
|
||||
Technically there are many more commands and readings possible, but I think
|
||||
these are the main usecases within FHEM.
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="ZWDongle"></a>
|
||||
<h3>ZWDongle</h3>
|
||||
<ul>
|
||||
|
Loading…
Reference in New Issue
Block a user