Custom alarm model

Questions regarding the use of the .NET SDK 2.0 for Server or Client development or integration into customer products ...

Moderator: uasdknet

Post Reply
Rolf Kistler
Jr. Member
Jr. Member
Posts: 4
Joined: 10 Sep 2020, 14:54

Custom alarm model

Post by Rolf Kistler »

I create a custom alarm model in C# code (new CreateObjectTypeSettings()...SuperTypeId=ObjectTypeIds.AlarmConditionType, CreateObjectTypeNode()
with additional variables (new CreateVariableSettings(),CreateVariable() ...

I have to create instances of my alarm model dynamically.
How do I instantiate my model and set values of the additional variables?
I had a look at DemoServer and ServerGettingStarted.Lesson06, but there existing condition/alarm models are used.

User avatar
Support Team
Hero Member
Hero Member
Posts: 3255
Joined: 18 Mar 2011, 15:09

Re: Custom alarm model

Post by Support Team »

Hi,

You can add your own fields to alarms by creating subclasses for existing alarm types. The new types are given a child for each new alarm field.

Now we have to differentiate whether the new types are already known at compile time or only become known at runtime, e.g. at server startup through configuration.

If the new types are already known at compile time, then we recommend modeling the new types with the UaModeler and generating code. The generated code can be used in the same way as in the Getting Started example.

https://documentation.unified-automation.com/uasdknet/4.1.0/html/L3ServerTutGSLess06.html
https://documentation.unified-automation.com/uamodeler/1.7.0/html/howto_structureddatatypeandevents.html

If the new type only becomes known through configuration, then the type nodes must be created in the code.

Code: Select all


private readonly AbsoluteName m_additionalFieldName = new AbsoluteName("AdditionalField", yourorganisation.BA.Namespaces.BA);
private NodeId m_alarmTypeId;

void CreateSubtype()
{
    var settings = new CreateObjectTypeSettings()
    {
        BrowseName = new QualifiedName("ReallyOffNormalAlarmType", DefaultNamespaceIndex),
        RequestedNodeId = new NodeId("ReallyOffNormalAlarmType", DefaultNamespaceIndex),
        ParentNodeId = ObjectTypeIds.OffNormalAlarmType,
        ReferenceTypeId = ReferenceTypeIds.HasSubtype,
    };
    var alarmTypeNode = CreateObjectTypeNode(Server.DefaultRequestContext, settings);
    m_alarmTypeId = alarmTypeNode.NodeId;

    var variableSettings = new CreateVariableSettings()
    {
        BrowseName = m_additionalFieldName.ToQualifiedName(Server.NamespaceUris),
        RequestedNodeId = new NodeId("AdditionalField", DefaultNamespaceIndex),
        AccessLevel = AccessLevels.CurrentRead,
        DataType = DataTypeIds.UInt32,
        ParentAsOwner = true,
        ModellingRuleId = ObjectIds.ModellingRule_Mandatory,
        ParentNodeId = alarmTypeNode.NodeId,
        ReferenceTypeId = ReferenceTypeIds.HasProperty,
        TypeDefinitionId = VariableTypeIds.PropertyType,
        ValueRank = ValueRanks.Scalar
    };
    CreateVariable(Server.DefaultRequestContext, variableSettings);
}
To fire the alarm, you can use the model class of the base type and add the new event field to the alarm with Set.

Code: Select all

OffNormalAlarmModel alarm = new OffNormalAlarmModel
{
    NodeId = alarmId,
    EventType = m_alarmTypeId,
    SourceNode = new NodeId(block.Name, InstanceNamespaceIndex),
    SourceName = block.Name,
    Severity = (ushort)EventSeverity.Low,
    ConditionName = "StateCondition",
    ConditionClassId = ObjectTypeIds.ProcessConditionClassType,
    ConditionClassName = BrowseNames.ProcessConditionClassType,
    Message = $"{block.Name} is off!"
};
alarm.ConditionChanged += (o, e) =>
{
    GenericEvent ev = e.CreateEvent(Server.FilterManager, true);
    ev.Set(AbsoluteName.ToString(m_additionalFieldName, Server.NamespaceUris), new Variant(42u));
    ReportEvent(alarm.SourceNode, ev);
};
When instantiating the alarm in the address space, the NodeId of the new type must be used as the TypeDefinitionId.
Best regards
Unified Automation Support Team

Post Reply