Yamaha Netzwerk-Steuerung

Im zweiten Artikel dieser Serie möchte ich näher auf die Netzwerksteuerung von Yamaha-Geräten eingehen. Zuletzt hatte ich einen Überblick gegeben, wie verschiedene Komponenten eines Heimkinos per Netzwerk gesteuert werden können und was das für Vorteile hat.

Yamaha RX-V775 und BD-A1010: beide lassen sich per Netzwerk steuern

Heute wird es noch ein Stück technischer. Die meisten von Euch werden das wahrscheinlich bestenfalls überfliegen und sich wundern, was ihre Geräte da noch so alles können. Für die Programmierer unter Euch werde ich ein wenig Quellcode veröffentlichen. Ich zeige Beispiele für PHP und Node.js, die ich in ähnlicher Form im Einsatz habe.

Die Yamaha Netzwerk-Steuerung wird von der hauseigenen App genutzt
Die App von Yamaha zur Steuerung ihrer AV-Receiver

Aber nicht nur mit einer Programmiersprache kann man die Netzwerk-Schnittstelle von Yamaha nutzen. Es gibt jede Menge Software zur Heimautomatisierung, die ebenfalls Befehle per HTTP senden können. Ein Beispiel ist der GIRA HomeServer, über den man die Befehle etwas umständlich ausführen kann. Dieses und ähnliche Produkte erlauben wiederum die Kopplung an Amazon Echo — und spätestens da wird es interessant.

Vorab kann ich nur den Tipp geben, etwas Geduld zu haben und ein paar Stunden freie Zeit einzuplanen. Auf Anhieb wird wahrscheinlich gar nichts funktionieren – jedenfalls war das bei mir so.

Versucht zuerst, die Original-App von Yamaha, erhältlich für Android und iOS, in Eurem Netzwerk zum Laufen zu bringen. Eine Beschreibung ist in der App und natürlich in der Bedienungsanleitung der Geräte verfügbar. Wenn das funktioniert, steht eigenen Versuchen nichts mehr im Weg.

Ausgangssituation

Voraussetzung für die hier gezeigten Beispiele ist ein netzwerkfähiger AV-Receiver oder Blu-ray-Player von Yamaha. Die meisten Geräte der aktuellen Generation verfügen darüber, genauer gesagt eigentlich alle Receiver der Reihen RX-V und RX-A sowie die Player der Reihen BD-S und BD-A. Grundvoraussetzung für die Netzwerk-Steuerung: der Anschluss per Netzwerkkabel oder WLANDas Gerät muss mit dem Netzwerk verbunden sein, das heißt: ein Netzwerkkabel ist angeschlossen und verbindet das Gerät mit dem Router. Eine Internetverbindung ist nicht erforderlich.

Die allerneuesten Modelle verfügen auch über eingebautes WLAN – damit habe ich die hier gezeigten Möglichkeiten aber nicht getestet. Eventuell kann das Einschalten der Geräte nicht über WLAN funktionieren, denn wenn sie ausgeschaltet sind, haben sie ja auch keine WLAN-Verbindung mehr. Beim Anschluss per Netzwerkkabel ist das kein Problem, sofern die Option Network Standby in den Einstellungen aktiv ist.

Was Ihr aus den hier gezeigten Beispielen macht, ist erstmal nebensächlich. Deshalb gehe ich auch nicht zu sehr darauf ein, was Ihr sonst noch braucht. Wenn Ihr programmieren könnt – womit auch immer Ihr programmieren wollt – solltet Ihr ja selbst wissen, welche Umgebung Ihr dafür benötigt und wie Euer Programm auszuführen ist. Ihr solltet die gezeigten Codebeispiele auch auf andere Programmiersprachen übertragen können. Ich habe zwei Wege getestet, die beide eine Webanwendung als Benutzeroberfläche haben:

  • PHP: Ein kleiner Webserver, zum Beispiel XAMPP, dient zum Hosting einer PHP-Website. Wenn man in der Oberfläche einen Button drückt, wird ein PHP-Script aufgerufen, das den Befehl an das Gerät sendet.
  • Node.js: Eine leichtgewichtige JavaScript-Umgebung, mit der ein Webserver erstellt werden kann. Das Prinzip ist das selbe wie bei PHP, nur dass JavaScript die Kommunikation mit dem Gerät übernimmt.

Solltet Ihr grundsätzlich eine Webanwendung schreiben wollen, bedenkt bitte, dass Ihr in jedem Fall eine serverseitige Scriptsprache benötigt. Es ist nicht möglich, direkt mit Client-JavaScript im Browser die Geräte anzusprechen, da die Sicherheitseinstellungen des Browsers das nicht zulassen. PHP und Node.js (serverseitiges JavaScript) werden auf dem Webserver ausgeführt, was die Sache ganz anders aussehen lässt. Alle anderen Programmiersprachen wie Java oder C# haben natürlich ganz andere Ausgangsbedingungen und sollten ohne weitere Umwege auf die im Netzwerk angemeldeten Geräte zugreifen können.

Kommunikation mit den Geräten

Lange Rede, kurzer Sinn – legen wir los. Hier ein Codebeispiel, wie man mit PHP einen Yamaha-Receiver anspricht und einen Befehl sendet. Ich habe auf allzu viele Fehlerüberprüfungen verzichtet, um es einfach zu halten. Das Beispiel verwendet die cURL-Erweiterung, die unter den meisten PHP-Installationen standardmäßig verfügbar sein sollte.

$ip = '192.168.0.47';
$port = 80; // 50100 bei BD-Playern
$command = '<YAMAHA_AV cmd="PUT"><Main_Zone><Volume>' .
   '<Lvl><Val>-455</Val><Exp>1</Exp><Unit>dB</Unit></Lvl>' .
   '</Volume></Main_Zone></YAMAHA_AV>';

$url = 'http://' . $ip . ':' . $port . '/YamahaRemoteControl/ctrl';

$headers = array(
   'Content-Type: text/xml; charset=UTF-8',
   'Content-Length: ' . strlen($command)
);

$request = curl_init();

curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_HTTPHEADER, $headers);

