7:42, EEST
July 20, 2015
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
12:27, EEST
April 3, 2012
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
11:36, EEST
July 20, 2015
13:24, EET
February 14, 2020
11:54, EET
April 3, 2012
17:11, EET
February 14, 2020
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
11:08, EET
April 3, 2012
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).
14:41, EET
February 14, 2020
15:16, EET
April 3, 2012
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.
11:59, EET
February 14, 2020
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;
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, biancacraft16Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1