[
 {
  "id": "92799e65cd6e432e",
  "type": "tab",
  "label": "Демо-зал",
  "disabled": false,
  "info": "Учебная программа к интерфейсам «Демо-зал» и «Рецепты». Блоки подписаны комментариями; выделите комментарий — пояснение откроется на боковой панели «Информация».\n\nАдреса устройств — заглушки: что настроить после импорта, написано в комментарии блока 0.",
  "env": []
 },
 {
  "id": "aa0e4b3f0f2e0090",
  "type": "UI-listener",
  "name": "Демо: UI-Panel",
  "path": "/web-client",
  "hb": "30",
  "wholemsg": "true",
  "passcode": ""
 },
 {
  "id": "1760580618b6eca6",
  "type": "udp-config",
  "name": "Демо: матрица",
  "port": "12347",
  "portType": "num",
  "localportType": "random",
  "outport": "",
  "outportType": "num",
  "connectionType": "unicast",
  "ipv": "4",
  "iface": "",
  "group": "",
  "datatype": "utf8",
  "outip": "192.168.1.11",
  "outipType": "str",
  "multicastttl": 1,
  "autoConnect": true,
  "debug": "false",
  "delimiter": "",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "7c8d38ba8b9625de",
  "type": "udp-config",
  "name": "Демо: камера 1",
  "port": "52381",
  "portType": "num",
  "localportType": "random",
  "outport": "",
  "outportType": "num",
  "connectionType": "unicast",
  "ipv": "4",
  "iface": "",
  "group": "",
  "datatype": "hex",
  "outip": "192.168.1.21",
  "outipType": "str",
  "multicastttl": 1,
  "autoConnect": true,
  "debug": "false",
  "delimiter": "",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "909779aa859425ea",
  "type": "udp-config",
  "name": "Демо: камера 2",
  "port": "52381",
  "portType": "num",
  "localportType": "random",
  "outport": "",
  "outportType": "num",
  "connectionType": "unicast",
  "ipv": "4",
  "iface": "",
  "group": "",
  "datatype": "hex",
  "outip": "192.168.1.22",
  "outipType": "str",
  "multicastttl": 1,
  "autoConnect": true,
  "debug": "false",
  "delimiter": "",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "05ce72e53cd1ebd9",
  "type": "udp-config",
  "name": "Демо: камера 3",
  "port": "52381",
  "portType": "num",
  "localportType": "random",
  "outport": "",
  "outportType": "num",
  "connectionType": "unicast",
  "ipv": "4",
  "iface": "",
  "group": "",
  "datatype": "hex",
  "outip": "192.168.1.23",
  "outipType": "str",
  "multicastttl": 1,
  "autoConnect": true,
  "debug": "false",
  "delimiter": "",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "91d689ea00f6a303",
  "type": "telnet-config",
  "name": "Демо: звуковой процессор",
  "host": "192.168.1.12",
  "hostType": "str",
  "port": 23,
  "portType": "num",
  "username": "",
  "usernameType": "str",
  "password": "",
  "passwordType": "str",
  "usernamePrompt": "[Ll]ogin[: ]*$",
  "passwordPrompt": "[Pp]assword[: ]*$",
  "shellPrompt": "",
  "appendLineEnding": false,
  "autoConnect": "true",
  "debug": "false",
  "reconnectInterval": 5000,
  "delimiter": "\\r\\n",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "3e40226e00c0299f",
  "type": "ssh-config",
  "name": "Демо: кодек ВКС",
  "host": "192.168.1.13",
  "hostType": "str",
  "port": 22,
  "portType": "num",
  "usernameType": "str",
  "passwordType": "str",
  "autoConnect": "true",
  "debug": "false",
  "reconnectInterval": 5000,
  "privateKey": "",
  "passphrase": "",
  "appendLineEnding": false,
  "shellPrompt": "Last login|\\bready\\b|[$#>]\\s*$",
  "delimiter": "\\n",
  "delimiterTimeout": 0,
  "keepDelimiter": false,
  "bufferSize": 64
 },
 {
  "id": "1ab031db571a416b",
  "type": "device-connection",
  "name": "Демо: матрица",
  "driver": "avcit-phinx",
  "transportType": "udp",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "",
  "udpConfig": "1760580618b6eca6",
  "telnetConfig": "",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {
   "sendGapMs": {
    "type": "num",
    "value": 40
   },
   "ackTimeoutMs": {
    "type": "num",
    "value": 1500
   }
  }
 },
 {
  "id": "15203811eaad571c",
  "type": "device-connection",
  "name": "Демо: звуковой процессор",
  "driver": "Tesira",
  "transportType": "telnet",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "",
  "udpConfig": "",
  "telnetConfig": "91d689ea00f6a303",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {}
 },
 {
  "id": "811a7bdb7a23c17a",
  "type": "device-connection",
  "name": "Демо: кодек ВКС",
  "driver": "vinteo-st",
  "transportType": "ssh",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "3e40226e00c0299f",
  "udpConfig": "",
  "telnetConfig": "",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {}
 },
 {
  "id": "04f50b9433635ab6",
  "type": "device-connection",
  "name": "Демо: камера 1",
  "driver": "visca-generic",
  "transportType": "udp",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "",
  "udpConfig": "7c8d38ba8b9625de",
  "telnetConfig": "",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {
   "commandFormat": {
    "type": "str",
    "value": "ethernet"
   },
   "deviceId": {
    "type": "num",
    "value": 1
   }
  }
 },
 {
  "id": "a5e28ff614082699",
  "type": "device-connection",
  "name": "Демо: камера 2",
  "driver": "visca-generic",
  "transportType": "udp",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "",
  "udpConfig": "909779aa859425ea",
  "telnetConfig": "",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {
   "commandFormat": {
    "type": "str",
    "value": "ethernet"
   },
   "deviceId": {
    "type": "num",
    "value": 1
   }
  }
 },
 {
  "id": "261e03e172f1d094",
  "type": "device-connection",
  "name": "Демо: камера 3",
  "driver": "visca-generic",
  "transportType": "udp",
  "keepAlive": false,
  "keepAliveInterval": 30,
  "driverDebug": false,
  "tcpConfig": "",
  "sshConfig": "",
  "udpConfig": "05ce72e53cd1ebd9",
  "telnetConfig": "",
  "httpConfig": "",
  "localConfig": "",
  "rs232Config": "",
  "irConfig": "",
  "embeddedConfig": "",
  "wsConfig": "",
  "customParams": {
   "commandFormat": {
    "type": "str",
    "value": "ethernet"
   },
   "deviceId": {
    "type": "num",
    "value": 1
   }
  }
 },
 {
  "id": "cb6cb6685ae04453",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "738934b716fe30e4",
  "name": "0. Что настроить после импорта",
  "info": "Адреса устройств в этом файле — заглушки. После импорта откройте конфигурационные узлы\n(меню → «Конфигурационные узлы») и укажите свои:\n- «Демо: матрица» (UDP): адрес матрицы;\n- «Демо: звуковой процессор» (Telnet): адрес Tesira;\n- «Демо: кодек ВКС» (SSH): адрес кодека VINTEO ST, логин и пароль кодека;\n- «Демо: камера 1/2/3» (UDP): адреса камер.\nПорты в узлах — те, что у этих устройств по умолчанию; если на объекте другие, поменяйте их там же.\nДрайверы avcit-phinx, Tesira, vinteo-st, visca-generic должны быть сохранены на контроллере\nпод этими именами (редактор драйверов).\nUI-Panel: создаётся узел UI-listener «/web-client» (подпись «Демо: UI-Panel»). Если на контроллере\nтакой узел уже есть, переключите на него «События панели» и «Команды панели» и удалите лишний.\nИнтерфейсы «Демо-зал» и «Рецепты» должны быть загружены в UI-Designer с теми же именами элементов.",
  "x": 160,
  "y": 80,
  "wires": [
   []
  ]
 },
 {
  "id": "738934b716fe30e4",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "0. Что настроить после импорта",
  "style": {
   "label": true
  },
  "nodes": [
   "cb6cb6685ae04453"
  ],
  "x": 40,
  "y": 40,
  "w": 270,
  "h": 80
 },
 {
  "id": "265bc7315ce9ef11",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "762bd007bd603e4d",
  "name": "1. Старт: настройки зала и адресная книга",
  "info": "Через 3 с после «Развернуть» настройки зала кладутся в память потока — две карты для блока 4:\nflow.demoMatrix — «кнопка → параметры матрицы»: { \"Src_Cam1_b\": { \"input\": 1, \"output\": 1 }, … };\nflow.demoInputs — «вход → кнопка и название»: { \"1\": { \"button\": \"Src_Cam1_b\", \"title\": \"Камера 1\" }, … }.\nПоменять вход у кнопки или название источника — правка здесь, остальные узлы не трогать.\nЗатем поток запрашивает у кодека адресную книгу — список ВКС заполнен с самого начала.",
  "x": 160,
  "y": 260,
  "wires": [
   []
  ]
 },
 {
  "id": "84edd53db012bb32",
  "type": "inject",
  "z": "92799e65cd6e432e",
  "g": "762bd007bd603e4d",
  "name": "Старт",
  "props": [
   {
    "p": "payload"
   }
  ],
  "repeat": "",
  "crontab": "",
  "once": true,
  "onceDelay": "3",
  "topic": "",
  "payload": "",
  "payloadType": "date",
  "x": 160,
  "y": 320,
  "wires": [
   [
    "ef4e71baea347dfa"
   ]
  ]
 },
 {
  "id": "ef4e71baea347dfa",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "762bd007bd603e4d",
  "name": "Настройки «Демо-зала»",
  "rules": [
   {
    "t": "set",
    "p": "demoMatrix",
    "pt": "flow",
    "to": "{\"Src_Cam1_b\": {\"input\": 1, \"output\": 1}, \"Src_Cam2_b\": {\"input\": 2, \"output\": 1}, \"Src_Cam3_b\": {\"input\": 3, \"output\": 1}, \"Src_Vcs_b\": {\"input\": 4, \"output\": 1}, \"Src_Box1_b\": {\"input\": 5, \"output\": 1}, \"Src_Box2_b\": {\"input\": 6, \"output\": 1}, \"Src_Clear_b\": {\"input\": 0, \"output\": 1}}",
    "tot": "json"
   },
   {
    "t": "set",
    "p": "demoInputs",
    "pt": "flow",
    "to": "{\"1\": {\"button\": \"Src_Cam1_b\", \"title\": \"Камера 1\"}, \"2\": {\"button\": \"Src_Cam2_b\", \"title\": \"Камера 2\"}, \"3\": {\"button\": \"Src_Cam3_b\", \"title\": \"Камера 3\"}, \"4\": {\"button\": \"Src_Vcs_b\", \"title\": \"ВКС\"}, \"5\": {\"button\": \"Src_Box1_b\", \"title\": \"Лючок 1\"}, \"6\": {\"button\": \"Src_Box2_b\", \"title\": \"Лючок 2\"}, \"0\": {\"button\": \"reset state\", \"title\": \"Нет источника\"}}",
    "tot": "json"
   },
   {
    "t": "set",
    "p": "demoVcsMode",
    "pt": "flow",
    "to": "contacts",
    "tot": "str"
   },
   {
    "t": "set",
    "p": "demoCam",
    "pt": "flow",
    "to": "1",
    "tot": "num"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 460,
  "y": 320,
  "wires": [
   [
    "581012146ca07825"
   ]
  ]
 },
 {
  "id": "581012146ca07825",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "762bd007bd603e4d",
  "name": "Кодек: адресная книга",
  "connection": "811a7bdb7a23c17a",
  "command": "getContacts",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 760,
  "y": 320,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "762bd007bd603e4d",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "1. Старт: настройки зала и адресная книга",
  "style": {
   "label": true
  },
  "nodes": [
   "265bc7315ce9ef11",
   "84edd53db012bb32",
   "ef4e71baea347dfa",
   "581012146ca07825"
  ],
  "x": 40,
  "y": 220,
  "w": 870,
  "h": 140
 },
 {
  "id": "fecacbf94482309c",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "2. Связь с панелью",
  "info": "UI - Panel in — события всех панелей (нажатия, ползунки, выбор строки). По link они расходятся в блоки\nэкранов, где узлы ui - switch выбирают свои элементы по имени.\nUI - Panel out — всё, что меняет вид панели (выходы api - helper - 2 и interlock - 2).\nУзел отладки выключен: включите (кнопка справа от узла) — событие панели придёт строкой JSON.",
  "x": 160,
  "y": 500,
  "wires": [
   []
  ]
 },
 {
  "id": "7935eaa2b5e64efe",
  "type": "UI-Panel in",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "События панели",
  "server": "aa0e4b3f0f2e0090",
  "passcode": "",
  "x": 160,
  "y": 560,
  "wires": [
   [
    "842057998bfdfdf5",
    "d0eb6bd2671d24c9"
   ]
  ]
 },
 {
  "id": "842057998bfdfdf5",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "→ блоки экранов",
  "mode": "link",
  "links": [
   "cc821202fe680e88",
   "ab53539aee1881d4",
   "aca98059c4dc49af",
   "97ae85a825130bee",
   "a3429971fd55d601",
   "8affea4bc51e8521",
   "3b94df58804a80ca",
   "59c6716e94d289d9"
  ],
  "x": 460,
  "y": 560,
  "wires": []
 },
 {
  "id": "d0eb6bd2671d24c9",
  "type": "debug",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "Что прислала панель",
  "active": false,
  "tosidebar": true,
  "console": false,
  "tostatus": false,
  "complete": "$string(payload)",
  "targetType": "jsonata",
  "statusVal": "",
  "statusType": "auto",
  "x": 460,
  "y": 620,
  "wires": []
 },
 {
  "id": "d178e58c55a073f4",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "→ панель",
  "links": [
   "abbfef2ba26ca8c3",
   "baf0cab34443e7fb",
   "d5ebb70513f993c8",
   "1bc8394541d33edf",
   "c04822bf8d30381a",
   "b21cae3df91db338",
   "e6281b1be61c5f67",
   "89dff012bc5048f7",
   "8c7491244988f136"
  ],
  "x": 760,
  "y": 560,
  "wires": [
   [
    "7e57707391ac1300"
   ]
  ]
 },
 {
  "id": "7e57707391ac1300",
  "type": "UI-Panel out",
  "z": "92799e65cd6e432e",
  "g": "ad7792cc427977f5",
  "name": "Команды панели",
  "server": "aa0e4b3f0f2e0090",
  "passcode": "",
  "x": 1060,
  "y": 560,
  "wires": []
 },
 {
  "id": "ad7792cc427977f5",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "2. Связь с панелью",
  "style": {
   "label": true
  },
  "nodes": [
   "fecacbf94482309c",
   "7935eaa2b5e64efe",
   "842057998bfdfdf5",
   "d0eb6bd2671d24c9",
   "d178e58c55a073f4",
   "7e57707391ac1300"
  ],
  "x": 40,
  "y": 460,
  "w": 1170,
  "h": 200
 },
 {
  "id": "4c8430c8888f2d8b",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "3. Главная: сценарии и «Выключить всё?»",
  "info": "Сценарий — список шагов {dev, command, parameters} в узле change; выполняет их блок 10 по одному.\nОкно подтверждения открывает и закрывает сам интерфейс (ссылки кнопок на фрейм Pop_AllOff_fr):\nлогика видит только нажатие «Выключить» — Pop_Yes_b.\n«Выключить всё» выключает и микрофон ВКС: шаг кодеку setMute, а кнопку «Микрофон в ВКС» (toggle\nв UI-Designer) возвращает в обычное состояние api - helper - 2 «Микрофон ВКС: кнопка обычная».",
  "x": 160,
  "y": 800,
  "wires": [
   []
  ]
 },
 {
  "id": "cc821202fe680e88",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 860,
  "wires": [
   [
    "d73e94f9877c8c96"
   ]
  ]
 },
 {
  "id": "d73e94f9877c8c96",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "Главная",
  "outputs": 3,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "object": "Home_Meeting_b",
    "event": "push",
    "output": 1,
    "uuid": "f9546021-718b-5354-b19a-57c81f431647"
   },
   {
    "object": "Home_Vcs_b",
    "event": "push",
    "output": 2,
    "uuid": "4e5890e1-1b2d-5fcd-8cfd-99377e5080e9"
   },
   {
    "object": "Pop_Yes_b",
    "event": "push",
    "output": 3,
    "uuid": "21757af3-11a2-5d7c-93f7-cd4a61eed355"
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 860,
  "wires": [
   [
    "46b0d397196926e8"
   ],
   [
    "097260614e3b664e"
   ],
   [
    "ec8f7242aae2e85b",
    "37f20b27600924bb"
   ]
  ]
 },
 {
  "id": "46b0d397196926e8",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "Шаги: начало совещания",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "[{\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMicMaster\", \"channel\": 1, \"state\": false}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"channel\": 1, \"state\": false}}, {\"dev\": \"matrix\", \"command\": \"route\", \"parameters\": {\"input\": 1, \"output\": 1}}]",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 860,
  "wires": [
   [
    "b827237c17e28e38"
   ]
  ]
 },
 {
  "id": "097260614e3b664e",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "Шаги: начало ВКС",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "[{\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMicMaster\", \"channel\": 1, \"state\": false}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"channel\": 2, \"state\": false}}, {\"dev\": \"matrix\", \"command\": \"route\", \"parameters\": {\"input\": 4, \"output\": 1}}]",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 920,
  "wires": [
   [
    "b827237c17e28e38"
   ]
  ]
 },
 {
  "id": "ec8f7242aae2e85b",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "Шаги: выключить всё",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "[{\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMicMaster\", \"channel\": 1, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"channel\": 1, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"channel\": 2, \"state\": true}}, {\"dev\": \"codec\", \"command\": \"hangup\", \"parameters\": {}}, {\"dev\": \"codec\", \"command\": \"setMute\", \"parameters\": {\"mute\": true}}, {\"dev\": \"matrix\", \"command\": \"route\", \"parameters\": {\"input\": 0, \"output\": 1}}]",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 980,
  "wires": [
   [
    "b827237c17e28e38"
   ]
  ]
 },
 {
  "id": "37f20b27600924bb",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "Микрофон ВКС: кнопка обычная",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Vcs_Mic_b",
    "event": "uiState",
    "uuid": "65cd5a83-47e6-59b3-b27e-ef6ff796fb13",
    "value": "default"
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 760,
  "y": 1040,
  "wires": [
   [
    "abbfef2ba26ca8c3"
   ]
  ]
 },
 {
  "id": "b827237c17e28e38",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "→ шаги",
  "mode": "link",
  "links": [
   "458ea83401ea9ca3"
  ],
  "x": 1060,
  "y": 920,
  "wires": []
 },
 {
  "id": "abbfef2ba26ca8c3",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "5bd50f251671d0f6",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1060,
  "y": 1040,
  "wires": []
 },
 {
  "id": "5bd50f251671d0f6",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "3. Главная: сценарии и «Выключить всё?»",
  "style": {
   "label": true
  },
  "nodes": [
   "4c8430c8888f2d8b",
   "cc821202fe680e88",
   "d73e94f9877c8c96",
   "46b0d397196926e8",
   "097260614e3b664e",
   "ec8f7242aae2e85b",
   "37f20b27600924bb",
   "b827237c17e28e38",
   "abbfef2ba26ca8c3"
  ],
  "x": 40,
  "y": 760,
  "w": 1170,
  "h": 320
 },
 {
  "id": "a25f9fcade391e55",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "4. Экран: источник — подсветка по ответу матрицы",
  "info": "Одно правило ui - switch по шаблону Src_*_b ловит все кнопки источников; имя нажатой — msg.payload.object.\nУзел change «Кнопка → параметры матрицы» берёт msg.parameters из карты flow.demoMatrix по этому имени:\nflow.demoMatrix[msg.payload.object] — { input, output } («Убрать источник» — вход 0, выход отключается).\nПодсветку ставит матрица: её ответ проходит switch «Подтверждено?» (ack: true) и switch «Какой выход?»\n(только выход 1 — экран зала; ответы по другим выходам, например от вкладки «Первая программа», отброшены),\nзатем по карте flow.demoInputs[msg.payload.input] один change берёт имя кнопки → interlock - 2 «Источники»\nвыделяет её и гасит остальные (вход 0 — 'reset state': погасить все), другой — название → подписи «На экране».\nОбе карты задаёт блок 1.",
  "x": 160,
  "y": 1220,
  "wires": [
   []
  ]
 },
 {
  "id": "ab53539aee1881d4",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 1280,
  "wires": [
   [
    "dcd53399900ecd77"
   ]
  ]
 },
 {
  "id": "dcd53399900ecd77",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Экран",
  "outputs": 1,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "pattern": "Src_*_b",
    "matchMode": "wildcard",
    "event": "push",
    "output": 1
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 1280,
  "wires": [
   [
    "ad6f3321802dd5b0"
   ]
  ]
 },
 {
  "id": "ad6f3321802dd5b0",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Кнопка → параметры матрицы",
  "rules": [
   {
    "t": "set",
    "p": "parameters",
    "pt": "msg",
    "to": "demoMatrix[msg.payload.object]",
    "tot": "flow",
    "dc": true
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 1280,
  "wires": [
   [
    "fd1ab8b09e863f1d"
   ]
  ]
 },
 {
  "id": "fd1ab8b09e863f1d",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Матрица: подать вход",
  "connection": "1ab031db571a416b",
  "command": "route",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1060,
  "y": 1280,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "dad1d0ce5cc371bb",
  "type": "device-response-listener",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Матрица: ответы",
  "outputs": 2,
  "connection": "1ab031db571a416b",
  "driverName": "avcit-phinx",
  "totalOutputs": 2,
  "includeMetadata": true,
  "payloadFormat": "full",
  "outputsMap": "{\"route\": 1}",
  "x": 160,
  "y": 1400,
  "wires": [
   [],
   [
    "b1fe1a41f20a2523"
   ]
  ]
 },
 {
  "id": "b1fe1a41f20a2523",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Подтверждено?",
  "outputs": 1,
  "property": "payload.ack",
  "propertyType": "msg",
  "rules": [
   {
    "t": "true"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 460,
  "y": 1400,
  "wires": [
   [
    "8f3b6d2edebe94f9"
   ]
  ]
 },
 {
  "id": "8f3b6d2edebe94f9",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Какой выход?",
  "outputs": 1,
  "property": "payload.output",
  "propertyType": "msg",
  "rules": [
   {
    "t": "eq",
    "v": "1",
    "vt": "num"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 760,
  "y": 1400,
  "wires": [
   [
    "981cd0dd4b941332",
    "737070cdd3cb35b0"
   ]
  ]
 },
 {
  "id": "981cd0dd4b941332",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Вход → кнопка",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "demoInputs[msg.payload.input].button",
    "tot": "flow"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 1400,
  "wires": [
   [
    "4c2cd284a7b18e3e"
   ]
  ]
 },
 {
  "id": "737070cdd3cb35b0",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Вход → название",
  "rules": [
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{}",
    "tot": "json"
   },
   {
    "t": "set",
    "p": "topic.Disp_Preview_val_lb",
    "pt": "msg",
    "to": "demoInputs[msg.payload.input].title",
    "tot": "flow"
   },
   {
    "t": "set",
    "p": "topic.Home_Screen_val_lb",
    "pt": "msg",
    "to": "demoInputs[msg.payload.input].title",
    "tot": "flow"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 1460,
  "wires": [
   [
    "7c6bd1455a32cad2"
   ]
  ]
 },
 {
  "id": "4c2cd284a7b18e3e",
  "type": "interlock-2",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "Источники",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "eventType": "uiState",
  "activeStatus": "selected",
  "defaultStatus": "default",
  "buttons": [],
  "array_btn": [
   "Src_Cam1_b",
   "Src_Cam2_b",
   "Src_Cam3_b",
   "Src_Vcs_b",
   "Src_Box1_b",
   "Src_Box2_b"
  ],
  "buttons_uuid": [
   "d7529bca-8a0f-5e2b-8346-148f7439a932",
   "cb8e74f8-3eef-596d-a417-180ea943f278",
   "180fae08-e915-55fd-b905-ab84d63aa1b7",
   "750ae040-ab48-52de-bbc8-68919cfa7bc8",
   "d9593e33-da0b-5bd9-82e2-3f5e56ca9cc3",
   "8f40f25f-4ccb-5c35-a682-6960e65ae327"
  ],
  "inputProp": "payload",
  "inputPropType": "msg",
  "x": 1360,
  "y": 1400,
  "wires": [
   [
    "baf0cab34443e7fb"
   ]
  ]
 },
 {
  "id": "7c6bd1455a32cad2",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "На экране",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Disp_Preview_val_lb",
    "event": "text",
    "uuid": "db2d4de8-d340-5e56-9824-a48b72e8bf3f",
    "value": ""
   },
   {
    "name": "Home_Screen_val_lb",
    "event": "text",
    "uuid": "38206c20-d4e2-5593-b21e-5d9273ef6bef",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 1460,
  "wires": [
   [
    "baf0cab34443e7fb"
   ]
  ]
 },
 {
  "id": "baf0cab34443e7fb",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "bd8de5e547c5711e",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1660,
  "y": 1400,
  "wires": []
 },
 {
  "id": "bd8de5e547c5711e",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "4. Экран: источник — подсветка по ответу матрицы",
  "style": {
   "label": true
  },
  "nodes": [
   "a25f9fcade391e55",
   "ab53539aee1881d4",
   "dcd53399900ecd77",
   "ad6f3321802dd5b0",
   "fd1ab8b09e863f1d",
   "dad1d0ce5cc371bb",
   "b1fe1a41f20a2523",
   "8f3b6d2edebe94f9",
   "981cd0dd4b941332",
   "737070cdd3cb35b0",
   "4c2cd284a7b18e3e",
   "7c6bd1455a32cad2",
   "baf0cab34443e7fb"
  ],
  "x": 40,
  "y": 1180,
  "w": 1770,
  "h": 320
 },
 {
  "id": "d65aa215b52fdbd3",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "5. ВКС: кнопки и список → кодек",
  "info": "Каждое правило ui - switch — свой выход: «Контакты»/«История» (запросить список), выбор строки списка\n(событие item_selected), «Позвонить», «Завершить», «Микрофон в ВКС».\nКоманду кодеку выбирает узел change или функция (msg.command) — узел device - command один.\n«Микрофон в ВКС» — кнопка-toggle (флажок «Отметить как toggle» в UI-Designer): панель сама меняет её\nсостояние и присылает его событием value_changed — «pressed» (нажата: включить микрофон) или «default»\n(обычная: выключить). switch «Микрофон: вкл или выкл?» выбирает по msg.payload.value узел change с setMute.",
  "x": 160,
  "y": 1640,
  "wires": [
   []
  ]
 },
 {
  "id": "aca98059c4dc49af",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 1700,
  "wires": [
   [
    "7df0281139f5ff40"
   ]
  ]
 },
 {
  "id": "7df0281139f5ff40",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "ВКС",
  "outputs": 6,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "object": "Vcs_Contacts_b",
    "event": "push",
    "output": 1,
    "uuid": "15befa3e-7fba-59ed-a5f7-fbfadd6eb945"
   },
   {
    "object": "Vcs_History_b",
    "event": "push",
    "output": 2,
    "uuid": "008f7a50-5b5c-5115-8708-4587fafafd69"
   },
   {
    "object": "Vcs_List_ls",
    "event": "item_selected",
    "output": 3,
    "uuid": "a0831524-36ce-5a35-95e4-39029d57ffb4"
   },
   {
    "object": "Vcs_Call_b",
    "event": "push",
    "output": 4,
    "uuid": "742709aa-b7a3-594b-9ecb-0be3d415744d"
   },
   {
    "object": "Vcs_Hangup_b",
    "event": "push",
    "output": 5,
    "uuid": "4496ae6c-d7d8-529f-9e5b-e2ac85cff8a0"
   },
   {
    "object": "Vcs_Mic_b",
    "event": "value_changed",
    "output": 6,
    "uuid": "65cd5a83-47e6-59b3-b27e-ef6ff796fb13"
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 1700,
  "wires": [
   [
    "cf56164608ea4cbd"
   ],
   [
    "94b84576957737fe"
   ],
   [
    "451d197447caa75d"
   ],
   [
    "15d8cca017792b72"
   ],
   [
    "f6aa93dd9329814d"
   ],
   [
    "0debf3538af9f167"
   ]
  ]
 },
 {
  "id": "cf56164608ea4cbd",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Список: контакты",
  "rules": [
   {
    "t": "set",
    "p": "demoVcsMode",
    "pt": "flow",
    "to": "contacts",
    "tot": "str"
   },
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "getContacts",
    "tot": "str"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 1640,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "94b84576957737fe",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Список: история",
  "rules": [
   {
    "t": "set",
    "p": "demoVcsMode",
    "pt": "flow",
    "to": "history",
    "tot": "str"
   },
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "getHistory",
    "tot": "str"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 1700,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "451d197447caa75d",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Выбор строки → кому звоним",
  "outputs": 1,
  "func": "// Вход:  msg.payload.value — что панель прислала при выборе строки Vcs_List_ls (событие item_selected)\n// Выход: msg.topic для api-helper-2 «Кому звоним»; выбранная строка — в flow.demoVcsTarget\nconst rows = flow.get('demoVcsRows') || [];\nconst v = msg.payload.value;\nconst row = typeof v === 'number' ? rows[v] : rows.find((r) => r.key === (v && v.key !== undefined ? v.key : v));\nif (!row) {\n    node.warn('Строка списка не найдена: ' + JSON.stringify(v));\n    return null;\n}\nflow.set('demoVcsTarget', row);\nmsg.topic = { Vcs_Target_val_lb: row.key };\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 760,
  "y": 1760,
  "wires": [
   [
    "b02b0b16f77d5ae4"
   ]
  ]
 },
 {
  "id": "b02b0b16f77d5ae4",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Кому звоним",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Vcs_Target_val_lb",
    "event": "text",
    "uuid": "e8b344f0-b7a5-549d-9881-e56ee20dd9a8",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1060,
  "y": 1760,
  "wires": [
   [
    "d5ebb70513f993c8"
   ]
  ]
 },
 {
  "id": "15d8cca017792b72",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Позвонить выбранному",
  "outputs": 1,
  "func": "// Вход:  нажатие Vcs_Call_b. Кому звонить — строка, выбранная в списке (flow.demoVcsTarget)\n// Выход: msg.command и msg.parameters для «Кодек: команда» — набрать номер выбранной строки\nconst target = flow.get('demoVcsTarget');\nif (!target) {\n    node.warn('Сначала выберите строку в списке');\n    return null;\n}\nmsg.command = 'dial';\nmsg.parameters = { number: target.number };\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 760,
  "y": 1820,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "f6aa93dd9329814d",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Завершить",
  "rules": [
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "hangup",
    "tot": "str"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 1880,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "0debf3538af9f167",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Микрофон: вкл или выкл?",
  "outputs": 2,
  "property": "payload.value",
  "propertyType": "msg",
  "rules": [
   {
    "t": "eq",
    "v": "pressed",
    "vt": "str"
   },
   {
    "t": "eq",
    "v": "default",
    "vt": "str"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 760,
  "y": 2000,
  "wires": [
   [
    "cfb562bf3bc6ca6b"
   ],
   [
    "11472be8d83b386b"
   ]
  ]
 },
 {
  "id": "cfb562bf3bc6ca6b",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Микрофон: включить",
  "rules": [
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "setMute",
    "tot": "str"
   },
   {
    "t": "set",
    "p": "parameters",
    "pt": "msg",
    "to": "{\"mute\": false}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 2000,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "11472be8d83b386b",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Микрофон: выключить",
  "rules": [
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "setMute",
    "tot": "str"
   },
   {
    "t": "set",
    "p": "parameters",
    "pt": "msg",
    "to": "{\"mute\": true}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 2060,
  "wires": [
   [
    "22ebba228291d91c"
   ]
  ]
 },
 {
  "id": "22ebba228291d91c",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "Кодек: команда",
  "connection": "811a7bdb7a23c17a",
  "command": "getContacts",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1360,
  "y": 1700,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "d5ebb70513f993c8",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "b11351a650eacb83",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1360,
  "y": 1820,
  "wires": []
 },
 {
  "id": "b11351a650eacb83",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "5. ВКС: кнопки и список → кодек",
  "style": {
   "label": true
  },
  "nodes": [
   "d65aa215b52fdbd3",
   "aca98059c4dc49af",
   "7df0281139f5ff40",
   "cf56164608ea4cbd",
   "94b84576957737fe",
   "451d197447caa75d",
   "b02b0b16f77d5ae4",
   "15d8cca017792b72",
   "f6aa93dd9329814d",
   "0debf3538af9f167",
   "cfb562bf3bc6ca6b",
   "11472be8d83b386b",
   "22ebba228291d91c",
   "d5ebb70513f993c8"
  ],
  "x": 40,
  "y": 1600,
  "w": 1470,
  "h": 500
 },
 {
  "id": "25b57cc1cfe6aa1a",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "6. ВКС: ответы кодека → список и состояние звонка",
  "info": "Ответ кодека со списком функция превращает в строки [{key, value}], api - helper - 2 событием\n«Список (JSON)» заменяет содержимое Vcs_List_ls. Строки с id запоминаются — по ним блок 5 звонит.\nСостояние звонка поток спрашивает раз в 5 с (callinfo); rbe пропускает только изменения.\nТексты — в msg.topic, цвет плашки — в msg.colors: у второго api - helper - 2 другой «Источник данных».",
  "x": 160,
  "y": 2240,
  "wires": [
   []
  ]
 },
 {
  "id": "4b2da1263a2608d1",
  "type": "inject",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Раз в 5 с",
  "props": [
   {
    "p": "payload"
   }
  ],
  "repeat": "5",
  "crontab": "",
  "once": true,
  "onceDelay": "6",
  "topic": "",
  "payload": "",
  "payloadType": "date",
  "x": 160,
  "y": 2300,
  "wires": [
   [
    "f992b9fbef6ce79c"
   ]
  ]
 },
 {
  "id": "f992b9fbef6ce79c",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Кодек: состояние звонка",
  "connection": "811a7bdb7a23c17a",
  "command": "getCallInfo",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 460,
  "y": 2300,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "7a964055e9000171",
  "type": "device-response-listener",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Кодек: ответы",
  "outputs": 4,
  "connection": "811a7bdb7a23c17a",
  "driverName": "vinteo-st",
  "totalOutputs": 4,
  "includeMetadata": true,
  "payloadFormat": "full",
  "outputsMap": "{\"contacts\": 1, \"history\": 2, \"callInfo\": 3}",
  "x": 160,
  "y": 2420,
  "wires": [
   [],
   [
    "9637f564c9bffc79"
   ],
   [
    "9637f564c9bffc79"
   ],
   [
    "34b4c973e23486d4"
   ]
  ]
 },
 {
  "id": "9637f564c9bffc79",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Ответ кодека → строки списка",
  "outputs": 1,
  "func": "// Вход:  ответ кодека contacts или history: msg.payload.list = [{ name, number, … }]\n// Выход: msg.topic = { Vcs_List_ls: [{ ключ: значение }] } для api-helper-2 «Список ВКС»;\n//        строки с номером — в flow.demoVcsRows: по ним «Выбор строки» находит, кому звонить\nconst isContacts = msg.payload.type === 'contacts';\nif ((flow.get('demoVcsMode') || 'contacts') !== (isContacts ? 'contacts' : 'history')) return null;  // не тот список\nconst rows = msg.payload.list.map((r) => ({\n    key: r.name || r.number,\n    value: isContacts ? r.number : (r.incoming ? 'входящий' : 'исходящий'),\n    number: r.number\n}));\nconst seen = {};                                              // ключ строки — то, что панель вернёт при выборе: делаем уникальным\nrows.forEach((r) => { seen[r.key] = (seen[r.key] || 0) + 1; if (seen[r.key] > 1) r.key += ' (' + seen[r.key] + ')'; });\nflow.set('demoVcsRows', rows);\nflow.set('demoVcsTarget', null);\n// строка списка на панели — объект из одной пары { \"ключ\": \"значение\" } (проверено на стенде)\nmsg.topic = { Vcs_List_ls: rows.map((r) => ({ [r.key]: r.value })), Vcs_Target_val_lb: 'Выберите контакт' };\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 460,
  "y": 2420,
  "wires": [
   [
    "02efcb6289bd8e9d"
   ]
  ]
 },
 {
  "id": "02efcb6289bd8e9d",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Список ВКС",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Vcs_List_ls",
    "event": "list",
    "uuid": "a0831524-36ce-5a35-95e4-39029d57ffb4",
    "value": "[]"
   },
   {
    "name": "Vcs_Target_val_lb",
    "event": "text",
    "uuid": "e8b344f0-b7a5-549d-9881-e56ee20dd9a8",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 760,
  "y": 2420,
  "wires": [
   [
    "1bc8394541d33edf"
   ]
  ]
 },
 {
  "id": "34b4c973e23486d4",
  "type": "rbe",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Звонок изменился?",
  "func": "rbe",
  "gap": "",
  "start": "",
  "inout": "out",
  "septopics": true,
  "property": "payload.inCall",
  "topi": "topic",
  "x": 460,
  "y": 2540,
  "wires": [
   [
    "73e9459a4c366551"
   ]
  ]
 },
 {
  "id": "73e9459a4c366551",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Идёт звонок?",
  "outputs": 2,
  "property": "payload.inCall",
  "propertyType": "msg",
  "rules": [
   {
    "t": "true"
   },
   {
    "t": "false"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 760,
  "y": 2540,
  "wires": [
   [
    "cab2b2949a2f4c18"
   ],
   [
    "84a51dc9aaca4f7f"
   ]
  ]
 },
 {
  "id": "cab2b2949a2f4c18",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Идёт разговор",
  "rules": [
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Vcs_State_val_lb\": \"Идёт разговор\", \"Home_Call_val_lb\": \"Идёт разговор\"}",
    "tot": "json"
   },
   {
    "t": "set",
    "p": "colors",
    "pt": "msg",
    "to": "{\"Vcs_State_val_lb\": \"#DCFCE7\"}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 2540,
  "wires": [
   [
    "864d5d170b68c41a",
    "9825dacf542995ea"
   ]
  ]
 },
 {
  "id": "84a51dc9aaca4f7f",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Нет звонка",
  "rules": [
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Vcs_State_val_lb\": \"Нет звонка\", \"Home_Call_val_lb\": \"Нет звонка\"}",
    "tot": "json"
   },
   {
    "t": "set",
    "p": "colors",
    "pt": "msg",
    "to": "{\"Vcs_State_val_lb\": \"#FFFFFF\"}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 2600,
  "wires": [
   [
    "864d5d170b68c41a",
    "9825dacf542995ea"
   ]
  ]
 },
 {
  "id": "864d5d170b68c41a",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Звонок: подписи",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Vcs_State_val_lb",
    "event": "text",
    "uuid": "a65fa6b8-a0c9-585b-9bb0-981c9624053c",
    "value": ""
   },
   {
    "name": "Home_Call_val_lb",
    "event": "text",
    "uuid": "49d74f04-3f66-509d-acbc-c943bcbfb100",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 2540,
  "wires": [
   [
    "1bc8394541d33edf"
   ]
  ]
 },
 {
  "id": "9825dacf542995ea",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "Звонок: цвет плашки",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Vcs_State_val_lb",
    "event": "backgroundColor",
    "uuid": "a65fa6b8-a0c9-585b-9bb0-981c9624053c",
    "value": ""
   }
  ],
  "inputProp": "colors",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 2600,
  "wires": [
   [
    "1bc8394541d33edf"
   ]
  ]
 },
 {
  "id": "1bc8394541d33edf",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "6607ab18297b803e",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1660,
  "y": 2480,
  "wires": []
 },
 {
  "id": "6607ab18297b803e",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "6. ВКС: ответы кодека → список и состояние звонка",
  "style": {
   "label": true
  },
  "nodes": [
   "25b57cc1cfe6aa1a",
   "4b2da1263a2608d1",
   "f992b9fbef6ce79c",
   "7a964055e9000171",
   "9637f564c9bffc79",
   "02efcb6289bd8e9d",
   "34b4c973e23486d4",
   "73e9459a4c366551",
   "cab2b2949a2f4c18",
   "84a51dc9aaca4f7f",
   "864d5d170b68c41a",
   "9825dacf542995ea",
   "1bc8394541d33edf"
  ],
  "x": 40,
  "y": 2200,
  "w": 1770,
  "h": 440
 },
 {
  "id": "7c5b64d560542c07",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "7. Микрофоны: 13 мест — одно правило",
  "info": "Правила идут по порядку, проверка останавливается на первом совпадении: Mic_AllOff_b стоит первым,\nиначе его поймал бы шаблон Mic_*_b. Шаблон ловит все 13 мест; функция берёт номер канала из имени.\nВид места по нажатию не меняется — его ставит ответ звукового процессора (блок 9). Оттуда же\nприходят уведомления мест для подписи «Говорят: …»: функция помнит включённые места в flow.demoMicsOn.",
  "x": 160,
  "y": 2780,
  "wires": [
   []
  ]
 },
 {
  "id": "97ae85a825130bee",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 2840,
  "wires": [
   [
    "05832331e915552b"
   ]
  ]
 },
 {
  "id": "05832331e915552b",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Микрофоны",
  "outputs": 2,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "object": "Mic_AllOff_b",
    "event": "push",
    "output": 1,
    "uuid": "010d60fe-a302-588a-81ec-d04e2812238b"
   },
   {
    "pattern": "Mic_*_b",
    "matchMode": "wildcard",
    "event": "push",
    "output": 2
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 2840,
  "wires": [
   [
    "2ce3e2c505609b12"
   ],
   [
    "4f6ad3dd608a10e7"
   ]
  ]
 },
 {
  "id": "2ce3e2c505609b12",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Шаги: выключить все места",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "[{\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 1, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 2, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 3, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 4, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 5, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 6, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 7, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 8, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 9, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 10, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 11, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 12, \"state\": true}}, {\"dev\": \"dsp\", \"command\": \"setMute\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"channel\": 13, \"state\": true}}]",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 2840,
  "wires": [
   [
    "0de0f5b0a6e7c10b"
   ]
  ]
 },
 {
  "id": "0de0f5b0a6e7c10b",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "→ шаги",
  "mode": "link",
  "links": [
   "458ea83401ea9ca3"
  ],
  "x": 1060,
  "y": 2840,
  "wires": []
 },
 {
  "id": "4f6ad3dd608a10e7",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Место → канал звукового процессора",
  "outputs": 1,
  "func": "// Вход:  msg.payload.object — имя места: Mic_01_b … Mic_12_b (канал = номер), Mic_Chair_b (канал 13)\n// Выход: msg.parameters для «Звук: переключить микрофон» (toggleMute блока DemoMics)\nconst name = msg.payload.object;\nconst channel = name === 'Mic_Chair_b' ? 13 : Number(name.slice(4, 6));\nif (!(channel >= 1 && channel <= 13)) {\n    node.warn('Не место за столом: ' + name);\n    return null;\n}\nmsg.parameters = { instanceTag: 'DemoMics', channel };\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 760,
  "y": 2900,
  "wires": [
   [
    "559ee8e079db2f03"
   ]
  ]
 },
 {
  "id": "559ee8e079db2f03",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Звук: переключить микрофон",
  "connection": "15203811eaad571c",
  "command": "toggleMute",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1060,
  "y": 2900,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "27c529d1ba0ae572",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "места: «Говорят»",
  "links": [
   "65bb8d748331e0ca"
  ],
  "x": 160,
  "y": 3020,
  "wires": [
   [
    "88b0dacb7f3cd78e"
   ]
  ]
 },
 {
  "id": "88b0dacb7f3cd78e",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Включённые места → «Говорят»",
  "outputs": 1,
  "func": "// Вход:  уведомление звукового процессора { publishToken: 'Mic_04_b', value } — value true: место выключено (mute)\n// Выход: msg.topic — «Говорят: 4, 9» для двух подписей; включённые места помнит flow.demoMicsOn\nconst on = flow.get('demoMicsOn') || {};\non[msg.payload.publishToken] = msg.payload.value === false;\nflow.set('demoMicsOn', on);\nconst seats = Object.keys(on).filter((name) => on[name]).sort()\n    .map((name) => (name === 'Mic_Chair_b' ? 'председатель' : String(Number(name.slice(4, 6)))));\nconst text = 'Говорят: ' + (seats.length ? seats.join(', ') : '—');\nmsg.topic = { Mic_Count_val_lb: text, Home_Mics_val_lb: text };\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 460,
  "y": 3020,
  "wires": [
   [
    "0c6fdc201b708f13"
   ]
  ]
 },
 {
  "id": "0c6fdc201b708f13",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "Говорят",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Mic_Count_val_lb",
    "event": "text",
    "uuid": "df4a3afb-a90e-5d38-b2f3-a5e2be35f962",
    "value": ""
   },
   {
    "name": "Home_Mics_val_lb",
    "event": "text",
    "uuid": "9c28755f-fa6b-5b56-8f08-42cc2c7a9a68",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 760,
  "y": 3020,
  "wires": [
   [
    "c04822bf8d30381a"
   ]
  ]
 },
 {
  "id": "c04822bf8d30381a",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "a03ce9dab6e1b4a7",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1060,
  "y": 3020,
  "wires": []
 },
 {
  "id": "a03ce9dab6e1b4a7",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "7. Микрофоны: 13 мест — одно правило",
  "style": {
   "label": true
  },
  "nodes": [
   "7c5b64d560542c07",
   "97ae85a825130bee",
   "05832331e915552b",
   "2ce3e2c505609b12",
   "0de0f5b0a6e7c10b",
   "4f6ad3dd608a10e7",
   "559ee8e079db2f03",
   "27c529d1ba0ae572",
   "88b0dacb7f3cd78e",
   "0c6fdc201b708f13",
   "c04822bf8d30381a"
  ],
  "x": 40,
  "y": 2740,
  "w": 1170,
  "h": 320
 },
 {
  "id": "08a3a822719b7850",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "8. Звук: ползунки и кнопки → звуковой процессор",
  "info": "Ползунок присылает значение 0…1 при отпускании (slide_end); range переводит его в дБ (−60…0).\nФункция выбирает команду по имени элемента: ползунок — уровень, +/− — шаг 3 дБ, «Звук» и кнопки\nшапки «Микрофоны», «Звук в зале» — переключить mute. Вид элементов ставит ответ устройства (блок 9).",
  "x": 160,
  "y": 3200,
  "wires": [
   []
  ]
 },
 {
  "id": "a3429971fd55d601",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 3260,
  "wires": [
   [
    "a521577d9061cf7e"
   ]
  ]
 },
 {
  "id": "a521577d9061cf7e",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "Звук",
  "outputs": 4,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "pattern": "Snd_*_vol_sl",
    "matchMode": "wildcard",
    "event": "slide_end",
    "output": 1
   },
   {
    "pattern": "Snd_*_b",
    "matchMode": "wildcard",
    "event": "push",
    "output": 2
   },
   {
    "object": "Hdr_Mics_b",
    "event": "push",
    "output": 3,
    "uuid": "08da95d4-5c58-509a-bdc0-38951766ddd1"
   },
   {
    "object": "Hdr_Sound_b",
    "event": "push",
    "output": 4,
    "uuid": "17f368a2-b437-5f28-9ce3-166c011213e1"
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 3260,
  "wires": [
   [
    "5b335fc9f5aaeba4"
   ],
   [
    "3e430b4adbabdf79"
   ],
   [
    "3e430b4adbabdf79"
   ],
   [
    "3e430b4adbabdf79"
   ]
  ]
 },
 {
  "id": "5b335fc9f5aaeba4",
  "type": "range",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "0…1 → дБ",
  "minin": "0",
  "maxin": "1",
  "minout": "-60",
  "maxout": "0",
  "action": "clamp",
  "round": true,
  "property": "payload.value",
  "x": 760,
  "y": 3200,
  "wires": [
   [
    "3e430b4adbabdf79"
   ]
  ]
 },
 {
  "id": "3e430b4adbabdf79",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "Элемент → команда звука",
  "outputs": 1,
  "func": "// Вход:  msg.payload.object — ползунок (value уже в дБ после range), кнопка +/−/«Звук» или кнопка шапки\n// Выход: msg.command и msg.parameters для «Звук: команда»\nconst FADER = { Snd_Hall: 1, Snd_Vcs: 2 };                 // канал блока DemoLevels: зал, ВКС\nconst name = msg.payload.object;\nif (name === 'Hdr_Mics_b') {\n    msg.command = 'toggleMute';\n    msg.parameters = { instanceTag: 'DemoMicMaster', channel: 1 };\n    return msg;\n}\nconst fader = name === 'Hdr_Sound_b' ? 'Snd_Hall' : name.split('_').slice(0, 2).join('_');\nconst part = name === 'Hdr_Sound_b' ? 'mute' : name.split('_')[2];\nconst p = { instanceTag: 'DemoLevels', channel: FADER[fader] };\nif (!p.channel) return null;\nif (part === 'vol') { msg.command = 'setLevel'; p.level = msg.payload.value; }\nelse if (part === 'up' || part === 'dn') { msg.command = 'StepSetLevel'; p.step = 3; p.stepDirection = part === 'up' ? 'increment' : 'decrement'; }\nelse if (part === 'mute') msg.command = 'toggleMute';\nelse return null;\nmsg.parameters = p;\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 1060,
  "y": 3260,
  "wires": [
   [
    "1248f086566c962b"
   ]
  ]
 },
 {
  "id": "1248f086566c962b",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "e3a84dec6584bf82",
  "name": "Звук: команда",
  "connection": "15203811eaad571c",
  "command": "toggleMute",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1360,
  "y": 3260,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "e3a84dec6584bf82",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "8. Звук: ползунки и кнопки → звуковой процессор",
  "style": {
   "label": true
  },
  "nodes": [
   "08a3a822719b7850",
   "a3429971fd55d601",
   "a521577d9061cf7e",
   "5b335fc9f5aaeba4",
   "3e430b4adbabdf79",
   "1248f086566c962b"
  ],
  "x": 40,
  "y": 3160,
  "w": 1470,
  "h": 140
 },
 {
  "id": "aef3d051e4a6e4b4",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "9. Звуковой процессор: ответы → вид элементов",
  "info": "После каждого подключения поток подписывается на уровни и mute (блок 10) — дальше устройство само\nприсылает каждое изменение. Имя подписки = имя элемента: уведомление уже говорит, что перекрасить.\nКнопки (Mic_*, «Звук», шапка): mute true — обычное состояние, false — нажата. template ставит имя\nиз уведомления ключом словаря {имя: {uiState: …}} — api - helper - 2 без списка элементов.\nУровень: range (дБ → %) → template (значение ползунка и тексты) → api - helper - 2 со списком.",
  "x": 160,
  "y": 3440,
  "wires": [
   []
  ]
 },
 {
  "id": "393536d67ccc0012",
  "type": "device-response-listener",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Звук: уведомления",
  "outputs": 2,
  "connection": "15203811eaad571c",
  "driverName": "Tesira",
  "totalOutputs": 2,
  "includeMetadata": true,
  "payloadFormat": "full",
  "outputsMap": "{\"subscribeNotification\": 1}",
  "x": 160,
  "y": 3500,
  "wires": [
   [],
   [
    "a9d5fbaa13737f30"
   ]
  ]
 },
 {
  "id": "a9d5fbaa13737f30",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Чьё уведомление",
  "outputs": 4,
  "property": "payload.publishToken",
  "propertyType": "msg",
  "rules": [
   {
    "t": "regex",
    "v": "_b$",
    "vt": "str",
    "case": false
   },
   {
    "t": "eq",
    "v": "Snd_Hall_vol_sl",
    "vt": "str"
   },
   {
    "t": "eq",
    "v": "Snd_Vcs_vol_sl",
    "vt": "str"
   },
   {
    "t": "regex",
    "v": "^Mic_",
    "vt": "str",
    "case": false
   }
  ],
  "checkall": "true",
  "repair": false,
  "x": 460,
  "y": 3500,
  "wires": [
   [
    "dbf2d8e2e0700844"
   ],
   [
    "4f91ed8821347e3c"
   ],
   [
    "9c4d9ee89effeca8"
   ],
   [
    "65bb8d748331e0ca"
   ]
  ]
 },
 {
  "id": "65bb8d748331e0ca",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "→ места: «Говорят»",
  "mode": "link",
  "links": [
   "27c529d1ba0ae572"
  ],
  "x": 760,
  "y": 3800,
  "wires": []
 },
 {
  "id": "dbf2d8e2e0700844",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Выключено?",
  "outputs": 2,
  "property": "payload.value",
  "propertyType": "msg",
  "rules": [
   {
    "t": "true"
   },
   {
    "t": "false"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 760,
  "y": 3440,
  "wires": [
   [
    "e46daebc17072a77"
   ],
   [
    "1b210f150e5a68a2"
   ]
  ]
 },
 {
  "id": "e46daebc17072a77",
  "type": "template",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Кнопка: обычная",
  "field": "topic",
  "fieldType": "msg",
  "format": "json",
  "syntax": "mustache",
  "template": "{ \"{{payload.publishToken}}\": { \"uiState\": \"default\" } }",
  "output": "json",
  "x": 1060,
  "y": 3440,
  "wires": [
   [
    "a3fb7d296cabad0c"
   ]
  ]
 },
 {
  "id": "1b210f150e5a68a2",
  "type": "template",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Кнопка: нажата",
  "field": "topic",
  "fieldType": "msg",
  "format": "json",
  "syntax": "mustache",
  "template": "{ \"{{payload.publishToken}}\": { \"uiState\": \"pressed\" } }",
  "output": "json",
  "x": 1060,
  "y": 3500,
  "wires": [
   [
    "a3fb7d296cabad0c"
   ]
  ]
 },
 {
  "id": "a3fb7d296cabad0c",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Кнопки по имени",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 3440,
  "wires": [
   [
    "b21cae3df91db338"
   ]
  ]
 },
 {
  "id": "b21cae3df91db338",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1660,
  "y": 3560,
  "wires": []
 },
 {
  "id": "4f91ed8821347e3c",
  "type": "range",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Зал: дБ → %",
  "minin": "-60",
  "maxin": "0",
  "minout": "0",
  "maxout": "100",
  "action": "clamp",
  "round": true,
  "property": "payload.value",
  "x": 760,
  "y": 3560,
  "wires": [
   [
    "50f00d603c8e6f1a"
   ]
  ]
 },
 {
  "id": "50f00d603c8e6f1a",
  "type": "template",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Зал: ползунок и тексты",
  "field": "topic",
  "fieldType": "msg",
  "format": "json",
  "syntax": "mustache",
  "template": "{\n    \"Snd_Hall_vol_sl\": {{payload.value}},\n    \"Snd_Hall_val_lb\": \"{{payload.value}} %\",\n    \"Home_Sound_val_lb\": \"Зал: {{payload.value}} %\"\n}",
  "output": "json",
  "x": 1060,
  "y": 3560,
  "wires": [
   [
    "8a715d051c19d1b8"
   ]
  ]
 },
 {
  "id": "8a715d051c19d1b8",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "Зал: ползунок и подписи",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Snd_Hall_vol_sl",
    "event": "value",
    "uuid": "04a0c70e-8cb1-556c-b64b-6dd327ba783c",
    "value": "0",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Snd_Hall_val_lb",
    "event": "text",
    "uuid": "c4aed030-eed7-5a30-82d3-fd119519c16e",
    "value": ""
   },
   {
    "name": "Home_Sound_val_lb",
    "event": "text",
    "uuid": "5189c378-aace-5f2c-8d9b-f0d5cabd1db5",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 3560,
  "wires": [
   [
    "b21cae3df91db338"
   ]
  ]
 },
 {
  "id": "9c4d9ee89effeca8",
  "type": "range",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "ВКС: дБ → %",
  "minin": "-60",
  "maxin": "0",
  "minout": "0",
  "maxout": "100",
  "action": "clamp",
  "round": true,
  "property": "payload.value",
  "x": 760,
  "y": 3620,
  "wires": [
   [
    "f487e741e732ed40"
   ]
  ]
 },
 {
  "id": "f487e741e732ed40",
  "type": "template",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "ВКС: ползунок и тексты",
  "field": "topic",
  "fieldType": "msg",
  "format": "json",
  "syntax": "mustache",
  "template": "{\n    \"Snd_Vcs_vol_sl\": {{payload.value}},\n    \"Snd_Vcs_val_lb\": \"{{payload.value}} %\"\n}",
  "output": "json",
  "x": 1060,
  "y": 3620,
  "wires": [
   [
    "602446ec28722365"
   ]
  ]
 },
 {
  "id": "602446ec28722365",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "53364b0e703f7077",
  "name": "ВКС: ползунок и подписи",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Snd_Vcs_vol_sl",
    "event": "value",
    "uuid": "8826d220-9cc7-5de4-9a3d-bdc9dda2729f",
    "value": "0",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Snd_Vcs_val_lb",
    "event": "text",
    "uuid": "1c0e8564-6ace-5e6d-8277-f81e86ad447d",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1360,
  "y": 3620,
  "wires": [
   [
    "b21cae3df91db338"
   ]
  ]
 },
 {
  "id": "53364b0e703f7077",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "9. Звуковой процессор: ответы → вид элементов",
  "style": {
   "label": true
  },
  "nodes": [
   "aef3d051e4a6e4b4",
   "393536d67ccc0012",
   "a9d5fbaa13737f30",
   "65bb8d748331e0ca",
   "dbf2d8e2e0700844",
   "e46daebc17072a77",
   "1b210f150e5a68a2",
   "a3fb7d296cabad0c",
   "b21cae3df91db338",
   "4f91ed8821347e3c",
   "50f00d603c8e6f1a",
   "8a715d051c19d1b8",
   "9c4d9ee89effeca8",
   "f487e741e732ed40",
   "602446ec28722365"
  ],
  "x": 40,
  "y": 3400,
  "w": 1770,
  "h": 440
 },
 {
  "id": "cbe3282271a71b60",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "10. Камеры: выбор и управление",
  "info": "Выбор камеры — три правила по элементу: change ставит flow.demoCam (номер) и подпись «Управляемая камера».\nСтрелки и приближение работают, пока кнопка нажата: правило с событием push начинает движение, такое\nже правило с событием release останавливает. Шаблон — regex, чтобы не поймать Cam_Home_b и Cam_Wide_b.\nКоманду отправляет камера, выбранная сейчас: switch по flow.demoCam.",
  "x": 160,
  "y": 3980,
  "wires": [
   []
  ]
 },
 {
  "id": "8affea4bc51e8521",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 4040,
  "wires": [
   [
    "5482a5e9fa685268"
   ]
  ]
 },
 {
  "id": "5482a5e9fa685268",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камеры",
  "outputs": 7,
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "rules": [
   {
    "object": "Cam_1_b",
    "event": "push",
    "output": 1,
    "uuid": "ca0951c9-2046-5895-851c-34be64b69d7a"
   },
   {
    "object": "Cam_2_b",
    "event": "push",
    "output": 2,
    "uuid": "ea81903d-07df-5af6-b19c-1051e25e1e11"
   },
   {
    "object": "Cam_3_b",
    "event": "push",
    "output": 3,
    "uuid": "f8750fb9-60ff-5bbe-b903-464c43eba423"
   },
   {
    "pattern": "^Cam_(Up|Down|Left|Right|ZoomIn|ZoomOut)_b$",
    "matchMode": "regex",
    "event": "push",
    "output": 4
   },
   {
    "pattern": "^Cam_(Up|Down|Left|Right|ZoomIn|ZoomOut)_b$",
    "matchMode": "regex",
    "event": "release",
    "output": 5
   },
   {
    "object": "Cam_Home_b",
    "event": "push",
    "output": 6,
    "uuid": "3f85716c-9df1-5311-875c-178ed5fccc7d"
   },
   {
    "object": "Cam_Wide_b",
    "event": "push",
    "output": 7,
    "uuid": "b1057733-bc0e-568c-b1dd-7b73ca9b51b2"
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 4100,
  "wires": [
   [
    "b0cade3b1f181437"
   ],
   [
    "abc0b4a715343381"
   ],
   [
    "5685679ee37ceea9"
   ],
   [
    "fc04aeecf3eddd1a"
   ],
   [
    "fc04aeecf3eddd1a"
   ],
   [
    "fc04aeecf3eddd1a"
   ],
   [
    "fc04aeecf3eddd1a"
   ]
  ]
 },
 {
  "id": "b0cade3b1f181437",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 1",
  "rules": [
   {
    "t": "set",
    "p": "demoCam",
    "pt": "flow",
    "to": "1",
    "tot": "num"
   },
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Cam_Sel_val_lb\": \"Камера 1\"}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 3980,
  "wires": [
   [
    "9d1e88c3059f85a4"
   ]
  ]
 },
 {
  "id": "abc0b4a715343381",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 2",
  "rules": [
   {
    "t": "set",
    "p": "demoCam",
    "pt": "flow",
    "to": "2",
    "tot": "num"
   },
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Cam_Sel_val_lb\": \"Камера 2\"}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 4040,
  "wires": [
   [
    "9d1e88c3059f85a4"
   ]
  ]
 },
 {
  "id": "5685679ee37ceea9",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 3",
  "rules": [
   {
    "t": "set",
    "p": "demoCam",
    "pt": "flow",
    "to": "3",
    "tot": "num"
   },
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Cam_Sel_val_lb\": \"Камера 3\"}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 4100,
  "wires": [
   [
    "9d1e88c3059f85a4"
   ]
  ]
 },
 {
  "id": "9d1e88c3059f85a4",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Управляемая камера",
  "ui": "Демо-зал",
  "interfaceUuid": "1d3ed87f-28e3-5a5a-a125-325a1ffa73f4",
  "action_type": "uiState",
  "object": [
   {
    "name": "Cam_Sel_val_lb",
    "event": "text",
    "uuid": "a88117b8-3556-5f64-9a05-99f34804479b",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1060,
  "y": 4040,
  "wires": [
   [
    "e6281b1be61c5f67"
   ]
  ]
 },
 {
  "id": "e6281b1be61c5f67",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1360,
  "y": 4040,
  "wires": []
 },
 {
  "id": "fc04aeecf3eddd1a",
  "type": "function",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Кнопка → команда камеры",
  "outputs": 1,
  "func": "// Вход:  msg.payload.object — кнопка камеры, msg.payload.event: push — нажата, release — отпущена\n// Выход: msg.command и msg.parameters для выбранной камеры (VISCA): движение, стоп, пресет 1 «Домой», пресет 2 «Общий вид»\nconst PAN = { Cam_Up_b: 'Up', Cam_Down_b: 'Down', Cam_Left_b: 'Left', Cam_Right_b: 'Right' };\nconst ZOOM = { Cam_ZoomIn_b: 'Tele', Cam_ZoomOut_b: 'Wide' };\nconst name = msg.payload.object;\nconst start = msg.payload.event === 'push';\nif (PAN[name]) {\n    msg.command = 'setPanTilt';\n    msg.parameters = { direction: start ? PAN[name] : 'Stop', panSpeed: 8, tiltSpeed: 8 };\n} else if (ZOOM[name]) {\n    msg.command = 'setZoom';\n    msg.parameters = { direction: start ? ZOOM[name] : 'Stop', speed: 4 };\n} else if (name === 'Cam_Home_b' || name === 'Cam_Wide_b') {\n    msg.command = 'recallPreset';\n    msg.parameters = { preset: name === 'Cam_Home_b' ? 1 : 2 };\n} else {\n    return null;\n}\nreturn msg;\n",
  "timeout": 0,
  "noerr": 0,
  "initialize": "",
  "finalize": "",
  "libs": [],
  "x": 760,
  "y": 4220,
  "wires": [
   [
    "a12730357dec9833"
   ]
  ]
 },
 {
  "id": "a12730357dec9833",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Какая камера",
  "outputs": 3,
  "property": "demoCam",
  "propertyType": "flow",
  "rules": [
   {
    "t": "eq",
    "v": "1",
    "vt": "num"
   },
   {
    "t": "eq",
    "v": "2",
    "vt": "num"
   },
   {
    "t": "eq",
    "v": "3",
    "vt": "num"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 1060,
  "y": 4220,
  "wires": [
   [
    "67a64c37cffe5fdb"
   ],
   [
    "e6a8a23cedb69cdc"
   ],
   [
    "5485f6c2fa9ab44b"
   ]
  ]
 },
 {
  "id": "67a64c37cffe5fdb",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 1",
  "connection": "04f50b9433635ab6",
  "command": "setPanTilt",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1360,
  "y": 4160,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "e6a8a23cedb69cdc",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 2",
  "connection": "a5e28ff614082699",
  "command": "setPanTilt",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1360,
  "y": 4220,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "5485f6c2fa9ab44b",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "9219aefcbafd2de4",
  "name": "Камера 3",
  "connection": "261e03e172f1d094",
  "command": "setPanTilt",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1360,
  "y": 4280,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "9219aefcbafd2de4",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "10. Камеры: выбор и управление",
  "style": {
   "label": true
  },
  "nodes": [
   "cbe3282271a71b60",
   "8affea4bc51e8521",
   "5482a5e9fa685268",
   "b0cade3b1f181437",
   "abc0b4a715343381",
   "5685679ee37ceea9",
   "9d1e88c3059f85a4",
   "e6281b1be61c5f67",
   "fc04aeecf3eddd1a",
   "a12730357dec9833",
   "67a64c37cffe5fdb",
   "e6a8a23cedb69cdc",
   "5485f6c2fa9ab44b"
  ],
  "x": 40,
  "y": 3940,
  "w": 1470,
  "h": 380
 },
 {
  "id": "35a6f65aa5e77946",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "11. Шаги сценариев и подписки",
  "info": "Сюда по link «→ шаги» приходят списки шагов [{dev, command, parameters}]: сценарии и\nподписки звукового процессора. split разбивает список, delay пропускает не чаще шага в 0,4 с,\nchange переносит шаг в msg.command / msg.parameters, switch выбирает устройство.\nПервый выход device - command — состояние подключения: после каждого подключения звукового\nпроцессора поток заново подписывается на уровни и mute (имя подписки = имя элемента интерфейса).",
  "x": 160,
  "y": 4460,
  "wires": [
   []
  ]
 },
 {
  "id": "458ea83401ea9ca3",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "шаги",
  "links": [
   "b827237c17e28e38",
   "0de0f5b0a6e7c10b",
   "8620ee94ade4e8cf"
  ],
  "x": 160,
  "y": 4520,
  "wires": [
   [
    "40d8924259801471"
   ]
  ]
 },
 {
  "id": "40d8924259801471",
  "type": "split",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "По одному шагу",
  "splt": "\\n",
  "spltType": "str",
  "arraySplt": 1,
  "arraySpltType": "len",
  "stream": false,
  "addname": "",
  "x": 460,
  "y": 4520,
  "wires": [
   [
    "fcf27f0f40abc050"
   ]
  ]
 },
 {
  "id": "fcf27f0f40abc050",
  "type": "delay",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Шаг в 0,4 с",
  "pauseType": "rate",
  "timeout": "5",
  "timeoutUnits": "seconds",
  "rate": "1",
  "nbRateUnits": "0.4",
  "rateUnits": "second",
  "randomFirst": "1",
  "randomLast": "5",
  "randomUnits": "seconds",
  "drop": false,
  "allowrate": false,
  "outputs": 1,
  "x": 760,
  "y": 4520,
  "wires": [
   [
    "6e8dc58870e6d732"
   ]
  ]
 },
 {
  "id": "6e8dc58870e6d732",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Шаг → команда",
  "rules": [
   {
    "t": "set",
    "p": "command",
    "pt": "msg",
    "to": "payload.command",
    "tot": "msg"
   },
   {
    "t": "set",
    "p": "parameters",
    "pt": "msg",
    "to": "payload.parameters",
    "tot": "msg"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 1060,
  "y": 4520,
  "wires": [
   [
    "734082d6b01bdc40"
   ]
  ]
 },
 {
  "id": "734082d6b01bdc40",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Какому устройству",
  "outputs": 3,
  "property": "payload.dev",
  "propertyType": "msg",
  "rules": [
   {
    "t": "eq",
    "v": "matrix",
    "vt": "str"
   },
   {
    "t": "eq",
    "v": "dsp",
    "vt": "str"
   },
   {
    "t": "eq",
    "v": "codec",
    "vt": "str"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 1360,
  "y": 4520,
  "wires": [
   [
    "a6ee4decdb4e7edb"
   ],
   [
    "761960ca27e1b7ad"
   ],
   [
    "6876ba45e1064c47"
   ]
  ]
 },
 {
  "id": "a6ee4decdb4e7edb",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Матрица (шаги)",
  "connection": "1ab031db571a416b",
  "command": "route",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1660,
  "y": 4520,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "761960ca27e1b7ad",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Звук (шаги)",
  "connection": "15203811eaad571c",
  "command": "setMute",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1660,
  "y": 4580,
  "wires": [
   [
    "bda12b7bc0e6b2ec"
   ],
   []
  ]
 },
 {
  "id": "6876ba45e1064c47",
  "type": "device-command",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Кодек (шаги)",
  "connection": "811a7bdb7a23c17a",
  "command": "getCallInfo",
  "parameters": {},
  "commandMetadata": {},
  "commandParams": [],
  "statusFeedback": true,
  "x": 1660,
  "y": 4640,
  "wires": [
   [],
   []
  ]
 },
 {
  "id": "bda12b7bc0e6b2ec",
  "type": "switch",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Подключился?",
  "outputs": 1,
  "property": "payload.status",
  "propertyType": "msg",
  "rules": [
   {
    "t": "eq",
    "v": "connected",
    "vt": "str"
   }
  ],
  "checkall": "false",
  "repair": false,
  "x": 1960,
  "y": 4580,
  "wires": [
   [
    "d176bd6f920a5ee1"
   ]
  ]
 },
 {
  "id": "d176bd6f920a5ee1",
  "type": "delay",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Пауза 2 с",
  "pauseType": "delay",
  "timeout": "2",
  "timeoutUnits": "seconds",
  "rate": "1",
  "nbRateUnits": "1",
  "rateUnits": "second",
  "randomFirst": "1",
  "randomLast": "5",
  "randomUnits": "seconds",
  "drop": false,
  "allowrate": false,
  "outputs": 1,
  "x": 2260,
  "y": 4580,
  "wires": [
   [
    "17b04322765fbd96"
   ]
  ]
 },
 {
  "id": "17b04322765fbd96",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "Шаги: подписки звука",
  "rules": [
   {
    "t": "set",
    "p": "payload",
    "pt": "msg",
    "to": "[{\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"attribute\": \"level\", \"channel\": 1, \"subscriptionName\": \"Snd_Hall_vol_sl\", \"minInterval\": 200}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"attribute\": \"level\", \"channel\": 2, \"subscriptionName\": \"Snd_Vcs_vol_sl\", \"minInterval\": 200}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"attribute\": \"mute\", \"channel\": 1, \"subscriptionName\": \"Snd_Hall_mute_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"attribute\": \"mute\", \"channel\": 1, \"subscriptionName\": \"Hdr_Sound_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoLevels\", \"attribute\": \"mute\", \"channel\": 2, \"subscriptionName\": \"Snd_Vcs_mute_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMicMaster\", \"attribute\": \"mute\", \"channel\": 1, \"subscriptionName\": \"Hdr_Mics_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 1, \"subscriptionName\": \"Mic_01_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 2, \"subscriptionName\": \"Mic_02_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 3, \"subscriptionName\": \"Mic_03_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 4, \"subscriptionName\": \"Mic_04_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 5, \"subscriptionName\": \"Mic_05_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 6, \"subscriptionName\": \"Mic_06_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 7, \"subscriptionName\": \"Mic_07_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 8, \"subscriptionName\": \"Mic_08_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 9, \"subscriptionName\": \"Mic_09_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 10, \"subscriptionName\": \"Mic_10_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 11, \"subscriptionName\": \"Mic_11_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 12, \"subscriptionName\": \"Mic_12_b\", \"minInterval\": 0}}, {\"dev\": \"dsp\", \"command\": \"subscribe\", \"parameters\": {\"instanceTag\": \"DemoMics\", \"attribute\": \"mute\", \"channel\": 13, \"subscriptionName\": \"Mic_Chair_b\", \"minInterval\": 0}}]",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 2560,
  "y": 4580,
  "wires": [
   [
    "8620ee94ade4e8cf"
   ]
  ]
 },
 {
  "id": "8620ee94ade4e8cf",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "6d96eaad8e1e770b",
  "name": "→ шаги",
  "mode": "link",
  "links": [
   "458ea83401ea9ca3"
  ],
  "x": 2860,
  "y": 4580,
  "wires": []
 },
 {
  "id": "6d96eaad8e1e770b",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "11. Шаги сценариев и подписки",
  "style": {
   "label": true
  },
  "nodes": [
   "35a6f65aa5e77946",
   "458ea83401ea9ca3",
   "40d8924259801471",
   "fcf27f0f40abc050",
   "6e8dc58870e6d732",
   "734082d6b01bdc40",
   "a6ee4decdb4e7edb",
   "761960ca27e1b7ad",
   "6876ba45e1064c47",
   "bda12b7bc0e6b2ec",
   "d176bd6f920a5ee1",
   "17b04322765fbd96",
   "8620ee94ade4e8cf"
  ],
  "x": 40,
  "y": 4420,
  "w": 2970,
  "h": 260
 },
 {
  "id": "ae4a9a2e25111370",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "12. Рецепты: живые значения для второго интерфейса",
  "info": "Интерфейс «Рецепты» — образцы оформления (спидометры, слайдеры, списки). Значения им даёт логика:\nодин change собирает их в msg.topic, один api - helper - 2 (интерфейс «Рецепты») отправляет на панель.\nКогда: при старте потока (панель получит значения и открытая позже — их помнит сервер UI-Panel)\nи при нажатии любой вкладки Rcp_Nav_*_b — правило ui - switch по шаблону в интерфейсе «Рецепты».\nСобытия «интерфейс открыт» UI - Panel in не присылает (стенд: только push/release/tap и disconnected).\nСпидометр и слайдер принимают 0…100 (min/max в api - helper - 2), список — [{«ключ»: «значение»}].",
  "x": 160,
  "y": 4820,
  "wires": [
   []
  ]
 },
 {
  "id": "3b94df58804a80ca",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 4880,
  "wires": [
   [
    "9e1fc061a18ede71"
   ]
  ]
 },
 {
  "id": "9e1fc061a18ede71",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "Вкладки «Рецептов»",
  "outputs": 1,
  "ui": "Рецепты",
  "interfaceUuid": "ffd86fb7-76d0-525e-b6f3-1f9bbadaea16",
  "rules": [
   {
    "pattern": "Rcp_Nav_*_b",
    "matchMode": "wildcard",
    "event": "push",
    "output": 1
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 4880,
  "wires": [
   [
    "45ef14aa9eca77a2"
   ]
  ]
 },
 {
  "id": "f780faa0c1b57582",
  "type": "inject",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "Старт",
  "props": [
   {
    "p": "payload"
   }
  ],
  "repeat": "",
  "crontab": "",
  "once": true,
  "onceDelay": "5",
  "topic": "",
  "payload": "",
  "payloadType": "date",
  "x": 460,
  "y": 4940,
  "wires": [
   [
    "45ef14aa9eca77a2"
   ]
  ]
 },
 {
  "id": "45ef14aa9eca77a2",
  "type": "change",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "Значения для снимка",
  "rules": [
   {
    "t": "set",
    "p": "topic",
    "pt": "msg",
    "to": "{\"Rcp_GgZone_gg\": 65, \"Rcp_GgKnob_gg\": 60, \"Rcp_GgRing_gg\": 70, \"Rcp_GgRect_gg\": 40, \"Rcp_SlPill_sl\": 70, \"Rcp_SlFader_sl\": 65, \"Rcp_SlGrad_sl\": 80, \"Rcp_SlGrad2_sl\": 55, \"Rcp_SlThin_sl\": 64, \"Rcp_SlThin_val_lb\": \"64 %\", \"Rcp_LstA_ls\": [{\"Переговорная 2\": \"SIP\"}, {\"Филиал «Север»\": \"SIP\"}, {\"Учебный класс\": \"H.323\"}, {\"Дежурная служба\": \"SIP\"}], \"Rcp_LstB_ls\": [{\"Учебный класс\": \"исходящий\"}, {\"Переговорная 2\": \"входящий\"}, {\"Дежурная служба\": \"пропущенный\"}]}",
    "tot": "json"
   }
  ],
  "action": "",
  "property": "",
  "from": "",
  "to": "",
  "reg": false,
  "x": 760,
  "y": 4880,
  "wires": [
   [
    "4b5b5953afcd41c4"
   ]
  ]
 },
 {
  "id": "4b5b5953afcd41c4",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "Рецепты: значения",
  "ui": "Рецепты",
  "interfaceUuid": "ffd86fb7-76d0-525e-b6f3-1f9bbadaea16",
  "action_type": "uiState",
  "object": [
   {
    "name": "Rcp_GgZone_gg",
    "event": "value",
    "uuid": "865e4e8e-fc9c-5f2c-988a-1307fef63c31",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_GgKnob_gg",
    "event": "value",
    "uuid": "0130fd8d-d622-5404-9351-0097b603d238",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_GgRing_gg",
    "event": "value",
    "uuid": "90b356f9-a60f-5e9a-a434-9b066f0955a3",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_GgRect_gg",
    "event": "value",
    "uuid": "cf30ab83-c057-5703-a923-1ad70177bd95",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlPill_sl",
    "event": "value",
    "uuid": "3cad1a00-173a-59c7-a09a-69af3f5dc1f5",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlFader_sl",
    "event": "value",
    "uuid": "88dc1cf6-e389-5e2b-952c-5fbbd9972c74",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlGrad_sl",
    "event": "value",
    "uuid": "4490f549-9a0c-57fa-be60-f4eaca605f65",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlGrad2_sl",
    "event": "value",
    "uuid": "952dd49c-56f4-5a17-a521-9c376b373926",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlThin_sl",
    "event": "value",
    "uuid": "13a89a05-8104-5368-8547-355a8e0b4d5c",
    "value": "",
    "min": "0",
    "max": "100",
    "step": "100"
   },
   {
    "name": "Rcp_SlThin_val_lb",
    "event": "text",
    "uuid": "280b3049-0a6b-5318-a53d-535f4c6b2552",
    "value": ""
   },
   {
    "name": "Rcp_LstA_ls",
    "event": "list",
    "uuid": "8a51781e-e311-5bae-a253-eb6ce19b4c88",
    "value": "[]"
   },
   {
    "name": "Rcp_LstB_ls",
    "event": "list",
    "uuid": "b5af56a8-f16f-510f-94c9-ca6fd6c078a9",
    "value": "[]"
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1060,
  "y": 4880,
  "wires": [
   [
    "89dff012bc5048f7"
   ]
  ]
 },
 {
  "id": "89dff012bc5048f7",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "f6a198f287009a75",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1360,
  "y": 4880,
  "wires": []
 },
 {
  "id": "f6a198f287009a75",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "12. Рецепты: живые значения для второго интерфейса",
  "style": {
   "label": true
  },
  "nodes": [
   "ae4a9a2e25111370",
   "3b94df58804a80ca",
   "9e1fc061a18ede71",
   "f780faa0c1b57582",
   "45ef14aa9eca77a2",
   "4b5b5953afcd41c4",
   "89dff012bc5048f7"
  ],
  "x": 40,
  "y": 4780,
  "w": 1470,
  "h": 200
 },
 {
  "id": "d3304e71b01ae9d1",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "13. Ввод с клавиатуры: инпут → программа",
  "info": "Инпут присылает текст событием value_changed — по кнопке отправки или Enter (однострочный инпут).\nС флагом «Отправлять символы…» каждый символ приходит отдельно — keyboard_button_pressed.\nЗдесь: правило по шаблону Rcp_In*_in (интерфейс «Рецепты»), template подставляет текст в\n«В программу: …», api - helper - 2 пишет его в лейбл Rcp_KbEcho_lb. Узел отладки (выключен)\nпоказывает каждое событие инпутов строкой JSON — по нему сверяется формат на стенде.",
  "x": 160,
  "y": 5120,
  "wires": [
   []
  ]
 },
 {
  "id": "59c6716e94d289d9",
  "type": "link in",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "события панели",
  "links": [
   "842057998bfdfdf5"
  ],
  "x": 160,
  "y": 5180,
  "wires": [
   [
    "2d4e4fbd76e65eb4"
   ]
  ]
 },
 {
  "id": "2d4e4fbd76e65eb4",
  "type": "ui-switch",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "Инпуты «Рецептов»",
  "outputs": 2,
  "ui": "Рецепты",
  "interfaceUuid": "ffd86fb7-76d0-525e-b6f3-1f9bbadaea16",
  "rules": [
   {
    "pattern": "Rcp_In*_in",
    "matchMode": "wildcard",
    "event": "value_changed",
    "output": 1
   },
   {
    "pattern": "Rcp_In*_in",
    "matchMode": "wildcard",
    "event": "",
    "output": 2
   }
  ],
  "checkall": "true",
  "x": 460,
  "y": 5180,
  "wires": [
   [
    "aa0f0a8288907ab0",
    "2397b2fc441df15d"
   ],
   [
    "2397b2fc441df15d"
   ]
  ]
 },
 {
  "id": "aa0f0a8288907ab0",
  "type": "template",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "В программу: текст",
  "field": "topic",
  "fieldType": "msg",
  "format": "json",
  "syntax": "mustache",
  "template": "{ \"Rcp_KbEcho_lb\": \"В программу: {{payload.value}}\" }",
  "output": "json",
  "x": 760,
  "y": 5180,
  "wires": [
   [
    "4877c8b4189ea274"
   ]
  ]
 },
 {
  "id": "4877c8b4189ea274",
  "type": "api-helper-2",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "Эхо ввода",
  "ui": "Рецепты",
  "interfaceUuid": "ffd86fb7-76d0-525e-b6f3-1f9bbadaea16",
  "action_type": "uiState",
  "object": [
   {
    "name": "Rcp_KbEcho_lb",
    "event": "text",
    "uuid": "a93437a2-7183-5e28-9661-e805cbdb3174",
    "value": ""
   }
  ],
  "inputProp": "topic",
  "inputPropType": "msg",
  "debug": false,
  "x": 1060,
  "y": 5180,
  "wires": [
   [
    "8c7491244988f136"
   ]
  ]
 },
 {
  "id": "8c7491244988f136",
  "type": "link out",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "→ панель",
  "mode": "link",
  "links": [
   "d178e58c55a073f4"
  ],
  "x": 1360,
  "y": 5180,
  "wires": []
 },
 {
  "id": "2397b2fc441df15d",
  "type": "debug",
  "z": "92799e65cd6e432e",
  "g": "828fc2717a9b9ffb",
  "name": "Ввод: события инпутов",
  "active": false,
  "tosidebar": true,
  "console": false,
  "tostatus": false,
  "complete": "$string(payload)",
  "targetType": "jsonata",
  "statusVal": "",
  "statusType": "auto",
  "x": 760,
  "y": 5240,
  "wires": []
 },
 {
  "id": "828fc2717a9b9ffb",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "13. Ввод с клавиатуры: инпут → программа",
  "style": {
   "label": true
  },
  "nodes": [
   "d3304e71b01ae9d1",
   "59c6716e94d289d9",
   "2d4e4fbd76e65eb4",
   "aa0f0a8288907ab0",
   "4877c8b4189ea274",
   "8c7491244988f136",
   "2397b2fc441df15d"
  ],
  "x": 40,
  "y": 5080,
  "w": 1470,
  "h": 200
 },
 {
  "id": "34c6b369cf3d1ea3",
  "type": "comment",
  "z": "92799e65cd6e432e",
  "g": "4674f10bbf48e689",
  "name": "14. Скриптер: сценарий «Перерыв»",
  "info": "Весь сценарий — один узел scripter, код на вкладке On Start. Проводов нет: Скриптер сам слушает\nкнопку Home_Break_b интерфейса «Демо-зал» (onTap) и сам отправляет команды устройствам по имени\nподключения («Демо: звуковой процессор», «Демо: матрица», «Демо: камера 1»).\nШаги идут с паузами (ctrl.wait): микрофоны зала выключены → на экране нет источника → камера 1\n«Домой» → надпись в шапке. Кнопку подсвечивает сам Скриптер (setUiState); остальной вид меняют ответы\nустройств, как и при нажатии кнопок: шапка «Микрофоны» (блок 9), «Нет источника» (блок 4).\nКнопку Home_Break_b не ловит ни один ui - switch — её обрабатывает только Скриптер.",
  "x": 160,
  "y": 5420,
  "wires": [
   []
  ]
 },
 {
  "id": "0d6687dbd5f090aa",
  "type": "scripter",
  "z": "92799e65cd6e432e",
  "g": "4674f10bbf48e689",
  "name": "Сценарий «Перерыв»",
  "initialize": "// Сценарий «Перерыв»: кнопка Home_Break_b на главной интерфейса «Демо-зал».\n// Кнопку не ловит ни один узел ui - switch — весь сценарий здесь.\nconst panel = ctrl.panel('Демо-зал');                    // интерфейс — по имени, как в UI-Designer\nconst sound = ctrl.device('Демо: звуковой процессор');   // устройства — по имени подключения\nconst matrix = ctrl.device('Демо: матрица');\nconst camera = ctrl.device('Демо: камера 1');\n\npanel.onTap('Home_Break_b', () => {\n    // Шаг 1 — сразу: подсветить кнопку и выключить микрофоны зала\n    panel.setUiState('Home_Break_b', 'pressed');\n    sound.send('setMute', { instanceTag: 'DemoMicMaster', channel: 1, state: true });\n\n    // Шаг 2 — через 1 с: убрать источник с экрана (как кнопка Src_Clear_b)\n    ctrl.wait(1, () => matrix.send('route', { input: 0, output: 1 }));\n\n    // Шаг 3 — через 2 с: камера 1 в положение «Домой» (как кнопка Cam_Home_b)\n    ctrl.wait(2, () => camera.send('recallPreset', { preset: 1 }));\n\n    // Шаг 4 — через 3 с: надпись в шапке\n    ctrl.wait(3, () => panel.setText('Hdr_Title_lb', 'Демо-зал — перерыв'));\n});\n\n// Начался другой сценарий — перерыв окончен: снять подсветку и вернуть заголовок\npanel.onTap(['Home_Meeting_b', 'Home_Vcs_b', 'Pop_Yes_b'], () => {\n    panel.setUiState('Home_Break_b', 'default');\n    panel.setText('Hdr_Title_lb', 'Демо-зал');\n});\n",
  "func": "",
  "finalize": "",
  "tabs": [],
  "outputs": 0,
  "x": 160,
  "y": 5480,
  "wires": []
 },
 {
  "id": "4674f10bbf48e689",
  "type": "group",
  "z": "92799e65cd6e432e",
  "name": "14. Скриптер: сценарий «Перерыв»",
  "style": {
   "label": true
  },
  "nodes": [
   "34c6b369cf3d1ea3",
   "0d6687dbd5f090aa"
  ],
  "x": 40,
  "y": 5380,
  "w": 270,
  "h": 140
 }
]