UNPKG

@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
[ { "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": [] } ]