ANSI C Based OPC UA Client/Server SDK  1.9.0.430
custom_provider_events.c
/*****************************************************************************
* *
* Copyright (c) 2006-2019 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.7 *
* *
* Unless explicitly acquired and licensed from Licensor under another *
* license, the contents of this file are subject to the Software License *
* Agreement ("SLA") Version 2.7, or subsequent versions as allowed by the *
* SLA, and You may not copy or use this file in either source code or *
* executable form, except in compliance with the terms and conditions of *
* the SLA. *
* *
* All software distributed under the SLA is provided strictly on an "AS *
* IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
* AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
* PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific *
* language governing rights and limitations under the SLA. *
* *
* The complete license agreement can be found here: *
* http://unifiedautomation.com/License/SLA/2.7/ *
* *
* Project: Unified Automation ANSI C based OPC UA Server SDK *
* *
*****************************************************************************/
#include <uaserver_config.h>
#include <opcua_identifiers.h>
#include <opcua_memory.h>
#include <opcua_string.h>
#include <opcua_errorhandling.h>
#include <uaserver_events.h>
#include <uaserver_utilities.h>
#include "custom_provider_helper.h"
OPCUA_BEGIN_EXTERN_C
OpcUa_UInt32 g_HeaterSwitchedEventTypeId;
OpcUa_Int32 g_HeaterSwitchedEventType_IndexSwitchPosition;
OpcUa_Int32 g_HeaterSwitchedEventType_IndexCurrentTemperature;
OpcUa_UInt32 g_TemperatureAlarmTypeId;
OpcUa_Int32 g_TemperatureAlarmType_IndexSwitchPosition;
OpcUa_Int32 g_TemperatureAlarmType_IndexCurrentTemperature;
OpcUa_StatusCode CustomProvider_RegisterEventTypes(OpcUa_NodeId *a_pStartingNodeId)
{
OpcUa_NodeId parentEventTypeId, nodeId;
UaServer_EventField eventField;
UaServer_AddressSpace *pAddressSpace = &g_pCustomProvider->AddressSpace;
UaServer_AddressSpace *pServerAddressSpace = OpcUa_Null;
OpcUa_BaseNode *pBaseNode = OpcUa_Null;
OpcUa_ObjectType *pEventType = OpcUa_Null;
OpcUa_Property *pProperty = OpcUa_Null;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_RegisterEventTypes");
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_NodeId_Initialize(&parentEventTypeId);
OpcUa_NodeId_Initialize(&nodeId);
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
/* HeaterSwitchedEventType */
a_pStartingNodeId->Identifier.Numeric++;
g_HeaterSwitchedEventTypeId = a_pStartingNodeId->Identifier.Numeric;
parentEventTypeId.NamespaceIndex = 0;
parentEventTypeId.Identifier.Numeric = OpcUaId_BaseEventType;
/* Register HeaterSwitchedEventType as new event type in the SDK */
uStatus = UaServer_Events_RegisterEventType(a_pStartingNodeId, &parentEventTypeId);
OpcUa_GotoErrorIfBad(uStatus);
/* Register the event fields of HeaterSwitchedEventType in the SDK */
/* SwitchPosition */
eventField.BrowsePath.Elements = (OpcUa_QualifiedName*)OpcUa_Alloc(sizeof(OpcUa_QualifiedName));
OpcUa_GotoErrorIfAllocFailed(eventField.BrowsePath.Elements);
eventField.BrowsePath.NoOfElements = 1;
OpcUa_QualifiedName_Initialize(&eventField.BrowsePath.Elements[0]);
eventField.BrowsePath.Elements[0].NamespaceIndex = g_uCustomProvider_NamespaceIndex;
OpcUa_String_StrnCpy(&eventField.BrowsePath.Elements[0].Name,
OpcUa_String_FromCString("SwitchPosition"),
OPCUA_STRING_LENDONTCARE);
g_HeaterSwitchedEventType_IndexSwitchPosition = UaServer_Events_RegisterEventField(a_pStartingNodeId,
&eventField);
/* CurrentTemperature */
OpcUa_QualifiedName_Clear(&eventField.BrowsePath.Elements[0]);
eventField.BrowsePath.Elements[0].NamespaceIndex = g_uCustomProvider_NamespaceIndex;
OpcUa_String_StrnCpy(&eventField.BrowsePath.Elements[0].Name,
OpcUa_String_FromCString("CurrentTemperature"),
OPCUA_STRING_LENDONTCARE);
g_HeaterSwitchedEventType_IndexCurrentTemperature = UaServer_Events_RegisterEventField(a_pStartingNodeId,
&eventField);
/* Create nodes for HeaterSwitchedEventType in the address space */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_BaseEventType;
UaServer_GetNode(pServerAddressSpace, &nodeId, &pBaseNode);
uStatus = UaServer_CreateObjectType(pAddressSpace,
&pEventType,
(OpcUa_BaseNode*)pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"HeaterSwitchedEventType");
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateProperty(pAddressSpace,
&pProperty,
(OpcUa_BaseNode*)pEventType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"SwitchPosition");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pProperty, OpcUaId_Boolean, 0);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateProperty(pAddressSpace,
&pProperty,
(OpcUa_BaseNode*)pEventType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"CurrentTemperature");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pProperty, OpcUaId_Double, 0);
/* TemperatureAlarmType */
a_pStartingNodeId->Identifier.Numeric++;
g_TemperatureAlarmTypeId = a_pStartingNodeId->Identifier.Numeric;
parentEventTypeId.NamespaceIndex = 0;
parentEventTypeId.Identifier.Numeric = OpcUaId_LimitAlarmType;
/* Register TemperatureAlarmType as new event type in the SDK */
uStatus = UaServer_Events_RegisterEventType(a_pStartingNodeId, &parentEventTypeId);
OpcUa_GotoErrorIfBad(uStatus);
/* Register the event fields of TemperatureAlarmType in the SDK */
/* SwitchPosition */
OpcUa_QualifiedName_Clear(&eventField.BrowsePath.Elements[0]);
eventField.BrowsePath.Elements[0].NamespaceIndex = g_uCustomProvider_NamespaceIndex;
OpcUa_String_StrnCpy(&eventField.BrowsePath.Elements[0].Name,
OpcUa_String_FromCString("SwitchPosition"),
OPCUA_STRING_LENDONTCARE);
g_TemperatureAlarmType_IndexSwitchPosition = UaServer_Events_RegisterEventField(a_pStartingNodeId,
&eventField);
/* CurrentTemperature */
OpcUa_QualifiedName_Clear(&eventField.BrowsePath.Elements[0]);
eventField.BrowsePath.Elements[0].NamespaceIndex = g_uCustomProvider_NamespaceIndex;
OpcUa_String_StrnCpy(&eventField.BrowsePath.Elements[0].Name,
OpcUa_String_FromCString("CurrentTemperature"),
OPCUA_STRING_LENDONTCARE);
g_TemperatureAlarmType_IndexCurrentTemperature = UaServer_Events_RegisterEventField(a_pStartingNodeId,
&eventField);
/* Create nodes for TemperatureAlarmType in the address space */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_LimitAlarmType;
UaServer_GetNode(pServerAddressSpace, &nodeId, &pBaseNode);
uStatus = UaServer_CreateObjectType(pAddressSpace,
&pEventType,
(OpcUa_BaseNode*)pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"TemperatureAlarmType");
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateProperty(pAddressSpace,
&pProperty,
(OpcUa_BaseNode*)pEventType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"SwitchPosition");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pProperty, OpcUaId_Boolean, 0);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateProperty(pAddressSpace,
&pProperty,
(OpcUa_BaseNode*)pEventType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"CurrentTemperature");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pProperty, OpcUaId_Double, 0);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_UnregisterEventTypes()
{
OpcUa_NodeId eventTypeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_UnregisterEventTypes");
OpcUa_NodeId_Initialize(&eventTypeId);
/* HeaterSwitchedEventType */
eventTypeId.NamespaceIndex = g_uCustomProvider_NamespaceIndex;
eventTypeId.Identifier.Numeric = g_HeaterSwitchedEventTypeId;
uStatus = UaServer_Events_UnregisterEventType(&eventTypeId);
OpcUa_GotoErrorIfBad(uStatus);
/* TemperatureAlarmType */
eventTypeId.NamespaceIndex = g_uCustomProvider_NamespaceIndex;
eventTypeId.Identifier.Numeric = g_TemperatureAlarmTypeId;
uStatus = UaServer_Events_UnregisterEventType(&eventTypeId);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_FireHeaterSwitchedEvent(Machine *a_pMachine)
{
UaServer_Event *pEvent = OpcUa_Null;
OpcUa_NodeId eventTypeId;
OpcUa_ByteString bsEventId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_FireHeaterSwitchedEvent");
OpcUa_ReturnErrorIfArgumentNull(a_pMachine);
OpcUa_NodeId_Initialize(&eventTypeId);
OpcUa_ByteString_Initialize(&bsEventId);
OpcUa_Variant_Initialize(&value);
eventTypeId.NamespaceIndex = g_uCustomProvider_NamespaceIndex;
eventTypeId.Identifier.Numeric = g_HeaterSwitchedEventTypeId;
pEvent = UaServer_Events_CreateEvent(&eventTypeId);
/* Set event fields of BaseEventType */
UaServer_Events_SetEventId(pEvent, &bsEventId);
UaServer_Events_SetEventType(pEvent, &eventTypeId);
UaServer_Events_SetSourceNode(pEvent, &a_pMachine->nodeId);
UaServer_Events_SetSourceName(pEvent, OpcUa_String_GetRawString(&a_pMachine->sMachineName));
UaServer_Events_SetTime(pEvent, OpcUa_DateTime_UtcNow());
UaServer_Events_SetReceiveTime(pEvent, OpcUa_DateTime_UtcNow());
if (*a_pMachine->pHeaterSwitch->pValue == OpcUa_False)
{
UaServer_Events_SetMessage(pEvent, "en", "The switch was set to OFF");
}
else
{
UaServer_Events_SetMessage(pEvent, "en", "The switch was set to ON");
}
/* Set custom event fields */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = *a_pMachine->pHeaterSwitch->pValue;
UaServer_Events_SetEventField(pEvent, g_HeaterSwitchedEventType_IndexSwitchPosition, &value);
value.Datatype = OpcUaType_Double;
value.Value.Double = *a_pMachine->pTemperatureSensor->pValue;
UaServer_Events_SetEventField(pEvent, g_HeaterSwitchedEventType_IndexCurrentTemperature, &value);
uStatus = UaServer_Events_FireEvent(pEvent);
OpcUa_ByteString_Clear(&bsEventId);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_InitializeTemperatureAlarm(Machine *a_pMachine,
UaServer_Event *a_pTemperatureAlarm,
OpcUa_NodeId *a_pStartingNodeId)
{
OpcUa_NodeId eventTypeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_InitializeTemperatureAlarm");
OpcUa_ReturnErrorIfArgumentNull(a_pMachine);
OpcUa_ReturnErrorIfArgumentNull(a_pTemperatureAlarm);
OpcUa_NodeId_Initialize(&eventTypeId);
OpcUa_Variant_Initialize(&value);
eventTypeId.NamespaceIndex = g_uCustomProvider_NamespaceIndex;
eventTypeId.Identifier.Numeric = g_TemperatureAlarmTypeId;
/* Set event fields of BaseEventType */
UaServer_Events_SetEventType(a_pTemperatureAlarm, &eventTypeId);
UaServer_Events_SetSourceNode(a_pTemperatureAlarm, &a_pMachine->nodeId);
UaServer_Events_SetSourceName(a_pTemperatureAlarm, OpcUa_String_GetRawString(&a_pMachine->sMachineName));
UaServer_Events_SetSeverity(a_pTemperatureAlarm, 500);
/* Set event fields of ConditionType */
value.Datatype = OpcUaType_String;
OpcUa_String_Initialize(&value.Value.String);
OpcUa_String_StrnCpy(&value.Value.String,
OpcUa_String_FromCString("TemperatureAlarm"),
OPCUA_STRING_LENDONTCARE);
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_ConditionName, &value);
OpcUa_String_Clear(&value.Value.String);
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_EnabledState_Id, &value);
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_Retain, &value);
a_pStartingNodeId->Identifier.Numeric++;
value.Datatype = OpcUaType_NodeId;
value.Value.NodeId = (OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_NodeId_Initialize(value.Value.NodeId);
OpcUa_NodeId_CopyTo(a_pStartingNodeId, value.Value.NodeId);
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_ConditionNodeId, &value);
OpcUa_NodeId_Clear(value.Value.NodeId);
OpcUa_Free(value.Value.NodeId);
/* Set event fields of AcknowledgeableConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AcknowledgeableConditionTypeField_AckedState_Id, &value);
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AcknowledgeableConditionTypeField_ConfirmedState_Id, &value);
/* Set event fields of AlarmConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AlarmConditionTypeField_ActiveState_Id, &value);
/* Set event fields of LimitAlarmType */
value.Datatype = OpcUaType_Double;
value.Value.Double = 100.0;
UaServer_Events_SetEventField(a_pTemperatureAlarm, LimitAlarmTypeField_HighLimit, &value);
value.Datatype = OpcUaType_Double;
value.Value.Double = 0.0;
UaServer_Events_SetEventField(a_pTemperatureAlarm, LimitAlarmTypeField_LowLimit, &value);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_FireTemperatureAlarm(Machine *a_pMachine, UaServer_Event *a_pTemperatureAlarm)
{
OpcUa_NodeId eventTypeId;
OpcUa_ByteString bsEventId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_FireTemperatureAlarm");
OpcUa_ReturnErrorIfArgumentNull(a_pMachine);
OpcUa_ReturnErrorIfArgumentNull(a_pTemperatureAlarm);
OpcUa_NodeId_Initialize(&eventTypeId);
OpcUa_ByteString_Initialize(&bsEventId);
OpcUa_Variant_Initialize(&value);
/* Set event fields of BaseEventType */
UaServer_Events_SetEventId(a_pTemperatureAlarm, &bsEventId);
UaServer_Events_SetTime(a_pTemperatureAlarm, OpcUa_DateTime_UtcNow());
UaServer_Events_SetReceiveTime(a_pTemperatureAlarm, OpcUa_DateTime_UtcNow());
if (*a_pMachine->pTemperatureSensor->pValue >= 100.0 || *a_pMachine->pTemperatureSensor->pValue <= 0.0)
{
if (*a_pMachine->pTemperatureSensor->pValue >= 100.0)
{
UaServer_Events_SetMessage(a_pTemperatureAlarm, "en", "Temperature above the limit!");
}
else if (*a_pMachine->pTemperatureSensor->pValue <= 0.0)
{
UaServer_Events_SetMessage(a_pTemperatureAlarm, "en", "Temperature below the limit!");
}
/* Set event fields of ConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_True;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_EnabledState_Id, &value);
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_True;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_Retain, &value);
/* Set event fields of AcknowledgeableConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AcknowledgeableConditionTypeField_AckedState_Id, &value);
/* Set event fields of AlarmConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_True;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AlarmConditionTypeField_ActiveState_Id, &value);
}
else
{
/* Set event fields of ConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_EnabledState_Id, &value);
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, ConditionTypeField_Retain, &value);
/* Set event fields of AcknowledgeableConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AcknowledgeableConditionTypeField_AckedState_Id, &value);
/* Set event fields of AlarmConditionType */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = OpcUa_False;
UaServer_Events_SetEventField(a_pTemperatureAlarm, AlarmConditionTypeField_ActiveState_Id, &value);
}
/* Set custom event fields */
value.Datatype = OpcUaType_Boolean;
value.Value.Boolean = *a_pMachine->pHeaterSwitch->pValue;
UaServer_Events_SetEventField(a_pTemperatureAlarm, g_TemperatureAlarmType_IndexSwitchPosition, &value);
value.Datatype = OpcUaType_Double;
value.Value.Double = *a_pMachine->pTemperatureSensor->pValue;
UaServer_Events_SetEventField(a_pTemperatureAlarm, g_TemperatureAlarmType_IndexCurrentTemperature, &value);
uStatus = UaServer_Events_FireEvent(a_pTemperatureAlarm);
OpcUa_ByteString_Clear(&bsEventId);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OPCUA_END_EXTERN_C