Search functionality. Minor adjustments in the equipment views

This commit is contained in:
Salijoghli 2025-08-26 18:45:29 +04:00
parent 0c24d9ebdd
commit 6b61d880a3
115 changed files with 2283 additions and 2112 deletions

View File

@ -1,20 +0,0 @@
def navigate_to_additional_view(self):
"""
This function is used to navigate to a page from a navigation button.
This function can be used on any button that has a property called "self.custom.page_id"
which is the target page for the button.
Args:
self: Refrence to the object that is invoking this function.
Returns:
This is a description of what is returned.
Raises:
KeyError: Raises an exception.
"""
page_id = self.custom.page_id
plc = page_id.split("-")[0]
url_to_navigate = "/DetailedView/%s/%s" % (page_id, plc)
system.perspective.navigate(page = url_to_navigate)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "",
"searchId": "value",
"state": 0,
"string": "Inactive"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": true,
"plc": "System",
"priority": 5,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Stopped"
},
@ -44,21 +42,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -119,15 +102,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

View File

@ -1,34 +0,0 @@
def show_alarm_from_docked_window(self,event):
#Get the alarm properties from the alarm object.
"""
Displays the currently active alarm from the south docked alarm table in the detailed view.
If the alarm is on a different page to the current page the function will navigate the user
to the correct page and show the alarm.
Args:
self: Refrence to the object thats invoking this function.
event: Refrence to the event that is invoking this function.
Returns:
The fucntion doses not return any values.
Raises:
KeyError: None
"""
alarm_id = event.value.get("AlarmId")
tags_to_read = system.tag.readBlocking(["System/ActiveAlarms"])
active_alarms = system.util.jsonDecode(tags_to_read[0].value)
UDT = active_alarms.get(alarm_id,{}).get("UDT_tag")
plc = UDT.split("_")[0]
name = active_alarms.get(alarm_id,{}).get("Name")
page_id = active_alarms.get(alarm_id,{}).get("PageId","None")
display_path = active_alarms.get(alarm_id,{}).get("DisplayPath")
#Set the session custom variables to highlight the selected alarm.
self.session.custom.searchId = UDT
self.session.custom.deviceSearchId = display_path
url_to_navigate = "/DetailedView/%s/%s" % (page_id, plc)
system.perspective.navigate(page = url_to_navigate)

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

View File

@ -1,10 +1,7 @@
{
"custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 1,
"string": "Running"
"state": 0,
"string": "Starting"
},
"params": {
"name": "amber",
@ -22,51 +19,6 @@
]
},
"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": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

View File

