Pushing everything to the main

This commit is contained in:
Salijoghli 2025-08-25 18:35:36 +04:00
parent ba9bed0e00
commit 0c24d9ebdd
317 changed files with 64062 additions and 154601 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -1,8 +0,0 @@
SELECT DISTINCT destination_act AS lane
FROM package_history
WHERE destination_act IS NOT NULL
UNION
SELECT DISTINCT lane_id AS lane
FROM pe_history
WHERE lane_id LIKE "CH%" OR lane_id LIKE "RS%1CH"
ORDER BY lane ASC;

View File

@ -1,290 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "VFD"
},
"props": {
"config": {
"enableHighlight": true,
"isClickable": false
},
"status": {
"color": {
"left": "#B3B3B3",
"right": "#D3D3D3"
},
"showAlways": true,
"tagPath": "[default]MCP03/RO02/RO02_03/VFD",
"tooltip": ""
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 105,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "VFD"
},
"position": {
"height": 64,
"width": 64,
"x": 67.5,
"y": 2.5
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "try(\r\n\tjsonSet({value}, \"showAlways\", true),\r\n\t{view.params.props.status}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false
}
},
"type": "dex.display.vfd"
},
{
"meta": {
"name": "Label_15"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 40
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Status:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"code": "\treturn utils.extractStatus(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_1"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 5
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Name: "
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbName"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027\u0027)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_12"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 75
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Panel:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus_0"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 75
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.OPC_Server"
},
"transforms": [
{
"expression": "coalesce({value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

View File

@ -618,7 +618,7 @@
"$": [
"ds",
192,
1755615167883
1755876354367
],
"$columns": [
{
@ -2165,7 +2165,7 @@
"$": [
"ds",
192,
1755615167863
1755876354366
],
"$columns": [
{
@ -2217,7 +2217,7 @@
"$": [
"ds",
192,
1755615167863
1755876354366
],
"$columns": [
{
@ -3538,7 +3538,7 @@
"$": [
"ds",
192,
1755615167883
1755876354367
],
"$columns": [
{
@ -4880,7 +4880,7 @@
"$": [
"ds",
192,
1755615167885
1755876354369
],
"$columns": [
{
@ -9629,7 +9629,7 @@
"$": [
"ds",
192,
1755615167885
1755876354369
],
"$columns": [
{
@ -24962,7 +24962,7 @@
"$": [
"ds",
192,
1755614835115
1755875431925
],
"$columns": [
{
@ -27735,19 +27735,19 @@
"$": [
"ds",
192,
1755614835115
1755875431925
],
"$columns": [
{
"data": [
"2025-08-19 18:00"
"2025-08-22 18:00"
],
"name": "Start Timestamp",
"type": "String"
},
{
"data": [
"H0"
"H1"
],
"name": "Hour",
"type": "String"
@ -27807,7 +27807,7 @@
"dataSources": {
"example": [
{
"Hour": "H0",
"Hour": "H1",
"ULGL1": null,
"ULGL2": null,
"ULGL3": null
@ -28807,7 +28807,7 @@
}
},
"props": {
"currentTabIndex": 1,
"currentTabIndex": 5,
"menuStyle": {
"backgroundColor": "#FFFFFFBD",
"fontSize": "1.0vmin",
@ -31364,7 +31364,7 @@
},
"props": {
"dismissOnSelect": false,
"formattedValue": "Aug 19, 2025 5:52 PM",
"formattedValue": "Aug 22, 2025 6:25 PM",
"formattedValues": {
"date": "Mar 26, 2021",
"datetime": "Mar 26, 2021 12:00 AM",
@ -31382,9 +31382,9 @@
"$": [
"ts",
192,
1755615167861
1755876353750
],
"$ts": 1755611567000
"$ts": 1755872753000
}
},
"type": "ia.input.date-time-input"
@ -31535,7 +31535,7 @@
},
"props": {
"dismissOnSelect": false,
"formattedValue": "Aug 19, 2025 6:52 PM",
"formattedValue": "Aug 22, 2025 7:25 PM",
"formattedValues": {
"date": "Mar 29, 2021",
"datetime": "Mar 29, 2021 1:37 PM",
@ -31553,9 +31553,9 @@
"$": [
"ts",
192,
1755615167887
1755876353750
],
"$ts": 1755615167000
"$ts": 1755876353000
}
},
"type": "ia.input.date-time-input"

File diff suppressed because one or more lines are too long

View File

@ -1,38 +0,0 @@
WITH SORTERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:%i:00") AS time,
COUNT(*) AS total,
SUM(sort_code="Success") AS success,
SUM(sort_code IN ("Dest Invalid", "Dest None", "Underutilized")) AS awcs,
SUM(sort_code IN ("Dest Disabled", "Dest Full", "Dim Error", "Unexpected", "Weight Err")) AS operational,
SUM(sort_code IN ("Dest Fault", "Div Fail", "Gap Err", "Lost", "Rate High", "Track Err", "Unknown", "Unsafe")) AS machine,
SUM(sort_code IN ("No Read", "No Code", "Multi Label")) AS scanner
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND sorter = :sorter
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
)
SELECT
time,
/* Counts: */
total AS total_count,
success AS success_count,
awcs AS awcs_issues_count,
operational AS operational_issues_count,
machine AS machine_issues_count,
scanner AS scanner_issues_count,
/* PPH: */
ROUND(total*60) AS total_pph,
ROUND(success*60) AS success_pph,
ROUND(awcs*60) AS awcs_issues_pph,
ROUND(operational*60) AS operational_issues_pph,
ROUND(machine*60) AS machine_issues_pph,
ROUND(scanner*60) AS scanner_issues_pph,
/* Percents: */
ROUND(success/total, 4) AS success_percent,
ROUND(awcs/total, 4) AS awcs_issues_percent,
ROUND(operational/total, 4) AS operational_issues_percent,
ROUND(machine/total, 4) AS machine_issues_percent,
ROUND(scanner/total, 4) AS scanner_issues_percent
FROM SORTERS;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1,169 +0,0 @@
{
"custom": {
"alarmHighlight": "",
"areaHover": [],
"currentGraphic": "Windows/Graphics/Overview",
"demoHighlight": "",
"dexmanager": {
"config": {
"font": "bold 12px Arial",
"highlight": "#ff0"
},
"highlight": [],
"show": {
"Beacons": false,
"ConveyorLabels": true,
"ConveyorPatterns": true,
"Conveyors": true,
"DivertPaddles": true,
"EIPs": false,
"Encoders": false,
"Estops": false,
"Gaylords": true,
"LimitSwitches": false,
"MCPs": false,
"PhotoEyes": false,
"PushButtons": false,
"Scanners": false,
"VFDs": false
}
},
"heatmapSettings": {
"alarms": [],
"alarmsText": "",
"data": {
"$": [
"ds",
192,
1602856991637
],
"$columns": [
{
"data": [],
"name": "firsttime",
"type": "Date"
},
{
"data": [],
"name": "lasttime",
"type": "Date"
},
{
"data": [],
"name": "duration",
"type": "String"
},
{
"data": [],
"name": "count",
"type": "Long"
},
{
"data": [],
"name": "device",
"type": "String"
},
{
"data": [],
"name": "description",
"type": "String"
}
]
},
"devices": [],
"devicesText": "",
"enabled": false,
"shifts": [],
"shiftsText": "",
"time": {
"end": "2020-07-30 00:00:00",
"start": "2020-07-29 00:00:00"
}
},
"isMobile": false,
"timewidget": {
"endDate": {
"$": [
"ts",
192,
1646422591477
],
"$ts": 1646438400000
},
"mode": "currentDay",
"startDate": {
"$": [
"ts",
192,
1646422591477
],
"$ts": 1646352000000
},
"update": {
"$": [
"ts",
192,
1646422591477
],
"$ts": 1646422591465
}
}
},
"propConfig": {
"props.auth": {
"access": "PRIVATE",
"persistent": false
},
"props.device.accelerometer": {
"access": "SYSTEM",
"persistent": false
},
"props.device.identifier": {
"access": "SYSTEM",
"persistent": false
},
"props.device.timezone": {
"access": "SYSTEM",
"persistent": false
},
"props.device.type": {
"access": "SYSTEM",
"persistent": false
},
"props.device.userAgent": {
"access": "SYSTEM",
"persistent": false
},
"props.gateway": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.data": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.permissionGranted": {
"access": "SYSTEM",
"persistent": false
},
"props.host": {
"access": "SYSTEM",
"persistent": false
},
"props.id": {
"access": "SYSTEM",
"persistent": false
},
"props.lastActivity": {
"access": "SYSTEM",
"persistent": false
}
},
"props": {
"address": "127.0.0.1",
"device": {},
"geolocation": {},
"locale": "en-US",
"timeZoneId": "Asia/Tbilisi"
}
}

View File

@ -1,4 +0,0 @@
SELECT DISTINCT destination_act AS lane
FROM package_history
WHERE destination_act IS NOT NULL
ORDER BY lane ASC;

View File

@ -1,6 +0,0 @@
def set_priority_filters(self):
filters = self.props.value
payload = {}
payload["data"] = filters
system.perspective.sendMessage("set-priority-filters", payload = payload,
scope = "page")

View File

@ -1,63 +0,0 @@
################################################################
################################################################
## Version: 1.0 / Author: Dillon Uzar
##
## DESC: For use in WCS Sorting Lane Lookup & Recording
## WARN: Modifying code may cause system to function incorrectly
################################################################
################################################################
import time
#######################################################
#######################################################
#######################################################
#### Constants
#######################################################
# Logger:
LOG = system.util.logger("GL BreakCount Handler")
# For inserting data into database:
CONFIRM_INSERT_QUERY = "INSERT IGNORE INTO gl_history (gaylord_id,count) VALUES (?,?)"
#######################################################
#######################################################
#######################################################
#### Parsing Utils
#######################################################
def logTime(title, trackID, seconds):
millisec = round(seconds * 1000, 1)
if millisec > 4:
LOG.info("%s[ID=%s] took longer than expected (%sms to process)" % (title, trackID, millisec))
#######################################################
#######################################################
#######################################################
#### PLC Event Handling
#######################################################
def processBreak(gaylordID, count):
# This function handles confirm events, and logs the event in SQL
# Ensure ID is valid
if count > 0:
start_time = time.time()
# Log confirm event in SQL:
# Insert into Package History:
system.db.runPrepUpdate(CONFIRM_INSERT_QUERY, [gaylordID, count])
logTime("GL_BREAK[DB_INSERT]", gaylordID, time.time() - start_time)
def processBreakAsync(gaylordID, count):
# This function handles confirm events, and logs the event in SQL
# Ensure ID is valid
if count > 0:
def processConfirmInner():
start_time = time.time()
# Log confirm event in SQL:
# Insert into Package History:
system.db.runPrepUpdate(CONFIRM_INSERT_QUERY, [gaylordID, count])
logTime("GL_BREAK[DB_INSERT]", gaylordID, time.time() - start_time)
system.util.invokeAsynchronous(processConfirmInner)

View File

@ -1,26 +0,0 @@
WITH SORTERS AS (
SELECT
MIN(timestamp) AS start_timestamp,
MAX(timestamp) AS end_timestamp,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
"SYSTEM" AS sorter,
SUM(IF(lane_id LIKE "UL%", count, 0)) AS inducted,
SUM(IF(lane_id LIKE "CH%", count, 0)) AS sorted
FROM pe_history
WHERE timestamp BETWEEN :startDate AND :endDate
GROUP BY "SYSTEM" /* Makes it so no row is returned if no rows are processed */
)
SELECT
start_timestamp,
end_timestamp,
sorter,
/* Counts: */
inducted AS inducted_count,
sorted AS sorted_count,
/* PPH: */
ROUND(inducted*pph_multiplier) AS inducted_pph,
ROUND(sorted*pph_multiplier) AS sorted_pph,
/* Percents: */
ROUND(inducted/inducted, 4) AS inducted_percent,
ROUND(sorted/sorted, 4) AS sorted_percent
FROM SORTERS;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -1,275 +0,0 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Idle"
},
"params": {
"tagProps": [
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 1,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
"type": "expression"
},
{
"fallback": 0,
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": 1
},
{
"input": 2,
"output": 2
},
{
"input": 3,
"output": 3
},
{
"input": 4,
"output": 4
},
{
"input": 5,
"output": 5
},
{
"input": 6,
"output": 6
},
{
"input": 7,
"output": 7
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Unknown",
"inputType": "scalar",
"mappings": [
{
"input": 0,
"output": "Idle"
},
{
"input": 1,
"output": "Actuated"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 30,
"width": 30
}
},
"root": {
"children": [
{
"meta": {
"name": "EPC"
},
"position": {
"height": 1,
"width": 1
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_epc"
},
"type": "property"
}
},
"props.elements[2].fill.paint": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#00FF00",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"elements": [
{
"fill": {
"paint": "#FFFF00"
},
"height": "20",
"name": "rect",
"type": "rect",
"width": "20",
"x": "0",
"y": "0"
},
{
"d": "M 0,0 H 20 V 20 H 0 Z",
"fill": {
"paint": "transparent"
},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "1.5"
},
"type": "path"
},
{
"d": "m 17,10.5 a 7,7 0 0 1 -7,7 7,7 0 0 1 -7,-7 7,7 0 0 1 7,-7 7,7 0 0 1 7,7 z",
"fill": {},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "1"
},
"type": "path"
}
],
"viewBox": "0 0 20 20"
},
"type": "ia.shapes.svg"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-EPC\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\t\n\talarm \u003d []\n\tmessage \u003d None\n\t\n\tsleep(0.5)\n\t\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_epc"
},
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"cursor": "pointer"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,393 +0,0 @@
{
"custom": {},
"params": {
"enableTooltip": true,
"label": null,
"tagPath": "",
"tagPathControl": "",
"view": ""
},
"propConfig": {
"params.enableTooltip": {
"paramDirection": "input",
"persistent": true
},
"params.label": {
"paramDirection": "input",
"persistent": true
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
},
"params.tagPathControl": {
"paramDirection": "input",
"persistent": true
},
"params.view": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 40,
"width": 135
}
},
"root": {
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Status"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"props.style.backgroundColor": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}.jsonValues"
},
"transforms": [
{
"expression": "try(\r\n\tif(jsonGet({value}, \"Estop_Active\") \u0026\u0026 {[default]Gateway/ToggleTag},\r\n\t\t\"#F00\",\t\t// Estop\r\n\t\tif(jsonGet({value}, \"bStarted\"),\r\n\t\t\t\"#0F0\",\t// Running\r\n\t\t\t\"#AAA\"\t// Stopped\r\n\t\t)\r\n\t),\r\n\t\"#808080\" // Unknown\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": 1
}
},
"type": "ia.display.label"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Text"
},
"position": {
"height": "calc(100% - 10px)",
"width": "calc(100% - 10px)",
"x": 5,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({view.params.label}, {value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"backgroundColor": "#FFF",
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": 1,
"fontSize": "12px",
"fontWeight": "bold",
"overflow": "hidden",
"paddingLeft": "5px",
"textOverflow": "ellipsis",
"textTransform": "uppercase",
"user-select": "none",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "TooltipOverlay"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"path": "view.params.enableTooltip"
},
"type": "property"
}
},
"props.status.tooltip": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "if(isGood({value}),\r\n\tjsonGet({value}, \"tooltip\"),\r\n\t\"Tooltip not configured\"\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"status": {}
},
"type": "dex.display.tooltipoverlay"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPath \u003d self.view.params.tagPathControl\n\tif tagPath \u003c\u003e \"\":\n\t\ttags \u003d [tagPath + \"/SetStart\"]\n\t\tvalues \u003d [1]\n\t\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Start"
},
"position": {
"height": 25,
"width": 25,
"x": "calc(100% - 60px)",
"y": "calc(50% - 12.5px)"
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPathControl": "{view.params.tagPathControl}"
},
"tagPath": "{tagPathControl}/SetStart"
},
"transforms": [
{
"expression": "isGood({value})",
"type": "expression"
}
],
"type": "tag"
}
},
"props.textStyle.color": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPathControl": "{view.params.tagPathControl}"
},
"tagPath": "{tagPathControl}/Alarms/bStarted"
},
"transforms": [
{
"expression": "coalesce({value}, false)",
"type": "expression"
},
{
"fallback": "#888888",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "#32CD32"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "►",
"textStyle": {
"fontFamily": "Arial",
"fontSize": "14px"
}
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPath \u003d self.view.params.tagPathControl\n\tif tagPath \u003c\u003e \"\":\n\t\ttags \u003d [tagPath + \"/SetStop\"]\n\t\tvalues \u003d [1]\n\t\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Stop"
},
"position": {
"height": 25,
"width": 25,
"x": "calc(100% - 32.5px)",
"y": "calc(50% - 12.5px)"
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPathControl": "{view.params.tagPathControl}"
},
"tagPath": "{tagPathControl}/SetStop"
},
"transforms": [
{
"expression": "isGood({value})",
"type": "expression"
}
],
"type": "tag"
}
},
"props.textStyle.color": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPathControl": "{view.params.tagPathControl}"
},
"tagPath": "{tagPathControl}/Alarms/bStarted"
},
"transforms": [
{
"expression": "coalesce({value}, true)",
"type": "expression"
},
{
"fallback": "#888888",
"inputType": "scalar",
"mappings": [
{
"input": false,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "■",
"textStyle": {
"fontFamily": "monospace",
"fontSize": "14px"
}
},
"type": "ia.input.button"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"cursor": "pointer"
}
},
"scripts": {
"customMethods": [
{
"name": "openWindow",
"params": [],
"script": "\tview \u003d self.view.params.view\n\tif view in [\"\", None]:\n\t\tview \u003d \"Windows/Graphics/\"+self.getChild(\"Text\").props.text.replace(\" \", \"_\")\n\t# Open window:\n\twindow \u003d \"Windows/GraphicsWrapper\"\n\tparams \u003d {\"view\": view}\n\tsystem.perspective.navigate(\"/\")\n\tsystem.perspective.navigate(view\u003dwindow, params\u003dparams)"
}
],
"messageHandlers": []
},
"type": "ia.container.coord"
}
}

View File

@ -1,156 +0,0 @@
################################################################
################################################################
## Version: 1.0 / Author: Dillon Uzar
##
## DESC: For use in FMS in recording Flow Management data
## WARN: Modifying code may cause system to function incorrectly
################################################################
################################################################
import json
import system
import time
#######################################################
#######################################################
#######################################################
#### Constants
#######################################################
# Logger:
LOG = system.util.logger("FMS Handler")
# For inserting data into database:
INSERT_QUERY = "INSERT INTO fms_history (conveyor, segment, data) VALUES (?,?,?)"
#######################################################
#######################################################
#######################################################
#### Parsing Utils
#######################################################
def extractNibble(val, nibble):
if val is not None:
return (val >> (nibble*4)) & 0x0F
def logTime(title, conv, seg, data, start_time):
millisec = round((time.time() - start_time) * 1000, 1)
LOG.info("%s[CONV=%s][SEG=%s][DATA=%s] took %sms to process" % (title, conv, seg, data, millisec))
#######################################################
#######################################################
#######################################################
#### Tag Event Handling
#######################################################
def logSegment(conveyor, segment, data):
# Log event in SQL:
# Insert into FMS History:
start_time = time.time()
INSERT_QUERY = "INSERT INTO fms_history (conveyor, segment, data) VALUES (?,?,?)"
system.db.runPrepUpdate(INSERT_QUERY, [conveyor, segment, data])
#logTime("FMS[DB_INSERT]", conveyor, segment, data, start_time)
def dintOnChange(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
# Don't execute on startup, or if new value is bad quality:
if currentValue.quality.isGood():
# Only consider it a change if the value is different:
if currentValue.value <> previousValue.value:
id = int(tagPath.split("/")[-1].replace("DINT", ""))
conveyor = tag['parameters']['LabelFull']
# ID=0 is unique where the first nibble is the average of all segments, the 7 other segments are normal segments:
if id == 0:
# Ignore first nibble, which is the average of all segments:
for i in range(1, 8):
# Check if segment changed:
curVal = extractNibble(currentValue.value, i)
prevVal = extractNibble(previousValue.value, i)
if curVal <> prevVal:
segment = i - 1
logSegment(conveyor, segment, curVal)
else:
for i in range(0, 8):
# Check if segment changed:
curVal = extractNibble(currentValue.value, i)
prevVal = extractNibble(previousValue.value, i)
if curVal <> prevVal:
segment = i + (id-1)*8 + 7
logSegment(conveyor, segment, curVal)
#######################################################
#######################################################
#######################################################
#### Graphics Tag Scripts
#######################################################
"""
radial-gradient(circle at 30%,
#f5bff5 calc((var(--conv-width) - 4px)/2*0.25),
#000 calc((var(--conv-width) - 4px)/2*0.25),
#000 calc((var(--conv-width) - 4px)/2*0.25 + 1px),
transparent calc((var(--conv-width) - 4px)/2*0.25 + 1px)),
radial-gradient(circle at 50%, #d900d9 calc((var(--conv-width) - 4px)/2*1), #000 calc((var(--conv-width) - 4px)/2*1), #000 calc((var(--conv-width) - 4px)/2*1 + 1px), transparent calc((var(--conv-width) - 4px)/2*0.25 + 1px)), radial-gradient(circle at 70%, #ec7fec 7px, #000 7px, #000 8px, transparent 8px), radial-gradient(circle at 90%, #e23fe2 10px, #000 10px, #000 11px, transparent 11px), #00D900
"""
def genSegmentsTable(obj):
segments = []
if obj is not None and obj["Count"] is not None:
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
percent = extractNibble(obj[dint], i % 8) / 15.0
segments.append([i, percent])
return system.dataset.toDataSet(["segment", "fill"], segments)
def genSegmentColor(data):
perc = (data/15.0)
c1 = 255 - (255 - 217)*perc
c2 = 255 - (255 - 0)*perc
return "rgb(%s, %s, %s)" % (c1, c2, c1)
def genSegmentsPattern(obj):
if obj["Count"] is not None and obj["Count"] > 0:
percUnit = 100 / float(obj["Count"])
gradients = []
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
color = genSegmentColor(data)
circlePos = ((obj["Count"]-i))*percUnit + percUnit/2.0
perc = (data/15.0*0.5+0.5) if data > 0 else 0.0 # Make circle size between 50%-100%
if perc > 0.0:
output = "radial-gradient(circle at %s%%" % (circlePos)
output += ", %s calc((var(--conv-width) - 8px)/2*%s)" % (color, perc)
output += ", #000 calc((var(--conv-width) - 8px)/2*%s)" % (perc)
output += ", #000 calc((var(--conv-width) - 8px)/2*%s + 1px)" % (perc)
output += ", transparent calc((var(--conv-width) - 8px)/2*%s + 1px)" % (perc)
output += ")"
gradients.append(output)
if len(gradients) > 0:
return ", ".join(gradients)+","
return ""
def genSegmentsTooltip(obj):
if obj["Count"] is not None and obj["Count"] > 0:
data = extractNibble(obj["DINT0"], 0)
output = "<br><br>SegmentAVG: %s%%" % (int(round(100 * data / 15.0)))
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
output += "<br>Segment%s: %s%%" % (i, int(round(100 * data / 15.0)))
return output
return ""
def genSegmentHeatmap(obj):
segments = []
if obj["Count"] is not None and obj["Count"] > 0:
for i in range(1, obj["Count"]+1):
dint = "DINT"+str(int(i/8))
if obj[dint] is not None:
data = extractNibble(obj[dint], i % 8)
color = 255 * data / 15
segments.append("rgb(255, %s, %s)" % (color, color))
return json.dumps(segments)

View File

@ -1,36 +0,0 @@
{
"base": {
"style": {
"backgroundImage": "linear-gradient(180deg, rgba(245,245,245,1) 0%, rgba(235,235,235,1) 70%, rgba(208,208,208,1) 100%);",
"borderColor": "#555",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#000",
"textTransform": "uppercase"
}
},
"variants": [
{
"pseudo": "hover",
"style": {
"backgroundImage": "linear-gradient(0deg, rgba(245,245,245,1) 0%, rgba(235,235,235,1) 70%, rgba(208,208,208,1) 100%);",
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#000",
"cursor": "pointer"
}
},
{
"pseudo": "disabled",
"style": {
"backgroundImage": "linear-gradient(180deg, rgba(208,208,208,1) 0%, rgba(208,208,208,1) 100%);",
"borderColor": "#555",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#555555",
"cursor": "not-allowed"
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

View File

@ -1,908 +0,0 @@
{
"custom": {},
"params": {
"alwaysShowAll": false,
"isClickable": true,
"isRightOfSorter": false,
"mirror": false,
"tagPath": "[default]MCP20/SO01/So01_CH01"
},
"propConfig": {
"params.alwaysShowAll": {
"paramDirection": "input",
"persistent": true
},
"params.isClickable": {
"paramDirection": "input",
"persistent": true
},
"params.isRightOfSorter": {
"paramDirection": "input",
"persistent": true
},
"params.mirror": {
"paramDirection": "input",
"persistent": true
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 20,
"width": 60
},
"loading": {
"mode": "blocking"
}
},
"root": {
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openPopup()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Conveyor"
},
"position": {
"height": 20,
"width": 38,
"x": 22
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/CH/IsChuteMode"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "coalesce({value}, true)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false,
"showLabel": false,
"type": "bar"
},
"status": {
"color": "#FFF"
}
},
"type": "dex.display.conveyor"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openPopup()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Gaylord"
},
"position": {
"height": 16,
"width": 16,
"x": 22,
"y": 2
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"expression": "try( tag({view.params.tagPath}+\"/CH/IsCartMode\")\r\n\t||tag({view.params.tagPath}+\"/CH/IsGLLMode\"),\r\n\ttrue\r\n)"
},
"type": "expr"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false
}
},
"type": "dex.display.gaylord"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openPopup()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Chute"
},
"position": {
"height": 20,
"rotate": {
"anchor": "0 0"
},
"width": 23
},
"propConfig": {
"props.config.isClickable": {
"binding": {
"config": {
"expression": "!{view.params.isClickable}"
},
"type": "expr"
}
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/CH/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"showLabel": false
}
},
"type": "dex.display.conveyor"
},
{
"meta": {
"name": "LS1"
},
"position": {
"height": 6,
"width": 6,
"x": 19,
"y": 14
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/LS1/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GR Presence)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"showLabel": false
}
},
"type": "dex.display.limitswitch"
},
{
"meta": {
"name": "BCN1_GRN"
},
"position": {
"height": 5,
"rotate": {
"angle": "-90deg"
},
"width": 5,
"x": 5,
"y": 15
},
"propConfig": {
"position.x": {
"binding": {
"config": {
"expression": "if({../BCN1_AMB.meta.visible}, 10, 5)"
},
"type": "expr"
},
"persistent": true
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/GRN/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(-1, 1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "BCN1_AMB",
"visible": false
},
"position": {
"height": 5,
"rotate": {
"angle": "-90deg"
},
"width": 5,
"x": 5,
"y": 15
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/AMB/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "isGood({value})",
"type": "expression"
}
],
"type": "tag"
},
"persistent": true
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/AMB/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(-1, 1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "BCN1_BLU"
},
"position": {
"height": 5,
"rotate": {
"angle": "-90deg"
},
"width": 5,
"y": 15
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/BLU/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(-1, 1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "GS1_ENABLE"
},
"position": {
"height": 6,
"width": 6,
"x": 38,
"y": 14
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/GS1/Enable/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.pushbutton"
},
{
"meta": {
"name": "PE3"
},
"position": {
"height": 6,
"rotate": {
"anchor": "0 50%"
},
"width": 8,
"x": 3,
"y": 2
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/PE3/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GL 100% Full)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"type": "diffuse"
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "PE4"
},
"position": {
"height": 6,
"rotate": {
"anchor": "0 50%",
"angle": "-45deg"
},
"width": 8,
"x": 5,
"y": 10
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/PE4/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GL Presence)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"type": "diffuse"
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "PE2"
},
"position": {
"height": 6,
"width": 28,
"x": 13,
"y": 7
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/PE2/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GR 50% Full)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"type": "diffuse"
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "PE1B"
},
"position": {
"height": 6,
"rotate": {
"anchor": "0 50%"
},
"width": 20,
"x": 15
},
"propConfig": {
"position.rotate.angle": {
"binding": {
"config": {
"path": "view.params.isRightOfSorter"
},
"transforms": [
{
"fallback": "-45deg",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "45deg"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
},
"position.y": {
"binding": {
"config": {
"path": "view.params.isRightOfSorter"
},
"transforms": [
{
"fallback": 14,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": 0
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/PE1B/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GR 100% Full)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"type": "diffuse"
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "PE1A"
},
"position": {
"height": 6,
"rotate": {
"anchor": "0 50%"
},
"width": 20,
"x": 15
},
"propConfig": {
"position.rotate.angle": {
"binding": {
"config": {
"path": "view.params.isRightOfSorter"
},
"transforms": [
{
"fallback": "45deg",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "-45deg"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
},
"position.y": {
"binding": {
"config": {
"path": "view.params.isRightOfSorter"
},
"transforms": [
{
"fallback": 0,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": 14
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/PE1A/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "jsonSet({value}, \"tooltip\", replace(jsonGet({value}, \"tooltip\"), \"\u003cbr\u003e\", \" (GR 100% Full)\u003cbr\u003e\"))",
"type": "expression"
},
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"type": "diffuse"
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "RS1_RESTART"
},
"position": {
"height": 6,
"width": 6,
"x": 44,
"y": 14
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/RS1/Restart/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.pushbutton"
},
{
"meta": {
"name": "FIO1"
},
"position": {
"height": 5,
"width": 10,
"x": 50,
"y": 15
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/FIO1/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.eip"
}
],
"meta": {
"name": "root"
},
"propConfig": {
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(1, -1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"overflow": "hidden"
}
},
"scripts": {
"customMethods": [
{
"name": "openPopup",
"params": [],
"script": "\tif self.view.params.isClickable:\n\t\tid \u003d \"FlexChute|\" + self.view.params.tagPath\n\t\ttitle \u003d utils.prettyName(self.view.params.tagPath.split(\"/\")[-1])\n\t\tparams \u003d { \n\t\t\t\"deviceType\": \"chutedestination\",\n\t\t\t\"props\": { \n\t\t\t\t\"config\": {\n\t\t\t\t\t\"alwaysShowAll\": self.view.params.alwaysShowAll,\n\t\t\t\t\t\"isClickable\": self.view.params.isClickable,\n\t\t\t\t\t\"isRightOfSorter\": self.view.params.isRightOfSorter,\n\t\t\t\t\t\"mirror\": self.view.params.mirror\n\t\t\t\t},\n\t\t\t\t\"status\": {\n\t\t\t\t\t\"tagPath\": self.view.params.tagPath\n\t\t\t\t}\n\t\t \t},\n\t\t \t\"tabs\": [\"Controls\", \"Alarm History\", \"Devices\"]\t\t\n\t\t}\n\t\tsystem.perspective.openPopup(id, \"Popups/DeviceWrapper\", params, title, resizable \u003d True)"
}
],
"extensionFunctions": null,
"messageHandlers": []
},
"type": "ia.container.coord"
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,290 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "VFD"
},
"props": {
"config": {
"enableHighlight": true,
"isClickable": false
},
"status": {
"color": {
"left": "#B3B3B3",
"right": "#D3D3D3"
},
"showAlways": true,
"tagPath": "[default]MCP03/RO02/RO02_03/VFD",
"tooltip": ""
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 105,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "VFD"
},
"position": {
"height": 64,
"width": 64,
"x": 67.5,
"y": 17.5
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "try(\r\n\tjsonSet({value}, \"showAlways\", true),\r\n\t{view.params.props.status}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false
}
},
"type": "dex.display.vfd"
},
{
"meta": {
"name": "Label_15"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 40
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Status:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"code": "\treturn utils.extractStatus(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_1"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 5
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Name: "
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbName"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027\u0027)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_12"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 75
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Panel:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus_0"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 75
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.OPC_Server"
},
"transforms": [
{
"expression": "coalesce({value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,44 +0,0 @@
WITH SCANNERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:00") AS start_timestamp,
CONCAT("H",
CAST(
TIMESTAMPDIFF(
HOUR,
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:00:00"),
DATE_FORMAT(LEAST(CURRENT_TIMESTAMP(), :endDate), "%Y-%m-%d %H:00:00")
) AS CHAR
)
) AS hour,
COUNT(*) AS total,
SUM(scanner_status NOT IN ("No Read", "No Code", "Multi Label")) AS good_read,
SUM(scanner_status = "No Read") AS no_read,
SUM(scanner_status = "No Code") AS no_code,
SUM(scanner_status = "Multi Label") AS multi_label
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND scanner=:scanner
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:00")
)
SELECT
start_timestamp,
hour,
/* Counts: */
total AS total_count,
good_read AS good_read_count,
no_read AS no_read_count,
no_code AS no_code_count,
multi_label AS multi_label_count,
/* PPH: */
total AS total_pph,
good_read AS good_read_pph,
no_read AS no_read_pph,
no_code AS no_code_pph,
multi_label AS multi_label_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent,
ROUND(good_read/total, 4) AS good_read_percent,
ROUND(no_read/total, 4) AS no_read_percent,
ROUND(no_code/total, 4) AS no_code_percent,
ROUND(multi_label/total, 4) AS multi_label_percent
FROM SCANNERS;

View File

@ -1,23 +0,0 @@
WITH GAYLORDS AS (
SELECT
MIN(timestamp) AS start_timestamp,
MAX(timestamp) AS end_timestamp,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
gaylord_id AS gaylord,
SUM(count) AS total
FROM gl_history
WHERE timestamp BETWEEN :startDate AND :endDate
GROUP BY gaylord_id
ORDER BY gaylord_id
)
SELECT
start_timestamp,
end_timestamp,
gaylord,
/* Counts: */
total AS total_count,
/* PPH: */
ROUND(total*pph_multiplier) AS total_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent
FROM GAYLORDS;

View File

@ -1,415 +0,0 @@
{
"custom": {},
"params": {
"alwaysShowAll": false,
"chuteNum": "",
"isClickable": true,
"mirror": false,
"tagPath": "MCP05/PS01/PS01_28CH"
},
"propConfig": {
"params.alwaysShowAll": {
"paramDirection": "input",
"persistent": true
},
"params.chuteNum": {
"paramDirection": "input",
"persistent": true
},
"params.isClickable": {
"paramDirection": "input",
"persistent": true
},
"params.mirror": {
"paramDirection": "input",
"persistent": true
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 92,
"width": 94
},
"loading": {
"mode": "blocking"
}
},
"root": {
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openPopup()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Conveyor"
},
"position": {
"height": 48,
"rotate": {
"anchor": "0 0",
"angle": 90
},
"width": 89,
"x": 69,
"y": 1
},
"propConfig": {
"props.config.isClickable": {
"binding": {
"config": {
"expression": "!{view.params.isClickable}"
},
"type": "expr"
}
},
"props.config.showLabel": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Conv/Parameters.LabelFull"
},
"overlayOptOut": true,
"type": "tag"
}
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Conv/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(1, -1) translateY(-100%)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"config": {
"type": "chute"
}
},
"type": "dex.display.conveyor"
},
{
"meta": {
"name": "BCN1_BLU"
},
"position": {
"height": 16,
"width": 16,
"y": 3
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/BLU/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "parent.props.style.transform"
},
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "BCN1_AMB"
},
"position": {
"height": 16,
"width": 16,
"y": 18
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/AMB/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "parent.props.style.transform"
},
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "BCN1_GRN"
},
"position": {
"height": 16,
"width": 16,
"y": 33
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/GRN/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "parent.props.style.transform"
},
"type": "property"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "Half_PE"
},
"position": {
"height": 10,
"rotate": {
"angle": 180
},
"width": 62,
"x": 17,
"y": 74
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Half_PE/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "Jam_PE"
},
"position": {
"height": 10,
"rotate": {
"angle": 180
},
"width": 62,
"x": 17,
"y": 6
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Jam_PE/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "Full_PE"
},
"position": {
"height": 10,
"rotate": {
"angle": 180
},
"width": 62,
"x": 17,
"y": 36
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Full_PE/Graphics"
},
"overlayOptOut": true,
"transforms": [
{
"expression": "if({view.params.alwaysShowAll},\r\n\tjsonSet({value}, \"showAlways\", {view.params.alwaysShowAll}),\r\n\t{value}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.photoeye"
}
],
"meta": {
"name": "root"
},
"propConfig": {
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(-1, 1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"overflow": "hidden"
}
},
"scripts": {
"customMethods": [
{
"name": "openPopup",
"params": [],
"script": "\tif self.view.params.isClickable:\n\t\tid \u003d \"DivChute|\" + self.view.params.tagPath\n\t\ttitle \u003d utils.prettyName(self.view.params.tagPath.split(\"/\")[-1])\n\t\tparams \u003d { \n\t\t\t\"deviceType\": \"divchute\",\n\t\t\t\"props\": { \n\t\t\t\t\"config\": {\n\t\t\t\t\t\"alwaysShowAll\": self.view.params.alwaysShowAll,\n\t\t\t\t\t\"isClickable\": self.view.params.isClickable,\n\t\t\t\t\t#\"rotate\": self.view.params.rotate,\n\t\t\t\t\t\"mirror\": self.view.params.mirror\n\t\t\t\t},\n\t\t\t\t\"status\": {\n\t\t\t\t\t\"tagPath\": self.view.params.tagPath\n\t\t\t\t}\n\t\t \t},\n\t\t \t\"tabs\": [\"Controls\", \"Alarm History\", \"Devices\"]\t\t\n\t\t}\n\t\tsystem.perspective.openPopup(id, \"Popups/DeviceWrapper\", params, title, resizable \u003d True)"
}
],
"extensionFunctions": null,
"messageHandlers": []
},
"type": "ia.container.coord"
}
}

View File

@ -1,43 +0,0 @@
WITH SORTERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:%i:00") AS time,
COUNT(*) AS total,
/* PPH Data */
SUM(sort_code="Success") AS success,
SUM(sort_code IN ("Dest Invalid", "Dest None", "Underutilized")) AS awcs,
SUM(sort_code IN ("Dest Disabled", "Dest Full", "Dim Error", "Unexpected", "Weight Err")) AS operational,
SUM(sort_code IN ("Dest Fault", "Div Fail", "Gap Err", "Lost", "Rate High", "Track Err", "Unknown", "Unsafe")) AS machine,
SUM(sort_code IN ("No Read", "No Code", "Multi Label")) AS scanner,
/* Problem Solve Data */
SUM(sort_code="No Read") AS no_read,
SUM(sort_code="No Code") AS no_code,
SUM(sort_code="Multi Label") AS multi_label,
/* Sorter Error Data */
SUM(sort_code="Gap Err") AS gap_err,
SUM(sort_code="Div Fail") AS div_fail,
SUM(sort_code="Dest None") AS dest_none,
SUM(sort_code="Lost") AS lost
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND sorter = :sorter
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
), DATA AS (
SELECT
total,
/* PPH: */
ROUND((SUM((total - machine - scanner)*60) OVER w)/(:movAvgMin+1)) AS total_pph,
/* Problem Solve Percents: */
no_read+no_code+multi_label AS scanner,
/* Sorter Error Percents: */
gap_err+div_fail+dest_none+lost AS sorter
FROM SORTERS
WINDOW w AS (ORDER BY STR_TO_DATE(time, "%Y-%m-%d %H:%i:00") RANGE BETWEEN INTERVAL :movAvgMin MINUTE PRECEDING AND CURRENT ROW)
)
SELECT
MAX(total_pph) AS total_pph,
/* Problem Solve Percents: */
ROUND(SUM(scanner)/SUM(total), 4) AS scanner,
/* Sorter Error Percents: */
ROUND(SUM(sorter)/SUM(total), 4) AS sorter
FROM DATA;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

View File

@ -1,210 +0,0 @@
{
"custom": {
"alarmHighlight": "",
"alarm_filter": {
"show_VFD": true,
"show_beacons": true,
"show_buttons": true,
"show_camera_jams": true,
"show_dpm_mcm": true,
"show_encoders": true,
"show_epc": true,
"show_fio_safety": true,
"show_map": false,
"show_photoeyes": true,
"show_px": true
},
"areaHover": [],
"currentGraphic": "Windows/Graphics/Overview",
"demoHighlight": "",
"dexmanager": {
"config": {
"font": "bold 12px Arial",
"highlight": "#ff0"
},
"show": {
"Beacons": false,
"ConveyorLabels": true,
"ConveyorPatterns": true,
"Conveyors": true,
"DivertPaddles": true,
"EIPs": false,
"Encoders": false,
"Estops": false,
"Gaylords": true,
"LimitSwitches": false,
"MCPs": false,
"PhotoEyes": false,
"PushButtons": false,
"Scanners": false,
"VFDs": false
}
},
"fc": "BNA8",
"heatmapSettings": {
"alarms": [],
"alarmsText": "",
"data": {
"$": [
"ds",
192,
1754654890875
],
"$columns": [
{
"data": [],
"name": "firsttime",
"type": "Date"
},
{
"data": [],
"name": "lasttime",
"type": "Date"
},
{
"data": [],
"name": "duration",
"type": "String"
},
{
"data": [],
"name": "count",
"type": "Long"
},
{
"data": [],
"name": "device",
"type": "String"
},
{
"data": [],
"name": "description",
"type": "String"
}
]
},
"devices": [],
"devicesText": "",
"enabled": false,
"shifts": [],
"shiftsText": "",
"time": {
"end": "2020-07-30 00:00:00",
"start": "2020-07-29 00:00:00"
}
},
"searchId": "value",
"timewidget": {
"endDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604116800000
},
"mode": "currentDay",
"startDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604030400000
},
"update": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604092861010
}
},
"view_in_focus": "/"
},
"propConfig": {
"custom.dexmanager.highlight": {
"binding": {
"config": {
"struct": {
"alarm": "{this.custom.alarmHighlight}",
"demo": "{this.custom.demoHighlight}",
"toggle": "{[default]Gateway/ToggleTag}"
},
"waitOnAll": true
},
"transforms": [
{
"code": "\thighlights \u003d []\n\t# Add alarm highlight:\n\tif len(value.alarm) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [value.alarm]\n\t\t})\n\t\tif \".\" in value.alarm:\n\t\t\thighlights.append({\n\t\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\t\"keys\": [value.alarm.split(\".\")[0], \"conveyor\"]\n\t\t\t})\n\t# Add demo highlight:\n\tif False and len(value.demo) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [\"conveyor\", value.demo]\n\t\t})\n\treturn highlights",
"type": "script"
}
],
"type": "expr-struct"
}
},
"custom.isMobile": {
"binding": {
"config": {
"expression": "indexOf(lower({session.props.device.userAgent}), \"mobile\")\u003e\u003d0"
},
"type": "expr"
}
},
"props.auth": {
"access": "PRIVATE",
"persistent": false
},
"props.device.accelerometer": {
"access": "SYSTEM",
"persistent": false
},
"props.device.identifier": {
"access": "SYSTEM",
"persistent": false
},
"props.device.timezone": {
"access": "SYSTEM",
"persistent": false
},
"props.device.type": {
"access": "SYSTEM",
"persistent": false
},
"props.device.userAgent": {
"access": "SYSTEM",
"persistent": false
},
"props.gateway": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.data": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.permissionGranted": {
"access": "SYSTEM",
"persistent": false
},
"props.host": {
"access": "SYSTEM",
"persistent": false
},
"props.id": {
"access": "SYSTEM",
"persistent": false
},
"props.lastActivity": {
"access": "SYSTEM",
"persistent": false
}
},
"props": {
"address": "127.0.0.1",
"device": {},
"geolocation": {},
"locale": "en-US",
"timeZoneId": "Asia/Tbilisi"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

View File

@ -92,7 +92,7 @@
"props": {
"params": {
"tagProps": [
"/system/mcm01/test",
"/system/mcm01/baro nodo",
"value",
"value",
"value",
@ -2499,7 +2499,7 @@
"props": {
"params": {
"tagProps": [
"/system/mcm01/test",
"/system/mcm01/hello world",
"value",
"value",
"value",

View File

@ -1,130 +0,0 @@
################################################################
################################################################
## Version: 1.0 / Author: Dillon Uzar
##
## DESC: For use in WCS Sorting Lane Lookup & Recording
## WARN: Modifying code may cause system to function incorrectly
################################################################
################################################################
from __future__ import with_statement
import csv
import os
import random
import re
import string
import system
import time
from os import path
#######################################################
#######################################################
#######################################################
#### Constants
#######################################################
# Logger:
LOG = system.util.logger("WCS Sorting Handler")
# Defaults for function arguments:
PROGRAM_PATH = ""
CARTON_PATH = "WCS_Package"
DEFAULT_DEVICE = "MCP20"
DEFAULT_OPC_SERVER = "Ignition OPC UA Server"
# Configuration variables:
MAX_CARTONS = 100 # Max possible carton IDs
MAX_BARCODE_SIZE = 82 # Max possible size of full barcode
# For extracting PLC info:
PACKAGE_DATA = [
#["Induct_ID", "induct"], # The induct the package was inducted from
#["Scanner_ID", "scanner"], # The scanner the package was scanned from
#["Sorter_ID", "sorter"], # The sorter the package was sorted from
["BCR_Img_ID", "bcr_imgid"], # Barcode reader, sequence ID
["BCR_Seq_ID", "bcr_seqid"], # Barcode reader, image ID
["Length", "pkg_length"], # Package length in units of 1/10". Only populated if available, use 0 if not
["Width", "pkg_width"], # Package width in units of 1/10". Only populated if available, use 0 if not
["Height", "pkg_height"], # Package height in units of 1/10". Only populated if available, use 0 if not
["Carriers", "carriers"], # Num of carriers (trays/shoes) on sorter that the package is occupying. Only populated if available, use 0 if not
["Gap_Leading", "gap_leading"], # Leading edge gap distance in units of 1/10". Only populated if available, use 0 if not. If value exceeds INT size, cap it to the max INT value
["Gap_Trailing", "gap_trailing"], # Trailing edge gap distance in units of 1/10". Only populated if available, use 0 if not. If value exceeds INT size, cap it to the max INT value
["S01_Barcode", "s01_barcode"], # The barcode sent in the S01 message
["S02_Req_Dest_ID", "s02_req_dest"], # The requested destination ID sent in the S02 message
["S02_Alt_Dest_ID", "s02_alt_dest"], # The alternate destination ID sent in the S02 message
["S04_PLC_ID", "s04_plc_id"], # Internal PLC number used to track packages and cross reference to the Host ID
["S04_Host_ID", "s04_host_id"], # The PLC record number sent in the S04 message, (1 - 9999)
["S04_Req_Dest_ID", "s04_req_dest"], # The requested destination ID sent in the S04 message
["S04_Act_Dest_ID", "s04_act_dest"], # The actual destination ID sent in the S04 message
["S04_Sort_Code", "s04_sort_code"], # The reason code sent in the S04 message
["Req_Dest_Reason", "req_dest_reason"], # See Destination Reason Bit-Map sheet
["Alt_Dest_Reason", "alt_dest_reason"] # See Destination Reason Bit-Map sheet
]
TIMESTAMP_DATA = [
["S01_Timestamp_H", "s01_timestamp"], # The timestamp sent in the S01 message, Upper 32-bits, UTS in microseconds
["S01_Timestamp_L", "s01_timestamp"], # The timestamp sent in the S01 message, Lower 32-bits, UTS in microseconds
["S02_Timestamp_H", "s02_timestamp"], # The timestamp sent in the S02 message, Upper 32-bits, UTS in microseconds
["S02_Timestamp_L", "s02_timestamp"], # The timestamp sent in the S02 message, Lower 32-bits, UTS in microseconds
["S04_Timestamp_H", "s04_timestamp"], # The timestamp sent in the S04 message, Upper 32-bits, UTS in microseconds
["S04_Timestamp_L", "s04_timestamp"] # The timestamp sent in the S04 message, Lower 32-bits, UTS in microseconds
]
# Generate array of paths to read:
PACKAGE_PATHS = [v[0] for v in PACKAGE_DATA]
TIMESTAMP_PATHS = [v[0] for v in TIMESTAMP_DATA]
DATA_PATHS = PACKAGE_PATHS + TIMESTAMP_PATHS
# For inserting data into database:
PACKAGE_COLS = [v[1] for v in PACKAGE_DATA]
PACKAGE_VALS = ["?"]*len(PACKAGE_COLS)
TIMESTAMP_COLS = [TIMESTAMP_DATA[i][1] for i in range(len(TIMESTAMP_DATA)) if TIMESTAMP_DATA[i][1] in (v[1] for v in TIMESTAMP_DATA[:i])]
TIMESTAMP_VALS = ["FROM_UNIXTIME(((?&(POWER(2, 32)-1))*POWER(2, 32)+(?&(POWER(2, 32)-1)))/1000000)"]*len(TIMESTAMP_COLS)
UNIQUE_COLS = ["trackid", "induct", "scanner", "sorter"] + PACKAGE_COLS + TIMESTAMP_COLS
UNIQUE_VALS = ["?"]*4 + PACKAGE_VALS + TIMESTAMP_VALS
CONFIRM_INSERT_QUERY = "INSERT IGNORE INTO package_history (" + ",".join(UNIQUE_COLS) + ") VALUES (" + ",".join(UNIQUE_VALS) + ")"
#######################################################
#######################################################
#######################################################
#### Parsing Utils
#######################################################
def isNoRead(field):
return field.replace("?","") == ""
def isMultiRead(field):
return field.replace("#","") == ""
def isBadRead(field):
return (field == None or isNoRead(field) or isMultiRead(field))
def logTime(title, trackID, seconds):
millisec = round(seconds * 1000, 1)
LOG.info("%s[ID=%s] took %sms to process" % (title, trackID, millisec))
#######################################################
#######################################################
#######################################################
#### PLC Event Handling
#######################################################
def processConfirmAsync(trackID, induct, scanner, sorter, program=PROGRAM_PATH, carton=CARTON_PATH, device=DEFAULT_DEVICE, opcServer=DEFAULT_OPC_SERVER):
# This function handles confirm events, and logs the event in SQL
# Ensure ID is valid
if trackID > 0 and trackID < MAX_CARTONS:
def processConfirmInner():
start_time = time.time()
# Setup carton location:
devicePrefix = "[" + device + "]" + program
cartonPrefix = devicePrefix + carton + "[" + str(trackID) + "]"
# Read all carton data directly:
tags = [cartonPrefix + "." + path for path in DATA_PATHS]
values = [trackID, induct, scanner, sorter] + [value.value for value in system.opc.readValues(opcServer, tags)]
logTime("Confirm[PLC_READ]", trackID, time.time() - start_time)
start_time = time.time()
# Log confirm event in SQL:
# Insert into Package History:
system.db.runPrepUpdate(CONFIRM_INSERT_QUERY, values)
logTime("Confirm[DB_INSERT]", trackID, time.time() - start_time)
system.util.invokeAsynchronous(processConfirmInner)

View File

@ -1,7 +1,7 @@
{
"custom": {},
"params": {
"Tab_ID": 2,
"Tab_ID": 0,
"Table": "Status_tab"
},
"propConfig": {
@ -1569,7 +1569,6 @@
"width": 1.0016
},
"props": {
"currentTabIndex": 2,
"tabSize": {
"width": 130
},
@ -3290,7 +3289,7 @@
},
"props": {
"dismissOnSelect": false,
"formattedValue": "Aug 22, 2025 4:52 PM",
"formattedValue": "Aug 22, 2025 7:20 PM",
"formattedValues": {
"date": "Mar 26, 2021",
"datetime": "Mar 26, 2021 12:00 AM",
@ -3300,9 +3299,9 @@
"$": [
"ts",
192,
1755868962606
1755877827337
],
"$ts": 1755867162000
"$ts": 1755876027000
}
},
"type": "ia.input.date-time-input"
@ -3450,7 +3449,7 @@
},
"props": {
"dismissOnSelect": false,
"formattedValue": "Aug 22, 2025 5:22 PM",
"formattedValue": "Aug 22, 2025 7:50 PM",
"formattedValues": {
"date": "Mar 29, 2021",
"datetime": "Mar 29, 2021 1:37 PM",
@ -3460,9 +3459,9 @@
"$": [
"ts",
192,
1755868962606
1755877827337
],
"$ts": 1755868962000
"$ts": 1755877827000
}
},
"type": "ia.input.date-time-input"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1,208 +0,0 @@
{
"custom": {
"alarmHighlight": "",
"alarm_filter": {
"magnificaiton": "x2",
"show_VFD": true,
"show_beacons": true,
"show_buttons": true,
"show_camera_jams": true,
"show_dpm_mcm": true,
"show_encoders": true,
"show_epc": true,
"show_fio_safety": true,
"show_photoeyes": true
},
"areaHover": [],
"currentGraphic": "Windows/Graphics/Overview",
"demoHighlight": "",
"dexmanager": {
"config": {
"font": "bold 12px Arial",
"highlight": "#ff0"
},
"show": {
"Beacons": false,
"ConveyorLabels": true,
"ConveyorPatterns": true,
"Conveyors": true,
"DivertPaddles": true,
"EIPs": false,
"Encoders": false,
"Estops": false,
"Gaylords": true,
"LimitSwitches": false,
"MCPs": false,
"PhotoEyes": false,
"PushButtons": false,
"Scanners": false,
"VFDs": false
}
},
"fc": "BNA8",
"heatmapSettings": {
"alarms": [],
"alarmsText": "",
"data": {
"$": [
"ds",
192,
1754654890875
],
"$columns": [
{
"data": [],
"name": "firsttime",
"type": "Date"
},
{
"data": [],
"name": "lasttime",
"type": "Date"
},
{
"data": [],
"name": "duration",
"type": "String"
},
{
"data": [],
"name": "count",
"type": "Long"
},
{
"data": [],
"name": "device",
"type": "String"
},
{
"data": [],
"name": "description",
"type": "String"
}
]
},
"devices": [],
"devicesText": "",
"enabled": false,
"shifts": [],
"shiftsText": "",
"time": {
"end": "2020-07-30 00:00:00",
"start": "2020-07-29 00:00:00"
}
},
"searchId": "value",
"timewidget": {
"endDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604116800000
},
"mode": "currentDay",
"startDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604030400000
},
"update": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604092861010
}
}
},
"propConfig": {
"custom.dexmanager.highlight": {
"binding": {
"config": {
"struct": {
"alarm": "{this.custom.alarmHighlight}",
"demo": "{this.custom.demoHighlight}",
"toggle": "{[default]Gateway/ToggleTag}"
},
"waitOnAll": true
},
"transforms": [
{
"code": "\thighlights \u003d []\n\t# Add alarm highlight:\n\tif len(value.alarm) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [value.alarm]\n\t\t})\n\t\tif \".\" in value.alarm:\n\t\t\thighlights.append({\n\t\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\t\"keys\": [value.alarm.split(\".\")[0], \"conveyor\"]\n\t\t\t})\n\t# Add demo highlight:\n\tif False and len(value.demo) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [\"conveyor\", value.demo]\n\t\t})\n\treturn highlights",
"type": "script"
}
],
"type": "expr-struct"
}
},
"custom.isMobile": {
"binding": {
"config": {
"expression": "indexOf(lower({session.props.device.userAgent}), \"mobile\")\u003e\u003d0"
},
"type": "expr"
}
},
"props.auth": {
"access": "PRIVATE",
"persistent": false
},
"props.device.accelerometer": {
"access": "SYSTEM",
"persistent": false
},
"props.device.identifier": {
"access": "SYSTEM",
"persistent": false
},
"props.device.timezone": {
"access": "SYSTEM",
"persistent": false
},
"props.device.type": {
"access": "SYSTEM",
"persistent": false
},
"props.device.userAgent": {
"access": "SYSTEM",
"persistent": false
},
"props.gateway": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.data": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.permissionGranted": {
"access": "SYSTEM",
"persistent": false
},
"props.host": {
"access": "SYSTEM",
"persistent": false
},
"props.id": {
"access": "SYSTEM",
"persistent": false
},
"props.lastActivity": {
"access": "SYSTEM",
"persistent": false
}
},
"props": {
"address": "127.0.0.1",
"device": {},
"geolocation": {},
"locale": "en-US",
"timeZoneId": "Asia/Tbilisi"
}
}

View File

@ -1,24 +0,0 @@
WITH LANES AS (
SELECT
MIN(timestamp) AS start_timestamp,
MAX(timestamp) AS end_timestamp,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
lane_id AS induct,
SUM(count) AS total
FROM pe_history FORCE INDEX (timestamp)
WHERE timestamp BETWEEN :startDate AND :endDate
AND (lane_id LIKE "UL%" OR lane_id LIKE "PRS%" OR lane_id LIKE "RE%")
GROUP BY lane_id
ORDER BY lane_id
)
SELECT
start_timestamp,
end_timestamp,
induct,
/* Counts: */
total AS total_count,
/* PPH: */
ROUND(total*pph_multiplier) AS total_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent
FROM LANES;

View File

@ -1,251 +0,0 @@
{
"custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 0,
"string": "Unknown"
},
"params": {
"tagProps": [
"/system/mcm01/test",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.disconnected": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "!isGood({value})",
"type": "expression"
}
],
"type": "tag"
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
"type": "expression"
},
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": 1
},
{
"input": 0,
"output": 0
},
{
"input": 2,
"output": 2
},
{
"input": 3,
"output": 3
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Unknown",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "OK"
},
{
"input": 2,
"output": "Faulted"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 20,
"width": 40
}
},
"root": {
"children": [
{
"meta": {
"name": "Label"
},
"position": {
"height": 1,
"width": 1
},
"props": {
"text": "FIO",
"textStyle": {
"fontSize": "20px",
"textAlign": "center",
"textTransform": "uppercase"
}
},
"type": "ia.display.label"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-JR\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\t\n\talarm \u003d []\n\tmessage \u003d None\n\t\n\tsleep(0.5)\n\t\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_fio_safety"
},
"type": "property"
}
},
"props.style.backgroundColor": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#808080",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "#00FF00"
},
{
"input": 2,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"borderStyle": "solid",
"cursor": "pointer",
"overflow": "hidden"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,395 +0,0 @@
{
"custom": {
"hasControls": null,
"isRunning": false
},
"params": {
"label": "System",
"tagPath": "[default]SystemStatus",
"tagPaths": [],
"view": "Windows/Graphics/Overview"
},
"propConfig": {
"custom.hasControls": {
"binding": {
"config": {
"expression": "// Force refresh:\r\nif(now(1000)\u003dnow(1000),\r\n\t{view.params.tagPaths},\r\n\t{view.params.tagPaths}\r\n)"
},
"transforms": [
{
"code": "\ttags \u003d [tagPath + \"/SetStart.Quality\" for tagPath in value] + [tagPath + \"/SetStop.Quality\" for tagPath in value]\n\tqualities \u003d [v.getQuality() for v in system.tag.readBlocking(tags)]\n\tqualities \u003d [v \u003d\u003d v.Good for v in qualities]\n\treturn any(qualities) and len(qualities) \u003e 0",
"type": "script"
}
],
"type": "expr"
},
"persistent": true
},
"custom.isRunning": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/bStarted"
},
"type": "tag"
},
"persistent": true
},
"params.label": {
"paramDirection": "input",
"persistent": true
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
},
"params.tagPaths": {
"paramDirection": "input",
"persistent": true
},
"params.tagPaths[0]": {
"paramDirection": "input",
"persistent": true
},
"params.tagPaths[1]": {
"paramDirection": "input",
"persistent": true
},
"params.tagPaths[2]": {
"paramDirection": "input",
"persistent": true
},
"params.tagPaths[3]": {
"paramDirection": "input",
"persistent": true
},
"params.view": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 40,
"width": 125
}
},
"root": {
"children": [
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Status"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"props.style.backgroundColor": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}.jsonValues"
},
"transforms": [
{
"expression": "try(\r\n\tif(jsonGet({value}, \"Estop_Active\") \u0026\u0026 {[default]Gateway/ToggleTag},\r\n\t\t\"#F00\",\t\t// Estop\r\n\t\tif(jsonGet({value}, \"bStarted\"),\r\n\t\t\t\"#0F0\",\t// Running\r\n\t\t\t\"#AAA\"\t// Stopped\r\n\t\t)\r\n\t),\r\n\t\"#808080\" // Unknown\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": 1
}
},
"type": "ia.display.label"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Text"
},
"position": {
"height": "calc(100% - 10px)",
"width": "calc(100% - 10px)",
"x": 5,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "if({view.params.label} \u003d None || {view.params.label} \u003d \"\",\r\n\t{value},\r\n\t{view.params.label}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"backgroundColor": "#FFF",
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": 1,
"fontFamily": "var(--font-NotoSans)",
"fontSize": "12px",
"fontWeight": "bold",
"paddingLeft": "5px",
"textTransform": "uppercase",
"user-select": "none"
}
},
"type": "ia.display.label"
},
{
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tself.parent.openWindow()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "TooltipOverlay"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"props.status.tooltip": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "//\"System\u003cbr\u003eStatus: \"+if({view.custom.hasControls}, if({view.custom.isRunning}, \"Running\", \"Stopped\"), \"Unknown\")\r\njsonGet({value}, \"tooltip\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"status": {}
},
"type": "dex.display.tooltipoverlay"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPaths \u003d self.view.params.tagPaths\n\tif len(tagPaths) \u003e 0:\n\t\ttags \u003d [tagPath + \"/SetStart\" for tagPath in tagPaths]\n\t\tvalues \u003d [1]*len(tagPaths)\n\t\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Start"
},
"position": {
"height": 25,
"width": 25,
"x": "calc(100% - 60px)",
"y": "calc(50% - 12.5px)"
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"path": "view.custom.hasControls"
},
"type": "property"
}
},
"props.textStyle.color": {
"binding": {
"config": {
"path": "view.custom.isRunning"
},
"transforms": [
{
"expression": "if(isGood({value}), {value}, \"\")",
"type": "expression"
},
{
"fallback": "#888888",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "#32CD32"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "►",
"textStyle": {
"fontFamily": "Arial",
"fontSize": "14px"
}
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPaths \u003d self.view.params.tagPaths\n\tif len(tagPaths) \u003e 0:\n\t\ttags \u003d [tagPath + \"/SetStop\" for tagPath in tagPaths]\n\t\tvalues \u003d [1]*len(tagPaths)\n\t\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Stop"
},
"position": {
"height": 25,
"width": 25,
"x": "calc(100% - 32.5px)",
"y": "calc(50% - 12.5px)"
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"path": "view.custom.hasControls"
},
"type": "property"
}
},
"props.textStyle.color": {
"binding": {
"config": {
"path": "view.custom.isRunning"
},
"transforms": [
{
"expression": "if(isGood({value}), {value}, \"\")",
"type": "expression"
},
{
"fallback": "#888888",
"inputType": "scalar",
"mappings": [
{
"input": false,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "■",
"textStyle": {
"fontFamily": "monospace",
"fontSize": "14px"
}
},
"type": "ia.input.button"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"cursor": "pointer"
}
},
"scripts": {
"customMethods": [
{
"name": "openWindow",
"params": [],
"script": "\tview \u003d self.view.params.view\n\tif view in [\"\", None]:\n\t\tview \u003d \"Windows/Graphics/\"+self.getChild(\"Text\").props.text.replace(\" \", \"_\")\n\t# Open window:\n\twindow \u003d \"Windows/GraphicsWrapper\"\n\tparams \u003d {\"view\": view}\n\tsystem.perspective.navigate(\"/\")\n\tsystem.perspective.navigate(view\u003dwindow, params\u003dparams)"
}
],
"extensionFunctions": null,
"messageHandlers": []
},
"type": "ia.container.coord"
}
}

View File

@ -1,685 +0,0 @@
{
"custom": {
"title": ""
},
"params": {},
"permissions": {
"securityLevels": [],
"type": "AllOf"
},
"propConfig": {
"custom.title": {
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 400,
"width": 1600
}
},
"root": {
"children": [
{
"children": [
{
"meta": {
"name": "Table"
},
"position": {
"height": "100%",
"width": "100%"
},
"props": {
"cells": {
"style": {
"borderBottomColor": "#D5D5D5",
"borderBottomStyle": "solid",
"borderBottomWidth": "1px",
"borderRightColor": "#D5D5D5",
"borderRightStyle": "solid",
"borderRightWidth": "1px",
"color": "#000",
"fontFamily": "Helvetica",
"fontSize": "14px"
}
},
"columns": [
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "MM/DD/YYYY",
"editable": false,
"field": "eventtime",
"footer": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "left",
"style": {
"classes": ""
},
"title": ""
},
"justify": "auto",
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "#62A3F6",
"linecap": "round",
"width": 5
},
"max": 100,
"track": {
"color": "#DADADA",
"linecap": "round",
"width": 2
},
"value": {
"color": "#7D7D7D",
"show": true
}
},
"render": "auto",
"resizable": true,
"sort": "none",
"sortable": true,
"strictWidth": false,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "#2196F3",
"unselected": "#FFFFFF"
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": ""
}
],
"pager": {
"bottom": false
},
"rows": {
"highlight": {
"enabled": false
},
"striped": {
"enabled": false
},
"style": {
"classes": "table/highlight"
}
},
"style": {
"fontFamily": "Helvetica",
"fontSize": "14px",
"fontWeight": "bold"
}
},
"type": "ia.display.table"
}
],
"meta": {
"name": "Table"
},
"position": {
"height": "calc(100% - 40px)",
"width": "calc(100% - 250px)",
"x": 250,
"y": 40
},
"props": {
"style": {
"border-left": "2px solid #000",
"min-width": "450px"
}
},
"type": "ia.container.coord"
},
{
"meta": {
"name": "LabelHeader"
},
"position": {
"height": 40,
"width": "100%"
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"expression": " \"Custom Reports\"\r\n+if(len({view.custom.title})\u003e0, \" - \" + {view.custom.title}, \"\")"
},
"type": "expr"
}
}
},
"props": {
"style": {
"backgroundColor": "#1A4A5E",
"borderBottomColor": "#000000",
"borderBottomStyle": "solid",
"borderBottomWidth": "2px",
"color": "#fff",
"fontFamily": "Helvetica",
"fontSize": 20,
"fontWeight": "bold",
"textAlign": "center"
}
},
"type": "ia.display.label"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\t# Grab Data:\n\ttable \u003d self.parent.getChild(\"Table\").getChild(\"Table\")\n\tdata \u003d utils.downloadCSV(table, self.view.custom.title)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button_Export"
},
"position": {
"height": 30,
"width": 100,
"x": "calc(100% - 105px)",
"y": 5
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "Export"
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\treportTree \u003d self.getSibling(\"ReportTree\")\n\treportTree.meta.visible \u003d not reportTree.meta.visible"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button_Mode"
},
"position": {
"height": 32,
"width": 85,
"x": 4,
"y": 4
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"expression": "if({../ReportTree.meta.visible},\r\n\t\"Files\",\r\n\t\"Reports\"\r\n)"
},
"type": "expr"
},
"persistent": true
}
},
"props": {
"enabled": false,
"style": {
"classes": "Buttons/Grey"
},
"text": "Files"
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"draggable": false,
"id": "PABE2XXI",
"modal": true,
"overlayDismiss": true,
"resizable": false,
"showCloseIcon": true,
"title": "Upload Custom Report",
"type": "open",
"viewPath": "Popups/CustomReports/ConfigUpload"
},
"scope": "C",
"type": "popup"
}
}
},
"meta": {
"name": "Button_UploadConfig",
"visible": false
},
"position": {
"height": 32,
"width": 85,
"x": 93,
"y": 4
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"expression": "{../ReportTree.meta.visible}\r\n\u0026\u0026 ({session.props.device.type} \u003d \"designer\" || isAuthorized(\r\n\tfalse,\r\n\t\u0027Authenticated/Roles/Administrator\u0027,\r\n\t\u0027Authenticated/Roles/Developer\u0027\r\n))"
},
"type": "expr"
},
"persistent": true
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "Upload"
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\t# Get filenames:\n\ttree \u003d self.getSibling(\u0027ReportTree\u0027)\n\tfilenames \u003d [sel.value for sel in tree.props.selectionData]\n\t\n\terr \u003d reports.downloadConfigs(filenames)\n\n\t# Check if err:\n\tif err is not None:\n\t\tsystem.gui.messageBox(err, \"Error\")"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button_DownloadConfig",
"visible": false
},
"position": {
"height": 32,
"width": 95,
"x": 182,
"y": 4
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"expression": "{../ReportTree.meta.visible}\r\n\u0026\u0026 ({session.props.device.type} \u003d \"designer\" || isAuthorized(\r\n\tfalse,\r\n\t\u0027Authenticated/Roles/Administrator\u0027,\r\n\t\u0027Authenticated/Roles/Developer\u0027\r\n))"
},
"type": "expr"
},
"persistent": true
},
"props.enabled": {
"binding": {
"config": {
"path": "../ReportTree.props.selection"
},
"transforms": [
{
"code": "\treturn len(value)\u003e0",
"type": "script"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "Download"
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"draggable": false,
"id": "5QyUoYBU",
"modal": true,
"overlayDismiss": true,
"resizable": false,
"showCloseIcon": true,
"title": "Delete Confirmation",
"type": "open",
"viewParams": {
"filenames": "{/root/ReportTree.props.selectionData}"
},
"viewPath": "Popups/CustomReports/DeleteConfirmation"
},
"scope": "C",
"type": "popup"
}
}
},
"meta": {
"name": "Button_DeleteConfig",
"visible": false
},
"position": {
"height": 32,
"width": 85,
"x": 281,
"y": 4
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"expression": "{../ReportTree.meta.visible}\r\n\u0026\u0026 ({session.props.device.type} \u003d \"designer\" || isAuthorized(\r\n\tfalse,\r\n\t\u0027Authenticated/Roles/Administrator\u0027,\r\n\t\u0027Authenticated/Roles/Developer\u0027\r\n))"
},
"type": "expr"
},
"persistent": true
},
"props.enabled": {
"binding": {
"config": {
"path": "../ReportTree.props.selection"
},
"transforms": [
{
"code": "\treturn len(value)\u003e0",
"type": "script"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "Delete"
},
"type": "ia.input.button"
},
{
"meta": {
"name": "FileTree",
"visible": false
},
"position": {
"height": "calc(100% - 97px)",
"width": 250,
"y": 65
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"expression": "!{../ReportTree.meta.visible}"
},
"type": "expr"
},
"persistent": true
}
},
"props": {
"appearance": {
"defaultNodeIcons": {
"collapsed": {
"color": "#5F707E",
"path": "material/folder"
},
"empty": {
"color": "#869DB1",
"path": "material/stop"
},
"expanded": {
"color": "#5F707E",
"path": "material/folder_open"
}
},
"expandIcons": {
"collapsed": {
"color": "#869DB1",
"path": "material/arrow_right"
},
"empty": {
"color": "#869DB1"
},
"expanded": {
"color": "#869DB1",
"path": "material/arrow_drop_down"
}
},
"selectedStyle": {
"backgroundColor": "#BBE0F6",
"color": "#000",
"cursor": "pointer"
},
"unselectedStyle": {
"classes": "Tree/hoverUnselected",
"cursor": "pointer"
}
}
},
"type": "ia.display.tree"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\tsystem.perspective.print(self.getSibling(\"FileTree\").props.selection)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Button_DownloadFiles",
"visible": false
},
"position": {
"height": 32,
"y": "calc(100% - 32px)"
},
"propConfig": {
"meta.visible": {
"binding": {
"config": {
"path": "../FileTree.meta.visible"
},
"type": "property"
},
"persistent": true
},
"position.width": {
"binding": {
"config": {
"path": "../FileTree.position.width"
},
"type": "property"
}
},
"props.enabled": {
"binding": {
"config": {
"path": "../FileTree.props.selection"
},
"transforms": [
{
"code": "\treturn len(value)\u003e0",
"type": "script"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"classes": "Buttons/Grey"
},
"text": "Download Selected"
},
"type": "ia.input.button"
},
{
"events": {
"dom": {
"onDoubleClick": {
"config": {
"script": "\tdata \u003d self.props.selectionData\n\tif len(data) \u003d\u003d 1:\n\t\tconfig \u003d data[0].value\n\t\tresults \u003d reports.readTable(config)\n\t\t# Return data table:\n\t\tif \u0027err\u0027 in results:\n\t\t\tsystem.gui.messageBox(results[\u0027err\u0027], \"Error\")\n\t\telse:\n\t\t\ttable \u003d self.getSibling(\"Table\").getChild(\"Table\")\n\t\t\ttable.props.data \u003d results[\u0027data\u0027]\n\t\t\ttable.props.columns \u003d results[\u0027columns\u0027]\n\t\t\tself.view.custom.title \u003d \".\".join(config.split(\".\")[:-1])"
},
"scope": "G",
"type": "script"
}
},
"system": {
"onStartup": {
"config": {
"script": "\tself.refreshList()"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "ReportTree"
},
"position": {
"height": "calc(100% - 65px)",
"width": 250,
"y": 65
},
"props": {
"appearance": {
"defaultNodeIcons": {
"collapsed": {
"color": "#5F707E",
"path": "material/folder"
},
"empty": {
"color": "#869DB1",
"path": "material/stop"
},
"expanded": {
"color": "#5F707E",
"path": "material/folder_open"
}
},
"expandIcons": {
"collapsed": {
"color": "#869DB1",
"path": "material/arrow_right"
},
"empty": {
"color": "#869DB1"
},
"expanded": {
"color": "#869DB1",
"path": "material/arrow_drop_down"
}
},
"selectedStyle": {
"backgroundColor": "#BBE0F6",
"color": "#000",
"cursor": "pointer",
"user-select": "none"
},
"unselectedStyle": {
"classes": "Tree/hoverUnselected",
"cursor": "pointer",
"user-select": "none"
}
}
},
"scripts": {
"customMethods": [
{
"name": "refreshList",
"params": [],
"script": "\ticons \u003d {\n\t\t\"csv\": {\n\t\t\t\"path\": \"material/table_chart\",\n\t\t\t\"color\": \"#869DB1\"\n\t\t},\n\t\t\"sql\": {\n\t\t\t\"path\": \"material/storage\",\n\t\t\t\"color\": \"#869DB1\"\n\t\t}\n\t}\n\t\n\tconfigs \u003d []\n\troles \u003d self.session.props.auth.user.roles\n\tfor config in reports.getConfigs(roles\u003droles):\n\t\tparts \u003d config.split(\".\")\n\t\tconfigs.append({\n\t\t\t\"label\": \".\".join(parts[:-1]),\n\t\t\t\"expanded\": False,\n\t\t\t\"icon\": icons.get(parts[-1], \"\"),\n\t\t\t\"data\": config,\n\t\t\t\"items\": []\n\t\t})\n\t\n\tself.props.items \u003d configs"
}
],
"messageHandlers": [
{
"messageType": "custom-reports-refreshlist",
"pageScope": true,
"script": "\tself.refreshList()",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.tree"
},
{
"meta": {
"name": "LabelTree"
},
"position": {
"height": 25,
"width": 250,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"expression": "if({../ReportTree.meta.visible},\r\n\t\"On-Demand Reports\",\r\n\t\"Pre-Run Reports\"\r\n)"
},
"type": "expr"
},
"persistent": true
}
},
"props": {
"style": {
"backgroundColor": "#808080",
"borderBottomColor": "#000",
"borderBottomStyle": "solid",
"borderBottomWidth": 2,
"color": "#FFF",
"fontSize": "16px",
"fontWeight": "bold",
"textAlign": "center",
"user-select": "none"
},
"text": "On-Demand Reports"
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"min-width": "1000px"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,112 +0,0 @@
import re
import system
reDefault = re.compile(r'\[[^[]+\]')
def _extractParameter(params, parameter, path):
val = params[parameter].value
if hasattr(val, "bindType"):
return system.tag.readBlocking([path+"/Parameters."+parameter])[0].value
else:
return val
def _isGroupedUDT(obj):
for tag in obj["tags"]:
if tag["name"] in ["Graphics", "StatusText"]:
return False
return True
def getSiblingDevices(tagPath, filterType=None, filterTagPath=True):
devices = []
def extractStatusText(obj, path):
# Scan for status text tag:
for tag in obj["tags"]:
if tag["name"] == "StatusText":
return "[ignition]" + reDefault.sub("", path) + "/StatusText"
# Couldn't find it, so return None:
return None
def scan(obj, parentPath):
if isinstance(obj, list):
for tag in obj:
scan(tag, parentPath)
else:
path = parentPath + "/" + obj["name"]
if str(obj["tagType"]) == "Folder" or (str(obj["tagType"]) == "UdtInstance" and (tagPath <> path or not filterTagPath) and _isGroupedUDT(obj)):
for tag in obj["tags"]:
scan(tag, path)
elif str(obj["tagType"]) == "UdtInstance" and (tagPath <> path or not filterTagPath):
params = obj["parameters"]
# Make sure this is a renderable device:
if "DeviceType" in params:
deviceType = _extractParameter(params, "DeviceType", path)
if filterType == None or deviceType in filterType:
labelFull = _extractParameter(params, "LabelFull", path)
devices.append({
"deviceType": deviceType,
"tagPath": path,
"device": labelFull,#"[ignition]" + reDefault.sub("", path) + "/Parameters.LabelFull",
"status": extractStatusText(obj, path)
})
# Scan devices:
if tagPath not in [None, ""]:
tagPath = reDefault.sub("", tagPath) # Remove [default] from tagpath
parentPath = "/".join(tagPath.split("/")[:-1])
config = system.tag.getConfiguration(parentPath, True)
#system.perspective.print(parentPath)
#system.perspective.print(config)
if len(config) > 0 and "tags" in config[0]:
scan(config[0]["tags"], parentPath)
devices.sort(key=lambda x: x["device"])
return devices
def _isTagOPC(path):
try:
return system.tag.readBlocking([path+".ValueSource"])[0].value == "opc"
except:
return False
def _isTagEnabled(path):
try:
return system.tag.readBlocking([path+".Enabled"])[0].value
except:
return False
def getOPCTags(tagPath):
tags = []
def scan(obj, parentPath, relPath=""):
if isinstance(obj, list):
for tag in obj:
scan(tag, parentPath, relPath)
elif "name" in obj:
path = parentPath + "/" + obj["name"]
if "tags" in obj:
# Scan deeper:
relPath = relPath + obj["name"] + "/"
for tag in obj["tags"]:
scan(tag, path, relPath)
else:
if _isTagEnabled(path) and _isTagOPC(path):#and obj["name"] not in ["Graphics"]:
# Found an OPC tag:
tags.append({
"tagName": relPath + obj["name"],
"tagType": "opc",
"tagPath": "[ignition]" + path + ".OpcItemPath",
"tagValue": "[ignition]" + path,
"tagTooltip": "[ignition]" + path + ".Tooltip",
"tagDocumentation": "[ignition]" + path + ".Documentation"
})
# Scan devices:
if tagPath not in [None, ""]:
tagPath = reDefault.sub("", tagPath) # Remove [default] from tagpath
config = system.tag.getConfiguration(tagPath, True)
if len(config) > 0 and "tags" in config[0]:
scan(config[0]["tags"], tagPath)
tags.sort(key=lambda x: x["tagName"])
return tags

View File

@ -1,34 +0,0 @@
WITH SCANNERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:%i:00") AS time,
COUNT(*) AS total,
SUM(scanner_status NOT IN ("No Read", "No Code", "Multi Label")) AS good_read,
SUM(scanner_status = "No Read") AS no_read,
SUM(scanner_status = "No Code") AS no_code,
SUM(scanner_status = "Multi Label") AS multi_label
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND scanner = :scanner
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
)
SELECT
time,
/* Counts: */
total AS total_count,
good_read AS good_read_count,
no_read AS no_read_count,
no_code AS no_code_count,
multi_label AS multi_label_count,
/* PPH: */
ROUND(total*60) AS total_pph,
ROUND(good_read*60) AS good_read_pph,
ROUND(no_read*60) AS no_read_pph,
ROUND(no_code*60) AS no_code_pph,
ROUND(multi_label*60) AS multi_label_pph,
/* Percents: */
ROUND(good_read/total, 4) AS good_read_percent,
ROUND(no_read/total, 4) AS no_read_percent,
ROUND(no_code/total, 4) AS no_code_percent,
ROUND(multi_label/total, 4) AS multi_label_percent
FROM SCANNERS;

View File

@ -1,73 +0,0 @@
WITH LANES_SUCCESS AS (
SELECT
MIN(s04_timestamp) AS start_timestamp,
MAX(s04_timestamp) AS end_timestamp,
sorter,
destination_act AS lane,
COUNT(*) AS total
FROM package_history a
WHERE s04_timestamp BETWEEN :startDate AND :endDate
GROUP BY sorter, s04_act_dest
), LANES_FAIL_REQ AS (
SELECT
MIN(s04_timestamp) AS start_timestamp,
MAX(s04_timestamp) AS end_timestamp,
sorter,
CONCAT(sorter, LPAD(s02_req_dest, 2, '0')) AS lane,
SUM(req_dest_reason=5) AS dest_full,
SUM(req_dest_reason=6) AS dest_fault,
SUM(req_dest_reason=12) AS dest_disabled
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND s04_act_dest != s02_req_dest
GROUP BY sorter, s02_req_dest
), LANES_FAIL_ALT AS (
SELECT
MIN(s04_timestamp) AS start_timestamp,
MAX(s04_timestamp) AS end_timestamp,
sorter,
CONCAT(sorter, LPAD(s02_alt_dest, 2, '0')) AS lane,
SUM(alt_dest_reason=5) AS dest_full,
SUM(alt_dest_reason=6) AS dest_fault,
SUM(alt_dest_reason=12) AS dest_disabled
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND s04_act_dest != s02_alt_dest
GROUP BY sorter, s02_alt_dest
), LANES AS (
SELECT
LEAST(s.start_timestamp, IFNULL(r.start_timestamp, s.start_timestamp), IFNULL(r.start_timestamp, a.start_timestamp)) AS start_timestamp,
GREATEST(s.end_timestamp, IFNULL(r.end_timestamp, s.end_timestamp), IFNULL(r.end_timestamp, a.end_timestamp)) AS end_timestamp,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
s.sorter,
s.lane,
s.total,
IFNULL(r.dest_full, 0)+IFNULL(a.dest_full, 0) AS dest_full,
IFNULL(r.dest_fault, 0)+IFNULL(a.dest_fault, 0) AS dest_fault,
IFNULL(r.dest_disabled, 0)+IFNULL(a.dest_disabled, 0) AS dest_disabled
FROM LANES_SUCCESS s
LEFT JOIN LANES_FAIL_REQ r ON s.sorter=r.sorter AND s.lane=r.lane
LEFT JOIN LANES_FAIL_ALT a ON s.sorter=a.sorter AND s.lane=a.lane
)
SELECT
start_timestamp,
end_timestamp,
sorter,
lane,
/* Counts: */
total AS total_count,
dest_full AS dest_full_count,
dest_fault AS dest_fault_count,
dest_disabled AS dest_disabled_count,
/* PPH: */
ROUND(total*pph_multiplier) AS total_pph,
ROUND(dest_full*pph_multiplier) AS dest_full_pph,
ROUND(dest_fault*pph_multiplier) AS dest_fault_pph,
ROUND(dest_disabled*pph_multiplier) AS dest_disabled_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent,
ROUND(dest_full/total, 4) AS dest_full_percent,
ROUND(dest_fault/total, 4) AS dest_fault_percent,
ROUND(dest_disabled/total, 4) AS dest_disabled_percent
FROM LANES
ORDER BY sorter, lane;

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@ -1,64 +0,0 @@
WITH ALARM_TIMELAPSES AS (
/* Group related active & clear events into a single row */
SELECT
id, /* Unique to each row in alarm_events, used to look up metadata in alarm_event_data */
source, /* Unique alarm path in Ignition */
eventtime AS starttime,
displaypath, /* Get description */
/* Get the last time this event was active within the given time range*/
CAST(LEAST(COALESCE((
/* Search for the clear event (if exists) for the outer query's active event */
SELECT MIN(eventtime)
FROM alarm_events e2
WHERE e2.eventid = e.eventid /* eventid is unique per alarm instance */
AND e2.eventtime >= e.eventtime
AND e2.eventtype = 1 /* Look only for the clear event */
ORDER BY eventtime ASC
), NOW()), :endDate) AS DATETIME) AS endtime, /* Clamp to end of time range if clear event is after end time */
priority
FROM alarm_events e
/* The range for both start/end allows for index optimizations */
WHERE eventtime BETWEEN :startDate AND :endDate
/* Filter shifts */
{shifts}
/* Filter alarm types */
AND displaypath IN ({alarms})
/* Filter out active events */
AND eventtype = 0
), HITLIST AS (
/* Group the same type of alarms together to get hit counts and total durations */
SELECT
MAX(id) AS id, /* Use latest id to get the latest metadata */
MIN(starttime) AS firsttime, /* Get the earliest it's been active in the given time range */
MAX(endtime) AS lasttime, /* Get the latest it's been active in the given time range */
MIN(displaypath) AS displaypath, /* Get one of the displaypaths associated with source */
MAX(priority) AS priority,
COUNT(*) AS count,
SUM(TIME_TO_SEC(TIMEDIFF(endtime, starttime))) AS duration
FROM ALARM_TIMELAPSES
GROUP BY source
ORDER BY count DESC
LIMIT 2000
)
/* Finally, merge metadata into hitlist */
SELECT
/*e.firsttime, e.lasttime,*/
/* Translate duration to a string */
CAST(SEC_TO_TIME(FLOOR(e.duration)) AS CHAR) AS duration,
/* Retrieve instance count and total duration */
e.count,
dtag.strvalue AS plctag,
ddevice.strvalue AS device,
displaypath AS description
FROM HITLIST e
/* Lookup Device */
JOIN alarm_event_data dtag ON e.id = dtag.id AND dtag.propname = "PLCTag"
/* Lookup Device */
JOIN alarm_event_data ddevice ON e.id = ddevice.id AND ddevice.propname = "Device"
/* Lookup Class */
JOIN alarm_event_data dclass ON e.id = dclass.id AND dclass.propname = "Class"
/* Lookup DeviceType */
JOIN alarm_event_data dtype ON e.id = dtype.id AND dtype.propname = "DeviceType"
WHERE dclass.strvalue IN ("Error", "Warning")
AND ddevice.strvalue NOT IN ("Ignition")
AND SUBSTRING_INDEX(dtype.strvalue, "_", 1) IN ({devices});

View File

@ -1,83 +0,0 @@
WITH ALARM_TIMELAPSES AS (
/* Group related active & clear events into a single row */
SELECT
e.id, /* Unique to each row in alarm_events, used to look up metadata in alarm_event_data */
source, /* Unique alarm path in Ignition */
eventtime AS starttime,
displaypath, /* Get description */
/* Get the last time this event was active within the given time range*/
CAST(LEAST(COALESCE((
/* Search for the clear event (if exists) for the outer query's active event */
SELECT MIN(eventtime)
FROM alarm_events e2
WHERE e2.eventid = e.eventid /* eventid is unique per alarm instance */
AND e2.eventtime >= e.eventtime
AND e2.eventtype = 1 /* Look only for the clear event */
ORDER BY eventtime ASC
), NOW()), :endDate) AS DATETIME) AS endtime, /* Clamp to end of time range if clear event is after end time */
priority
FROM alarm_events e
/* The range for both start/end allows for index optimizations */
WHERE e.eventtime BETWEEN :startDate AND :endDate
/* Filter for disabled messages, full messages, and jam messages */
AND e.displaypath IN ("Available", "Full", "Full Warn", "25% Full Warn", "50% Full Warn", "75% Full Warn", "HMI Chute Disabled", "Jammed", "EStop or Faulted")
/* Filter out system events and active events only */
AND e.eventflags & 1 != 1 AND e.eventtype = 0
), HITLIST AS (
/* Group the same type of alarms together to get hit counts and total durations */
SELECT
MAX(id) AS id, /* Use latest id to get the latest metadata */
MIN(starttime) AS firsttime, /* Get the earliest it's been active in the given time range */
MAX(endtime) AS lasttime, /* Get the latest it's been active in the given time range */
MIN(displaypath) AS displaypath, /* Get one of the displaypaths associated with source */
MAX(priority) AS priority,
COUNT(*) AS count,
SUM(TIME_TO_SEC(TIMEDIFF(endtime, starttime))) AS duration
FROM ALARM_TIMELAPSES
GROUP BY source
ORDER BY count DESC
LIMIT 2000
), HITLIST_DATA AS (
/* Finally, merge metadata into hitlist */
SELECT e.id,
e.firsttime, e.lasttime,
SUBSTRING_INDEX(SUBSTRING_INDEX(dtag.strvalue, ']', 1), '[', -1) AS sorter,
SUBSTRING_INDEX(ddevice.strvalue, '.', 1) AS lane,
displaypath AS description,
/* Retrieve instance count and total duration */
e.count,
e.duration
FROM HITLIST e
/* Lookup PLCTag */
JOIN alarm_event_data dtag ON e.id = dtag.id AND dtag.propname = "PLCTag"
/* Lookup Device */
JOIN alarm_event_data ddevice ON e.id = ddevice.id AND ddevice.propname = "Device"
)
SELECT
DATE_FORMAT(MIN(firsttime), '%Y-%m-%d %T') AS start_timestamp,
DATE_FORMAT(MAX(lasttime), '%Y-%m-%d %T') AS end_timestamp,
lane,
/* Counts */
SUM(IF(description="Available", count, 0)) AS available_count,
SUM(IF(description="Full", count, 0)) AS full_count,
SUM(IF(description IN ("Full Warn", "50% Full Warn"), count, 0)) AS full_warn_count,
SUM(IF(description="25% Full Warn", count, 0)) AS full_warn_25_count,
SUM(IF(description IN ("Full Warn", "50% Full Warn"), count, 0)) AS full_warn_50_count,
SUM(IF(description="75% Full Warn", count, 0)) AS full_warn_75_count,
SUM(IF(description="HMI Chute Disabled", count, 0)) AS disabled_count,
SUM(IF(description="Jammed", count, 0)) AS jam_count,
SUM(IF(description="EStop or Faulted", count, 0)) AS faulted_count,
/* Durations, translated to strings */
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="Available", duration, 0)))) AS CHAR) AS available_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="Full", duration, 0)))) AS CHAR) AS full_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description IN ("Full Warn", "50% Full Warn"), duration, 0)))) AS CHAR) AS full_warn_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="25% Full Warn", duration, 0)))) AS CHAR) AS full_warn_25_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description IN ("Full Warn", "50% Full Warn"), duration, 0)))) AS CHAR) AS full_warn_50_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="75% Full Warn", duration, 0)))) AS CHAR) AS full_warn_75_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="HMI Chute Disabled", duration, 0)))) AS CHAR) AS disabled_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="Jammed", duration, 0)))) AS CHAR) AS jam_duration,
CAST(SEC_TO_TIME(FLOOR(SUM(IF(description="EStop or Faulted", duration, 0)))) AS CHAR) AS faulted_duration
FROM HITLIST_DATA
WHERE {where}
GROUP BY lane
ORDER BY lane;

