node-red-contrib-sonos-plus
Version:
A set of Node-RED nodes to control SONOS player in your local network.
2,200 lines • 57.1 kB
JSON
[
{
"id": "c249bd9e.21742",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 03: Replace SONOS-Queue without playing",
"info": "",
"x": 241,
"y": 789,
"wires": []
},
{
"id": "3ce73efc.9acb82",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 04: Line in Play:5 / TV Beam or Playbar",
"info": "",
"x": 221,
"y": 908,
"wires": []
},
{
"id": "51281a6b.ba3244",
"type": "switch",
"z": "25081f9e.f5f34",
"name": "",
"property": "payload.modelName",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "Sonos Play:5",
"vt": "str"
},
{
"t": "eq",
"v": "Sonos Beam",
"vt": "str"
},
{
"t": "eq",
"v": "Sonos Playbar",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 3,
"x": 434,
"y": 942,
"wires": [
[
"b123fdba.28bbb"
],
[
"66623590.23783c"
],
[
"66623590.23783c"
]
]
},
{
"id": "b123fdba.28bbb",
"type": "change",
"z": "25081f9e.f5f34",
"name": "line in",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "'x-rincon-stream:RINCON_' & \t$replace(msg.payload.MACAddress, ':', '') & \t'01400'\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 568,
"y": 913,
"wires": [
[
"c3c2037.bf1ca"
]
]
},
{
"id": "da2d9474.71d978",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 05: Play Playlist from Music-Library in My Sonos",
"info": "",
"x": 251,
"y": 1015,
"wires": []
},
{
"id": "beaf5dab.83544",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 91,
"y": 1049,
"wires": [
[
"45978a20.48df94"
]
]
},
{
"id": "85b7f00d.8f89c",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "mute on",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 100,
"y": 1154,
"wires": [
[
"afcd2661.3533b8",
"d85e139d.6ee3c"
]
]
},
{
"id": "afcd2661.3533b8",
"type": "delay",
"z": "25081f9e.f5f34",
"name": "",
"pauseType": "delay",
"timeout": "1",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"outputs": 1,
"x": 231.33333333333337,
"y": 1203,
"wires": [
[
"a6a04d77.01a48",
"6b92a219.98c95c"
]
]
},
{
"id": "6b92a219.98c95c",
"type": "delay",
"z": "25081f9e.f5f34",
"name": "",
"pauseType": "delay",
"timeout": "1",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"outputs": 1,
"x": 434,
"y": 1253,
"wires": [
[
"e3fb4a2f.088628"
]
]
},
{
"id": "66623590.23783c",
"type": "change",
"z": "25081f9e.f5f34",
"name": "tv (line in)",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "'x-sonos-htastream:RINCON_' & \t$replace(msg.payload.MACAddress, ':', '') & \t'01400:spdif'\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 578,
"y": 973,
"wires": [
[
"54c37fb8.f6b96",
"c3c2037.bf1ca"
]
]
},
{
"id": "c7c57729.8e9638",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 06: Set a morning station but dont play right now",
"info": "",
"x": 251,
"y": 1119,
"wires": []
},
{
"id": "e0d75c39.aba64",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 01: Play using My-Sonos - read me",
"info": "This is the recommended way for often uses music.\n\nPrerequisite: You have to manually add the items to My Sonos.",
"x": 210,
"y": 457,
"wires": []
},
{
"id": "8c3aa7e.24fa958",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "Music library imported playlist",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "LibPl_10CC",
"payloadType": "str",
"x": 160,
"y": 618,
"wires": [
[
"6df55e35.988ef"
]
]
},
{
"id": "b572596c.3d7ac8",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "YouTube playlist",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "Feel-Good R&B",
"payloadType": "str",
"x": 120,
"y": 520.6666666666667,
"wires": [
[
"6df55e35.988ef"
]
]
},
{
"id": "6df55e35.988ef",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.mysonos",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 413,
"y": 521,
"wires": [
[]
]
},
{
"id": "a72c5aae.097e58",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 08: Group snapshot with save queue",
"info": "",
"x": 175,
"y": 1366,
"wires": []
},
{
"id": "47546566.e54dac",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 90,
"y": 1401,
"wires": [
[
"a6faed33.59f02"
]
]
},
{
"id": "a3913e88.2f518",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.create.snap",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 710,
"y": 1440,
"wires": [
[
"214d9ba2.b171d4"
]
]
},
{
"id": "214d9ba2.b171d4",
"type": "change",
"z": "25081f9e.f5f34",
"name": "store in flow, stop",
"rules": [
{
"t": "set",
"p": "recentsnapshot",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 853,
"y": 1399,
"wires": [
[
"8793912b.c33de"
]
]
},
{
"id": "864433c7.ce87b",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.save.queue",
"state": "queueBackup",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 433,
"y": 1440,
"wires": [
[
"9c8b04f0.ffcfa8"
]
]
},
{
"id": "7f4c7f7b.d858b",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 90,
"y": 1501,
"wires": [
[
"2e987a06.948b86"
]
]
},
{
"id": "2e987a06.948b86",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.clear.queue",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 160,
"y": 1541,
"wires": [
[
"53358155.282d6"
]
]
},
{
"id": "8793912b.c33de",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.stop",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 951,
"y": 1440,
"wires": [
[
"94510914.f1a8f8"
]
]
},
{
"id": "a6faed33.59f02",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "household.remove.sonosplaylist",
"state": "queueBackup",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 190,
"y": 1440,
"wires": [
[
"864433c7.ce87b"
]
]
},
{
"id": "94510914.f1a8f8",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 1110,
"y": 1400,
"wires": []
},
{
"id": "45978a20.48df94",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.clear.queue",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 261.33333333333337,
"y": 1049,
"wires": [
[
"5863ebe9.89e0b4"
]
]
},
{
"id": "5863ebe9.89e0b4",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.mysonos",
"state": "LibPl_10CC",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 474,
"y": 1049,
"wires": [
[
"54c37fb8.f6b96"
]
]
},
{
"id": "a6a04d77.01a48",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.tunein",
"state": "s24896",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 433,
"y": 1203,
"wires": [
[
"1c33a5c6.c4c47a"
]
]
},
{
"id": "1c33a5c6.c4c47a",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.stop",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 617,
"y": 1203,
"wires": [
[]
]
},
{
"id": "54c37fb8.f6b96",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 723,
"y": 992,
"wires": []
},
{
"id": "70f8c562.6cfc6c",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "8d44022c.adb65",
"command": "player.get.properties",
"name": "",
"x": 259.33333333333337,
"y": 942,
"wires": [
[
"51281a6b.ba3244"
]
]
},
{
"id": "67a14287.ce336c",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 91,
"y": 942,
"wires": [
[
"70f8c562.6cfc6c"
]
]
},
{
"id": "c3c2037.bf1ca",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "8d44022c.adb65",
"command": "player.play.avtransport",
"name": "",
"x": 762,
"y": 937,
"wires": [
[]
]
},
{
"id": "d85e139d.6ee3c",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.set.mutestate",
"state": "on",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 294.33333333333337,
"y": 1154,
"wires": [
[]
]
},
{
"id": "e3fb4a2f.088628",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.set.mutestate",
"state": "Off",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 622,
"y": 1253,
"wires": [
[]
]
},
{
"id": "9c8b04f0.ffcfa8",
"type": "change",
"z": "25081f9e.f5f34",
"name": "store volumes, mute sate",
"rules": [
{
"t": "set",
"p": "snapVolumes",
"pt": "msg",
"to": "true",
"tot": "bool"
},
{
"t": "set",
"p": "snapMutestates",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 590,
"y": 1399,
"wires": [
[
"a3913e88.2f518"
]
]
},
{
"id": "2c292e27.39eec2",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.snap",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 680,
"y": 1540,
"wires": [
[
"dd8d92da.82331"
]
]
},
{
"id": "dd8d92da.82331",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 850,
"y": 1506,
"wires": []
},
{
"id": "53358155.282d6",
"type": "sonos-manage-mysonos",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "mysonos.queue.item",
"state": "queueBackup",
"stateType": "str",
"name": "",
"x": 378,
"y": 1541,
"wires": [
[
"ec6a899a.01f038"
]
]
},
{
"id": "ec6a899a.01f038",
"type": "change",
"z": "25081f9e.f5f34",
"name": "restore from flow",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "recentsnapshot",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 550,
"y": 1504,
"wires": [
[
"2c292e27.39eec2"
]
]
},
{
"id": "6162cad1.5fbc54",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "household.get.groups",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 241,
"y": 1683,
"wires": [
[
"a5ac24fd.39eda8"
]
]
},
{
"id": "a5ac24fd.39eda8",
"type": "split",
"z": "25081f9e.f5f34",
"name": "split group",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 439,
"y": 1683,
"wires": [
[
"52490b6b.2bd554"
]
]
},
{
"id": "42da530c.e6e47c",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.create.snap",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 709,
"y": 1723,
"wires": [
[
"f9aeefd2.81d0e"
]
]
},
{
"id": "52490b6b.2bd554",
"type": "change",
"z": "25081f9e.f5f34",
"name": "Set snapshot properties",
"rules": [
{
"t": "set",
"p": "playerName",
"pt": "msg",
"to": "payload[0].playerName",
"tot": "msg"
},
{
"t": "set",
"p": "snapVolumes",
"pt": "msg",
"to": "true",
"tot": "bool"
},
{
"t": "set",
"p": "snapMutestates",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 490,
"y": 1723,
"wires": [
[
"42da530c.e6e47c"
]
]
},
{
"id": "f9aeefd2.81d0e",
"type": "join",
"z": "25081f9e.f5f34",
"name": "join groups snap",
"mode": "auto",
"build": "string",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 734,
"y": 1683,
"wires": [
[
"ded91223.8c5dd"
]
]
},
{
"id": "36c2013b.149e8e",
"type": "link in",
"z": "25081f9e.f5f34",
"name": "create household snapshot: start",
"links": [],
"x": 54,
"y": 1683,
"wires": [
[
"6162cad1.5fbc54"
]
]
},
{
"id": "ded91223.8c5dd",
"type": "change",
"z": "25081f9e.f5f34",
"name": "set flow variable",
"rules": [
{
"t": "set",
"p": "householdSnapshot",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 924,
"y": 1683,
"wires": [
[
"1771f4d3.060ceb",
"33da512c.231aee"
]
]
},
{
"id": "a0a66691.d95cf8",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 114,
"y": 1723,
"wires": [
[
"6162cad1.5fbc54"
]
]
},
{
"id": "1771f4d3.060ceb",
"type": "link out",
"z": "25081f9e.f5f34",
"name": "create household snapshot: start",
"links": [],
"x": 1077,
"y": 1683,
"wires": []
},
{
"id": "560a3349.18adfc",
"type": "link in",
"z": "25081f9e.f5f34",
"name": "restore household snapshot: start",
"links": [],
"x": 54,
"y": 1856,
"wires": [
[
"51a2efc6.772c4"
]
]
},
{
"id": "51a2efc6.772c4",
"type": "change",
"z": "25081f9e.f5f34",
"name": "restore from flow variable",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "householdSnapshot",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 251,
"y": 1856,
"wires": [
[
"2a726a5c.8af7b6"
]
]
},
{
"id": "2a726a5c.8af7b6",
"type": "split",
"z": "25081f9e.f5f34",
"name": "split snap",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 449,
"y": 1856,
"wires": [
[
"33b43891.954d98"
]
]
},
{
"id": "33b43891.954d98",
"type": "change",
"z": "25081f9e.f5f34",
"name": "set playerName",
"rules": [
{
"t": "set",
"p": "playerName",
"pt": "msg",
"to": "payload.membersData[0].playerName",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 492,
"y": 1894,
"wires": [
[
"e86b25e3.728c58"
]
]
},
{
"id": "e86b25e3.728c58",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.snap",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 683,
"y": 1894,
"wires": [
[
"511a5c97.a2da54"
]
]
},
{
"id": "851786be.0cd4a8",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 114,
"y": 1896,
"wires": [
[
"51a2efc6.772c4"
]
]
},
{
"id": "b4321803.d207c8",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "restore group states from flow variable \"householdSnapshot\"",
"info": "# restore group states from flow variable\n\n## Use case\n- to play a notification on all players\n- to listen to tv, podcast, line in and restore after\n- \nWorks together with create household snapshot flow\n\n## Customizing\n - edit `group.play.snap` and select your configuration node.\n - edit `restore from flow variable` node to define a different flow variable (optionally)\n\n## Result\nThe original state is restored in all groups.\n\n## Restrictions\nWhat is not restored\n - the original household topology is not restore\n - the queue state such as shuffle or normal\n - the queue entries",
"x": 259,
"y": 1823,
"wires": [],
"icon": "node-red/subflow.svg"
},
{
"id": "414c2f8b.f00eb",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "create snapshop and save in flow variable \"householdSnapshot\"",
"info": "# Creates a snapshot of all group states and the topology in household.\n\n## Use case\n - to play a notification on all players\n - to listen to tv, podcast, line in and restore after\n\nWorks together with flow to restore household snapshot.\n\n## Customizing\n - edit `household.get.group`, `group.create.snap` and select your configuration node.\n - edit `set flow variable` node to define a different flow variable (optionally)\n\n## Result\nAn array of group state snapshopts are stored in the the flow variable. That can be used to restore the household players state.\n\n## Limitations\nWhat is not stored: \n - the queue state such as shuffle or normal\n - the queue entries\n ",
"x": 269,
"y": 1651,
"wires": [],
"icon": "node-red/subflow.svg"
},
{
"id": "1d9709f0.e93166",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 09 Household snapshot and grouping",
"info": "",
"x": 185,
"y": 1615,
"wires": [],
"icon": "node-red-contrib-sonos-plus/sonos.png"
},
{
"id": "355071e3.75cf1e",
"type": "link out",
"z": "25081f9e.f5f34",
"name": "restore household snapshot: end",
"links": [],
"x": 965,
"y": 1856,
"wires": []
},
{
"id": "33da512c.231aee",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1014,
"y": 1721,
"wires": []
},
{
"id": "56622eb.11089d",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 863,
"y": 1893,
"wires": []
},
{
"id": "2a8e796.4a28886",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑just for testing",
"info": "\n ",
"x": 119,
"y": 1928,
"wires": []
},
{
"id": "e9a92b48.97d058",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑ just for testing",
"info": "\n ",
"x": 119,
"y": 1756,
"wires": []
},
{
"id": "511a5c97.a2da54",
"type": "join",
"z": "25081f9e.f5f34",
"name": "join groups snap",
"mode": "auto",
"build": "string",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 713,
"y": 1856,
"wires": [
[
"56622eb.11089d",
"355071e3.75cf1e"
]
]
},
{
"id": "721200ae.054a5",
"type": "link in",
"z": "25081f9e.f5f34",
"name": "restore household topology: start",
"links": [],
"x": 56,
"y": 2039,
"wires": [
[
"220deafb.f86326"
]
]
},
{
"id": "220deafb.f86326",
"type": "change",
"z": "25081f9e.f5f34",
"name": "restore from flow variable",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "householdSnapshot",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 254,
"y": 2039,
"wires": [
[
"b9f2373e.3c56d8"
]
]
},
{
"id": "a474fde9.320a7",
"type": "split",
"z": "25081f9e.f5f34",
"name": "split snap",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 626,
"y": 2039,
"wires": [
[
"e620d11.285013"
]
]
},
{
"id": "e620d11.285013",
"type": "change",
"z": "25081f9e.f5f34",
"name": "create csv",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "$join(payload.membersData.playerName, ',')\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 652,
"y": 2077,
"wires": [
[
"d19c3ef7.4399c"
]
]
},
{
"id": "d19c3ef7.4399c",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "household.create.group",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 858,
"y": 2077,
"wires": [
[
"65355b70.f421b4"
]
]
},
{
"id": "a350d2f9.b9ccd",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 116,
"y": 2079,
"wires": [
[
"220deafb.f86326"
]
]
},
{
"id": "af18af1.6fcdd5",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "restore topologoy from flow variable \"householdSnapshot\"",
"info": "restore topologoy from flow variable \"householdSnapshot\"\n\n## Use case\n- to play a notification on all players and roll back\n\n## Customizing\n - edit `household.create.group`, and select your configuration node.\n - edit `set flow variable` node to define a different flow variable (optionally)\n\n## Result\nAll household players are grouped as defined in the snapshot\n\n## Limitation\n - The coordinator can not be set in this flow. \n - It may take some seconds until SONOS player have finished their jobs.\n\n## CAUTION\nIn case your household has a lot of players the creation of a group may take too long and therefore the group creation will fail. ",
"x": 251,
"y": 2006,
"wires": [],
"icon": "node-red/subflow.svg"
},
{
"id": "ba401a28.07edd8",
"type": "link out",
"z": "25081f9e.f5f34",
"name": "restore household topology: end",
"links": [],
"x": 1144,
"y": 2039,
"wires": []
},
{
"id": "dd9aeada.78aa08",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1082,
"y": 2077,
"wires": []
},
{
"id": "fb3ad86a.cf7a08",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑just for testing",
"info": "\n ",
"x": 121,
"y": 2111,
"wires": []
},
{
"id": "65355b70.f421b4",
"type": "join",
"z": "25081f9e.f5f34",
"name": "",
"mode": "auto",
"build": "string",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": "false",
"timeout": "",
"count": "",
"reduceRight": false,
"x": 951,
"y": 2039,
"wires": [
[
"ba401a28.07edd8",
"dd9aeada.78aa08"
]
]
},
{
"id": "51b597a0.230198",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "group all players into single group",
"info": "# group all players into single group\n\n## Use case\n- to play a notification on all players\n\n## Customizing\n - edit `household.get.groups`, `household.create.group` and select your configuration node.\n\n## Result\nAll household players are in single group.\n\n## Limitation\n - The coordinator is not set in this flow. \n - It may take some seconds to complete this.",
"x": 170,
"y": 2227,
"wires": [],
"icon": "node-red/subflow.svg"
},
{
"id": "7fa8fa96.d0af54",
"type": "link in",
"z": "25081f9e.f5f34",
"name": "group all players in single group: start",
"links": [],
"x": 55,
"y": 2260,
"wires": [
[
"f06d6fa3.d8349"
]
]
},
{
"id": "5e21d4e1.1b3c1c",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 115,
"y": 2325,
"wires": [
[
"f06d6fa3.d8349"
]
]
},
{
"id": "f06d6fa3.d8349",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "household.get.groups",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 235,
"y": 2260,
"wires": [
[
"1882a0ef.94a6af"
]
]
},
{
"id": "bc712824.bf17c8",
"type": "change",
"z": "25081f9e.f5f34",
"name": "create csv",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "$join(payload.playerName,',')\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 609,
"y": 2260,
"wires": [
[
"80b0b8f.59ed948"
]
]
},
{
"id": "80b0b8f.59ed948",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "household.create.group",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 821,
"y": 2260,
"wires": [
[
"c11ad469.112368"
]
]
},
{
"id": "6d411e2c.93dfd",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑just for testing",
"info": "\n ",
"x": 120,
"y": 2357,
"wires": []
},
{
"id": "c11ad469.112368",
"type": "link out",
"z": "25081f9e.f5f34",
"name": "group all players in single group: end",
"links": [],
"x": 1018,
"y": 2260,
"wires": []
},
{
"id": "1882a0ef.94a6af",
"type": "change",
"z": "25081f9e.f5f34",
"name": "biggest first",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "$sort(payload, function($l, $r) {\t $count($r) > $count($l)\t})\t\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 437,
"y": 2260,
"wires": [
[
"bc712824.bf17c8"
]
]
},
{
"id": "ba13e419.057c88",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Select your config-node or modify it and use your ip address.",
"x": 286,
"y": 2287,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "607cd186.7b0b5",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↓modify",
"info": "Select your config-node or modify it and use your ip address.",
"x": 852,
"y": 2237,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "d7a0e21b.c7d47",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↓modify",
"info": "",
"x": 796,
"y": 2051,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "847b1465.a7c858",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "",
"x": 290,
"y": 1710,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "40dc9f97.d2fdc",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "",
"x": 750,
"y": 1750,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "9fac1ab6.7839e8",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "",
"x": 713,
"y": 1918,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "be6b3b4e.443648",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify?",
"info": "",
"x": 305,
"y": 2066,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "c74a5f3d.b3a48",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify?",
"info": "",
"x": 321,
"y": 1882,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "ca002798.a37758",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↓modify?",
"info": "",
"x": 945,
"y": 1656,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "b9f2373e.3c56d8",
"type": "change",
"z": "25081f9e.f5f34",
"name": "smallest first",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "$sort(payload, function($l, $r) {\t $count($r.membersData) < $count($l.membersData)\t})\t\t",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 464,
"y": 2039,
"wires": [
[
"a474fde9.320a7"
]
]
},
{
"id": "a04b8409.5ae458",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 10 Create one single group with all players",
"info": "",
"x": 195,
"y": 2194,
"wires": [],
"icon": "node-red-contrib-sonos-plus/sonos.png"
},
{
"id": "c5f72fd3.2bb79",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "SONOS Radio station",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "Bayern 3",
"payloadType": "str",
"x": 140,
"y": 489,
"wires": [
[
"6df55e35.988ef"
]
]
},
{
"id": "3926de4a.bafdf2",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 02A: Home Assistant Integration Commands - Read Me",
"info": "PURPOSE: \nSend commands and parameter from Home Assisant to the Universal node.\n\nMETHOD\n1. Create a entity node \n - select type \"Switch\"\n - In Home Assistant Config use as name \"Sonos Plus Universal Node\"\n\n2. import the example 02 from the example folder\n\n3. Create connection from entitynode to the 2 imported nodes. \n4. You can now use automation, scripts, ... \n\n`service: nodered.trigger\ndata:\n entity_id: switch.sonos_plus_universal_node\n payload:\n topic: group.stop`\n \nor in case you need to transfer data: \n\n`entity_id: switch.sonos_plus_universal_node\npayload:\n topic: group.play.tunein\n payload: s24896`\n \npayload also support Home Assistant templates!\n\n",
"x": 271,
"y": 687,
"wires": []
},
{
"id": "eb4bd71e.20eaa8",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "message",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 537,
"y": 736,
"wires": [
[]
]
},
{
"id": "c4108064.32c79",
"type": "function",
"z": "25081f9e.f5f34",
"name": "msg.payload to msg",
"func": "Object.assign(msg, msg.payload);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 347,
"y": 736,
"wires": [
[
"eb4bd71e.20eaa8"
]
]
},
{
"id": "08e96912cd7dafab",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↓modify",
"info": "Select your config-node or change the IP address in this config node.",
"x": 542,
"y": 704,
"wires": [],
"icon": "font-awesome/fa-arrow-down"
},
{
"id": "f1a0d984884c6620",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Select your config-node or modify it and use your ip address.",
"x": 460,
"y": 550,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "aeceb84f7e8ebddb",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "here HA entity node",
"info": "PURPOSE: \nSend commands and parameter from Home Assisant to the Universal node.\n\nMETHOD\n1. Create a entity node \n - select type \"Switch\"\n - In Home Assistant Config use as name \"Sonos Plus Universal Node\"\n\n2. import the example 02 from the example folder\n\n3. Create connection from entitynode to the 2 imported nodes. \n4. You can now use automation, scripts, ... \n\n`service: nodered.trigger\ndata:\n entity_id: switch.sonos_plus_universal_node\n payload:\n topic: group.stop`\n \nor in case you need to transfer data: \n\n`entity_id: switch.sonos_plus_universal_node\npayload:\n topic: group.play.tunein\n payload: s24896`\n\n",
"x": 129,
"y": 736,
"wires": []
},
{
"id": "ed6f33c4faa83c1a",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Use your My Sonos titles.",
"x": 109,
"y": 648,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "a3d58123.59236",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.clear.queue",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 261.33333333333337,
"y": 822,
"wires": [
[
"a85e280f.b66018"
]
]
},
{
"id": "446e86a7.1f0e68",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 662,
"y": 822,
"wires": []
},
{
"id": "5f89d0e1.e0f5a",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 91,
"y": 822,
"wires": [
[
"a3d58123.59236"
]
]
},
{
"id": "a85e280f.b66018",
"type": "sonos-manage-mysonos",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "mysonos.queue.item",
"state": "LibPl_10CC",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 481.6666666666667,
"y": 822,
"wires": [
[
"446e86a7.1f0e68"
]
]
},
{
"id": "4b688b0f622cf0c1",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 02B: Home Assistant Integration - Events - Read Me",
"info": "PURPOSE: \nAct on Sonos events and send data to Home Assisant\n\nMETHOD\n1. Subscribe to an event from package sonos-events\n2. Either use a \"call service node\" and change helper or submit an event with \"fire event\"\n\nExample call servcie node with helper \n`Domain: input_boolean\nService: {{#payload}}turn_on{{/payload}}{{^payload}}turn_off{{/payload}}\nEntity Idinput_boolean.is_beam_microphone\n`\n\n\n",
"x": 943,
"y": 687,
"wires": []
},
{
"id": "dbfba6e4886df549",
"type": "sonosevents-selection",
"z": "25081f9e.f5f34",
"d": true,
"name": "",
"confignode": "1c70290d.90a4e7",
"playerHostname": "192.168.178.53",
"events": [
{
"fullName": "DevicePropertiesService.micEnabled"
}
],
"outputs": 1,
"x": 823,
"y": 719,
"wires": [
[
"8c66a3c05af5c3e7"
]
]
},
{
"id": "8c66a3c05af5c3e7",
"type": "debug",
"z": "25081f9e.f5f34",
"name": "Microphone at Beam enabled/disabled",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1123,
"y": 719,
"wires": []
},
{
"id": "439289f650f3ba5a",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify - node from sonos-events package",
"info": "Select your config-node or change the IP address in this config node.",
"x": 893,
"y": 753,
"wires": [],
"icon": "font-awesome/fa-arrow-down"
},
{
"id": "8a2a92e7ac72228f",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "use HA Node \"call service\" or \"fire event\" instead of debug node",
"info": "",
"x": 1323,
"y": 747,
"wires": [],
"icon": "font-awesome/fa-arrow-down"
},
{
"id": "25dc92f71c85709a",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Select your config-node or modify it and use your ip address.",
"x": 310,
"y": 853,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "01e54af4d93f0265",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Enter a valid payload, means a My Sonos playlist, album,...",
"x": 538,
"y": 853,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "3cf79766dc783777",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "Example 07: Play notification - Read me",
"info": "## Purpose: \nPlay notification on a player an afterwards restore the origional played sound.\n\n## Restrictions:\nThis is not a SONOS build in function. The current SONOS player status is captured, then the notification is played and afterwards, the status is being restored. \n\nIf the current song has been started via an Smartphone app such as Apple or spotify, it is not possible to capture the current status and therefore the restore is not possible.\n\nSONOS does not provide a \"blocking command\". So another flow with different commands, being send while a notification is playing will mess up the process. \n\n\n## Method\nThis flow uses a function node to serialize (queue) the incoming notifications. The status node listen on the group.play.notification and initiates playing the next notification.\n\n",
"x": 985,
"y": 1153,
"wires": []
},
{
"id": "1cb3359af3b9410d",
"type": "function",
"z": "25081f9e.f5f34",
"name": "queue",
"func": "// from https://gist.github.com/dceejay/cea8afa28b7a93ebdc0f \n// if queue doesn't exist, create it\nif (msg.hasOwnProperty(\"restartQueue\")) {\n context.queue = []\n \n} else {\n context.queue = context.queue || []\n context.busy = context.busy || false\n\n // if the msg is a trigger one release next message\n if (msg.hasOwnProperty(\"releaseNext\")) {\n if (context.queue.length > 0) {\n var m = context.queue.shift()\n node.status({ fill: 'green', shape: 'dot', text: context.queue.length })\n return m \n }\n else {\n context.busy = false;\n }\n }\n else {\n if (context.busy) {\n // if busy add to queue\n context.queue.push(msg);\n }\n else {\n // otherwise we are empty so just pass through and set busy flag\n context.busy = true;\n node.status({ fill: 'green', shape: 'dot', text: context.queue.length })\n return msg;\n }\n }\n}\nnode.status({ fill: 'green', shape: 'dot', text: context.queue.length })\n\nreturn null;\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1330,
"y": 1193,
"wires": [
[
"918a3409e44f6d77"
]
]
},
{
"id": "918a3409e44f6d77",
"type": "sonos-universal",
"z": "25081f9e.f5f34",
"confignode": "88e9fa70.4a53e8",
"command": "group.play.notification",
"state": "",
"stateType": "str",
"avoidCheckPlayerAvailability": false,
"name": "",
"x": 1504,
"y": 1193,
"wires": [
[]
]
},
{
"id": "71af6193cc72265e",
"type": "comment",
"z": "25081f9e.f5f34",
"name": "↑modify",
"info": "Select your config node.",
"x": 1570,
"y": 1219,
"wires": [],
"icon": "font-awesome/fa-edit"
},
{
"id": "a4b21d8eb40d6f76",
"type": "inject",
"z": "25081f9e.f5f34",
"name": "trigger",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 1150,
"y": 1253,
"wires": [
[
"305a9cefba4d8577"
]
]
},
{
"id": "305a9cefba4d8577",
"type": "change",
"z": "25081f9e.f5f34",
"name": "reset",
"rules": [
{
"t": "set",
"p": "restartQueue",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1270,
"y": 1253,
"wires": [
[
"1cb3359af3b9410d"
]
]
},
{
"id": "9fca6dfa78099394",
"type": "change",
"z": "25081f9e.f5f34",
"name": "initiate next",
"rules": [
{
"t": "set",
"p": "releaseNext",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1511,
"y": 1150,
"wires": [
[
"1cb3359af3b9410d"
]
]
},
{
"id": "70d2c2afc4fe3a69",