@ -257,7 +257,7 @@
"$": [
"ds",
192,
1755878824844
1756210018042
],
"$columns": [
{
@ -301,19 +301,6 @@
},
"virtualized": false
},
"scripts": {
"customMethods": [],
"extensionFunctions": null,
"messageHandlers": [
{
"messageType": "search-devices",
"pageScope": true,
"script": "\tself.props.data \u003d payload.get(\"dataset\")",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.table"
}
],

View File

@ -1,16 +1,5 @@
{
"custom": {},
"events": {
"system": {
"onStartup": {
"config": {
"script": "\tbuttonid \u003d self.custom.activityLogger.buttonid\n\tself.custom.activityLogger.start_time \u003d system.date.now()\n\tactivityLog.productMetrics.callLogger(self, \u0027click\u0027, buttonid)\n\t"
},
"scope": "G",
"type": "script"
}
}
},
"params": {},
"props": {
"defaultSize": {
@ -72,7 +61,7 @@
"component": {
"onRowDoubleClick": {
"config": {
"script": "\trow \u003d event.value\n\tsource_id \u003d row.get(\"SourceId\") \n\tconfig.project_config.source_id_lookup(self, source_id)\n\tsystem.perspective.closePopup(id \u003d \"Search\")"
"script": "\trow \u003d event.value\n\tsource_id \u003d row.get(\"SourceId\") \n\tautStand.config.project_config.source_id_lookup(self, source_id)\n\tsystem.perspective.closePopup(id \u003d \"Search\")"
},
"scope": "G",
"type": "script"
@ -257,16 +246,22 @@
"$": [
"ds",
192,
1755879137747
1756214343007
],
"$columns": [
{
"data": [],
"data": [
"System/MCM01/Station/SSPB/UL6_1_SS1",
"/system/mcm01/test"
],
"name": "SourceId",
"type": "String"
},
{
"data": [],
"data": [
"MCM01-FLUID INBOUND",
"MCM02-NC SORTER"
],
"name": "Page",
"type": "String"
}
@ -301,19 +296,6 @@
},
"virtualized": false
},
"scripts": {
"customMethods": [],
"extensionFunctions": null,
"messageHandlers": [
{
"messageType": "search-devices",
"pageScope": true,
"script": "\tself.props.data \u003d payload.get(\"dataset\")",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.table"
}
],
@ -321,7 +303,7 @@
"system": {
"onStartup": {
"config": {
"script": "\tids \u003d autStand.config.project_config.global_project_page_ids\n\tsystem.perspective.print(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\t\n\tsystem.perspective.print(\"happy end\")"
"script": "\t\n\tids \u003d autStand.config.project_config.get_project_config()\n\t\n\t# Ensure its actually a dictionary\n\tif not isinstance(ids, dict):\n\t system.perspective.print(\"Error: global_project_page_ids is not a dictionary\")\n\telse:\n\t data \u003d []\n\t for k, v in ids.items():\n\t data.append([str(k), str(v)])\n\t\n\t header \u003d [\"SourceId\", \"Page\"]\n\t dataset \u003d system.dataset.toDataSet(header, data)\n\t self.getChild(\"Table\").props.data \u003d dataset"
},
"scope": "G",
"type": "script"

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Normal"
},
@ -32,21 +30,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -91,15 +74,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,50 +0,0 @@
def detailed_view(self, tag_name, device_id, area):
"""
This function is used to naviagte to a detailed view
For example an on click event of a component.
The input paramter array to the component contains a reference to the PLC.
Detail view display all devices and equipement connected to a particular PLC.
The PLC ID is looked up in the "Configuration/DetailedViews" dictionary.
if found it navigates to the detailed view of the page_name {/<PLCid>}.
Args:
self: This is a reference to the object that is clicked on the screen.
tag_name: Hold information on the particular event that call this function.
area : The area within the FC
Returns:
None.
Raises:
None.
"""
device = tag_name.split("_")
device = device[0]
# Example: page_name = /F01
pages = system.tag.readBlocking(["Configuration/DetailedViews"])
pages_value = pages[0].value
pages_decoded = system.util.jsonDecode(pages_value)
for view , devices in pages_decoded.items():
if device in devices:
self.session.custom.searchId = tag_name
self.session.custom.deviceSearchId = device_id
system.perspective.sendMessage("plc-to-display", payload = {"device":view,"show_controls":True,"area":area}, scope = "page")
url_to_navigate = "/DetailedView/%s/%s" % (view, view)
system.perspective.navigate(page = url_to_navigate)
return
def navigate_to_deatiled_view(source):
page_id = config.project_config.get_project_config.global_project_page_ids.get(source)
if page_id:
url_to_navigate = "/DetailedView/%s/%s" % (page_id, page_id)
navigation.amzl_navigation.set_session_variables(self, page_id, False)
system.perspective.navigate(page = url_to_navigate)
elif not page_id:
data = source.split("/")
pass

View File

@ -1,44 +0,0 @@
def generate_tag_config(self,event):
"""This function generates the tag config in the search window.
Args:
self: A reference to the object that is invoking this function.
event: A reference to the event object that is being called by this function..
Returns:
This is a description of what is returned.
Raises:
None.
"""
tag = event.value.get("Tags")
fc = system.tag.read("Configuration/FC").value
path ="[%s_SCADA_TAG_PROVIDER]%s/OPC/" % (fc, tag)
results = system.tag.browse( path = path)
tag_list = results.getResults()
data = [i["fullPath"] for i in tag_list]
table_data = []
for i in data:
config = system.tag.getConfiguration(i)
alarms = [x.get("alarms") for x in config]
try:
for alarm in alarms:
for x in alarm:
# replace = "[%s_SCADA_TAG_PROVIDER]" % (fc)
system.perspective.print(x)
full_path = str(i)
name = x.get("name")
additional_info = x.get("AdditionalInfo")
priority = x.get("priority")
bit_position = x.get("bitPosition")
row = row_builder.build_row(FullPath = full_path, AdditionalInfo = additional_info,
Priority = priority, Name = name, StyleClass = {"classes":"Alarms-Styles/NoAlarms"})
table_data.append(row)
except:
system.perspective.print("object not iterable")
# self.getSibling("Table_0").props.data = table_data
payload = {}
payload["table_data"] = table_data
system.perspective.sendMessage("build-tag-config", payload = payload, scope = "view")

View File

@ -1,8 +1,5 @@
{
"custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -21,51 +18,6 @@
]
},
"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": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,91 @@
import os, json, sys
global_project_page_ids = {}
def get_project_config():
"""
Scan each view.json under Detailed_Views (no recursion),
read top-level children, extract tagProps[0],
and store as {source_id: view_folder_name}.
"""
global global_project_page_ids
global_project_page_ids.clear()
try:
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 {}
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
with open(json_file, "r") as fh:
view_json = json.load(fh)
# only top-level children
children = (view_json.get("root") or {}).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:
source_id = str(tag_props[0])
global_project_page_ids[source_id] = view_folder
except:
whid = system.tag.readBlocking("Configuration/FC")[0].value
logger = system.util.getLogger("%s-get_project_config" % whid)
exc_type, exc_obj, tb = sys.exc_info()
logger.error("Error at line %s: %s" % (tb.tb_lineno, exc_obj))
return global_project_page_ids
def navigate_to_url(self, source_id, page_id):
url_to_navigate = "autStand/Detailed_Views/%s" % (page_id)
system.perspective.navigate(view=url_to_navigate, params={"highlightTagPath": source_id + "||Diagnostic"})
def source_id_lookup(self, source_id):
"""
Finds page_id from global_project_page_ids by source_id or by hierarchy,
then navigates.
"""
if not source_id:
return
page_id = global_project_page_ids.get(source_id)
found = False
if page_id:
found = True
navigate_to_url(self, source_id, page_id)
else:
# Walk hierarchy upwards until we find a match
items = source_id.split("/")
while len(items) > 1:
items.pop()
source_id = "/".join(items)
page_id = global_project_page_ids.get(source_id)
if page_id:
found = True
navigate_to_url(self, source_id, page_id)
break
if not found:
open_pop_up("No page id found")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Idle"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
@ -127,8 +117,8 @@
},
"props": {
"defaultSize": {
"height": 40,
"width": 80
"height": 42,
"width": 81
}
},
"root": {

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -1,15 +0,0 @@
def detailed_view(page_id):
"""
This function is used to naviagte to a page from a navigation button
This function takes one parameter "page_id. This is the id of the page
the user wishes to navigate to.
Args:
page_id : Target page the function will use to navigate to.
Returns:
None.
Raises:
None.
"""
system.perspective.navigate(page_id)

View File

@ -1,99 +0,0 @@
import re
import os
import json
import sys
#Stores the page configuration for the project.
#This global variable is accesible form all gateway scoped events using "." notation
#congig.project_config.global_project_page_ids
global_project_page_ids = {}
def get_project_config():
"""
Function searches through the project directory Detailed-Views.
It looks for all the source ids on each Detailed-View and returns a
Dict with source ids as the keys and page ids as the values.
Args:
param1: self. refrence to the object being called.
param2: source_id. The source_id of the alarm.
Returns:
N/A.
Raises:
KeyError: Will log an error message to the console if the basepath is not found.
logger = {whid}_get_project_config
"""
system.perspective.print(system.util.getProjectName)
if not global_project_page_ids:
try:
basePath = os.getcwd().replace('\\','/') + '/data/projects/' + system.util.getProjectName() + '/com.inductiveautomation.perspective/views/autStand/Detailed_Views'
files = os.listdir(basePath)
files_found = True
except:
whid = system.tag.readBlocking("Configuration/FC")[0].value
logger = system.util.getLogger("%s-get_project_config" % (whid))
exc_type, exc_obj, tb = sys.exc_info()
lineno = tb.tb_lineno
# logger.error("Error: %s, %s, %s" % (lineno, exc_type, exc_obj)) #JCM
files_found = False
if files_found:
for i in files:
jsonPath = basePath+'/'+str(i)+'/view.json'
with open(jsonPath, 'r') as f:
data= f.read()
obj = json.loads(data)
for child in obj['root']['children']:
tag_props = child.get("props",{}).get("params", {}).get("tagProps")
if tag_props:
source_id = tag_props[0]
global global_project_page_ids
global_project_page_ids[source_id] = i
def navigate_to_url(self, source_id, page_id):
url_to_navigate = "/DetailedView/%s/%s" % (page_id, page_id)
navigation.amzl_navigation.set_session_variables(self, source_id, False)
system.perspective.navigate(page = url_to_navigate)
def source_id_lookup(self, source_id):
"""
This function looks for the source_id in
the global_project_page_ids variable.
If found it returns the corrresponding page id.
If no page id is found it will search up the hierachy
of the source_id until it finds a match. It will then
navigate the user to the correct page and set the session
custom variable search_id.
Args:
param1: self. refrence to the object being called.
param2: source_id. The source_id of the alarm.
Returns:
N/A.
Raises:
KeyError: N/A.
"""
logger = system.util.getLogger("Naviagtion function")
# logger.info(str(global_project_page_ids))
page_id = global_project_page_ids.get(source_id)
found = False
if page_id:
found = True
navigate_to_url(self, source_id, page_id)
else:
items = source_id.split("/")
length_of_items = len(items)-1
while length_of_items > 0:
items.pop()
source_id = "/".join(items)
page_id = global_project_page_ids.get(source_id)
if page_id:
found = True
navigate_to_url(self, source_id, page_id)
break
length_of_items -= 1
if not found:
open_pop_up("No page id found")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "",
"searchId": "value",
"state": 0,
"string": "Inactive"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Normal"
},
@ -32,21 +30,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -91,15 +74,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -20,30 +18,6 @@
]
},
"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": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

View File

@ -1,65 +0,0 @@
def set_session_variables(self, search_id, covert):
"""
chnaged from:(self, search_id, device_search_id, plc_tag_path, display_cc, detailed_view)
This function is used to set the custom session variables in the perspective session.
Args:
self: This is a reference to the object that is calling this function.
search_id: Type string, this should be a UDT name.
device_search_id: Type string, display path of the alarm.
Returns:
None.
Raises:
None.
"""
self.session.custom.searchId = search_id
self.session.custom.covert = covert
def navigate_to_alarm(self, mhe_id):
"""
This function is used to navigate to the location of an alarm within SCADA
Args:
self: This is a reference to the object that is clicked on the screen.
event: This is a reference to the event that is clicked on the screen.
Returns:
None.
Raises:
Logs and error to the gateway if the Config/cfg tag is not found
or the LinkToPage field is empty.
"""
config = "%s/Config/cfg" % (mhe_id)
tags_to_read = system.tag.readBlocking(["Configuration/FC", "Configuration/DetailedViews"])
tag_provider = "[%s_SCADA_TAG_PROVIDER]" % (tags_to_read[0].value)
tags_config = system.tag.readBlocking([tag_provider + config])
tag_config_value = system.util.jsonDecode(tags_config[0].value)
if tag_config_value:
link_to_page = tag_config_value.get("LinkToPage")
if link_to_page == None or len(link_to_page) == 0:
error_message = "No page id found in Cfg tag"
system.perspective.openPopup("ErrorPopUP", "PopUp-Views/Error",
params ={"Error_message":error_message},
showCloseIcon = False, modal = True,
viewportBound = True,
draggable = False,
overlayDismiss = True
)
else:
url_to_navigate = "/DetailedView/%s/%s" % (link_to_page, link_to_page)
#Update the session variables to flash the pointers.
set_session_variables(self, mhe_id, False)
system.perspective.navigate(page = url_to_navigate)
else:
error_message = "No cfg tag found"
system.perspective.openPopup("ErrorPopUP", "PopUp-Views/Error",
params ={"Error_message":error_message},
showCloseIcon = False, modal = True,
viewportBound = True,
draggable = False,
overlayDismiss = True
)

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -1,22 +1,18 @@
{
"custom": {
"covert_mode": true,
"covert_mode": null,
"disconnected": false,
"display_icon": true,
"display_icon": null,
"error": false,
"isMatch": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"running_status": 0,
"searchId": "value",
"searchId": null,
"state": 5,
"state_string": "Unknown"
},
"params": {
"directionLeft": true,
"forceFaultStatus": null,
"forceRunningStatus": null,
"tagProps": [
"value",
"value",
@ -100,21 +96,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -247,18 +228,6 @@
},
"persistent": true
},
"params.directionLeft": {
"paramDirection": "input",
"persistent": true
},
"params.forceFaultStatus": {
"paramDirection": "input",
"persistent": true
},
"params.forceRunningStatus": {
"paramDirection": "input",
"persistent": true
},
"params.tagProps": {
"paramDirection": "inout",
"persistent": true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

View File

@ -1,7 +1,6 @@
{
"custom": {
"state": 1,
"state_string": "Device Disconnected",
"string": "Device Disconnected"
},
"params": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

View File

@ -109,7 +109,6 @@
"start": "2020-07-29 00:00:00"
}
},
"searchId": "value",
"show_dpm_device_view": true,
"show_dpm_view": true,
"timewidget": {

View File

@ -1,79 +0,0 @@
def set_session_variables(self, search_id, device_search_id):
"""
chnaged from:(self, search_id, device_search_id, plc_tag_path, display_cc, detailed_view)
This function is used to set the custom session variables in the perspective session.
Args:
self: This is a reference to the object that is calling this function.
search_id: Type string, this should be a UDT name.
device_search_id: Type string, display path of the alarm.
Returns:
None.
Raises:
None.
"""
self.session.custom.searchId = search_id
self.session.custom.deviceSearchId = device_search_id
def navigate_to_alarm(self, event):
"""
This function is used to navigate to a detailed view when double
clicking a row in the active alarm table. It takes the Ignition alarm id
to return the alarm information from the "System/ActiveAlarms" tag.
Args:
self: This is a reference to the object that is clicked on the screen.
event: This is a reference to the event that is clicked on the screen.
Returns:
None.
Raises:
None.
"""
alarm_id = event.value.get("AlarmId")
tags_to_read = system.tag.readBlocking(["Configuration/DetailedViews","System/ActiveAlarms"])
pages_decoded = system.util.jsonDecode(tags_to_read[0].value)
active_alarms = system.util.jsonDecode(tags_to_read[1].value)
UDT = active_alarms.get(alarm_id,{}).get("UDT_tag")
bit_position = active_alarms.get(alarm_id,{}).get("bitPosition")
name = active_alarms.get(alarm_id,{}).get("Name")
page_id = active_alarms.get(alarm_id,{}).get("PageId","None")
page = UDT.split("_")[0]
if page_id != "None" and len(page_id)>0:
page_id = page_id.split("-")[0]
udt_to_read = "%s/Parameters.AREA" % (page_id)
else:
udt_to_read = "%s/Parameters.AREA" % (page)
system.perspective.print(udt_to_read)
read_area = system.tag.readBlocking([udt_to_read])
area = read_area[0].value
page_name = "/"+page
display_path = active_alarms.get(alarm_id,{}).get("DisplayPath")
check_keys = pages_decoded.get(page,0)
if page_id != "None" and page_id != "":
page = page_id.split("-")[0]
url_to_navigate = "/DetailedView/%s/%s" % (page_id, page)
set_session_variables(self, UDT, display_path)
system.perspective.navigate(page = url_to_navigate)
system.perspective.sendMessage("plc-to-display", payload = {"device":page_id, "show_controls":True, "area":area}, scope = "page")
elif check_keys != 0:
set_session_variables(self, UDT, display_path)
url_to_navigate = "/DetailedView/%s/%s" % (page, page)
system.perspective.navigate(page = url_to_navigate )
system.perspective.sendMessage("plc-to-display", payload = {"device":page, "show_controls":True, "area":area}, scope = "page")
else:
for i in pages_decoded:
page_list = pages_decoded[i]
if page in page_list:
set_session_variables(self, UDT, display_path)
url_to_navigate = "/DetailedView/%s/%s" % (i,i)
system.perspective.navigate(page = url_to_navigate)
system.perspective.sendMessage("plc-to-display", payload = {"device":i, "show_controls":True, "area":area}, scope = "page")

View File

@ -109,7 +109,6 @@
"start": "2020-07-29 00:00:00"
}
},
"searchId": "value",
"show_dpm_device_view": true,
"show_dpm_view": true,
"timewidget": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-22T14:04:34Z"
"timestamp": "2025-08-26T14:29:54Z"
},
"lastModificationSignature": "5ada1fec1f3bc1a7586a858a96fcd600752780a5fcb95c0bb4a350d2efeebf3a"
"lastModificationSignature": "072e26ef45c87452c86252cb59819c115600d912431e760fb33771ad38f0b65b"
}
}

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-25T14:15:19Z"
"timestamp": "2025-08-26T14:43:54Z"
},
"lastModificationSignature": "59e18195ab7e8917dfb7eb76cdb5c49e32936fd03347af5878816fb03c86c723"
"lastModificationSignature": "dad5067c7ab40f285c1e00bc14ccea8cb263cd7faf3c9bcf732d6ed34e49818b"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-25T14:32:44Z"
"timestamp": "2025-08-26T14:44:14Z"
},
"lastModificationSignature": "b9296f4bae27e040adc54c9302ab0f9a43081d649318d8e4f9421a9ba877fe5b"
"lastModificationSignature": "a477cf434c3c5677944c76852b27a00a4d61dcb09836bad1ad05adfab7cad549"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:30:10Z"
},
"lastModificationSignature": "73e039a970ca282909374a668a9c7c05f468488d3aa4353484bf11e5e1c0d224"
"lastModificationSignature": "31547fae731c654947b76d30598feda67b91f353f3cc97b55a8ac136d2727fe5"
}
}

