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

View File

@ -1,10 +1,8 @@
{ {
"custom": { "custom": {
"disconnected": true, "disconnected": true,
"plc": "System",
"priority": 5, "priority": 5,
"priority_string": "No active alarms", "priority_string": "No active alarms",
"searchId": "value",
"state": 0, "state": 0,
"state_string": "Stopped" "state_string": "Stopped"
}, },
@ -44,21 +42,6 @@
}, },
"persistent": true "persistent": true
}, },
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": { "custom.priority": {
"binding": { "binding": {
"config": { "config": {
@ -119,15 +102,6 @@
}, },
"persistent": true "persistent": true
}, },
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "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": { "custom": {
"disconnected": true, "state": 0,
"plc": "", "string": "Starting"
"searchId": "value",
"state": 1,
"string": "Running"
}, },
"params": { "params": {
"name": "amber", "name": "amber",
@ -22,51 +19,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

View File

@ -257,7 +257,7 @@
"$": [ "$": [
"ds", "ds",
192, 192,
1755878824844 1756210018042
], ],
"$columns": [ "$columns": [
{ {
@ -301,19 +301,6 @@
}, },
"virtualized": false "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" "type": "ia.display.table"
} }
], ],

View File

@ -1,16 +1,5 @@
{ {
"custom": {}, "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": {}, "params": {},
"props": { "props": {
"defaultSize": { "defaultSize": {
@ -72,7 +61,7 @@
"component": { "component": {
"onRowDoubleClick": { "onRowDoubleClick": {
"config": { "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", "scope": "G",
"type": "script" "type": "script"
@ -257,16 +246,22 @@
"$": [ "$": [
"ds", "ds",
192, 192,
1755879137747 1756214343007
], ],
"$columns": [ "$columns": [
{ {
"data": [], "data": [
"System/MCM01/Station/SSPB/UL6_1_SS1",
"/system/mcm01/test"
],
"name": "SourceId", "name": "SourceId",
"type": "String" "type": "String"
}, },
{ {
"data": [], "data": [
"MCM01-FLUID INBOUND",
"MCM02-NC SORTER"
],
"name": "Page", "name": "Page",
"type": "String" "type": "String"
} }
@ -301,19 +296,6 @@
}, },
"virtualized": false "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" "type": "ia.display.table"
} }
], ],
@ -321,7 +303,7 @@
"system": { "system": {
"onStartup": { "onStartup": {
"config": { "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", "scope": "G",
"type": "script" "type": "script"

View File

@ -1,10 +1,8 @@
{ {
"custom": { "custom": {
"disconnected": 0, "disconnected": 0,
"plc": "value",
"priority": 0, "priority": 0,
"priority_string": "No active alarms", "priority_string": "No active alarms",
"searchId": "value",
"state": 0, "state": 0,
"state_string": "Normal" "state_string": "Normal"
}, },
@ -32,21 +30,6 @@
}, },
"persistent": true "persistent": true
}, },
"custom.plc": {
"binding": {
"config": {
"path": "view.params.tagProps[0]"
},
"transforms": [
{
"expression": "split({value}, \"/\")[0]",
"type": "expression"
}
],
"type": "property"
},
"persistent": true
},
"custom.priority": { "custom.priority": {
"binding": { "binding": {
"config": { "config": {
@ -91,15 +74,6 @@
}, },
"persistent": true "persistent": true
}, },
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "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": { "custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -21,51 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Idle" "string": "Idle"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

@ -1,6 +1,5 @@
{ {
"custom": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "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": { "custom": {
"plc": "",
"searchId": "value",
"state": 0, "state": 0,
"string": "Inactive" "string": "Inactive"
}, },
@ -20,30 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 B

View File

@ -109,7 +109,6 @@
"start": "2020-07-29 00:00:00" "start": "2020-07-29 00:00:00"
} }
}, },
"searchId": "value",
"show_dpm_device_view": true, "show_dpm_device_view": true,
"show_dpm_view": true, "show_dpm_view": true,
"timewidget": { "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" "start": "2020-07-29 00:00:00"
} }
}, },
"searchId": "value",
"show_dpm_device_view": true, "show_dpm_device_view": true,
"show_dpm_view": true, "show_dpm_view": true,
"timewidget": { "timewidget": {

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"disconnected": true, "state": 0,
"plc": "", "string": "Starting"
"searchId": "value",
"state": 1,
"string": "Running"
}, },
"params": { "params": {
"name": "amber", "name": "amber",
@ -22,51 +19,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

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

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Idle" "string": "Idle"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"state_string": "OK",
"string": "OK" "string": "OK"
}, },
"params": { "params": {

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"disconnected": true,
"plc": "",
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -21,51 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Clear" "string": "Clear"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "config": {
@ -127,8 +117,8 @@
}, },
"props": { "props": {
"defaultSize": { "defaultSize": {
"height": 40, "height": 42,
"width": 80 "width": 81
} }
}, },
"root": { "root": {

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"plc": "value",
"searchId": "value",
"state": 0, "state": 0,
"string": "Clear" "string": "Clear"
}, },
@ -20,30 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"plc": "value",
"searchId": "value",
"state": 0, "state": 0,
"string": "Clear" "string": "Clear"
}, },
@ -20,30 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"plc": "",
"searchId": "value",
"state": 0, "state": 0,
"string": "Inactive" "string": "Inactive"
}, },
@ -20,30 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"searchId": "value",
"state": 0, "state": 0,
"string": "Unknown" "string": "Unknown"
}, },
@ -19,15 +18,6 @@
] ]
}, },
"propConfig": { "propConfig": {
"custom.searchId": {
"binding": {
"config": {
"path": "session.custom.searchId"
},
"type": "property"
},
"persistent": true
},
"custom.state": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

@ -9,8 +9,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": { "custom": {
"plc": "",
"searchId": "value",
"state": 0, "state": 0,
"string": "Inactive" "string": "Inactive"
}, },
@ -20,30 +18,6 @@
] ]
}, },
"propConfig": { "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": { "custom.state": {
"binding": { "binding": {
"config": { "config": {

View File

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

View File

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

View File

@ -10,8 +10,8 @@
"attributes": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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": {}, "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": {}, "params": {},
"props": { "props": {
"defaultSize": { "defaultSize": {
@ -72,7 +61,7 @@
"component": { "component": {
"onRowDoubleClick": { "onRowDoubleClick": {
"config": { "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", "scope": "G",
"type": "script" "type": "script"
@ -257,16 +246,22 @@
"$": [ "$": [
"ds", "ds",
192, 192,
1755879137747 1756214343007
], ],
"$columns": [ "$columns": [
{ {
"data": [], "data": [
"System/MCM01/Station/SSPB/UL6_1_SS1",
"/system/mcm01/test"
],
"name": "SourceId", "name": "SourceId",
"type": "String" "type": "String"
}, },
{ {
"data": [], "data": [
"MCM01-FLUID INBOUND",
"MCM02-NC SORTER"
],
"name": "Page", "name": "Page",
"type": "String" "type": "String"
} }
@ -301,19 +296,6 @@
}, },
"virtualized": false "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" "type": "ia.display.table"
} }
], ],
@ -321,7 +303,7 @@
"system": { "system": {
"onStartup": { "onStartup": {
"config": { "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", "scope": "G",
"type": "script" "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": { "attributes": {
"lastModification": { "lastModification": {
"actor": "admin", "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, json, sys
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 = {} global_project_page_ids = {}
def get_project_config(): def get_project_config():
""" """
Function searches through the project directory Detailed-Views. Scan each view.json under Detailed_Views (no recursion),
It looks for all the source ids on each Detailed-View and returns a read top-level children, extract tagProps[0],
Dict with source ids as the keys and page ids as the values. and store as {source_id: view_folder_name}.
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) global global_project_page_ids
if not global_project_page_ids: global_project_page_ids.clear()
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
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): def navigate_to_url(self, source_id, page_id):
url_to_navigate = "/DetailedView/%s/%s" % (page_id, page_id) url_to_navigate = "autStand/Detailed_Views/%s" % (page_id)
navigation.amzl_navigation.set_session_variables(self, source_id, False) system.perspective.navigate(view=url_to_navigate, params={"highlightTagPath": source_id + "||Diagnostic"})
system.perspective.navigate(page = url_to_navigate)
def source_id_lookup(self, source_id): def source_id_lookup(self, source_id):
""" """
This function looks for the source_id in Finds page_id from global_project_page_ids by source_id or by hierarchy,
the global_project_page_ids variable. then navigates.
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") if not source_id:
# logger.info(str(global_project_page_ids)) return
page_id = global_project_page_ids.get(source_id) page_id = global_project_page_ids.get(source_id)
found = False found = False
if page_id: if page_id:
found = True found = True
navigate_to_url(self, source_id, page_id) navigate_to_url(self, source_id, page_id)
else: else:
# Walk hierarchy upwards until we find a match
items = source_id.split("/") items = source_id.split("/")
length_of_items = len(items)-1 while len(items) > 1:
while length_of_items > 0:
items.pop() items.pop()
source_id = "/".join(items) source_id = "/".join(items)
page_id = global_project_page_ids.get(source_id) page_id = global_project_page_ids.get(source_id)
@ -94,6 +81,11 @@ def source_id_lookup(self, source_id):
found = True found = True
navigate_to_url(self, source_id, page_id) navigate_to_url(self, source_id, page_id)
break break
length_of_items -= 1
if not found: if not found:
open_pop_up("No page id found") open_pop_up("No page id found")

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