In perspective I have a popup page that I want to show up on all screens in the network if a certain tag is set to true. How would I go about doing that and what would that script look like?
thank you
In perspective I have a popup page that I want to show up on all screens in the network if a certain tag is set to true. How would I go about doing that and what would that script look like?
thank you
Bind the tag to a session custom property and use a change script on the property to open the popup.
what would that change script include? would I use an If statement followed by system.perpective.openPopup? I am pretty new to ignition
@mcgheeiv has supplied one route, but the problem is that session properties have no insight into the page in use, which is required when opening a Popup. Your logs would supply an exception or error along the lines of “No perspective page attached to thread.”
There are some important things to consider when planning this: Each browser session could have multiple pages open, so which page gets the Popup? The first page found for a session, or all pages? What conditions would warrant closing the popup across across any pages it is opened on? Would sessions opened AFTER the opening condition becomes true instantly open the popup, or would they be exempt?
I’m going to make some assumptions, and you can manipulate the logic as you see fit. Let’s assume this is a boolean tag, and you want the Popup to be opened for all pages in all sessions when the tag becomes true, and you want the Popup to close for all pages in all sessions when the tag becomes false. Pages/Sessions opened after the tag has become true will be exempt from the Popup.
I think the best solution is going to be to have tag change script.
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
popupId = "SomeUniqueValue"
viewPath = "PopupViews/SmallPopup" # insert your view path here
logger = system.util.getLogger("POPUP")
sessions = system.perspective.getSessionInfo()
for session in sessions:
for pageId in session.pageIds:
logger.info("{0} | {1}".format(session.id, pageId))
if currentValue.value:
system.perspective.openPopup(popupId, viewPath, sessionId=session.id, pageId=pageId)
else:
# note no viewPath arg
system.perspective.closePopup(popupId, sessionId=session.id, pageId=pageId)
It should be pretty simple… If the new value is true open popup…
https://docs.inductiveautomation.com/display/DOC81/system.perspective.openPopup
This is pretty much exactly what I am trying to do. Should this be a gateway event tag change script? in the logic is there anything else I need to substitute in beside viewPath? thank you for all of the help, like I said pretty new to ignition so still some things I need to learn.
No, this should be in the value changed script for a tag.
You should replace the “SomeUniqueValue” with something which is either a UUID or which holds a specific meaning to your use-case; that ID is used to open/close the popup across all sessions, and so if you use the same ID for any other popup you risk trampling other usages.
One question: what happens if there are multiple runnable projects and this only applies for one project?
Another: you’re also not filtering by session type, I.e. Filtering out designer sessions. Probably not an issue since the designers would just ignore it anyway, does it produce an error though?
system.perspective.getSessionInfo()
allows for filtering sessions by username or project, so you could always just get sessions for project "X".
Designer sessions ignore the request for the popup, just like they ignore attempts at navigation.
Would it not be possible to use a message handler here? That way filtering pages is as simple as adding the message handler or not if there are pages in the future you want to exempt.
Why do I use a tag change scrip on the tag vs the gateway? What is the difference between using one or the other?
INFO | jvm 1 | 2022/06/27 08:57:24 | Current value is:
INFO | jvm 1 | 2022/06/27 08:57:24 | True
INFO | jvm 1 | 2022/06/27 08:57:24 | O2Alarm
INFO | jvm 1 | 2022/06/27 08:57:24 | Page/Popups/O2 Alarm Popup
INFO | jvm 1 | 2022/06/27 08:57:24 | I [POPUP ] [13:57:24]: efdfcba8-5006-464c-a1a3-56a33a88059e | 172301c6
INFO | jvm 1 | 2022/06/27 08:57:24 | I [POPUP ] [13:57:24]: E066391F | Page/Popups/O2 Alarm Popup
INFO | jvm 1 | 2022/06/27 08:57:28 | I [c.s.p.g.ProductionGatewayHook ] [13:57:28]: Unable to check availability of null datasource (Local).
INFO | jvm 1 | 2022/06/27 08:57:30 | I [POPUP ] [13:57:29]: efdfcba8-5006-464c-a1a3-56a33a88059e | 172301c6
INFO | jvm 1 | 2022/06/27 08:57:30 | I [POPUP ] [13:57:29]: E066391F | Page/Popups/O2 Alarm Popup
This is what is showing up in my wrapper logs, added a few print statements inside the if statement which show up there but still not popping up on my sessions.
popupId = "O2Alarm"
viewPath = "Page/Popups/O2 Alarm Popup" # insert your view path here
logger = system.util.getLogger("POPUP")
sessions = system.perspective.getSessionInfo()
for session in sessions:
for pageId in session.pageIds:
logger.info("{0} | {1}".format(session.id, pageId))
if currentValue.value:
print "Current value is:"
print currentValue.value
print popupId
print viewPath
system.perspective.openPopup(popupId, viewPath, sessionId=session.id, pageId=pageId)
else:
# note no viewPath arg
system.perspective.closePopup(popupId, sessionId=session.id, pageId=pageId)
This is what I have for my code which is pretty much what you sent besides a few added print statements, not quite sure why my popup is not showing up.
That logging looks very much like it should be working, and I even see a sessionId and pageId in the logging. That code worked for me and I’ve even verified that the space in the View path does not affect functionality. Are you positive you saved after creating the “Page/Popups/O2 Alarm Popup” file?
I am positive that I had saved that file, everything else seems as it is working, strictly the popup is not showing up when enabling that tag.
Remove the logging you put into place and place a new line of logging AFTER the popup functions are called. This will tell you whether or not the function is executing as expected. Are you looking at the browser session, or are you testing this in the Designer?
Looking at it in the browser session and still have no popup, have tried changing value in designer as well as in studio 5000 to toggle the value.
Below is what happens in the logger when I place logger.info(“{0} | {1}” … inside of the if statement
INFO | jvm 1 | 2022/06/27 10:33:29 | Current value is:
INFO | jvm 1 | 2022/06/27 10:33:29 | True
INFO | jvm 1 | 2022/06/27 10:33:29 | O2Alarm
INFO | jvm 1 | 2022/06/27 10:33:29 | Page/Popups/O2 Alarm Popup
INFO | jvm 1 | 2022/06/27 10:33:29 | Current value is:
INFO | jvm 1 | 2022/06/27 10:33:29 | True
INFO | jvm 1 | 2022/06/27 10:33:29 | I [POPUP ] [15:33:29]: efdfcba8-5006-464c-a1a3-56a33a88059e | 172301c6
INFO | jvm 1 | 2022/06/27 10:33:29 | O2Alarm
INFO | jvm 1 | 2022/06/27 10:33:29 | Page/Popups/O2 Alarm Popup
INFO | jvm 1 | 2022/06/27 10:33:29 | I [POPUP ] [15:33:29]: E066391F | Page/Popups/O2 Alarm Popup
INFO | jvm 1 | 2022/06/27 10:33:29 | E [t.e.dispatcher ] [15:33:29]: ([default]OKC/O2/O2_Popup_Trigger, valueChanged) Error executing tag event script: Traceback (most recent call last):
INFO | jvm 1 | 2022/06/27 10:33:29 | File “tagevent:valueChanged”, line 16, in valueChanged
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.UUID.fromString(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:616)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:231)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Invalid UUID string: E066391F
INFO | jvm 1 | 2022/06/27 10:33:29 |
INFO | jvm 1 | 2022/06/27 10:33:29 | com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
INFO | jvm 1 | 2022/06/27 10:33:29 | File “tagevent:valueChanged”, line 16, in valueChanged
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.UUID.fromString(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:616)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:231)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Invalid UUID string: E066391F
INFO | jvm 1 | 2022/06/27 10:33:29 |
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.Py.JavaError(Py.java:547)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.Py.JavaError(Py.java:538)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:192)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.call(ScriptManager.java:541)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyObject.call(PyObject.java:400)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.pycode.pyx34.valueChanged$1(tagevent:valueChanged:8)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.pycode.pyx34.call_function(tagevent:valueChanged)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyTableCode.call(PyTableCode.java:173)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyFunction.function___call(PyFunction.java:474)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyFunction.call(PyFunction.java:469)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyFunction.call(PyFunction.java:464)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:831)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:813)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$FunctionInvokerImpl.run(TagScriptManagerImpl.java:533)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.gateway.tags.scripting.events.AbstractTagScript.invoke(AbstractTagScript.java:34)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$Task.invoke(TagScriptManagerImpl.java:482)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$TagScriptDispatcher.run(TagScriptManagerImpl.java:445)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:539)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.lang.Thread.run(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | Caused by: org.python.core.PyException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Invalid UUID string: E066391F
INFO | jvm 1 | 2022/06/27 10:33:29 | … 25 common frames omitted
INFO | jvm 1 | 2022/06/27 10:33:29 | Caused by: java.lang.IllegalArgumentException: Invalid UUID string: E066391F
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.util.UUID.fromString(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.popupAction(PerspectiveScriptingFunctions.java:616)
INFO | jvm 1 | 2022/06/27 10:33:29 | at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.openPopup(PerspectiveScriptingFunctions.java:231)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
INFO | jvm 1 | 2022/06/27 10:33:29 | at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:190)
INFO | jvm 1 | 2022/06/27 10:33:29 | … 22 common frames omitted
INFO | jvm 1 | 2022/06/27 10:33:32 | I [c.s.p.g.ProductionGatewayHook ] [15:33:32]: Unable to check availability of null datasource (Local).
INFO | jvm 1 | 2022/06/27 10:33:47 | I [c.s.p.g.ProductionGatewayHook ] [15:33:47]: Unable to check availability of null datasource (Local).
INFO | jvm 1 | 2022/06/27 10:34:02 | I [c.s.p.g.ProductionGatewayHook ] [15:34:02]: Unable to check availability of null datasource (Local).
No, don’t place the same logging, just put
logger.info("openPopup complete")
on the line following the openPopup function. I recommend removing your print statements, just to remove clutter. Also, always place any stacktraces within a code block (triple back-ticks) so that it can be easily parsed.
Also also, if you modify code and provide a new stacktrace, you should also provide the NEW code in a code-block, and it’s extra helpful if you can identify which line the error is referencing. In your case, leave a comment on what is line 16 in your code-block. If you don’t do this, then others trying to help you have to make guesses about which line you’ve made changes to, and what could possibly be triggering the error.
When I run the following code:
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
popupId = "O2Alarm"
viewPath = "Split" # insert your view path here
logger = system.util.getLogger("POPUP")
sessions = system.perspective.getSessionInfo()
for session in sessions:
for pageId in session.pageIds:
logger.info("{0} | {1}".format(session.id, pageId))
if currentValue and currentValue.value: # I added an additional safety check for first time use here
system.perspective.openPopup(popupId, viewPath, sessionId=session.id, pageId=pageId)
logger.info("openPopup complete")
else:
# note no viewPath arg
system.perspective.closePopup(popupId, sessionId=session.id, pageId=pageId)
I get the following logging:
POPUP 27Jun2022 08:49:51 B9B1743A | Split
POPUP 27Jun2022 08:49:51 openPopup complete
POPUP 27Jun2022 08:49:51 f456b99d-af9d-4410-94ce-39aec47272c8 | 32a9092e
Which tells me that
Also, my line 14 was my previous line 16, I just removed white space from above.