recursivly showing all the tags in the views, modified the tags table
@ -1567,6 +1567,75 @@
|
||||
"results": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"selection": {
|
||||
"data": [
|
||||
{
|
||||
"Description": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1 - TEST"
|
||||
},
|
||||
"Device": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1"
|
||||
},
|
||||
"Duration": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "01:12:29"
|
||||
},
|
||||
"FullTag": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "System/MCM01/IO_Block/SIO/PS3_1_SIO1/Alarm/twesrt"
|
||||
},
|
||||
"ID": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
"Location": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "MCM01"
|
||||
},
|
||||
"Priority": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "Diagnostic"
|
||||
},
|
||||
"StartTimestamp": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": {
|
||||
"$": [
|
||||
"ts",
|
||||
0,
|
||||
1758293457803
|
||||
],
|
||||
"$ts": 1758289226000
|
||||
}
|
||||
},
|
||||
"Tag": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1.HMI.twesrt"
|
||||
}
|
||||
}
|
||||
],
|
||||
"selectedColumn": "Duration",
|
||||
"selectedRow": 0
|
||||
}
|
||||
},
|
||||
"type": "ia.display.table"
|
||||
@ -3260,7 +3329,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755606669646
|
||||
},
|
||||
@ -3268,7 +3337,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755608469646
|
||||
}
|
||||
@ -4410,7 +4479,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755606669646
|
||||
},
|
||||
@ -4418,7 +4487,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755608469646
|
||||
},
|
||||
|
After Width: | Height: | Size: 58 KiB |
@ -0,0 +1,81 @@
|
||||
def deviceType(self, path, props):
|
||||
try:
|
||||
docked_view = "Docked-East-"
|
||||
|
||||
devices = []
|
||||
tags = []
|
||||
|
||||
if "Conveyor" in path:
|
||||
docked_view += "Conv"
|
||||
devices = autStand.devices.build_device_table(self)
|
||||
system.perspective.print(devices)
|
||||
elif "VFD" in path:
|
||||
docked_view += "VFD"
|
||||
else:
|
||||
docked_view += "Device"
|
||||
|
||||
tags = autStand.devices.getAllTags(self, props[0])
|
||||
system.perspective.print(tags)
|
||||
|
||||
# return 1
|
||||
return [docked_view, tags, devices]
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
msg = "Error in deviceType: {}\n{}".format(str(e), traceback.format_exc())
|
||||
system.perspective.print(msg)
|
||||
# optionally: system.gui.errorBox(msg) # if running in Vision, not Perspective
|
||||
return None
|
||||
|
||||
|
||||
def handleTagHighlight(view, currentValue):
|
||||
tag_priority = currentValue.value
|
||||
|
||||
# --- CASE 1: Remove all highlights by applying CLEAR class ---
|
||||
if not tag_priority or str(tag_priority).upper() == "CLEAR":
|
||||
for child in view.rootContainer.getChildren()[0].getChildren():
|
||||
try:
|
||||
child.props.style.classes = ""
|
||||
except:
|
||||
pass
|
||||
return False
|
||||
|
||||
parts = str(tag_priority).split("||")
|
||||
tag = parts[0]
|
||||
splitedTag = tag.split("/")
|
||||
deviceName = splitedTag[-1]
|
||||
|
||||
components = view.rootContainer.getChildren()[0].getChildren()
|
||||
|
||||
priority = parts[1]
|
||||
|
||||
foundMatch = False
|
||||
|
||||
# clear all highlights and apply new one when found
|
||||
for child in components:
|
||||
params = child.props.get("params", {})
|
||||
tagProps = params.get("tagProps", {})
|
||||
tagsList = list(tagProps)
|
||||
|
||||
if len(tagsList) == 0:
|
||||
continue
|
||||
|
||||
child.props.style.classes = ""
|
||||
|
||||
tagPath = tagsList[0]
|
||||
# system.perspective.print(tagPath)
|
||||
|
||||
if tag == tagPath:
|
||||
child.props.style["classes"] = "Highlight/Pulse-" + priority
|
||||
path = child.props.get("path")
|
||||
# docked_view = deviceType(child)
|
||||
docked_view = deviceType(view, path, tagProps)
|
||||
# system.perspective.print(docked_view)
|
||||
system.perspective.openDock(docked_view[0], params = {'tagProps':tagProps, 'tags': docked_view[1], 'devices':docked_view[2]})
|
||||
# tags = autStand.devices.getAllTags(view, tagProps[0])
|
||||
# system.perspective.openDock(docked_view, params={'tagProps': tagProps, 'tags': tags})
|
||||
|
||||
foundMatch = True
|
||||
|
||||
return foundMatch
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"$": [
|
||||
"ds",
|
||||
192,
|
||||
1758290292372
|
||||
1758293575644
|
||||
],
|
||||
"$columns": [
|
||||
{
|
||||
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 710 B |
|
Before Width: | Height: | Size: 763 B |
@ -1,6 +1,6 @@
|
||||
{
|
||||
"custom": {
|
||||
"color": "#f9050d",
|
||||
"color": "#C2C2C2",
|
||||
"priority": "No Active Alarms"
|
||||
},
|
||||
"params": {
|
||||
@ -1,58 +0,0 @@
|
||||
def deviceType(view):
|
||||
path = view.props.get("path")
|
||||
docked_view = "Docked-East-"
|
||||
|
||||
if "Conveyor" in path:
|
||||
docked_view +="Conv"
|
||||
elif "VFD" in path:
|
||||
docked_view +="VFD"
|
||||
else :
|
||||
docked_view +="Device"
|
||||
|
||||
return docked_view
|
||||
|
||||
def handleTagHighlight(view, currentValue):
|
||||
tag_priority = currentValue.value
|
||||
|
||||
# --- CASE 1: Remove all highlights by applying CLEAR class ---
|
||||
if not tag_priority or str(tag_priority).upper() == "CLEAR":
|
||||
for child in view.rootContainer.getChildren()[0].getChildren():
|
||||
try:
|
||||
child.props.style.classes = ""
|
||||
except:
|
||||
pass
|
||||
return False
|
||||
|
||||
parts = str(tag_priority).split("||")
|
||||
tag = parts[0]
|
||||
splitedTag = tag.split("/")
|
||||
deviceName = splitedTag[-1]
|
||||
|
||||
components = view.rootContainer.getChildren()[0].getChildren()
|
||||
|
||||
priority = parts[1]
|
||||
|
||||
foundMatch = False
|
||||
|
||||
# clear all highlights and apply new one when found
|
||||
for child in components:
|
||||
params = child.props.get("params", {})
|
||||
tagProps = params.get("tagProps", {})
|
||||
tagsList = list(tagProps)
|
||||
|
||||
if len(tagsList) == 0:
|
||||
continue
|
||||
|
||||
child.props.style.classes = ""
|
||||
|
||||
tagPath = tagsList[0]
|
||||
# system.perspective.print(tagPath)
|
||||
|
||||
if tag == tagPath:
|
||||
child.props.style["classes"] = "Highlight/Pulse-" + priority
|
||||
docked_view = deviceType(child)
|
||||
system.perspective.openDock(docked_view, params={'tagProps': tagProps})
|
||||
foundMatch = True
|
||||
|
||||
return foundMatch
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"PLC": "MCM01",
|
||||
"color": "#C2C2C2",
|
||||
"showTags": true,
|
||||
"state": "Actuated"
|
||||
"state": "Closed"
|
||||
},
|
||||
"params": {
|
||||
"devices": [],
|
||||
@ -1225,7 +1225,10 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin",
|
||||
"whiteSpace": "normal",
|
||||
"wordBreak": "break-all"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1236,7 +1239,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 130
|
||||
"width": 180
|
||||
},
|
||||
{
|
||||
"align": "center",
|
||||
@ -1317,7 +1320,10 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin",
|
||||
"whiteSpace": "normal",
|
||||
"wordBreak": "break-all"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1328,7 +1334,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 350
|
||||
"width": 310
|
||||
},
|
||||
{
|
||||
"align": "center",
|
||||
@ -1409,7 +1415,8 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1420,7 +1427,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 100
|
||||
"width": ""
|
||||
}
|
||||
],
|
||||
"pager": {
|
||||
@ -1454,6 +1461,7 @@
|
||||
"grow": 1
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 3,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
After Width: | Height: | Size: 11 KiB |
@ -167,12 +167,12 @@ def build_device_table(self):
|
||||
|
||||
def getAllTags(self, tagPath):
|
||||
"""
|
||||
Reads all tags under a UDT instance and returns a dataset.
|
||||
|
||||
Reads all tags under a UDT instance (recursively) 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
|
||||
|
||||
tagPath (str): Full path to the clicked device instance
|
||||
(e.g., System/MCM01/Photoeyes/TPE/PS3_1_TPE1)
|
||||
|
||||
Returns:
|
||||
system.dataset: Dataset with columns ["Name", "OPC Path", "Value"]
|
||||
"""
|
||||
@ -180,34 +180,45 @@ def getAllTags(self, tagPath):
|
||||
rows = []
|
||||
|
||||
try:
|
||||
# Determine the tag provider
|
||||
path = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]" + tagPath
|
||||
providerPath = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]"
|
||||
|
||||
# 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]
|
||||
def browseRecursive(basePath, prefix=""):
|
||||
children = system.tag.browse(providerPath + basePath, filter={}).getResults()
|
||||
for child in children:
|
||||
tagType = str(child.get("tagType", ""))
|
||||
name = str(child.get("name", ""))
|
||||
fullPath = str(child.get("fullPath", ""))
|
||||
|
||||
# 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"
|
||||
# Strip provider name
|
||||
if fullPath.startswith("[") and "]" in fullPath:
|
||||
fullPath = fullPath.split("]", 1)[1]
|
||||
|
||||
rows.append([name, fullPath, value])
|
||||
if tagType == "AtomicTag":
|
||||
value = None
|
||||
try:
|
||||
readPath = providerPath + fullPath
|
||||
result = system.tag.readBlocking([readPath])[0]
|
||||
|
||||
if result.quality.isGood():
|
||||
value = str(result.value)
|
||||
else:
|
||||
value = "Unknown"
|
||||
except:
|
||||
value = "Unknown"
|
||||
|
||||
# Use prefix/folder style path if inside folder
|
||||
displayName = prefix + name if prefix else name
|
||||
rows.append([displayName, fullPath, value])
|
||||
|
||||
elif tagType == "Folder":
|
||||
# Dive deeper into folder
|
||||
newPrefix = prefix + name + "/"
|
||||
browseRecursive(basePath + "/" + name, prefix=newPrefix)
|
||||
|
||||
# Start recursion
|
||||
browseRecursive(tagPath)
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
|
After Width: | Height: | Size: 44 KiB |
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-19T12:36:20Z"
|
||||
"timestamp": "2025-09-19T14:52:55Z"
|
||||
},
|
||||
"lastModificationSignature": "b2e342fbe4be98836829c596ad8705d49b652ed3b7d92ceffbd5959bf68bf8c5"
|
||||
"lastModificationSignature": "426a85d902d87208ae4b9e1ece86b27662a69ec0f84ad8525cc6176457f2e505"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
@ -1567,6 +1567,75 @@
|
||||
"results": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"selection": {
|
||||
"data": [
|
||||
{
|
||||
"Description": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1 - TEST"
|
||||
},
|
||||
"Device": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1"
|
||||
},
|
||||
"Duration": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "01:12:29"
|
||||
},
|
||||
"FullTag": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "System/MCM01/IO_Block/SIO/PS3_1_SIO1/Alarm/twesrt"
|
||||
},
|
||||
"ID": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
"Location": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "MCM01"
|
||||
},
|
||||
"Priority": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "Diagnostic"
|
||||
},
|
||||
"StartTimestamp": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": {
|
||||
"$": [
|
||||
"ts",
|
||||
0,
|
||||
1758293457803
|
||||
],
|
||||
"$ts": 1758289226000
|
||||
}
|
||||
},
|
||||
"Tag": {
|
||||
"style": {
|
||||
"classes": "Alarms-Styles/Diagnostic"
|
||||
},
|
||||
"value": "PS3_1_SIO1.HMI.twesrt"
|
||||
}
|
||||
}
|
||||
],
|
||||
"selectedColumn": "Duration",
|
||||
"selectedRow": 0
|
||||
}
|
||||
},
|
||||
"type": "ia.display.table"
|
||||
@ -3260,7 +3329,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755606669646
|
||||
},
|
||||
@ -3268,7 +3337,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755608469646
|
||||
}
|
||||
@ -4410,7 +4479,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755606669646
|
||||
},
|
||||
@ -4418,7 +4487,7 @@
|
||||
"$": [
|
||||
"ts",
|
||||
192,
|
||||
1758280365675
|
||||
1758290858284
|
||||
],
|
||||
"$ts": 1755608469646
|
||||
},
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-19T13:41:00Z"
|
||||
"timestamp": "2025-09-19T14:14:52Z"
|
||||
},
|
||||
"lastModificationSignature": "159bcf779d752460467d842af762f1f4a47cdc2f73efe60da26c4b885dd28702"
|
||||
"lastModificationSignature": "182cc8b9fb64c597187e2e07de9667bc41a9398f6d5a3abeaf73bc1062d5dc13"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 58 KiB |
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-19T13:58:13Z"
|
||||
"timestamp": "2025-09-19T14:52:55Z"
|
||||
},
|
||||
"lastModificationSignature": "b67275b216883876b5da86e62e8434c6a7eb4f0d23a5ba286676c34465d88102"
|
||||
"lastModificationSignature": "82fe10033dc0f7d34622625de96b56b94cdd37e8a748941e2989f86af46b003f"
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
"$": [
|
||||
"ds",
|
||||
192,
|
||||
1758290292372
|
||||
1758293575644
|
||||
],
|
||||
"$columns": [
|
||||
{
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-16T13:36:34Z"
|
||||
"timestamp": "2025-09-19T14:25:56Z"
|
||||
},
|
||||
"lastModificationSignature": "4b1237ac15b4a71b5aca7a85545cea02fd5bcbd3814669135b7d99c28c1a4c68"
|
||||
"lastModificationSignature": "4a006674d6d86b950bd34d4dc9993b3dfe70377a954f0bcf9b632edb664fc92e"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 710 B |
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-18T19:37:21Z"
|
||||
"timestamp": "2025-09-19T14:26:19Z"
|
||||
},
|
||||
"lastModificationSignature": "a59741c6f4844901815e6d950b0dbdf1263034263340da919f0e85a01be19f7b"
|
||||
"lastModificationSignature": "824eacbeea448afe5a876e2b7b4896da09a2fc68d7f1778abb2e5c05f2d4d1c5"
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"custom": {
|
||||
"color": "#f9050d",
|
||||
"color": "#C2C2C2",
|
||||
"priority": "No Active Alarms"
|
||||
},
|
||||
"params": {
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-12T08:57:39Z"
|
||||
"timestamp": "2025-09-22T09:36:12Z"
|
||||
},
|
||||
"lastModificationSignature": "ceb13f6804a08c80f987c4ee866abe4c4961c8867da6993353eaa172e085ae22"
|
||||
"lastModificationSignature": "4a36dafff395ff4abbb3f6ea103d133ce10be38fa32664a5b8410ce0dd8ad540"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB |
@ -3,7 +3,7 @@
|
||||
"PLC": "MCM01",
|
||||
"color": "#C2C2C2",
|
||||
"showTags": true,
|
||||
"state": "Actuated"
|
||||
"state": "Closed"
|
||||
},
|
||||
"params": {
|
||||
"devices": [],
|
||||
@ -1225,7 +1225,10 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin",
|
||||
"whiteSpace": "normal",
|
||||
"wordBreak": "break-all"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1236,7 +1239,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 130
|
||||
"width": 180
|
||||
},
|
||||
{
|
||||
"align": "center",
|
||||
@ -1317,7 +1320,10 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin",
|
||||
"whiteSpace": "normal",
|
||||
"wordBreak": "break-all"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1328,7 +1334,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 350
|
||||
"width": 310
|
||||
},
|
||||
{
|
||||
"align": "center",
|
||||
@ -1409,7 +1415,8 @@
|
||||
"sortable": true,
|
||||
"strictWidth": false,
|
||||
"style": {
|
||||
"classes": ""
|
||||
"classes": "",
|
||||
"fontSize": "0.9vmin"
|
||||
},
|
||||
"toggleSwitch": {
|
||||
"color": {
|
||||
@ -1420,7 +1427,7 @@
|
||||
"viewParams": {},
|
||||
"viewPath": "",
|
||||
"visible": true,
|
||||
"width": 100
|
||||
"width": ""
|
||||
}
|
||||
],
|
||||
"pager": {
|
||||
@ -1454,6 +1461,7 @@
|
||||
"grow": 1
|
||||
},
|
||||
"props": {
|
||||
"currentTabIndex": 3,
|
||||
"menuType": "modern",
|
||||
"tabSize": {
|
||||
"width": 1000
|
||||
|
||||
@ -1,15 +1,32 @@
|
||||
def deviceType(view):
|
||||
path = view.props.get("path")
|
||||
docked_view = "Docked-East-"
|
||||
|
||||
if "Conveyor" in path:
|
||||
docked_view +="Conv"
|
||||
elif "VFD" in path:
|
||||
docked_view +="VFD"
|
||||
else :
|
||||
docked_view +="Device"
|
||||
|
||||
return docked_view
|
||||
def deviceType(self, path, props):
|
||||
try:
|
||||
docked_view = "Docked-East-"
|
||||
|
||||
devices = []
|
||||
tags = []
|
||||
|
||||
if "Conveyor" in path:
|
||||
docked_view += "Conv"
|
||||
devices = autStand.devices.build_device_table(self)
|
||||
system.perspective.print(devices)
|
||||
elif "VFD" in path:
|
||||
docked_view += "VFD"
|
||||
else:
|
||||
docked_view += "Device"
|
||||
|
||||
tags = autStand.devices.getAllTags(self, props[0])
|
||||
system.perspective.print(tags)
|
||||
|
||||
# return 1
|
||||
return [docked_view, tags, devices]
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
msg = "Error in deviceType: {}\n{}".format(str(e), traceback.format_exc())
|
||||
system.perspective.print(msg)
|
||||
# optionally: system.gui.errorBox(msg) # if running in Vision, not Perspective
|
||||
return None
|
||||
|
||||
|
||||
def handleTagHighlight(view, currentValue):
|
||||
tag_priority = currentValue.value
|
||||
@ -50,8 +67,14 @@ def handleTagHighlight(view, currentValue):
|
||||
|
||||
if tag == tagPath:
|
||||
child.props.style["classes"] = "Highlight/Pulse-" + priority
|
||||
docked_view = deviceType(child)
|
||||
system.perspective.openDock(docked_view, params={'tagProps': tagProps})
|
||||
path = child.props.get("path")
|
||||
# docked_view = deviceType(child)
|
||||
docked_view = deviceType(view, path, tagProps)
|
||||
# system.perspective.print(docked_view)
|
||||
system.perspective.openDock(docked_view[0], params = {'tagProps':tagProps, 'tags': docked_view[1], 'devices':docked_view[2]})
|
||||
# tags = autStand.devices.getAllTags(view, tagProps[0])
|
||||
# system.perspective.openDock(docked_view, params={'tagProps': tagProps, 'tags': tags})
|
||||
|
||||
foundMatch = True
|
||||
|
||||
return foundMatch
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-19T13:21:15Z"
|
||||
"timestamp": "2025-09-19T14:43:02Z"
|
||||
},
|
||||
"hintScope": 2,
|
||||
"lastModificationSignature": "717c54551cb487cf4325361e5e75e5db3a065f14656df7dc6ee5dca07eb0f544"
|
||||
"lastModificationSignature": "9d58c365d8aba15c6e322fa153e168c440f81681d7ecc1e0e3405f21b64be363"
|
||||
}
|
||||
}
|
||||
@ -167,12 +167,12 @@ def build_device_table(self):
|
||||
|
||||
def getAllTags(self, tagPath):
|
||||
"""
|
||||
Reads all tags under a UDT instance and returns a dataset.
|
||||
|
||||
Reads all tags under a UDT instance (recursively) 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
|
||||
|
||||
tagPath (str): Full path to the clicked device instance
|
||||
(e.g., System/MCM01/Photoeyes/TPE/PS3_1_TPE1)
|
||||
|
||||
Returns:
|
||||
system.dataset: Dataset with columns ["Name", "OPC Path", "Value"]
|
||||
"""
|
||||
@ -180,34 +180,45 @@ def getAllTags(self, tagPath):
|
||||
rows = []
|
||||
|
||||
try:
|
||||
# Determine the tag provider
|
||||
path = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]" + tagPath
|
||||
providerPath = "[" + self.session.custom.fc + "_SCADA_TAG_PROVIDER]"
|
||||
|
||||
# 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]
|
||||
def browseRecursive(basePath, prefix=""):
|
||||
children = system.tag.browse(providerPath + basePath, filter={}).getResults()
|
||||
for child in children:
|
||||
tagType = str(child.get("tagType", ""))
|
||||
name = str(child.get("name", ""))
|
||||
fullPath = str(child.get("fullPath", ""))
|
||||
|
||||
# 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"
|
||||
# Strip provider name
|
||||
if fullPath.startswith("[") and "]" in fullPath:
|
||||
fullPath = fullPath.split("]", 1)[1]
|
||||
|
||||
rows.append([name, fullPath, value])
|
||||
if tagType == "AtomicTag":
|
||||
value = None
|
||||
try:
|
||||
readPath = providerPath + fullPath
|
||||
result = system.tag.readBlocking([readPath])[0]
|
||||
|
||||
if result.quality.isGood():
|
||||
value = str(result.value)
|
||||
else:
|
||||
value = "Unknown"
|
||||
except:
|
||||
value = "Unknown"
|
||||
|
||||
# Use prefix/folder style path if inside folder
|
||||
displayName = prefix + name if prefix else name
|
||||
rows.append([displayName, fullPath, value])
|
||||
|
||||
elif tagType == "Folder":
|
||||
# Dive deeper into folder
|
||||
newPrefix = prefix + name + "/"
|
||||
browseRecursive(basePath + "/" + name, prefix=newPrefix)
|
||||
|
||||
# Start recursion
|
||||
browseRecursive(tagPath)
|
||||
|
||||
return system.dataset.toDataSet(headers, rows)
|
||||
|
||||
except Exception as e:
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
return system.dataset.toDataSet(headers, [])
|
||||
system.perspective.print("Error in getAllTags: {}".format(e))
|
||||
@ -9,9 +9,9 @@
|
||||
"attributes": {
|
||||
"lastModification": {
|
||||
"actor": "admin",
|
||||
"timestamp": "2025-09-11T14:21:44Z"
|
||||
"timestamp": "2025-09-22T10:07:38Z"
|
||||
},
|
||||
"hintScope": 2,
|
||||
"lastModificationSignature": "ac100dce34bb5394c6ec164e067a535fc23d24c32e0c752058d22c189107f89f"
|
||||
"lastModificationSignature": "71fab1ecf8f0a34c150bbd0e39819fb04f54cc9c1d343925f1b6d41c07383a4e"
|
||||
}
|
||||
}
|
||||
@ -36,3 +36,7 @@ Starting conversion: 20250919:12.08.01
|
||||
Conversion finished. Elapsed time: 10 ms
|
||||
Starting conversion: 20250919:14.45.44
|
||||
Conversion finished. Elapsed time: 9 ms
|
||||
Starting conversion: 20250920:12.20.22
|
||||
Conversion finished. Elapsed time: 10 ms
|
||||
Starting conversion: 20250922:11.54.29
|
||||
Conversion finished. Elapsed time: 11 ms
|
||||
|
||||