Last active
May 7, 2025 00:13
-
-
Save My-Random-Thoughts/f25651d85a35367a7290a7502b9eb80a to your computer and use it in GitHub Desktop.
Node-RED SubFlow to Get LibreLinkUp API Data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [ | |
| { | |
| "id": "99c028b90d557c84", | |
| "type": "group", | |
| "z": "c07b047ac4d1031c", | |
| "name": "Blood Glucose Data", | |
| "style": { | |
| "label": true | |
| }, | |
| "nodes": [ | |
| "7eac23037bb2cb6e", | |
| "0fc4e3f21fb3c353", | |
| "39ba2ede2e620cf7", | |
| "ff92dd37eadf0d91", | |
| "1e062653f6408f1b" | |
| ], | |
| "x": 154, | |
| "y": 179, | |
| "w": 652, | |
| "h": 122 | |
| }, | |
| { | |
| "id": "971815d09245e7d0", | |
| "type": "subflow", | |
| "name": "llu-api", | |
| "info": "", | |
| "category": "", | |
| "in": [ | |
| { | |
| "x": 40, | |
| "y": 40, | |
| "wires": [ | |
| { | |
| "id": "173b49ec74fa2d74" | |
| } | |
| ] | |
| } | |
| ], | |
| "out": [ | |
| { | |
| "x": 1140, | |
| "y": 240, | |
| "wires": [ | |
| { | |
| "id": "98d4be588da5dd41", | |
| "port": 0 | |
| }, | |
| { | |
| "id": "6b3ae50153996dd0", | |
| "port": 0 | |
| } | |
| ] | |
| } | |
| ], | |
| "env": [ | |
| { | |
| "name": "baseUrl", | |
| "type": "str", | |
| "value": "https://api-eu.libreview.io/", | |
| "ui": { | |
| "icon": "font-awesome/fa-link", | |
| "label": { | |
| "en-US": "Base URL" | |
| }, | |
| "type": "input", | |
| "opts": { | |
| "types": [ | |
| "str" | |
| ] | |
| } | |
| } | |
| }, | |
| { | |
| "name": "username", | |
| "type": "str", | |
| "value": "", | |
| "ui": { | |
| "icon": "font-awesome/fa-address-card-o", | |
| "label": { | |
| "en-US": "Username" | |
| }, | |
| "type": "input", | |
| "opts": { | |
| "types": [ | |
| "str" | |
| ] | |
| } | |
| } | |
| }, | |
| { | |
| "name": "password", | |
| "type": "cred", | |
| "ui": { | |
| "icon": "font-awesome/fa-lock", | |
| "label": { | |
| "en-US": "Password" | |
| } | |
| } | |
| }, | |
| { | |
| "name": "returnGraphDataOnly", | |
| "type": "bool", | |
| "value": "true", | |
| "ui": { | |
| "label": { | |
| "en-US": "Return just graph data" | |
| }, | |
| "type": "checkbox" | |
| } | |
| } | |
| ], | |
| "meta": {}, | |
| "color": "#FDF0C2", | |
| "icon": "font-awesome/fa-eyedropper", | |
| "status": { | |
| "x": 340, | |
| "y": 100, | |
| "wires": [ | |
| { | |
| "id": "173b49ec74fa2d74", | |
| "port": 0 | |
| }, | |
| { | |
| "id": "06a1a2a78d10ecf6", | |
| "port": 0 | |
| } | |
| ] | |
| } | |
| }, | |
| { | |
| "id": "173b49ec74fa2d74", | |
| "type": "function", | |
| "z": "971815d09245e7d0", | |
| "name": "Check Data", | |
| "func": "// Checks to see if there is a token and that it has not expired.\n// If the token is valie, it then checks to see if there is a PatientId/\n//\n// Data is stored in a flow context data with the fllowing format:\n// \n// llu-data: {\n// baseUrl: \"...\" <-- Base URL\n// expiry: \"...\" <-- expiry date for token\n// token: \"...\" <-- auth token\n// patient: \"...\" <-- patient id for connections\n// }\n\nvar status = \"\";\nvar llu_data = (global.get(\"llu-data\")) || {}\nvar baseUrl = llu_data.baseUrl ? llu_data.baseUrl : env.get(\"baseUrl\");\nif (baseUrl.match(/\\/$/)) { baseUrl = baseUrl.slice(0, -1); }\n\nswitch (true) {\n case (!(llu_data.token)):\n msg.url = `${baseUrl}/llu/auth/login`;\n msg.method = \"POST\";\n status = \"Login...\"; // No Token\n break;\n\n case (!(llu_data.expiry)):\n msg.url = `${baseUrl}/llu/auth/login`;\n msg.method = \"POST\";\n status = \"Login...\"; // No Expiry\n break;\n \n case (llu_data.expiry):\n var expiry = new Date(llu_data.expiry * 1000)\n var date = new Date();\n\n if (expiry.getTime() <= date.getTime()) {\n msg.url = `${baseUrl}/llu/auth/login`; // Expiry date has passed\n msg.method = \"POST\"\n status = \"Login..\"; // Expired\n }\n break;\n\n case (!(llu_data.patient)):\n msg.url = `${baseUrl}/llu/connections`;\n msg.method = \"GET\";\n status = \"Getting Connections...\";\n break;\n\n default:\n msg.url = `${baseUrl}/llu/connections/${llu_data.patient}/graph`;\n msg.method = \"GET\";\n status = \"Getting Data...\";\n}\n\nmsg.headers = {\n \"cache-control\": \"no-cache\",\n \"connection\": \"Keep-Alive\",\n \"content-type\": \"application/json\",\n \"product\": \"llu.android\",\n \"version\": \"4.10\",\n \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3\",\n};\n\nif (msg.url.match(\"/auth/login\")) {\n msg.payload = {\n \"email\": env.get(\"username\"),\n \"password\": env.get(\"password\")\n }\n}\nelse {\n msg.headers.authorization = `Bearer ${llu_data.token}`\n}\n\nreturn [\n {payload: {fill: \"blue\", shape: \"dot\", text: status}},\n msg\n];\n", | |
| "outputs": 2, | |
| "timeout": 0, | |
| "noerr": 0, | |
| "initialize": "", | |
| "finalize": "", | |
| "libs": [], | |
| "x": 190, | |
| "y": 140, | |
| "wires": [ | |
| [], | |
| [ | |
| "b6781cd7458a3ebf" | |
| ] | |
| ], | |
| "outputLabels": [ | |
| "", | |
| "Status Messages" | |
| ] | |
| }, | |
| { | |
| "id": "b6781cd7458a3ebf", | |
| "type": "http request", | |
| "z": "971815d09245e7d0", | |
| "name": "HTTP Request", | |
| "method": "use", | |
| "ret": "obj", | |
| "paytoqs": "ignore", | |
| "url": "", | |
| "tls": "", | |
| "persist": false, | |
| "proxy": "", | |
| "insecureHTTPParser": false, | |
| "authType": "", | |
| "senderr": false, | |
| "headers": [], | |
| "x": 400, | |
| "y": 180, | |
| "wires": [ | |
| [ | |
| "1684874edacc0c07" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "1684874edacc0c07", | |
| "type": "switch", | |
| "z": "971815d09245e7d0", | |
| "name": "Check URL", | |
| "property": "responseUrl", | |
| "propertyType": "msg", | |
| "rules": [ | |
| { | |
| "t": "regex", | |
| "v": "/auth/login$", | |
| "vt": "str", | |
| "case": true | |
| }, | |
| { | |
| "t": "regex", | |
| "v": "/connections$", | |
| "vt": "str", | |
| "case": true | |
| }, | |
| { | |
| "t": "else" | |
| } | |
| ], | |
| "checkall": "true", | |
| "repair": false, | |
| "outputs": 3, | |
| "x": 590, | |
| "y": 180, | |
| "wires": [ | |
| [ | |
| "e826b0b853799d13" | |
| ], | |
| [ | |
| "baf3265cb8a2f01a" | |
| ], | |
| [ | |
| "956e732bc92e3d5a", | |
| "0471ecd36f1d7754" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "2aac8eeb3ff68f71", | |
| "type": "link in", | |
| "z": "971815d09245e7d0", | |
| "name": "Login Loop", | |
| "links": [ | |
| "df3225ef197ddd60" | |
| ], | |
| "x": 35, | |
| "y": 140, | |
| "wires": [ | |
| [ | |
| "173b49ec74fa2d74" | |
| ] | |
| ], | |
| "icon": "font-awesome/fa-unlock-alt" | |
| }, | |
| { | |
| "id": "df3225ef197ddd60", | |
| "type": "link out", | |
| "z": "971815d09245e7d0", | |
| "name": "Login Loop", | |
| "mode": "link", | |
| "links": [ | |
| "2aac8eeb3ff68f71" | |
| ], | |
| "x": 935, | |
| "y": 140, | |
| "wires": [], | |
| "icon": "font-awesome/fa-unlock-alt" | |
| }, | |
| { | |
| "id": "e826b0b853799d13", | |
| "type": "change", | |
| "z": "971815d09245e7d0", | |
| "name": "Set Token", | |
| "rules": [ | |
| { | |
| "t": "set", | |
| "p": "llu-data.token", | |
| "pt": "global", | |
| "to": "payload.data.authTicket.token", | |
| "tot": "msg" | |
| }, | |
| { | |
| "t": "set", | |
| "p": "llu-data.expiry", | |
| "pt": "global", | |
| "to": "payload.data.authTicket.expires", | |
| "tot": "msg" | |
| } | |
| ], | |
| "action": "", | |
| "property": "", | |
| "from": "", | |
| "to": "", | |
| "reg": false, | |
| "x": 780, | |
| "y": 120, | |
| "wires": [ | |
| [ | |
| "df3225ef197ddd60" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "baf3265cb8a2f01a", | |
| "type": "change", | |
| "z": "971815d09245e7d0", | |
| "name": "Set Patient", | |
| "rules": [ | |
| { | |
| "t": "set", | |
| "p": "llu-data.patient", | |
| "pt": "global", | |
| "to": "payload.data[0].patientId", | |
| "tot": "msg" | |
| } | |
| ], | |
| "action": "", | |
| "property": "", | |
| "from": "", | |
| "to": "", | |
| "reg": false, | |
| "x": 790, | |
| "y": 180, | |
| "wires": [ | |
| [ | |
| "df3225ef197ddd60" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "98d4be588da5dd41", | |
| "type": "change", | |
| "z": "971815d09245e7d0", | |
| "name": "Set Payload", | |
| "rules": [ | |
| { | |
| "t": "set", | |
| "p": "payload", | |
| "pt": "msg", | |
| "to": "payload.data.graphData", | |
| "tot": "msg", | |
| "dc": true | |
| } | |
| ], | |
| "action": "", | |
| "property": "", | |
| "from": "", | |
| "to": "", | |
| "reg": false, | |
| "x": 990, | |
| "y": 260, | |
| "wires": [ | |
| [] | |
| ] | |
| }, | |
| { | |
| "id": "956e732bc92e3d5a", | |
| "type": "switch", | |
| "z": "971815d09245e7d0", | |
| "name": "Return All?", | |
| "property": "returnGraphDataOnly", | |
| "propertyType": "env", | |
| "rules": [ | |
| { | |
| "t": "false" | |
| }, | |
| { | |
| "t": "true" | |
| } | |
| ], | |
| "checkall": "true", | |
| "repair": false, | |
| "outputs": 2, | |
| "x": 790, | |
| "y": 240, | |
| "wires": [ | |
| [ | |
| "f1c48b5cb938cde7" | |
| ], | |
| [ | |
| "98d4be588da5dd41" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "7a8ee83ccf83fe36", | |
| "type": "change", | |
| "z": "971815d09245e7d0", | |
| "name": "Clear Status", | |
| "rules": [ | |
| { | |
| "t": "set", | |
| "p": "payload", | |
| "pt": "msg", | |
| "to": "", | |
| "tot": "str" | |
| } | |
| ], | |
| "action": "", | |
| "property": "", | |
| "from": "", | |
| "to": "", | |
| "reg": false, | |
| "x": 990, | |
| "y": 320, | |
| "wires": [ | |
| [ | |
| "3e3498f715bb4361" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "0471ecd36f1d7754", | |
| "type": "delay", | |
| "z": "971815d09245e7d0", | |
| "name": "1s Delay", | |
| "pauseType": "delay", | |
| "timeout": "1", | |
| "timeoutUnits": "seconds", | |
| "rate": "1", | |
| "nbRateUnits": "1", | |
| "rateUnits": "second", | |
| "randomFirst": "1", | |
| "randomLast": "5", | |
| "randomUnits": "seconds", | |
| "drop": false, | |
| "allowrate": false, | |
| "outputs": 1, | |
| "x": 780, | |
| "y": 320, | |
| "wires": [ | |
| [ | |
| "7a8ee83ccf83fe36" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "06a1a2a78d10ecf6", | |
| "type": "link in", | |
| "z": "971815d09245e7d0", | |
| "name": "Clear Status", | |
| "links": [ | |
| "3e3498f715bb4361" | |
| ], | |
| "x": 235, | |
| "y": 100, | |
| "wires": [ | |
| [] | |
| ], | |
| "icon": "font-awesome/fa-paint-brush" | |
| }, | |
| { | |
| "id": "3e3498f715bb4361", | |
| "type": "link out", | |
| "z": "971815d09245e7d0", | |
| "name": "Clear Status", | |
| "mode": "link", | |
| "links": [ | |
| "06a1a2a78d10ecf6" | |
| ], | |
| "x": 1135, | |
| "y": 320, | |
| "wires": [], | |
| "icon": "font-awesome/fa-paint-brush" | |
| }, | |
| { | |
| "id": "f1c48b5cb938cde7", | |
| "type": "junction", | |
| "z": "971815d09245e7d0", | |
| "x": 920, | |
| "y": 200, | |
| "wires": [ | |
| [ | |
| "6b3ae50153996dd0" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "6b3ae50153996dd0", | |
| "type": "junction", | |
| "z": "971815d09245e7d0", | |
| "x": 1060, | |
| "y": 200, | |
| "wires": [ | |
| [] | |
| ] | |
| }, | |
| { | |
| "id": "7eac23037bb2cb6e", | |
| "type": "subflow:971815d09245e7d0", | |
| "z": "c07b047ac4d1031c", | |
| "g": "99c028b90d557c84", | |
| "name": "", | |
| "env": [ | |
| { | |
| "name": "baseUrl", | |
| "value": "https://api-eu2.libreview.io/", | |
| "type": "str" | |
| }, | |
| { | |
| "name": "password", | |
| "type": "cred" | |
| } | |
| ], | |
| "x": 390, | |
| "y": 240, | |
| "wires": [ | |
| [ | |
| "ff92dd37eadf0d91", | |
| "1e062653f6408f1b" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "0fc4e3f21fb3c353", | |
| "type": "inject", | |
| "z": "c07b047ac4d1031c", | |
| "g": "99c028b90d557c84", | |
| "name": "Inject", | |
| "props": [], | |
| "repeat": "", | |
| "crontab": "", | |
| "once": false, | |
| "onceDelay": 0.1, | |
| "topic": "", | |
| "x": 250, | |
| "y": 240, | |
| "wires": [ | |
| [ | |
| "7eac23037bb2cb6e" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "39ba2ede2e620cf7", | |
| "type": "ui_chart", | |
| "z": "c07b047ac4d1031c", | |
| "g": "99c028b90d557c84", | |
| "name": "", | |
| "group": "0fc25052abbbacd2", | |
| "order": 1, | |
| "width": "12", | |
| "height": "7", | |
| "label": "Chart", | |
| "chartType": "line", | |
| "legend": "false", | |
| "xformat": "HH:mm:ss", | |
| "interpolate": "linear", | |
| "nodata": "", | |
| "dot": false, | |
| "ymin": "0", | |
| "ymax": "20", | |
| "removeOlder": 1, | |
| "removeOlderPoints": "90", | |
| "removeOlderUnit": "3600", | |
| "cutout": 0, | |
| "useOneColor": false, | |
| "useUTC": false, | |
| "colors": [ | |
| "#1f77b4", | |
| "#aec7e8", | |
| "#ff7f0e", | |
| "#2ca02c", | |
| "#98df8a", | |
| "#d62728", | |
| "#ff9896", | |
| "#9467bd", | |
| "#c5b0d5" | |
| ], | |
| "outputs": 1, | |
| "useDifferentColor": false, | |
| "className": "", | |
| "x": 730, | |
| "y": 220, | |
| "wires": [ | |
| [] | |
| ] | |
| }, | |
| { | |
| "id": "ff92dd37eadf0d91", | |
| "type": "function", | |
| "z": "c07b047ac4d1031c", | |
| "g": "99c028b90d557c84", | |
| "name": "Format Data", | |
| "func": "var msgNew = {\n topic: \"Blood Glucose Data\",\n payload: [{\n \"series\": [\"Blood Glucose Data\"],\n \"data\": [[]],\n \"labels\": [\"Blood Glucose Data\"]\n }]\n};\n\nmsg.payload.forEach(item => {\n msgNew.payload[0].data[0].push({\n x: item.Timestamp,\n y: item.Value\n })\n})\n\nreturn msgNew;\n", | |
| "outputs": 1, | |
| "timeout": 0, | |
| "noerr": 0, | |
| "initialize": "", | |
| "finalize": "", | |
| "libs": [], | |
| "x": 570, | |
| "y": 220, | |
| "wires": [ | |
| [ | |
| "39ba2ede2e620cf7" | |
| ] | |
| ] | |
| }, | |
| { | |
| "id": "1e062653f6408f1b", | |
| "type": "debug", | |
| "z": "c07b047ac4d1031c", | |
| "g": "99c028b90d557c84", | |
| "name": "Data Output", | |
| "active": true, | |
| "tosidebar": true, | |
| "console": false, | |
| "tostatus": false, | |
| "complete": "true", | |
| "targetType": "full", | |
| "statusVal": "", | |
| "statusType": "auto", | |
| "x": 570, | |
| "y": 260, | |
| "wires": [] | |
| }, | |
| { | |
| "id": "0fc25052abbbacd2", | |
| "type": "ui_group", | |
| "name": "Chart", | |
| "tab": "70ad754f34f21b44", | |
| "order": 1, | |
| "disp": true, | |
| "width": "12", | |
| "collapse": false, | |
| "className": "" | |
| }, | |
| { | |
| "id": "70ad754f34f21b44", | |
| "type": "ui_tab", | |
| "name": "Blood Glucose Data", | |
| "icon": "dashboard", | |
| "order": 11, | |
| "disabled": false, | |
| "hidden": false | |
| } | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment