[
    {
        "id": "901c8e8f8d43cbb7",
        "type": "tab",
        "label": "Connecting a SQL DB",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "e4df151a7bc1c137",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Build SQL Query",
        "func": "// create array of machine keys\nconst machineKeys = Object.keys(msg.locationMapping)\n\n// Format machine keys to a comma seperated string\nlet listifiedKeys = `${machineKeys.map(key => `${key}`).join(', ')}`;\n\nmsg.query = `SELECT * FROM table_name WHERE machine_id IN (${listifiedKeys})`;\n\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 350,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "f63c018b4ea9f73f",
        "type": "inject",
        "z": "901c8e8f8d43cbb7",
        "name": "Configuration",
        "props": [
            {
                "p": "locationMapping",
                "v": "{\"MCH2001\":\"883ba0a6-f6d1-4814-bcda-b8518fb12423\",\"MCH2002\":\"a92023f5-0371-47ca-9ff8-7272756e68e3\",\"MCH2003\":\"655efb1e-90c7-41d7-987b-837a337240f1\"}",
                "vt": "json"
            },
            {
                "p": "timestamp",
                "v": "",
                "vt": "date"
            }
        ],
        "repeat": "",
        "crontab": "*/1 0 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 220,
        "wires": [
            [
                "e4df151a7bc1c137"
            ]
        ]
    },
    {
        "id": "c7529de85ac16b2e",
        "type": "split",
        "z": "901c8e8f8d43cbb7",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "property": "payload",
        "x": 670,
        "y": 220,
        "wires": [
            [
                "c90dd0d53d225625",
                "7144c51ebf3a07d9",
                "5c46a03c48378bc4"
            ]
        ]
    },
    {
        "id": "0ab7229eaa0c8b1d",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "SQL Node",
        "info": "",
        "x": 520,
        "y": 220,
        "wires": []
    },
    {
        "id": "72b8a4bf0e26d004",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Is entry new?",
        "func": "const machineId = msg.payload.machine_id;\nconst timestamp = msg.payload.timestamp;\nconst oldTimestamp = flow.get(`${machineId}oldTimestamp`);\n\nif (timestamp !== oldTimestamp) {\n    flow.set(`${machineId}oldTimestamp`, timestamp);\n    return msg;\n}\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 690,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "5f3b159ca5543a98",
        "type": "switch",
        "z": "901c8e8f8d43cbb7",
        "name": "Switch on Machine Identifier",
        "property": "payload.machine_id",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "MCH2001",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "MCH2002",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "MCH2003",
                "vt": "str"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 3,
        "x": 1300,
        "y": 120,
        "wires": [
            [
                "44b76704ca27625a"
            ],
            [
                "66c36876da27c237"
            ],
            [
                "c5fe935eafb3f4fc"
            ]
        ]
    },
    {
        "id": "c90dd0d53d225625",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Build measurements",
        "func": "const INTERVALL_IN_SECONDS = 60\nmsg.from = msg.payload.timestamp\nmsg.to = msg.payload.timestamp // Use this if your count is <1 or you dont want automatic distribution\nmsg.to = msg.payload.timestamp - (INTERVALL_IN_SECONDS * 1000) // Use this if you query in a set intervall or have an accumulating counter and want it to be distributed\n\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1040,
        "y": 120,
        "wires": [
            [
                "5f3b159ca5543a98"
            ]
        ]
    },
    {
        "id": "44b76704ca27625a",
        "type": "oee-ai-connector",
        "z": "901c8e8f8d43cbb7",
        "name": "MCH2001",
        "server": "production",
        "protocol": "wss-443",
        "x": 1610,
        "y": 40,
        "wires": []
    },
    {
        "id": "66c36876da27c237",
        "type": "oee-ai-connector",
        "z": "901c8e8f8d43cbb7",
        "name": "MCH2002",
        "server": "production",
        "protocol": "wss-443",
        "x": 1610,
        "y": 100,
        "wires": []
    },
    {
        "id": "c5fe935eafb3f4fc",
        "type": "oee-ai-connector",
        "z": "901c8e8f8d43cbb7",
        "name": "MCH2003",
        "server": "production",
        "protocol": "wss-443",
        "x": 1610,
        "y": 160,
        "wires": []
    },
    {
        "id": "7144c51ebf3a07d9",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Product changed",
        "func": "const machineId = msg.payload.machine_id;\nconst productId = msg.payload.product_id;\nconst oldProductId = flow.get(`${machineId}oldProductId`);\n\nif (productId !== oldProductId){\n    flow.set(`${machineId}oldProductId`, productId);\n    msg.productId = productId;\n    msg.machineId = machineId;\n    return msg;\n}\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1030,
        "y": 320,
        "wires": [
            [
                "137f502157697867"
            ]
        ]
    },
    {
        "id": "26f2af41978494b7",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Create changeover payload",
        "func": "if (msg.payload.data.length > 0){\n    const productId = msg.payload.data[0].id;\n    const locationId = msg.locationMapping[msg.machineId].locationId;\n    const time = new Date(msg.timestamp).toISOString();\n\n    msg.payload = {\n        \"data\": {\n            \"attributes\": {\n                \"time\": time,\n            },\n            \"relationships\": {\n                \"product\": {\n                    \"data\": {\n                        \"id\": productId,\n                    }\n                },\n                \"location\": {\n                    \"data\": {\n                        \"id\": locationId,\n                    }\n                }\n            }\n        }\n    };\n\n    return msg;\n}else{\n    node.error(`Product with productId \"${msg.productId}\" not found in oee.ai`);\n}\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1660,
        "y": 320,
        "wires": [
            [
                "e0c243a0daa0c10f"
            ]
        ]
    },
    {
        "id": "137f502157697867",
        "type": "http request",
        "z": "901c8e8f8d43cbb7",
        "name": "GET Product for Article ID",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.oee.ai/products?filter[code-or-description]={{{productId}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "bearer",
        "senderr": false,
        "headers": [],
        "x": 1290,
        "y": 320,
        "wires": [
            [
                "26f2af41978494b7"
            ]
        ]
    },
    {
        "id": "e0c243a0daa0c10f",
        "type": "mqtt out",
        "z": "901c8e8f8d43cbb7",
        "name": "Send Changeover",
        "topic": "",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "",
        "x": 1930,
        "y": 320,
        "wires": []
    },
    {
        "id": "e363d841ceef487b",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Replace with oee.ai sensor information",
        "info": "",
        "x": 1700,
        "y": 220,
        "wires": []
    },
    {
        "id": "af515eb18929c95a",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Add MQTT Details",
        "info": "",
        "x": 1940,
        "y": 380,
        "wires": []
    },
    {
        "id": "e76053f379176fab",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Add API-Token",
        "info": "",
        "x": 1270,
        "y": 360,
        "wires": []
    },
    {
        "id": "5c46a03c48378bc4",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Loss Reason detected",
        "func": "const machineId = msg.payload.machine_id;\nconst machineState = msg.payload.machine_state;\nconst oldMachineState = flow.get(`${machineId}oldMachineState`);\n\n\nif (machineState !== oldMachineState){\n    msg.machineState = machineState;\n    msg.locationId = msg.locationMapping[machineId].locationId;\n    msg.machineId = machineId;\n    flow.set(`${machineId}machineState`, machineState);\n\n    return msg;\n}\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1040,
        "y": 500,
        "wires": [
            [
                "84b4f6668f75c205"
            ]
        ]
    },
    {
        "id": "84b4f6668f75c205",
        "type": "http request",
        "z": "901c8e8f8d43cbb7",
        "name": "GET Loss Reasons",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.oee.ai/loss-reasons?filter[locations]={{{locationId}}}",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "bearer",
        "senderr": false,
        "headers": [],
        "x": 1270,
        "y": 500,
        "wires": [
            [
                "f641ac63c0667b9e"
            ]
        ]
    },
    {
        "id": "f641ac63c0667b9e",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Save Loss Reason ID ",
        "func": "const lossReasonId = msg.payload.data.find(item => item.attributes.details?.machineState === msg.machineState)?.id || null;\n\n// we save it with the location ID so its easier to match on the incoming loss alerts\nflow.set(`${msg.locationId}lossReasonId`, lossReasonId);\n\nif(msg.machineState && lossReasonId === null){\n    node.error(`Loss Reason with machineState \"${msg.machineState}\" not found in oee.ai`);\n}",
        "outputs": 0,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1640,
        "y": 500,
        "wires": []
    },
    {
        "id": "21b7325c1f731f54",
        "type": "mqtt in",
        "z": "901c8e8f8d43cbb7",
        "name": "Listen for Loss Alerts",
        "topic": " ",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 1030,
        "y": 640,
        "wires": [
            [
                "4ccc3c62c54fbbcf"
            ]
        ]
    },
    {
        "id": "4ccc3c62c54fbbcf",
        "type": "function",
        "z": "901c8e8f8d43cbb7",
        "name": "Create payload",
        "func": "const locationId = msg.payload.data.relationships.location.data.id;\nconst lossAlertHasLossReason = msg.payload.data.relationships[\"loss-reason\"]?.data?.id;\nconst lossReasonId = flow.get(`${locationId}lossReasonId`);\nconst lossAlertId = msg.payload.data.id;\n\nif (!lossAlertHasLossReason && lossReasonId){\n    msg.payload = {\n        \"data\": {\n            \"id\": lossAlertId,\n            \"relationships\": {\n                \"loss-reason\": {\n                    \"data\": {\n                        \"id\": lossReasonId\n                    }\n                }\n            }\n        }\n    };\n\n    return msg;\n}\n\nif (!lossAlertHasLossReason && lossReasonId === null ){\n    node.warn(`No UserState for loss alert \"${lossAlertId}\"`);\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1260,
        "y": 640,
        "wires": [
            [
                "2172febdd78e2f57"
            ]
        ]
    },
    {
        "id": "2172febdd78e2f57",
        "type": "mqtt out",
        "z": "901c8e8f8d43cbb7",
        "name": "Send Alert Reason",
        "topic": "",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "",
        "x": 1630,
        "y": 640,
        "wires": []
    },
    {
        "id": "13e741079e2f04c0",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Add API-Token",
        "info": "",
        "x": 1270,
        "y": 540,
        "wires": []
    },
    {
        "id": "196ce0f652f62656",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^Optional validity check",
        "info": "",
        "x": 730,
        "y": 360,
        "wires": []
    },
    {
        "id": "8b97ac3dd6983c00",
        "type": "switch",
        "z": "901c8e8f8d43cbb7",
        "name": "Data up to date?",
        "property": "payload.data_up_to_date",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "1",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 710,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "14749a70ee842810",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Add MQTT Details",
        "info": "",
        "x": 1640,
        "y": 700,
        "wires": []
    },
    {
        "id": "e043f1ef64fb06a4",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^ Add MQTT Details",
        "info": "",
        "x": 1040,
        "y": 700,
        "wires": []
    },
    {
        "id": "cd42aacb94ae34ae",
        "type": "comment",
        "z": "901c8e8f8d43cbb7",
        "name": "^^Optional validity check",
        "info": "",
        "x": 150,
        "y": 260,
        "wires": []
    }
]