showing devices and tags in the docked conveyor
@ -0,0 +1,213 @@
|
||||
import os, json, sys
|
||||
|
||||
global_device_mapping = {}
|
||||
|
||||
def build_device_mapping(full_tag_path):
|
||||
"""
|
||||
Builds global_device_mapping for devices that:
|
||||
- Belong to the same PLC (index 1)
|
||||
- Are children of the clicked device (start with clicked_name + "_")
|
||||
"""
|
||||
global global_device_mapping
|
||||
global_device_mapping.clear()
|
||||
|
||||
try:
|
||||
# Parse PLC and clicked device
|
||||
path_parts = full_tag_path.split("/")
|
||||
plc_name = path_parts[1] if len(path_parts) > 1 else path_parts[0]
|
||||
clicked_name = path_parts[-1] if len(path_parts) > 0 else ""
|
||||
|
||||
project_name = system.util.getProjectName()
|
||||
base_path = (
|
||||
os.getcwd().replace("\\", "/")
|
||||
+ "/data/projects/"
|
||||
+ project_name
|
||||
+ "/com.inductiveautomation.perspective/Views/autStand/Detailed_Views"
|
||||
)
|
||||
|
||||
if not os.path.exists(base_path):
|
||||
system.perspective.print("Path not found: " + base_path)
|
||||
return {}
|
||||
|
||||
# loop through all view folders
|
||||
for view_folder in os.listdir(base_path):
|
||||
json_file = os.path.join(base_path, view_folder, "view.json")
|
||||
if not os.path.isfile(json_file):
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(json_file, "r") as fh:
|
||||
view_json = json.load(fh)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# go one level deeper: root -> children[0] (coordinateContainer) -> its children
|
||||
root_children = (view_json.get("root") or {}).get("children") or []
|
||||
if not root_children:
|
||||
continue
|
||||
|
||||
container = root_children[0]
|
||||
children = container.get("children") or []
|
||||
|
||||
for child in children:
|
||||
props = child.get("props") or {}
|
||||
params = props.get("params") or {}
|
||||
tag_props = params.get("tagProps")
|
||||
|
||||
if isinstance(tag_props, list) and len(tag_props) > 0:
|
||||
tag_prop = str(tag_props[0])
|
||||
parts = tag_prop.split("/")
|
||||
|
||||
if len(parts) > 1 and parts[1] == plc_name:
|
||||
dev_name = parts[-1]
|
||||
|
||||
# ONLY include devices that are children of clicked_name
|
||||
prefix = clicked_name + "_"
|
||||
if dev_name.startswith(prefix):
|
||||
global_device_mapping[dev_name] = {
|
||||
"tagPath": tag_prop,
|
||||
"zone": view_folder
|
||||
}
|
||||
|
||||
return global_device_mapping
|
||||
|
||||
except Exception as e:
|
||||
whid = "unknown"
|
||||
try:
|
||||
whid = system.tag.readBlocking("Configuration/FC")[0].value
|
||||
except:
|
||||
pass
|
||||
logger = system.util.getLogger("%s-build_device_mapping" % whid)
|
||||
exc_type, exc_obj, tb = sys.exc_info()
|
||||
logger.error("Error at line %s: %s" % (tb.tb_lineno, exc_obj))
|
||||
return {}
|
||||
|
||||
def build_device_table(self):
|
||||
"""
|
||||
Converts global_device_mapping into a dataset:
|
||||
Columns: Device, Status
|
||||
Reads each tag value, falls back to 'Unknown' if error/null.
|
||||
"""
|
||||
headers = ["Device", "Status"]
|
||||
rows = []
|
||||
state_mappings = {
|
||||
0: "Closed",
|
||||
1: "Actuated",
|
||||
2: "Communication Faulted",
|
||||
3: "Conveyor Running In Maintenance Mode",
|
||||
4: "Disabled",
|
||||
5: "Disconnected",
|
||||
6: "Stopped",
|
||||
7: "Enabled Not Running",
|
||||
8: "Encoder Fault",
|
||||
9: "Energy Management",
|
||||
10: "ESTOP Was Actuated",
|
||||
11: "EStopped",
|
||||
12: "EStopped Locally",
|
||||
13: "Extended Faulted",
|
||||
14: "Full",
|
||||
15: "Gaylord Start Pressed",
|
||||
16: "Jam Fault",
|
||||
17: "Jammed",
|
||||
18: "Loading Allowed",
|
||||
19: "Loading Not Allowed",
|
||||
20: "Low Air Pressure Fault Was Present",
|
||||
21: "Maintenance Mode",
|
||||
22: "Conveyor Stopped In Maintenance Mode",
|
||||
23: "Motor Faulted",
|
||||
24: "Motor Was Faulted",
|
||||
25: "Normal",
|
||||
26: "Off Inactive",
|
||||
27: "Open",
|
||||
28: "PLC Ready To Run",
|
||||
29: "Package Release Pressed",
|
||||
30: "Power Branch Was Faulted",
|
||||
31: "Pressed",
|
||||
32: "Ready To Receive",
|
||||
33: "Running",
|
||||
34: "Started",
|
||||
35: "Stopped",
|
||||
36: "System Started",
|
||||
37: "Unknown",
|
||||
38: "VFD Fault",
|
||||
39: "Conveyor Running In Power Saving Mode",
|
||||
40: "Conveyor Jogging In Maintenance Mode",
|
||||
41: "VFD Reset Required",
|
||||
42: "Jam Reset Push Button Pressed",
|
||||
43: "Start Push Button Pressed",
|
||||
44: "Stop Push Button Pressed",
|
||||
45: "No Container",
|
||||
46: "Ready To Be Enabled",
|
||||
47: "Half Full",
|
||||
48: "Enabled",
|
||||
49: "Tipper Faulted"
|
||||
}
|
||||
|
||||
try:
|
||||
for dev_name, info in global_device_mapping.items():
|
||||
tagPath = info.get("tagPath", "")
|
||||
status_value = ""
|
||||
provider = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]"
|
||||
path = provider + tagPath + "/State"
|
||||
|
||||
if tagPath:
|
||||
try:
|
||||
result = system.tag.readBlocking([path])[0]
|
||||
status_value = state_mappings.get(result.value, "Unknown")
|
||||
except:
|
||||
status_value = "Unknown"
|
||||
|
||||
rows.append([dev_name, status_value])
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error building device table: %s" % e)
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
|
||||
def getAllTags(self, tagPath):
|
||||
"""
|
||||
Reads all tags under a UDT instance and returns a dataset.
|
||||
|
||||
Args:
|
||||
tagPath (str): Full path to the clicked device instance (e.g., System/MCM01/Photoeyes/TPE/PS3_1_TPE1)
|
||||
fc_custom (str): Name of the FC custom property to determine the tag provider
|
||||
|
||||
Returns:
|
||||
system.dataset: Dataset with columns ["Name", "OPC Path", "Value"]
|
||||
"""
|
||||
headers = ["Name", "OPC Path", "Value"]
|
||||
rows = []
|
||||
|
||||
try:
|
||||
# Determine the tag provider
|
||||
path = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]" + tagPath
|
||||
|
||||
# Browse all child tags under this UDT instance
|
||||
children = system.tag.browse(path, filter = {}).getResults()
|
||||
for child in children:
|
||||
tagType = str(child.get("tagType", ""))
|
||||
name = str(child.get("name", ""))
|
||||
fullPath = str(child.get("fullPath", ""))
|
||||
|
||||
# Remove provider if present
|
||||
if fullPath.startswith("[") and "]" in fullPath:
|
||||
fullPath = fullPath.split("]", 1)[1]
|
||||
|
||||
# Only include atomic tags, skip folders
|
||||
if tagType == "AtomicTag":
|
||||
value = None
|
||||
try:
|
||||
result = system.tag.readBlocking([fullPath])[0]
|
||||
if result is not None and not result.isNull() and result.quality.isGood():
|
||||
value = result.value
|
||||
except:
|
||||
value = "Unknown"
|
||||
|
||||
rows.append([name, fullPath, value])
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
@ -156,7 +156,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/PS3_1",
|
||||
"value",
|
||||
@ -249,7 +248,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/PS3_2",
|
||||
"value",
|
||||
@ -3002,7 +3000,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"forceFaultStatus": null,
|
||||
"name": "red",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/VFD/UL14_1_VFD1",
|
||||
@ -4274,7 +4271,7 @@
|
||||
},
|
||||
{
|
||||
"meta": {
|
||||
"name": "PS3_3_SIO1"
|
||||
"name": "PS3_2_SIO1"
|
||||
},
|
||||
"position": {
|
||||
"height": 0.0204,
|
||||
@ -4285,7 +4282,7 @@
|
||||
"props": {
|
||||
"params": {
|
||||
"tagProps": [
|
||||
"System/MCM01/SIO/PS3_3_SIO1",
|
||||
"System/MCM01/SIO/PS3_2_SIO1",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
|
Before Width: | Height: | Size: 9.6 KiB |
@ -1,6 +1,161 @@
|
||||
{
|
||||
"custom": {
|
||||
"FilteredViews": []
|
||||
"FilteredViews": [
|
||||
{
|
||||
"Path": "autStand/Equipment/Beacon",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Button",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Camera",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Chute",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Conveyor",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Conveyor45",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Conveyor_Left90",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Conveyor_Right90",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/DPM",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/EPC",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Encoder",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Field_IO",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/JAM",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/MCM",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Photoeye_Tracking",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Photoeye_Long",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Photoeye_Chute",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/ProxSwitch",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/SS_Button",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Safety_IO",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/Solenoid",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Path": "autStand/Equipment/VFD",
|
||||
"instancePosition": {},
|
||||
"instanceStyle": {
|
||||
"classes": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"events": {
|
||||
"system": {
|
||||
|
After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 34 KiB |
@ -190,7 +190,7 @@
|
||||
"dom": {
|
||||
"onClick": {
|
||||
"config": {
|
||||
"script": "\tsystem.perspective.openDock(\u0027Docked-East-VFD\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})\t"
|
||||
"script": "\tautStand.devices.build_device_mapping(self.view.params.tagProps[0])\n\tdevice_table_dataset \u003d autStand.devices.build_device_table(self)\n\ttags_table_dataset \u003d autStand.devices.getAllTags(self, self.view.params.tagProps[0])\n\tsystem.perspective.openDock(\u0027Docked-East-VFD\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps, \"devices\": device_table_dataset, \"tags\":tags_table_dataset})"
|
||||
},
|
||||
"scope": "G",
|
||||
"type": "script"
|
||||
|
Before Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
@ -0,0 +1,643 @@
|
||||
{
|
||||
"custom": {
|
||||
"color": "#C2C2C2",
|
||||
"priority": "No Active Alarms",
|
||||
"state": "Closed"
|
||||
},
|
||||
"params": {
|
||||
"angle": 0,
|
||||
"directionLeft": true,
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/VFD/UL1_3_VFD1",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"propConfig": {
|
||||
"custom.color": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"fallbackDelay": 2.5,
|
||||
"mode": "indirect",
|
||||
"references": {
|
||||
"0": "{view.params.tagProps[0]}",
|
||||
"fc": "{session.custom.fc}"
|
||||
},
|
||||
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/Color"
|
||||
},
|
||||
"transforms": [
|
||||
{
|
||||
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
|
||||
"type": "expression"
|
||||
},
|
||||
{
|
||||
"fallback": "#000000",
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": 0,
|
||||
"output": "#C2C2C2"
|
||||
},
|
||||
{
|
||||
"input": 1,
|
||||
"output": "#FF0000"
|
||||
},
|
||||
{
|
||||
"input": 2,
|
||||
"output": "#FFA500"
|
||||
},
|
||||
{
|
||||
"input": 3,
|
||||
"output": "#0008FF"
|
||||
},
|
||||
{
|
||||
"input": 4,
|
||||
"output": "#00FF00"
|
||||
},
|
||||
{
|
||||
"input": 5,
|
||||
"output": "#FFF700"
|
||||
},
|
||||
{
|
||||
"input": 6,
|
||||
"output": "#87CEEB"
|
||||
},
|
||||
{
|
||||
"input": 7,
|
||||
"output": "#90EE90"
|
||||
},
|
||||
{
|
||||
"input": 8,
|
||||
"output": "#964B00"
|
||||
},
|
||||
{
|
||||
"input": 9,
|
||||
"output": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"input": 10,
|
||||
"output": "#000000"
|
||||
},
|
||||
{
|
||||
"input": 11,
|
||||
"output": "#8B0000"
|
||||
},
|
||||
{
|
||||
"input": 12,
|
||||
"output": "#808080"
|
||||
},
|
||||
{
|
||||
"input": 13,
|
||||
"output": "#8B8000"
|
||||
},
|
||||
{
|
||||
"input": 14,
|
||||
"output": "#006400"
|
||||
},
|
||||
{
|
||||
"input": 15,
|
||||
"output": "#FFFFC5"
|
||||
},
|
||||
{
|
||||
"input": 16,
|
||||
"output": "#00008B"
|
||||
},
|
||||
{
|
||||
"input": 17,
|
||||
"output": "#FF7276"
|
||||
},
|
||||
{
|
||||
"input": 18,
|
||||
"output": "#556B2F"
|
||||
},
|
||||
{
|
||||
"input": 19,
|
||||
"output": "#B43434"
|
||||
},
|
||||
{
|
||||
"input": 20,
|
||||
"output": "#4682B4"
|
||||
},
|
||||
{
|
||||
"input": 21,
|
||||
"output": "#FFD700"
|
||||
}
|
||||
],
|
||||
"outputType": "color",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "tag"
|
||||
},
|
||||
"persistent": true
|
||||
},
|
||||
"custom.priority": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"fallbackDelay": 2.5,
|
||||
"mode": "indirect",
|
||||
"references": {
|
||||
"0": "{view.params.tagProps[0]}",
|
||||
"fc": "{session.custom.fc}"
|
||||
},
|
||||
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/Priority"
|
||||
},
|
||||
"transforms": [
|
||||
{
|
||||
"expression": "coalesce({value},{view.params.forceFaultStatus},0)",
|
||||
"type": "expression"
|
||||
},
|
||||
{
|
||||
"fallback": null,
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": 0,
|
||||
"output": "No Active Alarms"
|
||||
},
|
||||
{
|
||||
"input": 1,
|
||||
"output": "High"
|
||||
},
|
||||
{
|
||||
"input": 2,
|
||||
"output": "Medium"
|
||||
},
|
||||
{
|
||||
"input": 3,
|
||||
"output": "Low"
|
||||
},
|
||||
{
|
||||
"input": 4,
|
||||
"output": "Diagnostic"
|
||||
}
|
||||
],
|
||||
"outputType": "scalar",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "tag"
|
||||
},
|
||||
"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": "Unknown",
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": 0,
|
||||
"output": "Closed"
|
||||
},
|
||||
{
|
||||
"input": 1,
|
||||
"output": "Actuated"
|
||||
},
|
||||
{
|
||||
"input": 2,
|
||||
"output": "Communication Faulted"
|
||||
},
|
||||
{
|
||||
"input": 3,
|
||||
"output": "Conveyor Running In Maintenance Mode"
|
||||
},
|
||||
{
|
||||
"input": 4,
|
||||
"output": "Disabled"
|
||||
},
|
||||
{
|
||||
"input": 5,
|
||||
"output": "Disconnected"
|
||||
},
|
||||
{
|
||||
"input": 6,
|
||||
"output": "Stopped"
|
||||
},
|
||||
{
|
||||
"input": 7,
|
||||
"output": "Enabled Not Running"
|
||||
},
|
||||
{
|
||||
"input": 8,
|
||||
"output": "Encoder Fault"
|
||||
},
|
||||
{
|
||||
"input": 9,
|
||||
"output": "Energy Management"
|
||||
},
|
||||
{
|
||||
"input": 10,
|
||||
"output": "ESTOP Was Actuated"
|
||||
},
|
||||
{
|
||||
"input": 11,
|
||||
"output": "EStopped"
|
||||
},
|
||||
{
|
||||
"input": 12,
|
||||
"output": "EStopped Locally"
|
||||
},
|
||||
{
|
||||
"input": 13,
|
||||
"output": "Extended Faulted"
|
||||
},
|
||||
{
|
||||
"input": 14,
|
||||
"output": "Full"
|
||||
},
|
||||
{
|
||||
"input": 15,
|
||||
"output": "Gaylord Start Pressed"
|
||||
},
|
||||
{
|
||||
"input": 16,
|
||||
"output": "Jam Fault"
|
||||
},
|
||||
{
|
||||
"input": 17,
|
||||
"output": "Jammed"
|
||||
},
|
||||
{
|
||||
"input": 18,
|
||||
"output": "Loading Allowed"
|
||||
},
|
||||
{
|
||||
"input": 19,
|
||||
"output": "Loading Not Allowed"
|
||||
},
|
||||
{
|
||||
"input": 20,
|
||||
"output": "Low Air Pressure Fault Was Present"
|
||||
},
|
||||
{
|
||||
"input": 21,
|
||||
"output": "Maintenance Mode"
|
||||
},
|
||||
{
|
||||
"input": 22,
|
||||
"output": "Conveyor Stopped In Maintenance Mode"
|
||||
},
|
||||
{
|
||||
"input": 23,
|
||||
"output": "Motor Faulted"
|
||||
},
|
||||
{
|
||||
"input": 24,
|
||||
"output": "Motor Was Faulted"
|
||||
},
|
||||
{
|
||||
"input": 25,
|
||||
"output": "Normal"
|
||||
},
|
||||
{
|
||||
"input": 26,
|
||||
"output": "Off Inactive"
|
||||
},
|
||||
{
|
||||
"input": 27,
|
||||
"output": "Open"
|
||||
},
|
||||
{
|
||||
"input": 28,
|
||||
"output": "PLC Ready To Run"
|
||||
},
|
||||
{
|
||||
"input": 29,
|
||||
"output": "Package Release Pressed"
|
||||
},
|
||||
{
|
||||
"input": 30,
|
||||
"output": "Power Branch Was Faulted"
|
||||
},
|
||||
{
|
||||
"input": 31,
|
||||
"output": "Pressed"
|
||||
},
|
||||
{
|
||||
"input": 32,
|
||||
"output": "Ready To Receive"
|
||||
},
|
||||
{
|
||||
"input": 33,
|
||||
"output": "Running"
|
||||
},
|
||||
{
|
||||
"input": 34,
|
||||
"output": "Started"
|
||||
},
|
||||
{
|
||||
"input": 35,
|
||||
"output": "Stopped"
|
||||
},
|
||||
{
|
||||
"input": 36,
|
||||
"output": "System Started"
|
||||
},
|
||||
{
|
||||
"input": 37,
|
||||
"output": "Unknown"
|
||||
},
|
||||
{
|
||||
"input": 38,
|
||||
"output": "VFD Fault"
|
||||
},
|
||||
{
|
||||
"input": 39,
|
||||
"output": "Conveyor Running In Power Saving Mode"
|
||||
},
|
||||
{
|
||||
"input": 40,
|
||||
"output": "Conveyor Jogging In Maintenance Mode"
|
||||
},
|
||||
{
|
||||
"input": 41,
|
||||
"output": "VFD Reset Required"
|
||||
},
|
||||
{
|
||||
"input": 42,
|
||||
"output": "Jam Reset Push Button Pressed"
|
||||
},
|
||||
{
|
||||
"input": 43,
|
||||
"output": "Start Push Button Pressed"
|
||||
},
|
||||
{
|
||||
"input": 44,
|
||||
"output": "Stop Push Button Pressed"
|
||||
},
|
||||
{
|
||||
"input": 45,
|
||||
"output": "No Container"
|
||||
},
|
||||
{
|
||||
"input": 46,
|
||||
"output": "Ready To Be Enabled"
|
||||
},
|
||||
{
|
||||
"input": 47,
|
||||
"output": "Half Full"
|
||||
},
|
||||
{
|
||||
"input": 48,
|
||||
"output": "Enabled"
|
||||
},
|
||||
{
|
||||
"input": 49,
|
||||
"output": "Tipper Faulted"
|
||||
}
|
||||
],
|
||||
"outputType": "scalar",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "tag"
|
||||
},
|
||||
"persistent": true
|
||||
},
|
||||
"params.angle": {
|
||||
"paramDirection": "input",
|
||||
"persistent": true
|
||||
},
|
||||
"params.directionLeft": {
|
||||
"paramDirection": "input",
|
||||
"persistent": true
|
||||
},
|
||||
"params.tagProps": {
|
||||
"paramDirection": "inout",
|
||||
"persistent": true
|
||||
}
|
||||
},
|
||||
"props": {
|
||||
"defaultSize": {
|
||||
"height": 20,
|
||||
"width": 29
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"children": [
|
||||
{
|
||||
"meta": {
|
||||
"name": "RunningStatus"
|
||||
},
|
||||
"position": {
|
||||
"grow": 1
|
||||
},
|
||||
"propConfig": {
|
||||
"position.display": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"expression": "if(({view.custom.display_icon} || ({view.custom.show_running} \u0026\u0026 !{view.custom.show_error})) \u0026\u0026 !{view.params.directionLeft}, True, False)"
|
||||
},
|
||||
"enabled": false,
|
||||
"type": "expr"
|
||||
}
|
||||
},
|
||||
"props.elements[0].fill.paint": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"expression": "if(\r\n {view.custom.state} \u003d \"Closed\",\r\n \"#000000\",\r\n {view.custom.color}\r\n)\r\n"
|
||||
},
|
||||
"type": "expr"
|
||||
}
|
||||
},
|
||||
"props.style.transform": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"fallbackDelay": 2.5,
|
||||
"mode": "indirect",
|
||||
"references": {
|
||||
"0": "{view.params.tagProps[0]}",
|
||||
"fc": "{session.custom.fc}"
|
||||
},
|
||||
"tagPath": "[{fc}_SCADA_TAG_PROVIDER]{0}/Maintenance/Direction"
|
||||
},
|
||||
"transforms": [
|
||||
{
|
||||
"expression": "coalesce({value},{view.params.forceFaultStatus},\"\")",
|
||||
"type": "expression"
|
||||
},
|
||||
{
|
||||
"fallback": "",
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": true,
|
||||
"output": "scaleX(-1)"
|
||||
}
|
||||
],
|
||||
"outputType": "scalar",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "tag"
|
||||
}
|
||||
}
|
||||
},
|
||||
"props": {
|
||||
"elements": [
|
||||
{
|
||||
"d": "M 5 15 L 45 15 L 60 25 L 60 55 L 20 55 L 5 45 Z M 5 15 L 15 5 L 55 5 L 60 25 M 45 15 L 55 5",
|
||||
"fill": {},
|
||||
"name": "path",
|
||||
"stroke": {
|
||||
"paint": "#4c4c4c",
|
||||
"width": "2"
|
||||
},
|
||||
"type": "path"
|
||||
}
|
||||
],
|
||||
"style": {
|
||||
"overflow": "hidden"
|
||||
},
|
||||
"viewBox": "-1.5 -1.5 73 63"
|
||||
},
|
||||
"type": "ia.shapes.svg"
|
||||
}
|
||||
],
|
||||
"events": {
|
||||
"dom": {
|
||||
"onClick": {
|
||||
"config": {
|
||||
"script": "\tsystem.perspective.openDock(\u0027Docked-Eas-TPR\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})"
|
||||
},
|
||||
"scope": "G",
|
||||
"type": "script"
|
||||
},
|
||||
"onDoubleClick": {
|
||||
"config": {
|
||||
"script": "\ttagProps \u003d self.view.params.tagProps\n\tsystem.perspective.openPopup(\"StatusPopUP\", \"PopUp-Views/Controller-Equipment/Information\", params \u003d{\"tagProps\":tagProps})\n\t"
|
||||
},
|
||||
"enabled": false,
|
||||
"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,
|
||||
"location": "top-left",
|
||||
"style": {}
|
||||
}
|
||||
},
|
||||
"propConfig": {
|
||||
"meta.tooltip.style.classes": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"expression": "{view.custom.priority}"
|
||||
},
|
||||
"transforms": [
|
||||
{
|
||||
"fallback": "Alarms-Styles/NoAlarm",
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": "High",
|
||||
"output": "Alarms-Styles/High"
|
||||
},
|
||||
{
|
||||
"input": "Medium",
|
||||
"output": "Alarms-Styles/Medium"
|
||||
},
|
||||
{
|
||||
"input": "Low",
|
||||
"output": "Alarms-Styles/Low"
|
||||
},
|
||||
{
|
||||
"input": "Diagnostic",
|
||||
"output": "Alarms-Styles/Diagnostic"
|
||||
}
|
||||
],
|
||||
"outputType": "style-list",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "expr"
|
||||
}
|
||||
},
|
||||
"meta.tooltip.text": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"expression": "if(\n {view.custom.state} !\u003d \"Closed\",\n \"Source Id: \" + {view.params.tagProps[0]} + \", Priority: \" + {view.custom.priority} + \", State: \" + {view.custom.state},\n \"Device Disconnected\"\n)\n"
|
||||
},
|
||||
"type": "expr"
|
||||
}
|
||||
},
|
||||
"meta.visible": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"path": "session.custom.alarm_filter.show_running"
|
||||
},
|
||||
"type": "property"
|
||||
}
|
||||
},
|
||||
"props.style.borderStyle": {
|
||||
"binding": {
|
||||
"config": {
|
||||
"path": "view.custom.disconnected"
|
||||
},
|
||||
"enabled": false,
|
||||
"transforms": [
|
||||
{
|
||||
"fallback": "",
|
||||
"inputType": "scalar",
|
||||
"mappings": [
|
||||
{
|
||||
"input": true,
|
||||
"output": "solid"
|
||||
},
|
||||
{
|
||||
"input": false,
|
||||
"output": "none"
|
||||
}
|
||||
],
|
||||
"outputType": "scalar",
|
||||
"type": "map"
|
||||
}
|
||||
],
|
||||
"type": "property"
|
||||
}
|
||||
}
|
||||
},
|
||||
"props": {
|
||||
"justify": "center",
|
||||
"style": {
|
||||
"borderColor": "#FF0000",
|
||||
"borderStyle": "none",
|
||||
"borderWidth": "2px",
|
||||
"cursor": "pointer"
|
||||
}
|
||||
},
|
||||
"type": "ia.container.flex"
|
||||
}
|
||||
}
|
||||
@ -53,7 +53,18 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value"
|
||||
"tagProps": [
|
||||
"System/MCM02/Conveyor/PS3_12",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"path": "autStand/Equipment/Conveyor"
|
||||
},
|
||||
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 23 KiB |
@ -428,7 +428,7 @@
|
||||
"modal": false,
|
||||
"resizable": false,
|
||||
"show": "onDemand",
|
||||
"size": 400,
|
||||
"size": 600,
|
||||
"viewParams": {},
|
||||
"viewPath": "autStand/PopUp-Views/Controller-Equipment/Information-Docked-East-Conv"
|
||||
},
|
||||
@ -596,7 +596,7 @@
|
||||
"modal": false,
|
||||
"resizable": false,
|
||||
"show": "onDemand",
|
||||
"size": 400,
|
||||
"size": 600,
|
||||
"viewParams": {},
|
||||
"viewPath": "autStand/PopUp-Views/Controller-Equipment/Information-Docked-East-Conv"
|
||||
},
|
||||
|
After Width: | Height: | Size: 14 KiB |
@ -830,7 +830,6 @@
|
||||
}
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 2,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 14 KiB |
@ -3287,7 +3287,7 @@
|
||||
"grow": 1
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 2,
|
||||
"currentTabIndex": 1,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
After Width: | Height: | Size: 10 KiB |
@ -428,7 +428,7 @@
|
||||
"modal": false,
|
||||
"resizable": false,
|
||||
"show": "onDemand",
|
||||
"size": 400,
|
||||
"size": 600,
|
||||
"viewParams": {},
|
||||
"viewPath": "autStand/PopUp-Views/Controller-Equipment/Information-Docked-East-Conv"
|
||||
},
|
||||
@ -596,7 +596,7 @@
|
||||
"modal": false,
|
||||
"resizable": false,
|
||||
"show": "onDemand",
|
||||
"size": 400,
|
||||
"size": 600,
|
||||
"viewParams": {},
|
||||
"viewPath": "autStand/PopUp-Views/Controller-Equipment/Information-Docked-East-Conv"
|
||||
},
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-04T14:13:10Z"
|
||||
"timestamp": "2025-09-10T08:20:09Z"
|
||||
},
|
||||
"lastModificationSignature": "02a3fd1afca63b5162124a67cb4a784c58d8f416ea4c7abd469435cf6f5777ca"
|
||||
"lastModificationSignature": "4604c221ea422bc2df7f817693ca918ac76a7b6deea75cc0f98f02304c3f589b"
|
||||
}
|
||||
}
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-10T06:49:04Z"
|
||||
"timestamp": "2025-09-11T13:51:08Z"
|
||||
},
|
||||
"lastModificationSignature": "44f4fb4480d7e3818a23f3e6bc8b8f8fb62bc4849ebba282fd85b074289e1402"
|
||||
"lastModificationSignature": "0d5aa46aa0f12e061d22c571ce45ba9752fc2950f666a99f1153bd736126c651"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 67 KiB |
@ -156,7 +156,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/PS3_1",
|
||||
"value",
|
||||
@ -249,7 +248,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/PS3_2",
|
||||
"value",
|
||||
@ -3002,7 +3000,6 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"forceFaultStatus": null,
|
||||
"name": "red",
|
||||
"tagProps": [
|
||||
"System/MCM01/Conveyor/VFD/UL14_1_VFD1",
|
||||
@ -4274,7 +4271,7 @@
|
||||
},
|
||||
{
|
||||
"meta": {
|
||||
"name": "PS3_3_SIO1"
|
||||
"name": "PS3_2_SIO1"
|
||||
},
|
||||
"position": {
|
||||
"height": 0.0204,
|
||||
@ -4285,7 +4282,7 @@
|
||||
"props": {
|
||||
"params": {
|
||||
"tagProps": [
|
||||
"System/MCM01/SIO/PS3_3_SIO1",
|
||||
"System/MCM01/SIO/PS3_2_SIO1",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-09T14:19:22Z"
|
||||
"timestamp": "2025-09-10T10:52:17Z"
|
||||
},
|
||||
"lastModificationSignature": "683c9c1c5b1fb4e19ed2274bbde72455648b29581be47b22839cbceaebef45fe"
|
||||
"lastModificationSignature": "be8f9b14912997311b30491445b083d73b6008d021f37e0063c8cb4e7301b51a"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 90 KiB |
@ -53,7 +53,18 @@
|
||||
},
|
||||
"props": {
|
||||
"params": {
|
||||
"key": "value"
|
||||
"tagProps": [
|
||||
"System/MCM02/Conveyor/PS3_12",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"path": "autStand/Equipment/Conveyor"
|
||||
},
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-09T16:29:55Z"
|
||||
"timestamp": "2025-09-11T13:36:49Z"
|
||||
},
|
||||
"lastModificationSignature": "65ff29e1fcfd4476403a9de995a74ba26950ceb1e7c0e8418517e47c8bb3f419"
|
||||
"lastModificationSignature": "9651f468fd3cab1023dfd80b86ab1fd43ea4b0f43b8ba04bd3c59ddd2bb652a3"
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,7 @@
|
||||
"dom": {
|
||||
"onClick": {
|
||||
"config": {
|
||||
"script": "\tsystem.perspective.openDock(\u0027Docked-East-VFD\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps})\t"
|
||||
"script": "\tautStand.devices.build_device_mapping(self.view.params.tagProps[0])\n\tdevice_table_dataset \u003d autStand.devices.build_device_table(self)\n\ttags_table_dataset \u003d autStand.devices.getAllTags(self, self.view.params.tagProps[0])\n\tsystem.perspective.openDock(\u0027Docked-East-VFD\u0027,params\u003d{\u0027tagProps\u0027:self.view.params.tagProps, \"devices\": device_table_dataset, \"tags\":tags_table_dataset})"
|
||||
},
|
||||
"scope": "G",
|
||||
"type": "script"
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-02T13:45:42Z"
|
||||
"timestamp": "2025-09-10T07:53:32Z"
|
||||
},
|
||||
"lastModificationSignature": "bc77c0ec2c7d05aee6a4a8211df208458a47fffd138e162845eec2b13e46e83a"
|
||||
"lastModificationSignature": "17f7c799be9fd0b4d841f4503eec436a243b32a33f1a1bb5cdc431ce4ad86c65"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 16 KiB |
@ -830,7 +830,6 @@
|
||||
}
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 2,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-02T14:52:25Z"
|
||||
"timestamp": "2025-09-11T14:00:54Z"
|
||||
},
|
||||
"lastModificationSignature": "736e305f35825b0e5643c4c38f95080c5fcd1d7430d699ef0a4e23d218c6e91c"
|
||||
"lastModificationSignature": "cc7f5bc89bdbc61531f44eaa129785367a39a4c2b85cb158444ecb538d8348d4"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 14 KiB |
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-02T14:49:12Z"
|
||||
"timestamp": "2025-09-10T07:56:52Z"
|
||||
},
|
||||
"lastModificationSignature": "27246210e54b3eb4f5cfaba54e4c440c3ae20b7b1829a0766d94f7362c93796d"
|
||||
"lastModificationSignature": "d7208e9095befc233592771a00607908395c5ccacce1821ada57e3955c228fa6"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 34 KiB |
@ -3287,7 +3287,7 @@
|
||||
"grow": 1
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 2,
|
||||
"currentTabIndex": 1,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-10T07:16:44Z"
|
||||
"timestamp": "2025-09-10T07:18:12Z"
|
||||
},
|
||||
"lastModificationSignature": "1fbbd48f74c3d1f7cb590d090d3d808a1acd6e136d8d28d8010bc3f43271ca6d"
|
||||
"lastModificationSignature": "2b540246a675bc0678874102553f75fa14c2d6fdd3f49011d4c2cb479030f3d1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
213
BNA8/ignition/script-python/autStand/devices/code.py
Normal file
@ -0,0 +1,213 @@
|
||||
import os, json, sys
|
||||
|
||||
global_device_mapping = {}
|
||||
|
||||
def build_device_mapping(full_tag_path):
|
||||
"""
|
||||
Builds global_device_mapping for devices that:
|
||||
- Belong to the same PLC (index 1)
|
||||
- Are children of the clicked device (start with clicked_name + "_")
|
||||
"""
|
||||
global global_device_mapping
|
||||
global_device_mapping.clear()
|
||||
|
||||
try:
|
||||
# Parse PLC and clicked device
|
||||
path_parts = full_tag_path.split("/")
|
||||
plc_name = path_parts[1] if len(path_parts) > 1 else path_parts[0]
|
||||
clicked_name = path_parts[-1] if len(path_parts) > 0 else ""
|
||||
|
||||
project_name = system.util.getProjectName()
|
||||
base_path = (
|
||||
os.getcwd().replace("\\", "/")
|
||||
+ "/data/projects/"
|
||||
+ project_name
|
||||
+ "/com.inductiveautomation.perspective/Views/autStand/Detailed_Views"
|
||||
)
|
||||
|
||||
if not os.path.exists(base_path):
|
||||
system.perspective.print("Path not found: " + base_path)
|
||||
return {}
|
||||
|
||||
# loop through all view folders
|
||||
for view_folder in os.listdir(base_path):
|
||||
json_file = os.path.join(base_path, view_folder, "view.json")
|
||||
if not os.path.isfile(json_file):
|
||||
continue
|
||||
|
||||
try:
|
||||
with open(json_file, "r") as fh:
|
||||
view_json = json.load(fh)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# go one level deeper: root -> children[0] (coordinateContainer) -> its children
|
||||
root_children = (view_json.get("root") or {}).get("children") or []
|
||||
if not root_children:
|
||||
continue
|
||||
|
||||
container = root_children[0]
|
||||
children = container.get("children") or []
|
||||
|
||||
for child in children:
|
||||
props = child.get("props") or {}
|
||||
params = props.get("params") or {}
|
||||
tag_props = params.get("tagProps")
|
||||
|
||||
if isinstance(tag_props, list) and len(tag_props) > 0:
|
||||
tag_prop = str(tag_props[0])
|
||||
parts = tag_prop.split("/")
|
||||
|
||||
if len(parts) > 1 and parts[1] == plc_name:
|
||||
dev_name = parts[-1]
|
||||
|
||||
# ONLY include devices that are children of clicked_name
|
||||
prefix = clicked_name + "_"
|
||||
if dev_name.startswith(prefix):
|
||||
global_device_mapping[dev_name] = {
|
||||
"tagPath": tag_prop,
|
||||
"zone": view_folder
|
||||
}
|
||||
|
||||
return global_device_mapping
|
||||
|
||||
except Exception as e:
|
||||
whid = "unknown"
|
||||
try:
|
||||
whid = system.tag.readBlocking("Configuration/FC")[0].value
|
||||
except:
|
||||
pass
|
||||
logger = system.util.getLogger("%s-build_device_mapping" % whid)
|
||||
exc_type, exc_obj, tb = sys.exc_info()
|
||||
logger.error("Error at line %s: %s" % (tb.tb_lineno, exc_obj))
|
||||
return {}
|
||||
|
||||
def build_device_table(self):
|
||||
"""
|
||||
Converts global_device_mapping into a dataset:
|
||||
Columns: Device, Status
|
||||
Reads each tag value, falls back to 'Unknown' if error/null.
|
||||
"""
|
||||
headers = ["Device", "Status"]
|
||||
rows = []
|
||||
state_mappings = {
|
||||
0: "Closed",
|
||||
1: "Actuated",
|
||||
2: "Communication Faulted",
|
||||
3: "Conveyor Running In Maintenance Mode",
|
||||
4: "Disabled",
|
||||
5: "Disconnected",
|
||||
6: "Stopped",
|
||||
7: "Enabled Not Running",
|
||||
8: "Encoder Fault",
|
||||
9: "Energy Management",
|
||||
10: "ESTOP Was Actuated",
|
||||
11: "EStopped",
|
||||
12: "EStopped Locally",
|
||||
13: "Extended Faulted",
|
||||
14: "Full",
|
||||
15: "Gaylord Start Pressed",
|
||||
16: "Jam Fault",
|
||||
17: "Jammed",
|
||||
18: "Loading Allowed",
|
||||
19: "Loading Not Allowed",
|
||||
20: "Low Air Pressure Fault Was Present",
|
||||
21: "Maintenance Mode",
|
||||
22: "Conveyor Stopped In Maintenance Mode",
|
||||
23: "Motor Faulted",
|
||||
24: "Motor Was Faulted",
|
||||
25: "Normal",
|
||||
26: "Off Inactive",
|
||||
27: "Open",
|
||||
28: "PLC Ready To Run",
|
||||
29: "Package Release Pressed",
|
||||
30: "Power Branch Was Faulted",
|
||||
31: "Pressed",
|
||||
32: "Ready To Receive",
|
||||
33: "Running",
|
||||
34: "Started",
|
||||
35: "Stopped",
|
||||
36: "System Started",
|
||||
37: "Unknown",
|
||||
38: "VFD Fault",
|
||||
39: "Conveyor Running In Power Saving Mode",
|
||||
40: "Conveyor Jogging In Maintenance Mode",
|
||||
41: "VFD Reset Required",
|
||||
42: "Jam Reset Push Button Pressed",
|
||||
43: "Start Push Button Pressed",
|
||||
44: "Stop Push Button Pressed",
|
||||
45: "No Container",
|
||||
46: "Ready To Be Enabled",
|
||||
47: "Half Full",
|
||||
48: "Enabled",
|
||||
49: "Tipper Faulted"
|
||||
}
|
||||
|
||||
try:
|
||||
for dev_name, info in global_device_mapping.items():
|
||||
tagPath = info.get("tagPath", "")
|
||||
status_value = ""
|
||||
provider = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]"
|
||||
path = provider + tagPath + "/State"
|
||||
|
||||
if tagPath:
|
||||
try:
|
||||
result = system.tag.readBlocking([path])[0]
|
||||
status_value = state_mappings.get(result.value, "Unknown")
|
||||
except:
|
||||
status_value = "Unknown"
|
||||
|
||||
rows.append([dev_name, status_value])
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error building device table: %s" % e)
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
|
||||
def getAllTags(self, tagPath):
|
||||
"""
|
||||
Reads all tags under a UDT instance and returns a dataset.
|
||||
|
||||
Args:
|
||||
tagPath (str): Full path to the clicked device instance (e.g., System/MCM01/Photoeyes/TPE/PS3_1_TPE1)
|
||||
fc_custom (str): Name of the FC custom property to determine the tag provider
|
||||
|
||||
Returns:
|
||||
system.dataset: Dataset with columns ["Name", "OPC Path", "Value"]
|
||||
"""
|
||||
headers = ["Name", "OPC Path", "Value"]
|
||||
rows = []
|
||||
|
||||
try:
|
||||
# Determine the tag provider
|
||||
path = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]" + tagPath
|
||||
|
||||
# Browse all child tags under this UDT instance
|
||||
children = system.tag.browse(path, filter = {}).getResults()
|
||||
for child in children:
|
||||
tagType = str(child.get("tagType", ""))
|
||||
name = str(child.get("name", ""))
|
||||
fullPath = str(child.get("fullPath", ""))
|
||||
|
||||
# Remove provider if present
|
||||
if fullPath.startswith("[") and "]" in fullPath:
|
||||
fullPath = fullPath.split("]", 1)[1]
|
||||
|
||||
# Only include atomic tags, skip folders
|
||||
if tagType == "AtomicTag":
|
||||
value = None
|
||||
try:
|
||||
result = system.tag.readBlocking([fullPath])[0]
|
||||
if result is not None and not result.isNull() and result.quality.isGood():
|
||||
value = result.value
|
||||
except:
|
||||
value = "Unknown"
|
||||
|
||||
rows.append([name, fullPath, value])
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
17
BNA8/ignition/script-python/autStand/devices/resource.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"scope": "A",
|
||||
"version": 1,
|
||||
"restricted": false,
|
||||
"overridable": true,
|
||||
"files": [
|
||||
"code.py"
|
||||
],
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-11T14:21:44Z"
|
||||
},
|
||||
"hintScope": 2,
|
||||
"lastModificationSignature": "ac100dce34bb5394c6ec164e067a535fc23d24c32e0c752058d22c189107f89f"
|
||||
}
|
||||
}
|
||||
@ -20,3 +20,7 @@ Starting conversion: 20250909:10.44.27
|
||||
Conversion finished. Elapsed time: 10 ms
|
||||
Starting conversion: 20250910:10.51.22
|
||||
Conversion finished. Elapsed time: 11 ms
|
||||
Starting conversion: 20250910:19.14.58
|
||||
Conversion finished. Elapsed time: 10 ms
|
||||
Starting conversion: 20250910:19.17.28
|
||||
Conversion finished. Elapsed time: 11 ms
|
||||
|
||||