Direkte Onkyo Steuerung ohne Middleware

diverse Zusatzsoftware

Moderator: Co-Administratoren

Rauschi
Beiträge: 47
Registriert: 27.10.2013, 12:03

Direkte Onkyo Steuerung ohne Middleware

Beitrag von Rauschi » 28.10.2013, 23:09

Hallo an Alle,

ich bin seit 3 Tagen Besitzer einer Homematic Testumgebung bestehend aus CCU2, dem neuen Heizkörperthermostat, einem Fenstersensor und einem 6-fach Taster. Die Heizungsgeschichte ist soweit ja einfach. Interessant ist ja die Anbindung an andere Geräte.
Ich selbst habe ein gewisses IT-Grundwissen.

Falls mir das Ganze gefällt steht evtl. ein Rasberry PI mit OpenHab, CCU Historian und der Onkyo Middleware auf dem Plan.

Changelog
2013-11-01 - Stufe 3 ergänzt
2013-11-02 - Stufe 4 ergänzt
2013-11-03 - Änderungen an Stufe 4
2013-11-06 - Stufe 5 ergänzt

Nun aber zum Onkyo, die Aufgabenstellung:
Steuerung der Zone 2 (Küche) über 6 fach Wandtaster
- Ein/Aus
- Lauter/Leiser
- Direkttaste Internetradio "Öffentlich rechtlicher Sender"
- Direkttaste Playlist auf USB-Stick

In diesem Thread möchte ich euch über meine Fortschritte auf dem laufenden halten, um ggf. anderen Einsteigern bei dem Thema zu helfen und soweit möglich die Informationsquellen entsprechend verlinken.

Stufe #1
Ich habe gelesen das System.Exec() Befehle über CuxD abgesetzt werden, sollen, da diese die Box nicht zum Absturz bringen, also das CuxD Addon installiert.
Für den Anfang sollen es 4 Tasten sein:
- Aus
- Ein
- Lauter
- Leiser

Also im CuxD 4 Geräte angelegt und entsprechende Shell Commandos hinterlegt.
Zum Einsatz kommt folgendes Script, dass ich im Internet gefunden habe (ist bereits um Stufe 2 erweitert):

Code: Alles auswählen

#!/bin/sh
#
# Simple script to control my Onkyo TX-NR609 from any linux host
# using just bash (or sh) and netcat (nc), works on my Nokia N900.

# Set the IP and PORT of your AVR
IP=x.x.x.x
PORT=60128

########################################
            
# Command to send: 
case $2 in
	01)
	   VOLUME="01"
	   ;;
	02)
       VOLUME="02"
	   ;;
	03)
	   VOLUME="03"
	   ;;
	04)
	   VOLUME="04"
	   ;;
	05)
	   VOLUME="05"
	   ;;
	06)
	   VOLUME="06"
	   ;;
	07)
	   VOLUME="07"
	   ;;
	08)
	   VOLUME="08"
	   ;;
	09)
	   VOLUME="09"
       ;;
    10)
	   VOLUME="0A"
	   ;;
    11)
	   VOLUME="0B"
	   ;;
	12)
	   VOLUME="0C"
	   ;;
	13)
	   VOLUME="0D"
	   ;;
	14)
	   VOLUME="0E"
	   ;;
	15)
	   VOLUME="0F"
	   ;;
	16)
	   VOLUME="10"
	   ;;
	17)
	   VOLUME="11"
	   ;;
	18)
	   VOLUME="12"
	   ;;
	19)
	   VOLUME="13"
	   ;;
	20)
	   VOLUME="14"
	   ;;
	21)
	   VOLUME="15"
	   ;;
	22)
	   VOLUME="16"
	   ;;
	23)
	   VOLUME="17"
	   ;;
	24)
	   VOLUME="18"
	   ;;
	25)
	   VOLUME="19"
	   ;;
	26)
	   VOLUME="1A"
	   ;;
	27)
	   VOLUME="1B"
	   ;;
	28)
	   VOLUME="1C"
	   ;;
	29)
	   VOLUME="1D"
	   ;;
	30)
	   VOLUME="1E"
	   ;;
	31)
	   VOLUME="1F"
	   ;;
	32)
	   VOLUME="20"
	   ;;
	33)
	   VOLUME="21"
	   ;;
	34)
	   VOLUME="22"
	   ;;
	35)
	   VOLUME="23"
	   ;;
	36)
	   VOLUME="24"
	   ;;
	37)
	   VOLUME="25"
	   ;;
	38)
	   VOLUME="26"
	   ;;
	39)
	   VOLUME="27"
	   ;;
	40)
	   VOLUME="28"
	   ;;
	41)
	   VOLUME="29"
	   ;;
	42)
	   VOLUME="2A"
	   ;;
	43)
	   VOLUME="2B"
	   ;;
	44)
	   VOLUME="2C"
	   ;;
	45)
	   VOLUME="2D"
	   ;;
	46)
	   VOLUME="2E"
	   ;;
	47)
	   VOLUME="2F"
	   ;;
	48)
	   VOLUME="30"
	   ;;
	49)
	   VOLUME="31"
	   ;;
	50)
	   VOLUME="32"
	   ;;
	51)
	   VOLUME="33"
	   ;;
	52)
	   VOLUME="34"
	   ;;
	53)
	   VOLUME="35"
	   ;;
	54)
	   VOLUME="36"
	   ;;
	55)
	   VOLUME="37"
	   ;;
	56)
	   VOLUME="38"
	   ;;
	57)
	   VOLUME="39"
	   ;;
	58)
	   VOLUME="3A"
	   ;;
    59)
	   VOLUME="3B"
	   ;;	  
    60)
	   VOLUME="3C"
	   ;;
    61)
	   VOLUME="3D"
	   ;;
    62)
	   VOLUME="3E"
	   ;;
    63)
	   VOLUME="3F"
	   ;;
    64)
	   VOLUME="40"
	   ;;
    65)
	   VOLUME="41"
	   ;;
    66)
	   VOLUME="42"
	   ;;
    67)
	   VOLUME="43"
	   ;;
    68)
	   VOLUME="44"
	   ;;
    69)
	   VOLUME="45"
	   ;;
    70)
	   VOLUME="46"
	   ;;
    71)
	   VOLUME="47"
	   ;;
    72)
	   VOLUME="48"
	   ;;
    73)
	   VOLUME="49"
	   ;;
    74)
	   VOLUME="4A"
	   ;;
    75)
	   VOLUME="4B"
	   ;;
    76)
	   VOLUME="4C"
	   ;;
    77)
	   VOLUME="4D"
	   ;;
    78)
	   VOLUME="4E"
	   ;;
    79)
	   VOLUME="4F"
	   ;;
    80)
	   VOLUME="50"
	   ;;
	*)
	   VOLUME="10"
	   ;;
