Yamaha Musiccast Node Collection

If you're interested in controlling and monitoring a Yamaha Musiccast network, this collection may work for you. Not limited to Musiccast functions, it can also be used to control compatible stand-alone Yamaha devices like receivers.

The collection is designed by a huge music fan to be all about the music. It is quite simple to use and avoids the overhead of technologies such as UPNP and DLNA. As the collection is focused solely on working with Yamaha devices, it is much more stable and less prone to "noise" from other devices on a network.

4 Likes

Hello,
i have started to use the Yama Musiccast Node.
For Zone node input selection Net Radio is missing.
Via android app it is possible to select it.
Is there a way to select missing inputs?
"input": "juke|tidal|qobuz|deezer|server|bluetooth|airplay|mc_link|usb",
on input node it is shown, but not possible to select.

it is just missing in the dropdown menue.

Works with manual set:
{
"input": "net_radio",
"mode": "autoplay_endabled"
}

Which dropdown are you referring to? The Zone node should not have a dropdown for "input" as that value, if required for a command, is defined in Attributes. Are you referring to the example attribute contents that be copied in?

sorry, i worte a little bit confusing.
On Node "Zone" if command is set to "input" the "attribute list options" is not complete.
That confused me in the beginning.
{"input":"juke|tidal|qobuz|deezer|server|bluetooth|airplay|mc_link|usb","mode":"autoplay_disabled"}

After i realised that i can use the name from the yamaha android app ( original input name, not anything renamed) it works perfect.

I first thought, that the listed atributes are the only one ,who will be accepted by the nodes.
But they are only examples ;).

