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

No permission to create posts
sp_Feed Topic RSS sp_TopicIcon
help TCDHelpOffNormalAlarmTypeNode (subtype of HelpOffNormalAlarmType defined in OPC 40083)
December 21, 2022
13:16, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Good morning,

I am using the prosys-opc-ua-sdk-for-java-4.9.0-43-client-server-binary library.

I’m trying to implement an OPC UA server with classes generated by the codegen tool (information model: EUROMAP 82.1 url: https://www.euromap.org/euromap82-1).

Please can you explain me how to handle TCDHelpOffNormalAlarmTypeNode?
I would trigger a new alarm and then view it in an OPC UA client (UAExpert)

References:
– Parent: TCD_InterfaceType
– BrowseName: TCDHelpOffNormalAlarmType
– Subtype of 3:HelpOffNormalAlarmType (defined in OPC 40083)
– file: EUROMAP82.1_Release_1.01.pdf
– page: 26.

Thanks in advance for the support,
Francesco

December 21, 2022
15:12, EET
Avatar
Matti Siponen
Moderator
Members

Moderators
Forum Posts: 346
Member Since:
February 11, 2020
sp_UserOfflineSmall Offline

Hello,

You will need to create an instance of TCDHelpOffNormalAlarmTypeNode with NodeManagerUaNode by calling:

TCDHelpOffNormalAlarmTypeNode alarm = nodeManager.createInstance(TCDHelpOffNormalAlarmTypeNode.class, name, nodeId);

where nodeManager is your NodeManagerUaNode, name is the name for the alarm as String and nodeId is the NodeId for the alarm.

You can then call various setter methods, e.g. setActive and setDeviceMappingNumber, for the created alarm to set Values of various Event Fields.

You can then send the alarm by calling one of its triggerEvent methods, e.g. alarm.triggerEvent(null).

Since the created alarm is a Node, you can also display it in the AddressSpace of your OPC UA Server if you wish. You can create this Node in advance and set the initial Values for its Properties and add it to AddressSpace as you would add any other Node. You can then set the Values of Properties related to the alarm in your system before triggering the event. I would recommend taking a look at myAlarm field of MyNodeManager class of SampleConsoleServer sample application for an example of how to add an Alarm Node to AddressSpace.

December 27, 2022
15:17, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Matti,

Thank you for your reply.

Please could you help me with the following code?
— start code
private void testAlarms(NodeDevice nodeDevice) {
try {
TCDHelpOffNormalAlarmTypeNode alarm = nodeManagerEu82_1.createInstance( //
TCDHelpOffNormalAlarmTypeNode.class, //
“TCDHelpOffNormalAlarmType”, //
new NodeId(nodeManagerEu82_1.getNamespaceIndex(),
“TCDHelpOffNormalAlarmType_” + nodeDevice.getDevice().getFmId())); //

System.err.println(“— alarm: ” + alarm.getNodeId());
System.err.println(“— alarm: ” + alarm);

TCDHelpOffNormalAlarmTypeNode retriveAlarm = nodeManagerEu82_1.getNode( //
new NodeId(nodeManagerEu82_1.getNamespaceIndex(),
“TCDHelpOffNormalAlarmType_” + nodeDevice.getDevice().getFmId()), //
TCDHelpOffNormalAlarmTypeNode.class);

System.err.println(“— check alarm ” + alarm.equals(retriveAlarm));
} catch (Exception e) {
e.printStackTrace();
}
}
— end code

The method nodeManagerEu82_1.getNode throws exception:
— start log
27/12/2022 14:02:34 [connectionThread] ERROR c.p.g.s.p.o.m.e.OPCUAEuromap82_1Module – — alarm: ns=4;s=TCDHelpOffNormalAlarmType_1
27/12/2022 14:02:34 [connectionThread] ERROR c.p.g.s.p.o.m.e.OPCUAEuromap82_1Module – — alarm: NodeId=ns=4;s=TCDHelpOffNormalAlarmType_1, NodeClass=Object, BrowseName=4:TCDHelpOffNormalAlarmType; Type={NodeId=ns=4;i=1009, NodeClass=ObjectType, BrowseName=4:TCDHelpOffNormalAlarmType, IsAbstract=false}
27/12/2022 14:02:34 [connectionThread] ERROR java.lang.Throwable – com.prosysopc.ua.StatusException: nodeId=ns=4;s=TCDHelpOffNormalAlarmType_1 StatusCode=Bad_NodeIdUnknown (0x80340000) “The node id refers to a node that does not exist in the server address space.” Diagnostics=Diagnostic Info:
nodeId=ns=4;s=TCDHelpOffNormalAlarmType_1
— end log

Best regards,
Francesco

December 27, 2022
17:40, EET
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

‘createInstance’ does not add the node to the address space. Typically, you should also add a reference to it from some other object. If you look at the sample server (MyNodeManager.createAlarm), the alarm node is added under ‘myDevice’ as follows:

myDevice.addComponent(myAlarm);

Alternatively, you can use

nodeManagerEu82_1.addNodeAndReference(objectsFolder, alarm, Identifiers.Organizes);

where ‘objectsFolder’ is the node under which you wish to add the alarm (MyNodemanager.createAddressSpace).

Or if you just wish to make your test code work, you can simply use

nodeManagerEu82_1.addNode(alarm);

but this is not recommended for real servers, since the clients will not be able to find the alarm from the address space by browsing.

December 29, 2022
13:36, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Hi everyone,
Thank you for your support.

If there is no problem I would continue writing in this thread.

My goal is to send the TCDHelpOffNormalAlarmTypeNode alarm (subtype of OffNormalAlarmTypeNode) and then check it with UAExpert.

My server code does the following:
1 Create an instance of the TCDHelpOffNormalAlarmTypeNode alarm.
2 Set the alarm source.
3 Send the alarm.

System.out.println("start —————————–");

System.out.println(alarmBean);

// create TCDHelpOffNormalAlarmTypeNode NodeId
String nodeIdValue = "TCDHelpOffNormalAlarmType_" //
+ nodeDevice.getDevice().getFmId() //
+ "_" //
+ alarmBean.getAlarmIdCode(); //
NodeId nodeId = new NodeId(1, nodeIdValue);

// create TCDHelpOffNormalAlarmTypeNode
TCDHelpOffNormalAlarmTypeNode alarm = nodeManagerUaNode.createInstance( //
TCDHelpOffNormalAlarmTypeNode.class, //
"TCDHelpOffNormalAlarmType", //
nodeId); //

// retrieve TCD_InterfaceTypeNode instance
NodeId tcdNodeId = new NodeId(1, "TCD_" + nodeDevice.getDevice().getFmId());
TCD_InterfaceTypeNode tcd = (TCD_InterfaceTypeNode) nodeManagerUaNode.getNode(tcdNodeId);

// set alarm source
alarm.setSource(tcd);

// send alarm
alarm.triggerEvent(null);

System.out.println("end —————————–");

I listened for events with UAExpert:

Question: in the Events tab I see the alarm, but why I don’t see anything in the Alarms tab?

See pictures:
link 1
link 2

Thank you,

December 29, 2022
15:14, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Hello,

I found the error: the Alarms tab displays only the alarms with the attribute retain = true.

Best regards,
Francesco

January 9, 2023
18:38, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Hello,

Please I need your help to set mandatory attributes of TCDHelpOffNormalAlarmType (see Consideration fields)
——————————————————————————–
Hierarchy:
BaseEventType (OPC UA part 5)
This EventType is defined in OPC 10000-3.
|
ConditionType (OPC UA part 9)
The ConditionType inherits all Properties of the BaseEventType. Their semantic is defined in 10000-5.
|
AcknowledgeableConditionType (OPC UA part 9)
The AcknowledgeableConditionType inherits all Properties of the ConditionType.
|
AlarmConditionType (OPC UA part 9)
The AlarmConditionType that extends the AcknowledgeableConditionType by introducing an ActiveState, SuppressedState and ShelvingState. It also adds the ability to set a delay time, re-alarm time, Alarm groups and audible Alarm settings.
|
DiscreteAlarmType
The DiscreteAlarmType is used to classify Types into Alarm Conditions where the input for the Alarm may take on only a certain number of possible values (e.g. True/False, running/stopped/terminating).
|
OffNormalAlarmType (OPC UA part 9)
The OffNormalAlarmType is a specialization of the DiscreteAlarmType intended to represent a discrete Condition that is considered to be not normal.
|
HelpOffNormalAlarmType (EUROMAP 83)
The HelpOffNormalAlarmType can be used by devices, to inform the client about a Condition that is considered to be not normal. It is a subtype of the OffNormalAlarmType defined in OPC UA Part 9 and adds the Property Helptext to give some additional information to the operator.
|
TCDHelpOffNormalAlarmType (EUROMAP 82.1)
For alarms (alarms, warnings, information) of the TCD the TCDHelpOffNormalAlarmType as defined in Table 21 shall be used, if the alarm facet is supported. A machine which connects to a TCD via OPC 40082-1 shall subscribe this event

——————————————————————————–
BaseEventType properties (mandatory):


– BrowseName: EventId.
– Description: is generated by the Server to uniquely identify a particular Event Notification.
– Considerations: managed by Prosys SDK: EventId increments when i send the alarm (method: com.prosysopc.ua.types.opcua.server.BaseEventTypeNode.triggerEvent(null)).


– BrowseName: EventType.
– Description: describes the specific type of Event.
– Considerations: managed by Prosys SDK: the value of EventType is already set (TCDHelpOffNormalAlarmTypeNode’s NodeId – EUROMAP 82.1).


– BrowseName: SourceNode.
– Description: identifies the Node that the Event originated from.
– Considerations: SourceNode could be the NodeId of a TCD instance / MonitoredParameterType if this is out of tolerance


– BrowseName: SourceName.
– Description: provides a description of the source of the Event.
– Considerations: this could be the string-part of the DisplayName of the Event source


– BrowseName: Time.
– Description: Time provides the time the Event occurred. This value is set as close to the event generator as possible.
– Considerations: none.


– BrowseName: ReceiveTime.
– Description: provides the time the OPC UA Server received the Event from the underlying device of another Server.
– Considerations: none.


– BrowseName: Message.
– Description: provides a human-readable and localizable text description of the Event.
– Considerations: none.


– BrowseName: Severity.
– Description: is an indication of the urgency of the Event. This is also commonly called “priority”.
– Considerations: EUROMAP 82.1: For the Severity Property (included in BaseEventType) the following classes shall be used:
667-1000 Messages of high urgency
334-666 Messages of medium urgency
1-333 Messages of low urgency

——————————————————————————–
ConditionType properties (mandatory):

– BrowseName: ConditionClassId.
– Description: specifies in which domain this Condition is used. It is the NodeId of the corresponding subtype of BaseConditionClassType.
– Considerations: HELP. the value is null. What should i set?


– BrowseName: ConditionClassName.
– Description: provides the DisplayName of the of the ConditionClassType provided in the ConditionClassId.
– Considerations:HELP. the value is null. What should i set?


– BrowseName: ConditionName.
– Description: identifies the Condition instance that the Event originated from. It can be used together with the SourceName in a user display to distinguish between different Condition instances. If a ConditionSource has only one instance of a ConditionType, and the Server has no instance name, the Server shall supply the ConditionType browse name.
– Considerations: HELP. the value is null. Please can you give me an example?


– BrowseName: BranchId.
– Description: is NULL for all Event Notifications that relate to the current state of the Condition instance. If BranchId is not NULL, it identifies a previous state of this Condition instance that still needs attention by an Operator.
– Considerations: HELP. the value is null. Please can you give me an example?


– BrowseName: Retain.
– Description: when True describes a Condition (or ConditionBranch) as being in a state that is interesting for a Client wishing to synchronize its state with the Server’s state. The logic to determine how this flag is set is Server specific. Typically, all Active Alarms would have the Retain flag set; however, it is also possible for inactive Alarms to have their Retain flag set to TRUE.
– Considerations: if null the command Acknowledge of OPC UA CLIENT is not available.


– BrowseName: EnabledState.
– Description: indicates whether the Condition is enabled.
– Considerations: none.


– BrowseName: Quality
– Description: reveals the status of process values or other resources that this Condition instance is based upon.
– Considerations: HELP. the value is already set (GOOD (0x00000000) “The operation succeeded.”). When should i update it?


– BrowseName: LastSeverity
– Description: provides the previous severity of the ConditionBranch.
– Considerations: HELP. the value is null. Please can you give me an example?


– BrowseName: Comment
– Description: contains the last comment provided for a certain state (ConditionBranch).
– Considerations: HELP. the value is null. Please can you give me an example?


– BrowseName: ClientUserId
– Description: is related to the Comment field and contains the identity of the user who inserted the most recent Comment.
– Considerations: none.


– BrowseName: Disable
– Description: Method is used to change a Condition instance to the Disabled state.
– Considerations: none.


– BrowseName: Enable
– Description: Method is used to change a Condition instance to the enabled state.
– Considerations: none.


– BrowseName: AddComment
– Description: Method is used to apply a comment to a specific state of a Condition instance.
– Considerations: none.

——————————————————————————–
AcknowledgeableConditionType properties (mandatory):


– BrowseName: AckedState
– Description: when False indicates that the Condition instance requires acknowledgement for the reported Condition state.
– Considerations: none.


– BrowseName: Acknowledge
– Description: Method is used to acknowledge an Event Notification for a Condition instance state where AckedState is False.
– Considerations: none.

——————————————————————————–
AlarmConditionType properties (mandatory):


– BrowseName: ActiveState.
– Description: when set to True indicates that the situation the Condition is representing currently exists.
– Considerations: none.


– BrowseName: InputNode.
– Description: Property provides the NodeId of the Variable the Value of which is used as primary input in the calculation of the Alarm state.
– Considerations: none.


– BrowseName: SuppressedOrShelved
– Description: When an Alarm has any or all of the SuppressedState, OutOfServiceState or ShelvingState set to True, the SuppressedOrShelved property shall be set True and this Alarm is then typically not displayed by the Client.
– Considerations: none.

——————————————————————————–
DiscreteAlarmType properties (mandatory):

none.

——————————————————————————–
OffNormalAlarmType properties (mandatory):


– BrowseName: NormalState
– Description: The NormalState Property is a Property that points to a Variable which has a value that corresponds to one of the possible values of the Variable pointed to by the InputNode Property where the NormalState Property Variable value is the value that is considered to be the normal state of the Variable pointed to by the InputNode Property.
– Considerations: none.

——————————————————————————–
HelpOffNormalAlarmType properties (mandatory):
– BrowseName: HelpText
– Description: Servers can use the Property HelpText also in other server specific alarms which are not derived from OffNormalAlarmType
– Considerations: none.

——————————————————————————–
TCDHelpOffNormalAlarmType


– BrowseName: DeviceMappingNumber
– Description: The value of DeviceMappingNumber corresponds to the value given in the instance of the OperationType (see 9.1) for assigning the alarm to a device.
– Considerations: none.


– BrowseName: SourceNode
– Description: For unique identification of the alarm event, the SourceNode (included in BaseEventType) of the device needs to be sent for every alarm message. The SourceNode includes the namespace number and the Identifier from the object instance of TCD_InterfaceType (for general events) or the NodeId of a child element (e.g. a variable
of MonitoredParameterType if this is out of tolerance).
– Considerations: none.


– BrowseName: Severity
– Description: For the Severity Property (included in BaseEventType) the following classes shall be used: Table 22 – Severity Classes…
– Considerations: none.

Thanks,
Francesco

January 10, 2023
11:28, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

Please note that you might be the first person to ever ask this detailed questions regarding the Alarms&Conditions.

First I would like to ask that are setting these due to “a real need” or more like that you are curious what their values could be?

Note that a “Mandatory ModellingRule” (e.g. in https://reference.opcfoundation.org/v104/Core/docs/Part9/5.5.2/ table), means the Node must exist in the address space when an instance of the type is made. Technically it’s value can still be null. Like, it might not be correct per spec to have it as null, but it is possible to send the event while the value is null, and in very many cases that is what happens (Alarms&Conditions usage is less than e.g. Read/Browse +data-Subscriptions). And the value is only sent if a client requests it in the first place (there is no way in OPC UA to “send all event fields” to a client), thus a real need for these means a client must be asking the value via the EventFilter (or to do actual filtering, this is done server-side per the filter as well).

If you can, please ignore at least for now anything that says or is related to “CondtionBranches” (or “branch”). Basically we have never done nor tested condition branching (https://reference.opcfoundation.org/v104/Core/docs/Part9/5.5.3/) and I have never seen it used out in the world (but I see a small part of the world though), thus it is unlikely that you would need it (however, if you do let us know).

ConditionClassId+ConditionClassName
For now I personally would keep these as null as they basically have always been; the Part 9 5.5.2 does say “BaseConditionClassTypeis used as class whenever a Conditioncannot be assigned to a more concrete class.”, so I guess you can just set it as Identifiers.BaseConditionClassType and “BaseConditionClassType”). I have not seen these being used, but 1.05 core information model moved these to be optional in the BaseEventType so maybe more in the future.

Retain
Please see MyNodeManager.inactivateAlarm()+activateAlarm(), they toggle the retain flag depending is the alarm active or not.

Quality
Please read https://reference.opcfoundation.org/v104/Core/docs/Part9/5.5.2/ i.e.

Qualityreveals the status of process values or other resources that this Conditioninstance is based upon. If, for example, a process value is “Uncertain”, the associated “LevelAlarm” Conditionis also questionable. Values for the Qualitycan be any of the OPC StatusCodesdefined in OPC 10000-8as well as Good, Uncertainand Badas defined in OPC 10000-4. These StatusCodesare similar to but slightly more generic than the description of data quality in the various field bus specifications. It is the responsibility of the Serverto map internal status information to these codes. A Serverthat supports no quality information shall return Good. This quality can also reflect the communication status associated with the system that this value or resource is based on and from which this Alarmwas received. For communication errors to the underlying system, especially those that result in some unavailable Eventfields, the quality shall be Bad_NoCommunication error.

ConditionName
I would assume this to mean that if you have more than one alarm from the same node it can be used to differentiate them in UIs. We have not used this, so it is a bit hard to give a real example. But assuming the sampleconsoleserver MyDevice/MyLevelAlarm/MyLevel, if you would have instead 2 instances of “MyLevelAlarm” named “MyLevelAlarm1” and “MyLevelAlarm2” you would set this field to “MyLevelAlarm1” or “MyLevelAlarm2” depending on the alarm. So it can be used to differentiate between multiple instances of the same ConditionType whose alarms originate from the same node (then how likely is this scenario is a different thing).

Does this help?

January 11, 2023
19:34, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

Thank you very much for your help.

I answer your question:
“First I would like to ask that are setting these due to “a real need” or more like that you are curious what their values could be?”

Right now I’m trying to handle the event TCDHelpOffNormalAlarmType triggered by TCD instances / monitored variables.

Also, I’m studying Alarms&Conditions to understand how the alarm event types defined in the OPC UA standard work because later I’ll have to handle alarms from machines that don’t implement UA Companion Specifications.

——————————————————————————–

I have another question regarding the Event View of the UAExpert client:

Can you please explain how the Event View page tabs work?

– Events tab: should the client only display events triggered after the client connection? Or should the server send the events triggered before the client connection?

– Alarms: should the server send to it the alarms triggered before the client connection? (as for the Events tab).

– Event History: should the client view the events stored in the server’s event history?

Thanks,
Francesco

January 12, 2023
11:05, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Note that UaExpert is not made by us (https://www.unified-automation.com/products/development-tools/uaexpert.html), so I cannot explain exact internal details, but this is mostly general OPC UA stuff so this should be enough.

Our own generic client is the OPC UA Browser: https://www.prosysopc.com/products/opc-ua-browser/, for that it is easier to say.

When the client makes the Subscription+MonitoredItem (typically on the ‘Server’ node), no historical data is sent (this is how it is specified; skipping mostly of why, but e.g. history could be very big, that is why it is done separately via HistoryRead service calls). However, Clients can call standard Methods ConditionRefresh (Subscription level, https://reference.opcfoundation.org/v104/Core/docs/Part9/5.5.7/) and ConditionRefresh2 (MonitoredItem-level, https://reference.opcfoundation.org/Core/Part9/v104/5.5.8/), which causes the server to send Retain=true Conditions via the monitored item. So you can think this like receiving a list of still active alarms etc (e.g. some control room “do something to this” info). The SDK client-side Subscription class has conditionRefresh() helper method and MonitoredEventItem has conditionRefresh() as well (this calls ConditionRefresh2 on the server).

Our OPC UA Browser upon opening the Event View calls ConditionRefresh automatically for you (you will see a RefreshStartEventType + RefreshEndEventType). Note that we do not yet have an Alarm View, we will add it some day (but you can do the alarm Acknowledge etc. actions via the r-click context menu). If you Acknowledge something (this is an UA Method call) you will see an event where AckedState is true, this is still the same Alarm, but it state changed (and this change was given by the server as an Event).

There isn’t any “special-alarm-data” per se in OPC UA, it is just raw Events where the data can be snapshots of the alarm state. Clients (e.g. UaExpert) would keeps a local state model for these based on the raw events if they would implement things like the Alarm tab in UaExpert.

For the history part, it is hard to answer to “should the client view the events stored in the server’s event history?” as it depends on what your application does. Also note that it would be somewhat rare for a server to support event history (like, our samples do, but not very many real servers). If your application is continuously connected to the server, there shouldn’t be need to read history. If your application is more like a “log viewer” type of app, it would probably just read history data. Or maybe your app combines both styles.

January 12, 2023
16:33, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

I started using the OPC UA Browser client. Now I can check the differences between two clients. Thanks.

——————————————————————————–

Question: I noticed that if I don’t add my TCDHelpOffNormalAlarmTypeNode instance to the OPC UA tree (UaNode.addComponent() method), the client fails to execute the methods (Acknwoledge, Confirm, Active, …). Error: Bad_NodeIdUnknown.

I thought it wasn’t mandatory to add the alarms nodes to the OPC UA tree.

Is this behavior correct?

Question 2: I tried adding the myAlarm node to the MyHistorian event handler (SampleConsoleServer project). But it’s not working. Please can you send me an example?

Thanks,
Francesco

January 12, 2023
18:11, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

I have never seen (but I also see only a part of the world so to say) a server which would not add them (then again not many servers even use Events in the first place..). But seems per spec https://reference.opcfoundation.org/Core/Part9/v105/docs/4.10 + https://reference.opcfoundation.org/Core/Part9/v105/docs/6 that could be possible (at least in this spec version), but probably one would probably want to add them, if possible. So this might have been specified for some very low-end hardware or even chip-level servers.

The above also means since the spec doesn’t forbid “adding nodes to the tree”; doing so is within spec.

Anyway, with SDK, with Codegen+UaNodes+NodeManagerUaNode.createInstance (which I assume you use since you said “TCDHelpOffNormalAlarmTypeNode”), you must add it. Technically adding it to the manager is probably enough, but adding it as a component to other node also ensures it is added to the correct manager automatically (and I do recall something about all instances must be reachable via hierarchical references chain from the Objects folder, but cannot find it at the moment from the spec). It might be .. a flaw with createInstance that it wouldn’t add it by itself. Anyway you might also want to add the reference chains from the Server node to the alarm node as indicated in the spec.

Also assuming I recall this correctly, the Browser app would also need to see the instance. It might not be 100% correct, but explaining that will take long so skipping for now.

Technically using the lower-tier API with a “MyBigNodeManager-style” (from the sampleconsoleserver), you probably should be able to avoid the instances if really needed, however Browser probably wont yet work (not sure would UaExpert). Also with this you cannot use UaNodes nor Codegen, basically you would just respond to lower level Read/Write/Browse requests and handle Methods like MyMethodManagerListener (this can be used also with NodeManagerUaNode if you didn’t get the Method handled via Codegen; so called “static” Methods cannot be implemented via Codegen). You also would need to use raw UaClient.call to handle the Call of the Method (since Codegen code cannot call static methods, this is sort of the whole problem, but explaining some other time if needed as it is as least as much text than this answer, probably double).

So I guess a better question would be that is adding them to the address space a problem for you?

January 12, 2023
18:26, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

I answer your question:
“So I guess a better question would be that is adding them to the address space a problem for you?”
Thanks you for the explanation. For me it is not a problem to add the nodes. I prefer to use high level API (NodeManagerListener + Codegen classes).

Thanks,
Francesco

January 20, 2023
17:42, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Hello Bjarne,

Please can you tell me how to send an alarm only to the client of the subscpription?
Is it enough to use the method alarm.triggerEvent(null) ?

Example:

import com.prosysopc.ua.server.EventManagerListener;

public class OPCUAEventManagerListener implements EventManagerListener {

@Override
public void onConditionRefresh(ServiceContext serviceContext, Subscription subscription) throws StatusException {

}

}

Thanks,
Francesco

January 23, 2023
10:00, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Do you mean in general or when clients calls the ConditionRefersh?

In general, when you trigger an event, it will be added to the notifications of all subscriptions of all clients, which have a MonitoredItem in the subscription “that would see the event”. Typically clients monitor the ‘Server’ node, this will give all events of the server.

For ConditionRefresh, basically SDK should do this automatically, but there are a few notes. First the Condition node must have Retain true (i.e. the value of the Retain node must be true), and there must be a chain from the Node which is selected in MonitoredItem to the Condition node, i.e. there must be a link via HasNotifier, HasEventSource or HasCondition from the source (monitored) to the target (condition) either directly or indirectly (by following those references).
IF not, you can call MonitoredEventItem.notifyEvent(EventData), and all Conditions should have condition.getLastEvent().

January 24, 2023
12:27, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

Thanks for the support.

I added the following relationships:


// + HasCondition, the SourceNode of the reference should normally
// correspond to the Source set above
source.addReference(alarm, Identifiers.HasCondition, false);

// + EventSource, the target of the EventSource is normally the
// source of the HasCondition reference
device.addReference(source, Identifiers.HasEventSource, false);

// + HasNotifier, these are used to link the source of the EventSource
// up in the address space hierarchy
deviceFolder.addReference(source, Identifiers.HasNotifier, false);

Now the onConditionRefresh method works correctly.
I also get notifications when the client monitors the server node.

Before these changes, I had added the following relation (as described in document EUROMAP82.1_Release_1.01.pdf page 10):
BrowseName TCD_InterfaceType

0:GeneratesEvent ObjectType TCDHelpOffNormalAlarmType


source.addReference(alarm, Identifiers.GeneratesEvent, false);

But it didn’t work and all source node relationships are “disappeared”.

Maybe the relationship GeneratesEvent is not handled by the SDK?

Thanks,
Francesco

January 24, 2023
14:40, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

That may then be an error in the EUROMAP spec (based on what you said, I didn’t look the wording there); as far as I’m aware (and https://reference.opcfoundation.org/Core/Part3/v105/docs/7.15), the GeneratesEvent can only be used from within ObjectTypes to refer which EventTypes the instances of the ObjectType could potentially send (or something like that).

The GeneratesEvent ReferenceTypeis a concrete ReferenceTypeand can be used directly. It is a subtype of NonHierarchicalReferences.

The semantic of this ReferenceTypeis to identify the types of Eventsinstances of ObjectTypes or VariableTypesmay generate and Methodsmay generate on each Methodcall.

The SourceNodeof Referencesof this type shall be an ObjectType, a VariableTypeor a Method InstanceDeclaration.

The TargetNodeof this ReferenceTypeshall be an ObjectTyperepresenting EventTypes, that is, the BaseEventTypeor one of its subtypes.

Thus, it is a “types-only” reference, and intentionally ignored by the createInstance/NodeBuilder. Thus, it is also not part of the “event-hierarchy” calculation logic as it cannot appear in any instance.

February 1, 2023
16:44, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

Thanks for the explanation about ReferenceType.

Please can you tell me how to handle HistoryReadRequest?

After analyzing the network traffic with Wireshark, I saw that the client (UAExpert) asks for the events history data of the server node instance (NodeId=”i=2253″).
Server node instance is managed by NodeManagerRoot.
I don’t understand if I have to create a new HistoryManagerListener.

Best regards,

Francesco

February 1, 2023
17:22, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1026
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

It depends if you want to support event history for the ‘Server’ node. To be honest I don’t think we have done that yet (I sort of noticed this just now) ourselves in our apps nor the sample (sampleconsoleserver) doesn’t cover that case: /Root/Objects/Server EventNotifier is just [SubscribeToEvents] while /Root/Objects/2:MyObjects/2:MyDevice is [SubscribeToEvents, HistoryRead]. So only the live Events do come via Server automatically.

Most likely in the future maybe (not sure yet when) we could do something similar to the ConditionRefresh thingy (using the References chain), but for now you would need to set the listener in the NodeManagerRoot via server.getNodeManagerRoot().getHistoryManager().setListener(HistoryManagerListener) and also set the EventNotifier Attribute to also contain HistoryRead as set for the ‘Server’ node. Our Browser application will note if it is not set (but allows to continue), some clients might not. Or some might not check the bit at all and just do the historyread anyway.

You can maybe just use the same HistoryManagerListener for all NodeManager/HistoryManagerss depending on how you store the history.

February 3, 2023
16:11, EET
Avatar
Francesco Zambon
Member
Members
Forum Posts: 83
Member Since:
December 20, 2021
sp_UserOfflineSmall Offline

Dear Bjarne,

I’m reading the OPC Part 11: Historical Access document, but I don’t understand if it is necessary to manage all services.

Does the com.prosysopc.ua.samples.server.MyHistorian class manage all the mandatory data / event history services?
The HistoryServerCapabilities node (sampleconsoleserver application) is not configured.

Thanks in advance for your help,
Francesco

No permission to create posts
Forum Timezone: Europe/Helsinki

Most Users Ever Online: 1919

Currently Online:
58 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: 734

Moderators: 7

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1523

Posts: 6449

Newest Members:

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

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

Administrators: admin: 1