{ "custom": {}, "params": {}, "props": { "defaultSize": { "height": 60, "width": 1600 } }, "root": { "children": [ { "events": { "component": { "onDexClick": { "config": { "script": "\twindow \u003d \"Popups/DeviceWrapper\"\n\tparams \u003d {\n\t\t\"deviceType\": event.type.split(\".\")[-1],\n\t\t\"props\": event.props,\n\t\t\"meta\": event.meta,\n\t\t\"custom\": event.custom\n\t}\n\t# Change device type if available:\n\ttry:\n\t\ttagPath \u003d \"[default]\"+params[\"props\"].status.tagPath+\"/Parameters.DeviceType\"\n\t\tvalue \u003d system.tag.readBlocking([tagPath])[0]\n\t\tif value.quality.isGood():\n\t\t\tparams[\"deviceType\"] \u003d value.value\n\texcept:\n\t\tpass\n\t# Open window, if one is specified:\n\tid \u003d event.props.status.tagPath\n\ttitle \u003d utils.extractName(event.props.status)\n\tif self.session.custom.isMobile:\n\t\tsystem.perspective.navigate(view\u003dwindow, params\u003dparams)\n\telse:\n\t\tsystem.perspective.openPopup(id, window, params, title, resizable\u003dTrue)" }, "scope": "G", "type": "script" }, "onDexComponentClick": { "config": { "script": "\tparams \u003d {\n\t\t\"type\": event.type,\n\t\t\"props\": event.props,\n\t\t\"meta\": event.meta,\n\t\t\"custom\": event.custom\n\t}\n\tsystem.perspective.openPopup(event.meta.name, \"Windows/Popup/Conveyor\", params)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "DexManager" }, "position": { "height": 10, "width": 10 }, "propConfig": { "props.config": { "binding": { "config": { "path": "session.custom.dexmanager.config" }, "type": "property" } }, "props.highlight": { "binding": { "config": { "path": "session.custom.dexmanager.highlight" }, "enabled": false, "type": "property" } }, "props.override": { "binding": { "config": { "expression": "if({session.custom.heatmapSettings.enabled},\r\n\t{session.custom.heatmapSettings.data},\r\n\t0\r\n)" }, "transforms": [ { "code": "\tif value \u003d\u003d 0:\n\t\treturn {}\n\telse:\n\t\tdata \u003d value\n\t\taggregate \u003d {}\n\t\taggregate_conv \u003d {}\n\t\tmaxCount \u003d 0\n\t\t# Perform aggregates:\n\t\tfor r in range(data.getRowCount()):\n\t\t\tdevice \u003d data.getValueAt(r, \"device\")\n\t\t\tcount \u003d data.getValueAt(r, \"count\")\n\t\t\t# Add count to device:\n\t\t\taggregate[device] \u003d aggregate[device] + count if device in aggregate else count\n\t\t\t# Check if new max:\n\t\t\tmaxCount \u003d aggregate[device] if aggregate[device] \u003e maxCount else maxCount\n\t\t\t# Retrieve conveyor name:\n\t\t\tconv \u003d device.split(\".\")[0]\n\t\t\t# Add count to conveyor:\n\t\t\taggregate_conv[conv] \u003d aggregate_conv[conv] + count if conv in aggregate_conv else count\n\t\t\t# Check if new max:\n\t\t\tmaxCount \u003d aggregate_conv[conv] if aggregate_conv[conv] \u003e maxCount else maxCount\n\t\t# Convert to overrides:\n\t\tresult \u003d {}\n\t\tfor k, v in aggregate.items():\n\t\t\tresult[k] \u003d {\n\t\t\t\t\"tooltip\": k+\"\u003cbr\u003eCount: \"+str(v),\n\t\t\t\t\"color\": \"#FF\"+(format(255 - int(round(255 * v / maxCount)), \u0027x\u0027).zfill(2)*2)\n\t\t\t}\n\t\tfor k, v in aggregate_conv.items():\n\t\t\tresult[\"conveyor_\"+k] \u003d {\n\t\t\t\t\"tooltip\": k+\"\u003cbr\u003eCount: \"+str(v),\n\t\t\t\t\"color\": \"#FF\"+(format(255 - int(round(255 * v / maxCount)), \u0027x\u0027).zfill(2)*2)\n\t\t\t}\n\t\treturn result", "type": "script" } ], "type": "expr" } }, "props.overrideAll.config.enableHighlight": { "binding": { "config": { "path": "session.custom.heatmapSettings.enabled" }, "enabled": false, "transforms": [ { "fallback": null, "inputType": "scalar", "mappings": [ { "input": true, "output": false } ], "outputType": "scalar", "type": "map" } ], "type": "property" } }, "props.overrideAll.config.isClickable": { "binding": { "config": { "path": "session.custom.heatmapSettings.enabled" }, "transforms": [ { "fallback": null, "inputType": "scalar", "mappings": [ { "input": true, "output": false } ], "outputType": "scalar", "type": "map" } ], "type": "property" } }, "props.overrideAll.status.color": { "binding": { "config": { "path": "session.custom.heatmapSettings.enabled" }, "transforms": [ { "fallback": null, "inputType": "scalar", "mappings": [ { "input": true, "output": "#FFF" } ], "outputType": "scalar", "type": "map" } ], "type": "property" } }, "props.overrideAll.status.tooltip": { "binding": { "config": { "path": "session.custom.heatmapSettings.enabled" }, "transforms": [ { "fallback": null, "inputType": "scalar", "mappings": [ { "input": true, "output": "" } ], "outputType": "scalar", "type": "map" } ], "type": "property" } }, "props.show": { "binding": { "config": { "struct": { "heatmapDevices": "{session.custom.heatmapSettings.devices}", "heatmapEnabled": "{session.custom.heatmapSettings.enabled}", "show": "{session.custom.dexmanager.show}" }, "waitOnAll": true }, "transforms": [ { "code": "\tif value.heatmapEnabled:\n\t\tdevices \u003d [v.value for v in value.heatmapDevices]\n\t\treturn {\n\t\t\t\"Beacons\": \"Beacons\" in devices,\n\t\t\t\"ConveyorLabels\": True,\n\t\t\t\"ConveyorPatterns\": False,\n\t\t\t\"Conveyors\": True,\n\t\t\t\"DivertPaddles\": True,\n\t\t\t\"EIPs\": \"EIPs\" in devices,\n\t\t\t\"Encoders\": \"Encoders\" in devices,\n\t\t\t\"Estops\": \"Estops\" in devices,\n\t\t\t\"Gaylords\": True,\n\t\t\t\"LimitSwitches\": \"LimitSwitches\" in devices,\n\t\t\t\"MCPs\": \"MCPs\" in devices,\n\t\t\t\"PhotoEyes\": \"PhotoEyes\" in devices,\n\t\t\t\"PushButtons\": \"PushButtons\" in devices,\n\t\t\t\"Scanners\": \"Scanners\" in devices,\n\t\t\t\"VFDs\": \"VFDs\" in devices\n\t\t}\n\telse:\n\t\treturn value.show#{k: v.value for k, v in value.show.iteritems()}", "type": "script" } ], "type": "expr-struct" } } }, "props": { "overrideAll": { "config": { "enableHighlight": null }, "status": {} } }, "type": "dex.controller.manager" }, { "meta": { "name": "Label_Date" }, "position": { "height": 28, "width": 90 }, "propConfig": { "props.text": { "binding": { "config": { "fallbackDelay": 2.5, "mode": "direct", "tagPath": "[default]Gateway/Date" }, "type": "tag" } } }, "props": { "style": { "borderBottomColor": "#000", "borderBottomStyle": "solid", "borderBottomWidth": "1px", "classes": "Docked/StatusText" } }, "type": "ia.display.label" }, { "meta": { "name": "Label_Time" }, "position": { "height": 28, "width": 90, "y": 28 }, "propConfig": { "props.text": { "binding": { "config": { "fallbackDelay": 2.5, "mode": "direct", "tagPath": "[default]Gateway/Time" }, "type": "tag" } } }, "props": { "style": { "borderTopColor": "#000", "borderTopStyle": "solid", "borderTopWidth": "1px", "classes": "Docked/StatusText" } }, "type": "ia.display.label" }, { "meta": { "name": "Label_Site" }, "position": { "height": 56, "width": 90, "x": 88 }, "propConfig": { "props.text": { "binding": { "config": { "expression": "{[default]Gateway/Parameters.Customer}" }, "transforms": [ { "code": "\treturn system.project.getProjectName() + \" \" + value", "type": "script" } ], "type": "expr" } } }, "props": { "style": { "classes": "Docked/StatusText" } }, "type": "ia.display.label" }, { "meta": { "name": "Label_IPAddr" }, "position": { "height": 28, "width": 120, "x": 176 }, "propConfig": { "props.text": { "binding": { "config": { "path": "session.props.host" }, "type": "property" } } }, "props": { "style": { "borderBottomColor": "#000", "borderBottomStyle": "solid", "borderBottomWidth": "1px", "classes": "Docked/StatusText" } }, "type": "ia.display.label" }, { "events": { "dom": { "onClick": { "config": { "script": "\tif self.session.props.auth.user.userName is not None:\n\t\t#system.perspective.print(\"Logout\")\n\t\tsystem.perspective.logout()\n\telse:\n\t\t#system.perspective.print(\"Login\")\n\t\tsystem.perspective.login()" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Label_User" }, "position": { "height": 28, "width": 120, "x": 176, "y": 28 }, "propConfig": { "props.text": { "binding": { "config": { "expression": "coalesce({session.props.auth.user.userName}, \"LOGIN\")" }, "type": "expr" } } }, "props": { "style": { "borderTopColor": "#000", "borderTopStyle": "solid", "borderTopWidth": "1px", "classes": "Docked/StatusText", "cursor": "pointer" } }, "type": "ia.display.label" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/help" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_Legend" }, "position": { "height": 52, "width": 100, "x": 988, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Help" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "script": "\t# Get the current gateway address dynamically\n\tcurrentHost = self.session.props.gateway.address\n\t\n\t# Build the full navigation URL\n\tnavigateUrl = currentHost + \"/data/perspective/client/BNA8_autStand\"\n\t\n\t# Navigate\n\tsystem.perspective.navigate(url=navigateUrl)\n" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Nav_Testing", "tooltip": { "enabled": true, "text": "Go to autStand project" } }, "position": { "height": 52, "width": 150, "x": 1600, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Navigate to autStand" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": [ { "config": { "page": "/" }, "scope": "C", "type": "nav" }, { "config": { "params": { "view": "Windows/Graphics/Overview" }, "view": "Windows/GraphicsWrapper" }, "scope": "C", "type": "nav" } ] } }, "meta": { "name": "Nav_Overview" }, "position": { "height": 52, "width": 100, "x": 356, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Overview" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "action": "Toggle", "type": "Page" }, "scope": "C", "type": "fullscreen" } } }, "meta": { "name": "Nav_ToggleFull" }, "position": { "height": 52, "width": 100, "x": 1090, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Fullscreen" }, "type": "ia.input.button" }, { "meta": { "name": "Label_Status" }, "position": { "height": 56, "width": 60, "x": 294 }, "props": { "style": { "classes": "Docked/StatusText" } }, "type": "ia.display.label" }, { "meta": { "name": "Status" }, "position": { "height": 40, "width": 40, "x": 304, "y": 8 }, "propConfig": { "props.elements[0].fill.paint": { "binding": { "config": { "fallbackDelay": 2.5, "mode": "direct", "tagPath": "[default]Gateway/CommStatusColor" }, "type": "tag" } } }, "props": { "elements": [ { "cx": 20, "cy": 20, "fill": {}, "r": 19, "stroke": { "paint": "#000", "width": 2 }, "style": {}, "type": "circle" } ], "preserveAspectRatio": "none", "viewBox": "0 0 40 40" }, "type": "ia.shapes.svg" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/alarms/active" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_ActiveAlarms" }, "position": { "height": 52, "width": 100, "x": 458, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Active Alarms" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/alarms/hitlist" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_HitList" }, "position": { "height": 25, "width": 100, "x": 560, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Hit List" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/alarms/history" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_History" }, "position": { "height": 25, "width": 100, "x": 560, "y": 29 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "History" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/statistics" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_Statistics" }, "position": { "height": 52, "width": 100, "x": 662, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Statistics" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/status" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_Status" }, "position": { "height": 52, "width": 100, "x": 764, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Status" }, "type": "ia.input.button" }, { "meta": { "name": "TooltipOverlay" }, "position": { "height": 40, "width": 40, "x": 304, "y": 8 }, "propConfig": { "props.status.tooltip": { "binding": { "config": { "fallbackDelay": 2.5, "mode": "direct", "tagPath": "[default]Gateway/CommStatusTooltip" }, "type": "tag" } } }, "props": { "status": {} }, "type": "dex.display.tooltipoverlay" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/custom-reports" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_CustomReports" }, "position": { "height": 52, "width": 100, "x": 1192, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Custom Reports" }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/config" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_Config" }, "position": { "height": 52, "width": 100, "x": 1294, "y": 2 }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "session.props.auth.user.roles" }, "transforms": [ { "code": "\troles \u003d [\"Administrator\", \"Developer\", \"Supervisor\", \"Maintenance\"]\n\treturn value !\u003d None and len(value) \u003e 0 and len([i for i in value if i in roles]) \u003e 0", "type": "script" } ], "type": "property" }, "persistent": true } }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Config", "visible": true }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "script": "\twindow\u003d\"Popups/Heatmap/Config\"\n\tif self.session.custom.isMobile:\n\t\tsystem.perspective.navigate(view\u003dwindow)\n\telse:\n\t\tsystem.perspective.openPopup(\"HeatmapSettings\", window, title\u003d\"Heatmap Configuration\", modal\u003dTrue, overlayDismiss\u003dTrue)" }, "scope": "G", "type": "script" } } }, "meta": { "name": "Nav_AlarmHeatmap" }, "position": { "height": 52, "width": 100, "x": 1498, "y": 2 }, "propConfig": { "meta.visible": { "binding": { "config": { "path": "session.props.auth.user.roles" }, "transforms": [ { "code": "\troles \u003d [\"Administrator\", \"Developer\"]\n\treturn value !\u003d None and len(value) \u003e 0 and len([i for i in value if i in roles]) \u003e 0", "type": "script" } ], "type": "property" }, "persistent": true }, "props.enabled": { "binding": { "config": { "expression": "!{session.custom.heatmapSettings.enabled}" }, "type": "expr" }, "persistent": true } }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Alarm Heatmap", "visible": true }, "type": "ia.input.button" }, { "meta": { "name": "LabelHeatMap", "visible": false }, "position": { "height": 56, "width": 732, "x": 458 }, "propConfig": { "meta.visible": { "binding": { "config": { "path": "session.custom.heatmapSettings.enabled" }, "type": "property" }, "persistent": true }, "props.style.backgroundColor": { "binding": { "config": { "expression": "if({session.custom.heatmapSettings.enabled},\r\n\tif({[default]Gateway/ToggleTag},\r\n\t\t\"#FF0\",\r\n\t\t\"#F00\"\r\n\t),\r\n\t\"#AAA\"\r\n)" }, "type": "expr" } } }, "props": { "style": { "borderBottomStyle": "none", "borderBottomWidth": 2, "borderLeftStyle": "solid", "borderLeftWidth": 2, "borderRightStyle": "solid", "borderRightWidth": 2, "borderTopStyle": "none", "borderTopWidth": 2, "fontWeight": "bold", "lineHeight": "16px", "textAlign": "center", "textTransform": "uppercase" }, "text": "Heatmap Mode Active" }, "type": "ia.display.label" }, { "meta": { "name": "LabelFireAlarm", "visible": false }, "position": { "height": 56, "width": 178 }, "propConfig": { "meta.visible": { "binding": { "config": { "fallbackDelay": 2.5, "mode": "direct", "tagPath": "[default]Gateway/FireAlarm" }, "type": "tag" }, "persistent": true }, "props.style.backgroundColor": { "binding": { "config": { "expression": "if({[default]Gateway/FireAlarm},\r\n\tif({[default]Gateway/ToggleTag},\r\n\t\t\"#FF0\",\r\n\t\t\"#F00\"\r\n\t),\r\n\t\"#AAA\"\r\n)" }, "type": "expr" } } }, "props": { "style": { "borderBottomStyle": "none", "borderBottomWidth": 2, "borderLeftStyle": "solid", "borderLeftWidth": 2, "borderRightStyle": "solid", "borderRightWidth": 2, "borderTopStyle": "none", "borderTopWidth": 2, "fontWeight": "bold", "lineHeight": "16px", "textAlign": "center", "textTransform": "uppercase" }, "text": "Building Fire Alarm" }, "type": "ia.display.label" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/commission" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_Commission" }, "position": { "height": 52, "width": 100, "x": 1396, "y": 2 }, "propConfig": { "props.enabled": { "binding": { "config": { "path": "session.props.auth.user.roles" }, "transforms": [ { "code": "\troles \u003d [\"Administrator\", \"Developer\", \"Supervisor\", \"Maintenance\"]\n\treturn value !\u003d None and len(value) \u003e 0 and len([i for i in value if i in roles]) \u003e 0", "type": "script" } ], "type": "property" }, "persistent": true } }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Commission", "visible": true }, "type": "ia.input.button" }, { "events": { "component": { "onActionPerformed": { "config": { "page": "/cameras" }, "scope": "C", "type": "nav" } } }, "meta": { "name": "Nav_JamCameras" }, "position": { "height": 52, "width": 100, "x": 866, "y": 2 }, "props": { "style": { "classes": "Buttons/Grey" }, "text": "Jam Cameras" }, "type": "ia.input.button" } ], "meta": { "name": "root" }, "props": { "style": { "background": "#AAA", "border-bottom": "2px solid #000", "border-top": "2px solid #000" } }, "type": "ia.container.coord" } }