esac

	
case $1 in
    forcemute)
        COMMAND='!1AMT01'
        echo "Muting"
        ;;
    forceunmute)
        COMMAND='!1AMT00'
        echo "Unmuting"
        ;;
    mute)
        COMMAND='!1AMTTG'
        echo "Toggling Mute"
        ;;
    mutestat)
        COMMAND='!1AMTQSTN'
        echo "Mute Status"
        ;;
    off)
        COMMAND='!1PWR00'
        echo "Power off"
        ;;
    on)
        COMMAND='!1PWR01'
        echo "Power on"
        ;;
    vup)
        COMMAND='!1MVLUP'
        echo "Volume up"
        ;;
    vdown)
        COMMAND='!1MVLDOWN'
        echo "Volume down"
        ;;
    pwrstat)
        COMMAND='!1PWRQSTN'
        echo "Power Status"
        ;;
    z2on)
        COMMAND='!1ZPW01'
        echo "Zone 2 on"
        ;;
    z2off)
        COMMAND='!1ZPW00'
        echo "Zone 2 off"
        ;;
    z2stat)
        COMMAND='!1ZPWQSTN'
        echo "Zone 2 Status"
        ;;
    z2vdown)
        COMMAND='!1ZVLDOWN'
        echo "Zone 2 Volume Down"
        ;;
    z2vup)
        COMMAND='!1ZVLUP'
        echo "Zone 2 Volume Up"
        ;;
    z2vstat)
        COMMAND='!1ZVLQSTN'
        echo "Zone 2 Volume Stat"
        ;;
    z2vset)
        COMMAND="!1ZVL$VOLUME";
        echo "Zone 2 Volume Set"
        ;;    
    *)
        echo "$0 mute, unmute, off, on, vup, vdown, ..."
        exit 1
        ;;
esac
            
############
# String to send is :
ISCP="ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00"
LENGTH=$(echo "\\x$(printf "%0.2x" $(echo $COMMAND | wc -c ))")
MID="\\x01\\x00\\x00\\x00"
CMD=${COMMAND} # Just to show the command's structure. :-P
END="\\x0D"
##########
# Mute example :
# echo -e 'ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x08\\x01\\x00\\x00\\x00!1AMT00\\x0D' | nc $IP $PORT
# (-i 1) allows you to get the status information sent back, not used at the moment...


# nur fuer netcat
echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/nc -i 1 $IP $PORT

#ccu loesung socat
#echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/socat TCP:$IP:60128,cr -
Also 4 Geräte, 4 Commands, funktioniert soweit.
Für netcat kommt übrigens die vorkompilierte Version aus diesem Thread zum Einsatz.

Stufe #2
Es gilt zwei neue Aufgabenstellungen zu lösen:
1. Ein/Aus soll über eine Taste funktionieren
2. Aufgrund des 1min Timeouts vom CuxD werden schnell aufeinandergesendete Commandos ab und zu verschluckt, deshalb soll die Lautstärke in 3er Schritten erhöht/gesenkt werden.

Nach dem Studium der CuxD-Dokumentation ist das auch relativ einfach und wird über zwei Systemvariablen geregelt:

Ein/Aus:

Code: Alles auswählen

var var_Status = dom.GetObject("VAR_Onkyo_V2_Power"); 

if (var_Status.State() == "OFF") {
    var_Status.State("ON");
    dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2on");
} else {
    var_Status.State("OFF");
    dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2off");
}
Lautstärke (analog dazu mit "-"):

Code: Alles auswählen

integer volume = dom.GetObject("VAR_Onkyo_V2_Volume").State().ToInteger();
volume = volume + 3;
dom.GetObject("VAR_Onkyo_V2_Volume").State(volume);
dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2vset " # volume);
Der Parameter "z2vset" ist neu im Script und aus der ISCP Kommando Liste.

Da die Lautstärke über ISCP im HEX-Format angegeben wird gibt es deshalb die HEX-Auswertung als Parameter 2 im Shell Script, möglich, dass dies einfacher funktioniert, aber das tut es soweit.

Schritt #3
Ein bißchen was funktioniert nun wieder. Zwei Internetradios werden direkt angesteuert. Außerdem wird bei ON/OFF ausgewertet ob Zone 2 aktiv ist.

Dazu das aktuelle Script:

Code: Alles auswählen

#!/bin/sh
#
# Simple script to control my Onkyo TX-NR609 from any linux host
# using just bash (or sh) and netcat (nc), works on my Nokia N900.

# Set the IP and PORT of your AVR
IP=10.65.17.1
PORT=60128
WAITKILL=1

########################################
            
