No announcement yet.

Yamaha MusicCast Control (without Plug-in)

  • Filter
  • Time
  • Show
Clear All
new posts

    Yamaha MusicCast Control (without Plug-in)

    So to start off, I am new to the world of Home Automation, new to Homeseer, new to Node-Red, and I wouldn't consider myself a programmer, so I apologize in advance if some of my terminology is wrong. Alot of what I do is just combining information from multiple sources, and figuring out how to make it all work together. With that said, if I can do this, I feel anyone can do this with a little bit of work, especially if you follow along with me.

    I don't have it fully completed yet, but I can see now I will (easily?) be able to get full control of all my Yamaha MusicCast devices without needing a plugin, as well as keep the devices up to date in Homeseer so they don't get out of Sync. I wanted to document this along the way of me fully implementing it, in case anyone had any comments/suggestions on how I'm going about it. It won't be as clean as if I had just documented it once finished, but you'll get to see my mistakes along the way I'm sure, and that will always be good for a laugh.

    Anyways, here are links to all the resources I am using to provide control over my MusicCast Devices:

    Node Red Used to send HTTP commands, as well as receive UDP Unicast Event packets to update my Virtual Devices

    HS4 Node Red Integration Obviously, I need Node Red to communicate with Homeseer

    node-red-contrib-yamaha-yxc - Used to control Yamaha MusicCast devices. Can also be done with http commands, but this seems simpler (maybe it won't be, I'm already questioning this method)

    node-red-contrib-avr-yamaha - Even though this uses the older YNCA Protocol, it is required by the previous yamaha-yxc module. I will probably only be using the YXC commands, as I only have one receiver to control, and 4 other MusicCast devices which don't support YNCA, so for the sake of consistency, I will do everything with YXC.

    Yamaha Extended Control API Basic - Details all HTTP commands for basic operation, and also how to receive Events (updates) You could just skip the above two modules and use this to send HTTP commands to devices.

    Yamaha Extended Control API Advanced - Details how to Link MusicCast devices so they will all play in sync. I don't believe the contents of this is covered in the above two modules, so if you are wanting to link devices, it will need to be done with HTTP commands.

    I initially used Big5 to send http commands to the devices, but then when I got to the point where I needed listen for Events to update my virtual devices, I realized Big5 could not receive UDP Unicast messages, as are required. It is great being able to send commands, but I want to make sure my Homeseer Devices don't become out of sync with reality, so getting updates is mandatory for me. I decided to use Node Red to handle the UDP listening, because I was interested in learning Node Red, and I want to keep all control of the devices in a central location. I find it much easier to troubleshoot when all control is happening from the same place (node-red) rather than jumping between node-red and big5 to troubleshoot an issue. I can get the full control of the devices working in Node-Red, then once it is all good, just link node-red and homeseer devices together to sync everything up.

    Initial Setup:

    First, I did some basic housekeeping of my MusicCast Devices. I reserved a Static IP for each device on my DHCP server in my router. I trust that since you are here, you will know how to do that, as every router is different. Write down the IP address for each device. I have the following devices and IP addresses assigned:

    Location - Model - IP
    Bathroom - WX-021 -
    Bedroom - WX-021 -
    Hallway - WX-010 -
    Rec Room - RX-A750 -
    Kitchen - RX-A750 Zone2 - Zone 2
    Upstairs TV - YAS-408 -

    All of these devices except for one (Rec Room/RX-A750) have only a single zone (main). The Rec Room has a second zone, and is controlled from the same IP as the Rec Room, just I will be addressing Zone2 instead of Main. YXC does not use the term Zone1 at all, but uses Main instead.

    Also, make sure Network Standby is turned on on each device. You can do this by going to their management web page and enabling it. You'll want this on so that you can turn devices on/off with network commands.

    So to start off with, I'm going to concern myself with just controlling On/Off state and Volume. I will initially do this all with one device, and then just copy what I did between all the devices. That is the nice thing about only using the YXC commands, it'll work between dedicated MusicCast devices, and Receivers.

    So first I setup a Virtual Device in Homeseer for my Rec Room Receiver. I set it up with two child devices, one for Volume, and one for power. Under Volume I have the following Status/Controls:

    Click image for larger version

