Steuerung von Onkyo Receivern mit Node-Blue über das ISCP-Protokoll

Hallo,

aktuelle Onkyo Receiver lassen sich mit Hilfe des ISCP Protokolls („Integra Serial Communication Protocol“) über das Netzwerk steuern, indem man Befehle an Port 60128 der IP-Adresse des Receivers sendet.

ISCP-Befehle bestehen immer aus einem vorgegebenen Header, der gewünschten Aktion als Zeichenkette und einer Byte-Folge zum Abschluss des Befehls.
„PWR01“ schaltet den AVR an oder „MVL28“ setzt die Lautstärke auf den Wert 40 (=28 hexadezimal) usw.

Die Steuerungsmöglichkeiten über ISCP sind wirklich sehr umfangreich und wer Lust hat, kann in diesem Dokument alle technischen Details finden:

https://www.capitolsales.com/UserFiles/Documents/Technical%20Tips/Onkyo%20Serial%20AVR_5-17.xlsx

Ich kann das Excel leider nicht direkt hochladen, weil das im Forum anscheinend nicht erlaubt ist. Bis jetzt habe ich mir nur mit den Funktionen im Blatt „CMND(MAIN)“ beschäftigt.

Für die Implementierung in Node-Blue habe ich einen Function-Node erstellt, der mit einem einfachen PHP Skript die ISCP-Befehle generiert und an den Receiver sendet.
Wer sich besser mit Node-Blue auskennt, kann ja vielleicht einen „richtigen“ Node daraus machen, aber für meine Zwecke reicht das völlig aus.

Im PHP-Code muss die Variable host auf die IP-Adresse bzw. den DNS-Namen des Receivers angepasst werden.
Der zu sendende Befehl wird dem Node über $message.payload übergeben, wobei die Message vorher mit einem Template-Node erzeugt wird.

Der folgende Beispiel-Flow schaltet beispielsweise das Radio ein (SLI24) und setzt die Lautstärke auf 35 (MVL23).
Über einen Timer-Node gesteuert hat man so morgens beim Aufstehen schon seine Lieblingsmusik…

Onkyo ISCP Beispiel Flow.txt (2,8 KB)

Das ISCP-Protokoll unterstützt auch Statusabfragen (z.B. über PWRQSTN), die der Receiver dann beantwortet. Dies liegt hier allerdings nicht im Scope.

Der PHP-Code beinhaltet nur eine rudimentäre Ausnahmebehandlung und auch keinen Check der Eingabe auf Gültigkeit - es handelt sich mehr um einen „Proof of Concept“ für den Eigengebrauch.

Grundsätzlich kann diese Vorgehensweise auch unabhängig von PHP bzw. Node-Blue verwendet werden.
Beispielsweise kann man in einer Linux-Shell mit dem Befehl netcat („nc“) Befehle an den Receiver senden und diesen somit über Shell-Skripte steuern.

Viel Spaß

FiveEights

2 Likes

Das sollte in jedem Fall hier mir rein ^^

Hallo,

brauche ich dafür einen Account bei GitHub oder kann ich das einfach so hochladen ?

Als Follow-Up zu meinem Posting hier noch ein einfacher PHP-Code, um Statusanfragen an den Receiver zu senden und die Antwort auszuwerten.

In Abhängigkeit vom aktuellen Betriebszustand und von der gesendeten Anfrage liefert der Receiver völlig unterschiedliche Antworten, teilweise auch im XML-Format.
Beispielsweise liefert die Anfrage PWRQSTN eine ganz andere Antwort als NRIQSTN. Um hier alle Möglichkeiten abzudecken, müsste man deutlich mehr Aufwand betreiben um die Antwort zu parsen.
Für meine Anwendungszwecke reicht jedoch der untenstehende Code bis jetzt völlig aus:

$hostname = ‘onkyo’; //Hier IP-Adresse oder DNS-Namen des Receivers eintragen
$port = 60128;

$iscp_command=“PWRQSTN”;
$header=“ISCP\x00\x00\x00\x10\x00\x00\x00\x0A\x01\x00\x00\x00”; //Header, Version etc. siehe ISCP-Doku

$packet_PWR=$header . “!1” . $iscp_command . “\x0A”;

$iscp_command=“SLIQSTN”;
$header=“ISCP\x00\x00\x00\x10\x00\x00\x00\x0A\x01\x00\x00\x00”; //Header, Version etc. siehe ISCP-Doku

$packet_SLI=$header . “!1” . $iscp_command . “\x0A”;

$fp = pfsockopen($hostname, $port);

if (!$fp)
{
exit(“Fehler”);
}

stream_set_timeout($fp,1);

//PWR Status abfragen
fwrite($fp, $packet_PWR);
$result=stream_get_contents($fp,256);

//result in lesbares Format bringen
$result = preg_replace(’/[\x00-\x1F\x7F]/u’, ‘.’, $result); //non-printable characters entfernen
$status_PWR=substr($result,-8);

//SLI Status abfragen
fwrite($fp, $packet_SLI);
$result=stream_get_contents($fp,256);

$result = preg_replace(’/[\x00-\x1F\x7F]/u’, ‘.’, $result); //non-printable characters entfernen
$status_SLI=substr($result,-8);

fclose($fp);

//Aktuellen Status für PWR und SLI in Message aufnehmen
$message[“status_PWR”]=$status_PWR;
$message[“status_SLI”]=$status_SLI;

return $message; //Weiter im Flow

Unter diesem Link findet man detaillierte technische Hintergrundinfos zur Steuerung von Onkyo-Receivern über das Netzwerk:

Und hier noch ein Link auf die neuste mir bekannte Version 1.40 der Spezifikation:

https://github.com/mkulesh/onpc/blob/master/doc/ISCP_AVR_140.xlsx

Noch ein Hinweis:
Man kann es anscheinend auch schaffen, durch zu viel „Herumprobieren“ die Netzwerkschnittstelle des Receivers zum Absturz zu bringen (oder zumindest in einen Zustand, wo sie auf Anfragen nicht mehr reagiert, auch nicht auf die App).
In diesem Fall hilft leider bei mir leider nur die traditionelle Methode: Netzstecker des Receivers ziehen…

Viele Grüße

FiveEights

1 Like

Ja, du brauchst einen account. Schlussendlich “forkst” du das Repository in deinen account und stellst, nachdem du deine Erweiterung gemacht hast, einen “pull request” an das ursprüngliche Repository mit der Bitte deinen Code aufzunehmen.

Schau mal hier:

https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/