View File

@ -1,10 +1,7 @@
{
"custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 1,
"string": "Running"
"state": 0,
"string": "Starting"
},
"params": {
"name": "amber",
@ -22,51 +19,6 @@
]
},
"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": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:30:55Z"
},
"lastModificationSignature": "c32cce2d3881aadd3d827b343cdcf3864a03069776b3604f60e810fb066f6655"
"lastModificationSignature": "ef60f49fab89fdb7fc2034f2ad6f90fad959767decc9be10d48e0404ceec2380"
}
}

View File

@ -1,22 +1,18 @@
{
"custom": {
"covert_mode": true,
"covert_mode": null,
"disconnected": false,
"display_icon": true,
"display_icon": null,
"error": false,
"isMatch": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"running_status": 0,
"searchId": "value",
"searchId": null,
"state": 5,
"state_string": "Unknown"
},
"params": {
"directionLeft": true,
"forceFaultStatus": null,
"forceRunningStatus": null,
"tagProps": [
"value",
"value",
@ -100,21 +96,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -247,18 +228,6 @@
},
"persistent": true
},
"params.directionLeft": {
"paramDirection": "input",
"persistent": true
},
"params.forceFaultStatus": {
"paramDirection": "input",
"persistent": true
},
"params.forceRunningStatus": {
"paramDirection": "input",
"persistent": true
},
"params.tagProps": {
"paramDirection": "inout",
"persistent": true

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:31:06Z"
},
"lastModificationSignature": "c47394ad7a0a642bdbdeeacd9e0265a604007908b6d903cc74efd79059dab8d9"
"lastModificationSignature": "9b3ebf3b94b300d6cf40fc71b8ae2fbb3e54be53a6f15751a7c3caf80c631c79"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 B

After

Width:  |  Height:  |  Size: 763 B

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Normal"
},
@ -32,21 +30,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -91,15 +74,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-25T14:18:25Z"
"timestamp": "2025-08-26T14:31:23Z"
},
"lastModificationSignature": "ca414c842b5ca1fef842aa1abb4125d0871e339ccf55f9615485de4006321af7"
"lastModificationSignature": "8c6479789d28d57bb747e57d21e8311157468fe9d7743be8df98f68744b43fa5"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

