SDK transfert data from gateway to perspective

I’m looking into why the perspective javadocs aren’t included, will follow up.

Just to follow up - we are building/uploading new javadocs with Perspective packages included. Should be available within an hour of this post. We will publish them going forward as well.

-Perry

3 Likes

Thanks @PerryAJ
Packages com.inductiveautomation.perspective.* are now available in javadoc 8.0.14 :grinning:

Dears,
thank you for this post.
Which is the dependency to add to the module pom, in terms of groupId and artifactId?

Thank you so much.

Not tested, but probably something like:

        <dependency>
            <groupId>com.inductiveautomation.ignitionsdk</groupId>
            <artifactId>perspective-gateway</artifactId>
            <version>${ignition-sdk-version}</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>

and perhaps:

        <dependency>
            <groupId>com.inductiveautomation.ignitionsdk</groupId>
            <artifactId>perspective-common</artifactId>
            <version>${ignition-sdk-version}</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>

to confirm by @PGriffith

Thank you @mazeyrat!
I am able to import the com.inductiveautomation.perspective.gateway package.
I follow the code snippet of @PGriffith, then when I install the module the following error occurs:

java.lang.NoClassDefFoundError: com/inductiveautomation/perspective/gateway/api/PerspectiveContext

It seems the module is not able to interact with the Perspective context in the startup phase.
Any suggestion will be appreciated.

Thank you.

have you the dependency with the perspective module in the build.pom

I suppose something like:

                    <depends>
                        <depend>
                            <scope>G</scope>
                            <moduleId>com.inductiveautomation.perspective</moduleId>
                        </depend>
                        <depend>
                            <scope>D</scope>
                            <moduleId>com.inductiveautomation.perspective</moduleId>
                        </depend>
                    </depends>

see gradle example:

moduleDependencies = [
                [scope: "G", moduleId: "com.inductiveautomation.perspective"],
                [scope: "D", moduleId: "com.inductiveautomation.perspective"]
        ]
1 Like

Dear @mazeyrat,
it works fine! Thank you for your kind support and help.

Best,
Andrea

Must be the message to call a Session Message Handler?
I run a java method using the snippet by @PGriffith, the code run with success, but the session message handler is not triggered.

    PerspectiveContext perspectiveContext = PerspectiveContext.get(this.context);
    for (UUID sessionId: GatewayHook.perspectiveSessionListener.getSessionIds()
         ) {
        if(perspectiveContext.getSessionMonitor().findSession(sessionId).isPresent()){
            InternalSession session = perspectiveContext.getSessionMonitor().findSession(sessionId).get();
            PyDictionary payloadMap = new PyDictionary();
            payloadMap.put("sessionId", sessionId.toString());
            payloadMap.put("paramUUID", paramUUID);
            UserScopeMessageEvent message = new UserScopeMessageEvent("test", payloadMap);

            session.queue().submit(() -> session.getEventBus().post(message));
        }
    }

Thanks a lot.

There’s no logging on the event bus itself, unfortunately. You do have a message handler configured on the target, with the same key defined, right?
You can clean up the code a little bit and make sure it’s actually calling your message:

    PerspectiveContext perspectiveContext = PerspectiveContext.get(this.context);
    for (UUID sessionId: GatewayHook.perspectiveSessionListener.getSessionIds()) {
        perspectiveContext.getSessionMonitor().findSession(sessionId).ifPresent(session -> {
            PyDictionary payloadMap = new PyDictionary();
            payloadMap.put("sessionId", sessionId.toString());
            payloadMap.put("paramUUID", paramUUID);
            UserScopeMessageEvent message = new UserScopeMessageEvent("test", payloadMap);
            LoggerEx.newBuilder("messageHandler").build().infof("Calling handler: %s", message)
            session.queue().submit(() -> session.getEventBus().post(message));
        });
    }

Thank you @PGriffith: it works!

1 Like

@PGriffith
That’s fine !
For a script function exposed by a module and called in perspective, can we obtain in the script function the context session Id ? (in order to interact with this session in the script function). I would like to avoid a sessionId parameter…

Seems to be ok with:

InternalSession.SESSION.get().getSession().getSessionId()

Is it the right way to do things ?

If you’re calling the InternalSession.SESSION threadlocal directly, then you don’t need to go through the rest of the Perspective context - you can directly call whatever you want to - ie,

InternalSession.SESSION.get().getEventBus().post();

Also, a healthy disclaimer that while it’s unlikely we’ll change things, the InternalSession threadlocal is not considered part of our API surface, so it could break in some future version without notice.

Is there any other method to retrieve the sessionId ?

Can we restrict the UserScopeMessageEvent for be send to a page and/or view

image

You don’t restrict the UserScopeMessageEvent - you just drill down into the required event bus. From an InternalSession, you can either findPage(<pageid>) or listPages() - then if you want to send a page scoped event, use the page’s event bus: getPageEventBus().

It looks like there’s no complementary function (that’s public) on Page, but sending a ‘View’ scope event would follow a similar model - you need to get to the View you want, then access its event bus.

1 Like

Thanks a lot for these clarifications :+1:

Hi @PGriffith

to obtain the sessionId

String sessionId = InternalSession.SESSION.get().getSession().getSessionId().toString();

work fine.

But if I need to obtain the pageId, I’ve tried:

String pageId = InternalSession.SESSION.get().getSession().getPage().getId().toString();

or

String pageId = InternalSession.SESSION.get().getPage().getId().toString();

But both of them are triggering a java.lang.NullPointerException: null

Did I missed something ?

I try to guess in a script function the sessionId and pageId to keep distinct data for multiple sessionId/pageId.

getPage() on a Session object will always return null. A Session may have multiple pages, so you may have to use getPages(), but I’m not sure if there is a way to know which page is open or whatever it is you are looking for.

Yes session have multiple page, but I try to obtain the “context” (sessionId,pageId) in a module script function.
For sessionId,

String sessionId = InternalSession.SESSION.get().getSession().getSessionId().toString();

but to obtain the current pageId from where the script is executed, I don’t see ?

I want to avoid to pass the pageId parameter to each script function…