[
    {
        "id": "f37cc8a1c6f1aab2",
        "type": "subflow",
        "name": "Subflow 3",
        "info": "",
        "in": [
            {
                "x": 60,
                "y": 260,
                "wires": [
                    {
                        "id": "c052e79f7bd986f5"
                    },
                    {
                        "id": "1cc7edee7a661424"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 920,
                "y": 40,
                "wires": [
                    {
                        "id": "1cc7edee7a661424",
                        "port": 0
                    }
                ]
            }
        ]
    },
    {
        "id": "79e741d7dde2c3a1",
        "type": "switch",
        "z": "f37cc8a1c6f1aab2",
        "name": "Task",
        "property": "payload.entities.0.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "musik",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "radio",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "mp3",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 530,
        "y": 480,
        "wires": [
            [
                "54d000572d259653"
            ],
            [
                "54d000572d259653"
            ],
            [
                "f71e9c5d2d10ae4a"
            ]
        ]
    },
    {
        "id": "54d000572d259653",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone2_On",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"on\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 460,
        "wires": [
            [
                "cbda1eb325f4a6f3"
            ]
        ]
    },
    {
        "id": "dd5c23c015860189",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone2_InputSever",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setInput",
        "type_command": "command",
        "payload": "{\"input\":\"server\",\"mode\":\"autoplay_enabled\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 970,
        "y": 540,
        "wires": [
            []
        ]
    },
    {
        "id": "d0aa96e7c76679d8",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone2_VolumeNormal",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setVolume",
        "type_command": "command",
        "payload": "{\"volume\":\"60\",\"step\":\"1\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 760,
        "y": 420,
        "wires": [
            []
        ]
    },
    {
        "id": "cbda1eb325f4a6f3",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone2_InputNetRadio",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setInput",
        "type_command": "command",
        "payload": "{\"input\":\"net_radio\",\"mode\":\"autoplay_endabled\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 980,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "f71e9c5d2d10ae4a",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone2_On",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"on\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 540,
        "wires": [
            [
                "dd5c23c015860189"
            ]
        ]
    },
    {
        "id": "b023ac8df53b8ebe",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone2_VolumeLauter",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setVolume",
        "type_command": "command",
        "payload": "{\"volume\":\"80\",\"step\":\"1\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 760,
        "y": 380,
        "wires": [
            []
        ]
    },
    {
        "id": "6a95b17f3afcb1b2",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone2_Off",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone2",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"standby\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "c052e79f7bd986f5",
        "type": "switch",
        "z": "f37cc8a1c6f1aab2",
        "name": "",
        "property": "payload.entities.1.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "garten",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "terrasse",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "draussen",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 4,
        "x": 190,
        "y": 260,
        "wires": [
            [
                "f19b881211b0cd60"
            ],
            [
                "f19b881211b0cd60"
            ],
            [
                "f19b881211b0cd60"
            ],
            [
                "497e313c1848bb2f"
            ]
        ]
    },
    {
        "id": "580138c167c57028",
        "type": "switch",
        "z": "f37cc8a1c6f1aab2",
        "name": "Task",
        "property": "payload.entities.0.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "musik",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "radio",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "mp3",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 530,
        "y": 220,
        "wires": [
            [
                "ea5fe6172a2ac462"
            ],
            [
                "ea5fe6172a2ac462"
            ],
            [
                "a29066866b3fa9cb"
            ]
        ]
    },
    {
        "id": "ea5fe6172a2ac462",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone3_On",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"on\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 200,
        "wires": [
            [
                "44adcfd2d9bab9cc"
            ]
        ]
    },
    {
        "id": "af0faac9d8bce2f6",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone3_InputSever",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setInput",
        "type_command": "command",
        "payload": "{\"input\":\"server\",\"mode\":\"autoplay_enabled\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 970,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "209fb0c723f65d37",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone3_VolumeNormal",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setVolume",
        "type_command": "command",
        "payload": "{\"volume\":\"60\",\"step\":\"1\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 760,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "44adcfd2d9bab9cc",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone3_InputNetRadio",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setInput",
        "type_command": "command",
        "payload": "{\"input\":\"net_radio\",\"mode\":\"autoplay_endabled\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 980,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "a29066866b3fa9cb",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone3_On",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"on\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 280,
        "wires": [
            [
                "af0faac9d8bce2f6"
            ]
        ]
    },
    {
        "id": "a8fdb47ab951e518",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "Zone3_VolumeLauter",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setVolume",
        "type_command": "command",
        "payload": "{\"volume\":\"80\",\"step\":\"1\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 760,
        "y": 120,
        "wires": [
            []
        ]
    },
    {
        "id": "3537bceffcfc1984",
        "type": "musiccast-zone",
        "z": "f37cc8a1c6f1aab2",
        "mc": "8be10d108ed04a37",
        "name": "GalerieZone3_Off",
        "device": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
        "type_device": "device",
        "zone": "zone3",
        "type_zone": "zone",
        "command": "setPower",
        "type_command": "command",
        "payload": "{\"power\":\"standby\"}",
        "type_payload": "json",
        "f_show_status": false,
        "x": 750,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "497e313c1848bb2f",
        "type": "switch",
        "z": "f37cc8a1c6f1aab2",
        "name": "",
        "property": "payload.entities.2.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "aus",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "lauter",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "leiser",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 4,
        "x": 390,
        "y": 460,
        "wires": [
            [
                "6a95b17f3afcb1b2"
            ],
            [
                "b023ac8df53b8ebe"
            ],
            [
                "d0aa96e7c76679d8"
            ],
            [
                "79e741d7dde2c3a1"
            ]
        ]
    },
    {
        "id": "f19b881211b0cd60",
        "type": "switch",
        "z": "f37cc8a1c6f1aab2",
        "name": "",
        "property": "payload.entities.2.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "aus",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "lauter",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "leiser",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 4,
        "x": 390,
        "y": 160,
        "wires": [
            [
                "3537bceffcfc1984"
            ],
            [
                "a8fdb47ab951e518"
            ],
            [
                "209fb0c723f65d37"
            ],
            [
                "580138c167c57028"
            ]
        ]
    },
    {
        "id": "1cc7edee7a661424",
        "type": "function",
        "z": "f37cc8a1c6f1aab2",
        "name": "set id and text receiver",
        "func": "msg.payload =  msg.payload.entities[0].raw_value + ' ' + msg.payload.entities[1].raw_value;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 340,
        "y": 40,
        "wires": [
            []
        ]
    },
    {
        "id": "8be10d108ed04a37",
        "type": "musiccast-config",
        "name": "RX-A2080",
        "device_list": {
            "c1b8fc66-8bff-4f29-bebf-3ba8f269505e": {
                "name": "RX-A2080 768070",
                "address": "192.168.178.119",
                "model": "RX-A2070",
                "zones": "Main",
                "inputs": "",
                "serial": "03554223",
                "udn": "uuid:9ab0c000-f668-11de-9976-64cc22768070",
                "uuid": "c1b8fc66-8bff-4f29-bebf-3ba8f269505e",
                "status": "seen"
            }
        },
        "f_use_debug": false,
        "zone_list": {
            "main": "Main",
            "zone2": "Zone 2",
            "zone3": "Zone 3",
            "zone4": "zone 4"
        },
        "list_language": "en",
        "command_timeout": "2000",
        "main": "Main",
        "zone_2": "Zone 2",
        "zone_3": "Zone 3",
        "zone_4": "zone 4",
        "services_timeout": "5000"
    }
]

Thank you very much for providing your node collection.
After a first success with basic commands like seeing devices, volume and starting/stopping them, I have a hard time to figure out how to set up music sources on the receivers.
Especially the necessary message content is a miracle to me without examples.
Are there any examples from your tests you could share?
(Or are the tests open source and you can share a link?)
What I'm trying to do is to play internet radio and spotify but for both I can't seem to find a guide on what to put into the messages and the docs don't help there.
Thank you!

Hello, glad you like the collection.

Navigating music services can be a bit of a challenge!

I only have Tidal to work with and I attached an example flow to this post that may help. Read the flow description to walk through what's happening. I believe most services will be basically the same. The document "Yamaha YXC Advanced API" that's linked to in the node help explains things in detail.

Basically, it's like navigating a file directory structure on the computer: Look at a directory, find the directory (list item) you want to go into and then enter it by supplying the item index number. Names don't work, it's always index numbers. So you'll have to drill down every time to get to where you want, checking all the way to ensure nothing has changed in the way things are ordered from the other end. You can NEVER rely on a certain track being at the exact same place as before.

To start over from the literal top, back out of each directory (list) until you end up as far as you can go.

Internet stations are fairly simple. Just switch to the input "net_radio" and execute a [setPlayback] {"playback":"play"}. You may have to setup the stations first though. I've never done that through my collection so let me know if you figure out how. (I set up my stations on the Yamaha receiver itself)

Let me know if this helps,
Vahdettin

Tidal Navigation.json (7.5 KB)

Quick follow up: Yes, the inline documentation and example attributes are not always completely accurate nor do they always provide every option possible for a command. It's just due to a lack of time on my part. Refer to the API docs to double-check everything.

--
Vahdettin

I have tried to use this collection to play just one song from a USB device, it plays the correct song, but when it's finished, it starts to play the next song on the USB device, on and on... is there a way to stop this from happening??? for my application, I want to play just one track..

My receiver is RX-A2050

thanks for any advice....

Are all the sound files in the same folder? If so, I think what happens is that Musiccast considers every file in a folder as belonging to the same "album" and just runs through all the ones that follow.

The way I got around this was to assign each music file to a preset and then recall the preset to play the file. Just make sure the preset is a single music file and not a directory or you'll probably get the same behavior.

HTH.

All in the same folder, 200 of them, I want to send commands from my Seeburg 3WA wall box to NodeRed to MusicCast ..

https://github.com/trlafleur/Tasmota_Seeburg_3WA_3W1_Decoder

~~ _/) ~~~~ _/) ~~~~ _/) ~~~~ _/) ~~