After

Width:  |  Height:  |  Size: 129 B

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Idle"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:31:28Z"
},
"lastModificationSignature": "55a935ec086b550825eec574ddbf40d233306f84dc5fd17634920f1929ab26f8"
"lastModificationSignature": "76f6b2cccd2a66012c965c80b56e59cf5f6c4c57904cb25e05f354fb406bf04d"
}
}

View File

@ -1,6 +1,5 @@
{
"custom": {
"state_string": "OK",
"string": "OK"
},
"params": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:31:41Z"
},
"lastModificationSignature": "cea01933a8567b24984cbd4bcfba9a95618d7e1aaf9276bbdc0508017142feba"
"lastModificationSignature": "4ffb52abe784449ce8c8d4d09acdef6b5ce14a7674f39e6776ccf5110d7ac89a"
}
}

View File

@ -1,8 +1,5 @@
{
"custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -21,51 +18,6 @@
]
},
"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": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-25T14:33:10Z"
"timestamp": "2025-08-26T14:31:49Z"
},
"lastModificationSignature": "8fe96c9df54126733f1774426951c0e93a8057ca8bf63285fec7f18b24037f6c"
"lastModificationSignature": "ff97fe9104740122fd584a0096f8eb07ff134647e6fdbf2e163955ad7447ad47"
}
}

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:32:19Z"
},
"lastModificationSignature": "592827931c77f1fa4ddd65c13b01746ea23a3091f050e0bb7560705d5b1d5433"
"lastModificationSignature": "466d8d395f7d5d2777041906e032b17a7b9feebe49874ad1d32efb9f0186a659"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

