{
  "custom": {},
  "params": {
    "cellPath": "",
    "equipmentPath": "",
    "reason": ""
  },
  "propConfig": {
    "params.cellPath": {
      "onChange": {
        "enabled": null,
        "script": "\t\n\tunplannedEquipmentStateList \u003d system.mes.getEquipmentStateOptions(currentValue.value,\u0027\u0027,\u0027Unplanned Downtime\u0027)\n\tplannedEquipmentStateList \u003d system.mes.getEquipmentStateOptions(currentValue.value,\u0027\u0027,\u0027Planned Downtime\u0027)\t\n\t\n\tdef createTreeMenu(MESObjectList):\n\t\tstorage \u003d []\n\t\tfor MESEquipmentState in  MESObjectList:\n\t\t\tchildMESObjectCollection \u003d MESEquipmentState.getChildCollection()\n\t\t\tif not(childMESObjectCollection.isEmpty()):\n\t\t\t\tchildMESObjectLinkList \u003d childMESObjectCollection.getList()\n\t\t\t\tchildMESObjectList \u003d system.mes.object.list.createList()\n\t\t\t\tfor MESObject in childMESObjectLinkList:\n\t\t\t\t\tchildMESObjectList.add(MESObject.getMESObject())\n\t\t\t\tchoiceWithNav \u003d {\n\t\t\t\t\t\"target\": \"\",\n\t\t\t\t\t\"items\":createTreeMenu(childMESObjectList),\n\t\t\t\t\t\"navIcon\": {\n\t\t\t\t\t\"path\": \"material/chevron_right\"\n\t\t\t\t\t},\n\t\t\t\t\t\"label\": {\n\t\t\t\t\t\"text\": MESEquipmentState.getName().encode(\"utf-8\"),\n\t\t\t\t\t\"icon\": {\n\t\t\t\t\t  \"path\": \"material/list\"\n\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"visible\": \"true\",\n\t\t\t\t\t\"enabled\": \"true\",\n\t\t\t\t\t\"showHeader\": \"true\",\n\t\t\t\t\t\"downtimeReason\" :  MESEquipmentState.getStateCode(),\n\t\t\t\t\t\"style\": {\n\t\t\t\t\t\"classes\": \"\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstorage.append(choiceWithNav)\t\n\t\t\telse:\n\t\t\t\tchoiceWithNoNav \u003d {\n\t\t\t\t\t\"target\": \"\",\n\t\t\t\t\t\"items\": [],\n\t\t\t\t\t\"navIcon\": {\n\t\t\t\t\t\"path\": \"\"\n\t\t\t\t\t},\n\t\t\t\t\t\"label\": {\n\t\t\t\t\t\"text\": MESEquipmentState.getName().encode(\"utf-8\"),\n\t\t\t\t\t\"icon\": {\n\t\t\t\t\t  \"path\": \"\"\n\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"visible\": \"true\",\n\t\t\t\t\t\"enabled\": \"true\",\n\t\t\t\t\t\"showHeader\": \"true\",\n\t\t\t\t\t\"downtimeReason\" :  MESEquipmentState.getStateCode() ,\n\t\t\t\t\t\"style\": {\n\t\t\t\t\t\"classes\": \"\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstorage.append(choiceWithNoNav)\n\t\treturn storage\n\t\n\tunplan \u003d {\n\t\t\"target\": \"\",\n\t\t\"items\":createTreeMenu(unplannedEquipmentStateList),\n\t\t\"navIcon\": {\n\t\t\"path\": \"material/chevron_right\"\n\t\t},\n\t\t\"label\": {\n\t\t\"text\": \"Unplanned Downtime\",\n\t\t\"icon\": {\n\t\t  \"path\": \"material/list\"\n\t\t}\n\t\t},\n\t\t\"visible\": \"true\",\n\t\t\"enabled\": \"true\",\n\t\t\"showHeader\": \"true\",\n\t\t\"style\": {\n\t\t\"classes\": \"\"\n\t\t}\n\t}\n\tplan \u003d {\n\t\t\"target\": \"\",\n\t\t\"items\":createTreeMenu(plannedEquipmentStateList),\n\t\t\"navIcon\": {\n\t\t\"path\": \"material/chevron_right\"\n\t\t},\n\t\t\"label\": {\n\t\t\"text\": \"Planned Downtime\",\n\t\t\"icon\": {\n\t\t  \"path\": \"material/list\"\n\t\t}\n\t\t},\n\t\t\"visible\": \"true\",\n\t\t\"enabled\": \"true\",\n\t\t\"showHeader\": \"true\",\n\t\t\"style\": {\n\t\t\"classes\": \"\"\n\t\t}\n\t}\n\tsource \u003d []\n\tsource.append(unplan)\n\tsource.append(plan)\n\tself.getChild(\"root\").getChild(\"MenuTree\").props.items \u003d source\n\t\t\t"
      },
      "paramDirection": "input",
      "persistent": true
    },
    "params.equipmentPath": {
      "paramDirection": "input",
      "persistent": true
    },
    "params.reason": {
      "paramDirection": "inout",
      "persistent": true
    }
  },
  "props": {
    "loading": {
      "mode": "blocking"
    }
  },
  "root": {
    "children": [
      {
        "children": [
          {
            "meta": {
              "name": "Start Label"
            },
            "props": {
              "style": {
                "borderStyle": "none",
                "borderWidth": 1,
                "marginBottom": 0,
                "marginLeft": 5,
                "marginRight": 5,
                "marginTop": 5,
                "paddingBottom": 5,
                "paddingLeft": 5,
                "paddingRight": 5,
                "paddingTop": 5
              },
              "text": "Start Time \u0026 Date:"
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "Start Input"
            },
            "propConfig": {
              "props.maxDate": {
                "binding": {
                  "config": {
                    "expression": "now(1000)"
                  },
                  "type": "expr"
                }
              },
              "props.value": {
                "onChange": {
                  "enabled": null,
                  "script": "\tif(currentValue.value is not None):\n\t\tif(system.date.getSecond(currentValue.value) !\u003d 0):\n\t\t\thour \u003d system.date.getHour24(currentValue.value)\n\t\t\tminute \u003d system.date.getMinute(currentValue.value)\n\t\t\tsecond \u003d 0\n\t\t\trevisedDate \u003d system.date.getDate(system.date.getYear(currentValue.value), system.date.getMonth(currentValue.value),system.date.getDayOfMonth(currentValue.value))\n\t\n\t\t\trevisedTime \u003d system.date.setTime(revisedDate,hour,minute,second)\n\t\t\tself.props.value \u003d revisedTime"
                }
              }
            },
            "props": {
              "formattedValue": "Mar 31, 2022 2:00 AM",
              "inputProps": {
                "style": {
                  "marginBottom": 5,
                  "marginTop": 5
                }
              },
              "value": {
                "$": [
                  "ts",
                  0,
                  1648779948124
                ],
                "$ts": 1648717200000
              }
            },
            "type": "ia.input.date-time-input"
          },
          {
            "meta": {
              "name": "End Label"
            },
            "props": {
              "style": {
                "borderStyle": "none",
                "borderWidth": 1,
                "marginLeft": 5,
                "marginRight": 5,
                "marginTop": 5,
                "paddingBottom": 5,
                "paddingLeft": 5,
                "paddingRight": 5,
                "paddingTop": 5
              },
              "text": "End Time \u0026 Date:"
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "End Input"
            },
            "propConfig": {
              "props.maxDate": {
                "binding": {
                  "config": {
                    "expression": "now(1000)"
                  },
                  "type": "expr"
                }
              },
              "props.minDate": {
                "binding": {
                  "config": {
                    "path": "../Start Input.props.value"
                  },
                  "type": "property"
                }
              }
            },
            "props": {
              "formattedValue": "Mar 31, 2022 2:01 AM",
              "inputProps": {
                "style": {
                  "marginBottom": 5,
                  "marginTop": 5
                }
              },
              "value": {
                "$": [
                  "ts",
                  192,
                  1658438199645
                ],
                "$ts": 1648717260000
              }
            },
            "type": "ia.input.date-time-input"
          },
          {
            "meta": {
              "name": "Duration Label"
            },
            "propConfig": {
              "props.text": {
                "binding": {
                  "config": {
                    "path": "../End Input.props.value"
                  },
                  "transforms": [
                    {
                      "expression": "\"Duration: \" + toInt(dateDiff(toDate({../Start Input.props.value} ), toDate({value}), \"minute\")) + \" Minutes\"",
                      "type": "expression"
                    }
                  ],
                  "type": "property"
                }
              }
            },
            "props": {
              "style": {
                "borderStyle": "none",
                "borderWidth": 1,
                "marginBottom": 0,
                "marginLeft": 5,
                "marginRight": 5,
                "marginTop": 5,
                "paddingBottom": 5,
                "paddingLeft": 5,
                "paddingRight": 5,
                "paddingTop": 5
              }
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "DurationNumericEntryField"
            },
            "position": {
              "basis": "32px"
            },
            "propConfig": {
              "props.value": {
                "binding": {
                  "config": {
                    "expression": "toInt(dateDiff(toDate({../Start Input.props.value} ), toDate({../End Input.props.value}), \"minute\"))"
                  },
                  "type": "expr"
                },
                "onChange": {
                  "enabled": null,
                  "script": "\t\n\tif (currentValue.value \u003c\u003d 0):\n\t\tcurrentValue.value \u003d 1\n\t\n\tif (self.getSibling(\"Start Input\").props.value is not None):\n\t\ttest \u003d system.date.addMinutes(self.getSibling(\"Start Input\").props.value,int(currentValue.value))\n\t\tif (system.date.isBefore(test,self.getSibling(\"Start Input\").props.maxDate)):\n\t\t\tself.getSibling(\"End Input\").props.value \u003d test\n\t\telse:\n\t\t\tself.getSibling(\"End Input\").props.value \u003d self.getSibling(\"Start Input\").props.maxDate\n\t\t\t#system.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"End date \u0026 time exceeds the current time. \"}, title \u003d \"Error\")\n\n\t\t"
                },
                "persistent": true
              }
            },
            "props": {
              "format": "0,0",
              "inputBounds": {
                "minimum": 1
              },
              "value": 1
            },
            "type": "ia.input.numeric-entry-field"
          }
        ],
        "meta": {
          "name": "Header"
        },
        "props": {
          "alignContent": "space-around",
          "alignItems": "center",
          "direction": "column",
          "justify": "space-around",
          "wrap": "wrap"
        },
        "type": "ia.container.flex"
      },
      {
        "events": {
          "component": {
            "onItemClicked": {
              "config": {
                "script": "\t\n\n\tdef transverse(list,name):\n\t\tfor object in list:\n\t\t\tif (object[\"label\"][\"text\"] \u003d\u003d name and \"downtimeReason\" in object.keys() ):\n\t\t\t\treturn object[\"downtimeReason\"]\n\t\t\telif( len( object[\"items\"]) !\u003d 0 ):\n\t\t\t\tdeepResult \u003d (transverse(object[\"items\"],name))\n\t\t\t\tif (deepResult !\u003d None):\n\t\t\t\t\treturn (deepResult)\n\t\n\tcode \u003d  transverse(self.props.items,event.label)\n\tif(isinstance(code,int)):\n\t\tself.view.params.reason \u003d  code\n\t\tself.parent.getChild(\"Bottom\").getChild(\"Reason Label\").props.text \u003d \"Selected Reason: \" + event.label"
              },
              "scope": "G",
              "type": "script"
            }
          }
        },
        "meta": {
          "name": "MenuTree"
        },
        "position": {
          "grow": 1
        },
        "props": {
          "items": null
        },
        "type": "ia.navigation.menutree"
      },
      {
        "children": [
          {
            "meta": {
              "name": "Reason Label"
            },
            "props": {
              "style": {
                "marginRight": 150
              },
              "text": "Selected Reason: "
            },
            "type": "ia.display.label"
          },
          {
            "events": {
              "component": {
                "onActionPerformed": {
                  "config": {
                    "script": "\t\n\tstart_date_timestamp \u003d self.parent.parent.getChild(\"Header\").getChild(\"Start Input\").props.value\n\tend_date_timestamp \u003d  self.parent.parent.getChild(\"Header\").getChild(\"End Input\").props.value\n\tequipmentPath \u003d self.view.params.equipmentPath\n\tcellPath \u003d self.view.params.cellPath\n\treasonID \u003d self.view.params.reason\n\tcompareTimeStamp \u003d None\n\n\trunningEquipmentState \u003d system.mes.getEquipmentStateOptions(cellPath,\u0027\u0027,\u0027\u0027)\n\tresult \u003d False\n\trunningStateCode \u003d 0\n\t\n\t#Checks if the cell has a running equipment state and prompts an exception error.\n\tfor index,test in enumerate(runningEquipmentState):\n\t\tresult \u003d (test.getName().encode(\"utf-8\").lower() \u003d\u003d \u0027running\u0027) \n\t\tif result:\t\n\t\t\trunningStateCode \u003d test.getStateCode()\n\t\t\tbreak\n\ttry:\n\t\tcompareTimeStamp \u003d system.mes.getTagCollectorLastTimeStamp(cellPath,\"Equipment State\",\"\")\n\texcept: #Clean Installation Scenario\n\t\tresponse \u003d system.mes.getCurrentOperation(equipmentPath)\n\t\toperationBeginTime \u003d response.getPropertyValue(\"BeginDateTime\")\n\t\tsystem.mes.oee.addEquipmentStateValue(cellPath, operationBeginTime, runningStateCode)\n\t\tsystem.mes.oee.updateEquipmentStateValue(equipmentPath.replace(\u0027[MES]\u0027,\u0027\u0027), cellPath, cellPath, operationBeginTime, runningStateCode)\n\t\tcompareTimeStamp \u003d system.mes.getTagCollectorLastTimeStamp(cellPath,\"Equipment State\",\"\")\n\tif not result:\n\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"This program requires a running equipment state.\"}, title \u003d \"Error\")\n\t\traise NotImplementedError(\"This program requires a running state\")\n\t\t\n\tif(system.mes.getTagCollectorLastValue(cellPath,\"Equipment Operation UUID\",\"\") !\u003d \u0027\u0027):\n\t\tlineStartTime \u003d system.mes.getTagCollectorLastTimeStamp(cellPath,\"Equipment Operation UUID\",\"\")\n\t\t## if the last timestamp of the equipment state is before the timestamp of the production run\n\t\t##set the comparsion time stamp to the production run start time stamp\n\t\tif(system.date.isBefore(compareTimeStamp,lineStartTime)): compareTimeStamp \u003d lineStartTime \n\t\tif(start_date_timestamp is not None and end_date_timestamp is not None and self.view.params.reason  !\u003d \"\"):\n\t\t\tif( system.date.isAfter(start_date_timestamp,compareTimeStamp)):\n\t\t\t\tsystem.mes.oee.addEquipmentStateValue(cellPath, start_date_timestamp, int(reasonID))\n\t\t\t\tsystem.mes.oee.updateEquipmentStateValue(equipmentPath.replace(\u0027[MES]\u0027,\u0027\u0027), cellPath, cellPath, start_date_timestamp, int(reasonID))\n\t\t\t\t\n\t\t\t\tsystem.mes.oee.addEquipmentStateValue(cellPath, end_date_timestamp, runningStateCode)\n\t\t\t\tsystem.mes.oee.updateEquipmentStateValue(equipmentPath.replace(\u0027[MES]\u0027,\u0027\u0027), cellPath, cellPath, end_date_timestamp, runningStateCode)\n\t\t\t\t\n\t\t\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\":\"Downtime Reason is Added \"}, title \u003d \"Success\")\n\t\t\telif not (system.date.isAfter(start_date_timestamp,compareTimeStamp)):\n\t\t\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"You could only add a downtime reason after the most recent downtime event or after a production run.\"}, title \u003d \"Error\")\n\t\telse:\n\t\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"Please input the dates and reason.\"}, title \u003d \"Error\")\n\telse:\n\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"Needs a valid production run\"}, title \u003d \"Error\")\n\t\n\t\t\t\t\n\t\t\t\t\n\t\t"
                  },
                  "scope": "G",
                  "type": "script"
                }
              }
            },
            "meta": {
              "name": "Add Event Button"
            },
            "props": {
              "style": {
                "classes": "Buttons/Medium_Button",
                "height": "64px",
                "marginBottom": 11,
                "marginRight": 11,
                "width": "100px"
              },
              "text": "Add Event"
            },
            "type": "ia.input.button"
          }
        ],
        "meta": {
          "name": "Bottom"
        },
        "props": {
          "justify": "flex-end"
        },
        "type": "ia.container.flex"
      }
    ],
    "events": {
      "system": {
        "onStartup": {
          "config": {
            "script": "\tif( self.view.params.cellPath !\u003d \u0027\u0027):\n\t\tif( system.mes.getTagCollectorLastValue(self.view.params.cellPath,\"Equipment Operation UUID\",\"\") !\u003d \u0027\u0027):\n\t\t\tself.getChild(\"Header\").getChild(\"Start Input\").props.value \u003d system.date.addMinutes(system.date.now(),-1)\n\t\t\tself.getChild(\"Header\").getChild(\"End Input\").props.value \u003d system.date.now()\n\t\telse:\n\t\t\tsystem.perspective.openPopup(\"InfoPane\",\"Popup/InfoPane\",params \u003d {\"action\": \"Needs a valid production run\"}, title \u003d \"Error\")\n\t"
          },
          "scope": "G",
          "type": "script"
        }
      }
    },
    "meta": {
      "name": "root"
    },
    "props": {
      "direction": "column",
      "style": {
        "backgroundColor": "#FFFFFF"
      }
    },
    "type": "ia.container.flex"
  }
}