| Vahdettin
3 July |

  • | - |

Are all the sound files in the same folder? If so, I think what happens is that Musiccast considers every file in a folder as belonging to the same "album" and just runs through all the ones that follow.

The way I got around this was to assign each music file to a preset and then recall the preset to play the file. Just make sure the preset is a single music file and not a directory or you'll probably get the same behavior.

HTH.

Sounds like an interesting setup! I would love to have one of those juke boxes. I miss them.

The only way I know how to do what you're asking is with the preset method mentioned above. I suppose another way would be to separate each track into its own folder but that seems like quite a pain.

Let me know if you find some other solution.

I have an idea, start playing a track, then get play status every 1 sec or so, check the time to play, and if it's less than 2 sec to play, send a stop....
select a new track, do the same....

I got it all working , I cheated I put a Bluetooth transmitter in the back of the jukebox sending audio to my receiver and onto MusicCast

It's not cheating if it works :grin:

Thanks for the collection. I use it to synchronize volume between ysp-2700 soundbar and wx-021 speakers in Home Assistant. Took some tinkering as range reported in attributes is float range [0.1], that needs to be translated to int range [0.60].
Also might be actually possible to somehow control group volume (as you can in musiccast app on Android), but I did not find such function :wink:

Hi, glad it is useful for you. If you're trying to adjust the volume as one, I think the two units need to be linked as one using what Yamaha calls a "distribution group". That is the one part of the Musiccast API that I didn't implement due to complexity. Also, I have an Aventage receiver and that uses zones to do the same thing. I'll try to add it when I get time.

The volume is tricky. I used "getFeatures" on the device to retrieve the min/max of displayed volume range to calculate the corresponding dB level min/max (actual volume). Unfortunately, that's not automatic.

Version 4.1.0 was just released which adds a node type to help build distribution groups: "link". They can be a bit complicated to understand but there is an example flow to help out. And I'm already using it at home with 4 devices and it works well.

Hello @Vahdettin
I really enjoy your node collection. Maybe I am a little late to the party but I have a question:
What I am still searching for is the possibility to switch between the predefined "Routines". That would make everything so much easier.
I can see that there is something called a "Scene" but I was not able to figure what it is.

Did you implement "Routines" switching or do you have an idea how to do?

Thank you
/// Jens

Hello,

Glad to hear you find it useful. From what I can see, "routines" are a feature of the app that uses the API to perform automation. Given that, it seems that Node-RED along with the collection can replicate the functionality of routines and it can be done independent of an app or secondary device. I only tried to use a routine once and found it lacking.

Scenes: the collection can be used to set a certain scene that's already been created on a device but I've never found any functionality in the API that can be used to create or edit an existing scene. If it's not in the API, I have nothing to add to the collection functions. But as scenes are essentially just a way to group and apply settings such as volume, input selection, audio program, etc., they are not really needed because the collection can do all of that via the Node-RED UI.

Also, from my experience, editing scenes on an Aventage receiver or other high-end Yamaha devices is not always easy and is one of the reasons I created the collection. I needed finer control and the API was the best way to do that.

--
Vahdettin

Thank you for your comment!
So it seems I have to take the adventure with the "list" function block.

Just to explain my issue: I have a WX-010 speaker. That is the one device that has barely no buttons on it. I am planning to remote control it some way with a hue switch button or something I could build from a soap box and a handful of switches. This way all family members can choose their favorite station without pulling out the phone.
I need to switch between 3 or 4 predefined radio stations (net_radio) that can be hard wired in the code.
So from your point of view the approach is to drill through the radio station trees, right?

Best regards
Jens