# Command to send: 
case $2 in
	01)
	   VOLUME="01"
	   ;;
	02)
       VOLUME="02"
	   ;;
	03)
	   VOLUME="03"
	   ;;
	04)
	   VOLUME="04"
	   ;;
	05)
	   VOLUME="05"
	   ;;
	06)
	   VOLUME="06"
	   ;;
	07)
	   VOLUME="07"
	   ;;
	08)
	   VOLUME="08"
	   ;;
	09)
	   VOLUME="09"
           ;;
        10)
	   VOLUME="0A"
	   ;;
        11)
	   VOLUME="0B"
	   ;;
	12)
	   VOLUME="0C"
	   ;;
	13)
	   VOLUME="0D"
	   ;;
	14)
	   VOLUME="0E"
	   ;;
	15)
	   VOLUME="0F"
	   ;;
	16)
	   VOLUME="10"
	   ;;
	17)
	   VOLUME="11"
	   ;;
	18)
	   VOLUME="12"
	   ;;
	19)
	   VOLUME="13"
	   ;;
	20)
	   VOLUME="14"
	   ;;
	21)
	   VOLUME="15"
	   ;;
	22)
	   VOLUME="16"
	   ;;
	23)
	   VOLUME="17"
	   ;;
	24)
	   VOLUME="18"
	   ;;
	25)
	   VOLUME="19"
	   ;;
	26)
	   VOLUME="1A"
	   ;;
	27)
	   VOLUME="1B"
	   ;;
	28)
	   VOLUME="1C"
	   ;;
	29)
	   VOLUME="1D"
	   ;;
	30)
	   VOLUME="1E"
	   ;;
	31)
	   VOLUME="1F"
	   ;;
	32)
	   VOLUME="20"
	   ;;
	33)
	   VOLUME="21"
	   ;;
	34)
	   VOLUME="22"
	   ;;
	35)
	   VOLUME="23"
	   ;;
	36)
	   VOLUME="24"
	   ;;
	37)
	   VOLUME="25"
	   ;;
	38)
	   VOLUME="26"
	   ;;
	39)
	   VOLUME="27"
	   ;;
	40)
	   VOLUME="28"
	   ;;
	41)
	   VOLUME="29"
	   ;;
	42)
	   VOLUME="2A"
	   ;;
	43)
	   VOLUME="2B"
	   ;;
	44)
	   VOLUME="2C"
	   ;;
	45)
	   VOLUME="2D"
	   ;;
	46)
	   VOLUME="2E"
	   ;;
	47)
	   VOLUME="2F"
	   ;;
	48)
	   VOLUME="30"
	   ;;
	49)
	   VOLUME="31"
	   ;;
	50)
	   VOLUME="32"
	   ;;
	51)
	   VOLUME="33"
	   ;;
	52)
	   VOLUME="34"
	   ;;
	53)
	   VOLUME="35"
	   ;;
	54)
	   VOLUME="36"
	   ;;
	55)
	   VOLUME="37"
	   ;;
	56)
	   VOLUME="38"
	   ;;
	57)
	   VOLUME="39"
	   ;;
	58)
	   VOLUME="3A"
	   ;;
    59)
	   VOLUME="3B"
	   ;;	  
    60)
	   VOLUME="3C"
	   ;;
    61)
	   VOLUME="3D"
	   ;;
    62)
	   VOLUME="3E"
	   ;;
    63)
	   VOLUME="3F"
	   ;;
    64)
	   VOLUME="40"
	   ;;
    65)
	   VOLUME="41"
	   ;;
    66)
	   VOLUME="42"
	   ;;
    67)
	   VOLUME="43"
	   ;;
    68)
	   VOLUME="44"
	   ;;
    69)
	   VOLUME="45"
	   ;;
    70)
	   VOLUME="46"
	   ;;
    71)
	   VOLUME="47"
	   ;;
    72)
	   VOLUME="48"
	   ;;
    73)
	   VOLUME="49"
	   ;;
    74)
	   VOLUME="4A"
	   ;;
    75)
	   VOLUME="4B"
	   ;;
    76)
	   VOLUME="4C"
	   ;;
    77)
	   VOLUME="4D"
	   ;;
    78)
	   VOLUME="4E"
	   ;;
    79)
	   VOLUME="4F"
	   ;;
    80)
	   VOLUME="50"
	   ;;
	*)
	   VOLUME="10"
	   ;;
esac

	
case $1 in
    forcemute)
        COMMAND='!1AMT01'
        echo "Muting"
        ;;
    forceunmute)
        COMMAND='!1AMT00'
        echo "Unmuting"
        ;;
    mute)
        COMMAND='!1AMTTG'
        echo "Toggling Mute"
        ;;
    mutestat)
        COMMAND='!1AMTQSTN'
        echo "Mute Status"
        ;;
    off)
        COMMAND='!1PWR00'
        echo "Power off"
        ;;
    on)
        COMMAND='!1PWR01'
        echo "Power on"
        ;;
    vup)
        COMMAND='!1MVLUP'
        echo "Volume up"
        ;;
    vdown)
        COMMAND='!1MVLDOWN'
        echo "Volume down"
        ;;
    pwrstat)
        COMMAND='!1PWRQSTN'
        echo "Power Status"
        ;;
    z2on)
        COMMAND='!1ZPW01'
        ;;
    z2off)
        COMMAND='!1ZPW00'
        ;;
    z2stat)
        COMMAND='!1ZPWQSTN'
        WAITKILL=2
        ;;
    z2vdown)
        COMMAND='!1ZVLDOWN'
        ;;
    z2vup)
        COMMAND='!1ZVLUP'
        ;;
    z2vstat)
        COMMAND='!1ZVLQSTN'
        WAITKILL=2
        ;;
    z2vset)
        COMMAND="!1ZVL$VOLUME"
        ;;    
    z2net)
        COMMAND="!1SLZ2B"
        ;;
    z2netfav)
        COMMAND="!1NSV010"    
        ;;
    z2netvtuner)
        COMMAND="!1NSV020"
        ;;
    z2netfav1)
        COMMAND="!1NPR01"
        ;;    
    z2netfav2)
        COMMAND="!1NPR02"
        ;;
    *)
        echo "$0 mute, unmute, off, on, vup, vdown, ..."
        exit 1
        ;;
