Yamaha musiccast binding

I feared. I have already tried to find he appropriate code site from the Sonos binding , but I have not found so far. Anyone some ideas?

Hi,

sorry for delay, I’m blocked a little bit with other task. I try to work on the Binding, but not yet something to show

Here is the Source Code

BEst Frank

Yamaha Binding SRC

I’ve no experience with this type of binding and how to use it in openhab, is it similar in application to another binding that i can look at the wiki for instructions? or if not maybe someone can show how 1 of the above functions can be configured so i can work out the rest?

Very excited to test this so i can stop trying to create rules and multiple items just to turn on my soundbar 8)

Thanks in advance.

ps. i have wx-010 , isx-18D , and YAS-306.

You just have to install the Binding manually for using it in this early state.
That means you have to download the jar file that frank has linked and put it in the addons folder of your openhab installtion.

Edit:
In my case (Openhabian installed on a raspberry the addons folder is located under

/usr/share/openhab2/addons

Anyone developed a method for finding the MusicCast services, I know they advertise as an http sink but there’s got to be a more specific way of identifying them, sorry if I’ve overlooked something! Thanks Ed

Ha! Didn’t know they released the API docs for MusicCast!

I figured a few things out by reverse engineering (sniffing the HTTP traffic from the official app) a year or so ago, when I was an openHAB noob :slight_smile:

Here’s my setup in case someone is interested.
My items:

Switch MusicCast_Salon "Salon (ampli) [%s]" <switch> {http="<[http://192.168.1.XXX/YamahaExtendedControl/v1/main/getStatus:20000:JS(musiccast_power.js)] >[ON:GET:http://192.168.1.XXX/YamahaExtendedControl/v1/main/setPower?power=on] >[OFF:GET:http://192.168.1.XXX/YamahaExtendedControl/v1/main/setPower?power=standby]"}
Switch MusicCast_Chambre "Chambre (réveil) [%s]" <switch> {http="<[http://192.168.1.YYY/YamahaExtendedControl/v1/main/getStatus:20000:JS(musiccast_power.js)] >[ON:GET:http://192.168.1.YYY/YamahaExtendedControl/v1/main/setPower?power=on] >[OFF:GET:http://192.168.1.YYY/YamahaExtendedControl/v1/main/setPower?power=standby]"}
Switch MusicCast_Bureau "Bureau (enceinte) [%s]" <switch> {http="<[http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/getStatus:20000:JS(musiccast_power.js)] >[ON:GET:http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/setPower?power=on] >[OFF:GET:http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/setPower?power=standby]"}

Number MusicCast_Salon_Volume "Volume Salon [%d]" <soundvolume> {http="<[http://192.168.1.XXX/YamahaExtendedControl/v1/main/getStatus:20000:JSONPATH($.volume)] >[*:GET:http://192.168.1.XXX/YamahaExtendedControl/v1/main/setVolume?volume=%2$s]"}
Number MusicCast_Chambre_Volume "Volume Chambre [%d]" <soundvolume> {http="<[http://192.168.1.YYY/YamahaExtendedControl/v1/main/getStatus:20000:JSONPATH($.volume)] >[*:GET:http://192.168.1.YYY/YamahaExtendedControl/v1/main/setVolume?volume=%2$s]"}
Number MusicCast_Bureau_Volume "Volume Bureau [%d]" <soundvolume> {http="<[http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/getStatus:20000:JSONPATH($.volume)] >[*:GET:http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/setVolume?volume=%2$s]"}

String MusicCast_Artist "Artiste [%s]" <parents_1_1> {http="<[http://192.168.1.XXX/YamahaExtendedControl/v1/netusb/getPlayInfo:20000:JSONPATH($.artist)]"}
String MusicCast_Track "Track [%s]" <microphone> {http="<[http://192.168.1.XXX/YamahaExtendedControl/v1/netusb/getPlayInfo:20000:JSONPATH($.track)]"}

Number MusicCast_Link "MusicCast Link" <network>

transform/musiccast_power.js is simply:

(JSON.parse(input).power == 'on') ? "ON" : "OFF"

I also wanted to link the main AV receiver to the other rooms easily - I always use the AV receiver as the link master so I control the music using the Yamaha receiver binding.
Here’s how I did it:

rule "MusicCast unlink"
  when
    Item MusicCast_Link received update 0
  then
    logInfo("MusicCast", "Unlinking MusicCast rooms")
    sendHttpPostRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/setServerInfo", "application/json", '{ "group_id": "" }')
    sendHttpPostRequest("http://192.168.1.YYY/YamahaExtendedControl/v1/dist/setClientInfo", "application/json", '{ "group_id": "" }')
    sendHttpPostRequest("http://192.168.1.ZZZ/YamahaExtendedControl/v1/dist/setClientInfo", "application/json", '{ "group_id": "" }')
end


rule "MusicCast link Chambre to Salon"
  when
    Item MusicCast_Link received update 1
  then
    logInfo("MusicCast", "Linking MusicCast room Chambre to Salon")
    sendHttpGetRequest("http://192.168.1.YYY/YamahaExtendedControl/v1/main/setPower?power=on")
    sendHttpPostRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/setServerInfo", "application/json", '{"group_id":"a89b0f9f2d334b63bab6bcc48a0587f0","type":"add","client_list":["192.168.1.YYY"]}')
    sendHttpPostRequest("http://192.168.1.YYY/YamahaExtendedControl/v1/dist/setClientInfo", "application/json", '{"group_id":"a89b0f9f2d334b63bab6bcc48a0587f0","zone":["main"],"server_ip_address":"192.168.1.XXX"}')
    sendHttpGetRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/startDistribution?num=0")
    sendHttpPostRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/setGroupName", "application/json", '{"name": "Salon+Chambre"}')
end

rule "MusicCast link Bureau to Salon"
  when
    Item MusicCast_Link received update 2
  then
    logInfo("MusicCast", "Linking MusicCast room Bureau to Salon")
    sendHttpGetRequest("http://192.168.1.ZZZ/YamahaExtendedControl/v1/main/setPower?power=on")
    sendHttpPostRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/setServerInfo", "application/json", '{"group_id":"a89b0f9f2d334b63bab6bcc48a0587f0","type":"add","client_list":["192.168.1.ZZZ"]}')
    sendHttpPostRequest("http://192.168.1.ZZZ/YamahaExtendedControl/v1/dist/setClientInfo", "application/json", '{"group_id":"a89b0f9f2d334b63bab6bcc48a0587f0","zone":["main"],"server_ip_address":"192.168.1.XXX"}')
    sendHttpGetRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/startDistribution?num=0")
    sendHttpPostRequest("http://192.168.1.XXX/YamahaExtendedControl/v1/dist/setGroupName", "application/json", '{"name": "Salon+Bureau"}')
end

I believe the order of the calls is important.
IIRC any random string will do for the group_id and I could also choose the name - the Yamaha app will still display e.g. “Salon +1 room” but the group name you chose will appear in some places like Spotify which is actually better than what the app does :wink:

Incidentally, if you control the volume of a receiver using the yamahareceiver binding and it’s a link master, the volumes of the additional rooms will be adjusted as well.

Hope that helps.

I’d be very interested in that as well!

3 Likes

Wow, @ysc that’s pretty cool for reverse engineering. I have the switch for my soundbar working with on/off functionality, but could you share a snippet of your sitemap with how you are handling the volume controls? are you using openhab2? and are they designed for a specific UI? is it configured with up/down control?

Thanks in advance from an forever openhab noob.

The volumes are numbers so in sitemaps a Slider or Setpoint will work.
Note that the max volume values in the MusicCast API depend on the device for some reason.
e.g. for my AV Receiver it’s 120 (?) and for the wireless speakers 60.

  Frame label="Audio & Video" {
    Text item=Yamaha_Power label="Audio Multiroom [%s]" {
      Frame label=Status {
        Switch item=MusicCast_Salon
        Switch item=MusicCast_Bureau
        Switch item=MusicCast_Chambre
        Selection item=MusicCast_Link icon="network" label="MusicCast Link" mappings=[0="No link", 1="Salon + Bureau", 2="Salon + Chambre"]
      }
      Frame label=Volumes {
        Slider item=Yamaha_Volume // this is the Yamaha receiver binding Volume channel (0-100)
        Setpoint item=MusicCast_Salon_Volume minValue=10 maxValue=120 step=5
        Setpoint item=MusicCast_Chambre_Volume minValue=10 maxValue=60 step=5
        Setpoint item=MusicCast_Bureau_Volume minValue=10 maxValue=60 step=5
      }
      Frame label=Sources {
        // those items are linked to the Yamaha receiver binding, not MusicCast
        //Switch item=Yamaha_Mute
        Selection item=Yamaha_Input icon=text mappings=[HDMI1="Kodi",HDMI2="Pi",Spotify="Spotify","NET RADIO"="Net Radio",TUNER="Tuner"]
        Selection item=Yamaha_NetRadio icon=text label="Radio" mappings=[1="Ambient", 2="Spotify Discover Weekly", 3="Spotify Release Radar", 4="Spotify My Library"]
        Selection item=Yamaha_Surround icon=text label="DSP Mode" mappings=["5ch Stereo"="5ch Stereo","Standard"="Standard"]
      }
      Frame label="Now Playing" {
        Text  item=MusicCast_Artist
        Text  item=MusicCast_Track
      }
    }

I also have duplicated invididual room’s volume and link in the room’s page (along with lights etc.)

Last but not least this is the equivalent HABPanel dashboard :wink:

1 Like

Thanks a lot! that’s great, this will accelerate my learning in this area of OH. :slight_smile:

Glad to see that there’s something going forward in this topic. :slight_smile:
I was really busy with things i had to do for my master degree
and Master thesis will take some time too in the 2nd half of this year,
but i will try to push this topic forward again in the next time.

Your reverse engineering and created stuff looks great btw.@ysc

1 Like

I was looking around a bit and found this:

I dont know if it could help us, but wanted to pin it here.

This seems to be controlling musiccast from code, but has anyone looked into creating a zone for a linux server? Then I can stream to it. Was thinking a Raspberry PI in the garage.

Hey ysc,

i assume the two green buttons set the input t spotify and start the respective playlists? How does that exactly work. That would be lovely to be able to select at least some standard playlist to play on musiccast. even better would obviously an option to brows through spotify

@Tomibeck sure, but it’s not exactly MusicCast, it’s actually a channel of the yamahareceiver binding.
So it will only work with a receiver capable of communicating with the legacy protocol.

What I found is you can add favorites with the MusicCast app to your receiver, including Spotify playlists (just use the context menu & add to a favorites slot while you’re playing it):

Then using an item linked to the “netradiotune” channel, like this:

Number Yamaha_NetRadio  "Net Radio" {channel="yamahareceiver:yamahaAV:xxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx:netradiotune"} 

You can send a playlist number to the item and it will tune your receiver to the corresponding playlist, including those which “rotate” once a week like Discover Weekly and Release Radar.

Hey @FrankZimmer,

Would it be ok if i host your already existing code on GitHub to have a public base for contributing to the binding?

If yes it would be great, to have your “signed off by”-data to mention it within commits. :slight_smile:

Hi, I’m just trying to show the AlbumArt on the HABPanel…
Right now I managed to get back the current jpg, but the beginning of the link seems to be missing…

String Ymh_sz_Aurl	"albumart_url"	{http="<[http://192.168.77.78/YamahaExtendedControl/v1/netusb/getPlayInfo:3000:JS(ymh_sz_albumart_url.js)]"}

returns the following:

/YamahaRemoteControl/AlbumART/AlbumART4415.jpg

Has anybody an idea how to modify the script to get

http://192.168.77.78/YamahaRemoteControl/AlbumART/AlbumART4415.jpg

Hardcoding it in ymh_sz_albumart_url.js is not an option?

var urlbase = "http://192.168.77.78"

// Get the Albumart url from API
var albumart_url = * here goes the code *

return (url_base + albumart_url)

You just have to manage that the device always gets the same ip,
but you have to do that anyway for the http binding.

(Of course a dynamic solution would be more comfortable, but this should work for now.)

Off-Topic:

I didn’t imagine that i am owning 22% of the whole topic. :smiley:
Sry for that.

Hi,

here you get the Code

1 Like

Hey all,

I prepared the Yamaha binding to include the new Json based protocol. Yamaha calls it Yamaha extended control protocol. It is exclusively used in all AVRs produced later than ~2013 and therefore the addition is a good thing to have.

The first step is this PR:

If anybody wants to help implementing the actual protocol (based on the linked java library for example), you are very welcome.

Hopefully we get this protocol merged fast.

Cheers,
David

1 Like

It might make sense to include the album art URL in a separate channel, what do you guys think?