Guest User

Music Control

a guest
Nov 29th, 2023
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JSON 42.96 KB | None | 0 0
  1. [
  2.     {
  3.         "id": "715b57c65332b13b",
  4.         "type": "subflow",
  5.         "name": "track info",
  6.         "info": "Gets current and next track BlueSound API",
  7.         "category": "",
  8.         "in": [
  9.             {
  10.                 "x": 40,
  11.                 "y": 40,
  12.                 "wires": [
  13.                     {
  14.                         "id": "639c5cadda10fd85"
  15.                     }
  16.                 ]
  17.             }
  18.         ],
  19.         "out": [
  20.             {
  21.                 "x": 1100,
  22.                 "y": 300,
  23.                 "wires": [
  24.                     {
  25.                         "id": "2fb50bf863ee52f3",
  26.                         "port": 0
  27.                     }
  28.                 ]
  29.             }
  30.         ],
  31.         "env": [
  32.             {
  33.                 "name": "info",
  34.                 "type": "str",
  35.                 "value": "",
  36.                 "ui": {
  37.                     "label": {
  38.                         "en-US": "Home Asisstant Information"
  39.                     },
  40.                     "type": "none"
  41.                 }
  42.             },
  43.             {
  44.                 "name": "haAddress",
  45.                 "type": "str",
  46.                 "value": "127.0.0.1",
  47.                 "ui": {
  48.                     "label": {
  49.                         "en-US": "HA Address"
  50.                     },
  51.                     "type": "input",
  52.                     "opts": {
  53.                         "types": [
  54.                             "str"
  55.                         ]
  56.                     }
  57.                 }
  58.             },
  59.             {
  60.                 "name": "haPort",
  61.                 "type": "num",
  62.                 "value": "8123",
  63.                 "ui": {
  64.                     "label": {
  65.                         "en-US": "HA Port"
  66.                     },
  67.                     "type": "input",
  68.                     "opts": {
  69.                         "types": [
  70.                             "num"
  71.                         ]
  72.                     }
  73.                 }
  74.             },
  75.             {
  76.                 "name": "haUseHTTPs",
  77.                 "type": "bool",
  78.                 "value": "false",
  79.                 "ui": {
  80.                     "label": {
  81.                         "en-US": "Use HTTPS"
  82.                     },
  83.                     "type": "checkbox"
  84.                 }
  85.             }
  86.         ],
  87.         "meta": {
  88.             "module": "track info",
  89.             "version": "1.0.0",
  90.             "author": "Me",
  91.             "desc": "Gets current and next track BlueSound API",
  92.             "license": "MIT"
  93.         },
  94.         "color": "#DEBD5C",
  95.         "icon": "font-awesome/fa-list-ol"
  96.     },
  97.     {
  98.         "id": "b2e2a65512769f0f",
  99.         "type": "join",
  100.         "z": "715b57c65332b13b",
  101.         "name": "Join",
  102.         "mode": "custom",
  103.         "build": "merged",
  104.         "property": "payload",
  105.         "propertyType": "msg",
  106.         "key": "topic",
  107.         "joiner": "\\n",
  108.         "joinerType": "str",
  109.         "accumulate": false,
  110.         "timeout": "2",
  111.         "count": "2",
  112.         "reduceRight": false,
  113.         "reduceExp": "",
  114.         "reduceInit": "",
  115.         "reduceInitType": "",
  116.         "reduceFixup": "",
  117.         "x": 170,
  118.         "y": 240,
  119.         "wires": [
  120.             [
  121.                 "06c81a105c5371f1"
  122.             ]
  123.         ]
  124.     },
  125.     {
  126.         "id": "0b8cf0cb01cec05e",
  127.         "type": "function",
  128.         "z": "715b57c65332b13b",
  129.         "name": "1 - Format URLs",
  130.         "func": "if (msg.info.ipAddress == \"\") {\n    return null;\n}\n\nvar urls = [\n    'Status',\n    'Playlist?length=1',\n]\n\nurls.forEach(url => {\n    node.send({\n        info: msg.info,\n        url: `http://${msg.info.ipAddress}:11000/${url}`,\n    });\n})\n\nnode.done();\n",
  131.         "outputs": 1,
  132.         "timeout": "",
  133.         "noerr": 0,
  134.         "initialize": "",
  135.         "finalize": "",
  136.         "libs": [],
  137.         "x": 340,
  138.         "y": 180,
  139.         "wires": [
  140.             [
  141.                 "e69f2d4e66f84cdf"
  142.             ]
  143.         ]
  144.     },
  145.     {
  146.         "id": "06c81a105c5371f1",
  147.         "type": "function",
  148.         "z": "715b57c65332b13b",
  149.         "name": "2 - Ensure Playlist",
  150.         "func": "msg.url = undefined;\n\nvar playListLen = -1;\nmsg.info.currentTrack.queuePos = parseInt(msg.payload.status.song[0] || -2);\nmsg.info.currentTrack.queuePos++    // Zero based counter\n\n// Ensure there is a playlist\nif (msg.payload.playlist) {\n    msg.info.totalTracks = parseInt(msg.payload.playlist.length[0]);\n\n    // Get next track information, if there is one\n    if (msg.info.currentTrack.queuePos < msg.info.totalTracks) {\n        msg.url = `http://${msg.info.ipAddress}:11000/Playlist?start=${msg.info.currentTrack.queuePos}&end=${msg.info.currentTrack.queuePos}`;\n    }\n    else {\n        msg.info.nextTrack.title  = \".\";\n        msg.info.nextTrack.artist = \".\";\n        msg.info.nextTrack.album  = \".\";\n    }\n}\n\nif (msg.url != undefined) {\n    return [msg, null];\n}\nelse {\n    return [null, msg];\n}\n",
  151.         "outputs": 2,
  152.         "timeout": "",
  153.         "noerr": 0,
  154.         "initialize": "",
  155.         "finalize": "",
  156.         "libs": [],
  157.         "x": 350,
  158.         "y": 240,
  159.         "wires": [
  160.             [
  161.                 "00f7ba72f2da2b3d"
  162.             ],
  163.             [
  164.                 "2fb50bf863ee52f3"
  165.             ]
  166.         ]
  167.     },
  168.     {
  169.         "id": "2fb50bf863ee52f3",
  170.         "type": "function",
  171.         "z": "715b57c65332b13b",
  172.         "name": "3 - NextTrack Info",
  173.         "func": "if (msg.info.currentTrack.queuepos === \".\") {\n    msg.info.currentTrack.queuepos = msg.temp.currTrackNo;\n}\n\nif (msg.payload.playlist) {\n    if (msg.payload.playlist.song) {\n        msg.info.nextTrack.album  = msg.payload.playlist.song[0].alb[0];\n        msg.info.nextTrack.artist = msg.payload.playlist.song[0].art[0];\n        msg.info.nextTrack.title  = msg.payload.playlist.song[0].title[0];\n    }\n    else {\n        msg.info.nextTrack.album  = \"&nbsp;\";\n        msg.info.nextTrack.artist = \"<i>End Of Playlist</i>\";\n        msg.info.nextTrack.title  = \"&nbsp;\";\n    }\n}\n\n//msg.temp = undefined;\nreturn {payload: msg.info};\n",
  174.         "outputs": 1,
  175.         "timeout": "",
  176.         "noerr": 0,
  177.         "initialize": "",
  178.         "finalize": "",
  179.         "libs": [],
  180.         "x": 350,
  181.         "y": 300,
  182.         "wires": [
  183.             []
  184.         ]
  185.     },
  186.     {
  187.         "id": "639c5cadda10fd85",
  188.         "type": "function",
  189.         "z": "715b57c65332b13b",
  190.         "name": "0 - Create Object",
  191.         "func": "var func = global.get(\"func\");\n\nvar emptyPlaylist = \"<i>(playlist empty)</i>\";\nvar emptyAlbumArt = \"\"\nvar haAddress  = env.get(\"haAddress\")  || \"1.1.1.1\"; \nvar haPort     = env.get(\"haPort\")     || 8123;\nvar haUseHTTPs = env.get(\"haUseHTTPs\") || false;\nvar urlType    = (haUseHTTPs ? \"https\" : \"http\");\n\nif (msg.data) {\n    if (msg.data.new_state) {\n        msg.data = msg.data.new_state;\n    }\n    else if ((msg.data) && (msg.data.event.new_state)) {\n        msg.data = msg.data.event.new_state;\n    }\n}\nelse if ((msg.payload) && (msg.payload.entity_id)) {\n    msg.data = msg.payload;\n}\n\nmsg.payload = undefined;\n\nvar info = {\n    \"currentTrack\": {\n        \"album\":     msg.data.attributes.media_album_name || \".\",\n        \"artist\":    msg.data.attributes.media_artist     || \".\",\n        \"queuePos\":  msg.data.attributes.queue_position   || -1,\n        \"title\":     msg.data.attributes.media_title      || emptyPlaylist,\n        \"artUri\":   `${urlType}://${haAddress}:${haPort}${msg.data.attributes.entity_picture}` || emptyAlbumArt,\n        \"length\":    parseInt(msg.data.attributes.media_duration)   || 0,                         // Length in seconds\n        \"trackPos\":  parseInt(msg.data.attributes.media_position)   || 0,                         // Track position in seconds\n        \"length2\":   func.convertTime(msg.data.attributes.media_duration, \"track\") || \"--:--\",    // Length as formatted string\n        \"trackPos2\": func.convertTime(msg.data.attributes.media_position, \"track\") || \"--:--\",    // Track position as formatted string\n    },\n\n    \"nextTrack\": {\n        \"album\":  \".\",\n        \"artist\": \".\",\n        \"title\":  \".\",\n    },\n\n    \"playbackState\": msg.data.state,\n    \"playerName\":    msg.data.attributes.friendly_name,\n    \"playerId\":      msg.data.entity_id,\n    \"totalTracks\":   -1,\n    \"ipAddress\":     msg.data.attributes.ip_address || \"\",\n    \"volume\":        parseInt(msg.data.attributes.volume_level * 100),\n\n}\n\nreturn {info};\n",
  192.         "outputs": 1,
  193.         "timeout": "",
  194.         "noerr": 0,
  195.         "initialize": "",
  196.         "finalize": "",
  197.         "libs": [],
  198.         "x": 130,
  199.         "y": 180,
  200.         "wires": [
  201.             [
  202.                 "0b8cf0cb01cec05e"
  203.             ]
  204.         ]
  205.     },
  206.     {
  207.         "id": "e69f2d4e66f84cdf",
  208.         "type": "http request",
  209.         "z": "715b57c65332b13b",
  210.         "name": "Playlist / Status",
  211.         "method": "GET",
  212.         "ret": "txt",
  213.         "paytoqs": "ignore",
  214.         "url": "",
  215.         "tls": "",
  216.         "persist": false,
  217.         "proxy": "",
  218.         "insecureHTTPParser": false,
  219.         "authType": "",
  220.         "senderr": false,
  221.         "headers": [],
  222.         "x": 580,
  223.         "y": 180,
  224.         "wires": [
  225.             [
  226.                 "701d5bed666ef95f"
  227.             ]
  228.         ]
  229.     },
  230.     {
  231.         "id": "9f3bf3e37f88796e",
  232.         "type": "xml",
  233.         "z": "715b57c65332b13b",
  234.         "name": "Xml",
  235.         "property": "payload",
  236.         "attr": "",
  237.         "chr": "",
  238.         "x": 930,
  239.         "y": 180,
  240.         "wires": [
  241.             [
  242.                 "b2e2a65512769f0f"
  243.             ]
  244.         ]
  245.     },
  246.     {
  247.         "id": "00f7ba72f2da2b3d",
  248.         "type": "http request",
  249.         "z": "715b57c65332b13b",
  250.         "name": "Set Queue Pos",
  251.         "method": "GET",
  252.         "ret": "txt",
  253.         "paytoqs": "ignore",
  254.         "url": "",
  255.         "tls": "",
  256.         "persist": false,
  257.         "proxy": "",
  258.         "insecureHTTPParser": false,
  259.         "authType": "",
  260.         "senderr": false,
  261.         "headers": [],
  262.         "x": 580,
  263.         "y": 240,
  264.         "wires": [
  265.             [
  266.                 "40237da30559eb4c"
  267.             ]
  268.         ]
  269.     },
  270.     {
  271.         "id": "09af8be8d4c96ef0",
  272.         "type": "xml",
  273.         "z": "715b57c65332b13b",
  274.         "name": "Xml",
  275.         "property": "payload",
  276.         "attr": "",
  277.         "chr": "",
  278.         "x": 930,
  279.         "y": 240,
  280.         "wires": [
  281.             [
  282.                 "2fb50bf863ee52f3"
  283.             ]
  284.         ]
  285.     },
  286.     {
  287.         "id": "f05c7d31ce947fc7",
  288.         "type": "comment",
  289.         "z": "715b57c65332b13b",
  290.         "name": "Stage 1",
  291.         "info": "Forumate URL for playlist length\nForumate URL for currently playing",
  292.         "x": 1090,
  293.         "y": 80,
  294.         "wires": []
  295.     },
  296.     {
  297.         "id": "bfbce7cf8a2daf2a",
  298.         "type": "comment",
  299.         "z": "715b57c65332b13b",
  300.         "name": "Stage 2",
  301.         "info": "Get current track number\nFormulate URL to get next track info",
  302.         "x": 1090,
  303.         "y": 120,
  304.         "wires": []
  305.     },
  306.     {
  307.         "id": "ca34320a5cf428fc",
  308.         "type": "comment",
  309.         "z": "715b57c65332b13b",
  310.         "name": "Stage 3",
  311.         "info": "Tie everything else together",
  312.         "x": 1090,
  313.         "y": 160,
  314.         "wires": []
  315.     },
  316.     {
  317.         "id": "701d5bed666ef95f",
  318.         "type": "switch",
  319.         "z": "715b57c65332b13b",
  320.         "name": "Status Code",
  321.         "property": "statusCode",
  322.         "propertyType": "msg",
  323.         "rules": [
  324.             {
  325.                 "t": "eq",
  326.                 "v": "200",
  327.                 "vt": "num"
  328.             },
  329.             {
  330.                 "t": "else"
  331.             }
  332.         ],
  333.         "checkall": "true",
  334.         "repair": false,
  335.         "outputs": 2,
  336.         "x": 770,
  337.         "y": 180,
  338.         "wires": [
  339.             [
  340.                 "9f3bf3e37f88796e"
  341.             ],
  342.             []
  343.         ]
  344.     },
  345.     {
  346.         "id": "40237da30559eb4c",
  347.         "type": "switch",
  348.         "z": "715b57c65332b13b",
  349.         "name": "Status Code",
  350.         "property": "statusCode",
  351.         "propertyType": "msg",
  352.         "rules": [
  353.             {
  354.                 "t": "eq",
  355.                 "v": "200",
  356.                 "vt": "num"
  357.             },
  358.             {
  359.                 "t": "else"
  360.             }
  361.         ],
  362.         "checkall": "true",
  363.         "repair": false,
  364.         "outputs": 2,
  365.         "x": 770,
  366.         "y": 240,
  367.         "wires": [
  368.             [
  369.                 "09af8be8d4c96ef0"
  370.             ],
  371.             []
  372.         ]
  373.     },
  374.     {
  375.         "id": "119ee3c8cec8edfc",
  376.         "type": "comment",
  377.         "z": "715b57c65332b13b",
  378.         "name": "Stage 0",
  379.         "info": "Delays incoming requests: important\nCreates the JS object to manipulate",
  380.         "x": 1090,
  381.         "y": 40,
  382.         "wires": []
  383.     },
  384.     {
  385.         "id": "36a51e882e7c8098",
  386.         "type": "tab",
  387.         "label": "Music Control",
  388.         "disabled": false,
  389.         "info": ""
  390.     },
  391.     {
  392.         "id": "2921e71710bf19f4",
  393.         "type": "group",
  394.         "z": "36a51e882e7c8098",
  395.         "name": "Update Currently Playing Information",
  396.         "style": {
  397.             "label": true,
  398.             "stroke": "#000000",
  399.             "fill": "#bfbfbf",
  400.             "fill-opacity": "0.25",
  401.             "color": "#000000"
  402.         },
  403.         "nodes": [
  404.             "1a9a96b0fcd6a6a6",
  405.             "6e4fa448f739629e",
  406.             "9691d3d8c01a1303",
  407.             "e028a150b4daa738",
  408.             "f00580961c860116",
  409.             "f53e6d14192943b8",
  410.             "699540e3dc5c9caf",
  411.             "51190bea03e13bca",
  412.             "ebecb87c4e391567",
  413.             "28cfc8bc6a861106",
  414.             "d48e9f739bc3a287",
  415.             "0ae94d25f03776f2",
  416.             "56686842eb01ab92",
  417.             "5efd47fae4b678e5"
  418.         ],
  419.         "x": 14,
  420.         "y": 639,
  421.         "w": 1112,
  422.         "h": 182
  423.     },
  424.     {
  425.         "id": "aebdab15ef4ba5d1",
  426.         "type": "group",
  427.         "z": "36a51e882e7c8098",
  428.         "name": "Change Album / Artist",
  429.         "style": {
  430.             "stroke": "#000000",
  431.             "fill": "#bfbfbf",
  432.             "fill-opacity": "0.25",
  433.             "label": true,
  434.             "color": "#000000"
  435.         },
  436.         "nodes": [
  437.             "0a0e8c6f95067f74",
  438.             "1e6dd7fcaab3047c",
  439.             "8a2ba92dfe1002f8",
  440.             "49af760f08bb7064",
  441.             "3b34dba3f4519a53",
  442.             "ca5c6417c40e9323",
  443.             "efbb5469bb8ad08c",
  444.             "da42e5a0c6bd7bf0",
  445.             "ca54ba3ac6aa7b42",
  446.             "845331a79935d27f",
  447.             "b6282e4a9ba743fb",
  448.             "0e6b9ca4662fbe68",
  449.             "d240618aedd55c9c",
  450.             "b0b0840a9f86b853",
  451.             "ee0f42289aef4f48"
  452.         ],
  453.         "x": 14,
  454.         "y": 379,
  455.         "w": 1112,
  456.         "h": 242
  457.     },
  458.     {
  459.         "id": "1a9a96b0fcd6a6a6",
  460.         "type": "ha-get-entities",
  461.         "z": "36a51e882e7c8098",
  462.         "g": "2921e71710bf19f4",
  463.         "name": "Music Players",
  464.         "server": "77c01ee87ceeb243",
  465.         "version": 0,
  466.         "rules": [
  467.             {
  468.                 "property": "entity_id",
  469.                 "logic": "is",
  470.                 "value": "media_player.*",
  471.                 "valueType": "re"
  472.             },
  473.             {
  474.                 "property": "attributes.media_content_type",
  475.                 "logic": "is",
  476.                 "value": "music",
  477.                 "valueType": "str"
  478.             },
  479.             {
  480.                 "property": "state",
  481.                 "logic": "is_not",
  482.                 "value": "grouped",
  483.                 "valueType": "str"
  484.             }
  485.         ],
  486.         "output_type": "split",
  487.         "output_empty_results": false,
  488.         "output_location_type": "msg",
  489.         "output_location": "payload",
  490.         "output_results_count": 1,
  491.         "x": 220,
  492.         "y": 740,
  493.         "wires": [
  494.             [
  495.                 "699540e3dc5c9caf"
  496.             ]
  497.         ]
  498.     },
  499.     {
  500.         "id": "6e4fa448f739629e",
  501.         "type": "switch",
  502.         "z": "36a51e882e7c8098",
  503.         "g": "2921e71710bf19f4",
  504.         "name": "Player Select",
  505.         "property": "payload.playerName",
  506.         "propertyType": "msg",
  507.         "rules": [
  508.             {
  509.                 "t": "eq",
  510.                 "v": "Lounge",
  511.                 "vt": "str"
  512.             },
  513.             {
  514.                 "t": "eq",
  515.                 "v": "Study",
  516.                 "vt": "str"
  517.             }
  518.         ],
  519.         "checkall": "false",
  520.         "repair": false,
  521.         "outputs": 2,
  522.         "x": 850,
  523.         "y": 760,
  524.         "wires": [
  525.             [
  526.                 "9691d3d8c01a1303"
  527.             ],
  528.             [
  529.                 "f00580961c860116"
  530.             ]
  531.         ]
  532.     },
  533.     {
  534.         "id": "9691d3d8c01a1303",
  535.         "type": "link out",
  536.         "z": "36a51e882e7c8098",
  537.         "g": "2921e71710bf19f4",
  538.         "name": "Lounge",
  539.         "mode": "link",
  540.         "links": [
  541.             "209b08538867494f",
  542.             "a83832506dc91f31",
  543.             "fed19dd1434279c9",
  544.             "d2be36990d5d15ae",
  545.             "75bfb14c0c477350"
  546.         ],
  547.         "x": 1040,
  548.         "y": 740,
  549.         "wires": [],
  550.         "icon": "font-awesome/fa-music",
  551.         "l": true
  552.     },
  553.     {
  554.         "id": "c4f3b4349c8ac21f",
  555.         "type": "api-call-service",
  556.         "z": "36a51e882e7c8098",
  557.         "name": "Music Control Service",
  558.         "server": "77c01ee87ceeb243",
  559.         "version": 5,
  560.         "debugenabled": false,
  561.         "domain": "",
  562.         "service": "",
  563.         "areaId": [],
  564.         "deviceId": [],
  565.         "entityId": [],
  566.         "data": "",
  567.         "dataType": "jsonata",
  568.         "mergeContext": "",
  569.         "mustacheAltTags": false,
  570.         "outputProperties": [],
  571.         "queue": "none",
  572.         "x": 360,
  573.         "y": 260,
  574.         "wires": [
  575.             []
  576.         ]
  577.     },
  578.     {
  579.         "id": "acbca54b7a1dbc7b",
  580.         "type": "function",
  581.         "z": "36a51e882e7c8098",
  582.         "name": "Music Control",
  583.         "func": "var action      = \"X\";\nvar player      = \"X\";\nvar players     = global.get(\"musicPlayers\");\nvar currTrack   = flow.get(\"currTrack\");\n\nif (typeof msg.payload.slots !== \"undefined\") {\n    // From JARVIS\n    player = msg.payload.siteId.toLowerCase();\n    action = msg.payload.slots.action.toLowerCase();\n}\nelse {\n    // From UI CONTROLS\n    player = msg.topic.toLowerCase();\n    action = msg.payload;\n    if (typeof action !== \"number\") {\n        action = action.toLowerCase();\n    }\n}\n\n// HACK FOR SPEAKER GROUPING ISSUE\nif (player === \"kitchen\") {\n    node.warn(\"'KITCHEN' Label Used\");\n    player = \"lounge\";\n}\n// HACK FOR SPEAKER GROUPING ISSUE\n\nmsg.payload = {};\nmsg.payload.domain = \"media_player\";\nplayer = player.replace('media_player.', '');\nmsg.payload.data = {\"entity_id\": `media_player.${player}`};\n\nvar skipForward = null;\n\nswitch (action) {\n    case \"playpause\":  // Toggle play/pause player\n        msg.payload.service = \"media_play_pause\";\n        break;\n\n    case \"play\":  // Start playing music\n        msg.payload.service = \"media_play\";\n        break;\n\n    case \"stop\":  // Stop playing music\n        msg.payload.service = \"media_pause\";\n        break;\n\n    case \"previous\":  // Play previous track\n        msg.payload.service = \"media_previous_track\";\n        break;\n\n    case \"next\":  // Play next track\n        msg.payload.service = \"media_next_track\";\n        break;\n\n    case \"album\":  // Skip to next album\n        msg.payload.service = \"media_pause\";\n        skipForward = { skipAction: \"Album\", player: player };\n        break;\n\n    case \"artist\":  // Skip to next artist\n        msg.payload.service = \"media_pause\";\n        skipForward = { skipAction: \"Artist\", player: player };\n        break;\n\n    case \"increase\":  // Raise volume\n        msg.payload.service = \"volume_up\";\n        break;\n\n    case \"decrease\":  // Lower volume\n        msg.payload.service = \"volume_down\";\n        break;\n\n    case \"track\":  // Get currently playing track\n        var currTrack = flow.get(\"currTrack\")\n        msg.payload = `Current track is \"${currTrack[player].title}\" by \"${currTrack[player].artist}\" on \"${currTrack[player].album}\"`;\n        msg.siteId  = player;\n        return [\n            msg,\n            null,\n            null\n        ];\n\n    default:\n        if (typeof action === \"number\") {  // Change volume to specific value\n            var newVolume = parseFloat(action / 100).toFixed(2);\n\n            if (players[player].volume !== newVolume) {\n                msg.payload.service = \"volume_set\";\n                msg.payload.data.volume_level = newVolume;\n            }\n            else {\n                msg = null;\n            }\n        }\n}\n\nreturn [\n    null,\n    skipForward,\n    msg\n];\n",
  584.         "outputs": 3,
  585.         "noerr": 0,
  586.         "initialize": "",
  587.         "finalize": "",
  588.         "libs": [],
  589.         "x": 120,
  590.         "y": 220,
  591.         "wires": [
  592.             [
  593.                 "a015e856239334be"
  594.             ],
  595.             [
  596.                 "069ea68f73053833"
  597.             ],
  598.             [
  599.                 "c4f3b4349c8ac21f"
  600.             ]
  601.         ]
  602.     },
  603.     {
  604.         "id": "e028a150b4daa738",
  605.         "type": "trigger-state",
  606.         "z": "36a51e882e7c8098",
  607.         "g": "2921e71710bf19f4",
  608.         "name": "Trigger State",
  609.         "server": "77c01ee87ceeb243",
  610.         "version": 4,
  611.         "inputs": 0,
  612.         "outputs": 2,
  613.         "exposeAsEntityConfig": "",
  614.         "entityId": "media_player",
  615.         "entityIdType": "substring",
  616.         "debugEnabled": false,
  617.         "constraints": [
  618.             {
  619.                 "targetType": "this_entity",
  620.                 "targetValue": "",
  621.                 "propertyType": "property",
  622.                 "propertyValue": "new_state.attributes.media_content_type",
  623.                 "comparatorType": "is",
  624.                 "comparatorValueDatatype": "str",
  625.                 "comparatorValue": "music"
  626.             },
  627.             {
  628.                 "targetType": "this_entity",
  629.                 "targetValue": "",
  630.                 "propertyType": "property",
  631.                 "propertyValue": "new_state.state",
  632.                 "comparatorType": "is_not",
  633.                 "comparatorValueDatatype": "str",
  634.                 "comparatorValue": "grouped"
  635.             }
  636.         ],
  637.         "customOutputs": [],
  638.         "outputInitially": false,
  639.         "stateType": "str",
  640.         "enableInput": false,
  641.         "exposeToHomeAssistant": false,
  642.         "haConfig": [
  643.             {
  644.                 "property": "name",
  645.                 "value": ""
  646.             },
  647.             {
  648.                 "property": "icon",
  649.                 "value": ""
  650.             }
  651.         ],
  652.         "x": 230,
  653.         "y": 680,
  654.         "wires": [
  655.             [
  656.                 "5efd47fae4b678e5"
  657.             ],
  658.             []
  659.         ]
  660.     },
  661.     {
  662.         "id": "f00580961c860116",
  663.         "type": "link out",
  664.         "z": "36a51e882e7c8098",
  665.         "g": "2921e71710bf19f4",
  666.         "name": "Study",
  667.         "links": [
  668.             "1c7556be09df24b9",
  669.             "1c979e46c6195e65",
  670.             "6d178decac8c3537",
  671.             "706b7cf43d7c62ce",
  672.             "159319c1082b295c",
  673.             "ccdc6ebc5259862d",
  674.             "11b8bb2e340a07a3",
  675.             "75e879a88b81d8bd",
  676.             "fc4e59a5379d791b",
  677.             "a1bd065a0a8cb6ea"
  678.         ],
  679.         "x": 1030,
  680.         "y": 780,
  681.         "wires": [],
  682.         "icon": "font-awesome/fa-music",
  683.         "l": true
  684.     },
  685.     {
  686.         "id": "b65bf698970b5964",
  687.         "type": "comment",
  688.         "z": "36a51e882e7c8098",
  689.         "name": "Flow Explaination",
  690.         "info": "Music Control Service\n    This does all the work to control\n    play/pause, next, prev and volume.\n\n\nMusic Player\n    Gets all information from all\n    `music_player.*` devices\n\n\nTrigger State\n    As above, but is trigger by events\n\n",
  691.         "x": 100,
  692.         "y": 80,
  693.         "wires": []
  694.     },
  695.     {
  696.         "id": "87aa0819e57ce109",
  697.         "type": "catch",
  698.         "z": "36a51e882e7c8098",
  699.         "name": "Catch All",
  700.         "scope": null,
  701.         "uncaught": true,
  702.         "x": 1000,
  703.         "y": 40,
  704.         "wires": [
  705.             [
  706.                 "67d16d8350936fe6"
  707.             ]
  708.         ]
  709.     },
  710.     {
  711.         "id": "67d16d8350936fe6",
  712.         "type": "link out",
  713.         "z": "36a51e882e7c8098",
  714.         "name": "Error Logging",
  715.         "mode": "link",
  716.         "links": [
  717.             "498db3b5.39bc9c",
  718.             "7495be3477187c7a"
  719.         ],
  720.         "x": 1115,
  721.         "y": 40,
  722.         "wires": [],
  723.         "icon": "font-awesome/fa-exclamation"
  724.     },
  725.     {
  726.         "id": "5157e70bae68b04e",
  727.         "type": "link in",
  728.         "z": "36a51e882e7c8098",
  729.         "name": "Music",
  730.         "links": [
  731.             "983ecb90.e0d3b8",
  732.             "17635279aac1c8b4",
  733.             "d79211d106243437",
  734.             "1549ea7d8f964923",
  735.             "596809fe0d4a7de5",
  736.             "a25cb078df0f4837",
  737.             "c4d3d1f8b171eca8",
  738.             "0b5e1fd28742cf9e",
  739.             "0e975831db7c85c9",
  740.             "bb4ea9df48c90b7b",
  741.             "b6385d7273de2d93",
  742.             "373e7b2e4bd696ba",
  743.             "41dbdd1a9d016910",
  744.             "072ecebf8ddc8049",
  745.             "d4fb5a4216e6e7f9",
  746.             "d2d51e9f5c787f7e"
  747.         ],
  748.         "x": 35,
  749.         "y": 40,
  750.         "wires": [
  751.             [
  752.                 "acbca54b7a1dbc7b"
  753.             ]
  754.         ],
  755.         "icon": "node-red/bridge.svg"
  756.     },
  757.     {
  758.         "id": "a015e856239334be",
  759.         "type": "link out",
  760.         "z": "36a51e882e7c8098",
  761.         "name": "Current Track",
  762.         "mode": "link",
  763.         "links": [
  764.             "349a75b9.2668ea"
  765.         ],
  766.         "x": 340,
  767.         "y": 180,
  768.         "wires": [],
  769.         "icon": "node-red/bridge.svg",
  770.         "l": true
  771.     },
  772.     {
  773.         "id": "f53e6d14192943b8",
  774.         "type": "function",
  775.         "z": "36a51e882e7c8098",
  776.         "g": "2921e71710bf19f4",
  777.         "name": "Set currTrack",
  778.         "func": "var currTrack    = flow.get(\"currTrack\") || {};\nvar musicPlayers = global.get(\"musicPlayers\") || {};\nvar currPlayer   = msg.payload.playerName.toLowerCase();\n\ncurrTrack[currPlayer] = msg.payload.currentTrack;\nmusicPlayers[currPlayer].ipAddress = msg.payload.ipAddress;\n\nflow.set(\"currTrack\", currTrack);\nglobal.set(\"musicPlayers\", musicPlayers);\n",
  779.         "outputs": 1,
  780.         "timeout": "",
  781.         "noerr": 0,
  782.         "initialize": "",
  783.         "finalize": "",
  784.         "libs": [],
  785.         "x": 850,
  786.         "y": 720,
  787.         "wires": [
  788.             []
  789.         ]
  790.     },
  791.     {
  792.         "id": "699540e3dc5c9caf",
  793.         "type": "delay",
  794.         "z": "36a51e882e7c8098",
  795.         "g": "2921e71710bf19f4",
  796.         "name": "Rate 1s",
  797.         "pauseType": "rate",
  798.         "timeout": "1",
  799.         "timeoutUnits": "seconds",
  800.         "rate": "1",
  801.         "nbRateUnits": "1",
  802.         "rateUnits": "second",
  803.         "randomFirst": "1",
  804.         "randomLast": "5",
  805.         "randomUnits": "seconds",
  806.         "drop": false,
  807.         "allowrate": false,
  808.         "outputs": 1,
  809.         "x": 400,
  810.         "y": 740,
  811.         "wires": [
  812.             [
  813.                 "d48e9f739bc3a287"
  814.             ]
  815.         ]
  816.     },
  817.     {
  818.         "id": "51190bea03e13bca",
  819.         "type": "function",
  820.         "z": "36a51e882e7c8098",
  821.         "g": "2921e71710bf19f4",
  822.         "name": "Save Volume ",
  823.         "func": "var musicPlayers = global.get(\"musicPlayers\") || {};\nvar currPlayer   = msg.topic.replace(\"media_player.\", \"\").toLowerCase();\n\nmusicPlayers[currPlayer] = {};\nmusicPlayers[currPlayer].volume = msg.data.event.new_state.attributes.volume_level;\nglobal.set(\"musicPlayers\", musicPlayers);\n\nreturn msg;\n",
  824.         "outputs": 1,
  825.         "noerr": 0,
  826.         "initialize": "",
  827.         "finalize": "",
  828.         "libs": [],
  829.         "x": 850,
  830.         "y": 680,
  831.         "wires": [
  832.             [
  833.                 "ebecb87c4e391567"
  834.             ]
  835.         ]
  836.     },
  837.     {
  838.         "id": "ebecb87c4e391567",
  839.         "type": "link out",
  840.         "z": "36a51e882e7c8098",
  841.         "g": "2921e71710bf19f4",
  842.         "name": "Volume",
  843.         "mode": "link",
  844.         "links": [
  845.             "ac38921646b7142f"
  846.         ],
  847.         "x": 1040,
  848.         "y": 680,
  849.         "wires": [],
  850.         "icon": "font-awesome/fa-volume-up",
  851.         "l": true
  852.     },
  853.     {
  854.         "id": "069ea68f73053833",
  855.         "type": "link out",
  856.         "z": "36a51e882e7c8098",
  857.         "name": "Change Album/Artist",
  858.         "mode": "link",
  859.         "links": [
  860.             "42a03c677f45d9bf",
  861.             "ca5c6417c40e9323"
  862.         ],
  863.         "x": 360,
  864.         "y": 220,
  865.         "wires": [],
  866.         "icon": "node-red-dashboard/ui_dropdown.png",
  867.         "l": true
  868.     },
  869.     {
  870.         "id": "0a0e8c6f95067f74",
  871.         "type": "ha-get-entities",
  872.         "z": "36a51e882e7c8098",
  873.         "g": "aebdab15ef4ba5d1",
  874.         "name": "Music Players",
  875.         "server": "77c01ee87ceeb243",
  876.         "version": 0,
  877.         "rules": [],
  878.         "output_type": "split",
  879.         "output_empty_results": false,
  880.         "output_location_type": "msg",
  881.         "output_location": "payload",
  882.         "output_results_count": 1,
  883.         "x": 520,
  884.         "y": 500,
  885.         "wires": [
  886.             [
  887.                 "b0b0840a9f86b853"
  888.             ]
  889.         ]
  890.     },
  891.     {
  892.         "id": "1e6dd7fcaab3047c",
  893.         "type": "http request",
  894.         "z": "36a51e882e7c8098",
  895.         "g": "aebdab15ef4ba5d1",
  896.         "name": "Get Data",
  897.         "method": "GET",
  898.         "ret": "txt",
  899.         "paytoqs": "ignore",
  900.         "url": "",
  901.         "tls": "",
  902.         "persist": false,
  903.         "proxy": "",
  904.         "insecureHTTPParser": false,
  905.         "authType": "",
  906.         "senderr": false,
  907.         "headers": [],
  908.         "x": 360,
  909.         "y": 560,
  910.         "wires": [
  911.             [
  912.                 "8a2ba92dfe1002f8"
  913.             ]
  914.         ]
  915.     },
  916.     {
  917.         "id": "8a2ba92dfe1002f8",
  918.         "type": "xml",
  919.         "z": "36a51e882e7c8098",
  920.         "g": "aebdab15ef4ba5d1",
  921.         "name": "XML",
  922.         "property": "payload",
  923.         "attr": "",
  924.         "chr": "",
  925.         "x": 510,
  926.         "y": 560,
  927.         "wires": [
  928.             [
  929.                 "49af760f08bb7064"
  930.             ]
  931.         ]
  932.     },
  933.     {
  934.         "id": "49af760f08bb7064",
  935.         "type": "function",
  936.         "z": "36a51e882e7c8098",
  937.         "g": "aebdab15ef4ba5d1",
  938.         "name": "Get Next",
  939.         "func": "var url = msg.url.split(\"Playlist\")[0];\n\nif (msg.payload.playlist.song === undefined) {\n    node.warn(\"msg.payload.playlist.song === undefined\");\n    return [\n        {\n            \"url\": url,\n            \"enabled\": true,\n            \"player\": msg.player\n        },\n        null\n    ];\n}\n\nvar currAlbum   = msg.payload.playlist.song[0].alb[0];\nvar currArtist  = msg.payload.playlist.song[0].art[0];\nvar currTrackId = parseInt(msg.payload.playlist.song[0].$.id) || 0;\nvar newTrackId  = -1;\n\nfunction matchArtist(newTitle) {\n    if ((newTitle.match(currArtist)) || (currArtist.match(newTitle))) {\n        return true;\n    }\n    return false;\n}\n\nif (msg.skipAction === \"Album\") {\n    msg.payload.playlist.song.forEach(item => {\n        if ((newTrackId === -1) || (newTrackId === currTrackId)) {\n            // if ALBUM is different : PLAYTRACK\n            if (item.alb[0] != currAlbum) {\n                newTrackId = parseInt(item.$.id);\n            }\n        }\n    })\n    // End of playlist check\n    if (newTrackId === -1) {newTrackId = -2}\n}\n\nelse if (msg.skipAction === \"Artist\") {\n    msg.payload.playlist.song.forEach(item => {\n        if ((newTrackId === -1) || (newTrackId === currTrackId)) {\n            // if ARTIST is different : PLAYTRACK\n            if (!matchArtist(item.art[0])) {\n                newTrackId = parseInt(item.$.id);\n            }\n        }\n    })\n    // End of playlist check\n    if (newTrackId === -1) { newTrackId = -2 }\n}\n\nelse {\n    node.warn(\"No skipAction specified\");\n    return [\n        {\n            \"url\": null,\n            \"enabled\": true,\n            \"player\": msg.player\n        },\n        null\n    ]\n}\n\nif ((newTrackId > -1) && (newTrackId > currTrackId)) {\n    url = (msg.url.split(\"Playlist\")[0]) + `Play?id=${newTrackId}`\n}\n\nreturn [\n    {\n        \"url\": url,\n        \"enabled\": true,\n        \"player\": msg.player\n    },\n    {\n        \"topic\": \"skipchange\",\n        \"player\": msg.player,\n        \"payload\": {\n            \"skipAction\": msg.skipAction,\n            \"currAlbum\":  currAlbum,\n            \"currArtist\": currArtist,\n            \"oldId\":      currTrackId,\n            \"newId\":      newTrackId\n        }\n    }\n];\n",
  940.         "outputs": 2,
  941.         "noerr": 0,
  942.         "initialize": "",
  943.         "finalize": "",
  944.         "libs": [],
  945.         "x": 660,
  946.         "y": 560,
  947.         "wires": [
  948.             [
  949.                 "d240618aedd55c9c",
  950.                 "3b34dba3f4519a53"
  951.             ],
  952.             [
  953.                 "ca54ba3ac6aa7b42"
  954.             ]
  955.         ]
  956.     },
  957.     {
  958.         "id": "3b34dba3f4519a53",
  959.         "type": "http request",
  960.         "z": "36a51e882e7c8098",
  961.         "g": "aebdab15ef4ba5d1",
  962.         "name": "Play Next",
  963.         "method": "POST",
  964.         "ret": "txt",
  965.         "paytoqs": "ignore",
  966.         "url": "",
  967.         "tls": "",
  968.         "persist": false,
  969.         "proxy": "",
  970.         "insecureHTTPParser": false,
  971.         "authType": "",
  972.         "senderr": false,
  973.         "headers": [],
  974.         "x": 840,
  975.         "y": 540,
  976.         "wires": [
  977.             []
  978.         ]
  979.     },
  980.     {
  981.         "id": "ca5c6417c40e9323",
  982.         "type": "link in",
  983.         "z": "36a51e882e7c8098",
  984.         "g": "aebdab15ef4ba5d1",
  985.         "name": "Change Album/Artist",
  986.         "links": [
  987.             "069ea68f73053833"
  988.         ],
  989.         "x": 55,
  990.         "y": 460,
  991.         "wires": [
  992.             [
  993.                 "efbb5469bb8ad08c"
  994.             ]
  995.         ],
  996.         "icon": "node-red-dashboard/ui_dropdown.png"
  997.     },
  998.     {
  999.         "id": "efbb5469bb8ad08c",
  1000.         "type": "change",
  1001.         "z": "36a51e882e7c8098",
  1002.         "g": "aebdab15ef4ba5d1",
  1003.         "name": "Set Rules",
  1004.         "rules": [
  1005.             {
  1006.                 "t": "set",
  1007.                 "p": "payload",
  1008.                 "pt": "msg",
  1009.                 "to": "$join(['{\"rules\":[{\"property\":\"entity_id\",\"logic\":\"is\",\"value\":\"media_player.', player, '\",\"valueType\":\"str\"}]}'], \"\")",
  1010.                 "tot": "jsonata"
  1011.             },
  1012.             {
  1013.                 "t": "set",
  1014.                 "p": "enabled",
  1015.                 "pt": "msg",
  1016.                 "to": "false",
  1017.                 "tot": "bool"
  1018.             }
  1019.         ],
  1020.         "action": "",
  1021.         "property": "",
  1022.         "from": "",
  1023.         "to": "",
  1024.         "reg": false,
  1025.         "x": 180,
  1026.         "y": 460,
  1027.         "wires": [
  1028.             [
  1029.                 "da42e5a0c6bd7bf0",
  1030.                 "d240618aedd55c9c"
  1031.             ]
  1032.         ]
  1033.     },
  1034.     {
  1035.         "id": "da42e5a0c6bd7bf0",
  1036.         "type": "json",
  1037.         "z": "36a51e882e7c8098",
  1038.         "g": "aebdab15ef4ba5d1",
  1039.         "name": "JSON",
  1040.         "property": "payload",
  1041.         "action": "",
  1042.         "pretty": false,
  1043.         "x": 350,
  1044.         "y": 500,
  1045.         "wires": [
  1046.             [
  1047.                 "0a0e8c6f95067f74"
  1048.             ]
  1049.         ]
  1050.     },
  1051.     {
  1052.         "id": "28cfc8bc6a861106",
  1053.         "type": "comment",
  1054.         "z": "36a51e882e7c8098",
  1055.         "g": "2921e71710bf19f4",
  1056.         "name": "Ignore \"grouped\" error",
  1057.         "info": "This is because it's finding a device that matches the \"is not\" rule.\nIt can be ignored.",
  1058.         "x": 600,
  1059.         "y": 780,
  1060.         "wires": []
  1061.     },
  1062.     {
  1063.         "id": "ca54ba3ac6aa7b42",
  1064.         "type": "link out",
  1065.         "z": "36a51e882e7c8098",
  1066.         "g": "aebdab15ef4ba5d1",
  1067.         "name": "Logging",
  1068.         "mode": "link",
  1069.         "links": [
  1070.             "1da60329.1c119d",
  1071.             "dff3e2daa88b43f4"
  1072.         ],
  1073.         "x": 840,
  1074.         "y": 580,
  1075.         "wires": [],
  1076.         "icon": "node-red/debug.svg",
  1077.         "l": true
  1078.     },
  1079.     {
  1080.         "id": "d240618aedd55c9c",
  1081.         "type": "switch",
  1082.         "z": "36a51e882e7c8098",
  1083.         "g": "aebdab15ef4ba5d1",
  1084.         "name": "Player Select",
  1085.         "property": "player",
  1086.         "propertyType": "msg",
  1087.         "rules": [
  1088.             {
  1089.                 "t": "eq",
  1090.                 "v": "lounge",
  1091.                 "vt": "str"
  1092.             },
  1093.             {
  1094.                 "t": "eq",
  1095.                 "v": "study",
  1096.                 "vt": "str"
  1097.             }
  1098.         ],
  1099.         "checkall": "false",
  1100.         "repair": false,
  1101.         "outputs": 2,
  1102.         "x": 850,
  1103.         "y": 460,
  1104.         "wires": [
  1105.             [
  1106.                 "845331a79935d27f"
  1107.             ],
  1108.             [
  1109.                 "b6282e4a9ba743fb"
  1110.             ]
  1111.         ]
  1112.     },
  1113.     {
  1114.         "id": "0e6b9ca4662fbe68",
  1115.         "type": "change",
  1116.         "z": "36a51e882e7c8098",
  1117.         "g": "aebdab15ef4ba5d1",
  1118.         "name": "Enable",
  1119.         "rules": [
  1120.             {
  1121.                 "t": "set",
  1122.                 "p": "enabled",
  1123.                 "pt": "msg",
  1124.                 "to": "true",
  1125.                 "tot": "bool"
  1126.             }
  1127.         ],
  1128.         "action": "",
  1129.         "property": "",
  1130.         "from": "",
  1131.         "to": "",
  1132.         "reg": false,
  1133.         "x": 860,
  1134.         "y": 420,
  1135.         "wires": [
  1136.             [
  1137.                 "845331a79935d27f",
  1138.                 "b6282e4a9ba743fb"
  1139.             ]
  1140.         ]
  1141.     },
  1142.     {
  1143.         "id": "b6282e4a9ba743fb",
  1144.         "type": "link out",
  1145.         "z": "36a51e882e7c8098",
  1146.         "g": "aebdab15ef4ba5d1",
  1147.         "name": "Study",
  1148.         "mode": "link",
  1149.         "links": [
  1150.             "108d075174f1e5b8",
  1151.             "a9c11b3bcd46d87d",
  1152.             "68ec3c38f6fd192d",
  1153.             "9446b87cc9422610",
  1154.             "1d4dde504ee6a9e7",
  1155.             "5e2968b3302e7ef5",
  1156.             "56fad6f71a3fdc12",
  1157.             "e331e98cdc5954f5"
  1158.         ],
  1159.         "x": 1030,
  1160.         "y": 460,
  1161.         "wires": [],
  1162.         "icon": "font-awesome/fa-toggle-off",
  1163.         "l": true
  1164.     },
  1165.     {
  1166.         "id": "845331a79935d27f",
  1167.         "type": "link out",
  1168.         "z": "36a51e882e7c8098",
  1169.         "g": "aebdab15ef4ba5d1",
  1170.         "name": "Lounge",
  1171.         "mode": "link",
  1172.         "links": [
  1173.             "1fb4a70acb1e0deb",
  1174.             "64cd11a0e798bbc2",
  1175.             "d2775ed3c672a3c1",
  1176.             "33a8c913445a89a6",
  1177.             "ca591f366f53a391",
  1178.             "7aab22d735add24e",
  1179.             "d041b7987b819a19"
  1180.         ],
  1181.         "x": 1040,
  1182.         "y": 420,
  1183.         "wires": [],
  1184.         "icon": "font-awesome/fa-toggle-off",
  1185.         "l": true
  1186.     },
  1187.     {
  1188.         "id": "b0b0840a9f86b853",
  1189.         "type": "function",
  1190.         "z": "36a51e882e7c8098",
  1191.         "g": "aebdab15ef4ba5d1",
  1192.         "name": "Format URL",
  1193.         "func": "var currTrack = flow.get(\"currTrack\") || undefined;\n\nif (currTrack === undefined) {\n    node.warn(\"currTrack is undefined\")\n    return null;\n}\n\nvar player    = msg.player;\nvar queuePosS = currTrack[player].queuePos       || 0;\nvar queuePosE = currTrack[player].queuePos + 300 || 300;\n\nmsg.url = `http://${msg.payload.attributes.ip_address}:11000/Playlist?start=${queuePosS}&end=${queuePosE}`\n\nreturn msg;\n",
  1194.         "outputs": 1,
  1195.         "noerr": 0,
  1196.         "initialize": "",
  1197.         "finalize": "",
  1198.         "libs": [],
  1199.         "x": 190,
  1200.         "y": 560,
  1201.         "wires": [
  1202.             [
  1203.                 "1e6dd7fcaab3047c"
  1204.             ]
  1205.         ]
  1206.     },
  1207.     {
  1208.         "id": "ee0f42289aef4f48",
  1209.         "type": "link in",
  1210.         "z": "36a51e882e7c8098",
  1211.         "g": "aebdab15ef4ba5d1",
  1212.         "name": "Trigger - Startup",
  1213.         "links": [],
  1214.         "x": 715,
  1215.         "y": 420,
  1216.         "wires": [
  1217.             [
  1218.                 "0e6b9ca4662fbe68"
  1219.             ]
  1220.         ],
  1221.         "icon": "font-awesome/fa-thumb-tack"
  1222.     },
  1223.     {
  1224.         "id": "d48e9f739bc3a287",
  1225.         "type": "subflow:715b57c65332b13b",
  1226.         "z": "36a51e882e7c8098",
  1227.         "g": "2921e71710bf19f4",
  1228.         "name": "Track Information",
  1229.         "env": [
  1230.             {
  1231.                 "name": "haAddress",
  1232.                 "value": "1.1.1.1",
  1233.                 "type": "str"
  1234.             }
  1235.         ],
  1236.         "x": 630,
  1237.         "y": 740,
  1238.         "wires": [
  1239.             [
  1240.                 "f53e6d14192943b8",
  1241.                 "6e4fa448f739629e"
  1242.             ]
  1243.         ]
  1244.     },
  1245.     {
  1246.         "id": "0ae94d25f03776f2",
  1247.         "type": "link in",
  1248.         "z": "36a51e882e7c8098",
  1249.         "g": "2921e71710bf19f4",
  1250.         "name": "Every 60 Minutes",
  1251.         "links": [
  1252.             "c3e046d5b1d7cd49"
  1253.         ],
  1254.         "x": 75,
  1255.         "y": 720,
  1256.         "wires": [
  1257.             [
  1258.                 "1a9a96b0fcd6a6a6"
  1259.             ]
  1260.         ]
  1261.     },
  1262.     {
  1263.         "id": "56686842eb01ab92",
  1264.         "type": "inject",
  1265.         "z": "36a51e882e7c8098",
  1266.         "g": "2921e71710bf19f4",
  1267.         "name": "Inject",
  1268.         "props": [],
  1269.         "repeat": "",
  1270.         "crontab": "",
  1271.         "once": false,
  1272.         "onceDelay": 0.1,
  1273.         "topic": "",
  1274.         "x": 75,
  1275.         "y": 760,
  1276.         "wires": [
  1277.             [
  1278.                 "1a9a96b0fcd6a6a6"
  1279.             ]
  1280.         ],
  1281.         "l": false
  1282.     },
  1283.     {
  1284.         "id": "5efd47fae4b678e5",
  1285.         "type": "delay",
  1286.         "z": "36a51e882e7c8098",
  1287.         "g": "2921e71710bf19f4",
  1288.         "name": "Delay 125ms",
  1289.         "pauseType": "delay",
  1290.         "timeout": "125",
  1291.         "timeoutUnits": "milliseconds",
  1292.         "rate": "1",
  1293.         "nbRateUnits": "1",
  1294.         "rateUnits": "second",
  1295.         "randomFirst": "1",
  1296.         "randomLast": "5",
  1297.         "randomUnits": "seconds",
  1298.         "drop": false,
  1299.         "allowrate": false,
  1300.         "outputs": 1,
  1301.         "x": 410,
  1302.         "y": 680,
  1303.         "wires": [
  1304.             [
  1305.                 "51190bea03e13bca",
  1306.                 "d48e9f739bc3a287"
  1307.             ]
  1308.         ]
  1309.     },
  1310.     {
  1311.         "id": "77c01ee87ceeb243",
  1312.         "type": "server",
  1313.         "name": "Home Assistant",
  1314.         "version": 5,
  1315.         "addon": false,
  1316.         "rejectUnauthorizedCerts": false,
  1317.         "ha_boolean": "y|yes|true|on|home|open",
  1318.         "connectionDelay": true,
  1319.         "cacheJson": true,
  1320.         "heartbeat": false,
  1321.         "heartbeatInterval": "30",
  1322.         "areaSelector": "friendlyName",
  1323.         "deviceSelector": "friendlyName",
  1324.         "entitySelector": "friendlyName",
  1325.         "statusSeparator": "at: ",
  1326.         "statusYear": "hidden",
  1327.         "statusMonth": "short",
  1328.         "statusDay": "numeric",
  1329.         "statusHourCycle": "h23",
  1330.         "statusTimeFormat": "h:m",
  1331.         "enableGlobalContextStore": true
  1332.     }
  1333. ]
Add Comment
Please, Sign In to add comment