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
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
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!