Last active
November 12, 2024 21:46
-
-
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 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