2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 03:06:37 +00:00

70_BRAVIA.pm: fix volume info from headphone; new package FHEM::BRAVIA; PBP changes

git-svn-id: https://svn.fhem.de/fhem/trunk@23605 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
vuffiraa 2021-01-24 11:17:25 +00:00
parent f5d73a31e1
commit 3fc724e9be
4 changed files with 183 additions and 121 deletions

View File

@ -1,5 +1,7 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- bugfix: 70_BRAVIA: fix volume info from headphone
- change: 70_BRAVIA: new package FHEM::BRAVIA, PBP changes
- feature: 52_I2C_ADS1x1x: New module for TI AD Converters - feature: 52_I2C_ADS1x1x: New module for TI AD Converters
- bugfix: 51_MOBILEALERTS: Perl Warnings and Init RainSensor - bugfix: 51_MOBILEALERTS: Perl Warnings and Init RainSensor
- bugfix: 57_Calendar: correct event selection for - bugfix: 57_Calendar: correct event selection for

View File

@ -29,35 +29,7 @@
# #
############################################################################## ##############################################################################
package main; package FHEM::BRAVIA;
use strict;
use warnings;
use vars qw( $readingFnAttributes );
###################################
sub BRAVIA_Initialize($) {
my ($hash) = @_;
Log3($hash, 5, "BRAVIA_Initialize: Entering");
$hash->{GetFn} = "BRAVIA::Get";
$hash->{SetFn} = "BRAVIA::Set";
$hash->{DefFn} = "BRAVIA::Define";
$hash->{UndefFn} = "BRAVIA::Undefine";
$hash->{AttrList} = "disable:0,1 macaddr:textField channelsMax:textField wolBroadcast:textField " . $readingFnAttributes;
$::data{RC_layout}{BRAVIA_SVG} = "BRAVIA::RClayout_SVG";
$::data{RC_layout}{BRAVIA} = "BRAVIA::RClayout";
$::data{RC_makenotify}{BRAVIA} = "BRAVIA::RCmakenotify";
return;
}
package BRAVIA;
use strict; use strict;
use warnings; use warnings;
@ -74,7 +46,7 @@ use MIME::Base64;
use XML::Simple qw(:strict); use XML::Simple qw(:strict);
use IO::Socket; use IO::Socket;
require "HttpUtils.pm"; require HttpUtils;
## Import der FHEM Funktionen ## Import der FHEM Funktionen
BEGIN { BEGIN {
@ -85,29 +57,56 @@ BEGIN {
fhemTimeLocal fhemTimeLocal
InternalTimer InternalTimer
InternalVal InternalVal
readingsSingleUpdate Log3
readingFnAttributes
ReadingsAge
readingsBeginUpdate
readingsBulkUpdate readingsBulkUpdate
readingsBulkUpdateIfChanged readingsBulkUpdateIfChanged
readingsBeginUpdate
readingsDelete readingsDelete
readingsSingleUpdate
readingsEndUpdate readingsEndUpdate
ReadingsAge
ReadingsNum ReadingsNum
ReadingsTimestamp ReadingsTimestamp
ReadingsVal ReadingsVal
RemoveInternalTimer RemoveInternalTimer
Log3
)) ))
}; };
sub Set($@); GP_Export(
sub Get($@); qw(
sub GetStatus($;$); Initialize
sub Define($$); )
sub Undefine($$); );
################################### ###################################
sub Define($$) { sub Initialize {
my ($hash) = @_;
Log3($hash, 5, "BRAVIA_Initialize: Entering");
$hash->{GetFn} = \&Get;
$hash->{SetFn} = \&Set;
$hash->{DefFn} = \&Define;
$hash->{UndefFn} = \&Undefine;
$hash->{AttrList} =
"disable:0,1 "
. "macaddr:textField "
. "channelsMax:textField "
. "wolBroadcast:textField "
. $readingFnAttributes;
$::data{RC_layout}{BRAVIA_SVG} = \&RClayout_SVG;
$::data{RC_layout}{BRAVIA} = \&RClayout;
$::data{RC_makenotify}{BRAVIA} = \&RCmakenotify;
return;
}
###################################
sub Define {
my ( $hash, $def ) = @_; my ( $hash, $def ) = @_;
my @a = split( "[ \t][ \t]*", $def ); my @a = split( "[ \t][ \t]*", $def );
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -155,13 +154,13 @@ sub Define($$) {
# start the status update timer # start the status update timer
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer( gettimeofday() + 2, "BRAVIA::GetStatus", $hash, 1 ); InternalTimer( gettimeofday() + 2, \&GetStatus, $hash, 1 );
return; return;
} }
################################### ###################################
sub Undefine($$) { sub Undefine {
my ( $hash, $arg ) = @_; my ( $hash, $arg ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -174,7 +173,7 @@ sub Undefine($$) {
} }
##################################### #####################################
sub GetStatus($;$) { sub GetStatus {
my ( $hash, $update ) = @_; my ( $hash, $update ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $interval = $hash->{INTERVAL}; my $interval = $hash->{INTERVAL};
@ -182,7 +181,7 @@ sub GetStatus($;$) {
Log3($name, 5, "BRAVIA $name: called function GetStatus()"); Log3($name, 5, "BRAVIA $name: called function GetStatus()");
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer( gettimeofday() + $interval, "BRAVIA::GetStatus", $hash, 0 ); InternalTimer( gettimeofday() + $interval, \&GetStatus, $hash, 0 );
return if ( AttrVal($name, "disable", 0) == 1 ); return if ( AttrVal($name, "disable", 0) == 1 );
@ -198,7 +197,7 @@ sub GetStatus($;$) {
} }
################################### ###################################
sub Get($@) { sub Get {
my ( $hash, @a ) = @_; my ( $hash, @a ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $what; my $what;
@ -208,7 +207,7 @@ sub Get($@) {
return "argument is missing" if ( int(@a) < 2 ); return "argument is missing" if ( int(@a) < 2 );
$what = $a[1]; $what = $a[1];
if ( $what =~ /^(power|presence|input|channel|volume|mute)$/ ) { if ( $what =~ /^(power|presence|input|channel|volume|mute)$/xms ) {
my $value = ReadingsVal($name, $what, ""); my $value = ReadingsVal($name, $what, "");
if ($value ne "") { if ($value ne "") {
return $value; return $value;
@ -225,7 +224,7 @@ sub Get($@) {
} }
################################### ###################################
sub Set($@) { sub Set {
my ( $hash, @a ) = @_; my ( $hash, @a ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $power = ReadingsVal($name, "power", ""); my $power = ReadingsVal($name, "power", "");
@ -281,7 +280,7 @@ sub Set($@) {
} }
if ( $channel ne "" && $channel ne "-" && $channelId ne "-" ) { if ( $channel ne "" && $channel ne "-" && $channelId ne "-" ) {
my $currentChannel = $channelId . ":" . $channel; my $currentChannel = $channelId . ":" . $channel;
my @matches = grep("/".$currentChannel."/", @channels); my @matches = grep {"/".$currentChannel."/"} @channels ;
push( @channels, $currentChannel ) if ( ( scalar @matches ) eq "0" ); push( @channels, $currentChannel ) if ( ( scalar @matches ) eq "0" );
} }
@channels = sort(@channels); @channels = sort(@channels);
@ -384,7 +383,7 @@ sub Set($@) {
my $vol = $a[2]; my $vol = $a[2];
if ( $presence eq 'present' ) { if ( $presence eq 'present' ) {
if ( $vol =~ m/^\d+$/ && $vol >= 1 && $vol <= 100 ) { if ( $vol =~ m/^\d+$/xms && $vol >= 1 && $vol <= 100 ) {
$cmd = $vol; $cmd = $vol;
} }
else { else {
@ -403,7 +402,7 @@ sub Set($@) {
} }
# volumeUp/volumeDown # volumeUp/volumeDown
elsif ( lc( $a[1] ) =~ /^(volumeup|volumedown)$/ ) { elsif ( lc( $a[1] ) =~ /^(volumeup|volumedown)$/xms ) {
Log3($name, 2, "BRAVIA set $name " . $a[1]); Log3($name, 2, "BRAVIA set $name " . $a[1]);
if ( $presence eq "present" ) { if ( $presence eq "present" ) {
@ -515,13 +514,13 @@ sub Set($@) {
if ( $presence eq "present" ) { if ( $presence eq "present" ) {
my $channelName = $channelStr; my $channelName = $channelStr;
if ( defined($hash->{helper}{device}{channelPreset}) && $channelName =~ /^(\d+).*$/ ) { if ( defined($hash->{helper}{device}{channelPreset}) && $channelName =~ /^(\d+).*$/xms ) {
if ( defined($hash->{helper}{device}{channelPreset}{$1}{uri}) ) { if ( defined($hash->{helper}{device}{channelPreset}{$1}{uri}) ) {
SendCommand( $hash, "setPlayContent", $hash->{helper}{device}{channelPreset}{$1}{uri} ); SendCommand( $hash, "setPlayContent", $hash->{helper}{device}{channelPreset}{$1}{uri} );
return; return;
} }
} }
if ( $channelName =~ /^(\d)(\d?)(\d?)(\d?).*$/ ) { if ( $channelName =~ /^(\d)(\d?)(\d?)(\d?).*$/xms ) {
my @successor = (); my @successor = ();
push(@successor, ["ircc", $2]) if (defined($2)); push(@successor, ["ircc", $2]) if (defined($2));
push(@successor, ["ircc", $3]) if (defined($3)); push(@successor, ["ircc", $3]) if (defined($3));
@ -538,7 +537,7 @@ sub Set($@) {
} }
# channelUp/channelDown # channelUp/channelDown
elsif ( lc( $a[1] ) =~ /^(channelup|channeldown)$/ ) { elsif ( lc( $a[1] ) =~ /^(channelup|channeldown)$/xms ) {
Log3($name, 2, "BRAVIA set $name " . $a[1]); Log3($name, 2, "BRAVIA set $name " . $a[1]);
if ( $presence eq "present" ) { if ( $presence eq "present" ) {
@ -642,10 +641,10 @@ sub Set($@) {
if ( $presence eq "present" ) { if ( $presence eq "present" ) {
Log3($name, 2, "BRAVIA set $name " . $a[1] . " " . $a[2]); Log3($name, 2, "BRAVIA set $name " . $a[1] . " " . $a[2]);
my $url = lc($a[2]); my $url = lc($a[2]);
if ($url !~ /^https?:\/\/.*/) { if ($url !~ /^https?:\/\/.*/xms) {
$url = "http://$url"; $url = "http://$url";
} }
$url =~ s/([\x2F \x3A])/sprintf("%%%02X",ord($1))/eg; $url =~ s/([\x2F \x3A])/sprintf("%%%02X",ord($1))/egxms;
$url = "localapp://webappruntime?url=$url"; $url = "localapp://webappruntime?url=$url";
Log3($name, 2, "BRAVIA set $name " . $a[1] . " " . $url); Log3($name, 2, "BRAVIA set $name " . $a[1] . " " . $url);
SendCommand( $hash, "setActiveApp", $url ); SendCommand( $hash, "setActiveApp", $url );
@ -776,7 +775,7 @@ sub Set($@) {
############################################################################################################ ############################################################################################################
################################### ###################################
sub SendCommand($$;$$@) { sub SendCommand {
my ( $hash, $service, $cmd, $param, @successor ) = @_; my ( $hash, $service, $cmd, $param, @successor ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $address = $hash->{helper}{ADDRESS}; my $address = $hash->{helper}{ADDRESS};
@ -822,7 +821,7 @@ sub SendCommand($$;$$@) {
$data = GetIrccRequest($cmd); $data = GetIrccRequest($cmd);
} elsif ($service eq "upnp") { } elsif ($service eq "upnp") {
my $value; my $value;
if ($cmd =~ m/^(.+):(\d+)$/) { if ($cmd =~ m/^(.+):(\d+)$/xms) {
$cmd = $1; $cmd = $1;
$value = $2; $value = $2;
} }
@ -885,7 +884,7 @@ sub SendCommand($$;$$@) {
if ($requestFormat eq "json") { if ($requestFormat eq "json") {
my $source = $cmd; my $source = $cmd;
my $index = 0; my $index = 0;
if ($cmd =~ /^(.*)\|(\d+)$/){ if ($cmd =~ /^(.*)\|(\d+)$/xms){
$source = $1; $source = $1;
$index = $2; $index = $2;
} }
@ -981,7 +980,7 @@ sub SendCommand($$;$$@) {
$data = "{\"method\":\"".$service."\",\"params\":[],\"id\":1,\"version\":\"1.0\"}"; $data = "{\"method\":\"".$service."\",\"params\":[],\"id\":1,\"version\":\"1.0\"}";
} else { } else {
$URL .= "/cers"; $URL .= "/cers";
if ($service =~ /^Mute.*$/) { if ($service =~ /^Mute.*$/xms) {
$URL .= "/command/".$service; $URL .= "/command/".$service;
} else { } else {
$URL .= "/api/" . $service; $URL .= "/api/" . $service;
@ -990,7 +989,7 @@ sub SendCommand($$;$$@) {
} }
$timeout = AttrVal($name, "timeout", 0); $timeout = AttrVal($name, "timeout", 0);
if ($timeout !~ /^\d+$/ or $timeout == 0) { if ($timeout !~ /^\d+$/xms or $timeout == 0) {
if ( $service eq "getStatus" ) { if ( $service eq "getStatus" ) {
$timeout = 10; $timeout = 10;
} else { } else {
@ -1018,7 +1017,7 @@ sub SendCommand($$;$$@) {
cmd => $cmd, cmd => $cmd,
successor => \@successor, successor => \@successor,
timestamp => $timestamp, timestamp => $timestamp,
callback => \&BRAVIA::ReceiveCommand, callback => \&ReceiveCommand,
} }
); );
@ -1026,7 +1025,7 @@ sub SendCommand($$;$$@) {
} }
################################### ###################################
sub ReceiveCommand($$$) { sub ReceiveCommand {
my ( $param, $err, $data ) = @_; my ( $param, $err, $data ) = @_;
my $hash = $param->{hash}; my $hash = $param->{hash};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1058,7 +1057,7 @@ sub ReceiveCommand($$$) {
if ( if (
( !defined( $hash->{helper}{AVAILABLE} ) ) ( !defined( $hash->{helper}{AVAILABLE} ) )
or ( defined( $hash->{helper}{AVAILABLE} ) or ( defined( $hash->{helper}{AVAILABLE} )
and $hash->{helper}{AVAILABLE} eq 1 ) and $hash->{helper}{AVAILABLE} == 1 )
) )
{ {
$hash->{helper}{AVAILABLE} = 0; $hash->{helper}{AVAILABLE} = 0;
@ -1080,7 +1079,7 @@ sub ReceiveCommand($$$) {
if ( if (
( !defined( $hash->{helper}{AVAILABLE} ) ) ( !defined( $hash->{helper}{AVAILABLE} ) )
or ( defined( $hash->{helper}{AVAILABLE} ) or ( defined( $hash->{helper}{AVAILABLE} )
and $hash->{helper}{AVAILABLE} eq 0 ) and $hash->{helper}{AVAILABLE} == 0 )
) )
{ {
$hash->{helper}{AVAILABLE} = 1; $hash->{helper}{AVAILABLE} = 1;
@ -1096,7 +1095,7 @@ sub ReceiveCommand($$$) {
LogSuccessors($hash, @successor); LogSuccessors($hash, @successor);
if ( $data ne "" ) { if ( $data ne "" ) {
if ( $data =~ /^<\?xml/ ) { if ( $data =~ /^<\?xml/xms ) {
my $parser = XML::Simple->new( my $parser = XML::Simple->new(
NormaliseSpace => 2, NormaliseSpace => 2,
KeepRoot => 0, KeepRoot => 0,
@ -1117,7 +1116,7 @@ sub ReceiveCommand($$$) {
$return = $parser->XMLin( encode_utf8($data), KeyAttr => [ ] ); $return = $parser->XMLin( encode_utf8($data), KeyAttr => [ ] );
} }
elsif ( $data =~ /^{/ || $data =~ /^\[/ ) { elsif ( $data =~ /^\{/xms || $data =~ /^\[/xms ) {
if ( !defined($cmd) || ref($cmd) eq "HASH" || $cmd eq "" ) { if ( !defined($cmd) || ref($cmd) eq "HASH" || $cmd eq "" ) {
Log3($name, 4, "BRAVIA $name: RES $service - $data"); Log3($name, 4, "BRAVIA $name: RES $service - $data");
} }
@ -1142,7 +1141,7 @@ sub ReceiveCommand($$$) {
$return = "not found"; $return = "not found";
} }
elsif ( $data =~ /^<s:Envelope/ ) { elsif ( $data =~ /^<s:Envelope/xms ) {
if ( !defined($cmd) ) { if ( !defined($cmd) ) {
Log3($name, 4, "BRAVIA $name: RES $service - response"); Log3($name, 4, "BRAVIA $name: RES $service - response");
} }
@ -1161,7 +1160,7 @@ sub ReceiveCommand($$$) {
Log3($name, 5, "BRAVIA $name: RES ERROR $service/" . ::urlDecode($cmd) . "\n" . $data); Log3($name, 5, "BRAVIA $name: RES ERROR $service/" . ::urlDecode($cmd) . "\n" . $data);
} }
return undef; return;
} }
} }
@ -1189,9 +1188,9 @@ sub ReceiveCommand($$$) {
# Set reading for state # Set reading for state
# #
my $currentState = ReadingsVal($name, "state", ""); my $currentState = ReadingsVal($name, "state", "");
if ( ( $currentState !~ /set_.*/ and $currentState ne $newstate ) if ( ( $currentState !~ /set_.*/xms and $currentState ne $newstate )
or $currentState eq "set_".$newstate or $currentState eq "set_".$newstate
or ($currentState =~ /set_.*/ and ReadingsAge($name, "state", 0) > 60) ) or ($currentState =~ /set_.*/xms and ReadingsAge($name, "state", 0) > 60) )
{ {
readingsBulkUpdate( $hash, "state", $newstate ); readingsBulkUpdate( $hash, "state", $newstate );
} }
@ -1228,26 +1227,26 @@ sub ReceiveCommand($$$) {
} }
################################### ###################################
sub wake ($$) { sub wake {
my ( $name, $mac_addr ) = @_; my ( $name, $mac_addr ) = @_;
my $address = AttrVal($name, 'wolBroadcast', '255.255.255.255'); my $address = AttrVal($name, 'wolBroadcast', '255.255.255.255');
my $port = 9; my $port = 9;
my $sock = new IO::Socket::INET( Proto => 'udp' ) my $sock = IO::Socket::INET->new( Proto => 'udp' )
or die "socket : $!"; or die "socket : $!\n";
die "Can't create WOL socket" if ( !$sock ); die "Can't create WOL socket\n" if ( !$sock );
my $ip_addr = inet_aton($address); my $ip_addr = inet_aton($address);
my $sock_addr = sockaddr_in( $port, $ip_addr ); my $sock_addr = sockaddr_in( $port, $ip_addr );
$mac_addr =~ s/://g; $mac_addr =~ s/://gxms;
my $packet = my $packet =
pack( 'C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $mac_addr x 16 ); pack( 'C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $mac_addr x 16 );
setsockopt( $sock, SOL_SOCKET, SO_BROADCAST, 1 ) setsockopt( $sock, SOL_SOCKET, SO_BROADCAST, 1 )
or die "setsockopt : $!"; or die "setsockopt : $!\n";
Log3($name, 4, "BRAVIA $name: Waking up by sending Wake-On-Lan magic packet to $mac_addr"); Log3($name, 4, "BRAVIA $name: Waking up by sending Wake-On-Lan magic packet to $mac_addr");
send( $sock, $packet, 0, $sock_addr ) or die "send : $!"; send( $sock, $packet, 0, $sock_addr ) or die "send : $!\n";
close($sock); close($sock);
return; return;
@ -1255,7 +1254,7 @@ sub wake ($$) {
################################### ###################################
# process return data # process return data
sub ProcessCommandData ($$$) { sub ProcessCommandData {
my ($param,$return,$successor) = @_; my ($param,$return,$successor) = @_;
my $hash = $param->{hash}; my $hash = $param->{hash};
@ -1296,7 +1295,7 @@ sub ProcessCommandData ($$$) {
my %statusKeys; my %statusKeys;
foreach ( keys %{ $hash->{READINGS} } ) { foreach ( keys %{ $hash->{READINGS} } ) {
$statusKeys{$_} = 1 if ( $_ =~ /^s_.*/ && ReadingsVal($name, $_, "") ne "-" ); $statusKeys{$_} = 1 if ( $_ =~ /^s_.*/xms && ReadingsVal($name, $_, "") ne "-" );
} }
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
@ -1421,7 +1420,7 @@ sub ProcessCommandData ($$$) {
my $currentMedia = "-"; my $currentMedia = "-";
foreach ( keys %{ $hash->{READINGS} } ) { foreach ( keys %{ $hash->{READINGS} } ) {
$contentKeys{$_} = 1 $contentKeys{$_} = 1
if ( $_ =~ /^ci_.*/ and ReadingsVal($name, $_, "") ne "-" ); if ( $_ =~ /^ci_.*/xms and ReadingsVal($name, $_, "") ne "-" );
} }
if ( ref($return) eq "HASH" ) { if ( ref($return) eq "HASH" ) {
$newstate = "on"; $newstate = "on";
@ -1472,7 +1471,7 @@ sub ProcessCommandData ($$$) {
$uri = $return->{result}[0]{$_}; $uri = $return->{result}[0]{$_};
# set TV input uri to last tv-norm (tv:dvbt, tv:dvbs) # set TV input uri to last tv-norm (tv:dvbt, tv:dvbs)
$hash->{helper}{device}{inputPreset}{TV}{uri} = $return->{result}[0]{$_} $hash->{helper}{device}{inputPreset}{TV}{uri} = $return->{result}[0]{$_}
if (defined($hash->{helper}{device}{inputPreset}) && $return->{result}[0]{$_} =~ /tv:.*/); if (defined($hash->{helper}{device}{inputPreset}) && $return->{result}[0]{$_} =~ /tv:.*/xms);
} else { } else {
readingsBulkUpdateIfChanged( $hash, "ci_".$_, $return->{result}[0]{$_} ); readingsBulkUpdateIfChanged( $hash, "ci_".$_, $return->{result}[0]{$_} );
delete $contentKeys{"ci_".$_}; delete $contentKeys{"ci_".$_};
@ -1484,7 +1483,7 @@ sub ProcessCommandData ($$$) {
foreach ( keys %{$hash->{helper}{device}{inputPreset}} ) { foreach ( keys %{$hash->{helper}{device}{inputPreset}} ) {
if ($hash->{helper}{device}{inputPreset}{$_}{uri} eq $uri) { if ($hash->{helper}{device}{inputPreset}{$_}{uri} eq $uri) {
$input = $_; $input = $_;
$input =~ s/#/ /g; $input =~ s/\#/ /gxms;
last; last;
} }
} }
@ -1548,7 +1547,7 @@ sub ProcessCommandData ($$$) {
foreach ( keys %{ $hash->{READINGS} } ) { foreach ( keys %{ $hash->{READINGS} } ) {
$contentKeys{$_} = 1 $contentKeys{$_} = 1
if ( $_ =~ /^ci_.*/ and ReadingsVal($name, $_, "") ne "-" ); if ( $_ =~ /^ci_.*/xms and ReadingsVal($name, $_, "") ne "-" );
} }
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
@ -1559,8 +1558,7 @@ sub ProcessCommandData ($$$) {
foreach ( @{ $return->{result} } ) { foreach ( @{ $return->{result} } ) {
foreach ( @{ $_ } ) { foreach ( @{ $_ } ) {
if ($_->{recordingStatus} eq "recording") { if ($_->{recordingStatus} eq "recording") {
my $key; foreach my $key ( keys %{ $_ }) {
foreach $key ( keys %{ $_ }) {
if ( $key eq "type" ) { if ( $key eq "type" ) {
$currentMedia = $_->{$key}; $currentMedia = $_->{$key};
readingsBulkUpdateIfChanged( $hash, "input", $_->{$key} ); readingsBulkUpdateIfChanged( $hash, "input", $_->{$key} );
@ -1606,8 +1604,7 @@ sub ProcessCommandData ($$$) {
my $channelNo; my $channelNo;
my $channelName; my $channelName;
my $channelUri; my $channelUri;
my $key; foreach my $key ( keys %{ $_ }) {
foreach $key ( keys %{ $_ }) {
if ( $key eq "dispNum" ) { if ( $key eq "dispNum" ) {
$channelNo = $_->{$key}; $channelNo = $_->{$key};
} elsif ( $key eq "title" ) { } elsif ( $key eq "title" ) {
@ -1629,7 +1626,7 @@ sub ProcessCommandData ($$$) {
if (++$channelIndex % InternalVal($name, "CHANNELCOUNT", 50) == 0) { if (++$channelIndex % InternalVal($name, "CHANNELCOUNT", 50) == 0) {
# try next junk of channels # try next junk of channels
my $source = $cmd; my $source = $cmd;
if ($cmd =~ /^(.*)\|(\d+)$/){ if ($cmd =~ /^(.*)\|(\d+)$/xms){
$source = $1; $source = $1;
} }
push(@$successor, ["getContentList", $source."|".$channelIndex]); push(@$successor, ["getContentList", $source."|".$channelIndex]);
@ -1642,9 +1639,8 @@ sub ProcessCommandData ($$$) {
if (ref($return->{result}) eq "ARRAY") { if (ref($return->{result}) eq "ARRAY") {
foreach ( @{ $return->{result} } ) { foreach ( @{ $return->{result} } ) {
foreach ( @{ $_ } ) { foreach ( @{ $_ } ) {
my $key;
my $scheme = undef; my $scheme = undef;
foreach $key ( keys %{ $_ }) { foreach my $key ( keys %{ $_ }) {
if ( $key eq "scheme" ) { if ( $key eq "scheme" ) {
$scheme = $_->{$key}; $scheme = $_->{$key};
} }
@ -1668,14 +1664,13 @@ sub ProcessCommandData ($$$) {
if (ref($return->{result}) eq "ARRAY") { if (ref($return->{result}) eq "ARRAY") {
foreach ( @{ $return->{result} } ) { foreach ( @{ $return->{result} } ) {
foreach ( @{ $_ } ) { foreach ( @{ $_ } ) {
my $key;
my $source = undef; my $source = undef;
foreach $key ( keys %{ $_ }) { foreach my $key ( keys %{ $_ }) {
if ( $key eq "source" ) { if ( $key eq "source" ) {
$source = $_->{$key}; $source = $_->{$key};
} }
} }
if (defined($source) and $source =~ /tv:dvb(.)/) { if (defined($source) and $source =~ /tv:dvb(.)/xms) {
my $dvbName = GetNormalizedName("TV / DVB-".uc($1)); my $dvbName = GetNormalizedName("TV / DVB-".uc($1));
$hash->{helper}{device}{inputPreset}{$dvbName}{uri} = $source; $hash->{helper}{device}{inputPreset}{$dvbName}{uri} = $source;
push(@$successor, ["getContentList", $source]); push(@$successor, ["getContentList", $source]);
@ -1695,8 +1690,7 @@ sub ProcessCommandData ($$$) {
my $inputName; my $inputName;
my $inputLabel; my $inputLabel;
my $inputUri; my $inputUri;
my $key; foreach my $key ( keys %{ $_ }) {
foreach $key ( keys %{ $_ }) {
if ( $key eq "uri" ) { if ( $key eq "uri" ) {
$inputUri = $_->{$key}; $inputUri = $_->{$key};
} elsif ( $key eq "title" ) { } elsif ( $key eq "title" ) {
@ -1709,7 +1703,7 @@ sub ProcessCommandData ($$$) {
} }
} }
my $tvUri = ReadingsVal($name, "uri", "tv"); my $tvUri = ReadingsVal($name, "uri", "tv");
$tvUri = "tv" if ($tvUri !~ /tv.*/); $tvUri = "tv" if ($tvUri !~ /tv.*/xms);
$hash->{helper}{device}{inputPreset}{TV}{uri} = $tvUri; $hash->{helper}{device}{inputPreset}{TV}{uri} = $tvUri;
} }
} }
@ -1723,8 +1717,7 @@ sub ProcessCommandData ($$$) {
foreach ( @{ $_ } ) { foreach ( @{ $_ } ) {
my $appName; my $appName;
my $appUri; my $appUri;
my $key; foreach my $key ( keys %{ $_ }) {
foreach $key ( keys %{ $_ }) {
if ( $key eq "uri" ) { if ( $key eq "uri" ) {
$appUri = $_->{$key}; $appUri = $_->{$key};
} elsif ( $key eq "title" ) { } elsif ( $key eq "title" ) {
@ -1749,7 +1742,7 @@ sub ProcessCommandData ($$$) {
foreach ( keys %{$hash->{helper}{device}{appPreset}} ) { foreach ( keys %{$hash->{helper}{device}{appPreset}} ) {
if ($hash->{helper}{device}{appPreset}{$_}{uri} eq $cmd) { if ($hash->{helper}{device}{appPreset}{$_}{uri} eq $cmd) {
$appName = $_; $appName = $_;
$appName =~ s/#/ /g; $appName =~ s/\#/ /gxms;
last; last;
} }
} }
@ -1768,7 +1761,7 @@ sub ProcessCommandData ($$$) {
last; last;
} }
} }
%speaker = @{$return->{result}}[0] if (!%speaker && ${$return->{result}} > 0); %speaker = %{@$elements[0]} if (!%speaker && $elements > 0);
if (%speaker) { if (%speaker) {
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged( $hash, 'volume', $speaker{volume} ); readingsBulkUpdateIfChanged( $hash, 'volume', $speaker{volume} );
@ -1804,13 +1797,13 @@ sub ProcessCommandData ($$$) {
@$successor = (); @$successor = ();
} else { } else {
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
if ( $header =~ /auth=([A-Za-z0-9]+)/ ) { if ( $header =~ /auth=([A-Za-z0-9]+)/xms ) {
readingsBulkUpdate( $hash, "authCookie", $1 ); readingsBulkUpdate( $hash, "authCookie", $1 );
} }
if ( $header =~ /[Ee]xpires=([^;]+)/ ) { if ( $header =~ /expires=([^;]+)/ixms ) {
readingsBulkUpdate( $hash, "authExpires", $1 ); readingsBulkUpdate( $hash, "authExpires", $1 );
} }
if ( $header =~ /[Mm]ax-[Aa]ge=(\d+)/ ) { if ( $header =~ /max-age=(\d+)/ixms ) {
readingsBulkUpdateIfChanged( $hash, "authMaxAge", $1 ); readingsBulkUpdateIfChanged( $hash, "authMaxAge", $1 );
} }
readingsEndUpdate( $hash, 1 ); readingsEndUpdate( $hash, 1 );
@ -1827,7 +1820,7 @@ sub ProcessCommandData ($$$) {
} }
##################################### #####################################
sub ClearContentInformation ($) { sub ClearContentInformation {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1836,7 +1829,7 @@ sub ClearContentInformation ($) {
#remove outdated content information - replaces by "-" #remove outdated content information - replaces by "-"
foreach ( keys %{ $hash->{READINGS} } ) { foreach ( keys %{ $hash->{READINGS} } ) {
readingsBulkUpdateIfChanged($hash, $_, "-") if ( $_ =~ /^ci_.*/ ); readingsBulkUpdateIfChanged($hash, $_, "-") if ( $_ =~ /^ci_.*/xms );
} }
readingsBulkUpdateIfChanged( $hash, "channel", "-" ); readingsBulkUpdateIfChanged( $hash, "channel", "-" );
@ -1847,9 +1840,11 @@ sub ClearContentInformation ($) {
readingsBulkUpdateIfChanged( $hash, "uri", "-" ); readingsBulkUpdateIfChanged( $hash, "uri", "-" );
readingsEndUpdate( $hash, 1 ); readingsEndUpdate( $hash, 1 );
return;
} }
sub FetchPresets($$) { sub FetchPresets {
my ($hash,$successor) = @_; my ($hash,$successor) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1866,9 +1861,11 @@ sub FetchPresets($$) {
|| !defined( $hash->{helper}{device}{appPreset} ) || !defined( $hash->{helper}{device}{appPreset} )
|| scalar( keys %{ $hash->{helper}{device}{appPreset} } ) == 0 ); || scalar( keys %{ $hash->{helper}{device}{appPreset} } ) == 0 );
} }
return;
} }
sub LogSuccessors($@) { sub LogSuccessors {
my ($hash,@successor) = @_; my ($hash,@successor) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1880,11 +1877,13 @@ sub LogSuccessors($@) {
$msg .= join(",", map { defined($_) ? $_ : '' } @succ_item); $msg .= join(",", map { defined($_) ? $_ : '' } @succ_item);
} }
Log3($name, 4, $msg) if (@successor > 0); Log3($name, 4, $msg) if (@successor > 0);
return;
} }
##################################### #####################################
# Callback from 95_remotecontrol for command makenotify. # Callback from 95_remotecontrol for command makenotify.
sub RCmakenotify($$) { sub RCmakenotify {
my ( $nam, $ndev ) = @_; my ( $nam, $ndev ) = @_;
my $nname = "notify_$nam"; my $nname = "notify_$nam";
@ -1897,7 +1896,7 @@ sub RCmakenotify($$) {
# RC layouts # RC layouts
# Sony TV with SVG # Sony TV with SVG
sub RClayout_SVG() { sub RClayout_SVG {
my @row; my @row;
$row[0] = "SOURCE:rc_AV.svg,:rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg"; $row[0] = "SOURCE:rc_AV.svg,:rc_BLANK.svg,:rc_BLANK.svg,POWER:rc_POWER.svg";
@ -1929,7 +1928,7 @@ sub RClayout_SVG() {
} }
# Sony TV with PNG # Sony TV with PNG
sub RClayout() { sub RClayout {
my @row; my @row;
$row[0] = "SOURCE,:blank,:blank,POWER:POWEROFF"; $row[0] = "SOURCE,:blank,:blank,POWER:POWEROFF";
@ -2061,7 +2060,7 @@ sub RClayout() {
# 755 <command name="BrowserReload" type="url" value="http://192.168.2.43:80/cers/command/BrowserReload" /> # 755 <command name="BrowserReload" type="url" value="http://192.168.2.43:80/cers/command/BrowserReload" />
# 755 <command name="BrowserStop" type="url" value="http://192.168.2.43:80/cers/command/BrowserStop" /> # 755 <command name="BrowserStop" type="url" value="http://192.168.2.43:80/cers/command/BrowserStop" />
# 755 <command name="BrowserBookmarkList" type="url" value="http://192.168.2.43:80/cers/command/BrowserBookmarkList" /> # 755 <command name="BrowserBookmarkList" type="url" value="http://192.168.2.43:80/cers/command/BrowserBookmarkList" />
sub GetRemotecontrolCommand($) { sub GetRemotecontrolCommand {
my ($command) = @_; my ($command) = @_;
my $commands = { my $commands = {
'POWER' => "AAAAAQAAAAEAAAAVAw==", 'POWER' => "AAAAAQAAAAEAAAAVAw==",
@ -2139,7 +2138,7 @@ sub GetRemotecontrolCommand($) {
} }
} }
sub GetModelYear($) { sub GetModelYear {
my ($command) = @_; my ($command) = @_;
my $commands = { my $commands = {
'1.0' => "2011", '1.0' => "2011",
@ -2159,7 +2158,7 @@ sub GetModelYear($) {
} }
} }
sub GetIrccRequest($) { sub GetIrccRequest {
my ($cmd) = @_; my ($cmd) = @_;
my $data = "<?xml version=\"1.0\"?>"; my $data = "<?xml version=\"1.0\"?>";
$data .= "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"; $data .= "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">";
@ -2173,7 +2172,7 @@ sub GetIrccRequest($) {
return $data; return $data;
} }
sub GetUpnpRequest($$) { sub GetUpnpRequest {
my ($cmd,$value) = @_; my ($cmd,$value) = @_;
my $data = "<?xml version=\"1.0\"?>"; my $data = "<?xml version=\"1.0\"?>";
$data .= "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"; $data .= "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">";
@ -2211,12 +2210,12 @@ sub GetUpnpRequest($$) {
return $data; return $data;
} }
sub CheckRegistration($$$$@) { sub CheckRegistration {
my ( $hash, $service, $cmd, $param, @successor ) = @_; my ( $hash, $service, $cmd, $param, @successor ) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if (ReadingsVal($name, "authCookie", "") ne "" and if (ReadingsVal($name, "authCookie", "") ne "" and
ReadingsTimestamp($name, "authCookie", "") =~ m/^(\d{4})-(\d{2})-(\d{2}) ([0-2]\d):([0-5]\d):([0-5]\d)$/) { ReadingsTimestamp($name, "authCookie", "") =~ m/^(\d{4})-(\d{2})-(\d{2}) ([0-2]\d):([0-5]\d):([0-5]\d)$/xms) {
my $time = fhemTimeLocal($6, $5, $4, $3, $2 - 1, $1 - 1900); my $time = fhemTimeLocal($6, $5, $4, $3, $2 - 1, $1 - 1900);
# max age defaults to 14 days # max age defaults to 14 days
@ -2266,12 +2265,12 @@ sub CheckServiceAvailable {
return 1; return 1;
} }
sub GetNormalizedName($) { sub GetNormalizedName {
my ( $name ) = @_; my ( $name ) = @_;
$name =~ s/^\s+//; $name =~ s/^\s+//xms;
$name =~ s/\s+$//; $name =~ s/\s+$//xms;
$name =~ s/\s/#/g; $name =~ s/\s/#/gxms;
$name =~ s/,/./g; $name =~ s/,/./gxms;
return $name; return $name;
} }

View File

@ -0,0 +1,59 @@
################################################
# test Set
################################################
package FHEM::BRAVIA;
use strict;
use warnings;
use Test::More;
use JSON qw(decode_json);
# used to import of FHEM functions from fhem.pl
use GPUtils qw(:all);
BEGIN {
GP_Import(
qw(
fhem
FhemTestUtils_gotEvent
)
);
}
# receive getVolumeInformation
{
my $service = 'getVolumeInformation';
my %params = (
hash => $::defs{tv},
service => $service
);
ProcessCommandData(\%params, decode_json('{"result":[],"id":2}'));
}
is(FhemTestUtils_gotEvent('tv:volume: 0'), 0, 'getVolumeInformation empty: Reading volume');
is(FhemTestUtils_gotEvent('tv:mute: off'), 0, 'getVolumeInformation empty: Reading mute');
{
my $service = 'getVolumeInformation';
my %params = (
hash => $::defs{tv},
service => $service
);
ProcessCommandData(\%params, decode_json('{"result":[[{"target":"headphone","volume":0,"mute":false,"maxVolume":100,"minVolume":0}]],"id":2}'));
}
is(FhemTestUtils_gotEvent('tv:volume: 0'), 1, 'getVolumeInformation headphone: Reading volume');
is(FhemTestUtils_gotEvent('tv:mute: off'), 1, 'getVolumeInformation headphone: Reading mute');
{
my $service = 'getVolumeInformation';
my %params = (
hash => $::defs{tv},
service => $service
);
ProcessCommandData(\%params, decode_json('{"result":[[{"target":"headphone","volume":42,"mute":true,"maxVolume":100,"minVolume":0}]],"id":2}'));
}
is(FhemTestUtils_gotEvent('tv:volume: 42'), 1, 'getVolumeInformation speaker: Reading volume');
is(FhemTestUtils_gotEvent('tv:mute: on'), 1, 'getVolumeInformation speaker: Reading mute');
done_testing;
exit(0);
1;

View File

@ -0,0 +1,2 @@
define tv BRAVIA 127.0.0.1
attr tv verbose 5