After

Width:  |  Height:  |  Size: 85 B

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": 0,
"plc": "value",
"priority": 0,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Normal"
},
@ -32,21 +30,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -91,15 +74,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-21T14:57:04Z"
"timestamp": "2025-08-26T14:29:42Z"
},
"lastModificationSignature": "1fa863ad7885c61ea8f865b14ff0fb59bfc837017e3e2856160741348f25e3e9"
"lastModificationSignature": "f7ba61a965cc42c0008e6db010fe516f136fa511669c21dcb971761b97c28292"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 90 B

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {
@ -127,8 +117,8 @@
},
"props": {
"defaultSize": {
"height": 40,
"width": 80
"height": 42,
"width": 81
}
},
"root": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:32:38Z"
},
"lastModificationSignature": "255771d60a708ebac97238c374a4a5370c1c432cd5c8a7ad2e8ee39cc98a8f33"
"lastModificationSignature": "d2ec57b53be92db9cedba4198acaf9ee1f1c68f33cd05d23b7c3acd204f39fd2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 487 B

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:32:32Z"
},
"lastModificationSignature": "83169ef949edcbb83f56f5b5492a016a75bd4a8b1649ec1ba45e1b25a7f3c12f"
"lastModificationSignature": "582e783fd51c7bbeb9f8e5beda5f64acc4a40bc1332da6b6e03ec281abe42ef8"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 B

