[
  {
    "id": "3005989d9cf1fea9",
    "type": "group",
    "style": {
      "stroke": "#999999",
      "stroke-opacity": "1",
      "fill": "none",
      "fill-opacity": "1",
      "label": true,
      "label-position": "nw",
      "color": "#a4a4a4"
    },
    "nodes": [
      "c81c82ddc7025c67",
      "7e39c0805403c58c",
      "233d473235fd68b9",
      "a2115417961824f4",
      "b9b86a05767a7595",
      "b15188966dfc1898",
      "95738d42303647b6",
      "6ca096f65be6bf40",
      "dfe265ae5aa831a6",
      "ad43ba0280b68479",
      "ab3820d651e5b3ef",
      "d681dac0fb37092d",
      "647eae8670026edf",
      "5419455986bc2f7f",
      "3b1fe0a66313ce27",
      "28e08fbd4d123cf7",
      "4dcca5c2aaf9c501",
      "65fb9508026fd46b",
      "ab564e3ccc7e2150",
      "bdc638f54b09b632",
      "06c625285b1abef1",
      "c098a08a3a809f91",
      "d13d0a9d4651aef4",
      "e89152a538b24737",
      "9fe9dccadb997b39",
      "a1c97dfef8e1e9c1",
      "13915f02dddb8964",
      "f58e9d490e154e12",
      "d1dca35c5b437a36",
      "e4675f9290f6ce1f",
      "1265329240a9bfae",
      "cce9d279381b2bc6",
      "febbb293ed3cbeea",
      "1e5fc04e7dfa78b0",
      "08307069899c7cfb",
      "fb9baac1ed12d0d3",
      "1ec4088a2bee1e9d"
    ],
    "x": 1414,
    "y": 839,
    "w": 1072,
    "h": 942
  },
  {
    "id": "c81c82ddc7025c67",
    "type": "widget-Audio",
    "g": "3005989d9cf1fea9",
    "dropdownRoom": "",
    "dropdownCategory": "",
    "dropdownWidget": "",
    "displayName": "Audio (set device)",
    "x": 2000,
    "y": 1320,
    "wires": [
      [
        "c098a08a3a809f91"
      ],
      [
        "d13d0a9d4651aef4"
      ],
      [
        "e89152a538b24737"
      ],
      [
        "9fe9dccadb997b39"
      ],
      [
        "a1c97dfef8e1e9c1"
      ],
      [
        "13915f02dddb8964"
      ],
      [
        "f58e9d490e154e12"
      ],
      [
        "d1dca35c5b437a36"
      ],
      [
        "e4675f9290f6ce1f"
      ],
      [
        "1265329240a9bfae"
      ],
      [
        "cce9d279381b2bc6"
      ],
      [
        "febbb293ed3cbeea"
      ],
      [
        "1e5fc04e7dfa78b0"
      ]
    ]
  },
  {
    "id": "7e39c0805403c58c",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Volume 10%",
    "props": [
      {
        "p": "inputTarget",
        "v": "Volume setpoint",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "10",
    "payloadType": "num",
    "x": 1530,
    "y": 940,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "233d473235fd68b9",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Volume 50%",
    "props": [
      {
        "p": "inputTarget",
        "v": "Volume setpoint",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "50",
    "payloadType": "num",
    "x": 1530,
    "y": 980,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "a2115417961824f4",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Volume 100%",
    "props": [
      {
        "p": "inputTarget",
        "v": "Volume setpoint",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "100",
    "payloadType": "num",
    "x": 1530,
    "y": 1020,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "b9b86a05767a7595",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Zone ON",
    "props": [
      {
        "p": "inputTarget",
        "v": "Zone On/Off",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "true",
    "payloadType": "bool",
    "x": 1520,
    "y": 1060,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "b15188966dfc1898",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Zone OFF",
    "props": [
      {
        "p": "inputTarget",
        "v": "Zone On/Off",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "false",
    "payloadType": "bool",
    "x": 1520,
    "y": 1100,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "95738d42303647b6",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Mute ON",
    "props": [
      {
        "p": "inputTarget",
        "v": "Mute On/Off",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "true",
    "payloadType": "bool",
    "x": 1520,
    "y": 1140,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "6ca096f65be6bf40",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Mute OFF",
    "props": [
      {
        "p": "inputTarget",
        "v": "Mute On/Off",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "false",
    "payloadType": "bool",
    "x": 1520,
    "y": 1180,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "dfe265ae5aa831a6",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Play",
    "props": [
      {
        "p": "inputTarget",
        "v": "Play/Stop",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "true",
    "payloadType": "bool",
    "x": 1510,
    "y": 1220,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "ad43ba0280b68479",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Stop",
    "props": [
      {
        "p": "inputTarget",
        "v": "Play/Stop",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "false",
    "payloadType": "bool",
    "x": 1510,
    "y": 1260,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "ab3820d651e5b3ef",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Source 1",
    "props": [
      {
        "p": "inputTarget",
        "v": "Source selection",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "1",
    "payloadType": "num",
    "x": 1520,
    "y": 1300,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "d681dac0fb37092d",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Source 2",
    "props": [
      {
        "p": "inputTarget",
        "v": "Source selection",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "2",
    "payloadType": "num",
    "x": 1520,
    "y": 1340,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "647eae8670026edf",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Previous",
    "props": [
      {
        "p": "inputTarget",
        "v": "Previous/Next",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "false",
    "payloadType": "bool",
    "x": 1520,
    "y": 1380,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "5419455986bc2f7f",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Next",
    "props": [
      {
        "p": "inputTarget",
        "v": "Previous/Next",
        "vt": "str"
      },
      {
        "p": "payload"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "payload": "true",
    "payloadType": "bool",
    "x": 1510,
    "y": 1420,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "3b1fe0a66313ce27",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Volume Feedback 75% (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Volume feedback",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "75",
        "vt": "num"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1600,
    "y": 1500,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "28e08fbd4d123cf7",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Zone Feedback ON (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Zone feedback",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "true",
        "vt": "bool"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1590,
    "y": 1540,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "4dcca5c2aaf9c501",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Mute Feedback OFF (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Mute feedback",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "false",
        "vt": "bool"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1590,
    "y": 1580,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "65fb9508026fd46b",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Play Feedback ON (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Play/Stop feedback",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "true",
        "vt": "bool"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1580,
    "y": 1620,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "ab564e3ccc7e2150",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Source Feedback 3 (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Source feedback",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "3",
        "vt": "num"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1590,
    "y": 1660,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "bdc638f54b09b632",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Track Title (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Track Title",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "Bohemian Rhapsody",
        "vt": "str"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1560,
    "y": 1700,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "06c625285b1abef1",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Track Artist (feedback)",
    "props": [
      {
        "p": "inputTarget",
        "v": "Track Artist",
        "vt": "str"
      },
      {
        "p": "payload",
        "v": "Queen",
        "vt": "str"
      }
    ],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1560,
    "y": 1740,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "c098a08a3a809f91",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "1 · Volume Setpoint (0-100)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2300,
    "y": 1100,
    "wires": []
  },
  {
    "id": "d13d0a9d4651aef4",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "2 · Volume Feedback (0-100)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2300,
    "y": 1140,
    "wires": []
  },
  {
    "id": "e89152a538b24737",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "3 · Zone On/Off (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2280,
    "y": 1180,
    "wires": []
  },
  {
    "id": "9fe9dccadb997b39",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "4 · Zone Feedback (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2290,
    "y": 1220,
    "wires": []
  },
  {
    "id": "a1c97dfef8e1e9c1",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "5 · Mute On/Off (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2280,
    "y": 1260,
    "wires": []
  },
  {
    "id": "13915f02dddb8964",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "6 · Mute Feedback (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2290,
    "y": 1300,
    "wires": []
  },
  {
    "id": "f58e9d490e154e12",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "7 · Play/Stop (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2270,
    "y": 1340,
    "wires": []
  },
  {
    "id": "d1dca35c5b437a36",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "8 · Play/Stop Feedback (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2310,
    "y": 1380,
    "wires": []
  },
  {
    "id": "e4675f9290f6ce1f",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "9 · Source Selection (1-3)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2290,
    "y": 1420,
    "wires": []
  },
  {
    "id": "1265329240a9bfae",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "10 · Source Feedback (1-3)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2300,
    "y": 1460,
    "wires": []
  },
  {
    "id": "cce9d279381b2bc6",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "11 · Previous/Next (bool)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2290,
    "y": 1500,
    "wires": []
  },
  {
    "id": "febbb293ed3cbeea",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "12 · Track Title (string)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2280,
    "y": 1540,
    "wires": []
  },
  {
    "id": "1e5fc04e7dfa78b0",
    "type": "debug",
    "g": "3005989d9cf1fea9",
    "name": "13 · Track Artist (string)",
    "active": true,
    "tosidebar": true,
    "console": false,
    "tostatus": false,
    "complete": "payload",
    "targetType": "msg",
    "statusVal": "",
    "statusType": "auto",
    "x": 2290,
    "y": 1580,
    "wires": []
  },
  {
    "id": "08307069899c7cfb",
    "type": "function",
    "g": "3005989d9cf1fea9",
    "name": "Audio Playlist Demo",
    "func": "// Simulate playing a playlist with track changes\nlet playlist = [\n    // Turn on zone and set volume\n    { inputTarget: \"Zone On/Off\", payload: true, delay: 0 },\n    { inputTarget: \"Volume setpoint\", payload: 60, delay: 500 },\n    { inputTarget: \"Source selection\", payload: 1, delay: 1000 },\n    \n    // Play first track\n    { inputTarget: \"Play/Stop\", payload: true, delay: 1500 },\n    { inputTarget: \"Track Title\", payload: \"Bohemian Rhapsody\", delay: 2000 },\n    { inputTarget: \"Track Artist\", payload: \"Queen\", delay: 2200 },\n    \n    \n    // Skip to next track\n    { inputTarget: \"Previous/Next\", payload: true, delay: 5000 },\n    { inputTarget: \"Track Title\", payload: \"Hotel California\", delay: 5500 },\n    { inputTarget: \"Track Artist\", payload: \"Eagles\", delay: 5700 },\n    \n    // Adjust volume and skip again\n    { inputTarget: \"Volume setpoint\", payload: 80, delay: 8000 },\n    { inputTarget: \"Previous/Next\", payload: true, delay: 10000 },\n    { inputTarget: \"Track Title\", payload: \"Stairway to Heaven\", delay: 10500 },\n    { inputTarget: \"Track Artist\", payload: \"Led Zeppelin\", delay: 10700 },\n    \n    // Mute and stop\n    { inputTarget: \"Mute On/Off\", payload: true, delay: 13000 },\n    { inputTarget: \"Play/Stop\", payload: false, delay: 14000 }\n];\n\nnode.status({\n    fill: \"blue\",\n    shape: \"dot\", \n    text: \"🎵 Playing Playlist\"\n});\n\n// Send each message with delay\nplaylist.forEach((msg, index) => {\n    setTimeout(() => {\n        node.send(msg);\n        if (index === playlist.length - 1) {\n            node.status({\n                fill: \"green\",\n                shape: \"dot\", \n                text: \"✅ Playlist Complete\"\n            });\n        }\n    }, msg.delay);\n});\n\nreturn null;",
    "outputs": 1,
    "timeout": 0,
    "noerr": 0,
    "initialize": "",
    "finalize": "",
    "libs": [],
    "x": 1820,
    "y": 1460,
    "wires": [
      [
        "c81c82ddc7025c67"
      ]
    ]
  },
  {
    "id": "fb9baac1ed12d0d3",
    "type": "inject",
    "g": "3005989d9cf1fea9",
    "name": "Run Playlist Demo",
    "props": [],
    "repeat": "",
    "crontab": "",
    "once": false,
    "onceDelay": "0",
    "topic": "",
    "x": 1550,
    "y": 1460,
    "wires": [
      [
        "08307069899c7cfb"
      ]
    ]
  },
  {
    "id": "1ec4088a2bee1e9d",
    "type": "comment",
    "g": "3005989d9cf1fea9",
    "name": "Communication Audio System",
    "info": "## Audio node\nDevice: double-click the device node and choose the device of your installation, then Deploy.\n\n### Input targets\n- `Volume setpoint` (0-100), `Zone On/Off`, `Mute On/Off`, `Play/Stop` (true / false), `Source selection` (source number), `Previous/Next` (false = previous, true = next) — commands\n- `Volume feedback`, `Zone feedback`, `Mute feedback`, `Play/Stop feedback`, `Source feedback`, `Track Title`, `Track Artist` (strings) — feedback\n\n### Outputs (13, in the order above: setpoint then feedback per function)\n1. Volume setpoint · 2. Volume feedback · 3. Zone On/Off · 4. Zone feedback · 5. Mute On/Off · 6. Mute feedback · 7. Play/Stop · 8. Play/Stop feedback · 9. Source selection · 10. Source feedback · 11. Previous/Next · 12. Track Title · 13. Track Artist\n\nPrevious/Next leaves its output every time, even when the value repeats.\n\n### Rules (node-red-cgen-widget-nodes 1.15)\n- `msg.inputTarget` must match a name above exactly (case-sensitive). Use an **Input Target** node to pick it from a list. A message with a missing or unknown target is ignored.\n- A message from the flow is sent to the server and also leaves on the output of the same name.\n- Outputs also fire when the device changes elsewhere: a **command** output when the app, a scenario, an automation or another flow commands it (only when the value changes), a **feedback** output each time the device reports a value.\n- Writing a feedback / status target updates the value HyperVisu shows; nothing is sent to the device. Use it with VIRTUAL devices.",
    "x": 1700,
    "y": 880,
    "wires": []
  }
]