Name:	image_2021-04-28_100727.png
Views:	523
Size:	45.8 KB
ID:	1471413

    A note about volume. You can do this several different ways, depending on how you want it to be presented to you. Yamaha uses several different methods for displaying volume level. On receivers they use dB, with a range of -80 to 0. On their MusicCast speakers , they use a range of 0 to 60. On my sound bar they use a range of 0-100. That is the value that you see presented to you either on screen, in their MusicCast app, or by connecting to their web interface. You need to keep this in mind when setting up each different device.

    Now to control the volume, they don't necessarily use those same values. For instance, if I use a browser and enter the following http command to my rec room receiver:

    I get an output of the features of my receiver. You'll notice a few things of interest here:

    actual_volume - this number represents the display volume level, just as the receiver shows it on screen. It lists a range of -80.5 to 16.5 with a step of 0.5. My actual receiver only seems to go to 0 though for some reason. Anyways this value can be used to display the same dB reading in Homeseer as you see on the receiver itself.
    "id:volume" - shows a min of 0, and a max of 161, step of 1. This is the volume level you use to control the receiver. So while I will display on a scale of -80.5 to 0, I will control on a scale of 0-161. I think this is why my receiver only goes to 0.0dB, 80.5 *2 (0.5dB steps) = 161.

    If I send the same command to my sound bar, there is no actual_volume, and my "volume" now has a min of 0, and a max of 100, with a step of 1.

    My WX-021/010 speakers have a min of 0, and a max of 60.

    So when setting up your virtual device, you'll need to first check what volume range your device supports, by using the /system/getFeatures command, then decide how you want to display it in Homeseer. Right now I'm only working on getting live status updates working in Homeseer from my MusicCast devices, so my only Volume Range in Homeseer is from -80 to 0. I turned it into a Slider control, and used a Suffix of dB. So whether I look in Homeseer, on Screen, or in the MusicCast app, I see the same reading everywhere.

    Power control is simple, Just on/off.

    Click image for larger version

Name:	image_2021-04-28_102645.png
Views:	435
Size:	17.7 KB
ID:	1471414

    So my Virtual Device looks like this:

    Click image for larger version

Name:	image_2021-04-28_102829.png
Views:	440
Size:	42.4 KB
ID:	1471415

    In the future I will add more controls to this device, but for now we are just getting the basics working. My next post will be getting these to update in Node Red.


      The first thing in Node Red I wanted to figure out was getting status updates from my MusicCast devices. This can be done two ways:

      1. Send an HTTP GET of http://IPADDRESS/YamahaExtendedContr...main/getStatus - This will poll the device and get its current status which you can then parse out the information you want to update your devices.

      2. Subscribe to a devices "Events" to receive Status updates as they happen. In an HTTP Request, if you send the following header information in Node-Red:

      msg.headers = {};
      msg.headers['X-AppName'] = 'MusicCast/1';
      msg.headers['X-AppPort'] = '41100';
      return msg;
      This will subscribe your Node Red server to Event Updates from that device. The subscription lasts 10 minutes, and is sent as a UDP Unicast message. You can pick any port you want, 41100 is just the one Yamaha uses as an example.

      I'm using both. Since I need to reup the subscription every 10 minutes, anyways, I'm going to do that by using a "getStatus" request from #1, which also contains the header information needed to subscribe to future updates, and then use the response from my getStatus request to update my devices.

      I will also have Node-Red listen on port 41100 for any Status Updates, and then update my devices that way as well.

      Doing both ensures that my devices status isn't anymore than 10 minutes out of sync, in the even that it misses a UDP Unicast message.

      Click image for larger version

