From 344e15b49b72631bed09c4165f146a6dec691d6c Mon Sep 17 00:00:00 2001 From: markusbloch <> Date: Sun, 25 May 2014 20:52:16 +0000 Subject: [PATCH] YAMAHA_AVR: big rewrite to execute HTTP requests non-blocking; added new set command trickPlay + new remoteControl commands, new reading trickPlay. git-svn-id: https://svn.fhem.de/fhem/trunk@5970 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 4 + fhem/FHEM/71_YAMAHA_BD.pm | 906 ++++++++++++++++++++++---------------- 2 files changed, 527 insertions(+), 383 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 8096be005..d2221abb6 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,9 @@ # 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. + - change: YAMAHA_BD: make YAMAHA_BD more performant by using non-blocking + HTTP request (from HttpUtils.pm) + - added: YAMAHA_BD: new set command trickPlay and more remoteControl + commands. new reading trickPlay - added: new module 98_statistics.pm: hourly, daily, monthly, yearly statistics for min/avg/max/delta/duration of selected readings - added: new module 52_I2C_MCP23017.pm (klausw) diff --git a/fhem/FHEM/71_YAMAHA_BD.pm b/fhem/FHEM/71_YAMAHA_BD.pm index 82f296783..d0d73da0d 100755 --- a/fhem/FHEM/71_YAMAHA_BD.pm +++ b/fhem/FHEM/71_YAMAHA_BD.pm @@ -31,7 +31,7 @@ package main; use strict; use warnings; -use Time::HiRes qw(gettimeofday sleep); +use Time::HiRes qw(gettimeofday); use HttpUtils; sub YAMAHA_BD_Get($@); @@ -41,9 +41,6 @@ sub YAMAHA_BD_Attr(@); sub YAMAHA_BD_ResetTimer($;$); sub YAMAHA_BD_Undefine($$); - - - ################################### sub YAMAHA_BD_Initialize($) @@ -55,8 +52,7 @@ YAMAHA_BD_Initialize($) $hash->{DefFn} = "YAMAHA_BD_Define"; $hash->{AttrFn} = "YAMAHA_BD_Attr"; $hash->{UndefFn} = "YAMAHA_BD_Undefine"; - - $hash->{AttrList} = "do_not_notify:0,1 disable:0,1 request-timeout:1,2,3,4,5 model ". + $hash->{AttrList} = "do_not_notify:0,1 disable:0,1 request-timeout:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 model ". $readingFnAttributes; } @@ -67,120 +63,33 @@ YAMAHA_BD_GetStatus($;$) my ($hash, $local) = @_; my $name = $hash->{NAME}; my $power; + my $return; $local = 0 unless(defined($local)); return "" if(!defined($hash->{helper}{ADDRESS}) or !defined($hash->{helper}{ON_INTERVAL}) or !defined($hash->{helper}{OFF_INTERVAL})); - my $device = $hash->{helper}{ADDRESS}; - # get the model informations if no informations are available - if(defined($hash->{MODEL}) or not defined($hash->{FIRMWARE})) + if((not defined($hash->{MODEL})) or (not defined($hash->{FIRMWARE}))) { YAMAHA_BD_getModel($hash); } Log3 $name, 4, "YAMAHA_BD: Requesting system status"; - my $return = YAMAHA_BD_SendCommand($hash, "GetParam"); - - - - - - if(not defined($return) or $return eq "") - { - readingsSingleUpdate($hash, "state", "absent", 1); - YAMAHA_BD_ResetTimer($hash) unless($local == 1); - return; - } - - readingsBeginUpdate($hash); - if($return =~ /(.+?)<\/Error_Info>/) - { - readingsBulkUpdate($hash, "error", lc($1)); - - } - + YAMAHA_BD_SendCommand($hash, "GetParam", "statusRequest","systemStatus"); + Log3 $name, 4, "YAMAHA_BD: Requesting power state"; - $return = YAMAHA_BD_SendCommand($hash, "GetParam"); - - if($return =~ /(.+?)<\/Power>/) - { - $power = $1; - - if($power eq "Standby" or $power eq "Network Standby") - { - $power = "off"; - } - readingsBulkUpdate($hash, "power", lc($power)); - readingsBulkUpdate($hash, "state", lc($power)); - } - + YAMAHA_BD_SendCommand($hash, "GetParam", "statusRequest","powerStatus"); Log3 $name, 4, "YAMAHA_BD: Requesting playing info"; - $return = YAMAHA_BD_SendCommand($hash, "GetParam"); - - if(defined($return)) - { - if($return =~ /(.+?)<\/Status>/) - { - readingsBulkUpdate($hash, "playStatus", lc($1)); - } - - if($return =~ /(.+?)<\/Chapter>/) - { - readingsBulkUpdate($hash, "currentChapter", lc($1)); - } - - if($return =~ /(.+?)<\/File_Name>/) - { - readingsBulkUpdate($hash, "currentMedia", $1); - } - - if($return =~ /(.+?)<\/Disc_Type>/) - { - readingsBulkUpdate($hash, "discType", $1); - } - - if($return =~ /(.+?)<\/Status><\/Input_Info/) - { - readingsBulkUpdate($hash, "input", $1); - } - elsif($return =~ /(.+?)<\/Input_Info/) - { - readingsBulkUpdate($hash, "input", $1); - } - - if($return =~ /(.+?)<\/Tray>/) - { - readingsBulkUpdate($hash, "trayStatus", lc($1)); - } - - if($return =~ /(.+?)<\/Current_PlayTime>/) - { - readingsBulkUpdate($hash, "playTimeCurrent", YAMAHA_BD_formatTimestamp($1)); - } - - if($return =~ /(.+?)<\/Total_Time>/) - { - readingsBulkUpdate($hash, "playTimeTotal", YAMAHA_BD_formatTimestamp($1)); - } - - } - else - { - - Log3 $name, 3, "YAMAHA_BD: Received no response for playing info request"; - } - - - readingsEndUpdate($hash, 1); + YAMAHA_BD_SendCommand($hash, "GetParam", "statusRequest","playInfo"); + Log3 $name, 4, "YAMAHA_BD: Requesting trickPlay info"; + YAMAHA_BD_SendCommand($hash, "GetParam", "statusRequest","trickPlayInfo"); + + # Reset timer if this is not a local run YAMAHA_BD_ResetTimer($hash) unless($local == 1); - - Log3 $name, 4, "YAMAHA_BD $name: ".$hash->{STATE}; - - return $hash->{STATE}; + } ################################### @@ -232,248 +141,288 @@ YAMAHA_BD_Set($@) my $result = ""; return "No Argument given" if(!defined($a[1])); - - # get the model informations if no informations are available - if(defined($hash->{MODEL}) or not defined($hash->{FIRMWARE})) - { - YAMAHA_BD_getModel($hash); - } - + my $what = $a[1]; - my $usage = "Unknown argument $what, choose one of on:noArg off:noArg statusRequest:noArg tray:open,close remoteControl:up,down,left,right,return,enter,OSDonScreen,OSDstatus,topMenu,popupMenu,red,green,blue,yellow,0,1,2,3,4,5,6,7,8,9,setup,home,clear fast:forward,reverse slow:forward,reverse skip:forward,reverse play:noArg pause:noArg stop:noArg"; + my $usage = "Unknown argument $what, choose one of on:noArg off:noArg statusRequest:noArg tray:open,close remoteControl:up,down,left,right,return,enter,OSDonScreen,OSDstatus,topMenu,popupMenu,red,green,blue,yellow,0,1,2,3,4,5,6,7,8,9,setup,home,clear,program,search,repeat,repeat-AB,subtitle,angle,audio,pictureInPicture,secondVideo,secondAudio fast:forward,reverse slow:forward,reverse skip:forward,reverse play:noArg pause:noArg stop:noArg trickPlay:normal,repeatChapter,repeatTitle,repeatFolder,repeat-AB,randomChapter,randomTitle,randomAll,shuffleChapter,shuffleTitle,shuffleAll,setApoint"; - # Depending on the status response, use the short or long Volume command - - if($what eq "on") - { - - $result = YAMAHA_BD_SendCommand($hash, "On"); - - if(defined($result) and $result =~ /RC="0"/ and $result =~ /<\/Power>/) - { - # As the player startup takes about 5 seconds, the status will be already set, if the return code of the command is 0. - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, "power", "on"); - readingsBulkUpdate($hash, "state","on"); - readingsEndUpdate($hash, 1); - return undef; - } - else - { - return "Could not set power to on"; - } - - } - elsif($what eq "off") - { - $result = YAMAHA_BD_SendCommand($hash, "Network Standby"); - - if(not defined($result) or not $result =~ /RC="0"/) - { - # if the returncode isn't 0, than the command was not successful - return "Could not set power to off"; - } - - } - elsif($what eq "remoteControl") - { - if($a[2] eq "up") - { - YAMAHA_BD_SendCommand($hash, "Up"); - } - elsif($a[2] eq "down") - { - YAMAHA_BD_SendCommand($hash, "Down"); - } - elsif($a[2] eq "left") - { - YAMAHA_BD_SendCommand($hash, "Left"); - } - elsif($a[2] eq "right") - { - YAMAHA_BD_SendCommand($hash, "Right"); - } - elsif($a[2] eq "enter") - { - YAMAHA_BD_SendCommand($hash, "Enter"); - } - elsif($a[2] eq "return") - { - YAMAHA_BD_SendCommand($hash, "Return"); - } - elsif($a[2] eq "OSDonScreen") - { - YAMAHA_BD_SendCommand($hash,"OnScreen"); - } - elsif($a[2] eq "OSDstatus") - { - YAMAHA_BD_SendCommand($hash,"Status"); - } - elsif($a[2] eq "topMenu") - { - YAMAHA_BD_SendCommand($hash,"TOP MENU"); - } - elsif($a[2] eq "popupMenu") - { - YAMAHA_BD_SendCommand($hash,"POPUP MENU"); - } - elsif($a[2] eq "red") - { - YAMAHA_BD_SendCommand($hash,"RED"); - } - elsif($a[2] eq "green") - { - YAMAHA_BD_SendCommand($hash,"GREEN"); - } - elsif($a[2] eq "blue") - { - YAMAHA_BD_SendCommand($hash,"BLUE"); - } - elsif($a[2] eq "yellow") - { - YAMAHA_BD_SendCommand($hash,"YELLOW"); - } - elsif($a[2] eq "0") - { - YAMAHA_BD_SendCommand($hash,"0"); - } - elsif($a[2] eq "1") - { - YAMAHA_BD_SendCommand($hash,"1"); - } - elsif($a[2] eq "2") - { - YAMAHA_BD_SendCommand($hash,"2"); - } - elsif($a[2] eq "3") - { - YAMAHA_BD_SendCommand($hash,"3"); - } - elsif($a[2] eq "4") - { - YAMAHA_BD_SendCommand($hash,"4"); - } - elsif($a[2] eq "5") - { - YAMAHA_BD_SendCommand($hash,"5"); - } - elsif($a[2] eq "6") - { - YAMAHA_BD_SendCommand($hash,"6"); - } - elsif($a[2] eq "7") - { - YAMAHA_BD_SendCommand($hash,"7"); - } - elsif($a[2] eq "8") - { - YAMAHA_BD_SendCommand($hash,"8"); - } - elsif($a[2] eq "9") - { - YAMAHA_BD_SendCommand($hash,"9"); - } - elsif($a[2] eq "setup") - { - YAMAHA_BD_SendCommand($hash,"SETUP"); - } - elsif($a[2] eq "home") - { - YAMAHA_BD_SendCommand($hash,"HOME"); - } - elsif($a[2] eq "clear") - { - YAMAHA_BD_SendCommand($hash,"CLEAR"); - } - elsif($a[2] eq "subtitle") - { - YAMAHA_BD_SendCommand($hash,"SUBTITLE"); - } - elsif($a[2] eq "angle") - { - YAMAHA_BD_SendCommand($hash,"ANGLE"); - } - elsif($a[2] eq "pictureInPicture") - { - YAMAHA_BD_SendCommand($hash,"PinP"); - } - elsif($a[2] eq "secondVideo") - { - YAMAHA_BD_SendCommand($hash,"2nd Video"); - } - elsif($a[2] eq "secondAudio") - { - YAMAHA_BD_SendCommand($hash,"2nd Audio"); - } - else - { - return $usage; - } - } - elsif($what eq "tray") - { - if($a[2] eq "open") - { - YAMAHA_BD_SendCommand($hash, "Open"); - } - elsif($a[2] eq "close") - { - YAMAHA_BD_SendCommand($hash, "Close"); - } - } - elsif($what eq "skip") - { - if($a[2] eq "forward") - { - YAMAHA_BD_SendCommand($hash, "Fwd"); - } - elsif($a[2] eq "reverse") - { - YAMAHA_BD_SendCommand($hash, "Rev"); - } - } - elsif($what eq "fast") - { - if($a[2] eq "forward") - { - YAMAHA_BD_SendCommand($hash, "Fwd"); - } - elsif($a[2] eq "reverse") - { - YAMAHA_BD_SendCommand($hash, "Rev"); - } - } - elsif($what eq "slow") - { - if($a[2] eq "forward") - { - YAMAHA_BD_SendCommand($hash, "Fwd"); - } - elsif($a[2] eq "reverse") - { - YAMAHA_BD_SendCommand($hash, "Rev"); - } - } - elsif($what eq "play") - { - YAMAHA_BD_SendCommand($hash, "Play"); - } - elsif($what eq "pause") - { - YAMAHA_BD_SendCommand($hash, "Pause"); - } - elsif($what eq "stop") - { - YAMAHA_BD_SendCommand($hash, "Stop"); - } - elsif($what eq "statusRequest") - { - # Will be executed anyway on the end of the function - } - else - { - return $usage; - } + if($what eq "on") + { + YAMAHA_BD_SendCommand($hash, "On","on",undef); + } + elsif($what eq "off") + { + YAMAHA_BD_SendCommand($hash, "Network Standby","off",undef); + } + elsif($what eq "remoteControl") + { + if($a[2] eq "up") + { + YAMAHA_BD_SendCommand($hash, "Up","remoteControl","up"); + } + elsif($a[2] eq "down") + { + YAMAHA_BD_SendCommand($hash, "Down","remoteControl","down"); + } + elsif($a[2] eq "left") + { + YAMAHA_BD_SendCommand($hash, "Left","remoteControl","left"); + } + elsif($a[2] eq "right") + { + YAMAHA_BD_SendCommand($hash, "Right","remoteControl","right"); + } + elsif($a[2] eq "enter") + { + YAMAHA_BD_SendCommand($hash, "Enter","remoteControl","enter"); + } + elsif($a[2] eq "return") + { + YAMAHA_BD_SendCommand($hash, "Return","remoteControl","return"); + } + elsif($a[2] eq "OSDonScreen") + { + YAMAHA_BD_SendCommand($hash,"OnScreen","remoteControl","OSDonScreen"); + } + elsif($a[2] eq "OSDstatus") + { + YAMAHA_BD_SendCommand($hash,"Status","remoteControl","OSDstatus"); + } + elsif($a[2] eq "topMenu") + { + YAMAHA_BD_SendCommand($hash,"TOP MENU","remoteControl","topMenu"); + } + elsif($a[2] eq "popupMenu") + { + YAMAHA_BD_SendCommand($hash,"POPUP MENU","remoteControl","popupMenu"); + } + elsif($a[2] eq "red") + { + YAMAHA_BD_SendCommand($hash,"RED","remoteControl","red"); + } + elsif($a[2] eq "green") + { + YAMAHA_BD_SendCommand($hash,"GREEN","remoteControl","green"); + } + elsif($a[2] eq "blue") + { + YAMAHA_BD_SendCommand($hash,"BLUE","remoteControl","blue"); + } + elsif($a[2] eq "yellow") + { + YAMAHA_BD_SendCommand($hash,"YELLOW","remoteControl","yellow"); + } + elsif($a[2] eq "0") + { + YAMAHA_BD_SendCommand($hash,"0","remoteControl","0"); + } + elsif($a[2] eq "1") + { + YAMAHA_BD_SendCommand($hash,"1","remoteControl","1"); + } + elsif($a[2] eq "2") + { + YAMAHA_BD_SendCommand($hash,"2","remoteControl","2"); + } + elsif($a[2] eq "3") + { + YAMAHA_BD_SendCommand($hash,"3","remoteControl","3"); + } + elsif($a[2] eq "4") + { + YAMAHA_BD_SendCommand($hash,"4","remoteControl","4"); + } + elsif($a[2] eq "5") + { + YAMAHA_BD_SendCommand($hash,"5","remoteControl","5"); + } + elsif($a[2] eq "6") + { + YAMAHA_BD_SendCommand($hash,"6","remoteControl","6"); + } + elsif($a[2] eq "7") + { + YAMAHA_BD_SendCommand($hash,"7","remoteControl","7"); + } + elsif($a[2] eq "8") + { + YAMAHA_BD_SendCommand($hash,"8","remoteControl","8"); + } + elsif($a[2] eq "9") + { + YAMAHA_BD_SendCommand($hash,"9","remoteControl","9"); + } + elsif($a[2] eq "setup") + { + YAMAHA_BD_SendCommand($hash,"SETUP","remoteControl","setup"); + } + elsif($a[2] eq "home") + { + YAMAHA_BD_SendCommand($hash,"HOME","remoteControl","home"); + } + elsif($a[2] eq "clear") + { + YAMAHA_BD_SendCommand($hash,"CLEAR","remoteControl","clear"); + } + elsif($a[2] eq "program") + { + YAMAHA_BD_SendCommand($hash,"PROGRAM","remoteControl","program"); + } + elsif($a[2] eq "search") + { + YAMAHA_BD_SendCommand($hash,"7C9E","remoteControl","search"); + } + elsif($a[2] eq "repeat") + { + YAMAHA_BD_SendCommand($hash,"7CA3","remoteControl","repeat"); + } + elsif($a[2] eq "repeat-AB") + { + YAMAHA_BD_SendCommand($hash,"7CA4","remoteControl","repeat-AB"); + } + elsif($a[2] eq "subtitle") + { + YAMAHA_BD_SendCommand($hash,"SUBTITLE","remoteControl","subtitle"); + } + elsif($a[2] eq "angle") + { + YAMAHA_BD_SendCommand($hash,"ANGLE","remoteControl","angle"); + } + elsif($a[2] eq "audio") + { + YAMAHA_BD_SendCommand($hash,"AUDIO","remoteControl","audio"); + } + elsif($a[2] eq "pictureInPicture") + { + YAMAHA_BD_SendCommand($hash,"PinP","remoteControl","pictureInPicture"); + } + elsif($a[2] eq "secondVideo") + { + YAMAHA_BD_SendCommand($hash,"2nd Video","remoteControl","secondVideo"); + } + elsif($a[2] eq "secondAudio") + { + YAMAHA_BD_SendCommand($hash,"2nd Audio","remoteControl","secondAudio"); + } + else + { + return $usage; + } + } + elsif($what eq "trickPlay") + { + if($a[2] eq "normal") + { + YAMAHA_BD_SendCommand($hash,"Normal","trickPlay","normal"); + } + elsif($a[2] eq "repeatChapter") + { + YAMAHA_BD_SendCommand($hash,"Repeat Chapter/Track/File","trickPlay","repeatChapter"); + } + elsif($a[2] eq "repeatTitle") + { + YAMAHA_BD_SendCommand($hash,"Repeat Title","trickPlay","repeatTitle"); + } + elsif($a[2] eq "repeatFolder") + { + YAMAHA_BD_SendCommand($hash,"Repeat Folder","trickPlay","repeatFolder"); + } + elsif($a[2] eq "randomChapter") + { + YAMAHA_BD_SendCommand($hash,"Random Chapter/Track/File","trickPlay","randomChapter"); + } + elsif($a[2] eq "randomTitle") + { + YAMAHA_BD_SendCommand($hash,"Random title","trickPlay","randomTitle"); + } + elsif($a[2] eq "randomAll") + { + YAMAHA_BD_SendCommand($hash,"Random All","trickPlay","randomAll"); + } + elsif($a[2] eq "shuffleChapter") + { + YAMAHA_BD_SendCommand($hash,"Shuffle Chapter/Track/File","trickPlay","shuffleChapter"); + } + elsif($a[2] eq "shuffleTitle") + { + YAMAHA_BD_SendCommand($hash,"Shuffle title","trickPlay","shuffleTitle"); + } + elsif($a[2] eq "shuffleAll") + { + YAMAHA_BD_SendCommand($hash,"Shuffle All","trickPlay","shuffleAll"); + } + elsif($a[2] eq "setApoint") + { + YAMAHA_BD_SendCommand($hash,"SetA point","trickPlay","setApoint"); + } + elsif($a[2] eq "repeat-AB") + { + YAMAHA_BD_SendCommand($hash,"A-B Repeat","trickPlay","ABrepeat"); + } + else + { + return $usage; + } + } + elsif($what eq "tray") + { + if($a[2] eq "open") + { + YAMAHA_BD_SendCommand($hash, "Open","tray","open"); + } + elsif($a[2] eq "close") + { + YAMAHA_BD_SendCommand($hash, "Close","tray","close"); + } + } + elsif($what eq "skip") + { + if($a[2] eq "forward") + { + YAMAHA_BD_SendCommand($hash, "Fwd","skip","forward"); + } + elsif($a[2] eq "reverse") + { + YAMAHA_BD_SendCommand($hash, "Rev","skip","reverse"); + } + } + elsif($what eq "fast") + { + if($a[2] eq "forward") + { + YAMAHA_BD_SendCommand($hash, "Fwd","fast","forward"); + } + elsif($a[2] eq "reverse") + { + YAMAHA_BD_SendCommand($hash, "Rev","fast","reverse"); + } + } + elsif($what eq "slow") + { + if($a[2] eq "forward") + { + YAMAHA_BD_SendCommand($hash, "Fwd","slow","forward"); + } + elsif($a[2] eq "reverse") + { + YAMAHA_BD_SendCommand($hash, "Rev","slow","reverse"); + } + } + elsif($what eq "play") + { + YAMAHA_BD_SendCommand($hash, "Play","play", undef); + } + elsif($what eq "pause") + { + YAMAHA_BD_SendCommand($hash, "Pause","pause", undef); + } + elsif($what eq "stop") + { + YAMAHA_BD_SendCommand($hash, "Stop", "play",undef); + } + elsif($what ne "statusRequest") + { + return $usage; + } # Call the GetStatus() Function to retrieve the new values after setting something (with local flag, so the internal timer is not getting interupted) @@ -523,11 +472,6 @@ YAMAHA_BD_Define($$) $hash->{helper}{ON_INTERVAL}=$hash->{helper}{OFF_INTERVAL}; } - unless(exists($hash->{helper}{AVAILABLE}) and ($hash->{helper}{AVAILABLE} == 0)) - { - $hash->{helper}{AVAILABLE} = 1; - readingsSingleUpdate($hash, "presence", "present", 1); - } # start the status update timer $hash->{helper}{DISABLED} = 0 unless(exists($hash->{helper}{DISABLED})); @@ -589,42 +533,223 @@ YAMAHA_BD_Undefine($$) ############################# sub -YAMAHA_BD_SendCommand($$;$) +YAMAHA_BD_SendCommand($$$$) { - my ($hash, $command, $loglevel) = @_; + my ($hash, $data,$cmd,$arg) = @_; my $name = $hash->{NAME}; my $address = $hash->{helper}{ADDRESS}; my $response; - Log3 $name, 5, "YAMAHA_BD: execute on $name: $command"; + Log3 $name, 4, "YAMAHA_BD ($name): execute \"$cmd".(defined($arg) ? " ".$arg : "")."\": $data"; # In case any URL changes must be made, this part is separated in this function". - $response = GetFileFromURL("http://".$address.":50100/YamahaRemoteControl/ctrl", AttrVal($name, "request-timeout", 4) , "".$command, 1, ($hash->{helper}{AVAILABLE} ? undef : 5)); + + HttpUtils_NonblockingGet({ + url => "http://".$address.":50100/YamahaRemoteControl/ctrl", + timeout => AttrVal($name, "request-timeout", 4), + noshutdown => 1, + data => "".$data, + loglevel => ($hash->{helper}{AVAILABLE} ? undef : 5), + hash => $hash, + cmd => $cmd, + arg => $arg, + callback => \&YAMAHA_BD_ParseResponse + } + ); - Log3 $name, 5, "YAMAHA_BD: got response for $name: $response" if(defined($response)); +} + +sub +YAMAHA_BD_ParseResponse($$$) +{ + + my ( $param, $err, $data ) = @_; - unless(defined($response)) + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + + my $cmd = $param->{cmd}; + my $arg = $param->{arg}; + + + if($err) { - - if((not exists($hash->{helper}{AVAILABLE})) or (exists($hash->{helper}{AVAILABLE}) and $hash->{helper}{AVAILABLE} eq 1)) + Log3 $name, 4, "YAMAHA_BD ($name): error while executing \"$cmd".(defined($arg) ? " ".$arg : "")."\": $err"; + + if((not exists($hash->{helper}{AVAILABLE})) or (exists($hash->{helper}{AVAILABLE}) and $hash->{helper}{AVAILABLE} eq 1)) { - Log3 $name, 3, "YAMAHA_BD: could not execute command on device $name. Please turn on your device in case of deactivated network standby or check for correct hostaddress."; + Log3 $name, 3, "YAMAHA_BD: could not execute command on device $name. Please turn on your device in case of deactivated network standby or check for correct hostaddress: $err"; readingsSingleUpdate($hash, "presence", "absent", 1); + readingsSingleUpdate($hash, "state", "absent", 1); } + } - else + elsif($data) { - if (defined($hash->{helper}{AVAILABLE}) and $hash->{helper}{AVAILABLE} eq 0) + + Log3 $name, 5, "YAMAHA_BD ($name): got HTTP response for \"$cmd".(defined($arg) ? " ".$arg : "")."\": $data"; + + + if (defined($hash->{helper}{AVAILABLE}) and $hash->{helper}{AVAILABLE} == 0) { Log3 $name, 3, "YAMAHA_BD: device $name reappeared"; readingsSingleUpdate($hash, "presence", "present", 1); } + + readingsBeginUpdate($hash); + + if(not $data =~ /RC="0"/) + { + # if the returncode isn't 0, than the command was not successful + Log3 $name, 3, "YAMAHA_BD ($name) - Could not execute \"$cmd".(defined($arg) ? " ".$arg : "")."\""; + } + + if($cmd eq "statusRequest" and $arg eq "systemStatus") + { + if($data =~ /(.+?)<\/Error_Info>/) + { + readingsBulkUpdate($hash, "error", lc($1)); + + } + } + elsif($cmd eq "statusRequest" and $arg eq "systemConfig") + { + if($data =~ /(.+?)<\/Model_Name>.*(.+?)<\/Version>/) + { + $hash->{MODEL} = $1; + $hash->{FIRMWARE} = $2; + + $hash->{MODEL} =~ s/\s*YAMAHA\s*//g; + + $attr{$name}{"model"} = $hash->{MODEL}; + } + + } + elsif($cmd eq "statusRequest" and $arg eq "powerStatus") + { + if($data =~ /(.+?)<\/Power>/) + { + my $power = $1; + + if($power eq "Standby" or $power eq "Network Standby") + { + $power = "off"; + } + readingsBulkUpdate($hash, "power", lc($power)); + readingsBulkUpdate($hash, "state", lc($power)); + } + + } + elsif($cmd eq "on") + { + if($data =~ /RC="0"/ and $data =~ /<\/Power>/) + { + # As the player startup takes about 5 seconds, the status will be already set, if the return code of the command is 0. + + readingsBulkUpdate($hash, "power", "on"); + readingsBulkUpdate($hash, "state","on"); + + + } + else + { + Log3 $name, 3, "YAMAHA_BD ($name) - Could not set power to on"; + } + } + elsif($cmd eq "off") + { + + if(not $data =~ /RC="0"/) + { + # if the returncode isn't 0, than the command was not successful + Log3 $name, 3, "YAMAHA_BD ($name) - Could not set power to off"; + } + + + } + elsif($cmd eq "remoteControl") + { + + + + + } + elsif($cmd eq "statusRequest" and $arg eq "trickPlayInfo") + { + if($data =~ /(.+?)<\/Trick_Play>/) + { + readingsBulkUpdate($hash, "trickPlay", $1); + } + + } + elsif($cmd eq "statusRequest" and $arg eq "inputInfo") + { + + + + } + elsif($cmd eq "statusRequest" and $arg eq "playInfo") + { + + + if($data =~ /(.+?)<\/Status>/) + { + readingsBulkUpdate($hash, "playStatus", lc($1)); + } + + if($data =~ /(.+?)<\/Chapter>/) + { + readingsBulkUpdate($hash, "currentChapter", lc($1)); + } + + if($data =~ /(.+?)<\/File_Name>/) + { + readingsBulkUpdate($hash, "currentMedia", $1); + } + + if($data =~ /(.+?)<\/Disc_Type>/) + { + readingsBulkUpdate($hash, "discType", $1); + } + + if($data =~ /(.+?)<\/Status><\/Input_Info/) + { + readingsBulkUpdate($hash, "input", $1); + } + elsif($data =~ /(.+?)<\/Input_Info/) + { + readingsBulkUpdate($hash, "input", $1); + } + + if($data =~ /(.+?)<\/Tray>/) + { + readingsBulkUpdate($hash, "trayStatus", lc($1)); + } + + if($data =~ /(.+?)<\/Current_PlayTime>/) + { + readingsBulkUpdate($hash, "playTimeCurrent", YAMAHA_BD_formatTimestamp($1)); + } + + if($data =~ /(.+?)<\/Total_Time>/) + { + readingsBulkUpdate($hash, "playTimeTotal", YAMAHA_BD_formatTimestamp($1)); + } + + + + } + + + readingsEndUpdate($hash, 1); + + + YAMAHA_BD_GetStatus($hash, 1) if($cmd ne "statusRequest"); + } - $hash->{helper}{AVAILABLE} = (defined($response) ? 1 : 0); - - return $response; + $hash->{helper}{AVAILABLE} = ($err ? 0 : 1); } @@ -668,25 +793,9 @@ sub YAMAHA_BD_getModel($) my $response; my $desc_url; - $response = YAMAHA_BD_SendCommand($hash, "GetParam"); - - Log3 $name, 3, "YAMAHA_BD: could not get system configuration from device $name. Please turn on the device or check for correct hostaddress!" if (not defined($response) and defined($hash->{helper}{AVAILABLE}) and $hash->{helper}{AVAILABLE} eq 1); - - if(defined($response) and $response =~ /(.+?)<\/Model_Name>.*(.+?)<\/System_ID>.*(.+?)<\/Version>/) - { - $hash->{MODEL} = $1; - $hash->{SYSTEM_ID} = $2; - $hash->{FIRMWARE} = $3; - } - else - { - return undef; - } + YAMAHA_BD_SendCommand($hash, "GetParam", "statusRequest","systemConfig"); - $hash->{MODEL} =~ s/\s*YAMAHA\s*//g; - - $attr{$name}{"model"} = $hash->{MODEL}; } @@ -774,6 +883,7 @@ sub YAMAHA_BD_formatTimestamp($)
  • skip forward,reverse   -   skip the current track or chapter
  • fast forward,reverse   -   fast forward or reverse playback
  • slow forward,reverse   -   slow forward or reverse playback
  • +
  • trickPlay normal,repeatChapter,repeatTitle,...   -   controls the Trick-Play features
  • @@ -819,7 +929,20 @@ sub YAMAHA_BD_formatTimestamp($) remoteControl yellow
    remoteControl blue


    - + + Play Control Buttons:

    +
      + remoteControl program
      + remoteControl search
      + remoteControl repeat
      + remoteControl repeat-AB
      + remoteControl subtitle
      + remoteControl audio
      + remoteControl angle
      + remoteControl pictureInPicture
      + remoteControl secondAudio
      + remoteControl secondVideo
      +


    The button names are the same as on your remote control.

    @@ -854,6 +977,7 @@ sub YAMAHA_BD_formatTimestamp($)
  • power - Reports the power status of the player or zone (can be "on" or "off")
  • presence - Reports the presence status of the player or zone (can be "absent" or "present"). In case of an absent device, it cannot be controlled via FHEM anymore.
  • trayStatus - The disc tray status (can be "open" or "close")
  • +
  • trickPlay - The current trickPlay mode
  • state - Reports the current power state and an absence of the device (can be "on", "off" or "absent")


  • Input dependent Readings/Events:
  • currentChapter - Number of the current DVD/BD Chapter (only at DVD/BD's)
  • @@ -865,7 +989,7 @@ sub YAMAHA_BD_formatTimestamp($)
    Implementator's note
      -
    • Some older models (e.g. BD-S671) cannot be controlled over networked by delivery. A firmware update is neccessary to control theese models via FHEM
    • +
    • Some older models (e.g. BD-S671) cannot be controlled over networked by delivery. A firmware update is neccessary to control these models via FHEM. In general it is always recommended to use the latest firmware.
    • The module is only usable if you activate "Network Control" on your player. Otherwise it is not possible to communicate with the player.

    @@ -934,7 +1058,7 @@ sub YAMAHA_BD_formatTimestamp($)
  • skip forward,reverse   -   überspringt das aktuelle Kapitel oder den aktuellen Titel
  • fast forward,reverse   -   schneller Vor- oder Rücklauf
  • slow forward,reverse   -   langsamer Vor- oder Rücklauf
  • - +
  • trickPlay normal,repeatChapter,repeatTitle,...   -   aktiviert Trick-Play Funktionen (Wiederholung, Zufallswiedergabe, ...)


  • @@ -980,6 +1104,21 @@ sub YAMAHA_BD_formatTimestamp($) remoteControl yellow
    remoteControl blue


    + + Wiedergabetasten:

    +
      + remoteControl program
      + remoteControl search
      + remoteControl repeat
      + remoteControl repeat-AB
      + remoteControl subtitle
      + remoteControl audio
      + remoteControl angle
      + remoteControl pictureInPicture
      + remoteControl secondAudio
      + remoteControl secondVideo
      +


    + Die Befehlsnamen entsprechen den Tasten auf der Fernbedienung.

    @@ -1014,6 +1153,7 @@ sub YAMAHA_BD_formatTimestamp($)
  • power - Der aktuelle Betriebsstatus ("on" => an, "off" => aus)
  • presence - Die aktuelle Empfangsbereitschaft ("present" => empfangsbereit, "absent" => nicht empfangsbereit, z.B. Stromausfall)
  • trayStatus - Der Status der Schublade("open" => geöffnet, "close" => geschlossen)
  • +
  • trickPlay - Der aktuell aktive Trick-Play Modus
  • state - Der aktuelle Schaltzustand (power-Reading) oder die Abwesenheit des Gerätes (mögliche Werte: "on", "off" oder "absent")


  • Quellenabhängige Readings/Events:
  • currentChapter - Das aktuelle Kapitel eines DVD- oder Blu-Ray-Films