Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
UA Event Filter Question
July 20, 2015
7:42, EEST
Avatar
patger2
New Member
Members
Forum Posts: 2
Member Since:
July 20, 2015
sp_UserOfflineSmall Offline

Hello,

I’m working with the client ua sdk and have some questions regarding the FilterBuilder for filtering ua events.

1. The “and” operator requires exactly 2 parameters which makes sense. But how could I add an filter which have an odd
number of “and” combinations, for example 3 ?

2. There are several base event types defined in the class Identifiers (for example GeneralModelChangeEventType).
Unfortunately this isn’t an enum so is there a way to get these events by a string? Is ask this because I build a xml configuration
where the user can define the event names (in their string representation). For now I doing the mapping from string to Identifiers (NodeId)
via java reflection.

3. What is the best way of retrieving all event types which a selected node supports ?

Thank you very much in advance

Patrick

July 20, 2015
12:27, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

1.
The specification Part 4. Annex B has some good examples on creating event filters. You could try downloading them from https://opcfoundation.org/developer-tools/specifications-unified-architecture since foundation membership is no longer required in order to download them (you still need to create an account). The main point is to use ElementOperands in first elements of the filter and use them to point to later indexies, i.e. at index 0 an AND pointing to index 1, 2, at 1 second AND pointing to 3,4 giving an AND rule for indexies 2,3,4. I can try to create more concrete example in case you have trouble downloading, say if needed.

2.
As a general solution, I think reflection is a good option here. Storing the NodeId directly would be the best option, but if the XML is edited by hand the name version might be easier.

3.
Set WhereClause to null. You still need to define which fields you do want from the events.

– Bjarne

July 22, 2015
11:36, EEST
Avatar
patger2
New Member
Members
Forum Posts: 2
Member Since:
July 20, 2015
sp_UserOfflineSmall Offline

Thank you very much! I’m trying this now!

January 11, 2022
13:24, EET
Avatar
Oleksandr
Member
Members
Forum Posts: 34
Member Since:
February 14, 2020
sp_UserOfflineSmall Offline

Hello,
I do the same for event types defined in the class Identifiers.
Can you please give an example for the mapping from string to Identifiers (NodeId)?

Thank you very much in advance
Oleksandr

January 13, 2022
11:54, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

I do not exactly understand what you wish to do, thus please clarify.

January 13, 2022
17:11, EET
Avatar
Oleksandr
Member
Members
Forum Posts: 34
Member Since:
February 14, 2020
sp_UserOfflineSmall Offline

