I recently inherited my family’s 2007-era Yamaha RX-V3900 receiver. It is no slouch, featuring three zones, 1080p video, a host of analog and digital inputs and outputs, as well as 7.2 surround sound.
Serious stuff.
However, one area where the receiver was seriously lacking was the automation department. It is a creature of its time, and so is unsupported by the official Yamaha integration, as well as the other existing community offerings.
While the unit does feature an RS-232 port, it appears to be disabled, and I wasn’t able to conjure any life out of it. While of course I could have used an IR blaster, I decided to rummage around in the receiver’s internal features to see if there was anything more elegant I could use through Home Assistant.
I then discovered this delightful gem:
This is a very basic web control interface offered by the receiver. It turns out, if you connect your receiver to ethernet, then navigate to its IP address, you are served with a quaint, Javascript-powered interface. Neat!
After some digging around in the network tab of my browser, I discovered that this interface uses fairly straightforward XML packets to send commands to the receiver. This meant it would be trivial (if time consuming) to reverse-engineer those commands, and then send my own.
After working out how the various functions were used and completely reverse-engineering the protocol, I then proceeded to sit on the project for several months. After my wife asked whether it was possible to have the receiver turn on automatically when she wanted to start playing music, I promptly leapt into action and finished it off.
Installing
The integration can be installed with HACS - you just need to add it as a custom repository:
Once installed, you can add it as an integration as normal. It has preliminary support for discovering receivers over the network using SSDP, but if that fails you can provide the IP address directly.
Features
This library exposes a separate media player entity for each zone operated by the receiver. Each entity can:
- Be turned on and off
- Be muted, and have its volume adjusted
- Select a source from the available list of sources (which should be populated according to the sources actually available on the receiver)
- (In the case of the main zone) select an audio program
Currently I can only confirm that the integration works with the RX-V3900, but there is no reason why it shouldn’t work with other Yamaha receivers of the same vintage. I would really like to expand its supported model list, but obviously that means I will need as many users as possible to test it on their hardware (see further below).
This integration uses a separate Python library I created, which also allows for some more low-level interaction with the receiver.
What’s next / How can I help?
I’m so glad you asked.
I would like to test this integration with as many Yamaha receivers as possible. Later Yamaha receiver models largely seem to have gone in different directions, supporting protocols like YNCA or even the official integration. However, several other Yamaha receivers from this era also seem to have used this web control interface.
If you have a receiver that uses this interface, and you would like to help me ensure this integration is compatible with it, I would be immensely grateful if you could provide me with some of your XML logs so that I can see how the interface works with different models.
To facilitate this, I have put together this library. The library contains two functions: first, a function which sets up the receiver as normal and then captures the XML packets (called ‘query’ mode); and second, a function which intercepts the XML packets between the computer and the web browser interface (called ‘relay’ mode). Both will be very useful to expanding the integration’s compatibility.
One of the reasons I need the XML logs themselves is that a great deal of the functionality seems to be hardcoded into the Javascript web control interface. For example, the interface just seems to assume that certain features exist in the receiver (such as the number of zones or the list of inputs) and then queries them, meaning that I don’t have any ability to preempt what functions a receiver might have. I also don’t know the interface was expanded for later models, or if they use the same protocol as for earlier models.
More data is the answer - so please, if you’re willing to help, dump the logs and get in touch!
Issues
If you have any issues, please raise an issue on GitHub, or post here. I am not a professional programmer by any means, and I am sure there is much that can be improved in my code.
At some stage I want to get the integration included in the official HACS repository, but that can only happen after more testing, so please give it a try and let me know how you go!