esac
            
############
# String to send is :
ISCP="ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00"
LENGTH=$(echo "\\x$(printf "%0.2x" $(echo $COMMAND | wc -c ))")
MID="\\x01\\x00\\x00\\x00"
CMD=${COMMAND} # Just to show the command's structure. :-P
END="\\x0D"
##########
# Mute example :
# echo -e 'ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x08\\x01\\x00\\x00\\x00!1AMT00\\x0D' | nc $IP $PORT
# (-i 1) allows you to get the status information sent back, not used at the moment...


# nur fuer netcat
echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/nc $IP $PORT > /usr/local/bin/onkyo.tmp &
MYPID=$!
sleep $WAITKILL
kill -9 $MYPID
cat /usr/local/bin/onkyo.tmp | grep -i "!" | grep -i -v "NLSC" | grep -i -v "NLSU" | grep -i -v "NLTF" | tr -d '\cr' | tr -d '\n' | tr -d '!' 

#ccu loesung socat
#echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/socat TCP:$IP:$PORT -

Die erste Änderung betrifft die Laufzeit des Scripts:
Um die CCU nicht unnötig zu belasten wird der netcat Prozess nach einer Sekunde, nach der Übermittlung des Befehls wieder gekillt. Bei Kommands, bei denen auf eine Rückantwort gewartet wird, wird der Timeout auf 2 Sekunden gesetzt, sonst kann es passieren, dass die Antwort noch nicht übermittelt wurde.

Die Auswertung der Antwort gestaltet sich etwas schwieriger. Die \x00 NULL-Values bringen die gängigen String-Manipulationsprogramme auf der Shell etwas aus dem Tritt. Beachtet die grep-Liste. Leider bekomme ich als String die Rückgabe mit einem Zeilenumbruch obwohl der eigentlich ausgefiltert werden soll. Mit dem Power-Command, wo sich die Antwort noch vorhersehbar ist lässt sich das über .Find() lösen. Das Auslesen der Lautstärke z.B. wo die Rückantwort unbekannt ist stellt mich aber vor ein Problem.

Das Homematic-Script für ON/OFF gestaltet sich nun so:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_SETS").State("/usr/local/bin/onkyo z2stat");
dom.GetObject("CUxD.CUX2801008:1.CMD_QUERY_RET").State(1);
var var_Status = dom.GetObject("CUxD.CUX2801008:1.CMD_RETS").State();

if (var_Status.Find( "1ZPW00") >= 0) {
    dom.GetObject("VAR_Onkyo_V2_Power").State("ON");
    dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2on");
} else {
    dom.GetObject("VAR_Onkyo_V2_Power").State("OFF");
    dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2off")
}  
Der zweite Punkt der jetzt funktioniert ist die direkte Ansteuerung von zwei Internetradios, die unter "My Favorites" im Webinterface eingetragen sind. Interessant hier war herauszufinden, ob die direkte Ansteuerung funktioniert, das tut es.

Der Homematic-Script-Code dafür ist jetzt wieder einfacher:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2netfav2");
Stufe #4
Mittlerweile kann ich auch die USB Funktion ansteuern. Beim ersten Mal hab ich über die Onkyo-App den USB Stick (nach Wechsel auf Eingang-USB) per Hand ausgewählt. Seitdem reicht das USB Input Kommando um Musik abzuspielen. Beim zurückwechseln auf die Internetradios muss zuerst der Input zurückgestellt werden, danach kann man die Favorites wieder direkt ansteuern.
Nach Ausschalten der Zone 2 verliert der Onkyo die USB-Stick Zuordnung, deshalb muss 2x mal ein NTCSELECT gesendet werden, einmal zur Auswahl des USB-Sticks (die direkte Ansteuerung von USB vorne oder hinten funktioniert anscheinend nicht und zeigt immer den Stick an) und dann um das erste Lied zu starten.

Im shell Script reicht der Befehl für USB (Rear)

Code: Alles auswählen

 z2usb)
        COMMAND="!1SLZ2A"
        ;;
netenter)
        COMMAND="!1NTCSELECT"
        ;;
Analog dazu ist der Wechsel auf USB einfach:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2usb");
2x

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo netenter");
Die Abfolge ist derzeit in der CCU gelöst, wo sich dann die Logik befinden soll, darüber lässt sich streiten, war eben die einfachste Lösung:
Bild

Dem Aufruf der Internetradios folg nun vorher der Inputwechsel; die beiden Kommandos werden ebenfalls nacheinander mit einer Sekunde Verzögerung ausgeführt:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2net");
dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2netfav2");
Zur Lautstärke noch ein Wort:
Zum Wechseln der wahrgenommen Lautstärke hat sich in den letzten Tagen bei mir ein Sprung von "4" als ideal erwiesen.
Außerdem bin ich noch auf einen "Bug" gestoßen, meine Dezimal->Hex Umrechnung war insofern fehlerhaft, da die CCU bei geringen Lautstärken die führende Null nicht übermittelt, deshalb hier noch die Anpassung:

Code: Alles auswählen

        1)
           VOLUME="01"
           ;;
        2)
           VOLUME="02"
           ;;

Aktuell ist der 6-fach Taster so bedienbar wie gewünscht.
Eine doofe Frage mal, ohne - die ich mir gerade selbst beantwortet habe -.
Der 6-fach Taster ist ja eigentlich ein 12-fach Taster.

