diff --git a/fhem/FHEM/70_PIONEERAVR.pm b/fhem/FHEM/70_PIONEERAVR.pm
new file mode 100644
index 000000000..e97387f1d
--- /dev/null
+++ b/fhem/FHEM/70_PIONEERAVR.pm
@@ -0,0 +1,1689 @@
+##############################################
+# $Id$
+#
+# 70_PIONEERAVR.pm
+#
+# This file is part of Fhem.
+#
+# Fhem is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Fhem is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Fhem. If not, see .
+#
+##############################################################################
+# by hofrichter
+#
+# This module handles the communication with a Pioneer AVR and controls the main zone.
+
+# this is the physical module - it opens the device (via rs232 or TCP), and its ReadFn is called after the global select reports,
+# that data is available.
+# - on Windows select does not work for devices not connected via TCP, here is a ReadyFn function necessary, which polls the device 10 times
+# a second, and returns true if data is available.
+# - ReadFn makes sure, that a message is complete and correct, and calls the global Dispatch() with one message
+# - Dispatch() searches for a matching logical module (by checking $hash->{Clients} or $hash->{MatchList} in the physical module, and
+# $hash->{Match} in all matching logical modules), and calls the ParseFn of the logical module
+# (we use this mechanism to pass informations to the PIONEERAVR_ZONE device(s) )
+#
+# See also:
+# Elite & Pioneer FY14AVR IP & RS-232 7-31-13.xlsx
+#
+
+# TODO:
+# match for devices/Dispatch() ???
+# random/repeat attributes
+# auto create zones
+# remote control layout (dynamic depending on available/current input?)
+# option for not permanent data connection
+# handle special chars in display
+# supress the "on" command if networkStandby = "off"
+#
+# changelog
+# 10.6.2014:version 0007
+# unified logging texts
+# added "verbose 5" log messages for all reads (messages coming from the PioneerAVR)
+# added "verbose 5" log messages for all set (commands sent to the PioneerAVR)
+# added "verbose 5" log messages for all get (commands sent to the PioneerAVR)
+# fixed set listeningMode
+# fixed get raw - this sends to the PioneerAVR (e.g. to power off the Pioneer AVR: get mypioneerAvr raw PF )
+# get raw (without further arguments) sends only a new line command -> this should wakeup the connection if the PioneerAVR is in standby
+# removed unneeded functions, RESTART OF FHEM NEEDED (reload PIONEERAVR is not enough)
+# updated set on -- to be even more Pioneer documentation conform (sending now additionally \n\r immediately before PO\n\r)
+# 9.6.2014: all commands end now with "\r\n"
+# The command for PowerOn (PO) is now send twice
+# "blink" (part of setextensions) does not make much sense for a Pioneer AVR - set blink returns this information ;-)
+# Added support for module 95_remotecontrol
+# New functions: sub RC_layout_PioneerAVR(); sub PIONEERAVR_RCmakenotify($$);
+# Updated PIONEERAVR_Initialize for remotecontrol
+# added reading "networkStandby" [on|off] -> "on" indicates that the Pioneer AVR can be turned on from standby
+# added reading "tunerFrequency"
+# version 0008
+# fixed get tunerFrequency
+
+package main;
+
+use strict;
+use warnings;
+use Time::HiRes qw(gettimeofday);
+if( $^O =~ /Win/ ) {
+ require Win32::SerialPort;
+} else {
+ require Device::SerialPort;
+}
+#########################
+# Forward declaration
+sub PIONEERAVR_Set($@);
+sub PIONEERAVR_Get($@);
+sub PIONEERAVR_Define($$);
+sub PIONEERAVR_Undef($$);
+sub PIONEERAVR_Read($);
+sub PIONEERAVR_Write($$);
+sub PIONEERAVR_Parse($$$);
+sub RC_layout_PioneerAVR();
+sub PIONEERAVR_RCmakenotify($$);
+
+#use vars qw {%attr %defs};
+
+#####################################
+#Die Funktion wird von Fhem.pl nach dem Laden des Moduls aufgerufen
+# und bekommt einen Hash für das Modul als zentrale Datenstruktur übergeben.
+# Dieser Hash wird im globalen Hash %modules gespeichert - hier $modules{PIONEERAVR}
+# Es handelt sich also nicht um den oben beschriebenen Hash der Geräteinstanzen sondern einen Hash,
+# der je Modul Werte enthält, beispielsweise auch die Namen der Funktionen, die das Modul implementiert
+# und die fhem.pl aufrufen soll. Die Initialize-Funktion setzt diese Funktionsnamen, in den Hash des Moduls
+#
+# Darüber hinaus sollten die vom Modul unterstützen Attribute definiert werden
+# In Fhem.pl werden dann die entsprechenden Werte beim Aufruf eines attr-Befehls in die
+# globale Datenstruktur $attr{$name}, z.B. $attr{$name}{header} für das Attribut header gespeichert.
+# Falls im Modul weitere Aktionen oder Prüfungen beim Setzen eines Attributs nötig sind, dann kann
+# die Funktion X_Attr implementiert und in der Initialize-Funktion bekannt gemacht werden.
+#
+# Die Variable $readingFnAttributes, die an die Liste der unterstützten Attribute angefügt wird, definiert Attributnamen,
+# die dann verfügbar werden, wenn das Modul zum Setzen von Readings die Funktionen
+# readingsBeginUpdate, readingsBulkUpdate, readingsEndUpdate oder readingsSingleUpdate verwendet.
+# In diesen Funktionen werden Attribute wie event-min-interval oder auch event-on-change-reading ausgewertet
+
+sub
+PIONEERAVR_Initialize($) {
+ my ($hash) = @_;
+
+# require "$attr{global}{modpath}/FHEM/DevIo.pm";
+
+ # Provider
+ $hash->{ReadFn} = "PIONEERAVR_Read";
+ $hash->{WriteFn} = "PIONEERAVR_Write";
+ $hash->{ReadyFn} = "PIONEERAVR_Ready";
+ $hash->{Clients} = ":PIONEERAVRZONE:";
+ $hash->{ClearFn} = "PIONEERAVR_Clear";
+
+ # Normal devices
+ $hash->{DefFn} = "PIONEERAVR_Define";
+ $hash->{UndefFn} = "PIONEERAVR_Undef";
+ $hash->{GetFn} = "PIONEERAVR_Get";
+ $hash->{SetFn} = "PIONEERAVR_Set";
+ $hash->{AttrFn} = "PIONEERAVR_Attr";
+ $hash->{AttrList}= "logTraffic:0,1,2,3,4,5 ".
+ $readingFnAttributes;
+
+ # remotecontrol
+ $data{RC_layout}{pioneerAvr} = "RC_layout_PioneerAVR";
+
+}
+
+######################################
+#Die Define-Funktion eines Moduls wird von Fhem aufgerufen wenn der Define-Befehl für ein Geräte ausgeführt wird
+# und das Modul bereits geladen und mit der Initialize-Funktion initialisiert ist. Sie ist typischerweise dazu da,
+# die übergebenen Parameter zu prüfen und an geeigneter Stelle zu speichern sowie
+# einen Kommunikationsweg zum Pioneer Receiver zu öffnen (z.B. TCP-Verbindung, RS232-Schnittstelle)
+#Als Übergabeparameter bekommt die Define-Funktion den Hash der Geräteinstanz sowie den Rest der Parameter, die im Befehl angegeben wurden.
+#
+# Damit die übergebenen Werte auch anderen Funktionen zur Verfügung stehen und an die jeweilige Geräteinstanz gebunden sind,
+# werden die Werte typischerweise als Internals im Hash der Geräteinstanz gespeichert
+
+sub
+PIONEERAVR_Define($$) {
+ my ($hash, $def) = @_;
+ my @a = split("[ \t]+", $def);
+ my $name = $hash->{NAME};
+
+ Log3 $name, 5, "PIONEERAVR $name: called function PIONEERAVR_Define()";
+
+ my $protocol = $a[2];
+
+ if( int(@a) != 4 || (($protocol ne "telnet") && ($protocol ne "serial"))) {
+ my $msg = "Wrong syntax: define PIONEERAVR telnet or define PIONEERAVR serial ";
+ Log3 $name, 4, "PIONEERAVR $name: " . $msg;
+ return $msg;
+ }
+ $hash->{TYPE} = "PIONEERAVR";
+
+ DevIo_CloseDev($hash);
+
+ $hash->{Protocol}= $protocol;
+ my $devicename= $a[3];
+ $hash->{DeviceName} = $devicename;
+
+ my $ret = DevIo_OpenDev($hash, 0, undef);
+
+ # set default attributes
+ unless ( exists( $attr{$name}{webCmd} ) ) {
+ $attr{$name}{webCmd} = 'volume:mute:input';
+ }
+ unless ( exists( $attr{$name}{devStateIcon} ) ) {
+ $attr{$name}{devStateIcon} =
+ 'on:rc_GREEN:off off:rc_STOP:on absent:rc_RED';
+ }
+ $hash->{helper}{receiver} = undef;
+
+ unless ( exists( $hash->{helper}{AVAILABLE} )
+ and ( $hash->{helper}{AVAILABLE} == 0 ))
+ {
+ $hash->{helper}{AVAILABLE} = 1;
+ readingsSingleUpdate( $hash, "presence", "present", 1 );
+ }
+
+ $hash->{helper}{INPUTNAMES} = {
+ "00" => {
+ "name" => "phono",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "01" => {
+ "name" => "cd",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "02" => {
+ "name" => "tuner",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "03" => {
+ "name" => "cdrTape",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "04" => {
+ "name" => "dvd",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "05" => {
+ "name" => "tvSat",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "06" => {
+ "name" => "CblSat",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "10" => {
+ "name" => "video1",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "12" => {
+ "name" => "multiChIn",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "14" => {
+ "name" => "video2",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "15" => {
+ "name" => "dvrBdr",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "17" => {
+ "name" => "iPodUsb",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "18" => {
+ "name" => "xmRadio",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "19" => {
+ "name" => "hdmi1",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "20" => {
+ "name" => "hdmi2",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "21" => {
+ "name" => "hdmi3",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "22" => {
+ "name" => "hdmi4",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "23" => {
+ "name" => "hdmi5",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "25" => {
+ "name" => "bd",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "26" => {
+ "name" => "homeMediaGallery",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "27" => {
+ "name" => "sirius",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "31" => {
+ "name" => "hdmiCyclic",
+ "aliasName" => "",
+ "enabled" => "1"
+ },
+ "33" => {
+ "name" => "adapterPort",
+ "aliasName" => "",
+ "enabled" => "1"
+ }
+ };
+
+ PIONEERAVR_askForInputNames($hash,5);
+
+ # ----------------Human Readable command mapping table-----------------------
+ $hash->{helper}{SETS} = {
+ 'main' => {
+ 'on' => 'PO',
+ 'off' => 'PF',
+ 'toggle' => 'PZ',
+ 'volumeUp' => 'VU',
+ 'volumeDown' => 'VD',
+ 'volume' => 'VL',
+ 'muteOn' => 'MO',
+ 'muteOff' => 'MF',
+ 'muteToggle' => 'MZ',
+ 'input' => 'FN',
+ 'inputUp' => 'FU',
+ 'inputDown' => 'FD',
+ 'channelUp' => 'TPI',
+ 'channelDown' => 'TPD',
+ 'playNetwork' => '10NW',
+ 'pauseNetwork' => '11NW',
+ 'stopNetwork' => '20NW',
+ 'repeatNetwork' => '34NW',
+ 'shuffleNetwork' => '35NW',
+ 'playIpod' => '00IP',
+ 'pauseIpod' => '01IP',
+ 'stopIpod' => '02IP',
+ 'repeatIpod' => '07IP',
+ 'shuffleIpod' => '08IP',
+ 'playAdapterPort' => '10BT',
+ 'pauseAdapterPort' => '11BT',
+ 'stopAdapterPort' => '12BT',
+ 'repeatAdapterPort' => '17BT',
+ 'shuffleAdapterPort' => '18BT',
+ 'playMhl' => '23MHL',
+ 'pauseMhl' => '25MHL',
+ 'stopMhl' => '24MHL'
+ },
+ 'zone2' => {
+ 'on' => 'APO',
+ 'off' => 'APF',
+ 'toggle' => 'APZ',
+ 'volumeUp' => 'ZU',
+ 'volumeDown' => 'ZD',
+ 'muteOn' => 'Z2MO',
+ 'muteOff' => 'Z2MF',
+ 'muteToggle' => 'Z2MZ',
+ 'inputUp' => 'ZSFU',
+ 'inputDown' => 'ZSFD'
+ },
+ 'zone3' => {
+ 'on' => 'BPO',
+ 'off' => 'BPF',
+ 'toggle' => 'BPZ',
+ 'volumeUp' => 'YU',
+ 'volumeDown' => 'YD',
+ 'muteOn' => 'Z3MO',
+ 'muteOff' => 'Z3MF',
+ 'muteToggle' => 'Z3MZ',
+ 'inputUp' => 'ZTFU',
+ 'inputDown' => 'ZTFD'
+ },
+ 'hdZone' => {
+ 'on' => 'ZEO',
+ 'off' => 'ZEF',
+ 'toggle' => 'ZEZ',
+ 'inputUp' => 'ZEC',
+ 'inputDown' => 'ZEB'
+ }
+ };
+ # ----------------Human Readable command mapping table-----------------------
+ $hash->{helper}{GETS} = {
+ 'main' => {
+ 'power' => '?P',
+ 'volume' => '?V',
+ 'mute' => '?M',
+ 'input' => '?F',
+ 'display' => '?FL',
+ 'listeningMode' => '?S',
+ 'listeningModePlaying' => '?L',
+ 'speakers' => '?SPK',
+ 'speakerSystem' => '?SSF',
+ 'channel' => '?PR',
+ 'tunerFrequency' => '?FR',
+ 'tunerChannelNames' => '?TQ',
+ 'model' => '?RGD',
+ 'networkStandby' => '?STJ',
+ 'softwareVersion' => '?SSI'
+ },
+ 'zone2' => {
+ 'power' => '?AP',
+ 'volume' => '?ZV',
+ 'mute' => '?Z2M',
+ 'input' => '?ZS'
+ },
+ 'zone3' => {
+ 'power' => '?BP',
+ 'volume' => '?YV',
+ 'mute' => '?Z3M',
+ 'input' => '?ZT'
+ },
+ 'hdZone' => {
+ 'power' => '?ZEP',
+ 'input' => '?ZEA'
+ }
+ };
+ # ----------------Human Readable command mapping table-----------------------
+ $hash->{helper}{SPEAKERSYSTEMS} = {
+ "10"=>"9.1ch FH/FW",
+ "00"=>"Normal(SB/FH)",
+ "01"=>"Normal(sb/FW)",
+ "02"=>"Speaker B",
+ "03"=>"Front Bi-Amp",
+ "04"=>"ZONE 2",
+ "11"=>"7.1ch + Speaker B",
+ "12"=>"7.1ch Front Bi-Amp",
+ "13"=>"7.1ch + ZONE2",
+ "14"=>"7.1ch FH/FW + ZONE2",
+ "15"=>"5.1ch Bi-Amp + ZONE2",
+ "16"=>"5.1ch + ZONE 2+3",
+ "17"=>"5.1ch + SP-B Bi-Amp",
+ "18"=>"5.1ch F+Surr Bi-Amp",
+ "19"=>"5.1ch F+C Bi-Amp",
+ "20"=>"5.1ch C+Surr Bi-Amp"
+ };
+
+ $hash->{helper}{TUNERCHANNELNAMES} = {
+ "A1"=>""
+ };
+
+ $hash->{helper}{LISTENINGMODES} = {
+ "0001"=>"stereoCyclic",
+ "0010"=>"standard",
+ "0009"=>"stereoDirectSet",
+ "0011"=>"2chSource",
+ "0013"=>"proLogic2movie",
+ "0018"=>"proLogic2xMovie",
+ "0014"=>"proLogic2music",
+ "0019"=>"proLogic2xMusic",
+ "0015"=>"proLogic2game",
+ "0020"=>"proLogic2xGame",
+ "0031"=>"proLogic2zHeight",
+ "0032"=>"wideSurroundMovie",
+ "0033"=>"wideSurroundMusic",
+ "0012"=>"proLogic",
+ "0016"=>"neo6cinema",
+ "0017"=>"neo6music",
+ "0028"=>"xmHdSurround",
+ "0029"=>"neuralSurround",
+ "0037"=>"neoXcinema",
+ "0038"=>"neoXmusic",
+ "0039"=>"neoXgame",
+ "0040"=>"neuralSurroundNeoXcinema",
+ "0041"=>"neuralSurroundNeoXmusic",
+ "0042"=>"neuralSurroundNeoXgame",
+ "0021"=>"multiChSource",
+ "0022"=>"multiChSourceDolbyEx",
+ "0023"=>"multiChSourceProLogic2xMovie",
+ "0024"=>"multiChSourceProLogic2xMusic",
+ "0034"=>"multiChSourceProLogic2zHeight",
+ "0035"=>"multiChSourceWideSurroundMovie",
+ "0036"=>"multiChSourceWideSurroundMusic",
+ "0025"=>"multiChSourceDtsEsNeo6",
+ "0026"=>"multiChSourceDtsEsMatrix",
+ "0027"=>"multiChSourceDtsEsDiscrete",
+ "0030"=>"multiChSourceDtsEs8chDiscrete",
+ "0043"=>"multiChSourceNeoXcinema",
+ "0044"=>"multiChSourceNeoXmusic",
+ "0045"=>"multiChSourceNeoXgame",
+ "0100"=>"advancedSurroundCyclic",
+ "0101"=>"action",
+ "0103"=>"drama",
+ "0102"=>"sciFi",
+ "0105"=>"monoFilm",
+ "0104"=>"entertainmentShow",
+ "0106"=>"expandedTheater",
+ "0116"=>"tvSurround",
+ "0118"=>"advancedGame",
+ "0117"=>"sports",
+ "0107"=>"classical",
+ "0110"=>"rockPop",
+ "0109"=>"unplugged",
+ "0112"=>"extendedStereo",
+ "0003"=>"frontStageSurroundAdvanceFocus",
+ "0004"=>"frontStageSurroundAdvanceWide",
+ "0153"=>"retrieverAir",
+ "0113"=>"phonesSurround",
+ "0050"=>"thxCyclic",
+ "0051"=>"prologicThxCinema",
+ "0052"=>"pl2movieThxCinema",
+ "0053"=>"neo6cinemaThxCinema",
+ "0054"=>"pl2xMovieThxCinema",
+ "0092"=>"pl2zHeightThxCinema",
+ "0055"=>"thxSelect2games",
+ "0068"=>"thxCinemaFor2ch",
+ "0069"=>"thxMusicFor2ch",
+ "0070"=>"thxGamesFor2ch",
+ "0071"=>"pl2musicThxMusic",
+ "0072"=>"pl2xMusicThxMusic",
+ "0093"=>"pl2zHeightThxMusic",
+ "0073"=>"neo6musicThxMusic",
+ "0074"=>"pl2gameThxGames",
+ "0075"=>"pl2xGameThxGames",
+ "0094"=>"pl2zHeightThxGames",
+ "0076"=>"thxUltra2games",
+ "0077"=>"prologicThxMusic",
+ "0078"=>"prologicThxGames",
+ "0201"=>"neoXcinemaThxCinema",
+ "0202"=>"neoXmusicThxMusic",
+ "0203"=>"neoXgameThxGames",
+ "0056"=>"thxCinemaForMultiCh",
+ "0057"=>"thxSurroundExForMultiCh",
+ "0058"=>"pl2xMovieThxCinemaForMultiCh",
+ "0095"=>"pl2zHeightThxCinemaForMultiCh",
+ "0059"=>"esNeo6thxCinemaForMultiCh",
+ "0060"=>"esMatrixThxCinemaForMultiCh",
+ "0061"=>"esDiscreteThxCinemaForMultiCh",
+ "0067"=>"es8chDiscreteThxCinemaForMultiCh",
+ "0062"=>"thxSelect2cinemaForMultiCh",
+ "0063"=>"thxSelect2musicForMultiCh",
+ "0064"=>"thxSelect2gamesForMultiCh",
+ "0065"=>"thxUltra2cinemaForMultiCh",
+ "0066"=>"thxUltra2musicForMultiCh",
+ "0079"=>"thxUltra2gamesForMultiCh",
+ "0080"=>"thxMusicForMultiCh",
+ "0081"=>"thxGamesForMultiCh",
+ "0082"=>"pl2xMusicThxMusicForMultiCh",
+ "0096"=>"pl2zHeightThxMusicForMultiCh",
+ "0083"=>"exThxGamesForMultiCh",
+ "0097"=>"pl2zHeightThxGamesForMultiCh",
+ "0084"=>"neo6thxMusicForMultiCh",
+ "0085"=>"neo6thxGamesForMultiCh",
+ "0086"=>"esMatrixThxMusicForMultiCh",
+ "0087"=>"esMatrixThxGamesForMultiCh",
+ "0088"=>"esDiscreteThxMusicForMultiCh",
+ "0089"=>"esDiscreteThxGamesForMultiCh",
+ "0090"=>"es8chDiscreteThxMusicForMultiCh",
+ "0091"=>"es8chDiscreteThxGamesForMultiCh",
+ "0204"=>"neoXcinemaThxCinemaForMultiCh",
+ "0205"=>"neoXmusicThxMusicForMultiCh",
+ "0206"=>"neoXgameThxGamesForMultiCh",
+ "0005"=>"autoSurrStreamDirectCyclic",
+ "0006"=>"autoSurround",
+ "0151"=>"autoLevelControlAlC",
+ "0007"=>"direct",
+ "0008"=>"pureDirect",
+ "0152"=>"optimumSurround"
+ };
+
+ $hash->{helper}{LISTENINGMODESPLAYING} = {
+ "0101"=>"[)(]PLIIx MOVIE",
+ "0102"=>"[)(]PLII MOVIE",
+ "0103"=>"[)(]PLIIx MUSIC",
+ "0104"=>"[)(]PLII MUSIC",
+ "0105"=>"[)(]PLIIx GAME",
+ "0106"=>"[)(]PLII GAME",
+ "0107"=>"[)(]PROLOGIC",
+ "0108"=>"Neo:6 CINEMA",
+ "0109"=>"Neo:6 MUSIC",
+ "010c"=>"2ch Straight Decode",
+ "010d"=>"[)(]PLIIz HEIGHT",
+ "010e"=>"WIDE SURR MOVIE",
+ "010f"=>"WIDE SURR MUSIC",
+ "0110"=>"STEREO",
+ "0111"=>"Neo:X CINEMA",
+ "0112"=>"Neo:X MUSIC",
+ "0113"=>"Neo:X GAME",
+ "1101"=>"[)(]PLIIx MOVIE",
+ "1102"=>"[)(]PLIIx MUSIC",
+ "1103"=>"[)(]DIGITAL EX",
+ "1104"=>"DTS Neo:6",
+ "1105"=>"ES MATRIX",
+ "1106"=>"ES DISCRETE",
+ "1107"=>"DTS-ES 8ch ",
+ "1108"=>"multi ch Straight Decode",
+ "1109"=>"[)(]PLIIz HEIGHT",
+ "110a"=>"WIDE SURR MOVIE",
+ "110b"=>"WIDE SURR MUSIC",
+ "110c"=>"Neo:X CINEMA ",
+ "110d"=>"Neo:X MUSIC",
+ "110e"=>"Neo:X GAME",
+ "0201"=>"ACTION",
+ "0202"=>"DRAMA",
+ "0208"=>"ADVANCEDGAME",
+ "0209"=>"SPORTS",
+ "020a"=>"CLASSICAL",
+ "020b"=>"ROCK/POP",
+ "020d"=>"EXT.STEREO",
+ "020e"=>"PHONES SURR.",
+ "020f"=>"FRONT STAGE SURROUND ADVANCE",
+ "0211"=>"SOUND RETRIEVER AIR",
+ "0212"=>"ECO MODE 1",
+ "0213"=>"ECO MODE 2",
+ "0301"=>"[)(]PLIIx MOVIE +THX",
+ "0302"=>"[)(]PLII MOVIE +THX",
+ "0303"=>"[)(]PL +THX CINEMA",
+ "0305"=>"THX CINEMA",
+ "0306"=>"[)(]PLIIx MUSIC +THX",
+ "0307"=>"[)(]PLII MUSIC +THX",
+ "0308"=>"[)(]PL +THX MUSIC",
+ "030a"=>"THX MUSIC",
+ "030b"=>"[)(]PLIIx GAME +THX",
+ "030c"=>"[)(]PLII GAME +THX",
+ "030d"=>"[)(]PL +THX GAMES",
+ "0310"=>"THX GAMES",
+ "0311"=>"[)(]PLIIz +THX CINEMA",
+ "0312"=>"[)(]PLIIz +THX MUSIC",
+ "0313"=>"[)(]PLIIz +THX GAMES",
+ "0314"=>"Neo:X CINEMA + THX CINEMA",
+ "0315"=>"Neo:X MUSIC + THX MUSIC",
+ "0316"=>"Neo:X GAMES + THX GAMES",
+ "1301"=>"THX Surr EX",
+ "1303"=>"ES MTRX +THX CINEMA",
+ "1304"=>"ES DISC +THX CINEMA",
+ "1305"=>"ES 8ch +THX CINEMA ",
+ "1306"=>"[)(]PLIIx MOVIE +THX",
+ "1309"=>"THX CINEMA",
+ "130b"=>"ES MTRX +THX MUSIC",
+ "130c"=>"ES DISC +THX MUSIC",
+ "130d"=>"ES 8ch +THX MUSIC",
+ "130e"=>"[)(]PLIIx MUSIC +THX",
+ "1311"=>"THX MUSIC",
+ "1313"=>"ES MTRX +THX GAMES",
+ "1314"=>"ES DISC +THX GAMES",
+ "1315"=>"ES 8ch +THX GAMES",
+ "1319"=>"THX GAMES",
+ "131a"=>"[)(]PLIIz +THX CINEMA",
+ "131b"=>"[)(]PLIIz +THX MUSIC",
+ "131c"=>"[)(]PLIIz +THX GAMES",
+ "131d"=>"Neo:X CINEMA + THX CINEMA",
+ "131e"=>"Neo:X MUSIC + THX MUSIC",
+ "131f"=>"Neo:X GAME + THX GAMES",
+ "0401"=>"STEREO",
+ "0402"=>"[)(]PLII MOVIE",
+ "0403"=>"[)(]PLIIx MOVIE",
+ "0405"=>"AUTO SURROUND Straight Decode",
+ "0406"=>"[)(]DIGITAL EX",
+ "0407"=>"[)(]PLIIx MOVIE",
+ "0408"=>"DTS +Neo:6",
+ "0409"=>"ES MATRIX",
+ "040a"=>"ES DISCRETE",
+ "040b"=>"DTS-ES 8ch ",
+ "040e"=>"RETRIEVER AIR",
+ "040f"=>"Neo:X CINEMA",
+ "0501"=>"STEREO",
+ "0502"=>"[)(]PLII MOVIE",
+ "0503"=>"[)(]PLIIx MOVIE",
+ "0504"=>"DTS/DTS-HD",
+ "0505"=>"ALC Straight Decode",
+ "0506"=>"[)(]DIGITAL EX",
+ "0507"=>"[)(]PLIIx MOVIE",
+ "0508"=>"DTS +Neo:6",
+ "0509"=>"ES MATRIX",
+ "050a"=>"ES DISCRETE",
+ "050b"=>"DTS-ES 8ch ",
+ "050e"=>"RETRIEVER AIR",
+ "050f"=>"Neo:X CINEMA",
+ "0601"=>"STEREO",
+ "0602"=>"[)(]PLII MOVIE",
+ "0603"=>"[)(]PLIIx MOVIE",
+ "0605"=>"STREAM DIRECT NORMAL Straight Decode",
+ "0606"=>"[)(]DIGITAL EX",
+ "0607"=>"[)(]PLIIx MOVIE",
+ "0609"=>"ES MATRIX",
+ "060a"=>"ES DISCRETE",
+ "060b"=>"DTS-ES 8ch ",
+ "060c"=>"Neo:X CINEMA",
+ "0701"=>"STREAM DIRECT PURE 2ch",
+ "0702"=>"[)(]PLII MOVIE",
+ "0703"=>"[)(]PLIIx MOVIE",
+ "0704"=>"Neo:6 CINEMA",
+ "0705"=>"STREAM DIRECT PURE Straight Decode",
+ "0706"=>"[)(]DIGITAL EX",
+ "0707"=>"[)(]PLIIx MOVIE",
+ "0708"=>"(nothing)",
+ "0709"=>"ES MATRIX",
+ "070a"=>"ES DISCRETE",
+ "070b"=>"DTS-ES 8ch ",
+ "070c"=>"Neo:X CINEMA",
+ "0881"=>"OPTIMUM",
+ "0e01"=>"HDMI THROUGH",
+ "0f01"=>"MULTI CH IN"
+ };
+ #### statusRequest
+ #### we execute all 'get XXX'
+ foreach my $zone ( keys %{$hash->{helper}{GETS}} ) {
+ foreach my $key ( keys %{$hash->{helper}{GETS}{$zone}} ) {
+ PIONEERAVR_Write($hash, $hash->{helper}{GETS}->{$zone}->{$key});
+ select(undef, undef, undef, 0.1);
+ }
+ }
+ return $ret;
+}
+
+#####################################
+#Die Undef-Funktion ist das Gegenstück zur Define-Funktion und wird aufgerufen wenn ein Gerät mit delete gelöscht wird
+# oder bei der Abarbeitung des Befehls rereadcfg, der ebenfalls alle Geräte löscht und danach das Konfigurationsfile neu abarbeitet.
+# Entsprechend müssen in der Funktion typische Aufräumarbeiten durchgeführt werden wie das saubere Schließen von Verbindungen
+# oder das Entfernen von internen Timern sofern diese im Modul zum Pollen verwendet wurden (siehe später).
+#
+#Zugewiesene Variablen im Hash der Geräteinstanz, Internals oder Readings müssen hier nicht gelöscht werden.
+# In fhem.pl werden die entsprechenden Strukturen beim Löschen der Geräteinstanz ohnehin vollständig gelöscht.
+sub
+PIONEERAVR_Undef($$)
+{
+ my ($hash, $arg) = @_;
+ my $name = $hash->{NAME};
+
+ # deleting port for clients
+ foreach my $d (sort keys %defs) {
+ if(defined($defs{$d}) &&
+ defined($defs{$d}{IODev}) &&
+ $defs{$d}{IODev} == $hash) {
+ my $lev = ($reread_active ? 4 : 2);
+ Log3 $hash, $lev, "PIONEERAVR $name: deleting port for $d";
+ delete $defs{$d}{IODev};
+ }
+ }
+
+ DevIo_CloseDev($hash);
+ return undef;
+}
+
+#####################################
+sub
+PIONEERAVR_Ready($)
+{
+ my ($hash) = @_;
+
+ return DevIo_OpenDev($hash, 1, "PIONEERAVR_DoInit")
+ if($hash->{STATE} eq "disconnected");
+
+ # This is relevant for windows/USB only
+ my $po = $hash->{USBDev};
+ my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags);
+ if($po) {
+ ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
+ }
+ return ($InBytes && $InBytes>0);
+}
+
+#####################################
+sub
+PIONEERAVR_DoInit($)
+{
+ my $hash = shift;
+ my $name = $hash->{NAME};
+ my $msg = undef;
+
+ PIONEERAVR_Clear($hash);
+
+ $hash->{STATE} = "Initialized" if(!$hash->{STATE});
+
+ return undef;
+}
+
+#####################################
+sub
+PIONEERAVR_Clear($)
+{
+ my $hash = shift;
+
+ # Clear the pipe
+ DevIo_TimeoutRead($hash, 0.1);
+}
+
+
+
+#####################################
+#Function to show special chars (e.g. \n\r) in logs
+sub
+dq($)
+{
+ my ($s)= @_;
+ $s= "" unless(defined($s));
+ return "\"" . escapeLogLine($s) . "\"";
+}
+
+#PIONEER_Log() is used to show the data sent end received from/to the PioneerAVR if attr logTraffic is set
+sub
+PIONEERAVR_Log($$$)
+{
+ my ($hash, $loglevel, $logmsg)= @_;
+ my $name= $hash->{NAME};
+ $loglevel = AttrVal($name, "logTraffic", undef) unless(defined($loglevel));
+ return unless(defined($loglevel));
+ Log3 $hash, $loglevel , "PIONEERAVR $name (loglevel: $loglevel): logTraffic $logmsg";
+}
+
+#####################################
+
+sub
+PIONEERAVR_Write($$)
+{
+ my ($hash, $msg) = @_;
+ $msg= $msg."\r\n";
+ PIONEERAVR_Log $hash, undef, "SimpleWrite " . dq($msg);
+ DevIo_SimpleWrite($hash, $msg, 0);
+}
+
+####################################
+sub
+PIONEERAVR_Set($@)
+{
+ my ($hash, @a) = @_;
+ my $name = $a[0];
+ my $cmd = $a[1];
+ my @setsPlayer= ("play","pause","stop","repeat","shuffle"); # available commands for certain inputs (@playerInputNr)
+ my @playerInputNr= ("17","33","38","44","45","48"); # Input number for Ipod, AdapterPort, InternetRadio, MediaServer, Favorites, Mhl
+ my @setsTuner = ("channelUp","channelDown","channelStraight","channel"); # available commands for input tuner
+ my @setsWithoutArg= ("off","toggle","volumeUp","volumeDown","muteOn","muteOff","muteToggle","inputUp","inputDown"); # set commands without arguments
+ my $playerCmd= "";
+ my $inputNr= "";
+
+ Log3 $name, 5, "PIONEERAVR $name: Processing PIONEERAVR_Set( $cmd )";
+ # get all input names (preferable the aliasName) of the enabled inputs for the drop down list of "set input xxx"
+ my @listInputNames = ();
+ foreach my $key ( keys %{$hash->{helper}{INPUTNAMES}} ) {
+ if (defined($hash->{helper}{INPUTNAMES}->{$key}{enabled})) {
+ if ( $hash->{helper}{INPUTNAMES}->{$key}{enabled} eq "1" ) {
+ if ($hash->{helper}{INPUTNAMES}{$key}{aliasName}) {
+ push(@listInputNames,$hash->{helper}{INPUTNAMES}{$key}{aliasName});
+ } elsif ($hash->{helper}{INPUTNAMES}{$key}{name}) {
+ push(@listInputNames,$hash->{helper}{INPUTNAMES}{$key}{name});
+ }
+ }
+ }
+ }
+
+ my $list = "reopen:noArg on:noArg off:noArg toggle:noArg input:"
+ . join(',', sort @listInputNames)
+ . " inputUp:noArg inputDown:noArg"
+ . " channelUp:noArg channelDown:noArg channelStraight"
+# . join(',', sort values ($hash->{helper}{TUNERCHANNELNAMES}))
+ . " channel:1,2,3,4,5,6,7,8,9"
+ . " listeningMode:"
+ . join(',', sort values (%{$hash->{helper}{LISTENINGMODES}}))
+ . " volumeUp:noArg volumeDown:noArg mute:on,off,toggle statusRequest:noArg volume:slider,0,1,100"
+ . " volumeStraight:slider,-80,1,12"
+ . " speakers:off,A,B,A+B";
+
+ my $currentInput= ReadingsVal($name,"input","");
+
+ if (defined($hash->{helper}{main}{CURINPUTNR})) {
+ $inputNr = $hash->{helper}{main}{CURINPUTNR};
+ }
+ #return "Can't find the current input - you might want to try 'get $name loadInputNames" if ($inputNr eq "");
+
+ # some input have more set commands ...
+ if ( $inputNr ~~ @playerInputNr ) {
+ $list .= "play:noArg stop:noArg pause:noArg repeat:noArg shuffle:noArg";
+ }
+ if ( $cmd eq "?" ) {
+ return SetExtensions($hash, $list, $name, $cmd, @a);
+
+ # set blink is part of the setextensions
+ # but blink does not make sense for an PioneerAVR so we disable it here
+ } elsif ( $cmd eq "blink" ) {
+ return "blink does not make too much sense with an PIONEER AVR isn't it?";
+ }
+ return "No Argument given" if ( !defined( $a[1] ) );
+
+ # process set command (without further argument(s))
+ if(@a == 2) {
+ Log3 $name, 5, "PIONEERAVR $name: Set $cmd (no arguments)";
+ # if the data connection between the PioneerAVR and Fhem is lost, we can try to reopen the data connection manually
+ if( $cmd eq "reopen" ) {
+ return PIONEERAVR_Reopen($hash);
+ ### Power on
+ ### Command: PO
+ ### according to "Elite & Pioneer FY14AVR IP & RS-232 7-31-13.xlsx" (notice) we need to send and
+ ### wait 100ms before the first command is accepted by the Pioneer AVR
+ } elsif ( $cmd eq "on" ) {
+ Log3 $name, 5, "PIONEERAVR $name: Set $cmd -> 2x newline + 2x PO with 100ms break in between";
+ my $setCmd= "";
+ PIONEERAVR_Write($hash, $setCmd);
+ select(undef, undef, undef, 0.1);
+ PIONEERAVR_Write($hash, $setCmd);
+ select(undef, undef, undef, 0.1);
+ $setCmd= "\n\rPO";
+ PIONEERAVR_Write($hash, $setCmd);
+ select(undef, undef, undef, 0.2);
+ PIONEERAVR_Write($hash, $setCmd);
+ return undef;
+
+ #### simple set commands without attributes
+ #### we just "translate" the human readable command to the PioneerAvr command
+ #### lookup in $hash->{helper}{SETS} if the command exists and what to write to PioneerAvr
+ } elsif ( $cmd ~~ @setsWithoutArg ) {
+ Log3 $name, 5, "PIONEERAVR $name: Set $cmd (setsWithoutArg)";
+ my $setCmd= $hash->{helper}{SETS}{main}{$a[1]};
+ my $v= PIONEERAVR_Write($hash, $setCmd);
+ return undef;
+
+ # statusRequest: execute all "get" commands to update the readings
+ } elsif ( $cmd eq "statusRequest") {
+ Log3 $name, 5, "PIONEERAVR $name: Set $cmd ";
+ foreach my $key ( keys %{$hash->{helper}{GETS}{main}} ) {
+ PIONEERAVR_Write($hash, $hash->{helper}{GETS}->{main}->{$key});
+ select(undef, undef, undef, 0.1);
+ }
+ #### play, pause, stop, random, repeat
+ #### Only available if the input is one of:
+ #### ipod, internetRadio, mediaServer, favorites, adapterPort, mhl
+ #### we need to send different Pioneer Avr commands
+ #### depending on that input
+ } elsif ($cmd ~~ @setsPlayer) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd for inputNr: $inputNr (player command)";
+ if ($inputNr eq "17") {
+ $playerCmd= $cmd."Ipod";
+ } elsif ($inputNr eq "33") {
+ $playerCmd= $cmd."AdapterPort";
+ #### internetRadio, mediaServer, favorites
+ } elsif (($inputNr eq "38") || ($inputNr eq "44") || ($inputNr eq "45")) {
+ $playerCmd= $cmd."Network";
+ #### 'random' and 'repeat' are not available on input mhl
+ } elsif (($inputNr eq "48") && (( $cmd eq "play") || ( $cmd eq "pause") ||( $cmd eq "stop"))) {
+ $playerCmd= $cmd."Mhl";
+ } else {
+ my $err= "PIONEERAVR $name: The command $cmd for input nr. $inputNr is not possible!";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ my $setCmd= $hash->{helper}{SETS}{main}{$playerCmd};
+ PIONEERAVR_Write($hash, $setCmd);
+ return undef;
+ #### channelUp, channelDown
+ #### Only available if the input is 02 (tuner)
+ } elsif ($cmd ~~ @setsTuner) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd for inputNr: $inputNr (tuner command)";
+ if ($inputNr eq "02") {
+ my $setCmd= $hash->{helper}{SETS}{main}{$cmd};
+ PIONEERAVR_Write($hash, $setCmd);
+ } else {
+ my $err= "PIONEERAVR $name: The tuner command $cmd for input nr. $inputNr is not possible!";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ return undef;
+ }
+ #### commands with argument(s)
+ } elsif(@a > 2) {
+ my $arg = $a[2];
+ ####Input (all available Inputs of the Pioneer Avr -> see 'get $name loadInputNames')
+ #### according to http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
+ #### first try the aliasName (only if this fails try the default input name)
+ if ( $cmd eq "input" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd ".dq($arg);
+ foreach my $key ( keys %{$hash->{helper}{INPUTNAMES}} ) {
+ if ( $hash->{helper}{INPUTNAMES}->{$key}{aliasName} eq $arg ) {
+ PIONEERAVR_Write($hash, sprintf "%02dFN", $key);
+ } elsif ( $hash->{helper}{INPUTNAMES}->{$key}{name} eq $arg ) {
+ PIONEERAVR_Write($hash, sprintf "%02dFN", $key);
+ }
+ }
+ return undef;
+ ####ListeningMode
+ } elsif ( $cmd eq "listeningMode" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd ".dq($arg);
+ foreach my $key ( keys %{$hash->{helper}{LISTENINGMODES}} ) {
+ if ( $hash->{helper}{LISTENINGMODES}->{$key} eq $arg ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd ".dq($arg)." -> found nr: ".$key." for listeningMode ".dq($arg);
+ PIONEERAVR_Write($hash, sprintf "%04dSR", $key);
+ return undef;
+ }
+ }
+ my $err= "PIONEERAVR $name: Error: unknown listeningMode $cmd --- $arg !";
+ Log3 $name, 5, $err;
+ return $err;
+
+ #####VolumeStraight (-80.5 - 12) in dB
+ ####according to http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
+ } elsif ( $cmd eq "volumeStraight" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd ".dq($arg);
+ my $zahl = 80.5 + $arg;
+ # Main Zone double as we have 0.5 db steps
+ PIONEERAVR_Write($hash, sprintf "%03dVL", $zahl*2);
+ return undef;
+ ####Volume (0 - 100) in %
+ ####according to http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
+ } elsif ( $cmd eq "volume" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd ".dq($arg);
+ my $zahl = sprintf "%d", $arg * 1.85;
+ PIONEERAVR_Write($hash, sprintf "%03dVL", $zahl);
+ return undef;
+ ####Mute (on|off|toggle)
+ ####according to http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
+ } elsif ( $cmd eq "mute" ) {
+ if ($arg eq "on") {
+ PIONEERAVR_Write($hash, "MO");
+ readingsSingleUpdate($hash, "mute", "on", 1 );
+ }
+ elsif ($arg eq "off") {
+ PIONEERAVR_Write($hash, "MF");
+ readingsSingleUpdate($hash, "mute", "off", 1 );
+ }
+ elsif ($arg eq "toggle") {
+ PIONEERAVR_Write($hash, "MZ");
+ } else {
+ my $err= "PIONEERAVR $name: Error: unknown set ... mute argument: $arg !";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ return undef;
+ #### channelStraight
+ #### set tuner preset in Pioneer preset format (A1...G9)
+ #### Only available if the input is 02 (tuner)
+ #### X0YPR -> X = tuner preset class (A...G), Y = tuner preset number (1...9)
+ } elsif ($cmd eq "channelStraight" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd for inputNr: $inputNr $arg (tuner command only available for 02)";
+ if (($inputNr eq "02") && $arg =~ m/([A-G])([1-9])/ ) {
+ my $setCmd= $1."0".$2."PR";
+ PIONEERAVR_Write($hash,$setCmd);
+ } else {
+ my $err= "PIONEERAVR $name: Error: set ... channelStraight only available for input 02 (tuner) - not for $inputNr !";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ return undef;
+ #### channel
+ ####according to http://www.fhemwiki.de/wiki/DevelopmentGuidelinesAV
+ #### set tuner preset numeric (1...9)
+ #### Only available if the input is 02 (tuner)
+ #### XTP -> X = tuner preset number (1...9)
+ } elsif ($cmd eq "channel" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd for inputNr: $inputNr $arg (tuner command)";
+ if (($inputNr eq "02") && $arg =~ m/([1-9])/ ) {
+ my $setCmd= $1."TP";
+ PIONEERAVR_Write($hash,$setCmd);
+ } else {
+ my $err= "PIONEERAVR $name: Error: set ... channel only available for input 02 (tuner) - not for $inputNr !";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ return undef;
+ ####Speakers (off|A|B|A+B)
+ } elsif ( $cmd eq "speakers" ) {
+ Log3 $name, 5, "PIONEERAVR $name: set $cmd $arg";
+ if ($arg eq "off") {
+ PIONEERAVR_Write($hash, "0SPK");
+ } elsif ($arg eq "A") {
+ PIONEERAVR_Write($hash, "1SPK");
+ } elsif ($arg eq "B") {
+ PIONEERAVR_Write($hash, "2SPK");
+ } elsif ($arg eq "A+B") {
+ PIONEERAVR_Write($hash, "3SPK");
+ } else {
+ my $err= "PIONEERAVR $name: Error: unknown argument $arg in set ... speakers. Must be one of off, A, B, A+B !";
+ Log3 $name, 5, $err;
+ return $err;
+ }
+ return undef;
+ } else {
+ return SetExtensions($hash, $list, $name, $cmd, @a);
+ }
+ } else {
+ return SetExtensions($hash, $list, $name, $cmd, @a);
+ }
+}
+#####################################
+sub
+PIONEERAVR_Get($@)
+{
+ my ($hash, @a) = @_;
+
+ return "get needs at least one parameter" if(@a < 2);
+
+ my $name = $a[0];
+ my $cmd= $a[1];
+ my $arg = ($a[2] ? $a[2] : "");
+ my @args= @a; shift @args; shift @args;
+ my ($answer, $err);
+
+ return "No get $cmd for dummies" if(IsDummy($name));
+ ####Raw
+ #### sends $arg to the PioneerAVR
+ if($cmd eq "raw") {
+ my $allArgs= join " ", @args;
+ Log3 $name, 5, "PIONEERAVR $name: sending raw command ".dq($allArgs);
+ PIONEERAVR_Write($hash, $allArgs);
+ ####loadInputNames
+ } elsif ( $cmd eq "loadInputNames" ) {
+ Log3 $name, 5, "PIONEERAVR $name: processing get loadInputNames";
+ PIONEERAVR_askForInputNames($hash, 5);
+ return undef;
+
+ } elsif(!defined($hash->{helper}{GETS}{main}{$cmd})) {
+ my $gets= "";
+ foreach my $key ( keys %{$hash->{helper}{GETS}{main}} ) {
+ $gets.= $key.":noArg ";
+ }
+ return "$name error: unknown argument $cmd, choose one of raw loadInputNames:noArg " . $gets;
+ ####get commands for the main zone without arguments
+ #### Fhem commands are translated to PioneerAVR commands as defined in PIONEERAVR_Define -> {helper}{GETS}{main}
+ } elsif(defined($hash->{helper}{GETS}{main}{$cmd})) {
+ Log3 $name, 5, "PIONEERAVR $name: processing get ". dq($cmd);
+ my $pioneerCmd= $hash->{helper}{GETS}{main}{$cmd};
+ my $v= PIONEERAVR_Write($hash, $pioneerCmd);
+ }
+}
+
+#####################################
+sub
+PIONEERAVR_Attr($@)
+{
+ my @a = @_;
+ my $hash= $defs{$a[1]};
+ return undef;
+}
+
+#####################################
+sub
+PIONEERAVR_Reopen($)
+{
+ my ($hash) = @_;
+ DevIo_CloseDev($hash);
+ DevIo_OpenDev($hash, 1, undef);
+
+ return undef;
+}
+
+#####################################
+# called from the global loop, when the select for hash->{FD} reports data
+# PIONEERAVR_Read() makes sure, that a message is complete and correct, and calls the global Dispatch() with one message
+sub PIONEERAVR_Read($)
+{
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+ my $state='';
+ my $buf = '';
+ #include previous partial message
+ if(defined($hash->{PARTIAL}) && $hash->{PARTIAL}) {
+ $buf = $hash->{PARTIAL} . DevIo_SimpleRead($hash);
+ }
+ else {
+ $buf = DevIo_SimpleRead($hash);
+ }
+ return if($buf eq '');
+
+ PIONEERAVR_Log $hash, undef, "Spontaneously received " . dq($buf);
+
+ Log3 $name, 5, "PIONEERAVR $name RAW: ". dq($buf);
+
+ # $buf can contain more than one line of information
+ # the lines are separated by "\r\n"
+ # if the information in the line is not for the main zone it is dispatched to
+ # all listening modules otherwise we process it here
+ readingsBeginUpdate($hash);
+ while($buf =~ m/^(.*?)\r\n(.*)\Z/s ) {
+ my $line = $1;
+ $buf = $2;
+
+ Log3 $name, 5, "PIONEERAVR $name: line received from PIONEERAVR: " . dq($line);
+ Log3 $name, 5, "PIONEERAVR $name: line to do soon PIONEERAVR: " . dq($buf) unless ($buf eq "");
+ if (( $line eq "R" ) ||( $line eq "" )) {
+ Log3 $hash, 5, "PIONEERAVR $name: Supressing received " . dq($line);
+ next;
+ # Main zone volume
+ } elsif ( substr($line,0,3) eq "VOL" ) {
+ my $volume = substr($line,3,3);
+ readingsBulkUpdate($hash, "volumeStraight", $volume/2 - 80 );
+ readingsBulkUpdate($hash, "volume", sprintf "%d", $volume/1.85 );
+ Log3 $name, 5, "PIONEERAVR $name: ". dq($line) ." interpreted as: Main Zone - New volume = ".$volume . " (raw volume data).";
+ # Main zone Mute
+ } elsif ( substr($line,0,3) eq "MUT" ) {
+ my $mute = substr($line,3,1);
+ if ($mute == "1") {
+ readingsBulkUpdate($hash, "mute", "off" );
+ Log3 $name, 5, "PIONEERAVR $name: ".dq($line) ." interpreted as: Main Zone - Mute off ";
+ }
+ else {
+ readingsBulkUpdate($hash, "mute", "on" );
+ Log3 $name, 5, "PIONEERAVR $name: ".dq($line) ." interpreted as: Main Zone - Mute on ";
+ }
+ # Main zone Input
+ } elsif ( $line =~ m/^FN(\d\d)$/) {
+ my $inputNr = $1;
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Main Zone - Input is set to inputNr: $inputNr ";
+
+ if ( $hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName} ) {
+ readingsBulkUpdate($hash, "input", $hash->{helper}{INPUTNAMES}{$inputNr}{aliasName} );
+ Log3 $hash,5,"PIONEERAVR $name: Main Input aliasName for input $inputNr is " . $hash->{helper}{INPUTNAMES}{$inputNr}{aliasName};
+ } elsif ( defined ( $hash->{helper}{INPUTNAMES}{$inputNr}{name}) ) {
+ readingsBulkUpdate($hash, "input", $hash->{helper}{INPUTNAMES}{$inputNr}{name} );
+ Log3 $hash,5,"PIONEERAVR $name: Main Input Name for input $inputNr is " . $hash->{helper}{INPUTNAMES}{$inputNr}{name};
+ } else {
+ readingsBulkUpdate($hash, "input", $line );
+ Log3 $hash,5,"PIONEERAVR $name: Main InputName: can't find Name for input $inputNr";
+ }
+ $hash->{helper}{main}{CURINPUTNR} = $inputNr;
+
+ # input names
+ # RGBXXY(14char)
+ # XX -> input number
+ # Y -> 1: aliasName; 0: Standard (predefined) name
+ # 14char -> name of the input
+ } elsif ( $line=~ m/^RGB(\d\d)(\d)(.*)/ ) {
+ my $inputNr = $1;
+ my $isAlias = $2; #1: aliasName; 0: Standard (predefined) name
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Name for InputNr: $inputNr is ".dq($3);
+ # remove non alnum
+ $line =~ s/[^a-zA-Z 0-9]/ /g;
+ # uc first
+ $line =~ s/([\w']+)/\u\L$1/g;
+ # remove whitespace
+ $line =~ s/\s//g;
+ # lc first
+ if ($isAlias) {
+ $hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName} = lcfirst(substr($line,6));
+ } else {
+ $hash->{helper}{INPUTNAMES}->{$inputNr}{name} = lcfirst(substr($line,6));
+ }
+ $hash->{helper}{INPUTNAMES}->{$inputNr}{enabled} = 1 if ( !defined($hash->{helper}{INPUTNAMES}->{$inputNr}{enabled}));
+ $hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName} = "" if ( !defined($hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName}));
+ Log3 $hash,5,"$name: Input name for input $inputNr is " . lcfirst(substr($line,6));
+
+ # input enabled
+ } elsif ( $line=~ m/^SSC(\d\d)030(1|0)$/ ) {
+
+ # select(undef, undef, undef, 0.001);
+ # check for input skip information
+ # format: ?SSC<2 digit input function nr>03
+ # response: SSC<2 digit input function nr>0300: use
+ # response: SSC<2 digit input function nr>0301: skip
+ # response: E06: inappropriate parameter (input function nr not available on that device)
+ # we can not trust "E06" as it is not sure that it is the reply for the current input nr
+
+ if ( $2 == 1) {
+ $hash->{helper}{INPUTNAMES}->{$1}{enabled} = 0;
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: InputNr: $1 is disabled";
+ } elsif ( $2 == 0) {
+ $hash->{helper}{INPUTNAMES}->{$1}{enabled} = 1;
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: InputNr: $1 is enabled";
+ }
+
+ # Speaker
+ } elsif ( substr($line,0,3) eq "SPK" ) {
+ my $speakers = substr($line,3,1);
+ if ($speakers == "0") {
+ readingsBulkUpdate($hash, "speakers", "off" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: speakers: off";
+ } elsif ($speakers == "1") {
+ readingsBulkUpdate($hash, "speakers", "A" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: speakers: A";
+ } elsif ($speakers == "2") {
+ readingsBulkUpdate($hash, "speakers", "B" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: speakers: B";
+ } elsif ($speakers == "3") {
+ readingsBulkUpdate($hash, "speakers", "A+B" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: speakers: A+B";
+ } else {
+ readingsBulkUpdate($hash, "speakers", $speakers );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: speakers: ". dq($speakers);
+ }
+ # Speaker System
+ # do we have Zone 2 speakers?
+ } elsif ( substr($line,0,3) eq "SSF" ) {
+ if ( defined ( $hash->{helper}{SPEAKERSYSTEMS}->{substr($line,3,2)}) ) {
+ readingsBulkUpdate($hash, "speakerSystem", $hash->{helper}{SPEAKERSYSTEMS}->{substr($line,3,2)} );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: SpeakerSystem: ". dq(substr($line,3,2));
+ }
+ else {
+ readingsBulkUpdate($hash, "speakerSystem", $line );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Unknown SpeakerSystem " . dq(substr($line,3,2));
+ }
+ # Listening Mode
+ } elsif ( substr($line,0,2) eq "SR" ) {
+ if ( defined ( $hash->{helper}{LISTENINGMODES}->{substr($line,2)}) ) {
+ readingsBulkUpdate($hash, "listeningMode", $hash->{helper}{LISTENINGMODES}->{substr($line,2)} );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: listeningMode: ". dq(substr($line,2));
+ }
+ else {
+ readingsBulkUpdate($hash, "listeningMode", $line );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: unknown listeningMode: ". dq(substr($line,2));
+ }
+ # Listening Mode Playing (for Display)
+ } elsif ( substr($line,0,2) eq "LM" ) {
+ if ( defined ( $hash->{helper}{LISTENINGMODESPLAYING}->{substr($line,2,4)}) ) {
+ readingsBulkUpdate($hash, "listeningModePlaying", $hash->{helper}{LISTENINGMODESPLAYING}->{substr($line,2,4)} );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: listeningModePlaying: ". dq(substr($line,2,4));
+ }
+ else {
+ readingsBulkUpdate($hash, "listeningModePlaying", $line );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: unknown listeningModePlaying: ". dq(substr($line,2,4));
+ }
+ # Main zone Power
+ } elsif ( substr($line,0,3) eq "PWR" ) {
+ my $power = substr($line,3,1);
+ if ($power == "0") {
+ readingsBulkUpdate($hash, "power", "on" );
+ $state = "on";
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Power: on";
+ } else {
+ readingsBulkUpdate($hash, "power", "off" );
+ $state = "off";
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Power: off";
+ }
+ # Set reading for state
+ #
+ if ( !defined( $hash->{READINGS}{state}{VAL} )
+ || $hash->{READINGS}{state}{VAL} ne $state )
+ {
+ readingsBulkUpdate( $hash, "state", $state );
+ }
+ # Display updates
+ } elsif ( substr($line,0,2) eq "FL" ) {
+ my $display = pack("H*",substr($line,4,28));
+ readingsBulkUpdate($hash, "displayPrevious", ReadingsVal($name,"display","") );
+ readingsBulkUpdate($hash, "display", $display );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Display update";
+
+ # Tuner channel names
+ } elsif ( $line =~ m/^TQ(\w\d)\"(.{8})\"$/ ) {
+ $hash->{helper}{TUNERCHANNELNAMES}{$1} = $2;
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: tunerChannel: $1 has the name: " .dq($2);
+ # Tuner channel
+ } elsif ( $line =~ m/^PR(\w)0(\d)$/ ) {
+ readingsBulkUpdate($hash, "channelStraight", $1.$2 );
+ readingsBulkUpdate($hash, "channelName", $hash->{helper}{TUNERCHANNELNAMES}{$1.$2} );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Current tunerChannel: " . $1.$2;
+ if ($1 eq "A") {
+ readingsBulkUpdate($hash, "channel", $2);
+ } else {
+ readingsBulkUpdate($hash, "channel", "-");
+ }
+ # Tuner frequency
+ # FRFXXXYY -> XXX.YY Mhz
+ } elsif ( $line =~ m/^FRF([0|1])([0-9]{2})([0-9]{2})$/ ) {
+ my $tunerFrequency = $2.".".$3;
+ if ($1==1) {
+ $tunerFrequency = $1.$tunerFrequency;
+ }
+ readingsBulkUpdate($hash, "tunerFrequency", $tunerFrequency);
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: tunerFrequency: " . $tunerFrequency;
+
+ # model
+ } elsif ( $line =~ m/^RGD<\d{3}><(.*)\/.*>$/ ) {
+ readingsBulkUpdate($hash, "model", $1);
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: Model is " . $1;
+
+ # Software version
+ } elsif ( $line =~ m/^SSI\"(.*)\"$/ ) {
+ readingsBulkUpdate($hash, "softwareVersion", $1);
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: softwareVersion is " . $1;
+
+ # ERROR MESSAGES
+ # E02 NOT AVAILABLE NOW Detected the Command line which could not work now.
+ # E03 INVALID COMMAND Detected an invalid Command with this model.
+ # E04 COMMAND ERROR "Detected inappropriate Command line.
+ # Detected IP-only Commands on RS232C (GIA,GIC,FCA,FCB,GIH and GII)."
+ # E06 PARAMETER ERROR Detected inappropriate Parameter.
+ # B00 BUSY Now AV Receiver is Busy. Please wait few seconds.
+
+ } elsif ( $line =~ m/^E0(\d)$/ ) {
+ my $errorMessage ="PIONEERAVR $name: Received Error code from PioneerAVR: $line";
+ if ($1 == 2) {
+ $errorMessage .= " (NOT AVAILABLE NOW - Detected the Command line which could not work now.)";
+ } elsif ($1 == 3) {
+ $errorMessage .= " (INVALID COMMAND - Detected an invalid Command with this model.)";
+ } elsif ($1 == 4) {
+ $errorMessage .= " (COMMAND ERROR - Detected inappropriate Command line.)";
+ } elsif ($1 == 6) {
+ $errorMessage .= " (PARAMETER ERROR - Detected inappropriate Parameter.)";
+ }
+ Log3 $hash, 5, $errorMessage;
+ } elsif ( $line =~ m/^B00$/ ) {
+ Log3 $hash, 5,"PIONEERAVR $name: Error nr $line received (BUSY Now AV Receiver is Busy. Please wait few seconds.)";
+ # network standby
+ # STJ1 -> on -> Pioneer AVR can be switched on from standby
+ # STJ0 -> off -> Pioneer AVR cannot be switched on from standby
+ } elsif ( $line =~ m/^STJ([0|1])/) {
+ if ($1 == "1") {
+ readingsBulkUpdate($hash, "networkStandby", "on" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: networkStandby is on";
+ }
+ else {
+ readingsBulkUpdate($hash, "networkStandby", "off" );
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: networkStandby is off";
+ }
+ # dispatch "zone" - commands to other zones
+ # Volume, mute, power
+ } elsif ($line =~ m/^[Y|Z]V(\d\d)$|^Z[2|3]MUT(\d)$|^Z[2|3]F(\d\d)$|^[A|B]PR(0|1)$|^ZEA(\d\d)$|^ZEP(0|1)$/) {
+ Dispatch($hash, $line, undef); # dispatch result to PIONEERAVRZONEs
+ Log3 $hash,5,"PIONEERAVR $name: ".dq($line) ." interpreted as: not for the Main zone -> dispatch to PIONEERAVRZONEs";
+ } else {
+ Log3 $hash, 5, "PIONEERAVR $name: received $line - don't know what this means - help me!";
+ }
+ }
+ readingsEndUpdate($hash, 1);
+ $hash->{PARTIAL} = $buf;
+}
+
+
+#########################################################
+
+sub PIONEERAVR_askForInputNames($$) {
+ my ($hash, $loglevel) = @_;
+ my $name = $hash->{NAME};
+ my $comstr = '';
+
+ # we ask for the inputs 1 to 49 if an input name exists (command: ?RGB00 ... ?RGB49)
+ # we ask for the inputs 1 to 49 if the input is disabled (command: ?SSC0003 ... ?SSC4903)
+ #
+ for ( my $i=0; $i<50; $i++ ) {
+ select(undef, undef, undef, 0.1);
+ $comstr = sprintf '?RGB%02d', $i;
+ PIONEERAVR_Write($hash,$comstr);
+ select(undef, undef, undef, 0.1);
+ $comstr = sprintf '?SSC%02d03',$i;
+ PIONEERAVR_Write($hash,$comstr);
+ }
+}
+#####################################
+# Callback from 95_remotecontrol for command makenotify.
+sub PIONEERAVR_RCmakenotify($$) {
+ my ($nam, $ndev) = @_;
+ my $nname="notify_$nam";
+
+ fhem("define $nname notify $nam set $ndev remoteControl ".'$EVENT',1);
+ Log3 undef, 2, "PIONEERAVR [remotecontrol:PIONEERAVR] Notify created: $nname";
+ return "Notify created by PIONEERAVR: $nname";
+}
+
+#####################################
+# Default-remote control layout for Pioneer AVR
+sub
+RC_layout_PioneerAVR() {
+ my $ret;
+ my @row;
+ $row[0]="toggle:POWEROFF";
+ $row[1]="volumeUp:UP,mute toggle:MUTE,inputUp:CHUP";
+ $row[2]=":VOL,:blank,:PROG";
+ $row[3]="channelDown:DOWN,:blank,channelDown:CHDOWN";
+ $row[4]="attr rc_iconpath icons/remotecontrol";
+ $row[5]="attr rc_iconprefix black_btn_";
+
+ # unused available commands
+ return @row;
+}
+#####################################
+
+
+1;
+
+=pod
+=begin html
+
+
+PIONEERAVR
+
+ This module allows to remotely control a Pioneer AV receiver (only the MAIN-zone, other zones are controlled by the module PIONEERAVRZONE)
+ equipped with an ethernet interface or a RS232 port.
+ It enables Fhem to
+
+ - switch ON/OFF the receiver
+ - adjust the volume
+ - set the input source
+ - and configure some other parameters
+
+
+ This module is based on the Pioneer documentation
+ and tested with a Pioneer AVR VSX-923 from Pioneer.
+
+ Note: this module requires the Device::SerialPort or Win32::SerialPort module
+ if the module is connected via serial Port or USB.
+
+ This module tries to
+
+ - keep the data connection between Fhem and the Pioneer AV receiver open. If the connection is lost, this module tries to reconnect once
+ - forwards data to the module PIONEERAVRZONE to control the ZONEs of a Pioneer AV receiver
+
+ As long as Fhem is connected to the Pioneer AV receiver no other device (e.g. a smartphone) can connect to the Pioneer AV receiver on the same port.
+ Some Pioneer AV receivers offer more than one port though.
+
+
+ Define
+
+ define <name> PIONEERAVR telnet <IPAddress:Port>
+ or
+ define <name> PIONEERAVR serial <SerialDevice>[<@BaudRate>]
+
+
+ Defines a physical PIONEERAVR device. The keywords telnet
or
+ serial
are fixed. Default port on Pioneer AV receivers is 23 (according to the above mentioned Pioneer documetation)
+
+ Examples:
+
+ define VSX923 PIONEERAVR telnet 192.168.0.91:23
+ define VSX923 PIONEERAVR serial /dev/ttyS0
+ define VSX923 PIONEERAVR serial /sev/ttyUSB0@9600
+
+
+
+
+
+ Set
+
+ set <name> <what> [<value>]
+
+ where <what> is one of
+ - reopen
Tries to reopen the data connection
+ - statusRequest
gets some information from the physical Pioneer AVR and updates the readings accordingly
+ - off
turn power off
+ - on
turn power on
+ - toggle
toggles power
+ - volume <0 ... 100>
main volume in % of the maximum volume
+ - volumeUp
increases the main volume by 0.5dB
+ - volumeDown
decreases the main volume by 0.5dB
+ - volumeStraight<-80.5 ... 12>
same values for volume as shown on the display of the Pioneer AV rreceiver
+ - mute
+ - input
the list of possible (i.e. not deactivated)
+ inputs is read in during Fhem start and with get statusRequest
+ - inputUp
change input to next input
+ - inputDown
change input to previous input
+ - listeningMode
+ - play
starts playback for the following inputs: AdapterPort, Ipod, Favorites, InternetRadio, MediaServer, Mhl
+ - pause
pause playback for the same inputs as play
+ - stop
stops playback for the same inputs as play
+ - repeat
repeat for the following inputs: AdapterPort, Ipod, Favorites, InternetRadio, MediaServer
+ - shuffle
random play for the same inputs as repeat
+
+ Example:
+
+
+ set <name> reopen
+
+ Closes and reopens the device. Could be handy if the connection between Fhem and the Pioneer AV receiver is lost and cannot be
+ reestablished automatically.
+
+
+
+
+ Get
+
+ get <name> raw <command>
+
+ Sends the command <command>
to the physical Pioneer AVR device
+ <name>
.
+
loadInputNames
reads the names of the inputs from the physical Pioneer AVR
+ and checks if those inputs are enabled
+ - display
updates the reading 'display' and 'displayPrevious' with what is shown
+ on the display of the physical Pioneer AVR
+
+
+
+
+ Attributes
+
+
+ - logTraffic <loglevel>
Enables logging of sent and received datagrams with the given loglevel.
+ Control characters in the logged datagrams are escaped, i.e. a double backslash is shown for a single backslash,
+ \n is shown for a line feed character, etc.
+ - verbose
+
+
+
+
+
+=end html
+=begin html_DE
+
+
+PIONEERAVR
+
+ Dieses Modul erlaubt es einen Pioneer AV Receiver via Fhem zu steuern (nur die MAIN-Zone, etwaige andere Zonen können mit dem Modul PIONEERAVRZONE gesteuert werden) wenn eine Datenverbindung via Ethernet oder RS232 hergestellt werden kann.
+ Es erlaubt Fhem
+
+ - Den Receiver ein/auszuschalten
+ - die Lautstärke zu ändern
+ - die Eingangsquelle auszuwählen
+ - und weitere Parameter zu kontrollieren
+
+
+ Dieses Modul basiert auf der Pioneer documentation
+ und ist mit einem Pioneer AVR VSX-923 von Pioneer getestet.
+
+ Achtung: Dieses Modul benötigt die Perl-Module Device::SerialPort oder Win32::SerialPort
+ wenn die Datenverbindung via USB bzw. rs232 Port erfolgt.
+
+ Dieses Modul versucht
+
+ - die Datenverbindung zwischen Fhem und Pioneer AV Receiver offen zu halten. Wenn die Verbindung abbricht, versucht das Modul
+ einmal die Verbindung wieder herzustellen
+ - Daten vom/zum Pioneer AV Receiver dem Modul PIONEERAVRZONE (für die Kontrolle weiterer Zonen des Pioneer AV Receiver)
+ zur Verfügung zu stellen.
+
+ Solange die Datenverbindung zwischen Fhem und dem Pioneer AV Receiver offen ist, kann kein anderes Gerät (z.B. ein Smartphone)
+ auf dem gleichen Port eine Verbindung zum Pioneer AV Receiver herstellen.
+ Einige Pioneer AV Receiver bieten mehr als einen Port für die Datenverbindung an.
+
+
+ Define
+
+ define <name> PIONEERAVR telnet <IPAddress:Port>
+ or
+ define <name> PIONEERAVR serial <SerialDevice>[<@BaudRate>]
+
+
+ Definiert ein physisches PIONEERAVR device. Die Schlüsselwörter telnet
bzw.
+ serial
sind fix. Der Standard Port für die Ethernet Verbindung bei Pioneer AV Receiver ist 23
+ (laut der oben angeführten Pioneer Dokumetation)
+
+ Beispiele:
+
+ define VSX923 PIONEERAVR telnet 192.168.0.91:23
+ define VSX923 PIONEERAVR serial /dev/ttyS0
+ define VSX923 PIONEERAVR serial /sev/ttyUSB0@9600
+
+
+
+
+
+ Set
+
+ set <name> <was> [<value>]
+
+ "was" ist eines von
+ - reopen
Versucht die Datenverbindung wieder herzustellen
+ - statusRequest
Fragt Information vom physischen Pioneer AV Receiver und aktualisiert die readings entsprechend
+ - off
Ausschalten
+ - on
Einschalten
+ - toggle
Ein/Ausschalten
+ - volume <0 ... 100>
Lautstärke der Main-Zone in % der Maximallautstärke
+ - volumeUp
Lautstärke um 0.5dB erhöhen
+ - volumeDown
Lautstärke um 0.5dB verringern
+ - volumeStraight<-80.5 ... 12>
Einstellen der Lautstärke mit einem Wert, wie er am Display des Pioneer AV Receiver angezeigt wird
+ - mute
+ - input
Die Liste der verfügbaren (also der nicht deaktivierten)
+ Eingangsquellen wird beim Start von Fhem und auch mit get statusRequest
eingelesen
+ - inputUp
nächste Eingangsquelle auswählen
+ - inputDown
vorherige Eingangsquelle auswählen
+ - listeningMode
+ - play
Startet die Wiedergabe für folgende Eingangsquellen: AdapterPort, Ipod, Favorites, InternetRadio, MediaServer, Mhl
+ - pause
Unterbricht die Wiedergabe für die gleichen Eingangsquellen wie "play"
+ - stop
Stoppt die Wiedergabe für die gleichen Eingangsquellen wie "play"
+ - repeat
Wiederholung für folgende Eingangsquellen: AdapterPort, Ipod, Favorites, InternetRadio, MediaServer
+ - shuffle
Zufällige Wiedergabe für die gleichen Eingangsquellen wie "repeat"
+
+ Beispiel:
+
+
+ set <name> reopen
+
+ Schliesst und öffnet ernaut die Datenverbindung von Fhem zum Pioneer AV Receiver.
+ Kann nützlich sein, wenn die Datenverbindung nicht automatisch wieder hergestellt werden kann.
+
+
+
+
+
+ Get
+
+ get <name> raw <Befehl>
+
+ Sendet <Befehl>
an den Pioneer AV Receiver
+ <name>
.
+
loadInputNames
liest die Namen der Eingangsquellen vom Pioneer AV Receiver
+ und überprüft, ob sie aktiviert sind
+ - display
Aktualisiert das reading 'display' und 'displayPrevious' mit der aktuellen Anzeige des Displays Pioneer AV Receiver
+
+
+
+
+ Attribute
+
+
+ - logTraffic <loglevel>
Ermöglicht das loggen der Datenommunikation vom/zum Pioneer AV Receiver.
+ Steuerzeichen werden angezeigtz.B. ein doppelter Ruckwärts-Schrägstrich wird als einfacher Rückwärts-Schrägstrich angezeigt,
+ \n wird für das Steuerzeichen "line feed" angezeigt, etc.
+ - verbose
+
+
+
+
+=end html_DE
+=cut