Denon Remote Protocol Telnet / TCPsend ?

  • Hallo,

    Ich hab seit kurzem ein Denon AVR-X1000 welcher einen Netzwerk anschluss besitzt und auch darüber gesteuert werden kann.
    Offizielles PDF mit den Spezifikationen: hier

    Fernbedienungen gibt es damit natürlich schon einige.
    n ganz simples Proof Of Concept hier
    hierhat jemand was zusammen gebastelt
    mit nem ordentlichen GUI gibts das Command3808 für nen anderes Model, das aber auch recht gut funktioniert.
    es gibt die grundzüge einer php version hier

    und dann gibt es da mich:

    [autoit][/autoit][autoit][/autoit][autoit]

    Opt('MustDeclareVars', 1)

    Example()

    Func Example()
    Local $ConnectedSocket, $szData
    Local $szIPADDRESS = "192.168.1.25"
    Local $nPORT = 23
    TCPStartup()
    $ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
    If @error Then
    MsgBox(4112, "Error", "TCPConnect failed: " & @error)
    Else
    While 1
    $szData = InputBox("Command", @LF & @LF & "Enter command to transmit:")
    If @error Or $szData = "" Then ExitLoop
    TCPSend($ConnectedSocket, $szData)
    If @error Then ExitLoop
    WEnd
    EndIf
    EndFunc ;Example

    [/autoit]

    der daran scheitert nen simples "PWSTANDBY<CR>" command zu senden.

    Leider scheint mein Netzwerk- und Programmiersprachenverständnis nicht mehr auszureichen.


    Sinn der ganzen Sache? Ich hätte gern ein simples Script das ich in den Autostart ordner legen kann das sobal der PC fertig aufgestartet ist den Reciever anschaltet sofern er nicht schon an ist, und dann auf GameMode umschaltet. Wenn ich es jetzt nur noch irgendwie dazu bringen könnte die commands zu akzeptieren :S

    Sieht hier irgendjemand wo mein vermutlich recht simpler Fehler liegen könnte?

    mfg

    Haldi


    Edit:
    Ein simples

    [autoit]

    TCPStartUp()
    $socket = TCPConnect("192.168.1.25", 23)
    TCPSend($socket, "PWON" & @CRLF)
    MsgBox(0, "TCP Example - server response",TCPRecv($socket, 1024))
    TCPCloseSocket($socket)
    TCPShutDown()

    [/autoit]


    Funktioniert ganz gut -.-

    Einmal editiert, zuletzt von Haldi (8. Mai 2014 um 03:58)

  • Unter Umständen musst Du ja ein CRLF als Abschluss des Kommandos im ersten Beispiel auch (im 'Simple' verwendest Du es ja auch) verwenden.

    Also z.B.:

    [autoit]

    TCPSend($ConnectedSocket, $szData & @CRLF)

    [/autoit]

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • vermutlich lag es an genau dem. :rolleyes:

    BTW, hab mir nun zwei Scripts damit gebastelt die recht gut funktionieren :)

    Das Autostart

    [autoit]

    #NoTrayIcon
    TCPStartUp()
    denon ("PWON")
    Sleep(2000)
    denon ("MSQUICK1")

    [/autoit][autoit][/autoit][autoit]

    ;Old method no quick Setting
    ;~ denon ("SIGAME")
    ;~ Sleep(1100)
    ;~ denon ("MSMCH STEREO")
    ;~ sleep(1100)
    ;~ denon ("MV70")
    ;~ Sleep(1100)

    [/autoit][autoit][/autoit][autoit]

    TCPShutDown()

    [/autoit][autoit][/autoit][autoit]

    Func denon($command)
    $socket = TCPConnect("192.168.1.25", 23)
    TCPSend($socket, $command & @CRLF)
    ConsoleWrite(TCPRecv($socket, 1024))
    TCPCloseSocket($socket)
    EndFunc

    [/autoit]

    Und nen Tray Icon womit ich auch am PC kurz umschalten kann.

    [autoit]

    #NoTrayIcon
    #include <TrayConstants.au3>
    TraySetIcon(@UserProfileDir&"\Pictures\Denon.ico")
    TraySetToolTip("Denon Sound Control")

    [/autoit][autoit][/autoit][autoit]

    Opt("TrayMenuMode", 3) ; The default tray menu items will not be shown and items are not checked when selected. These are options 1 and 2 for TrayMenuMode.
    Global $answer

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    TCPStartUp()
    Trayicon()
    TCPShutdown()

    [/autoit][autoit][/autoit][autoit]

    Func Trayicon()

    [/autoit][autoit][/autoit][autoit]

    $iSoundmod = TrayCreateMenu("Sound Mode")
    $iMCHSTEREO = TrayCreateItem("MCH Stereo",$iSoundmod, -1, 1)
    $iMatrix = TrayCreateItem("Matrix",$iSoundmod, -1, 1)
    $iVideoGame = TrayCreateItem("Video Game",$iSoundmod, -1, 1)
    $iDirect = TrayCreateItem("Direct", $iSoundmod, -1, 1)

    [/autoit][autoit][/autoit][autoit]

    $iBass = TrayCreateMenu("Bass")
    $iNoBass = TrayCreateItem("Normal",$iBass, -1, 1)
    $iBBass = TrayCreateItem("Bass Boost",$iBass, -1, 1)
    $iUBass = TrayCreateItem("Ultra Bass", $iBass, -1, 1)

    [/autoit][autoit][/autoit][autoit]

    TrayCreateItem("") ; Create a separator line.

    [/autoit][autoit][/autoit][autoit]

    $iQM1 = TrayCreateItem("Quick Mode 1")

    [/autoit][autoit][/autoit][autoit]

    Denon("PW?")
    ConsoleWrite(StringLen($answer))
    If StringLen($answer) >= 6 Then
    $iPWR = TrayCreateItem("Power On")
    Elseif StringLen($answer) = 5 Then
    $iPWR = TrayCreateItem("Shut Down")
    EndIf

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    TrayCreateItem("") ; Create a separator line.

    [/autoit][autoit][/autoit][autoit]

    $iExit = TrayCreateItem("Exit")

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    TraySetState(1) ; Show the tray menu.

    [/autoit][autoit][/autoit][autoit]

    While 1
    Switch TrayGetMsg()
    Case $iMCHSTEREO
    denon("MSMCH STEREO")
    Case $iMatrix
    denon ("MSMATRIX")
    Case $iVideoGame
    denon ("MSVIDEO GAME")
    Case $iDirect
    denon ("MSDIRECT")
    Case $iQM1
    denon ("MSQUICK1")
    Case $iNoBass
    denon ("CVSW 49")
    Case $iBBass
    denon ("CVSW 56")
    Case $iUBass
    denon ("CVSW 62")
    Case $iPWR
    if TrayItemGetText($iPWR) = "Power On" Then
    denon ("PWON")
    TrayItemSetText($iPWR, "Shut Down")
    ElseIf TrayItemGetText($iPWR) = "Shut Down" Then
    denon ("PWSTANDBY")
    TrayItemSetText($iPWR, "Power On")
    EndIf
    Case $iExit ; Exit the loop.
    ExitLoop
    EndSwitch
    WEnd
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func denon($command)
    $socket = TCPConnect("192.168.1.25", 23)
    TCPSend($socket, $command & @CRLF)
    $answer = TCPRecv($socket, 1024)
    TCPCloseSocket($socket)
    EndFunc

    [/autoit]


    EDIT:

    Mir sind aber noch 2 dinge ein Dorn im Auge für dir mir gerade keine Lösung in den Sinn kommt.
    1. Gibt es eine möglichkeit das sich das Tray menue nicht schliesst nachdem man auf etwas geclickt hat ?
    2. Wie bringt ich das am besten rein das sich ein TrayItem automatisch aktualisiert sobal ich das tray menue öffne ? Wenn ich es in die While 1 schleiffe vor dem Switch einbaue gibt das doch nur ein riesen workload oder ?

    Einmal editiert, zuletzt von Haldi (8. Mai 2014 um 22:23)

  • Mir sind aber noch 2 dinge ein Dorn im Auge für dir mir gerade keine Lösung in den Sinn kommt.
    1. Gibt es eine möglichkeit das sich das Tray menue nicht schliesst nachdem man auf etwas geclickt hat ?
    2. Wie bringt ich das am besten rein das sich ein TrayItem automatisch aktualisiert sobal ich das tray menue öffne ? Wenn ich es in die While 1 schleiffe vor dem Switch einbaue gibt das doch nur ein riesen workload oder ?


    1. Glaube nicht, dass das geht.
    2. Auch das scheint nicht zu gehen. Grund ist, dass das Script pausiert sobald sich das Traymenü öffnet. Du müsstest also eher permanent in Intervallen den Text des Trayicons neu setzen lassen, sprich in deiner while Schleife in Verbindung mit einem angemessenen Timer, oder alternativ via adlibregister. So sollte der Status möglichst aktuell sein wenn du das Traymenü einblendest.

    Viel einfacher und sinnvoller wäre es meiner Meinung nach wenn du dich vom Traymenü verabschiedest und stattdessen eine GUI verwendest, welche oberhalb der Taskleiste eingeblendet wird wenn du aufs Icon klickst und ausgeblendet wird wenn du den "minimize to tray button" klickst. Das sollte beide Probleme lösen. Jenachdem wie lange die Statusabfrage dauert kannst du diese dann on demand (also bei klick aufs tray icon) oder aber wie oben vorgeschlagen doch eher permanent in Intervallen machen (z.B. wenn es mehrere Sekunden dauert, da sonst die GUI sehr lange nicht sichtbar wäre).

    EDIT:

    Ahja und warum baust du dein tcpconnect / tcpclose nicht am Scriptanfang bzw. Scriptende ein anstatt für jeden Befehl innerhalb der Funktion neu zu connecten? Das sollte die Performance ein wenig verbessern. Problematisch wäre das nur wenn der Server Verbindungen nach einer gewissen Zeit trennt, aber auch dem könnte man entgegenwirken, entweder durch regelmässigen Kontakt oder aber durch die Prüfung ob TCPsend erfolgreich war (falls nicht wird die Verbindung innerhalb der Funktion neu aufgebaut und erneut gesendet).

  • Zitat von misterspeed


    Ahja und warum baust du dein tcpconnect / tcpclose nicht am Scriptanfang bzw. Scriptende ein anstatt für jeden Befehl innerhalb der Funktion neu zu connecten? Das sollte die Performance ein wenig verbessern. Problematisch wäre das nur wenn der Server Verbindungen nach einer gewissen Zeit trennt, aber auch dem könnte man entgegenwirken, entweder durch regelmässigen Kontakt oder aber durch die Prüfung ob TCPsend erfolgreich war (falls nicht wird die Verbindung innerhalb der Funktion neu aufgebaut und erneut gesendet).

    Sollte man denken, nicht wahr? Aber ich weiss nicht obs am 200ms(300ms?) Timeout des Befehls liegt, aber auf die andere weise wurde kein einziger Befehl akzeptiert! Darum musste das TCPconnect hat mit in die Funktion.

    da meistens sowieso nur 1 Befehl auf einmal gesendet wird ist die Performance auch nicht so wichtig.