Ich hab mir jetzt ein paar Tasten doppelt belegt mit "Tastendruck Lang"

Code: Alles auswählen

    nettrackup)
        COMMAND="!1NTCTRUP"
        ;;
    nettrackdown)
        COMMAND="!1NTCTRDN"
        ;;
    netrandom)
        COMMAND="!1NTCRANDOM"
        ;;
Die entprechenden Homematic Skripte dürften mittlerweile klar sein.
Hier wär vielleicht noch die eine oder andere Funktion möglich, wobei sich dann die Frage stellt ob ein Taster das richtige Eingabegerät ist. Für den Rest der Bewohner reichen definitiv die ersten 6 Tasten.

Stufe #5
Ein Kollege brachte mich auf die richtige Idee, es fehlte bei der Strinverarbeitung der Rückantwort ein "tr -d '\r'".
Das Shell Skript im Gesamtzustand schaut nun so aus:

Code: Alles auswählen

#!/bin/sh
#
# Simple script to control my Onkyo TX-NR609 from any linux host
# using just bash (or sh) and netcat (nc), works on my Nokia N900.

# Set the IP and PORT of your AVR
IP=x.x.x.x
PORT=60128
WAITKILL=1

########################################
            
# Command to send: 
case $2 in
	1)
	   VOLUME="01"
	   ;;
	2)
           VOLUME="02"
	   ;;
	3)
	   VOLUME="03"
	   ;;
	4)
	   VOLUME="04"
	   ;;
	5)
	   VOLUME="05"
	   ;;
	6)
	   VOLUME="06"
	   ;;
	7)
	   VOLUME="07"
	   ;;
	8)
	   VOLUME="08"
	   ;;
	9)
	   VOLUME="09"
           ;;
        10)
	   VOLUME="0A"
	   ;;
        11)
	   VOLUME="0B"
	   ;;
	12)
	   VOLUME="0C"
	   ;;
	13)
	   VOLUME="0D"
	   ;;
	14)
	   VOLUME="0E"
	   ;;
	15)
	   VOLUME="0F"
	   ;;
	16)
	   VOLUME="10"
	   ;;
	17)
	   VOLUME="11"
	   ;;
	18)
	   VOLUME="12"
	   ;;
	19)
	   VOLUME="13"
	   ;;
	20)
	   VOLUME="14"
	   ;;
	21)
	   VOLUME="15"
	   ;;
	22)
	   VOLUME="16"
	   ;;
	23)
	   VOLUME="17"
	   ;;
	24)
	   VOLUME="18"
	   ;;
	25)
	   VOLUME="19"
	   ;;
	26)
	   VOLUME="1A"
	   ;;
	27)
	   VOLUME="1B"
	   ;;
	28)
	   VOLUME="1C"
	   ;;
	29)
	   VOLUME="1D"
	   ;;
	30)
	   VOLUME="1E"
	   ;;
	31)
	   VOLUME="1F"
	   ;;
	32)
	   VOLUME="20"
	   ;;
	33)
	   VOLUME="21"
	   ;;
	34)
	   VOLUME="22"
	   ;;
	35)
	   VOLUME="23"
	   ;;
	36)
	   VOLUME="24"
	   ;;
	37)
	   VOLUME="25"
	   ;;
	38)
	   VOLUME="26"
	   ;;
	39)
	   VOLUME="27"
	   ;;
	40)
	   VOLUME="28"
	   ;;
	41)
	   VOLUME="29"
	   ;;
	42)
	   VOLUME="2A"
	   ;;
	43)
	   VOLUME="2B"
	   ;;
	44)
	   VOLUME="2C"
	   ;;
	45)
	   VOLUME="2D"
	   ;;
	46)
	   VOLUME="2E"
	   ;;
	47)
	   VOLUME="2F"
	   ;;
	48)
	   VOLUME="30"
	   ;;
	49)
	   VOLUME="31"
	   ;;
	50)
	   VOLUME="32"
	   ;;
	51)
	   VOLUME="33"
	   ;;
	52)
	   VOLUME="34"
	   ;;
	53)
	   VOLUME="35"
	   ;;
	54)
	   VOLUME="36"
	   ;;
	55)
	   VOLUME="37"
	   ;;
	56)
	   VOLUME="38"
	   ;;
	57)
	   VOLUME="39"
	   ;;
	58)
	   VOLUME="3A"
	   ;;
    59)
	   VOLUME="3B"
	   ;;	  
    60)
	   VOLUME="3C"
	   ;;
    61)
	   VOLUME="3D"
	   ;;
    62)
	   VOLUME="3E"
	   ;;
    63)
	   VOLUME="3F"
	   ;;
    64)
	   VOLUME="40"
	   ;;
    65)
	   VOLUME="41"
	   ;;
    66)
	   VOLUME="42"
	   ;;
    67)
	   VOLUME="43"
	   ;;
    68)
	   VOLUME="44"
	   ;;
    69)
	   VOLUME="45"
	   ;;
    70)
	   VOLUME="46"
	   ;;
    71)
	   VOLUME="47"
	   ;;
    72)
	   VOLUME="48"
	   ;;
    73)
	   VOLUME="49"
	   ;;
    74)
	   VOLUME="4A"
	   ;;
    75)
	   VOLUME="4B"
	   ;;
    76)
	   VOLUME="4C"
	   ;;
    77)
	   VOLUME="4D"
	   ;;
    78)
	   VOLUME="4E"
	   ;;
    79)
	   VOLUME="4F"
	   ;;
    80)
	   VOLUME="50"
	   ;;
	*)
	   VOLUME="10"
	   ;;