View File

@ -1,3 +0,0 @@
SELECT DISTINCT induct
FROM package_history
ORDER BY induct ASC;

View File

@ -1,46 +0,0 @@
WITH SORTERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:00") AS start_timestamp,
CONCAT("H",
CAST(
TIMESTAMPDIFF(
HOUR,
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:00:00"),
DATE_FORMAT(LEAST(CURRENT_TIMESTAMP(), :endDate), "%Y-%m-%d %H:00:00")
) AS CHAR
)
) AS hour,
COUNT(*) AS total,
SUM(sort_code="Success") AS success,
SUM(sort_code IN ("Dest Invalid", "Dest None", "Underutilized")) AS awcs,
SUM(sort_code IN ("Dest Disabled", "Dest Full", "Dim Error", "Unexpected", "Weight Err")) AS operational,
SUM(sort_code IN ("Dest Fault", "Div Fail", "Gap Err", "Lost", "Rate High", "Track Err", "Unknown", "Unsafe")) AS machine,
SUM(sort_code IN ("No Read", "No Code", "Multi Label")) AS scanner
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND sorter=:sorter
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:00")
)
SELECT
start_timestamp AS time,
hour,
/* Counts: */
success AS success_count,
awcs AS awcs_issues_count,
operational AS operational_issues_count,
machine AS machine_issues_count,
scanner AS scanner_issues_count,
/* PPH: */
success AS success_pph,
awcs AS awcs_issues_pph,
operational AS operational_issues_pph,
machine AS machine_issues_pph,
scanner AS scanner_issues_pph,
/* Percents: */
ROUND(success/total, 4) AS success_percent,
ROUND(awcs/total, 4) AS awcs_issues_percent,
ROUND(operational/total, 4) AS operational_issues_percent,
ROUND(machine/total, 4) AS machine_issues_percent,
ROUND(scanner/total, 4) AS scanner_issues_percent
FROM SORTERS
ORDER BY start_timestamp;