After

Width:  |  Height:  |  Size: 567 B

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "value",
"searchId": "value",
"state": 0,
"string": "Clear"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:32:43Z"
},
"lastModificationSignature": "2eed25220899cbae02fac1f7299325425478c20ef6380702172f90e5f384a3a3"
"lastModificationSignature": "a2e975e0664ac172de06d3e854080ee2347fba63f69fec977ca6507269d7d877"
}
}

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "",
"searchId": "value",
"state": 0,
"string": "Inactive"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:32:54Z"
},
"lastModificationSignature": "3a9508f5f8270d6f3fd39e8dada0a813516c21dbbee0b39dc46cf54663550c44"
"lastModificationSignature": "2298460af083ccdfba7e2a4da9e30a64dbdd68a50d1145d4e4f6b0695414e533"
}
}

View File

@ -1,10 +1,8 @@
{
"custom": {
"disconnected": true,
"plc": "System",
"priority": 5,
"priority_string": "No active alarms",
"searchId": "value",
"state": 0,
"state_string": "Stopped"
},
@ -44,21 +42,6 @@
},
"persistent": true
},
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": {
"binding": {
"config": {
@ -119,15 +102,6 @@
},
"persistent": true
},
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-25T14:05:04Z"
"timestamp": "2025-08-26T14:33:00Z"
},
"lastModificationSignature": "29a7b13e2400e93994c7886168a48cd03cbfe77f10b7254bb6e0b106c04a5eb9"
"lastModificationSignature": "c1104b8090860c55905dd030851c58702815feefa47a087ae04e79573d468503"
}
}

View File

@ -1,6 +1,5 @@
{
"custom": {
"searchId": "value",
"state": 0,
"string": "Unknown"
},
@ -19,15 +18,6 @@
]
},
"propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": {
"binding": {
"config": {

View File

@ -9,8 +9,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T09:26:57Z"
"timestamp": "2025-08-26T14:33:05Z"
},
"lastModificationSignature": "1ed0430f8930c3845ac8b585b1dd9ea7e04fdccfcd4b1287098cb8bb328fef80"
"lastModificationSignature": "5d991e3d4830438f4ec9a98629ad386e2be366855185ffcd3adda34533816bd4"
}
}