esac

	
case $1 in
    forcemute)
        COMMAND='!1AMT01'
        echo "Muting"
        ;;
    forceunmute)
        COMMAND='!1AMT00'
        echo "Unmuting"
        ;;
    mute)
        COMMAND='!1AMTTG'
        echo "Toggling Mute"
        ;;
    mutestat)
        COMMAND='!1AMTQSTN'
        echo "Mute Status"
        ;;
    off)
        COMMAND='!1PWR00'
        echo "Power off"
        ;;
    on)
        COMMAND='!1PWR01'
        echo "Power on"
        ;;
    vup)
        COMMAND='!1MVLUP'
        echo "Volume up"
        ;;
    vdown)
        COMMAND='!1MVLDOWN'
        echo "Volume down"
        ;;
    pwrstat)
        COMMAND='!1PWRQSTN'
        echo "Power Status"
        ;;
    z2on)
        COMMAND='!1ZPW01'
        ;;
    z2off)
        COMMAND='!1ZPW00'
        ;;
    z2stat)
        COMMAND='!1ZPWQSTN'
        WAITKILL=2
        ;;
    z2vdown)
        COMMAND='!1ZVLDOWN'
        ;;
    z2vup)
        COMMAND='!1ZVLUP'
        ;;
    z2vstat)
        COMMAND='!1ZVLQSTN'
        WAITKILL=2
        ;;
    z2vset)
        COMMAND="!1ZVL$VOLUME"
        ;;    
    z2net)
        COMMAND="!1SLZ2B"
        ;;
    z2usb)
        COMMAND="!1SLZ2A"
        ;;
    z2usbplay)
        COMMAND="!NTCPLAY"
        ;;
    z2netfav)
        COMMAND="!1NSV010"    
        ;;
    z2netvtuner)
        COMMAND="!1NSV020"
        ;;
    z2netfav1)
        COMMAND="!1NPR01"
        ;;    
    z2netfav2)
        COMMAND="!1NPR02"
        ;;
    netenter)
        COMMAND="!1NTCSELECT"
        ;;   
    nettrackup)
        COMMAND="!1NTCTRUP"
        ;;
    nettrackdown)
        COMMAND="!1NTCTRDN"
        ;;
    netrandom)
        COMMAND="!1NTCRANDOM"
        ;;
    *)
        echo "$0 mute, unmute, off, on, vup, vdown, ..."
        exit 1
        ;;
esac
            
############
# String to send is :
ISCP="ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00"
LENGTH=$(echo "\\x$(printf "%0.2x" $(echo $COMMAND | wc -c ))")
MID="\\x01\\x00\\x00\\x00"
CMD=${COMMAND} # Just to show the command's structure. :-P
END="\\x0D"
##########
# Mute example :
# echo -e 'ISCP\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x08\\x01\\x00\\x00\\x00!1AMT00\\x0D' | nc $IP $PORT
# (-i 1) allows you to get the status information sent back, not used at the moment...


# nur fuer netcat
echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/nc $IP $PORT > /usr/local/bin/onkyo.tmp &
MYPID=$!
sleep $WAITKILL
kill -9 $MYPID
case $1 in 
    z2vstat)
        printf "%d" 0x`cat /usr/local/bin/onkyo.tmp | grep -i "!" | grep -i -v "NLSC" | grep -i -v "NLSU" | grep -i -v "NLTF" | tr -d '\cr' | tr -d '\n' | tr -d '!' | tr -d '\r' | cut -c 6,7`
        ;;
    *)
        cat /usr/local/bin/onkyo.tmp | grep -i "!" | grep -i -v "NLSC" | grep -i -v "NLSU" | grep -i -v "NLTF" | tr -d '\cr' | tr -d '\n' | tr -d '!' | tr -d '\r'
        ;;