View File

@ -1,18 +0,0 @@
WITH LANES AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:%i:00") AS time,
COUNT(*) AS total
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND destination_act = :lane
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
)
SELECT
time,
/* Counts: */
total AS total_count,
/* PPH: */
ROUND(total*60) AS total_pph
/* Percents: */
FROM LANES;

View File

@ -1,209 +0,0 @@
{
"custom": {
"alarmHighlight": "",
"alarm_filter": {
"show_VFD": true,
"show_beacons": true,
"show_buttons": true,
"show_camera_jams": true,
"show_dpm_mcm": true,
"show_encoders": true,
"show_epc": true,
"show_fio_safety": true,
"show_map": true,
"show_photoeyes": true,
"show_px": true
},
"areaHover": [],
"currentGraphic": "Windows/Graphics/Overview",
"demoHighlight": "",
"dexmanager": {
"config": {
"font": "bold 12px Arial",
"highlight": "#ff0"
},
"show": {
"Beacons": false,
"ConveyorLabels": true,
"ConveyorPatterns": true,
"Conveyors": true,
"DivertPaddles": true,
"EIPs": false,
"Encoders": false,
"Estops": false,
"Gaylords": true,
"LimitSwitches": false,
"MCPs": false,
"PhotoEyes": false,
"PushButtons": false,
"Scanners": false,
"VFDs": false
}
},
"fc": "BNA8",
"heatmapSettings": {
"alarms": [],
"alarmsText": "",
"data": {
"$": [
"ds",
192,
1754654890875
],
"$columns": [
{
"data": [],
"name": "firsttime",
"type": "Date"
},
{
"data": [],
"name": "lasttime",
"type": "Date"
},
{
"data": [],
"name": "duration",
"type": "String"
},
{
"data": [],
"name": "count",
"type": "Long"
},
{
"data": [],
"name": "device",
"type": "String"
},
{
"data": [],
"name": "description",
"type": "String"
}
]
},
"devices": [],
"devicesText": "",
"enabled": false,
"shifts": [],
"shiftsText": "",
"time": {
"end": "2020-07-30 00:00:00",
"start": "2020-07-29 00:00:00"
}
},
"searchId": "value",
"timewidget": {
"endDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604116800000
},
"mode": "currentDay",
"startDate": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604030400000
},
"update": {
"$": [
"ts",
192,
1604092861010
],
"$ts": 1604092861010
}
}
},
"propConfig": {
"custom.dexmanager.highlight": {
"binding": {
"config": {
"struct": {
"alarm": "{this.custom.alarmHighlight}",
"demo": "{this.custom.demoHighlight}",
"toggle": "{[default]Gateway/ToggleTag}"
},
"waitOnAll": true
},
"transforms": [
{
"code": "\thighlights \u003d []\n\t# Add alarm highlight:\n\tif len(value.alarm) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [value.alarm]\n\t\t})\n\t\tif \".\" in value.alarm:\n\t\t\thighlights.append({\n\t\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\t\"keys\": [value.alarm.split(\".\")[0], \"conveyor\"]\n\t\t\t})\n\t# Add demo highlight:\n\tif False and len(value.demo) \u003e 0:\n\t\thighlights.append({\n\t\t\t\"color\": \"#F00\" if value.toggle else \"#FF0\",\n\t\t\t\"keys\": [\"conveyor\", value.demo]\n\t\t})\n\treturn highlights",
"type": "script"
}
],
"type": "expr-struct"
}
},
"custom.isMobile": {
"binding": {
"config": {
"expression": "indexOf(lower({session.props.device.userAgent}), \"mobile\")\u003e\u003d0"
},
"type": "expr"
}
},
"props.auth": {
"access": "PRIVATE",
"persistent": false
},
"props.device.accelerometer": {
"access": "SYSTEM",
"persistent": false
},
"props.device.identifier": {
"access": "SYSTEM",
"persistent": false
},
"props.device.timezone": {
"access": "SYSTEM",
"persistent": false
},
"props.device.type": {
"access": "SYSTEM",
"persistent": false
},
"props.device.userAgent": {
"access": "SYSTEM",
"persistent": false
},
"props.gateway": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.data": {
"access": "SYSTEM",
"persistent": false
},
"props.geolocation.permissionGranted": {
"access": "SYSTEM",
"persistent": false
},
"props.host": {
"access": "SYSTEM",
"persistent": false
},
"props.id": {
"access": "SYSTEM",
"persistent": false
},
"props.lastActivity": {
"access": "SYSTEM",
"persistent": false
}
},
"props": {
"address": "127.0.0.1",
"device": {},
"geolocation": {},
"locale": "en-US",
"timeZoneId": "Asia/Tbilisi"
}
}

