Yamaha : Remotely Controlled Amplifiers





Background

Yes, Yamaha, I know this is not an usual topic on this blog, but don't worry, we will still code a little ;) Modern amplifiers and home cinema's are now connected. Some with wifi, some with ethernet. It would be nice to have the ability to control them. Mine is a RX-V673, too old to have WiFi but I have an Ethernet port. There is a smartphone app as well. If there is connectivity and an app, for sure we can hack it !

Port 80 is open !

Yes, there is a way to interact with the amplifier : HTTP ! 

MacBook-Pro:~$ nc 192.168.1.31 -z 80
Connection to 192.168.1.31 port 80 [tcp/http] succeeded!

I was able to dig the Yamaha website and I've found a reference document for their API stack ! You can find it here (basic) & here (advanced).

With this, I think we can start with easy stuff : power on, off, mute, volume up, down, ....

First attempt, powering up the main zone. This string must be sent to the amp : <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>

I've found an existing function on the web that works perfectly !

    // -----------------------------------------
    // Function sending http commands to the amp
    // -----------------------------------------

    function sendToAmp($host,$method,$path='/',$data='')
    {
$buf="";
        $method = strtoupper($method);
        $fp = fsockopen($host, 80) or die("Unable to open socket");

        fputs($fp, "$method $path HTTP/1.1\r\n");
        fputs($fp, "Host: $host\r\n");
        fputs($fp, "Content-type: text/plain\r\n");

        if ($method == 'POST') fputs($fp, "Content-length: " . strlen($data) . "\r\n");
        fputs($fp, "Connection: close\r\n\r\n");

        if ($method == 'POST') fputs($fp, $data);

        while (!feof($fp))
          $buf .= fgets($fp,256);

        fclose($fp);
        return $buf;
    }

Let's try to power it up !

<?php
    $ip="192.168.1.31";
    $command="<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>";
    $yam =sendToAmp($ip.':80/YamahaRemoteControl/ctrl','POST','/YamahaRemoteControl/ctrl',$command);

?>

And it works perfectly ! With this, you can do whatever you want, the complex part is to find the relevant commands to match with your need. Sometimes, you will have to add a pause between the commands to let the amp some time to digest the action. Either with a sleep(1) or usleep(500).

For those who are also following on my other API implementation, you probably noticed this one is different. Indeed, Yamaha choose to speaks XML rather than JSON. Probably, because that was fashionable back in the years, I don't know. This is why the method that I'm using here is slightly different than my other framework.

Here are some examples for common actions with this amp : 

Action Command
Main power on <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone></YAMAHA_AV>
Main power off <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Power_Control><Power>Standby</Power></Power_Control></Main_Zone></YAMAHA_AV>
Mute <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Mute>On/Off</Mute></Volume></Main_Zone></YAMAHA_AV>
Volume Up <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>Up 5 dB</Val><Exp></Exp><Unit></Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>
Volume Down <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>Down 5 dB</Val><Exp></Exp><Unit></Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>
Input AV5 <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>AV5</Input_Sel></Input></Main_Zone></YAMAHA_AV>
Input Net Radio <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>NET RADIO</Input_Sel></Input></Main_Zone></YAMAHA_AV>
Input HDMI1 <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI1</Input_Sel></Input></Main_Zone></YAMAHA_AV>
Input HDMI2 <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI2</Input_Sel></Input></Main_Zone></YAMAHA_AV>
Input HDMI3 <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI3</Input_Sel></Input></Main_Zone></YAMAHA_AV>
Retrieve Status <YAMAHA_AV cmd=\"GET\"><Main_Zone><Basic_Status>GetParam</Basic_Status></Main_Zone></YAMAHA_AV>
Volume -45 dB <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>-450</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>
Volume -55 dB <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>-550</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>
Volume -65 dB <YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>-650</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>
Zone 2 Power On YAMAHA_AV cmd=\"PUT\"><Zone_2><Power_Control><Power>On</Power></Power_Control></Zone_2></YAMAHA_AV>
Zone 2 Power Off <YAMAHA_AV cmd=\"PUT\"><Zone_2><Power_Control><Power>Standby</Power></Power_Control></Zone_2></YAMAHA_AV>
Zone 2 Input Net Radio <YAMAHA_AV cmd=\"PUT\"><Zone_2><Input><Input_Sel>NET RADIO</Input_Sel></Input></Zone_2></YAMAHA_AV>
Zone 2 Volume -45 dB <YAMAHA_AV cmd=\"PUT\"><Zone_2><Volume><Lvl><Val>-450</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Zone_2></YAMAHA_AV>
Selection Line 1 <YAMAHA_AV cmd=\"PUT\"><NET_RADIO><List_Control><Direct_Sel>Line_1</Direct_Sel></List_Control></NET_RADIO></YAMAHA_AV>
Selection Line 2 <YAMAHA_AV cmd=\"PUT\"><NET_RADIO><List_Control><Direct_Sel>Line_2</Direct_Sel></List_Control></NET_RADIO></YAMAHA_AV>
Selection Line 3 <YAMAHA_AV cmd=\"PUT\"><NET_RADIO><List_Control><Direct_Sel>Line_3</Direct_Sel></List_Control></NET_RADIO></YAMAHA_AV>
Selection Go Back <YAMAHA_AV cmd=\"PUT\"><NET_RADIO><List_Control><Direct_Sel>Line_3</Direct_Sel></List_Control></NET_RADIO></YAMAHA_AV>

With this, you can already start to create interesting interaction. I have created a script, run in a crontab which starts every working day at 6:20 am and enable Zone 2 (the kitchen) on a specific net radio preset with a specific volume, one hour later, everything stops automatically. This run on the Raspberry Pi which acts as a home automation system. This is very handy !

Here is the cron definition : 

20 6 * * 1-5 /home/pi/start_radio.sh
30 7 * * 1-5 /home/pi/stop_radio.sh

The bash scripts couldn't be more simple : 

~# cat start_radio.sh
#!/bin/bash

php /root/radio-on.php

~# cat stop_radio.sh
#!/bin/bash

php /root/radio-off.php

With this, I don't need to do anything for my morning routine related to listening to the radio ;)

I have created a GitHub repository with some scripts that can be fine tuned to your needs.

It has been tested on my 9 years old RX-V673, but it works on many other models.



I hope this helps! ;)


Comments

What's hot ?

Raspberry : Boots in Emergency Mode

Nutanix : Create a simple VM with Terraform