esac  
#ccu loesung socat
#echo -e "${ISCP}${LENGTH}${MID}${CMD}${END}" | /usr/local/bin/socat TCP:$IP:$PORT -
Nachdem mein "New-Line Problem" beseitigt ist lässt sich nun auch ohne weiteres (evtl. wär das auch vorher gegangen) die aktuelle Lautstärke auslesen und ändern.
Das Homematic-Script zur Änderung der Lautstärke schaut nun so aus:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801008:1.CMD_SETS").State("/usr/local/bin/onkyo z2vstat");
dom.GetObject("CUxD.CUX2801008:1.CMD_QUERY_RET").State(1);
var var_Status = dom.GetObject("CUxD.CUX2801008:1.CMD_RETS").State();
integer volume = var_Status.Substr(5,2).ToInteger();
volume = volume - 4;
dom.GetObject("VAR_Onkyo_V2_Volume").State(volume);
dom.GetObject("CUxD.CUX2801008:1.CMD_EXEC").State("/usr/local/bin/onkyo z2vset " # volume);
Über Substr hol ich mir den Teil der Lautstärke aus der Rückantwort. Ok, zu früh gefreut, den Fehler grade erst beim Schreiben des Forum-Artikel gefunden. Die Rückantwort ist ja wieder hexadezimal. Leider hat Homematic keine direkte Umrechnung. Bin gerade am überlegen wie ich das hinbekomme.

Oh man, die Pipes auf der Shell sind nur noch krank, hab das Shell Script oben bereits aktualisiert.
Funktioniert mit cut und printf.
Die endgültige Version der Lautstärke in Homematic Script schaut wie oben aus und muss nur um den SubStr Teil gekürzt werden.
Zuletzt geändert von Rauschi am 06.11.2013, 22:20, insgesamt 2-mal geändert.

t_heinrich
Beiträge: 542
Registriert: 24.07.2011, 16:38

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von t_heinrich » 02.11.2013, 18:04

Hallo Rauschi,

das klingt ja alles super.
Ich habe ein ähnliches Setup, ich bediene mit dem 6-fach Taster direkt die erste Zone.
Ich habe Cuxd (noch) nicht installiert, bis jetzt hatte ich noch keinen Absturz.

Das mit der Lautstärke musst du mir bitte noch mal erklären, dass habe ich nicht verstanden.
Ich rufe ein Skript direkt auf und um die Lautstärke um 1 Punkt anzuheben, verwende ich folgendes Skript:

Code: Alles auswählen

echo -e "ISCP\x00\x00\x00\x10\x00\x00\x00\x08\x01\x00\x00\x00\x211MVLUP\x0D\x0A" | /usr/local/socat TCP:192.168.1.7:60128,cr -
Ist aber in der Tat unpratikabel, weil man dann gefühlt 100x Drücken muss, um die Lautstärke zu ändern.
Wie hast du das denn mit dem Sprung von 3 bzw. 4 realisiert!?

Gruß Thomas

PS: Habe auch doppelt belegt: Taste 1 An / Aus, Taste 2 Vol- / vorherriger Radiosender, Taste 3 Vol+ / nächster Radiosender

Rauschi
Beiträge: 47
Registriert: 27.10.2013, 12:03

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von Rauschi » 03.11.2013, 10:31

Hallo Thomas,

zur Lautstärke:
In "Stufe #1" habe ich ebenfalls die ISCP-Kommandos "MVLUP" und "MVLDOWN" genutzt, wie von dir beschrieben relativ unpraktikabel.

Die Onkyos 414 und 515 unterstützen ein Lautstärkelevel von 0-80, ab 616 bis 100, im weiteren bleibe ich bei der kleinen Version, falls du einen größeren hast, musst du nur die Lautstärke bis dahin ergänzen und den Wertebereich der Variablen in der CCU anders setzen.

Die Lautstärke 0-80 wird im Onkyo hexadecimal gespeichert, bzw. angegeben. Hier wäre eine Umrechnungstabelle.

Neben der relativen Änderung von MVLUP/DOWN ist es möglich mit dem Kommando M/Z - VL - XX die Lautstärke direkt zu setzen:
MVL10 - setzt die Lautstärke der Zone 1 auf 10
ZVL20 - setzt die Lautstärke der Zone 2 auf 32
Diese Funktion nutzt z.B. der Lautstärke Slider in der Onkyo-App.

Um die Funktion richtig nutzen zu können ist es natürlich zu wissen welche Lautstärke aktuell eingestellt ist, dadurch lässt sich sowas wie "Neue Lautstärke = Alte Lautstärke +- X" abbilden.
Die Lautstärke speichere ich in einer Systemvariablen der CCU und setze die bei jeder Änderung neu. Hier fehlt noch die Abfrage der Lautstärke, falls in der Zwischenzeit ein anderes Gerät die Lautstärke neu gesetzt hat.

Code: Alles auswählen

   *)
      VOLUME="10"
      ;;
Der Teil im Script vermeidet übrigens eine Fehleingabe, so kann man z.B. die Lautstärke nicht auf 500 setzen. 10 hat den Vorteil, das einem erstens nicht die Ohren rausfallen, man aber trotzdem mitbekommt, dass die Zone gerade aktiv ist.

t_heinrich
Beiträge: 542
Registriert: 24.07.2011, 16:38

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von t_heinrich » 03.11.2013, 14:07

Hallo Rauschi,

OK nun ist mir das Ganze schon etwas klarer, wobei ich mich mit Variablen etc. noch nicht beschäftigt habe, puh ob ich das schaffe!? :D

Aber eins ist mir noch nicht ganz klar :?:
Du schreibst es sind absolute Werte, zwischen 0-80, die du direkt ansteuerst (u.a. zB der Slider).
Weiter unter schreibst du, dass du die aktuelle Lautstärke brauchst, um von der in Schritten lauter oder leiser zu werden - das sind dann doch jetzt wieder relative Werte - oder wo ist gerade mein Gedankenfehler?

Ich verändere die Lautstärke auch mittels normaler Fernbedienung, wenn deine Variante also zwingend diese Änderung mitbekommen muss und dies noch nicht richtig implentiert ist, ist das glaub ich nicht das Richtige für mich!?

Am liebsten würde ich einfach die Lautstärke statt in 1er einfach in 3er bzw. 4er Schritten verändern.

Gruß Thomas

Rauschi
Beiträge: 47
Registriert: 27.10.2013, 12:03

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von Rauschi » 06.11.2013, 22:26

Hallo Thomas,

s. Stufe 5, hab das Auslesen der Lautsärke jetzt hinbekommen.

Zum Gedankenfehler:
Die Onkyo ISCP Funktion zum Lautstärke setzen akzepiert nur einen absoluten Wert. Mit den Tast "Leiser" und "Lauter" könnte ich dann nur 2 feste Lautsärken festlegen. Ich will diese ja Variabel einstellen durch öfteres drücken des Tasters. Daher muss ich eben zuerst den aktuellen <absoluten> Wert auslesen, relativ um +- 4 erhöhen/senken, und den daraus resultierenden <absoluten> Wert wieder an den Onkyo übermitteln.

Hoffe das ist verständlich.

Quintessenz des Ganzen:
Müsste bei dir jetzt auch funktionieren. Die Homematic Variable "Lautstärke" ist jetzt eig. nur noch zur Darstellung im Webinterface, wird aber zur Ausführung der Scriptlogik nicht mehr benötigt.

t_heinrich
Beiträge: 542
Registriert: 24.07.2011, 16:38

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von t_heinrich » 10.11.2013, 13:54

Hallo Rauschi,

danke für die Aufklärung, theoretisch ist es mir jetzt klar, jetzt muss ich es nur noch in die Praxis umsetzen :D

Gruß Thomas

Caipirinha
Beiträge: 5
Registriert: 13.11.2013, 09:53

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von Caipirinha » 26.11.2013, 14:31

Hallo zusammen,