Hello,
There are several base event types defined in the class Identifiers (for example GeneralModelChangeEventType).
Unfortunately this isn’t an enum so is there a way to get these events by a string? Is ask this because I build a xml configuration
where the user can define the event names (in their string representation: eventType ). For now I doing the mapping from string to Identifiers (NodeId: eventTypeId )
via java reflection:
String eventType = MethodConfigName.replace(“EUROMAP77_methodFor_”, “”);
NodeId eventTypeId = null;
Class identifiersObjectClass = Identifiers.class;
Field[] identifiersFields = identifiersObjectClass.getFields();
for (int i = 0; i < identifiersFields.length; i++) {
if (identifiersFields[i].getName().equals(eventType)){
NodeId nID = null;
try {
eventTypeId = (NodeId) identifiersFields[i].get(nID);
} catch (IllegalArgumentException | IllegalAccessException ex) {
LogHandler.log(PLCConnectorV2.LOGGER_NAME, LogLevel.ERROR, "error while accessing expected identifiersField \"" + identifiersFields[i].getName() + "\"", ex);
}
is there any other safe solution?

Thank you
Oleksandr

January 14, 2022
11:08, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

No, in general “it wont work like that”.

Since you asked this in this thread instead of making a new one, I assume you are on client side doing the EventFilter specifically.

The Identifiers class only contains the NodeIds of the base namespace “http://opcfoundation.org/UA/” (that always gets index 0).
Yes, technically there exist IdentifierDescriptions for that alone (see https://forum.prosysopc.com/forum/opc-ua-java-sdk/version-4-0-2-identifierdescriptions-tonodeid-not-working-anymore/, in the current 4.x releases that IdentifierDescriptions still exists), though I would not recommend using it. It was basically just re-created for backwards compatiblity reasons. That also internally pretty much does the same reflection.

The true key for the event types is the NodeId of the TypeDefinition node of that EventType. Note that the NamespaceIndexes are a connection-runtime information, it is free to change every Session and every server could have their own index). Thus NodeId-wise, that kind of thing can only work for the base namespace (as it is always 0). With the SDK’s Codegen, you can make XXXIds per model that will have ExpandedNodeIds with the NamespaceUri (of the model). You would need to convert those via the NamespaceTable of the client (per client) once you are connected. IMPORTANT! This would mean your users could only use ids that are generated, which could limit use-cases dramatically, most likely this is not what you want. Plus we do not generate any equivalent of the IdentifierDescriptions. Also the name of the java-field might not be 100% the name of the type, if the BrowseName contained special characters that cannot be used as a java field name.

So what you should have in the configuration are the NodeIds, not the BrowseNames. Plus also store the NamespaceUri instead of the index due to above reasons (or have a separate “configuration NamespaceTable” if you wish to use indexes as short forms; like NodeSet files do, or do equivalent aliases like they also do, so at the start of the model there is string->NodeId mapping table).

Technically at connection-runtime if you have the NamespaceUri + the BrowseName of the type in the configuration, you could read all types and match it to the correct type (or fail if no such type did exist).

January 14, 2022
14:41, EET
Avatar
Oleksandr
Member
Members
Forum Posts: 34
Member Since:
February 14, 2020
sp_UserOfflineSmall Offline

thank you.
what method can i use to read all types?

January 14, 2022
15:16, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

There is no such “easy method” what I assume you would be looking for, as typically you should not be checking all types; you would need to manually Browse them all.

Though, the current SDK 4.x release versions also happen to do that internally as part of the so called TypeDictionary initialization, thus you should be able to client.getAddressSpace.getNode(…) them quite fast (as the type nodes are cached). You would start for each well known base type (though for events it is easier as you would only need to check events), thus …getNode(Identifiers.BaseEventType). You would then need to chech the HasSubType references (by checking all references) to see all subtypes and repeat recursively.

That is why I said in general the “OPC UA Way” is to use the NodeId, not the BrowseName in the configuration.

January 18, 2022
11:59, EET
Avatar
Oleksandr
Member
Members
Forum Posts: 34
Member Since:
February 14, 2020
sp_UserOfflineSmall Offline

i can get:
NodeId browseNodeId = Identifiers.BaseEventType;
List references = client.getAddressSpace().browse(browseNodeId);

but how can i check the HasSubType at reference?

public class ReferenceDescription extends AbstractStructure {
public static class Builder extends Builder {
private NodeId referenceTypeId;
private Boolean isForward;
private ExpandedNodeId nodeId;
private QualifiedName browseName;
private LocalizedText displayName;
private NodeClass nodeClass;
private ExpandedNodeId typeDefinition;

January 18, 2022
13:55, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

As I said, the “OPC UA Way” is to use the NodeId, not the BrowseName in the configuration, not doing that is a lot of work.

Check that the referenceTypeId is the NodeId of the HasSubType ReferenceType.

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 1919

Currently Online:
17 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Heikki Tahvanainen: 402

hbrackel: 144

rocket science: 88

pramanj: 86

Francesco Zambon: 83

Ibrahim: 78

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

Member Stats:

Guest Posters: 0

Members: 735

Moderators: 7

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1523

Posts: 6449

Newest Members:

rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, Thomassnism, biancacraft16

Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0

Administrators: admin: 1