@ifp-software/node-red-contrib-oee-ai-connector
Version:
Easily connect your production machines to oee.ai – The Industry 4.0 solution for OEE optimization.
677 lines (676 loc) • 20.8 kB
JSON
[
{
"id": "87fc67442f9080e5",
"type": "subflow",
"name": "Patch loss reason",
"info": "",
"category": "",
"in": [
{
"x": 360,
"y": 260,
"wires": [
{
"id": "07058fae669a1665"
}
]
}
],
"out": [
{
"x": 920,
"y": 260,
"wires": [
{
"id": "a2d7b0882820171f",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "a2d7b0882820171f",
"type": "http request",
"z": "87fc67442f9080e5",
"name": "Patch loss reason",
"method": "use",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.oee.ai/loss-reasons/{{{oldLossReasonId}}}",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 770,
"y": 260,
"wires": [
[]
]
},
{
"id": "07058fae669a1665",
"type": "function",
"z": "87fc67442f9080e5",
"name": "Formatting json payload",
"func": "msg.headers = {\n \"Content-Type\": \"application/vnd.api+json\",\n \"Authorization\": \"Bearer \" + msg.bearerToken\n};\n\nmsg.method = \"PATCH\";\n\nmsg.payload = {\n \"data\": {\n \"type\": \"loss-reasons\",\n \"id\": msg.oldLossReasonId,\n \"attributes\": {\n \"title-de\": msg[\"title-de\"],\n \"title-en\": msg[\"title-en\"],\n \"title-it\": msg[\"title-it\"],\n \"title-ro\": msg[\"title-ro\"],\n \"title-cz\": msg[\"title-cz\"],\n \"valid-from\": msg[\"valid-from\"],\n \"valid-to\": msg[\"valid-to\"],\n \"classification\": msg.classification,\n \"tags\": msg.tags,\n \"color\": msg.color,\n \"icon\": msg.icon,\n \"mode\": msg.mode,\n \"target-minutes\": msg[\"target-minutes\"],\n \"reduces-oee\": msg[\"reduces-oee\"],\n \"changes-product\": msg[\"changes-product\"],\n \"input-rejects\": msg[\"input-rejects\"],\n \"ignore-units\": msg[\"ignore-units\"]\n },\n \"relationships\": {\n \"location\": {\n \"data\": {\n \"type\": \"locations\",\n \"id\": msg.location\n }\n },\n \"parent-loss-reason\":{\n \"data\": null\n }\n }\n }\n};\n\nif (msg[\"parent-loss-reason\"]) {\n msg.payload.data.relationships[\"parent-loss-reason\"].data = {\n \"type\": \"loss-reasons\",\n \"id\": msg[\"parent-loss-reason\"]\n };\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 530,
"y": 260,
"wires": [
[
"a2d7b0882820171f"
]
]
},
{
"id": "a312a6fc64b9406a",
"type": "subflow",
"name": "Post loss reason",
"info": "",
"category": "",
"in": [
{
"x": 380,
"y": 260,
"wires": [
{
"id": "b269a642d49879ba"
}
]
}
],
"out": [
{
"x": 940,
"y": 260,
"wires": [
{
"id": "3373fbee81df867c",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "b269a642d49879ba",
"type": "function",
"z": "a312a6fc64b9406a",
"name": "Formatting json payload",
"func": "msg.headers = {\n \"Authorization\": \"Bearer \" + msg.bearerToken,\n \"Content-Type\": \"application/vnd.api+json\"\n};\n\nmsg.payload = {\n \"data\": {\n \"type\": \"loss-reasons\",\n \"attributes\": {\n \"title-de\": msg[\"title-de\"],\n \"title-en\": msg[\"title-en\"],\n \"title-it\": msg[\"title-it\"],\n \"title-ro\": msg[\"title-ro\"],\n \"title-cz\": msg[\"title-cz\"],\n \"valid-from\": msg[\"valid-from\"],\n \"valid-to\": msg[\"valid-to\"],\n \"classification\": msg.classification,\n \"tags\": msg.tags,\n \"color\": msg.color,\n \"icon\": msg.icon,\n \"mode\": msg.mode,\n \"target-minutes\": msg[\"target-minutes\"],\n \"reduces-oee\": msg[\"reduces-oee\"],\n \"changes-product\": msg[\"changes-product\"],\n \"input-rejects\": msg[\"input-rejects\"],\n \"ignore-units\": msg[\"ignore-units\"]\n },\n \"relationships\": {\n \"location\": {\n \"data\": {\n \"type\": \"locations\",\n \"id\": msg.location\n }\n }\n }\n }\n};\n\nif (msg[\"parent-loss-reason\"]){\n msg.payload.data.relationships[\"parent-loss-reason\"] = {\n \"data\": {\n \"type\": \"loss-reasons\",\n \"id\": msg[\"parent-loss-reason\"]\n }\n };\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 550,
"y": 260,
"wires": [
[
"3373fbee81df867c"
]
]
},
{
"id": "3373fbee81df867c",
"type": "http request",
"z": "a312a6fc64b9406a",
"name": "POST loss reason",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.oee.ai/loss-reasons",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 790,
"y": 260,
"wires": [
[]
]
},
{
"id": "184cc4064c28bc4e",
"type": "subflow",
"name": "Get all loss reasons",
"info": "",
"category": "",
"in": [
{
"x": 160,
"y": 280,
"wires": [
{
"id": "08143ffcbe9f937c"
}
]
}
],
"out": [
{
"x": 1540,
"y": 280,
"wires": [
{
"id": "f59336dfb3d4af2c",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "9a567b3c853a51ea",
"type": "change",
"z": "184cc4064c28bc4e",
"name": "Delete response header",
"rules": [
{
"t": "delete",
"p": "headers",
"pt": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1130,
"y": 280,
"wires": [
[
"f59336dfb3d4af2c"
]
]
},
{
"id": "08143ffcbe9f937c",
"type": "function",
"z": "184cc4064c28bc4e",
"name": "Set Authorization header",
"func": "msg.headers = {\n \"Authorization\": \"Bearer \" + msg.bearerToken,\n};\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 280,
"wires": [
[
"9be5407c3b0330ee"
]
]
},
{
"id": "1045703e96def829",
"type": "http request",
"z": "184cc4064c28bc4e",
"name": "GET all loss-reasons",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.oee.ai/loss-reasons?filter[location]={{{location}}}&filter[valid-at]={{{now}}}",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 880,
"y": 280,
"wires": [
[
"9a567b3c853a51ea"
]
]
},
{
"id": "f59336dfb3d4af2c",
"type": "change",
"z": "184cc4064c28bc4e",
"name": "Save all loss reasons",
"rules": [
{
"t": "set",
"p": "all-loss-reasons",
"pt": "msg",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1380,
"y": 280,
"wires": [
[]
]
},
{
"id": "9be5407c3b0330ee",
"type": "function",
"z": "184cc4064c28bc4e",
"name": "Generate iso8601 date for today",
"func": "msg.now = new Date().toISOString();\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 610,
"y": 280,
"wires": [
[
"1045703e96def829"
]
]
},
{
"id": "3eaf2cca52ce5808",
"type": "subflow",
"name": "Send loss reasons to oee.ai",
"info": "",
"category": "",
"in": [
{
"x": 300,
"y": 360,
"wires": [
{
"id": "d8afcc01e4658d10"
}
]
}
],
"out": [],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "8807c315f7441134",
"type": "switch",
"z": "3eaf2cca52ce5808",
"name": "Has parent loss reason",
"property": "parent-loss-reason-title",
"propertyType": "msg",
"rules": [
{
"t": "nempty"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 690,
"y": 360,
"wires": [
[
"3f83b636f48f77d9"
],
[
"6ec87b6a5061674a"
]
]
},
{
"id": "d8afcc01e4658d10",
"type": "subflow:184cc4064c28bc4e",
"z": "3eaf2cca52ce5808",
"name": "",
"x": 450,
"y": 360,
"wires": [
[
"8807c315f7441134"
]
]
},
{
"id": "17c1dc97ca31b6f8",
"type": "subflow:a312a6fc64b9406a",
"z": "3eaf2cca52ce5808",
"name": "",
"x": 1790,
"y": 380,
"wires": [
[
"b7ae663e1a23236a"
]
]
},
{
"id": "6ec87b6a5061674a",
"type": "function",
"z": "3eaf2cca52ce5808",
"name": "Check if loss reason already exists",
"func": "// replace data=null if there is no parent loss reason with an id attribute of null\nconst match = msg['all-loss-reasons'].data.find(\n ({ relationships, attributes }) => {\n const parentId = relationships['parent-loss-reason'].data.id;\n const isMatchingTitle = [\n 'title-de',\n 'title-en',\n 'title-it',\n 'title-ro',\n 'title-cz',\n ].some((lang) => attributes[lang] === msg[lang]);\n return parentId === msg['parent-loss-reason'] && isMatchingTitle;\n }\n);\n\nfunction compareProperties(a, b, properties) {\n return properties.every((prop) => {\n if (prop === 'target-minutes') {\n return parseFloat(a[prop]) === parseFloat(b[prop]);\n } else {\n return a[prop] === b[prop];\n }\n });\n}\n\nif (match) {\n const propertiesToCompare = [\n 'classification',\n 'color',\n 'icon',\n 'mode',\n 'target-minutes',\n 'reduces-oee',\n 'changes-product',\n 'input-rejects',\n 'ignore-units',\n ];\n\n if (!compareProperties(match['attributes'], msg, propertiesToCompare)) {\n return [msg, null];\n } else {\n return null;\n }\n}\n\nreturn [null, msg];",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1380,
"y": 360,
"wires": [
[
"e36450a6aa0fe7e7"
],
[
"17c1dc97ca31b6f8"
]
]
},
{
"id": "e36450a6aa0fe7e7",
"type": "subflow:87fc67442f9080e5",
"z": "3eaf2cca52ce5808",
"name": "",
"x": 1790,
"y": 300,
"wires": [
[
"b7ae663e1a23236a"
]
]
},
{
"id": "b7ae663e1a23236a",
"type": "debug",
"z": "3eaf2cca52ce5808",
"name": "Response from oee.ai",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 2100,
"y": 340,
"wires": []
},
{
"id": "3f83b636f48f77d9",
"type": "function",
"z": "3eaf2cca52ce5808",
"name": "Check if parent loss reason title exists",
"func": "const parent = msg[\"all-loss-reasons\"].data.find(reason => reason.attributes.title === msg[\"parent-loss-reason-title\"]);\n\nif (parent){\n msg[\"parent-loss-reason\"] = parent.id;\n return msg;\n}\n\nnode.warn(\"Parent loss reason with title \" + msg[\"parent-loss-reason-title\"] + \" does not exist.\");\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1050,
"y": 300,
"wires": [
[
"6ec87b6a5061674a"
]
]
},
{
"id": "0246bd7e4768a9e3",
"type": "tab",
"label": "Synchronizing loss reasons",
"disabled": false,
"info": "",
"env": []
},
{
"id": "d7cedf884a2668a3",
"type": "comment",
"z": "0246bd7e4768a9e3",
"name": "^^ enter your oee.ai API token",
"info": "You can find your API Token on oee.ai",
"x": 920,
"y": 280,
"wires": []
},
{
"id": "c61e3bb84e3803c3",
"type": "comment",
"z": "0246bd7e4768a9e3",
"name": "Replace the Data input with your source and data transformation",
"info": "",
"x": 510,
"y": 200,
"wires": []
},
{
"id": "d44ed60b56ee05c0",
"type": "inject",
"z": "0246bd7e4768a9e3",
"name": "Data Input",
"props": [],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 360,
"y": 240,
"wires": [
[
"7103451a05d2216e"
]
]
},
{
"id": "a0cc0d031958f91a",
"type": "change",
"z": "0246bd7e4768a9e3",
"name": "Set API Token",
"rules": [
{
"t": "set",
"p": "bearerToken",
"pt": "msg",
"to": "",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 880,
"y": 240,
"wires": [
[
"28ac72dee746f85c"
]
]
},
{
"id": "7103451a05d2216e",
"type": "change",
"z": "0246bd7e4768a9e3",
"name": "Mapping loss reason attributes",
"rules": [
{
"t": "set",
"p": "title-de",
"pt": "msg",
"to": "Abfüllmasse dickflüssig",
"tot": "str"
},
{
"t": "set",
"p": "title-en",
"pt": "msg",
"to": "Filling compound is thick",
"tot": "str"
},
{
"t": "set",
"p": "title-it",
"pt": "msg",
"to": "Il composto di riempimento è denso",
"tot": "str"
},
{
"t": "set",
"p": "title-ro",
"pt": "msg",
"to": "Compusul de umplere este gros",
"tot": "str"
},
{
"t": "set",
"p": "title-cz",
"pt": "msg",
"to": "Plnicí hmota viskózní",
"tot": "str"
},
{
"t": "set",
"p": "valid-from",
"pt": "msg",
"to": "2021-01-01",
"tot": "str"
},
{
"t": "set",
"p": "classification",
"pt": "msg",
"to": "technical",
"tot": "str"
},
{
"t": "set",
"p": "tags",
"pt": "msg",
"to": "[\"material\",\"quality\"]",
"tot": "json"
},
{
"t": "set",
"p": "color",
"pt": "msg",
"to": "red",
"tot": "str"
},
{
"t": "set",
"p": "icon",
"pt": "msg",
"to": "fill-drip",
"tot": "str"
},
{
"t": "set",
"p": "mode",
"pt": "msg",
"to": "performance",
"tot": "str"
},
{
"t": "set",
"p": "target-minutes",
"pt": "msg",
"to": "0",
"tot": "str"
},
{
"t": "set",
"p": "reduces-oee",
"pt": "msg",
"to": "true",
"tot": "bool"
},
{
"t": "set",
"p": "changes-product",
"pt": "msg",
"to": "false",
"tot": "bool"
},
{
"t": "set",
"p": "input-rejects",
"pt": "msg",
"to": "false",
"tot": "bool"
},
{
"t": "set",
"p": "ignore-units",
"pt": "msg",
"to": "false",
"tot": "bool"
},
{
"t": "set",
"p": "parent-loss-reason-title",
"pt": "msg",
"to": "",
"tot": "str"
},
{
"t": "set",
"p": "location",
"pt": "msg",
"to": "",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 610,
"y": 240,
"wires": [
[
"a0cc0d031958f91a"
]
]
},
{
"id": "a68f364c344f2d98",
"type": "comment",
"z": "0246bd7e4768a9e3",
"name": "^^ set loss reason attributes",
"info": "Format your message to the data model of oee.ai\nThen map your message values to the predefined\nmessage values in the change node",
"x": 600,
"y": 280,
"wires": []
},
{
"id": "28ac72dee746f85c",
"type": "subflow:3eaf2cca52ce5808",
"z": "0246bd7e4768a9e3",
"name": "",
"x": 1180,
"y": 240,
"wires": []
}
]