Name:	image_2021-05-09_220431.png
Views:	703
Size:	67.8 KB
ID:	1473600

      [{"id":"61ce8ed.295de7","type":"switch","z":"5715c28f.467cfc","name":"","property":"payload.power","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"standby","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":790,"y":560,"wires":[["34b17dec.ed7632"],["958936cb.741fe8"]]},{"id":"c4bce7ba.b14238","type":"hs-device","z":"5715c28f.467cfc","name":"Main Rec Room Rec Room Receiver Power","device":"128","server":"949272a2.055cd","feature":"130","reportonstartup":false,"x":1310,"y":560,"wires":[[]]},{"id":"34b17dec.ed7632","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":540,"wires":[["c4bce7ba.b14238"]]},{"id":"958936cb.741fe8","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":580,"wires":[["c4bce7ba.b14238"]]},{"id":"6cdadd9c.58b124","type":"switch","z":"5715c28f.467cfc","name":"","property":"payload.volume","propertyType":"msg","rules":[{"t":"neq","v":"null","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":790,"y":640,"wires":[["de5a664e.3588e8"]]},{"id":"de5a664e.3588e8","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"payload.main.actual_volume.value","tot":"msg"},{"t":"set","p":"volume","pt":"flow","to":"payload.main.actual_volume.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":640,"wires":[["159c714f.238b5f"]]},{"id":"159c714f.238b5f","type":"hs-device","z":"5715c28f.467cfc","name":"Main Rec Room Rec Room Receiver Volume","device":"128","server":"949272a2.055cd","feature":"129","reportonstartup":false,"x":1310,"y":700,"wires":[[]]},{"id":"429fe713.708bf8","type":"switch","z":"5715c28f.467cfc","name":"","property":"payload.mute","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":790,"y":720,"wires":[["72d4f44c.3bbe0c"],["f80cd190.97a91"]]},{"id":"72d4f44c.3bbe0c","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"-100","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":700,"wires":[["159c714f.238b5f"]]},{"id":"f80cd190.97a91","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"volume","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":740,"wires":[["159c714f.238b5f"]]},{"id":"4e6ccb8a.1ae934","type":"switch","z":"5715c28f.467cfc","name":"","property":"payload.input","propertyType":"msg","rules":[{"t":"eq","v":"audio1","vt":"str"},{"t":"eq","v":"hdmi1","vt":"str"},{"t":"eq","v":"spotify","vt":"str"},{"t":"eq","v":"av4","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":790,"y":420,"wires":[["201d272d.daaef8"],["f24f9738.8a49b8"],["71d7f3a0.9b92cc"],["d7a165f.5971698"]]},{"id":"201d272d.daaef8","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":360,"wires":[["539e8104.45118"]]},{"id":"f24f9738.8a49b8","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":400,"wires":[["539e8104.45118"]]},{"id":"539e8104.45118","type":"hs-device","z":"5715c28f.467cfc","name":"Main Rec Room Rec Room Receiver Input","device":"128","server":"949272a2.055cd","feature":"133","reportonstartup":false,"x":1310,"y":420,"wires":[[]]},{"id":"71d7f3a0.9b92cc","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":440,"wires":[["539e8104.45118"]]},{"id":"d7a165f.5971698","type":"change","z":"5715c28f.467cfc","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"update","tot":"str"},{"t":"set","p":"payload.value","pt":"msg","to":"3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":480,"wires":[["539e8104.45118"]]},{"id":"91dea086.4ad8d","type":"inject","z":"5715c28f.467cfc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"480","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":410,"y":300,"wires":[["ae91a3ac.b6c2f"]]},{"id":"ae91a3ac.b6c2f","type":"function","z":"5715c28f.467cfc","name":"","func":"msg.headers = {};\nmsg.headers['X-AppName'] = 'MusicCast/1';\nmsg.headers['X-AppPort'] = '41100';\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":300,"wires":[["6dad6e8d.ed8fb"]]},{"id":"6dad6e8d.ed8fb","type":"http request","z":"5715c28f.467cfc","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":1230,"y":300,"wires":[["c0079fad.1a0a5"]]},{"id":"c0079fad.1a0a5","type":"json","z":"5715c28f.467cfc","name":"","property":"payload","action":"","pretty":true,"x":580,"y":580,"wires":[["4e6ccb8a.1ae934","61ce8ed.295de7","6cdadd9c.58b124","429fe713.708bf8"]]},{"id":"949272a2.055cd","type":"hs-server","name":"Homeseer","host":"localhost","port":"80"}]
      So here is what it looks like when I send a request out to my MusicCast device to get a Status Update, subscribe to Events, and update my devices. I'll give a quick rundown, but if you really want to see what is going on, just import the above code into your Node-Red and you can study the details.

      I have an Inject Node set to run every 8 minutes, I then insert the header information using a Function Node, and send out my HTTP Request. I will get a response back from the device, which I then use the JSON Node on to format it. Next step is a Switch Node, each switch is watching a specific function (input, power, volume, mute), and routing the output depending on the value (for power I have two possible outputs, on and standby). Each output of the Switch Node is tied into a Change Node, and this is where I change the payload.value (that is what HS Device is looking for to update your devices, read the HS documentation linked in first post if you need to familiarize yourself with it), to the Device Value I setup in each Homeseer Child Device (the payload.value for On changes to 1, and standby changes to 0). Finally I send it out to the Homeseer device using the Homeseer provided Nodes. If this is confusing, you're best to just load the above flow into Node-Red and check it out while reading along.

      Going back to what I said about volume reporting before, you may want things to look a bit different depending on what kind of device you have (Sound Bar, Speaker, Receiver) and how you want the volume level to be displayed (0-100 scale or dB). The receiver outputs both dB reading and where it is on the scale (0-161), so you just need to pick which one you want to use, and setup your switch to look for the proper one. I setup everything using dB for my receiver (payload.main.actual_volume.value).

      Also, since my Volume child device is looking after Mute status as well as volume level, if my device goes from being Muted to Unmuted, instead of having the device display "Unmuted", I want it to go back to displaying the actual volume. This is easily done by just saving each volume update in a variable (I used flow.volume), then when the device is unmuted, instead of sending a payload.value of "-102" (which is my Device Value for unmute), I just send it a payload.value of my flow.volume variable which contains my last set volume level.

      The next step is to listen for UDP Unicast messages, and create updates based on them. That is relatively simple, just use a "UDP In" node, listen for "udp messages" on port 41100 (or whatever port you chose to listen on) using ipv4, and output as a string. Just as before, you can then use a JSON Node to format it, before your series of switches to filter out the information you want and send status updates to your HS Devices.

      One thing to be aware of, when you use the "http://IPADDRESS/YamahaExtendedControl/v1/main/getStatus" HTTP command, you have already specified which Zone you are wanting the information for (main in this instance), so it only returns information on "Main". Therefor in your Switch Nodes, you don't have to specify which zone you are wanting the information for, so you can just look for say "Payload.volume" without specifying a zone.

      When you sign up for "Events" though, you sign up for events from that entire device, which includes all zones that that device is capable of. That means when you receive UDP Unicast Event status updates, they will specify which zone they are referring to. So now instead of watching for "payload.volume" you need to use "payload.main.volume" to specify which zone you are wanting to watch.






            Updated Post 2 with Virtual device I setup and some information on Yamaha Receiver Volume Ranges.


              Updated post 3 with information on using Node Red to update your Homeseer devices. Next step will be easy, having Homeseer control these devices through Node Red. The final step, is to be able to link different MusicCast devices together to be able to play the same audio throughout the entire house. I'm still debating on how to go about doing this. The easy way is to just setup some pre-defined groups, and just switch between those as needed. The alternative is to actually allow Homeseer to create different groups and link devices in whatever way I chose, similar to how it is done using the MusicCast app.

              I'm thinking of just going the pre-defined groups route, as we tend to either be listening to only a single device, or all the devices in the house. Out of all my devices, I also only tend to have 2 different Masters. So I'm thinking of just setting up creating an "Unlinked" command, a "Whole House Link, Upstairs TV Master" command, and a "Whole House Linked, Rec Room Receiver Master" command.


                Originally posted by cd36 View Post
                I will (easily?) be able to get full control of all my Yamaha MusicCast devices , as well as keep the devices up to date in Homeseer
                I know it's an old thread, but I have a silly question - why "without needing a plugin"?


                  Originally posted by alexbk66 View Post

                  I know it's an old thread, but I have a silly question - why "without needing a plugin"?
                  Because there is no plugin available for MusicCast? Sorry I guess I don't fully understand the question?


                    Originally posted by cd36 View Post
                    Because there is no plugin available for MusicCast? Sorry I guess I don't fully understand the question?
                    I started AKYamaha plugin