curl_setopt($request, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt($request, CURLOPT_TIMEOUT, 3);

curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($request, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);

curl_setopt($request, CURLOPT_POST, true);
curl_setopt($request, CURLOPT_POSTFIELDS, $command);

$result = curl_exec($request);
$httpCode = curl_getinfo($request, CURLINFO_HTTP_CODE);

if ($httpCode == 0) {
   die('Device not responding');
} else if ($httpCode == 400) {
   die('Bad request');
}

curl_close($request);

echo $result;

Und hier das gleiche in Node.js – auf die paar Zeilen, die zuzüglich noch den Webserver ausmachen, verzichte ich, um nur die reine Funktionalität zu veranschaulichen. Das Script ist ein in sich geschlossenes Node-Modul.

var http = require('http');

function executeCommand (data, onResult)
{
   var host = data.host || '192.168.0.47';
   var port = data.port || 80; // 50100 bei BD-Playern
   var command = '<YAMAHA_AV cmd="PUT"><Main_Zone><Volume>' +
      '<Lvl><Val>-455</Val><Exp>1</Exp><Unit>dB</Unit></Lvl>' +
      '</Volume></Main_Zone></YAMAHA_AV>';
 
   var requestOptions = {
      host: host,
      port: port,
      path: '/YamahaRemoteControl/ctrl',
      method: 'POST',
      headers: {
         'Content-Type': 'text/xml; charset=UTF-8',
         'Content-Length': command.length
      }
   };
 
   var request = http.request(requestOptions, function(response)
   {
      response.setEncoding('utf8');
 
      response.on('data', function (result)
      {
         console.log('Yamaha Response: ' + result);
         onResult(result);
      });
   });
 
   request.setTimeout(2000, function () {
      request.socket.end();
      request.socket.destroy();
   });
 
   request.on('error', function(error)
   {
      console.log('Device not responding');
      onResult('Error: Device not responding');
   });

   request.write(command);
   request.end();
}

module.exports = {
   executeCommand: executeCommand
};

Im Grunde stellen die Yamaha-Geräte von sich aus auch einen internen Webserver zur Verfügung, der unter einem bestimmten Pfad angesprochen werden kann. (Hier kommunizieren also zwei Webserver miteinander.) Die Beispiele bauen eine Verbindung über gewöhnliches HTTP auf, indem sie IP, Port und Pfad des Zielgerätes verwenden. Der eigentliche Befehl wird als POST-Content verpackt und so an das Gerät übertragen. Eine Antwort kommt als Ergebnis der Anfrage zurück, so als wäre es der HTML-Code einer Website. Die Schnittstelle ist also der Vorgehensweise des SOAP-Protokolls sehr ähnlich.

In beiden Beispielen gibt es ein paar ganz wichtige Details (die herauszufinden mich die meiste Zeit gekostet haben).

  • Ein AV-Receiver von Yamaha ist unter seiner IP über den Port 80 erreichbar. Ein Blu-ray Player ist dagegen unter Port 50100 anzusprechen. Immer. Ich habe noch keine Ausnahmen hierzu gefunden und auch keinen Weg, das umzustellen. Es erscheint etwas inkonsistent, ist aber von Yamaha so gesetzt.
  • Beide Arten von Geräten stellen den Pfad /YamahaRemoteControl/ctrl zur Verfügung, unter dem der Webservice zu erreichen ist. Gibt man diesen nicht richtig an, reagiert das Gerät nicht. Logisch, muss man aber wissen.
  • Die XML-Syntax des Befehls muss fehlerfrei sein – eigentlich selbstverständlich. Die XML-Deklaration kann angegeben oder weggelassen werden.
  • Attribute in der XML-Syntax müssen von doppelten Anführungszeichen umschlossen sein. Abweichend vom XML-Standard sind einfache Anführungszeichen nicht erlaubt.

Die XML-Syntax

Die eigentliche Arbeit beginnt erst mit dem Verstehen der XML-Syntax, die an die Geräte gesendet werden kann. Sie weist zwischen Receivern und Playern viele Gemeinsamkeiten auf, ist aber ansonsten völlig unterschiedlich, da die Geräte natürlich unterschiedliche Befehle kennen.

Nachfolgend ein paar Beispiele. Der erste XML-String ist jeweils die Anfrage, die zum Gerät gesendet wird, der zweite ist die Antwort, die man zurück bekommt. Ich habe ein paar Interessante Befehle herausgesucht, um deren Details zu erläutern.

Power

<YAMAHA_AV cmd="PUT"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>

Das ist ein sehr simpler Befehl für einen Blu-ray-Player. Statt On als Wert zu übergeben, wäre alternativ auch Network Standby möglich, wenn man den Player ausschalten will. Network Standby ist deshalb wichtig, damit das Geräte für die Netzwerk-Steuerung erreichbar bleibt, obwohl es ausgeschaltet ist.

Und hier die Antwort des Players auf diesen Befehl:

<YAMAHA_AV rsp="PUT" RC="0"><Main_Zone><Power_Control><Power></Power></Power_Control></Main_Zone></YAMAHA_AV>

Als Antwort kommt eine entsprechend ähnliche XML-Syntax zurück. Das Attribut RC="0" gibt dabei an, dass der Befehl erfolgreich ausgeführt wurde. Der aktuelle Power-Zustand wird nicht mitgeliefert, den müsste man bei Bedarf extra erfragen.

Es fällt übrigens auf, dass der Player auch über eine Zone verfügt. Normalerweise haben nur Receiver zwei oder mehr Zonen. Wahrscheinlich damit es einheitlich bleibt, hat Yamaha aber auch den Playern eine Zone untergejubelt, die sich in den Befehlen wiederfindet.

Volume

<YAMAHA_AV cmd="PUT"><Main_Zone><Volume><Lvl><Val>-455</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>

Die Lautstärke eines Receivers ist ein gutes Beispiel für die Vielseitigkeit der Befehle. Neben den oft gebräuchlichen relativen Angaben wie 1 Up, 2 Down oder einfach nur Up und Down (was den Tasten der Fernbedienung entspricht), gibt es hier die Möglichkeit, einen konkreten Wert anzugeben. Die Angabe in Val ist der Dezibel-Wert, den man einstellen möchte. Die Angabe in Exp ist der Exponent, oder einfach ausgedrückt, die Anzahl der Stellen des Wertes, die eigentlich Nachkommastellen sein sollen. Der Dezibel-Wert, der hier eingestellt werden soll, ist also eigentlich -45,5, nicht -455. Der letzte Teil gibt die Maßeinheit an.

Das sieht erstmal komplizierter aus, als es sein müsste. Tatsächlich hat das aber was mit der Wiederverwendbarkeit der XML-Struktur zu tun. Derartige Values werden auch für andere Angaben als nur die Lautstärke verwendet. Deshalb muss das Konstrukt entsprechend flexibel sein.

Input

<YAMAHA_AV cmd="PUT"><Main_Zone><Input><Input_Sel>HDMI1</Input_Sel></Input></Main_Zone></YAMAHA_AV>

Der aktuelle Eingang lässt sich sehr einfach festlegen. Es gibt fest definierte Werte, die übergeben werden können, zum Beispiel HDMI1, AV4, USB, TUNER und andere. Ähnlich funktioniert das auch, wenn man das DSP-Programm oder den Surround-Decoder einstellen will.

RC-Codes

Manchmal ist die XML-Syntax fast schon zu mächtig. So scheint es zum Beispiel bei einem Player (im Gegensatz zu einem Receiver) nicht möglich zu sein, einen Power-Toggle-Befehl zu senden. Wer damit nichts anfangen kann: Bei dem Power-Befehl oben wird immer der angegebene Wert gesetzt, egal, ob das Gerät gerade ein- oder ausgeschaltet ist. Ist es eingeschaltet und man schaltet es nochmal ein, bleibt es eben an. Bei einem Toggle-Befehl wird der aktuelle Zustand umgekehrt. Man sendet also immer den selben Befehl, und das Gerät schaltet sich an, wenn es aus ist, und aus, wenn es an ist.

Andererseits ist diese Funktionalität vorhanden, denn die Fernbedienung kann das ja auch: dort gibt es eine einzige Taste, zum An- und Ausschalten. Ähnliches passiert, wenn man den Sleep-Timer eines Receivers setzt: Per XML-Syntax lässt sich nur ein konkreter Wert wie 120 min, 30 min oder Off setzen – ungünstig, wenn man nur eine Taste dafür haben will, die wie auf der Original-Fernbedienung funktioniert.

<YAMAHA_AV cmd="PUT"><Main_Zone><Remote_Control><RC_Code>7C80</RC_Code></Remote_Control></Main_Zone></YAMAHA_AV>

Die Lösung ist dieser ganz einfache XML-Befehl, der nichts anderes macht, als die Tastencodes der Fernbedienung auszuführen. Man sucht sich aus der Dokumentation den passenden Tastencode heraus und gibt diesen als Parameter an. Das funktioniert bestens, um die exakte Funktionalität der Fernbedienung zu kopieren.

Playinfo

<YAMAHA_AV cmd="GET"><Main_Zone><Play_Info>GetParam</Play_Info></Main_Zone></YAMAHA_AV>

Dieser Befehl ist ein gutes Beispiel für die Abfrage von Statusinformationen. In diesem Fall greifen wir wieder auf einen Blu-ray-Player zu, nicht auf einen Receiver. Zu beachten ist, dass hier ein GET-Befehl gesendet wird, kein PUT. PUT setzt einen Wert, GET liest einen aktuellen Wert aus. An der Stellen, wo GetParam steht, wird ein Wert erwartet.

Und hier die Antwort des Players auf diese Anfrage:

<YAMAHA_AV rsp="GET" RC="0">
   <Main_Zone>
      <Play_Info>
         <Status>Play</Status>
         <Playback_Speed>0</Playback_Speed>
         <Tray>Close</Tray>
         <Contents>
            <Type>video</Type>
            <Title>0</Title>
            <Track>0</Track>
            <Chapter>4</Chapter>
            <File_Num>2</File_Num>
            <File_Name>Urlaubsvideo (2008).mkv</File_Name>
         </Contents>
         <Current_PlayTime>00112C</Current_PlayTime>
         <Input_Info>USB</Input_Info>
         <Disc_Info>
            <Disc_Type>No Disc</Disc_Type>
            <Track_Num>0</Track_Num>
            <Total_Time>010623</Total_Time>
         </Disc_Info>
         <USB_Info>
            <USB_Status>Ready</USB_Status>
         </USB_Info>
         <Network_Info>
            <Contents_Type>Not Ready</Contents_Type>
         </Network_Info>
      </Play_Info>
   </Main_Zone>
</YAMAHA_AV>

Mit einem einzigen Befehl werden hier sämtliche Statusinformationen des Players abgerufen, die sich auf das aktuell abgespielte Filmmaterial beziehen. Daraus lässt sich zum Beispiel entnehmen, ob eine Disc abgespielt wird, oder ob Inhalte von USB oder Netzwerk angezeigt werden. Die Art der Disc lässt sich ebenso erkennen wie Track- oder Kapitelnummern.

Besonders nützlich für gehobenere Anwendungen sind die Angaben CurrentPlayTime und TotalPlayTime: Die Werte sind hexadezimal codiert und geben – wer hätte es gedacht? – die aktuelle Spielzeit und die Gesamtspielzeit zurück. Daraus lässt sich dann zum Beispiel ganz einfach die Restspielzeit errechnen, oder was man sonst damit machen will. Auf diese Weise könnte eine App die Spielzeit anzeigen (welche Universalfernbedienung kann das schon?) oder zu bestimmten Zeiten im Film irgendetwas automatisch aktivieren (das Licht, wenn der Abspann beginnt).

Etwas wackelig ist die Rückgabe der Gesamtspielzeit. Diese scheint nur für CDs vorgesehen zu sein. Tatsächlich geben Player der Serie BD-S bei DVDs und BDs immer 0 zurück. Allerdings hatte ich schon einen Player der BD-A Serie, der hier immer etwas geliefert hat, unabhängig vom Disc-Typ. Intern ist der Wert auf jeden Fall bekannt, aber man kommt eben nicht immer ran. Ärgerlich!

Dokumentation

Woher bekommt man diese ganzen Befehle? Die Geräte selbst verraten sie einem jedenfalls nicht. Ich musste eine ganze Weile suchen, bis ich im Internet entsprechende Dokumente finden konnte. Die Dokumentationen werden von Yamaha nicht öffentlich zur Verfügung gestellt, sondern sind Vertriebspartnern vorbehalten. Aus rechtlichen Gründen darf ich hier also auch nichts davon zur Verfügung stellen. Wenn Ihr die Dokumentationen haben möchtet, hier zwei Tipps:

  • Wendet Euch per Mail an den Yamaha-Support, nennt Euer Anliegen und die Gerätebezeichnungen, für die Ihr die Daten benötigt. Ein paar Tage später solltet Ihr alles bekommen, was Ihr benötigt.
  • Nutzt eine Suchmaschine, um nach Yamaha RX Function Tree oder konkreter zum Beispiel Yamaha BD-A1010 Function Tree zu suchen. Die wesentliche Dokumentation ist eine Excel-Tabelle mit dem Titel Function Tree.
Yamaha Netzwerk-Steuerung in eine eigene App verpackt
Eine mögliche Variante, wie eine selbst entwickelte Fernbe­dienung aussehen könnte

Die besagte Excel-Tabelle listet alle verfügbaren Befehle in einer Baumstruktur auf. Sie bietet darüber hinaus Makros, mit denen die Befehle gleich generiert werden können. Fast noch nützlicher sind Listen als Textdatei, die eine gesamte Liste aller Befehle enthalten – diese lassen sich aus der Excel-Dokumentation ebenfalls generieren und sind hier und da als Download zu finden, wenn man Glück hat.

Neuere Versionen der Dokumentation bestehen aus einem Archiv, das eine HTML-basierte Dokumentation enthält. Diese ist deutlich aufgeräumter, aber auch nicht unbedingt leichter verständlich. Auch hier ist die beste Referenz eine Textdatei, die für jedes Gerät sämtliche verfügbaren Befehle listet.

Man findet nicht immer die Dokumentation für exakt den gewünschten Gerätetyp. Die Befehle sind aber auf allen Modellen gleich, sofern sie unterstützt werden. Man kann die meisten Befehle auch aus der Dokumentation für ein höheres Modell entnehmen.

Hier und da findet man weitere Dokumente, die die grundlegende Schnittstelle nochmals erläutern. Es kann nicht schaden, das alles mal irgendwo zu sammeln. Die Möglichkeiten gehen noch etwas über die hier gezeigten Beispiele hinaus. So ist es etwa auch möglich, die Yamaha-Geräte im Netzwerk überhaupt erstmal aufzuspüren. Das ist ganz praktisch, wenn man die IP-Adresse nicht kennt, weil sich diese häufig ändert. Die App vom Hersteller nutzt das auf ihrer Startseite.


Die hier auf die Yamaha Netzwerk-Steuerung bezogenen Beispiele sollten in ähnlicher Form auch für die Receiver anderer Hersteller möglich sein. Natürlich verwenden Onkyo, Denon, Marantz und weitere Hersteller völlig andere Schnittstellen und erst recht andere Befehle. Das Grundprinzip ist aber wohl bei allen mehr oder weniger gleich, weshalb sich dieses kleine Experiment wohl ganz gut auf andere Produkte übertragen lässt.

Letztendlich ist immer die Frage, wie viel Zeit man investieren möchte und wie leicht zugänglich und verständlich die Dokumentationen dafür sind. Wie ich im einleitenden Artikel geschrieben hatte, lohnt sich der Aufwand schon alleine deshalb, weil es bestimmte Möglichkeiten zur Steuerung eröffnet, die man sonst nicht hätte.

Im nächsten Artikel der Serie gehe ich dann näher auf die Projektorsteuerung ein.

Über Bert Kößler

Ein Kino in den eigenen vier Wänden fand ich schon immer spannend. Meine Leidenschaft gilt vor allem der Einrichtung, Steuerung und Automatisierung. Hier teile ich meine Erfahrungen mit Anfängern und Fortgeschrittenen, die mehr aus Ihrem Heimkino machen wollen.

35 Gedanken zu „Yamaha Netzwerk-Steuerung

  1. Sehr interessanter Artikel! Das gibt einen guten Einblick in die XML-Schnittstelle und erleichtert den Einstieg sicherlich sehr. Vielen Dank!
    Aktuell fehlt mir noch ein wenig die Zeit, um mich selbst mit dem Thema zu beschäftigen, aber wenn ich wieder was Luft habe, werde ich auf Basis dieses Artikels auch mal mit der Schnittstelle rumspielen, um mir die Bedienung meines AV-Receivers noch angenehmer zu machen 🙂
    Gruß,
    Markus

  2. Hallo Bert!
    Danke für diesen Artikel! Auf der Suche nach einem AV-Receiver (bzw. Marke), der sich per LAN ein- und ausschalten lässt, ist das der erste sinnvolle Artikel, der nicht bloß auf eine Hersteller-App verweist. Die Steuerung vom Smart Home braucht einfache Interfaces. Schade, dass die Hersteller das nicht rausrücken wollen, sonst wären sie sofort Favoriten auf meiner Suche. Dass das bei Yamaha so einfach ist, gefällt mir, denn einen (längst in die Jahre gekommenen – da gab’s noch kein HDMI) Yamaha habe ich schon, und der läuft seit Jahren super.
    Schönen Abend!
    Christian

    1. Schön, dass es wieder jemandem hilft. Es gibt ja hier noch weitere Artikel in diese Richtung, zum Beispiel über PJLink zur Steuerung von Projektoren und Bildschirmen.

      Die Hersteller sind sehr unterschiedlich geizig mit ihren Dokumentationen. Von den meisten findet man mehr oder weniger „erlaubt bereitgestellte“ Downloads im Internet. Auch wenn die oft zu anderen Geräten gehören, helfen sie meistens noch irgendwie weiter, weil innerhalb einer Serie eigentlich alle Geräte gleich arbeiten (nur manche Befehle werden nicht unterstützt). Bei Yamaha reagierte der Support auch sehr hilfsbereit, nachdem ich mitgeteilt hatte, dass ich das nicht kommerziell einsetzen will, sondern eine Steuerung für private Zwecke anstrebe. Könnte mir gut vorstellen, dass das bei anderen Herstellern ähnlich ist.

      Ansonsten bleibt nur das Netzwerk-Sniffing, zum Beispiel per WireShark. Ist zwar mühsam, hat für mich aber unter anderem einige undokumentierten Features meines Mitsubishi-Beamers offengelegt.

  3. Hallo, vielen Dank für den guten Bericht. Hat mir schon etwas geholfen 🙂 Das Projekt sollte bald fertig sein 😛 Werde hier noch ein kleines Update liefern, wenn es dann soweit ist.
    Zu dem Tipp dass man sich an Yamaha wenden soll, kann ich nur sagen, dass man mir auf meine freundliche Mail nicht geantwortet hat :-/

    Aktuell das PC-Programm (dient derzeit nur zum Testen, damit es mit der Android-App etwas schneller geht)

    Beste Grüße und danke nochmal!
    Martin

    1. Hi Martin, danke für die Rückmeldung. Es ist schon komisch, wie unterschiedlich der Support mit solchen Anfragen umgeht. Kommt wohl drauf an, wen man erwischt.

      Würde mich freuen, weiter von deinem Projekt zu hören. Sorry dass ich den Link löschen musste, nur zur Sicherheit. Manche Leute weinen immer gleich, wenn da eine EXE verlinkt ist. Screenshots oder Quellcode wären aber sicher auch sehr interessant.

    1. Ja, diese Beschreibung gibt es. Ich finde sie aber nicht so hilfreich, wie die Excel-Tabellen, die man zum Download findet oder die Dokumentation vom Yamaha Support. Wenn man einmal weiß, wie die XML-Befehle funktionieren, kann man hier aber gut nachschlagen, was es wirklich an Parametern gibt.

    2. Hallo Alex.
      bin kein Techniker und habe da eine blöde Frage bezüglich RX-V500D.
      Mit deinem Link http://IP-ADDRESS/YamahaRemoteControl/desc.xml kann ich ja die XML Datei auslesen.
      Gibt es in dieser Datei die Möglichkeit den Receiver bzw. deren eingebauten Webserver der nur abgespeckt angezeigt wird, voll aufzudrehen damit auch alle Menüs sichtbar und bearbeitbar werden?
      Wie könnte ich das sonst noch lösen!
      LG

      1. Weil Alex das wahrscheinlich nicht mehr liest, übernehme ich das mal.

        Was genau meinst Du mit „voll aufdrehen“? Willst Du die Inhalte der XML-Datei erweitern? Oder etwas am Bildschirmmenü des AVRs ändern?

        Die XML-Datei ist nur eine statische Beschreibung der Funktionen des jeweiligen Geräts. Sie kann nicht verändert werden, noch beeinflusst sie etwas am Gerät. Man könnte sagen, sie ist nur eine Dokumentation der Befehle im XML-Format.

        1. Hallo Bert,
          Freut mich dass du dich meiner Probleme mit meinen en RX-V500D annimmst.
          Frage 1: Gibt es eine Möglichkeit den Receiver bzw. deren eingebauten Webserver der nur abgespeckt angezeigt wird, freizuschalten, damit auch alle versteckten Parameter in den Menüs sichtbar und einstellbar werden wie bei den größeren Brüdern?
          Frage 2: Möchte mit meiner Loxone Hausautomatisation http/DLNA/UPnP Befehle an den Yamaha RX-V500D „Server“ senden, damit dieser sich eine mp3 Musikdatei von meiner Serverfestplatte abholt und auch abspielt. Wie kann ich die entsprechenden Befehl einbetten? zB: \\ServerLeo\Musik\Loxone\mp3 Song

          Wäre spitze wenn du mich da unterstützen könnest.
          LG

          1. Zu Frage 1: Mir ist nicht bekannt, dass es so eine Möglichkeit gibt. Die Menüs oder was der Receiver sonst so anzeigt können bzw. kann nicht verändert werden, auch nicht bei den größeren Modellen. Was möglich ist: jede einzelne Einstellung, die sich irgendwo tief in einem Menü versteckt, kann mit einem einzigen Befehl gezielt ausgelesen oder gesetzt werden. In einer eigenen App könntest Du Dir eine Benutzeroberfläche bauen, die alle Einstellungen auf einem Haufen anzeigt. Die App von Yamaha bietet einige davon an, aber längst nicht alle.

            Zu Frage 2: Das hab ich selbst noch nicht ausprobiert. Grundsätzlich kannst Du eine Art Makro schreiben, das der Reihe nach die Netzwerkquelle auswählt, in das richtige Verzeichnis wechselt und dort den Song startet. Das ist aber möglicherweise zu umständlich. Dass man ihm gezielt den Netzwerkpfad zu irgend einer Datei hinwirft, könnte schon funktionieren, ich hab aber noch keinen Befehl dafür in der Dokumentation gefunden. Die Yamaha-App kann das ja beispielsweise: man kann ein MP3-File, das auf der Karte vom Smartphone liegt, direkt auf dem Receiver wiedergeben. Ich weiß nur nicht, mit welchem Protokoll die das machen. Eine andere Möglichkeit wäre die von AirPlay oder Spotify, da geht das ja ähnlich.

            Ich kann nur eine Vermutung äußern: Du könntest mal als UDP Client unter der Adresse 239.255.255.250 im Netzwerk lauschen, ob da irgendwelche interessanten Informationen ausgetauscht werden. Dort senden die Yamaha-Geräte normalerweise ihre Events ins Netz, wenn man das zuvor aktiviert. Der Kanal scheint aber von allen möglichen Mediengeräten bzw. -servern genutzt zu werden, um da ihre Dienste bekannt zu machen. Auch die Yamaha Reveiver melden sich dort ab und zu mal zu Wort. Wahrscheinlich senden sie dort die Information, dass sie beispielsweise als AirPlay-Empfänger dienen können, woraufhin iTunes sie zur Auswahl für die Musikwiedergabe anzeigen kann. Das ist nur so ne Idee, ich kenne mich da nicht wirklich aus.

            Wenn Du es schaffst, herauszufinden, wie andere Software das macht, kommst Du vielleicht weiter. Vielleicht kannst Du mit Wireshark den Netzwerkverkehr mitschnüffeln und so die notwendige Kommunikation herausfinden. Das ist aber nur wilde Spekulation. Ich verliere bei sowas immer sehr schnell die Lust. Das mit den Events hat mich schon Tage gekostet. Sorry, wenn ich da nichts wirklich hilfreiches sagen kann.

  4. Hallo Bert

    Ich hoffe du kannst mir weiterhelfen, denn ich bin nicht vom Fach: mein yamahareceiver wird schon längere Zeit von meinem Iphone nicht mehr gefunden. Es heisst, man soll die ip-Adresse manuell konfigurieren. Ich versuchte dies zu machen. Wie erhalte ich eine neue ip für den Receiver? Wenn ich dort auf ip gehe und ok drücke und zahlen ändere dann dieselbe Kombination auf dem Handy eingebe geschieht gar nichts…

    Vielen Dank

    Helena

      1. Eine sehr gute Frage. Ganz allgemein bei Node.js hat man auf dem jeweiligen System die Konsolen-Anwendung node zur Verfügung. Dieser übergibt man als Parameter den Dateinamen eines JavaScripts. Idealerweise befindet man sich bereits in dem Verzeichnis, in dem das Script liegt. Die Dateiendung kann man weglassen. Die folgenden Aufrufe sind daher alle gleich.

        cd ~/remote
        
        node ~/remote/app.js
        node app.js
        node app

        Da man verschiedene Umgebungen betreibt, zum Beispiel auf einem Windows-PC für die Entwicklung und einen Linux-Server als Produktivsystem, kann man unter anderem das System als Parameter mitgeben, etwa um eine bestimmte Konfiguration zu laden. Natürlich ließe sich das aber auch aus einer Umgebungsvariablen auslesen. Als praktisch hat sich trotzdem die Variante mit dem Parameter erwiesen:

        node app development
        node app production

        Da Node.js aber mit einem sehr praktischen Package Manager (npm) daher kommt, der es unter anderem ermöglicht, verschiedene Aufgaben in einem einzigen Befehl zu bündeln, sieht das in der Praxis nochmal ganz anders aus. In der Entwicklungsumgebung werden neben dem eigentlichen Server auch Compiler für Frontend-JavaScript und SASS gestartet, die verschiedene Verzeichnisse überwachen. Im Produktivsystem kommt keine Überwachung zum Einsatz, sondern eine einmalige Kompilierung, die den Code dafür stärker komprimiert. Hinzu kommt ein automatischer Update-Prozess über SVN.

        Bei mir sieht das dann so aus, dass sich mein Synology NAS am Abend einschaltet, sich über SVN automatisch ein Update zieht, den Code kompiliert und optimiert und anschließend den Server startet. Ein parallel laufendes Node-Modul (forever) sorgt dafür, dass der Server sofort neu gestartet wird, sollte er mal abschmieren.

        Ganz schön kompliziert, stelle ich gerade fest. Das wäre vielleicht mal einen eigenen Artikel wert. Aber wie oben gezeigt geht es eben auch einfach.

  5. Hi,

    ok, das ist mir eine Nummer zu hoch. Arbeite nun an der PHP-Variante.

    Kennt jemand den XML-Befehl, einen Radiostream zu starten?

    1. Das hab ich selbst noch nicht ausprobiert, aber hiermit sollte es gehen.

      Eingang wählen

      <YAMAHA_AV cmd="PUT"><Main_Zone><Input><Input_Sel>NET RADIO</Input_Sel></Input></Main_Zone></YAMAHA_AV>

      Gespeicherten Radiosender starten (1 bis 40)

      <YAMAHA_AV cmd="PUT"><NET_RADIO><Play_Control><Preset><Preset_Sel>1</Preset_Sel></Preset></Play_Control></NET_RADIO></YAMAHA_AV>

      Stoppen und Starten

      <YAMAHA_AV cmd="PUT"><NET_RADIO><Play_Control><Playback>Stop</Playback></Play_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><Play_Control><Playback>Play</Playback></Play_Control></NET_RADIO></YAMAHA_AV>

      Eintrag aus der aktuell sichtbaren Liste der Radiosender starten (1 bis 8)

      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Direct_Sel>Line_1</Direct_Sel></List_Control></NET_RADIO></YAMAHA_AV>

      Zu einer bestimmten Zeile der Liste aller Radiosender springen (1 bis 65536)

      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Jump_Line>1</Jump_Line></List_Control></NET_RADIO></YAMAHA_AV>

      Und jede Menge weitere Befehle, um sich in der Liste zu bewegen

      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Cursor>Down</Cursor></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Cursor>Up</Cursor></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Cursor>Sel</Cursor></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Cursor>Back</Cursor></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Cursor>Back to Home</Cursor></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Page>Down</Page></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Page>Up</Page></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Bookmark>Off</Bookmark></List_Control></NET_RADIO></YAMAHA_AV>
      <YAMAHA_AV cmd="PUT"><NET_RADIO><List_Control><Bookmark>On</Bookmark></List_Control></NET_RADIO></YAMAHA_AV>
  6. Hi!

    Ich will das gerade mal testen, bin aber kompletter Anfänger. Ich packe den o.g. php-Code also in eine Datei (mit angepasster IP) auf meinem Webserver, rufe die dann auf und das war’s – der Befehl geht an den Yammie?

    Ist das schon der komplette Inhalt der php-Datei oder muss da noch was drumherum?

    1. Das Beispiel sollte genau so wie es ist funktionieren. Wenn Du andere Befehle senden willst, musst Du natürlich noch ein bisschen was drum herum bauen, damit eine praktikable Anwendung daraus wird. Das hängt ja aber davon ab, wie Du die Befehle genau aufrufen willst.

  7. Danke für die tolle Beschreibung der Schnittstelle! Ich hatte anfangs ziemlich mit Status 400/Bad Request-Antworten des Receivers zu kämpfen, die mich einiges an Zeit und Nerven gekostet haben. Die Lösung des Problems ist vergleichsweise banal – daher möchte ich sie hier gerne teilen, damit andere sich die Sucherei sparen können: bei dem XML, das an die Schnittstelle geschickt wird, muss unbedingt darauf geachtet werden, doppelte Anführungszeichen für Attribute zu verwenden (also z.B. „GET“, nicht ‚GET‘). Nach XML-Standard sollte das eigentlich gleichgültig sein, und mir ist auch kein XML-Parser bekannt, der da unterscheiden würde. Aber die Yamaha antwortet bei ‚…‘-Attributen stoisch mit einem 400-Fehler. Auf die Idee, einfache Anführungszeichen zu verwenden, kann man ja schnell mal kommen, wenn man die Schnittstellen-Kommunikation in der einen oder anderen Weise automatisiert und die XML-Fragente z.B. in einem String abspeichert. Mit doppelten Anführungszeichen klappt alles reibungslos. Hoffe, das hilft dem einen oder anderen.

  8. Hallo miteinander, erstmal möchte ich meine volle Beachtung zu diesem sagenhaften Blog ausdrücken. Ich habe selten eine so gelungene Seite gesehen, auf der man ein interessantes Projekt nach dem andren findet.

    Ich sitze nur schon seit ein paar Tagen an meinem 1. eigenen Steuerungsversuch verschiedener Geräte in meinem Heimnetzwerk.
    Ich glaube mir fehlt einfach irgendwo die nötige Grundkenntnis. Im grunde genommen möchte ich gerne meinen YAMAHA AVR RXV679 (Er hat auch die besagte Webschnittstelle) aus einer eigenen App heraus bedienen.

    Der Kern dieser Anwendung soll am liebsten in Visual Studio Studio als universelle Windows App geschrieben werden. Ich habe jetzt schon nach langer Suche herausgefunden, dass es auch die besagten Universellen Windows Apps mit Node.js Unterstützung gibt.
    Ich habe in Visual Studio schon die Anwendungsbibliotheken gefunden um Node.js einzubinden.
    Bei mir scheitert es jetzt an dem Punkt, wie und wo ich die oben genannten Code von Ihnen in einer solchen App anbinde.

    Andererseits hätte ich die Frage, ob Sie eine Ahnung haben wie man das ganze in VB oder C# schreiben könnte. Ich glaube mir fehlen einfach nur die Grundansätze, so dass mir das Zeil nicht mehr so fern erscheint.

    Liebe Grüße
    CasiWerdi

    1. Hallo CasiWerdi,

      erstmal vielen Dank für das Lob! 🙂

      Für den Anfang möchte ich aufgrund eigener Erfahrung davon abraten, .NET mit Node.js zu vermischen. Das muss ja grundsätzlich nicht schlecht sein, jedoch hat das für mich so ein bisschen was „erzwungenes“. Microsoft merkt halt, dass andere Spielsachen auch cool sind, und will es dann seinen Anhängern irgendwie ermöglichen, auch mal damit zu spielen — Hauptsache die gehen nicht dauerhaft von .NET weg. Der Programmieransatz und das Einsatzgebiet von .NET und Node.js sind grundsätzlich sehr verschieden, so dass es aber eigentlich keinen Grund für Kunden-Verlustängste und für diese an den Haaren herbeigezogene Kombination gibt.

      Daher mein Tipp: Mach es entweder nur mit .NET oder nur mit Node.js — keine Mischung. Das wäre nichts halbes und nichts ganzes. Welche Welt Du Dir aussuchst, hängt nur davon ab, wie tief Du darin verwurzelt bist, wie gut Du Dich damit auskennst und was Du eigentlich erreichen willst. Ich bin bei dem Ansatz mit Node.js geblieben, weil ich eine Web-App ideal finde: sie läuft einfach auf allen Geräten, die einen Browser haben, ganz egal was es ist. Wenn es Dir reicht, dass Deine Steuerung unter Windows läuft, ist das mit .NET auch fein. Oder Du entscheidest Dich für ASP.NET — selbe Sprache aber Web-App als Ergebnis. Zum Glück gibt es ja Möglichkeiten ohne Ende.

      Und nun zum eigentlichen Spaß: Die beiden Beispiele oben kannst Du ziemlich leicht auf .NET übertragen. Das PHP-Beispiel dürfte dabei einfacher zu übertragen sein, weil es dem prozeduralen Ansatz folgt, der auch in C# oder VB vorhanden ist.

      Für den Anfang würde ich Dir einen Versuch mit dem HttpWebRequest empfehlen. Beispiele gibt es ja im MSDN reichlich. Oder Du schaust Dir einfach mal diese Antwort hier an, genauer die Method C: Legacy. Dort siehst Du, wie Du POST-Daten übertragen kannst. Statt einen typischen query=string zu senden, schreibst Du dort den XML-Befehl rein. Alles weitere wie URL und Header solltest Du aus dem PHP-Beispiel ableiten können.

      Alternativ (und eine aktuelle Framework-Version vorausgesetzt) fängst Du gleich mit Method A: HttpClient an. Dort muss das XML dann eben als content rein.

  9. Hallo,
    das ging ja sehr fix mit der Antwort!

    Ich habe es zeitlich bisher nicht geschafft an dem Projekt weiter zu arbeiten.
    Aber gedanken machen konnte ich mir und ich bin zu dem entschluss gekommen, tatsächlich erstmal einen Apache Server auf meinem Raspberry PI zu installieren und das Projekt dann mit einer Webanwendung und PHP zu realisieren.

    Ich habe bei mir noch andere „SmartHome“ Geräte wie z.B. einen Epson Beamer, eine EZControl Schnittstelle für diverse Licht und Heizungsaktoren usw.
    Diese werde ich wenn alles klappt, auch in Zukunft implementieren.

    Dein Argument, bezüglich der Erreichbarkeit von fast allen Browserfähigen Geräten aus ist einfach unschlagbar.

    Können wir vielleicht per Mail in Kontakt treten? Da das ebenfalls mein erstes PHP Projekt ist, würde ich mich freuen wenn ich ab und an mal eine Frage stellen könnte.

    Und Nochmal vielen Dank für die Mühe, die du dir machst, um anderen mit deren Problemen weiter zu helfen. Das machen nicht viele!

    1. Das ist eine gute Entscheidung, denke ich. Um Dich aber noch weiter durcheinander zu bringen: Wenn Du mit PHP an die Sache ran gehst, verbaust Du Dir einen entscheidenden Vorteil, den Node.js hat: Events. Mit Node.js kannst Du sehr einfach eine bidirektionale Kommunikation aufbauen, d.h. der Client kann nicht nur Daten vom Server abfragen, sondern auch der Server kann von sich aus Daten an alle Clients senden. Mit PHP ist das nur extem umständlich hinzubekommen.

      Das ist dann von Vorteil, wenn Du Informationen vom Receiver live in der App anzeigen willst. Bei mir ist das so: Wenn ich am Lautstärkeregler des Receivers drehe, aktualisiert sich die App mit einer Verzögerung von höchstens 2 Sekunden. Ist nur eines von vielen möglichen Beispielen, aber da wird’s dann halt richtig lustig (natürlich auch vom Programmieren her).

      Wie auch immer, Du kannst mir natürlich auch eine E-Mail schreiben, kein Problem. Ich hab jetzt nicht die Zeit, Dir PHP oder Node.js zu erklären, aber wenn es um die Details der Kommunikation mit den Geräten geht, helfe ich gerne weiter, wenn ich kann.

  10. Hallo, ich steuere den Receiver auch über Alexa. Allerdings über eine CCU2. Das einzige was mir nur noch fehlt ist die Statusabfrage, damit Alexa weiß ob die Anlage schon an oder noch aus ist.

    1. Ob der AV-Receiver an oder aus ist, findest Du mit diesem Befehl heraus:

      <YAMAHA_AV cmd="GET"><System><Power_Control><Power>GetParam</Power></Power_Control></System></YAMAHA_AV>

      Die Antwort sollte dann ähnlich aussehen und an Stelle von GetParam sowas wie On oder Network Standby enthalten.

      Vielleicht brauchst Du das aber auch gar nicht. Du kannst ja den Power-Befehl nicht nur toggeln, sondern explizit auf an oder aus setzen — unabhängig vom aktuellen Zustand. Vielleicht erfüllt das die Anforderungen ja schon.

  11. Hi,
    sehr interessanter Artikel!
    Ich möchte das bei mir mit Node.js realisieren aber mir ist noch unklar wohin genau der Code Node-Moduls soll. Du schreibst:
    „Das Script ist ein in sich geschlossenes Node-Modul.“

    Also soll das als .js-Datei in den „node_modules“ Ordner? Wenn ja, unter welchem Namen?
    Oder wird dieser Code in die .js-Datei eingefügt, die ich zum starten des Node-Servers (über Terminal z. B. mit „node server.js“) nutze?

    Danke für deine Hilfe. 🙂

    1. Dazu schaust Du Dir am besten einfach nochmal die Grundlagen zu Node’s wichtigster Funktion require() an.

      Die Kurzfassung: In node_modules werden automatisch Module hinzugefügt, die man per NPM installiert. Manuell sollte man dort drin gar nichts machen. Eigene Module fügst Du als separate JavaScript-Datei hinzu, mit einem Namen, der Dir sinnvoll erscheint — zum Beispiel yamaha.js. Die unterscheiden sich beim Einbinden darin, dass man nicht nur den Namen des Moduls, sondern auch den relativen Pfad zur Datei angeben muss:

      var yamaha = require("./yamaha.js");
  12. Guten Morgen,

    danke für die Anleitung, nun habe ich es geschafft meinem AVR in mein Homematic-Netzwerk einzubinden.
    D.h. ich starte ausgewählte Sender zu bestimmten Zeiten oder mit bestimmten Aktionen. Dazu wird eine .sh-Datei abgearbeitet.

    Trotzdem möchte ich gerne wissen ob folgendes Szenarium möglich wäre.
    Ich möchte den AVR mit einem Türkontakt von Homematic beim öffnen der Tür anschalten (kein Problem).
    Türkontakt auf und Variable AVR =0, dann abrufen der sh-Datei zusätzlich eine Variable AVR auf 1.

    Das Problem ergibt sich für mich und mein mangelndes Wissen erst, wenn der AVR schon in Betrieb ist und zwar wenn er mit der APP oder manuell gestartet wurde, dann sollte die .sh-Datei nämlich nicht abgerufen werden.
    Wie kann ich beides verbinden?

    Hat jemand der lesenden hier eine Idee?

    MfG
    GF

    1. Der oben gezeigte Power-Befehl schaltet den AV-Receiver immer an. Wenn er schon an ist, hat das also keine Auswirkungen. Der Aufruf des Scripts sollte also keine Auswirkungen haben.

  13. Hi Bert,
    voller Bewunderung verfolge ich diesen blog nun schon geraume Zeit.
    Ich mache gerade erste Gehversuche mit node-red als node.js vorgeschalteter grafischer Entwicklungsumgebung. Ich kann aus meiner SPS meinen Linux-Server starten und dieser dann per node-red sich selbst (kodi, vlc), meinen A-3030 usw.
    Ich habe auch für node-red einen yamaha-contrib-node gefunden aber da ist der Befehlssatz fest voreingestellt (RX-V677). Mein Ziel wäre es, aus der individuellen /YamahaRemoteControl/desc.xml einen A-3030 spezifischen node/flow zu generieren um für jeden möglichen Befehl z.B. eine eigene function zu bekommen (i.S. file(desc.xml)->split->change->file(node) also im Grunde genommen einen „node-Generator“ mit node-red. Ob so etwas denkbar/möglich ist? Hauptgrund ist meine Schwierigkeit, das xml in einen gültigen html Befehl zu übertragen. Für kodi kann ich das mit einm REST-tool im browser checken und dann per copy paste nach node-red übertagen… Dank und Gruß

    1. Hi Thomas,

      machbar ist das bestimmt. Ich frage mich nur, ob es zielführend ist.

      Wenn man das so umsetzt, dann ja wohl mit dem Ziel, eine Oberfläche dynamisch zu generieren, abhängig von den unterstützen Befehlen. Aber braucht man das wirklich? Tut’s dafür nicht auch die App von Yamaha?

      Für die persönliche Steuerung brauchst Du nur einen bestimmten Befehlssatz, und den implementierst Du leichter manuell.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.