Controlling Bose SoundTouch with Node-RED

I live out in the country and have a long driveway from the gravel road to my house. It’s useful to know when someone is coming down the driveway so I put a solar-powered infrared sensor thingy out at the top of the driveway and it connects through some hocus pocus to HA where it can trigger automations when a car breaks the beam.

We also have a Bose Soundtouch speaker in the living room that plays streamed music. I wanted to make it play a sound when a car is coming, interrupting anything that might be playing at the time and then going back to the existing stream after the car coming sound.

Below is a Node Red flow that does that. It starts by saving whatever the selected source is on the soundtouch, then it plays an MP3 file from the HA config/www (aka local) directory, pauses for the length of the sound file, then sets the soundtouch back to the original source.

We only ever use two sources on our soundtouch, AUX and BLUETOOTH, so this flow only deals with those sources. It could easily be expanded to work with other sources. What you need to know to do that is all in this recent topic:

That topic shows a way of doing source selection and preset selection on the soundtouch via HA scripts and shell commands. Below is a Node Red alternative.

I haven’t actually tested what happens when you interrupt a bluetooth stream and then set it back to bluetooth. Interrupting the bluetooth stream might stop it and require you to restart it from your phone or whatever device was streaming to the soundtouch. I have tested it with the AUX input though and when the flow interrupts and then resets the source to AUX, the streaming music from the AUX source starts right back up automatically (4 seconds further along in the stream - i.e. no pause). very cool.

You can import the following flow into Node Red. This is an example. You’d obviously have to fill in the appropriate IP addresses and path and filename to any mp3 media you want to play to match your own data.

[
    {
        "id": "4b1f9d27.dea764",
        "type": "tab",
        "label": "soundtouch stuff",
        "disabled": true,
        "info": ""
    },
    {
        "id": "d557ee3f.543b3",
        "type": "http request",
        "z": "4b1f9d27.dea764",
        "name": "soundtouch current source",
        "method": "GET",
        "ret": "txt",
        "paytoqs": false,
        "url": "http://<soundtouch IP>:8090/now_playing",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 180,
        "y": 100,
        "wires": [
            [
                "84186783.a5e038"
            ]
        ]
    },
    {
        "id": "84186783.a5e038",
        "type": "xml",
        "z": "4b1f9d27.dea764",
        "name": "XML -> JS",
        "property": "payload",
        "attr": "",
        "chr": "",
        "x": 210,
        "y": 160,
        "wires": [
            [
                "47fc75a0.4084fc"
            ]
        ]
    },
    {
        "id": "47fc75a0.4084fc",
        "type": "change",
        "z": "4b1f9d27.dea764",
        "name": "source",
        "rules": [
            {
                "t": "set",
                "p": "source",
                "pt": "flow",
                "to": "payload.nowPlaying.$.source",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 230,
        "y": 220,
        "wires": [
            [
                "6b7f06f5.bf5bf8"
            ]
        ]
    },
    {
        "id": "2a7efbbf.1afba4",
        "type": "http request",
        "z": "4b1f9d27.dea764",
        "name": "post to soundtouch",
        "method": "POST",
        "ret": "txt",
        "paytoqs": false,
        "url": "http://<soundtouch IP>:8090/select",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 630,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "20cb1971.0b0396",
        "type": "function",
        "z": "4b1f9d27.dea764",
        "name": "set source to bluetooth",
        "func": "msg.payload = '<?xml version=\"1.0\" ?><ContentItem source=\"BLUETOOTH\" />';\nmsg.headers = {};\nmsg.headers['Content-Type'] = 'application/xml;charset=utf-8';\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 390,
        "y": 460,
        "wires": [
            [
                "2a7efbbf.1afba4"
            ]
        ]
    },
    {
        "id": "b14ea4a8.3c1ba8",
        "type": "function",
        "z": "4b1f9d27.dea764",
        "name": "set source to AUX",
        "func": "msg.payload = '<?xml version=\"1.0\" ?><ContentItem source=\"AUX\" sourceAccount=\"AUX\" />';\nmsg.headers = {};\nmsg.headers['Content-Type'] = 'application/xml;charset=utf-8';\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 410,
        "y": 400,
        "wires": [
            [
                "2a7efbbf.1afba4"
            ]
        ]
    },
    {
        "id": "6b7f06f5.bf5bf8",
        "type": "api-call-service",
        "z": "4b1f9d27.dea764",
        "name": "car coming sound",
        "server": "753d0826.5edb28",
        "version": 1,
        "debugenabled": false,
        "service_domain": "media_player",
        "service": "play_media",
        "entityId": "media_player.soundtouch_living_room",
        "data": "{\"media_content_type\":\"audio/mp3\",\"media_content_id\":\"http://<home assistant IP>:8123/local/car-coming.mp3\"}",
        "dataType": "json",
        "mergecontext": "",
        "output_location": "",
        "output_location_type": "none",
        "mustacheAltTags": false,
        "x": 330,
        "y": 300,
        "wires": [
            [
                "190e238e.d8fcdc"
            ]
        ]
    },
    {
        "id": "62169e3e.5af13",
        "type": "switch",
        "z": "4b1f9d27.dea764",
        "name": "reset source",
        "property": "source",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "AUX",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "BLUETOOTH",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 170,
        "y": 420,
        "wires": [
            [
                "b14ea4a8.3c1ba8"
            ],
            [
                "20cb1971.0b0396"
            ]
        ]
    },
    {
        "id": "190e238e.d8fcdc",
        "type": "delay",
        "z": "4b1f9d27.dea764",
        "name": "",
        "pauseType": "delay",
        "timeout": "4",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 540,
        "y": 300,
        "wires": [
            [
                "62169e3e.5af13"
            ]
        ]
    },
    {
        "id": "753d0826.5edb28",
        "type": "server",
        "z": "",
        "name": "Home Assistant"
    }
]