View File

@ -1,19 +0,0 @@
WITH INDUCTS AS (
SELECT
DATE_FORMAT(MIN(timestamp), "%Y-%m-%d %H:%i:00") AS time,
SUM(count) AS total
FROM pe_history
WHERE timestamp BETWEEN :startDate AND :endDate
AND lane_id = :chute
GROUP BY DATE_FORMAT(timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(timestamp, "%Y-%m-%d %H:%i:00")
)
SELECT
time,
/* Counts: */
total AS total_count,
/* PPH: */
ROUND(total*60) AS total_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent
FROM INDUCTS;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

View File

@ -1,45 +0,0 @@
WITH INDUCTS AS (
SELECT
MIN(s04_timestamp) AS start_timestamp,
MAX(s04_timestamp) AS end_timestamp,
sorter,
induct,
COUNT(*) AS total,
SUM(carriers=1) AS single_carrier,
SUM(carriers=2) AS double_carrier,
AVG(pkg_length/10) AS pkg_length_avg,
AVG(gap_leading/10) AS gap_avg
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
GROUP BY sorter, induct
), SORTERS AS (
SELECT
sorter,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
SUM(total) AS total
FROM INDUCTS
GROUP BY sorter
)
SELECT
I.start_timestamp,
I.end_timestamp,
S.sorter,
I.induct,
/* Averages: */
ROUND(I.pkg_length_avg, 1) AS 'avg_package_length_(")',
ROUND(I.gap_avg, 1) AS 'avg_gap_(")',
/* Counts: */
I.total AS total_count,
I.single_carrier AS single_carrier_count,
I.double_carrier AS double_carrier_count,
/* PPH: */
ROUND(I.total*S.pph_multiplier) AS total_pph,
ROUND(I.single_carrier*S.pph_multiplier) AS single_carrier_pph,
ROUND(I.double_carrier*S.pph_multiplier) AS double_carrier_pph,
/* Percents: */
ROUND(I.total/S.total, 4) AS 'total/sorter_percent',
ROUND(I.single_carrier/I.total, 4) AS single_carrier_percent,
ROUND(I.double_carrier/I.total, 4) AS double_carrier_percent
FROM INDUCTS I, SORTERS S
WHERE I.sorter = S.sorter
ORDER BY S.sorter, I.induct;

View File

@ -1,130 +0,0 @@
{
"custom": {},
"params": {
"titleExtra": "625 rows",
"usesTimewidget": false
},
"propConfig": {
"params.titleExtra": {
"paramDirection": "output",
"persistent": true
},
"params.usesTimewidget": {
"binding": {
"config": {
"expression": "false"
},
"type": "expr"
},
"paramDirection": "output",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 324,
"width": 1600
}
},
"root": {
"children": [
{
"meta": {
"name": "Ethernet"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"props.columns": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "direct",
"tagPath": "[default]Gateway/Ethernet"
},
"transforms": [
{
"expression": "jsonGet({value}, \"columns\")",
"type": "expression"
}
],
"type": "tag"
}
},
"props.data": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "direct",
"tagPath": "[default]Gateway/Ethernet"
},
"transforms": [
{
"code": "\tcou \u003d utils.getRowCount(value.data)\n\tself.view.params.titleExtra \u003d \"{:n} rows\".format(cou)\n\t# Return data\n\treturn value.data",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"cells": {
"style": {
"borderBottomColor": "#D5D5D5",
"borderBottomStyle": "solid",
"borderBottomWidth": "2px",
"borderRightColor": "#D5D5D5",
"borderRightStyle": "solid",
"borderRightWidth": "2px",
"color": "#000",
"fontFamily": "Helvetica",
"fontSize": "14px"
}
},
"filter": {
"enabled": true
},
"pager": {
"bottom": false
},
"rows": {
"highlight": {
"enabled": false
},
"striped": {
"enabled": false
},
"style": {
"classes": "table/highlight"
}
},
"style": {
"fontFamily": "Helvetica",
"fontSize": "14px",
"fontWeight": "bold"
}
},
"scripts": {
"customMethods": [],
"messageHandlers": [
{
"messageType": "export-data",
"pageScope": true,
"script": "\tutils.downloadCSV(self, \"Ethernet\")",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.table"
}
],
"meta": {
"name": "root"
},
"type": "ia.container.coord"
}
}

View File

@ -1,286 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "Conveyor"
},
"props": {
"config": {
"enableHighlight": true,
"isClickable": false,
"showLabel": true,
"type": "belt"
},
"status": {
"color": {
"inner": "#D2B48C",
"outer": "#C49C67"
},
"showAlways": false,
"tagPath": "",
"tooltip": ""
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 105,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "Gaylord"
},
"position": {
"height": 48,
"width": 48,
"x": 76,
"y": 11
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "try(\r\n\tjsonSet({value}, \"showAlways\", true),\r\n\t{view.params.props.status}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"type": "dex.display.gaylord"
},
{
"meta": {
"name": "lbStatus"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"code": "\treturn utils.extractStatus(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbName"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027\u0027)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_1"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 5
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Name: "
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_11"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 40
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Status:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_12"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 75
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Panel:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus_0"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 75
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.OPC_Server"
},
"transforms": [
{
"expression": "coalesce({value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,274 +0,0 @@
{
"custom": {
"disconnected": true,
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Unknown"
},
"params": {
"tagProps": [
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.disconnected": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "!isGood({value})",
"type": "expression"
}
],
"type": "tag"
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
"type": "expression"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Unknown",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "Start"
},
{
"input": 2,
"output": "Start Pressed"
},
{
"input": 3,
"output": "Start Illuminated"
},
{
"input": 4,
"output": "Start Pressed / Illuminated"
},
{
"input": 5,
"output": "Stop"
},
{
"input": 6,
"output": "Stop Pressed"
},
{
"input": 7,
"output": "Stop Illuminated"
},
{
"input": 8,
"output": "Stop Pressed / Illuminated"
},
{
"input": 9,
"output": "Restart"
},
{
"input": 10,
"output": "Restart Pressed"
},
{
"input": 11,
"output": "Restart Illuminated"
},
{
"input": 12,
"output": "Restart Pressed / Illuminated"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 25,
"width": 25
}
},
"root": {
"children": [
{
"meta": {
"name": "JR_Button"
},
"position": {
"height": 1,
"width": 1
},
"propConfig": {
"props.elements[0].fill.paint": {
"binding": {
"config": {
"expression": "if(\r\n {view.custom.state} \u003d 0, \"#a9a9a9\", // disconnected gray (DarkGray)\r\n if(\r\n {view.custom.state} % 2 \u003d 1, \"#ffffff\", // white\r\n \"#000000\" // black\r\n )\r\n)\r\n"
},
"type": "expr"
}
},
"props.elements[1].fill.paint": {
"binding": {
"config": {
"expression": "if({view.custom.state} \u003d 0, \"#a9a9a9\", // disconnected gray\r\n if({view.custom.state} \u003d 1 || {view.custom.state} \u003d 2, \"#90ee90\", // light green\r\n if({view.custom.state} \u003d 3 || {view.custom.state} \u003d 4, \"#228B22\", // softer dark green\r\n if({view.custom.state} \u003d 5 || {view.custom.state} \u003d 6, \"#ffc0cb\", // pink\r\n if({view.custom.state} \u003d 7 || {view.custom.state} \u003d 8, \"#ff0000\", // red\r\n if({view.custom.state} \u003d 9 || {view.custom.state} \u003d 10, \"#808080\", // normal gray\r\n if({view.custom.state} \u003d 11 || {view.custom.state} \u003d 12, \"#ffffff\", \"\") // white\r\n )\r\n )\r\n )\r\n )\r\n )\r\n)\r\n"
},
"type": "expr"
}
}
},
"props": {
"elements": [
{
"d": "M 0,0 H 20 V 20 H 0 Z",
"fill": {},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "1.5"
},
"type": "path"
},
{
"d": "m 17,10.5 a 7,7 0 0 1 -7,7 7,7 0 0 1 -7,-7 7,7 0 0 1 7,-7 7,7 0 0 1 7,7 z",
"fill": {},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "1"
},
"type": "path"
}
],
"viewBox": "0 0 20 20"
},
"type": "ia.shapes.svg"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-JR\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\t\n\talarm \u003d []\n\tmessage \u003d None\n\t\n\tsleep(0.5)\n\t\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_buttons"
},
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"cursor": "pointer"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,4 +0,0 @@
SELECT DISTINCT lane_id
FROM pe_history
WHERE lane_id LIKE "RS%4CH"
ORDER BY lane_id;

View File

@ -1,69 +0,0 @@
{
"custom": {},
"events": {
"system": {
"onShutdown": {
"config": {
"script": "\tsystem.perspective.sendMessage(\"custom-documents-refreshlist\", {})"
},
"scope": "G",
"type": "script"
}
}
},
"params": {
"parentFolder": ""
},
"propConfig": {
"params.parentFolder": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 300,
"width": 400
}
},
"root": {
"children": [
{
"events": {
"component": {
"onFileReceived": {
"config": {
"script": "\tdocuments.uploadDocument(event.file, self.view.params.parentFolder)\n\t\n\t# Close popup:\n\t#system.perspective.closePopup(\"\")"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "FileUpload"
},
"position": {
"height": "100%",
"width": "100%"
},
"props": {
"fileSizeLimit": 100,
"maxUploads": 10,
"supportedFileTypes": [
"pdf"
]
},
"type": "ia.input.fileupload"
}
],
"meta": {
"name": "root"
},
"position": {
"x": 3,
"y": -7
},
"type": "ia.container.coord"
}
}

View File

@ -1,14 +0,0 @@
{
"base": {
"style": {
"backgroundColor": "#2D7D9F",
"borderBottomColor": "#D5D5D5",
"borderBottomStyle": "solid",
"borderBottomWidth": "1px",
"borderRightColor": "#D5D5D5",
"borderRightStyle": "solid",
"borderRightWidth": "1px",
"color": "#FFF"
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,233 +0,0 @@
{
"custom": {
"plc": "",
"searchId": "value",
"state": 1,
"string": "Actuated"
},
"params": {
"tagProps": [
"/system/mcm01/test",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},0)",
"type": "expression"
},
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": 1
},
{
"input": 0,
"output": 0
},
{
"input": 2,
"output": 2
},
{
"input": 3,
"output": 3
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Unknown",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "Actuated"
},
{
"input": 2,
"output": "Faulted"
},
{
"input": 0,
"output": "Inactive"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 22,
"width": 25
}
},
"root": {
"children": [
{
"meta": {
"name": "Label"
},
"position": {
"height": 1,
"width": 1
},
"props": {
"text": "SOL",
"textStyle": {
"fontSize": 10,
"textAlign": "center",
"textTransform": "uppercase"
}
},
"type": "ia.display.label"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-JR\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\t\n\talarm \u003d []\n\tmessage \u003d None\n\t\n\tsleep(0.5)\n\t\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_beacons"
},
"type": "property"
}
},
"props.style.backgroundColor": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#808080",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "#00FF00"
},
{
"input": 2,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"borderStyle": "solid",
"cursor": "pointer",
"overflow": "hidden"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,98 +0,0 @@
WITH DISABLE_EVENTS AS (
/* Group related active & clear events into a single row */
SELECT
id,
NOT eventtype AS eventtype,
IF(eventtype = 1, COALESCE(LEAD(eventid, 1) OVER w, source), eventid) AS eventid,
source, /* Unique alarm path in Ignition */
eventtime,
displaypath /* Get description */
FROM alarm_events
/* The range for both start/end allows for index optimizations */
WHERE eventtime BETWEEN (:startDate - INTERVAL 4 DAY) AND (:endDate + INTERVAL 4 DAY)
/* Filter for disabled messages, full messages, and jam messages */
AND displaypath = "HMI Chute Disabled"
AND (source LIKE "%MCP05/%" or source LIKE "%MCP06/%")
/* Filter out system events and filter for active/clear events only */
AND eventflags & 1 != 1 AND eventtype IN (0, 1)
WINDOW w AS (PARTITION BY source ORDER BY eventtime ASC)
), ENABLES AS (
/* Group related active & clear events into a single row */
SELECT
eventid,
SUBSTRING_INDEX(ANY_VALUE(ddevice.strvalue), '.', 1) AS lane,
GREATEST(COALESCE(MIN(IF(eventtype=0, eventtime, NULL)), (:startDate - INTERVAL 4 DAY)), :startDate) AS starttime,
LEAST(COALESCE(MAX(IF(eventtype=1, eventtime, NULL)), LEAST(NOW(), (:endDate + INTERVAL 4 DAY))), :endDate) AS endtime,
ANY_VALUE(displaypath) AS displaypath /* Get description */
FROM DISABLE_EVENTS e
JOIN alarm_event_data ddevice ON e.id = ddevice.id AND ddevice.propname = "Device"
GROUP BY eventid
HAVING endtime >= :startDate AND starttime <= :endDate
ORDER BY starttime ASC
), STATES AS (
/* Group related active & clear events into a single row */
SELECT
eventid,
SUBSTRING_INDEX(ANY_VALUE(ddevice.strvalue), '.', 1) AS lane,
GREATEST(COALESCE(MIN(IF(eventtype=0, eventtime, NULL)), (:startDate - INTERVAL 4 DAY)), :startDate) AS starttime,
LEAST(COALESCE(MAX(IF(eventtype=1, eventtime, NULL)), LEAST(NOW(), (:endDate + INTERVAL 4 DAY))), :endDate) AS endtime,
ANY_VALUE(displaypath) AS displaypath /* Get description */
FROM alarm_events e
JOIN alarm_event_data ddevice ON e.id = ddevice.id AND ddevice.propname = "Device"
/* The range for both start/end allows for index optimizations */
WHERE eventtime BETWEEN (:startDate - INTERVAL 4 DAY) AND (:endDate + INTERVAL 4 DAY)
/* Filter for disabled messages, full messages, and jam messages */
AND displaypath IN ("Full", "Full Warn", "25% Full Warn", "50% Full Warn", "75% Full Warn", "Jammed", "EStop or Faulted", "Extend PX Faulted", "Retract PX Faulted")
AND (source LIKE "%MCP05/%" or source LIKE "%MCP06/%")
/* Filter out system events and clear events only */
AND eventflags & 1 != 1 AND eventtype IN (0, 1)
GROUP BY eventid
HAVING endtime >= :startDate AND starttime <= :endDate
), COMBINED AS (
SELECT
/* Meta */
MIN(LEAST(e.starttime, COALESCE(s.starttime, e.starttime))) AS firsttime, /* Get the earliest it's been active in the given time range */
MAX(GREATEST(e.endtime, COALESCE(s.endtime, e.endtime))) AS lasttime, /* Get the latest it's been active in the given time range */
MAX(e.lane) AS lane, /* Use latest id to get the latest metadata */
/* Durations */
TIME_TO_SEC(TIMEDIFF(e.endtime, e.starttime)) AS enabled_duration,
SUM(IF(s.displaypath="25% Full Warn", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full25_duration,
SUM(IF(s.displaypath IN ("Full Warn", "50% Full Warn"), TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full50_duration,
SUM(IF(s.displaypath="75% Full Warn", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full75_duration,
SUM(IF(s.displaypath="Full", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full100_duration,
SUM(IF(s.displaypath="Jammed", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS jammed_duration,
SUM(IF(s.displaypath IN ("EStop or Faulted", "Extend PX Faulted", "Retract PX Faulted"), TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS faulted_duration#,
/* Max Durations */
#TIME_TO_SEC(TIMEDIFF(e.endtime, e.starttime)) AS enabled_duration_max,
#MAX(IF(s.displaypath="25% Full Warn", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full25_duration_max,
#MAX(IF(s.displaypath IN ("Full Warn", "50% Full Warn"), TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full50_duration_max,
#MAX(IF(s.displaypath="75% Full Warn", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full75_duration_max,
#MAX(IF(s.displaypath="Full", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS full100_duration_max,
#MAX(IF(s.displaypath="Jammed", TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS jammed_duration_max,
#MAX(IF(s.displaypath IN ("EStop or Faulted", "Extend PX Faulted", "Retract PX Faulted"), TIME_TO_SEC(TIMEDIFF(LEAST(e.endtime, s.endtime), GREATEST(e.starttime, s.starttime))), 0)) AS faulted_duration_max
FROM ENABLES e
LEFT JOIN STATES s ON e.lane = s.lane AND e.starttime <= s.endtime AND e.endtime >= s.starttime
GROUP BY e.eventid
)
SELECT
DATE_FORMAT(MIN(firsttime), '%Y-%m-%d %T') AS firsttime,
DATE_FORMAT(MAX(lasttime), '%Y-%m-%d %T') AS lasttime,
lane,
CAST(SEC_TO_TIME(SUM(enabled_duration)) AS CHAR) AS enabled_duration,
CAST(SEC_TO_TIME(SUM(enabled_duration - full100_duration - jammed_duration - faulted_duration)) AS CHAR) AS available_duration,
CAST(SEC_TO_TIME(SUM(enabled_duration - full25_duration - full50_duration - full75_duration - full100_duration - jammed_duration - faulted_duration)) AS CHAR) AS empty_duration,
CAST(SEC_TO_TIME(SUM(full25_duration)) AS CHAR) AS full25_duration,
CAST(SEC_TO_TIME(SUM(full50_duration)) AS CHAR) AS full50_duration,
CAST(SEC_TO_TIME(SUM(full75_duration)) AS CHAR) AS full75_duration,
CAST(SEC_TO_TIME(SUM(full100_duration)) AS CHAR) AS full100_duration,
CAST(SEC_TO_TIME(SUM(jammed_duration)) AS CHAR) AS jammed_duration,
CAST(SEC_TO_TIME(SUM(faulted_duration)) AS CHAR) AS faulted_duration,
/* Inbound OEE (Loop's Efficiency) wants to have 25%/50%/75%/100% full all the time ==> 100% */
/* (Full25 + Full50 + Full75 + Full100) / (Enabled - Jammed - Faulted) */
SUM(full25_duration + full50_duration + full75_duration + full100_duration) / SUM(enabled_duration - jammed_duration - faulted_duration) AS inbound_oee,
/* Induct OEE (Operator's Efficiency) wants to have Empty or 25%/50%/75% full all the time ==> 100%, and is penalized for the time with active jams */
/* (Empty + Full25 + Full50 + Full75) / (Enabled - Faulted) */
SUM((enabled_duration - full100_duration - jammed_duration - faulted_duration)) / SUM(enabled_duration - faulted_duration) AS induct_oee
FROM COMBINED c
GROUP BY lane
ORDER BY lane;

View File

@ -1,241 +0,0 @@
{
"custom": {},
"params": {
"deviceType": "",
"props": {
"config": {
"enableHighlight": true,
"isClickable": false
},
"status": {
"color": "#aaa",
"showAlways": true,
"tagPath": "",
"tooltip": ""
}
}
},
"propConfig": {
"params.deviceType": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 280
}
},
"root": {
"children": [
{
"meta": {
"name": "Table"
},
"position": {
"height": "100%",
"width": "100%"
},
"propConfig": {
"props.data": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/FMS.jsonValues"
},
"transforms": [
{
"code": "\treturn historian.fms.genSegmentsTable(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"cells": {
"style": {
"borderBottomColor": "#D5D5D5",
"borderBottomStyle": "solid",
"borderBottomWidth": "1px",
"borderRightColor": "#D5D5D5",
"borderRightStyle": "solid",
"borderRightWidth": "1px",
"fontFamily": "Helvetica",
"fontSize": "16px"
}
},
"columns": [
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"editable": false,
"field": "segment",
"footer": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": "table/column-header"
},
"title": "Belt Section (10ft)"
},
"justify": "center",
"number": "value",
"numberFormat": "0,0.##",
"progressBar": {
"bar": {
"color": "#62A3F6",
"linecap": "round",
"width": 5
},
"max": 100,
"track": {
"color": "#DADADA",
"linecap": "round",
"width": 2
},
"value": {
"color": "#7D7D7D",
"show": true
}
},
"render": "auto",
"resizable": true,
"sortable": true,
"strictWidth": true,
"style": {
"classes": ""
},
"toggleSwitch": {
"color": {
"selected": "#2196F3",
"unselected": "#FFFFFF"
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 160
},
{
"align": "center",
"boolean": "checkbox",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"editable": false,
"field": "fill",
"footer": {
"align": "center",
"justify": "center",
"style": {
"classes": ""
},
"title": ""
},
"header": {
"align": "center",
"justify": "center",
"style": {
"classes": "table/column-header"
},
"title": "Package Fill (%)"
},
"justify": "center",
"number": "value",
"numberFormat": "0.##%",
"progressBar": {
"bar": {
"color": "#62A3F6",
"linecap": "round",
"width": 5
},
"max": 100,
"track": {
"color": "#DADADA",
"linecap": "round",
"width": 2
},
"value": {
"color": "#7D7D7D",
"show": true
}
},
"render": "auto",
"resizable": false,
"sortable": true,
"strictWidth": false,
"style": {
"classes": "",
"minWidth": "250px"
},
"toggleSwitch": {
"color": {
"selected": "#2196F3",
"unselected": "#FFFFFF"
}
},
"viewParams": {},
"viewPath": "",
"visible": true,
"width": 250
}
],
"pager": {
"bottom": false
},
"rows": {
"highlight": {
"enabled": false
},
"striped": {
"enabled": false
},
"style": {
"classes": "table/highlight"
}
},
"style": {
"fontFamily": "Helvetica",
"fontSize": "16px",
"fontWeight": "bold",
"zoom": 1
}
},
"scripts": {
"customMethods": [],
"messageHandlers": [
{
"messageType": "export-data",
"pageScope": true,
"script": "\tname \u003d utils.extractName(self.view.params.props.status)\n\tutils.downloadCSV(self, \"[\"+name+\"]FlowManagement\")",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.table"
}
],
"meta": {
"name": "root"
},
"type": "ia.container.coord"
}
}

View File

@ -1,334 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "S1-CH1"
},
"props": {
"config": {
"alwaysShowAll": true,
"isClickable": false,
"rotation": 0
},
"status": {
"tagPath": "[default]MCP04/CH_20116/CH_20116"
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
},
"params.props.config.alwaysShowAll": {
"paramDirection": "input",
"persistent": true
},
"params.props.config.rotation": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 349,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "ChuteLabel"
},
"position": {
"height": 30,
"width": 100,
"x": 198,
"y": 298.8
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"path": "view.params.props.status.tagPath"
},
"transforms": [
{
"code": "\treturn utils.prettyName(value.split(\"/\")[-1])",
"type": "script"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"fontSize": "20px",
"textAlign": "center"
}
},
"type": "ia.display.label"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPath \u003d self.view.params.props.status.tagPath\n\ttags \u003d [tagPath + \"/CH/SetEnable\"]\n\tvalues \u003d [1]\n\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Enable"
},
"position": {
"height": 40,
"width": 120,
"x": 120,
"y": 20.3
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/CH/SetEnable"
},
"transforms": [
{
"expression": "isGood({value})",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.classes": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/CH/SetEnable"
},
"transforms": [
{
"fallback": "Buttons/Grey",
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "Buttons/Green"
}
],
"outputType": "scalar",
"type": "map"
},
{
"expression": "if(isGood({value}),\r\n\t{value},\r\n\t\"Buttons/Grey\"\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {},
"text": "Enable"
},
"type": "ia.input.button"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttagPath \u003d self.view.params.props.status.tagPath\n\ttags \u003d [tagPath + \"/CH/SetEnable\"]\n\tvalues \u003d [0]\n\tsystem.tag.writeAsync(tags, values)"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Disable"
},
"position": {
"height": 40,
"width": 120,
"x": 260,
"y": 20.3
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/CH/SetEnable"
},
"transforms": [
{
"expression": "isGood({value})",
"type": "expression"
}
],
"type": "tag"
}
},
"props.style.classes": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/CH/SetEnable"
},
"transforms": [
{
"fallback": "Buttons/Grey",
"inputType": "scalar",
"mappings": [
{
"input": false,
"output": "Buttons/Red"
}
],
"outputType": "scalar",
"type": "map"
},
{
"expression": "if(isGood({value}),\r\n\t{value},\r\n\t\"Buttons/Grey\"\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {},
"text": "Disable"
},
"type": "ia.input.button"
},
{
"meta": {
"name": "SpiralChute"
},
"position": {
"height": 60,
"width": 85,
"x": 205,
"y": 165
},
"propConfig": {
"props.params": {
"binding": {
"config": {
"struct": {
"alwaysShowAll": true,
"isClickable": false,
"rotation": "{view.params.props.config.rotation}",
"tagPath": "{view.params.props.status.tagPath}"
},
"waitOnAll": true
},
"type": "expr-struct"
}
},
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.props.config.rotation"
},
"transforms": [
{
"expression": "\"scale(2) rotate(\" + {value} + \"deg)\"",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
}
},
"props": {
"path": "Templates/Areas/SpiralChute",
"style": {
"transform": "scale(2) rotate(0deg)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "ChuteLabel_0"
},
"position": {
"height": 35,
"width": 260,
"x": 120,
"y": 63
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/CH/StatusText"
},
"type": "tag"
}
}
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "center"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,307 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "FIO"
},
"props": {
"config": {
"enableHighlight": true,
"isClickable": false
},
"status": {
"color": "#aaa",
"showAlways": true,
"tagPath": "",
"tooltip": ""
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 105,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "EIP"
},
"position": {
"height": 45,
"width": 90,
"x": 54.5,
"y": 12.5
},
"propConfig": {
"meta.name": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Label"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027EIP\u0027)",
"type": "expression"
}
],
"type": "tag"
},
"persistent": true
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "try(\r\n\tjsonSet({value}, \"showAlways\", true),\r\n\t{view.params.props.status}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false
}
},
"type": "dex.display.eip"
},
{
"meta": {
"name": "lbStatus"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"code": "\treturn utils.extractStatus(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbName"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027\u0027)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_1"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 5
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Name: "
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_11"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 40
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Status:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_12"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 75
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Panel:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus_0"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 75
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.OPC_Server"
},
"transforms": [
{
"expression": "coalesce({value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,322 +0,0 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
"params": {
"tagProps": [
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 1,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
"type": "expression"
},
{
"fallback": 0,
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": 1
},
{
"input": 2,
"output": 2
},
{
"input": 3,
"output": 3
},
{
"input": 4,
"output": 4
},
{
"input": 5,
"output": 5
},
{
"input": 6,
"output": 6
},
{
"input": 7,
"output": 7
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Clear",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "Clear"
},
{
"input": 2,
"output": "Blocked"
},
{
"input": 3,
"output": "Disabled"
},
{
"input": 4,
"output": "Jammed"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 40,
"width": 200
}
},
"root": {
"children": [
{
"meta": {
"name": "Photoeye"
},
"position": {
"height": 1,
"width": 1
},
"propConfig": {
"props.elements[0].fill.paint": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#00FF00",
"inputType": "scalar",
"mappings": [
{
"input": 0,
"output": "#00FF00"
},
{
"input": 2,
"output": "#000000"
},
{
"input": 3,
"output": "#800080"
},
{
"input": 4,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
},
"props.elements[2].fill.paint": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#00FF00",
"inputType": "scalar",
"mappings": [
{
"input": 0,
"output": "#00FF00"
},
{
"input": 2,
"output": "#000000"
},
{
"input": 3,
"output": "#800080"
},
{
"input": 4,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"elements": [
{
"d": "m 28.763932,20 -20,10 V 10 Z",
"fill": {},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "2"
},
"type": "path"
},
{
"stroke": {
"paint": "#000000",
"width": "2"
},
"stroke-dasharray": "4,4",
"type": "line",
"x1": "30",
"x2": "95%",
"y1": "20",
"y2": "20"
},
{
"fill": {},
"height": "20",
"stroke": {
"paint": "#000000",
"width": "2"
},
"type": "rect",
"width": "6",
"x": "95%",
"y": "10"
}
],
"viewBox": "0 0 300 40"
},
"type": "ia.shapes.svg"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-Photoeye\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\n\talarm \u003d []\n\tmessage \u003d None\n\n\tsleep(0.5)\n\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_photoeyes"
},
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"cursor": "pointer"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,61 +0,0 @@
import copy
DEFAULT_BUTTON = {
"position": "absolute",
"top": "19px",
"left": "15px",
"bottom": "auto",
"right": "auto",
"zIndex": "auto",
"width": "auto",
"height": "auto",
"viewPath": "Templates/Buttons/NavButtonBanner",
"viewParams": {
#"label": "System",
"showIcons": True,
#"tagPath": "[default]SystemStatus",
#"view": "Windows/Graphics/Overview"
},
"style": {
"classes": ""
}
}
def genButtonsFromDataset(areas):
buttons = []
for i in range(areas.getRowCount()):
# Get values from row:
label = areas.getValueAt(i, "Label")
tagPath = areas.getValueAt(i, "TagPath")
view = areas.getValueAt(i, "View")
# Clone and customize button:
button = copy.deepcopy(DEFAULT_BUTTON)
button["left"] = str(15+140*i)+"px"
if label <> "":
button["viewParams"]["label"] = label
if tagPath <> "":
button["viewParams"]["tagPath"] = tagPath
else:
button["viewParams"]["showIcons"] = False
if view <> "":
button["viewParams"]["view"] = view
# Add button to list:
buttons.append(button)
return buttons
def genButtonsFromViews(areas=None):
if areas == None:
projectName = system.project.getProjectName()
path = os.path.join(os.getcwd(), "data", "projects", projectName, "com.inductiveautomation.perspective", "views", "Windows", "Graphics")
areas = [name for name in os.listdir(".") if os.path.isdir(name) and name.lower() not in ["overview", "templates"]]
buttons = []
for i, area in enumerate(areas):
button = copy.deepcopy(DEFAULT_BUTTON)
button["left"] = str(15+145*i)+"px"
button["viewParams"]["tagPath"] = area
return buttons

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@ -1,323 +0,0 @@
{
"custom": {
"forceModeRefresh": false,
"setDatesScript": null
},
"params": {
"endDate": "2021-02-11 00:00:00",
"refreshDelay": 30,
"startDate": "2021-02-10 00:00:00"
},
"propConfig": {
"custom.forceModeRefresh": {
"persistent": true
},
"custom.setDatesScript": {
"binding": {
"config": {
"expression": "toBoolean(now({view.params.refreshDelay}*1000))\r\n\u0026\u0026{view.custom.forceModeRefresh}"
},
"transforms": [
{
"code": "\tnow \u003d system.date.now()\n\tcurrentDay \u003d system.date.getDate(system.date.getYear(now), system.date.getMonth(now), system.date.getDayOfMonth(now))\n\tpreviousDay \u003d system.date.addDays(currentDay, -1)\n\tnextDay \u003d system.date.addDays(currentDay, 1)\n\tstartDate \u003d self.getChild(\"root\").getChild(\"StartDateTime\")\n\tendDate \u003d self.getChild(\"root\").getChild(\"EndDateTime\")\n\tvalue \u003d self.getChild(\"root\").getChild(\"Mode\").props.value\n\t\n\t# Retrieve shifts table:\n\tshifts \u003d utils.datasetToJSON(system.tag.readBlocking([\"[default]Gateway/Shifts\"])[0].value)\n\t# Filter for shifts that are enabled and for today:\n\tcurrentDayOfWeek \u003d system.date.getDayOfWeek(now)\n\tcurrentDayOfWeek \u003d \"is\" + [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"][currentDayOfWeek-1]\n\tshifts \u003d [shift for shift in shifts if shift[\"Enabled\"] and shift[currentDayOfWeek]]\n\t# Build SORTS list:\n\tSORTS \u003d [{ \"name\": shift[\"Name\"], \"start\": [shift[\"StartHour\"],shift[\"StartMinute\"]], \"actualEnd\": [shift[\"EndHour\"],shift[\"EndMinute\"]] } for shift in shifts]\n\tSORTS.sort(key\u003dlambda x: x[\"start\"])\n\t# Add end time based on next sort:\n\tfor i in range(len(SORTS) - 1):\n\t\tSORTS[i][\"end\"] \u003d SORTS[i+1][\"start\"]\n\tSORTS[-1][\"end\"] \u003d SORTS[0][\"start\"]\n\t\n\tstart \u003d startDate.props.value\n\tend \u003d endDate.props.value\n\t\n\tif value \u003d\u003d \"past30min\":\n\t\tstart \u003d system.date.addMinutes(now, -30)\n\t\tend \u003d now\n\t\n\telif value \u003d\u003d \"pastHour\":\n\t\tstart \u003d system.date.addHours(now, -1)\n\t\tend \u003d now\n\t\n\telif value \u003d\u003d \"past2Hours\":\n\t\tstart \u003d system.date.addHours(now, -2)\n\t\tend \u003d now\n\t\n\telif value \u003d\u003d \"past4Hours\":\n\t\tstart \u003d system.date.addHours(now, -4)\n\t\tend \u003d now\n\t\n\telif value \u003d\u003d \"past8Hours\":\n\t\tstart \u003d system.date.addHours(now, -8)\n\t\tend \u003d now\n\t\n\telif value \u003d\u003d \"currentDay\":\n\t\tstart \u003d currentDay\n\t\tend \u003d system.date.addDays(currentDay, 1)\n\t\n\telif value \u003d\u003d \"previousDay\":\n\t\tstart \u003d previousDay\n\t\tend \u003d currentDay\n\t\t\n\telse:\n\t\t# Resolve sort:\n\t\tif value \u003d\u003d \"currentShift\":\n\t\t\tsort \u003d SORTS[-1] # Default to last sort (assumes last sort includes midnight)\n\t\t\tfor i, s in enumerate(SORTS[::-1]):\n\t\t\t\tif system.date.isAfter(now, system.date.setTime(currentDay, s[\"start\"][0], s[\"start\"][1], 0)):\n\t\t\t\t\tsort \u003d s\n\t\t\t\t\tbreak\n\t\t\t# Apply:\n\t\t\tstart \u003d system.date.setTime(currentDay, sort[\"start\"][0], sort[\"start\"][1], 0)\n\t\t\tend \u003d system.date.setTime(currentDay, sort[\"actualEnd\"][0], sort[\"actualEnd\"][1], 0)\n\t\telif value \u003d\u003d \"previousShift\":\n\t\t\tsort \u003d SORTS[-2] # Default to second to last sort (assumes last sort includes midnight)\n\t\t\tSORTS_REV \u003d SORTS[:]\n\t\t\tSORTS_REV.sort(key\u003dlambda x: x[\"end\"])\n\t\t\tfor i, s in enumerate(SORTS_REV[::-1]):\n\t\t\t\tif system.date.isAfter(now, system.date.setTime(currentDay, s[\"end\"][0], s[\"end\"][1], 0)):\n\t\t\t\t\tsort \u003d s\n\t\t\t\t\tbreak\n\t\t\t# Apply:\n\t\t\tstart \u003d system.date.setTime(currentDay, sort[\"start\"][0], sort[\"start\"][1], 0)\n\t\t\tend \u003d system.date.setTime(currentDay, sort[\"actualEnd\"][0], sort[\"actualEnd\"][1], 0)\n\t\telse:\n\t\t\tfor s in SORTS:\n\t\t\t\tif s[\"name\"] \u003d\u003d value:\n\t\t\t\t\t# Apply:\n\t\t\t\t\tstart \u003d system.date.setTime(currentDay, s[\"start\"][0], s[\"start\"][1], 0)\n\t\t\t\t\tend \u003d system.date.setTime(currentDay, s[\"actualEnd\"][0], s[\"actualEnd\"][1], 0)\n\t\t\t\t\tbreak\n\n\t\t# Increase end if before start:\n\t\tif system.date.isAfter(start, end):\n\t\t\tend \u003d system.date.addDays(end, 1)\n\t\t# If current time is before startDate, then subtract one day to show last occurrence of that sort:\n\t\tif system.date.isBefore(now, start):\n\t\t\tstart \u003d system.date.addDays(start, -1)\n\t\t\tend \u003d system.date.addDays(end, -1)\n\t\t\t\n\t# Apply:\n\tif startDate.props.value !\u003d start or endDate.props.value !\u003d end or (system.date.isAfter(now, start) and system.date.isBefore(now, system.date.addMinutes(end, 1))):\n\t\tstartDate.props.value \u003d start\n\t\tendDate.props.value \u003d end\n\t\tself.session.custom.timewidget \u003d {\n\t\t\t\"startDate\": start,\n\t\t\t\"endDate\": end,\n\t\t\t\"mode\": value,\n\t\t\t\"update\": now\n\t\t}\n\t\n\treturn value",
"type": "script"
}
],
"type": "expr"
},
"persistent": true
},
"params.endDate": {
"binding": {
"config": {
"path": "/root/EndDateTime.props.formattedValues.datetime"
},
"type": "property"
},
"paramDirection": "output",
"persistent": true
},
"params.refreshDelay": {
"paramDirection": "input",
"persistent": true
},
"params.startDate": {
"binding": {
"config": {
"path": "/root/StartDateTime.props.formattedValues.datetime"
},
"type": "property"
},
"paramDirection": "output",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 40,
"width": 550
}
},
"root": {
"children": [
{
"meta": {
"name": "StartLabel"
},
"position": {
"height": 20,
"width": 40,
"x": 180,
"y": 10
},
"props": {
"style": {
"color": "#fff",
"fontSize": "14px",
"textAlign": "right"
},
"text": "Start:"
},
"type": "ia.display.label"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttimewidget \u003d self.session.custom.timewidget\n\thours \u003d system.date.hoursBetween(self.props.value, timewidget.endDate)\n\tsystem.perspective.print(hours)\n\tnewVal \u003d {\n\t\t\"startDate\": self.props.value,\n\t\t\"endDate\": timewidget.endDate,\n\t\t\"mode\": timewidget.mode\n\t}\n\tif hours \u003e 7*24:\n\t\t# Cap endDate to within 7 days of startDate:\n\t\tnewVal[\"endDate\"] \u003d system.date.addDays(self.props.value, 7)\n\t# Apply changes:\n\tself.session.custom.timewidget \u003d newVal"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "StartDateTime"
},
"position": {
"height": 20,
"width": 135,
"x": 225,
"y": 10
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"path": "../Mode.props.value"
},
"transforms": [
{
"expression": "{value} \u003d \"custom\"",
"type": "expression"
}
],
"type": "property"
}
},
"props.value": {
"binding": {
"config": {
"path": "session.custom.timewidget.startDate"
},
"type": "property"
}
}
},
"props": {
"format": "YYYY-MM-DD HH:mm:ss",
"formattedValue": "2022-03-04 04:00:00",
"formattedValues": {
"date": "2021-02-10",
"datetime": "2021-02-10 00:00:00",
"time": "00:00:00"
},
"inputProps": {
"style": {
"fontSize": "12px"
}
}
},
"type": "ia.input.date-time-input"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\ttimewidget \u003d self.session.custom.timewidget\n\thours \u003d system.date.hoursBetween(timewidget.startDate, self.props.value)\n\tnewVal \u003d {\n\t\t\"startDate\": timewidget.startDate,\n\t\t\"endDate\": self.props.value,\n\t\t\"mode\": timewidget.mode\n\t}\n\tif hours \u003e 7*24:\n\t\t# Cap startDate to within 7 days of endDate:\n\t\tnewVal[\"startDate\"] \u003d system.date.addDays(self.props.value, -7)\n\t# Apply changes:\n\tself.session.custom.timewidget \u003d newVal"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "EndDateTime"
},
"position": {
"height": 20,
"width": 135,
"x": 410,
"y": 10
},
"propConfig": {
"props.enabled": {
"binding": {
"config": {
"path": "../Mode.props.value"
},
"transforms": [
{
"expression": "{value} \u003d \"custom\"",
"type": "expression"
}
],
"type": "property"
}
},
"props.value": {
"binding": {
"config": {
"path": "session.custom.timewidget.endDate"
},
"type": "property"
}
}
},
"props": {
"format": "YYYY-MM-DD HH:mm:ss",
"formattedValue": "2022-03-05 04:00:00",
"formattedValues": {
"date": "2021-02-11",
"datetime": "2021-02-11 00:00:00",
"time": "00:00:00"
},
"inputProps": {
"style": {
"fontSize": "12px"
}
}
},
"type": "ia.input.date-time-input"
},
{
"meta": {
"name": "EndLabel"
},
"position": {
"height": 20,
"width": 40,
"x": 365,
"y": 10
},
"props": {
"style": {
"color": "#fff",
"fontSize": "14px",
"textAlign": "right"
},
"text": "End:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "ModeLabel"
},
"position": {
"height": 20,
"width": 45,
"x": 5,
"y": 10
},
"props": {
"style": {
"color": "#fff",
"fontSize": "14px",
"textAlign": "right"
},
"text": "Period:"
},
"type": "ia.display.label"
},
{
"events": {
"component": {
"onActionPerformed": {
"config": {
"script": "\tself.session.custom.timewidget.mode \u003d self.props.value\n\tself.view.custom.forceModeRefresh \u003d not self.view.custom.forceModeRefresh"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "Mode"
},
"position": {
"height": 20,
"width": 120,
"x": 55,
"y": 10
},
"propConfig": {
"props.options": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "direct",
"tagPath": "[default]Gateway/Shifts"
},
"transforms": [
{
"code": "\t# Add default relative options:\n\toptions \u003d [\n\t { \"value\": \"past30min\", \"label\": \"Past 30min\" },\n\t { \"value\": \"pastHour\", \"label\": \"Past Hour\" },\n\t { \"value\": \"past2Hours\", \"label\": \"Past 2 Hours\" },\n\t { \"value\": \"past4Hours\", \"label\": \"Past 4 Hours\" },\n\t { \"value\": \"past8Hours\", \"label\": \"Past 8 Hours\" },\n\t { \"value\": \"currentDay\", \"label\": \"Current Day\" },\n\t { \"value\": \"previousDay\", \"label\": \"Previous Day\" },\n\t { \"value\": \"currentShift\", \"label\": \"Current Shift\" },\n\t { \"value\": \"previousShift\", \"label\": \"Previous Shift\" }\n\t]\n\t# Add shifts:\n\tshifts \u003d utils.datasetToJSON(value)\n\t# Filter for shifts that are enabled and for today:\n\tcurrentDayOfWeek \u003d system.date.getDayOfWeek(system.date.now())\n\tcurrentDayOfWeek \u003d \"is\" + [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"][currentDayOfWeek-1]\n\tshifts \u003d [shift for shift in shifts if shift[\"Enabled\"] and shift[currentDayOfWeek]]\n\t# Add shifts to options:\n\tfor shift in shifts:\n\t\tif shift[\"Enabled\"]:\n\t\t\toptions.append({ \"value\": shift[\"Name\"], \"label\": \"Shift: \" + shift[\"Name\"] })\n\t# Add custom:\n\toptions.append({ \"value\": \"custom\", \"label\": \"Custom\" })\n\t# Return options:\n\treturn options",
"type": "script"
}
],
"type": "tag"
}
},
"props.value": {
"binding": {
"config": {
"struct": {
"mode": "{session.custom.timewidget.mode}",
"options": "{this.props.options}"
},
"waitOnAll": true
},
"transforms": [
{
"code": "\tif value.options !\u003d None:\n\t\tfor option in value.options:\n\t\t\tif option.value \u003d\u003d value.mode:\n\t\t\t\treturn value.mode\n\t# Value isn\u0027t in options, default to currentDay:\n\treturn \"currentDay\"",
"type": "script"
}
],
"type": "expr-struct"
}
}
},
"props": {
"dropdownOptionStyle": {
"fontSize": "11px"
},
"style": {
"fontSize": "10px"
}
},
"type": "ia.input.dropdown"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"overflow": "hidden"
}
},
"type": "ia.container.coord"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -1,13 +0,0 @@
{
"base": {
"style": {}
},
"variants": [
{
"pseudo": "hover",
"style": {
"backgroundColor": "#DBEFFA"
}
}
]
}

View File

@ -1,322 +0,0 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
"params": {
"tagProps": [
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value",
"value"
]
},
"propConfig": {
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
"fallbackDelay": 1,
"mode": "indirect",
"references": {
"0": "{view.params.tagProps[0]}",
"fc": "{session.custom.fc}"
},
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/STATE"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
"type": "expression"
},
{
"fallback": 0,
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": 1
},
{
"input": 2,
"output": 2
},
{
"input": 3,
"output": 3
},
{
"input": 4,
"output": 4
},
{
"input": 5,
"output": 5
},
{
"input": 6,
"output": 6
},
{
"input": 7,
"output": 7
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
},
"persistent": true
},
"custom.string": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "Clear",
"inputType": "scalar",
"mappings": [
{
"input": 1,
"output": "Clear"
},
{
"input": 2,
"output": "Blocked"
},
{
"input": 3,
"output": "Disabled"
},
{
"input": 4,
"output": "Jammed"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
},
"persistent": true
},
"params.tagProps": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 40,
"width": 110
}
},
"root": {
"children": [
{
"meta": {
"name": "Photoeye"
},
"position": {
"height": 1,
"width": 1
},
"propConfig": {
"props.elements[0].fill.paint": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#00FF00",
"inputType": "scalar",
"mappings": [
{
"input": 0,
"output": "#00FF00"
},
{
"input": 2,
"output": "#000000"
},
{
"input": 3,
"output": "#800080"
},
{
"input": 4,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
},
"props.elements[2].fill.paint": {
"binding": {
"config": {
"path": "view.custom.state"
},
"transforms": [
{
"fallback": "#00FF00",
"inputType": "scalar",
"mappings": [
{
"input": 0,
"output": "#00FF00"
},
{
"input": 2,
"output": "#000000"
},
{
"input": 3,
"output": "#800080"
},
{
"input": 4,
"output": "#FF0000"
}
],
"outputType": "color",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"elements": [
{
"d": "m 28.763932,20 -20,10 V 10 Z",
"fill": {},
"name": "path",
"stroke": {
"paint": "#000000",
"width": "2"
},
"type": "path"
},
{
"stroke": {
"paint": "#000000",
"width": "2"
},
"stroke-dasharray": "4,4",
"type": "line",
"x1": "30",
"x2": "90%",
"y1": "20",
"y2": "20"
},
{
"fill": {},
"height": "20",
"stroke": {
"paint": "#000000",
"width": "2"
},
"type": "rect",
"width": "6",
"x": "90%",
"y": "10"
}
],
"viewBox": "0 0 110 40"
},
"type": "ia.shapes.svg"
}
],
"events": {
"dom": {
"onClick": {
"config": {
"script": "\tsystem.perspective.openDock(\u0027Docked-East-Photoeye\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
},
"scope": "G",
"type": "script"
},
"onMouseEnter": {
"config": {
"script": "\tfrom time import sleep\n\n\talarm \u003d []\n\tmessage \u003d None\n\n\tsleep(0.5)\n\n\tif system.tag.exists(\"System/aws_data\"):\n\t\tif self.view.params.tagProps[0] !\u003d \"\":\n\t\t\ttags_to_read \u003d system.tag.readBlocking(\"System/aws_data\")\n\t\t\tdecode_alarm_data \u003d system.util.jsonDecode(tags_to_read[0].value)\n\t\t\talarm \u003d [decode_alarm_data[i] for i in decode_alarm_data\n\t\t\t\t\tif decode_alarm_data[i][\u0027sourceId\u0027].startswith(self.view.params.tagProps[0])]\n\t\tif alarm:\n\t\t\talarm \u003d sorted(alarm, key \u003d lambda t:t[\u0027timestamp\u0027], reverse\u003dTrue)\n\t\t\tmessage \u003d max(alarm, key \u003d lambda p:p[\u0027priority\u0027]).get(\u0027message\u0027)\n\t\t\tif len(alarm) \u003e 1:\n\t\t\t\tmessage +\u003d \" (+\" + str(len(alarm)-1) + \")\"\n\tself.view.custom.alarm_message \u003d message"
},
"scope": "G",
"type": "script"
}
}
},
"meta": {
"name": "root",
"tooltip": {
"enabled": true
}
},
"propConfig": {
"meta.tooltip.text": {
"binding": {
"config": {
"expression": "\"Source Id: \" + {view.params.tagProps[0]} + \", Status: \" + {view.custom.string}\n"
},
"type": "expr"
}
},
"meta.visible": {
"binding": {
"config": {
"path": "session.custom.alarm_filter.show_photoeyes"
},
"type": "property"
}
}
},
"props": {
"mode": "percent",
"style": {
"cursor": "pointer"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,36 +0,0 @@
{
"base": {
"style": {
"backgroundImage": "linear-gradient(180deg, rgba(255,255,0,1) 0%, rgba(245,245,0,1) 70%, rgba(208,208,0,1) 100%);",
"borderColor": "#555",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#000",
"textTransform": "uppercase"
}
},
"variants": [
{
"pseudo": "hover",
"style": {
"backgroundImage": "linear-gradient(0deg, rgba(255,255,0,1) 0%, rgba(245,245,0,1) 70%, rgba(208,208,0,1) 100%);",
"borderColor": "#000",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#000",
"cursor": "pointer"
}
},
{
"pseudo": "disabled",
"style": {
"backgroundImage": "linear-gradient(180deg, rgba(208,208,0,1) 0%, rgba(208,208,0,1) 100%);",
"borderColor": "#555",
"borderStyle": "solid",
"borderWidth": "2px",
"color": "#555555",
"cursor": "not-allowed"
}
}
]
}

View File

@ -1,4 +0,0 @@
{
"type": "AllOf",
"securityLevels": []
}

View File

@ -1,24 +0,0 @@
WITH LANES AS (
SELECT
MIN(timestamp) AS start_timestamp,
MAX(timestamp) AS end_timestamp,
3600/TIMESTAMPDIFF(SECOND, :startDate, :endDate) AS pph_multiplier,
lane_id AS induct,
SUM(count) AS total
FROM pe_history
WHERE timestamp BETWEEN :startDate AND :endDate
AND lane_id LIKE "UL%"
GROUP BY lane_id
ORDER BY lane_id
)
SELECT
start_timestamp,
end_timestamp,
induct,
/* Counts: */
total AS total_count,
/* PPH: */
ROUND(total*pph_multiplier) AS total_pph,
/* Percents: */
ROUND(total/total, 4) AS total_percent
FROM LANES;

View File

@ -1,318 +0,0 @@
{
"custom": {},
"params": {
"maxZoom": 8
},
"propConfig": {
"params.maxZoom": {
"binding": {
"config": {
"expression": "8"
},
"type": "expr"
},
"paramDirection": "output",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 3200,
"width": 8300
}
},
"root": {
"children": [
{
"meta": {
"name": "Smalls"
},
"position": {
"height": 195,
"width": 755,
"x": 1213,
"y": 859
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/Smalls",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "Unloads"
},
"position": {
"height": 1727,
"width": 1707,
"x": 180,
"y": 55
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/Unloads",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "EastSpirals"
},
"position": {
"height": 1500,
"width": 2281,
"x": 1800,
"y": 1576
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/EastSpirals",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "WestSpirals"
},
"position": {
"height": 1479,
"width": 1937,
"x": 133,
"y": 1576
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/WestSpirals",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "EastLoops"
},
"position": {
"height": 1698,
"width": 1942,
"x": 6209,
"y": 1398
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/EastLoops",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "WestLoops"
},
"position": {
"height": 1787,
"width": 2072,
"x": 4272,
"y": 1309
},
"props": {
"params": {
},
"path": "Windows/Graphics/Templates/WestLoops",
"style": {
"classes": "painted-events"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "WestLoopsNavButton"
},
"position": {
"height": 40,
"width": 120,
"x": 5274,
"y": 2101
},
"props": {
"params": {
"label": "West Loops",
"tagPath": "",
"view": "Windows/Graphics/West_Loops"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "UpperLoopsNavButton"
},
"position": {
"height": 40,
"width": 120,
"x": 6088,
"y": 2101
},
"props": {
"params": {
"label": "Upper Loops",
"tagPath": "",
"view": "Windows/Graphics/Upper_Loops"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "WestSpiralsNavButton"
},
"position": {
"height": 40,
"width": 105,
"x": 262,
"y": 2540
},
"props": {
"params": {
"label": "West Spirals",
"tagPath": "",
"view": "Windows/Graphics/West_Spirals"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "EastSpiralsNavButton"
},
"position": {
"height": 40,
"width": 105,
"x": 3257,
"y": 1380
},
"props": {
"params": {
"label": "East Spirals",
"tagPath": "",
"view": "Windows/Graphics/East_Spirals"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "SmallsNavButton"
},
"position": {
"height": 40,
"width": 80,
"x": 2200,
"y": 936
},
"props": {
"params": {
"label": "Smalls",
"tagPath": "",
"view": "Windows/Graphics/Smalls"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "UnloadsNavButton"
},
"position": {
"height": 40,
"width": 80,
"x": 843,
"y": 929
},
"props": {
"params": {
"label": "Unloads",
"tagPath": "",
"view": "Windows/Graphics/Unloads"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
},
{
"meta": {
"name": "EastLoopsNavButton"
},
"position": {
"height": 40,
"width": 120,
"x": 7215,
"y": 2101
},
"props": {
"params": {
"label": "East Loops",
"tagPath": "",
"view": "Windows/Graphics/East_Loops"
},
"path": "Templates/Buttons/NavButton",
"style": {
"transform": "scale(4)"
}
},
"type": "ia.display.view"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"overflow": "hidden"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,264 +0,0 @@
{
"custom": {},
"params": {
"alwaysShowAll": false,
"isClickable": true,
"tagPath": ""
},
"propConfig": {
"params.alwaysShowAll": {
"paramDirection": "input",
"persistent": true
},
"params.isClickable": {
"paramDirection": "input",
"persistent": true
},
"params.tagPath": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 110,
"width": 66
},
"loading": {
"mode": "blocking"
}
},
"root": {
"children": [
{
"meta": {
"name": "Conveyor"
},
"position": {
"height": 30,
"rotate": {
"anchor": "0 0",
"angle": "90deg"
},
"width": 102,
"x": 56,
"y": 1
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Conv/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"props": {
"config": {
"type": "chute"
}
},
"type": "dex.display.conveyor"
},
{
"meta": {
"name": "BCN1_AMB"
},
"position": {
"height": 16,
"width": 16,
"x": 5,
"y": 62
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/AMB/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "RS1"
},
"position": {
"height": 20,
"width": 20,
"x": 1,
"y": 82
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/RS1/Restart/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"type": "dex.display.pushbutton"
},
{
"meta": {
"name": "Half_PE"
},
"position": {
"height": 10,
"rotate": {
"anchor": "0 0",
"angle": "180deg"
},
"width": 43,
"x": 65,
"y": 79
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Half_PE/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"type": "dex.display.photoeye"
},
{
"meta": {
"name": "BCN1_BLU"
},
"position": {
"height": 16,
"width": 16,
"x": 5,
"y": 47
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/BCN1/BLU/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "Full_PE"
},
"position": {
"height": 10,
"rotate": {
"anchor": "0 0",
"angle": "180deg"
},
"width": 43,
"x": 65,
"y": 56
},
"propConfig": {
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.tagPath}"
},
"tagPath": "{tagPath}/Full_PE/Graphics"
},
"overlayOptOut": true,
"type": "tag"
}
}
},
"type": "dex.display.photoeye"
}
],
"meta": {
"name": "root"
},
"propConfig": {
"props.style.transform": {
"binding": {
"config": {
"path": "view.params.mirror"
},
"transforms": [
{
"fallback": null,
"inputType": "scalar",
"mappings": [
{
"input": true,
"output": "scale(-1, 1)"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "property"
}
}
},
"props": {
"style": {
"overflow": "hidden"
}
},
"scripts": {
"customMethods": [
{
"name": "openPopup",
"params": [],
"script": "\tif self.view.params.isClickable:\n\t\tid \u003d \"DivChute|\" + self.view.params.tagPath\n\t\ttitle \u003d utils.prettyName(self.view.params.tagPath.split(\"/\")[-1])\n\t\tparams \u003d { \n\t\t\t\"deviceType\": \"divchute\",\n\t\t\t\"props\": { \n\t\t\t\t\"config\": {\n\t\t\t\t\t\"alwaysShowAll\": self.view.params.alwaysShowAll,\n\t\t\t\t\t\"isClickable\": self.view.params.isClickable,\n\t\t\t\t\t#\"rotate\": self.view.params.rotate,\n\t\t\t\t\t\"mirror\": self.view.params.mirror\n\t\t\t\t},\n\t\t\t\t\"status\": {\n\t\t\t\t\t\"tagPath\": self.view.params.tagPath\n\t\t\t\t}\n\t\t \t},\n\t\t \t\"tabs\": [\"Controls\", \"Alarm History\", \"Devices\"]\t\t\n\t\t}\n\t\tsystem.perspective.openPopup(id, \"Popups/DeviceWrapper\", params, title, resizable \u003d True)"
}
],
"extensionFunctions": null,
"messageHandlers": []
},
"type": "ia.container.coord"
}
}

View File

@ -1,18 +1,5 @@
{
"custom": {
"activityLogger": {
"alt_pageid": "search",
"buttonid": "search",
"start_time": {
"$": [
"ts",
192,
1710275608985
],
"$ts": 1710275608985
}
}
},
"custom": {},
"events": {
"system": {
"onStartup": {
@ -25,25 +12,6 @@
}
},
"params": {},
"propConfig": {
"custom.activityLogger": {
"persistent": true
},
"custom.activityLogger.pageid": {
"binding": {
"config": {
"expression": "{page.props.path}"
},
"transforms": [
{
"code": "\tif value \u003d\u003d\u0027/\u0027 or value \u003d\u003d \u0027\u0027 or value \u003d\u003d None:\n\t\treturn self.custom.activityLogger.alt_pageid.lower()\n\telse:\n\t\treturn value[1:].lower()",
"type": "script"
}
],
"type": "expr"
}
}
},
"props": {
"defaultSize": {
"height": 294,
@ -289,7 +257,7 @@
"$": [
"ds",
192,
1710275544545
1755878824844
],
"$columns": [
{
@ -353,7 +321,7 @@
"system": {
"onStartup": {
"config": {
"script": "\tids \u003d config.project_config.global_project_page_ids\n\tdata \u003d []\n\tfor k,v in ids.items():\n\t items \u003d [str(k),str(v)]\n\t data.append(items)\n\theader \u003d [\"SourceId\", \"Page\"]\n\tdataset \u003d system.dataset.toDataSet(header, data)\n\tself.getChild(\"Table\").props.data \u003d dataset"
"script": "\tids \u003d config.project_config.global_project_page_ids\n\tdata \u003d []\n\tfor k,v in ids.items():\n\t items \u003d [str(k),str(v)]\n\t data.append(items)\n\theader \u003d [\"SourceId\", \"Page\"]\n\tdataset \u003d system.dataset.toDataSet(header, data)\n\tself.getChild(\"Table\").props.data \u003d dataset\n\tsystem.perspective.print(ids)"
},
"scope": "G",
"type": "script"

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1,297 +0,0 @@
{
"custom": {},
"params": {
"meta": {
"name": "BCN1_BLU"
},
"props": {
"config": {
"enableHighlight": true,
"isClickable": false
},
"status": {
"color": "#AAA",
"showAlways": true,
"showLabel": "B",
"tagPath": "",
"tooltip": ""
}
}
},
"propConfig": {
"params.meta": {
"paramDirection": "input",
"persistent": true
},
"params.meta.name": {
"paramDirection": "input",
"persistent": true
},
"params.props": {
"paramDirection": "input",
"persistent": true
}
},
"props": {
"defaultSize": {
"height": 105,
"width": 500
}
},
"root": {
"children": [
{
"meta": {
"name": "BCN1_BLU"
},
"position": {
"height": 48,
"width": 48,
"x": 76,
"y": 11
},
"propConfig": {
"meta.name": {
"binding": {
"config": {
"path": "view.params.meta.name"
},
"type": "property"
},
"persistent": true
},
"props.status": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"expression": "try(\r\n\tjsonSet({value}, \"showAlways\", true),\r\n\t{view.params.props.status}\r\n)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"config": {
"enableHighlight": false,
"isClickable": false
}
},
"type": "dex.display.beacon"
},
{
"meta": {
"name": "lbStatus"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 40
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Graphics"
},
"transforms": [
{
"code": "\treturn utils.extractStatus(value)",
"type": "script"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbName"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 5
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.LabelFull"
},
"transforms": [
{
"expression": "coalesce({value}, \u0027\u0027)",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_1"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 5
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Name: "
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_11"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 40
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Status:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "Label_12"
},
"position": {
"height": 25,
"width": 75,
"x": 195,
"y": 75
},
"props": {
"style": {
"fontSize": "20px",
"fontWeight": "bold",
"textAlign": "right"
},
"text": "Panel:"
},
"type": "ia.display.label"
},
{
"meta": {
"name": "lbStatus_0"
},
"position": {
"height": 25,
"width": "calc(100% - 300px)",
"x": 280,
"y": 75
},
"propConfig": {
"props.text": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"tagPath": "{view.params.props.status.tagPath}"
},
"tagPath": "{tagPath}/Parameters.OPC_Server"
},
"transforms": [
{
"expression": "coalesce({value}, \"Unknown\")",
"type": "expression"
}
],
"type": "tag"
}
}
},
"props": {
"style": {
"borderColor": "#000",
"borderStyle": "solid",
"fontSize": "14px",
"fontWeight": "bold",
"overflow": "hidden",
"textAlign": "center",
"textOverview": "ellipsis",
"whiteSpace": "nowrap"
}
},
"type": "ia.display.label"
}
],
"meta": {
"name": "root"
},
"props": {
"style": {
"background-color": "#CFCFCF"
}
},
"type": "ia.container.coord"
}
}

View File

@ -1,11 +0,0 @@
{
"custom": {},
"params": {},
"props": {},
"root": {
"meta": {
"name": "root"
},
"type": "ia.container.coord"
}
}

View File

@ -1,40 +0,0 @@
WITH SORTERS AS (
SELECT
DATE_FORMAT(MIN(s04_timestamp), "%Y-%m-%d %H:%i:00") AS time,
COUNT(*) AS total,
/* PPH Data */
SUM(sort_code="Success") AS success,
SUM(sort_code IN ("Dest Invalid", "Dest None", "Underutilized")) AS awcs,
SUM(sort_code IN ("Dest Disabled", "Dest Full", "Dim Error", "Unexpected", "Weight Err")) AS operational,
SUM(sort_code IN ("Dest Fault", "Div Fail", "Gap Err", "Lost", "Rate High", "Track Err", "Unknown", "Unsafe")) AS machine,
SUM(sort_code IN ("No Read", "No Code", "Multi Label")) AS scanner,
/* Problem Solve Data */
SUM(sort_code="No Read") AS no_read,
SUM(sort_code="No Code") AS no_code,
SUM(sort_code="Multi Label") AS multi_label,
/* Sorter Error Data */
SUM(sort_code="Gap Err") AS gap_err,
SUM(sort_code="Div Fail") AS div_fail,
SUM(sort_code="Dest None") AS dest_none,
SUM(sort_code="Lost") AS lost
FROM package_history
WHERE s04_timestamp BETWEEN :startDate AND :endDate
AND sorter = :sorter
GROUP BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
ORDER BY DATE_FORMAT(s04_timestamp, "%Y-%m-%d %H:%i:00")
)
SELECT
time,
/* PPH: */
ROUND((SUM((total - machine - scanner)*60) OVER w)/(:movAvgMin+1)) AS total_pph,
/* Problem Solve Percents: */
ROUND((SUM(no_read/total) OVER w)/(:movAvgMin+1), 4) AS no_read_percent,
ROUND((SUM(no_code/total) OVER w)/(:movAvgMin+1), 4) AS no_code_percent,
ROUND((SUM(multi_label/total) OVER w)/(:movAvgMin+1), 4) AS multi_label_percent,
/* Sorter Error Percents: */
ROUND((SUM(gap_err/total) OVER w)/(:movAvgMin+1), 4) AS gap_err_percent,
ROUND((SUM(div_fail/total) OVER w)/(:movAvgMin+1), 4) AS div_fail_percent,
ROUND((SUM(dest_none/total) OVER w)/(:movAvgMin+1), 4) AS dest_none_percent,
ROUND((SUM(lost/total) OVER w)/(:movAvgMin+1), 4) AS lost_percent
FROM SORTERS
WINDOW w AS (ORDER BY STR_TO_DATE(time, "%Y-%m-%d %H:%i:00") RANGE BETWEEN INTERVAL :movAvgMin MINUTE PRECEDING AND CURRENT ROW);

View File

@ -1,104 +0,0 @@
import os
import shutil
from com.inductiveautomation.ignition.common.model import ApplicationScope
os_symlink = getattr(os, "symlink", None)
if callable(os_symlink):
pass
else:
def symlink_ms(source, link_name):
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
flags = 1 if os.path.isdir(source) else 0
if csl(link_name, source, flags) == 0:
raise ctypes.WinError()
os.symlink = symlink_ms
#############
### Constants
#############
WP = os.path.join(os.getcwd(), "webserver", "webapps", "main", "documents")
DP = WP#"D:\\Ignition\\Documents"
#if not os.path.exists("D:\\"):
# Not on actual production server, so store locally:
#DP = "Ignition\\Documents"
if ApplicationScope.isGateway(ApplicationScope.getGlobalScope()) and not os.path.exists(DP):
os.makedirs(DP)
#os.symlink(DP, WP)
# The above symlink doesn't work on windows due to process permissions. Need to manually set up:
# mklink /J "C:\\Program Files\\Inductive Automation\\Ignition\\webserver\\webapps\\main\\documents" D:\\Ignition\\Documents
PDF_ICON = {
"path": "material/picture_as_pdf",
"color": "#869DB1",
"style": {}
}
#######################################################
#######################################################
#######################################################
#### Functions
#######################################################
def getFileTree(path, phantomPath=""):
files = []
for f in os.listdir(path):
filepath = os.path.join(path, f)
filephantompath = os.path.join(phantomPath, f)
# Check what type of file:
if os.path.isfile(filepath):
# Add leaf node (file) if pdf:
if f.endswith(".pdf"):
files.append({
"label": f,
"expanded": False,
"icon": PDF_ICON,
"data": filephantompath,
"items": []
})
elif os.path.isdir(filepath):
# Add folder:
files.append({
"label": f,
"expanded": False,
"data": "",
"items": getFileTree(filepath, filephantompath)
})
# Return list:
return files
def getDocuments():
# Return list:
return getFileTree(DP)
def createFolder(folderpath):
if not os.path.exists(folderpath):
os.makedirs(os.path.join(DP, folderpath))
def uploadDocument(file, folder=""):
filename = os.path.join(DP, folder, file.name)
if filename[-4:].lower() <> ".pdf":
system.perspective("File extension not compatible!\r\nThe supported extensions are: pdf")
else:
filepath = os.path.join(DP, filename)
#if system.file.fileExists(filepath):
#return "Config file already exists!\r\nYou must delete the config before uploading over it."
file.copyTo(filepath)
#system.file.writeFile(filepath, contents, False)
def deleteDocuments(filenames):
for filename in filenames:
filepath = os.path.join(DP, filename)
try:
if os.path.isfile(filepath):
os.remove(filepath)
elif os.path.isdir(filepath):
shutil.rmtree(filepath)
else:
pass#return "Config file doesn't exist!"
except:
system.perspective.print("Failed to delete "+filename)

Some files were not shown because too many files have changed in this diff Show More