ich habe mich gerade durch den Beitrag gelesen und muss sage, dass ich ziemlich erstaunt bin :D
Ich habe mir vor 2 Wochen auch eine CCU2 mit Dimmaktor, ein paar Schaltaktoren, Heizungsaktor, etc. gekauft und bin überzeugt dass wir unser ganzes Haus so umbauen werden.
Das beste daran ist, ich habe auch einen Onkyo TX-NR 828 und wäre begeistert wenn ich so etwas hinbekommen würde!!! :mrgreen:
Nur gibt es ein Problem an der Sache...
Ich bin Elektromeister und kein Programmierer. So wie ich das hier im Forum lese, sollte man schon ziemlich fundierte Kenntnisse im programmieren haben um die ganze Homematicsache optimal zu nutzen. Wo bekomme ich denn hier gute Tipps, Lektüren und was für eine Programmiersprache "spricht" man denn so in Homematickreisen :wink:
Ich würde mich echt über eine Antwort freuen!!!


Viele Grüße

Caipirinha

Goglo
Beiträge: 610
Registriert: 14.04.2012, 18:34
Danksagung erhalten: 1 Mal

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von Goglo » 26.11.2013, 18:59

Das, was hier so besprochen wird, geht von einfach (das sind die per Maus zusammenklickbaren webUI-Programme) über mittel (HMscript, die Programmiersprache der CCU) bis ans Eingemachte, wo Linux-Befehle ausgeführt oder gar eigene Sensoren und Aktoren zusammengelötet und dann natürlich auch programmiert werden. Das mit der Verstärker-Ansteuerung ist die Linux-Ebene, also schon für Eingeweihte.
Aber für Copy&Paste braucht man ja nicht viel können und wenn das Problem schon mal jemand gelöst hat, dann ist das meist halbwegs schnell nachgebaut.
83 Kanäle in 50 Geräten:
3x HM-LC-Sw1-Pl, 1x HM-WDS10-TH-O, 5x HM-PB-4-WM, 3x HM-PB-2-WM, 3x HM-LC-Dim1T-FM, 2x HM-Sec-SC, 4x HM-Sec-RHS, 5x HM-CC-VD, 4x HM-CC-TC, 5x HM-LC-Sw1-FM, 2x HM-Sec-MDIR, 1x HM-WDS30-T-O, 1x HM-LC-Sw1-Pl-2, 2x HM-PB-2-WM55, 1x HM-LC-Dim1L-CV, 1x HM-CCU-1, 1x HM-PBI-4-FM, 1x HM-LC-Dim1L-Pl-2, 1x HM-LC-Dim1T-CV, 1x HM-LC-Dim1L-Pl, 1x HM-LC-Sw2-FM, 1x HM-LC-Sw1-SM, 1x HM-Sec-WDS

82 Kanäle in 43 Geräten:
1x HM-PB-2-WM, 2x HM-LC-Bl1-FM, 3x HM-LC-Bl1PBU-FM, 3x HM-PB-2-WM55, 2x HM-PB-4-WM, 9x HM-CC-VD, 8x HM-CC-TC, 2x HM-LC-Sw2-FM, 1x HM-WDS10-TH-O, 1x HM-CCU-1, 1x HM-Sen-MDIR-O, 4x HM-LC-Sw1-FM, 2x HM-SwI-3-FM, 1x HM-LC-Sw4-SM, 1x HM-LC-Sw1-Pl-2, 1x HM-PBI-4-FM, 1x HM-WDS30-T-O

t_heinrich
Beiträge: 542
Registriert: 24.07.2011, 16:38

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von t_heinrich » 15.04.2014, 21:54

Hallo,

ich möchte mich nun endlich mal "nur" mit der Lautstärkereglung beschäftigen.
Welches Gerät muss ich den in CuxD erstellen?
Bildschirmfoto 2014-04-15 um 21.52.18.png
Ach und gleich noch ne Frage, in deinem Beitrag baust du ja sukssive auf deinen Verbesserungen auf.
Richte ich mich daher am Besten gleich nach Part #5?

Gruß Thomas

Beatz
Beiträge: 45
Registriert: 26.04.2014, 21:45

Re: Direkte Onkyo Steuerung ohne Middleware

Beitrag von Beatz » 11.05.2014, 13:56

Hallo,

vielen Dank für die tolle Arbeit. Die Befehle funktionieren wunderbar bei mir. Leider habe ich Probleme, mehrere Befehle zu senden.

Was ich vorhabe:
Ich möchte in einem Programm 1. den Receiver einschalten, 2. die Lautstärke setzen und 3. den Tuner als Eingang wählen.

Das Problem:
Die Befehle funktionieren einzeln wunderbar, nur nicht mehrere auf einmal. Bei CMD_EXEC scheint der Receiver Befehle nicht zu erhalten, vermutlich ein timing Problem. Der CUxD Doku habe ich entnommen, dass man mittels RETS die Möglichkeit hat, den nächsten Befehl erst die Rückmeldung abzuwarten und dann den nächsten Befehl auszuführen. Leider werde ich aber nicht ganz schlau aus der Doku.

Mein Skript:

Code: Alles auswählen

! Receiver einschalten
boolean bool_Status = dom.GetObject("Onkyo_Power").State();
if (bool_Status == false) {
!    dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("/usr/local/addons/onkyo on");
!    dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("/usr/local/addons/onkyo vset 14");
!    dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("/usr/local/addons/onkyo tuner");


    dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("/usr/local/addons/onkyo on");
    var v = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
    WriteLine(v);
    dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("/usr/local/addons/onkyo vset 14");
    var v = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
    WriteLine(v);
    dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("/usr/local/addons/onkyo tuner");
    var v = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
    WriteLine(v);
}
Hat jemand einen Lösungsvorschlag?

Antworten

Zurück zu „Sonstige Addons“