View File

@ -1,7 +1,5 @@
{
"custom": {
"plc": "",
"searchId": "value",
"state": 0,
"string": "Inactive"
},
@ -20,30 +18,6 @@
]
},
"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": {

View File

@ -9,9 +9,9 @@
],
"attributes": {
"lastModification": {
"actor": "external",
"timestamp": "2025-08-21T14:57:23Z"
"actor": "admin",
"timestamp": "2025-08-26T14:33:17Z"
},
"lastModificationSignature": "e78841e31f76dd61cab3a9ad2fcee4fffae81bb878d4831fa29201a5f7c51c75"
"lastModificationSignature": "20b2df5ace00d8a3ec767859dc06219a128542aa391120b6052c26b185d2a950"
}
}

View File

@ -1,7 +1,6 @@
{
"custom": {
"state": 1,
"state_string": "Device Disconnected",
"string": "Device Disconnected"
},
"params": {

View File

@ -10,8 +10,8 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-22T16:12:21Z"
"timestamp": "2025-08-26T13:29:31Z"
},
"lastModificationSignature": "cde0cd90de87671fcad4b50d5d799df59f5c2f892da2cf86344760131558c949"
"lastModificationSignature": "f99fb1cff0b72c89db2d8521106e3667fc8b2a647ce6ed2e13083e7e4535c183"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,16 +1,5 @@
{
"custom": {},
"events": {
"system": {
"onStartup": {
"config": {
"script": "\tbuttonid \u003d self.custom.activityLogger.buttonid\n\tself.custom.activityLogger.start_time \u003d system.date.now()\n\tactivityLog.productMetrics.callLogger(self, \u0027click\u0027, buttonid)\n\t"
},
"scope": "G",
"type": "script"
}
}
},
"params": {},
"props": {
"defaultSize": {
@ -72,7 +61,7 @@
"component": {
"onRowDoubleClick": {
"config": {
"script": "\trow \u003d event.value\n\tsource_id \u003d row.get(\"SourceId\") \n\tconfig.project_config.source_id_lookup(self, source_id)\n\tsystem.perspective.closePopup(id \u003d \"Search\")"
"script": "\trow \u003d event.value\n\tsource_id \u003d row.get(\"SourceId\") \n\tautStand.config.project_config.source_id_lookup(self, source_id)\n\tsystem.perspective.closePopup(id \u003d \"Search\")"
},
"scope": "G",
"type": "script"
@ -257,16 +246,22 @@
"$": [
"ds",
192,
1755879137747
1756214343007
],
"$columns": [
{
"data": [],
"data": [
"System/MCM01/Station/SSPB/UL6_1_SS1",
"/system/mcm01/test"
],
"name": "SourceId",
"type": "String"
},
{
"data": [],
"data": [
"MCM01-FLUID INBOUND",
"MCM02-NC SORTER"
],
"name": "Page",
"type": "String"
}
@ -301,19 +296,6 @@
},
"virtualized": false
},
"scripts": {
"customMethods": [],
"extensionFunctions": null,
"messageHandlers": [
{
"messageType": "search-devices",
"pageScope": true,
"script": "\tself.props.data \u003d payload.get(\"dataset\")",
"sessionScope": false,
"viewScope": false
}
]
},
"type": "ia.display.table"
}
],
@ -321,7 +303,7 @@
"system": {
"onStartup": {
"config": {
"script": "\tids \u003d autStand.config.project_config.global_project_page_ids\n\tsystem.perspective.print(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\t\n\tsystem.perspective.print(\"happy end\")"
"script": "\t\n\tids \u003d autStand.config.project_config.get_project_config()\n\t\n\t# Ensure its actually a dictionary\n\tif not isinstance(ids, dict):\n\t system.perspective.print(\"Error: global_project_page_ids is not a dictionary\")\n\telse:\n\t data \u003d []\n\t for k, v in ids.items():\n\t data.append([str(k), str(v)])\n\t\n\t header \u003d [\"SourceId\", \"Page\"]\n\t dataset \u003d system.dataset.toDataSet(header, data)\n\t self.getChild(\"Table\").props.data \u003d dataset"
},
"scope": "G",
"type": "script"

View File

@ -0,0 +1,51 @@
def handleTagHighlight(view, currentValue):
tag_priority = currentValue.value
if tag_priority == None:
return
parts = str(tag_priority).split("||")
tag = parts[0]
splitedTag = tag.split("/")
deviceName = splitedTag[-1]
Docked_East_Map = {
"VFD" : "Docked-East-VFD",
"MCM" : "Docked-East-MCM"
}
Docked_East_View = Docked_East_Map["VFD"]
if "PE" in deviceName:
tag = "/".join(splitedTag[:2]) + "/Conveyor/" + deviceName[:-3] + "VFD1"
if "MCM" in deviceName:
Docked_East_View = Docked_East_Map["MCM"]
components = view.rootContainer.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]
if tag == tagPath:
child.props.style["classes"] = "Highlight/Pulse-" + priority
system.perspective.openDock(Docked_East_View, params={'tagProps': tagProps})
foundMatch = True
return foundMatch

View File

@ -9,9 +9,9 @@
"attributes": {
"lastModification": {
"actor": "admin",
"timestamp": "2025-08-19T12:31:53Z"
"timestamp": "2025-08-26T14:26:47Z"
},
"lastModificationSignature": "9db18fbcf40c5119c8bedfb1d3d4f170352447911e3d4625d892bc8d9ef66cf6",
"hintScope": 2
"hintScope": 2,
"lastModificationSignature": "8ba5c5b0a0c691303495a603e2195ea954ff63a8d19fe1a18236cae5da6dbdf6"
}
}

View File

@ -1,92 +1,79 @@
import re
import os
import json
import sys
#Stores the page configuration for the project.
#This global variable is accesible form all gateway scoped events using "." notation
#congig.project_config.global_project_page_ids
import os, json, sys
global_project_page_ids = {}
def get_project_config():
"""
Function searches through the project directory Detailed-Views.
It looks for all the source ids on each Detailed-View and returns a
Dict with source ids as the keys and page ids as the values.
Args:
param1: self. refrence to the object being called.
param2: source_id. The source_id of the alarm.
Returns:
N/A.
Raises:
KeyError: Will log an error message to the console if the basepath is not found.
logger = {whid}_get_project_config
Scan each view.json under Detailed_Views (no recursion),
read top-level children, extract tagProps[0],
and store as {source_id: view_folder_name}.
"""
system.perspective.print(system.util.getProjectName)
if not global_project_page_ids:
try:
basePath = os.getcwd().replace('\\','/') + '/data/projects/' + system.util.getProjectName() + '/com.inductiveautomation.perspective/views/autStand/Detailed_Views'
files = os.listdir(basePath)
files_found = True
except:
whid = system.tag.readBlocking("Configuration/FC")[0].value
logger = system.util.getLogger("%s-get_project_config" % (whid))
exc_type, exc_obj, tb = sys.exc_info()
lineno = tb.tb_lineno
# logger.error("Error: %s, %s, %s" % (lineno, exc_type, exc_obj)) #JCM
files_found = False
if files_found:
for i in files:
jsonPath = basePath+'/'+str(i)+'/view.json'
with open(jsonPath, 'r') as f:
data= f.read()
obj = json.loads(data)
for child in obj['root']['children']:
tag_props = child.get("props",{}).get("params", {}).get("tagProps")
if tag_props:
source_id = tag_props[0]
global global_project_page_ids
global_project_page_ids[source_id] = i
global global_project_page_ids
global_project_page_ids.clear()
try:
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 {}
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
with open(json_file, "r") as fh:
view_json = json.load(fh)
# only top-level children
children = (view_json.get("root") or {}).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:
source_id = str(tag_props[0])
global_project_page_ids[source_id] = view_folder
except:
whid = system.tag.readBlocking("Configuration/FC")[0].value
logger = system.util.getLogger("%s-get_project_config" % whid)
exc_type, exc_obj, tb = sys.exc_info()
logger.error("Error at line %s: %s" % (tb.tb_lineno, exc_obj))
return global_project_page_ids
def navigate_to_url(self, source_id, page_id):
url_to_navigate = "/DetailedView/%s/%s" % (page_id, page_id)
navigation.amzl_navigation.set_session_variables(self, source_id, False)
system.perspective.navigate(page = url_to_navigate)
url_to_navigate = "autStand/Detailed_Views/%s" % (page_id)
system.perspective.navigate(view=url_to_navigate, params={"highlightTagPath": source_id + "||Diagnostic"})
def source_id_lookup(self, source_id):
"""
This function looks for the source_id in
the global_project_page_ids variable.
If found it returns the corrresponding page id.
If no page id is found it will search up the hierachy
of the source_id until it finds a match. It will then
navigate the user to the correct page and set the session
custom variable search_id.
Args:
param1: self. refrence to the object being called.
param2: source_id. The source_id of the alarm.
Returns:
N/A.
Raises:
KeyError: N/A.
Finds page_id from global_project_page_ids by source_id or by hierarchy,
then navigates.
"""
logger = system.util.getLogger("Naviagtion function")
# logger.info(str(global_project_page_ids))
if not source_id:
return
page_id = global_project_page_ids.get(source_id)
found = False
if page_id:
found = True
navigate_to_url(self, source_id, page_id)
else:
# Walk hierarchy upwards until we find a match
items = source_id.split("/")
length_of_items = len(items)-1
while length_of_items > 0:
while len(items) > 1:
items.pop()
source_id = "/".join(items)
page_id = global_project_page_ids.get(source_id)
@ -94,6 +81,11 @@ def source_id_lookup(self, source_id):
found = True
navigate_to_url(self, source_id, page_id)
break
length_of_items -= 1
if not found:
open_pop_up("No page id found")
if not found:
open_pop_up("No page id found")

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