#include "custom_provider.h"
#include <uaserver_utilities.h>
#include "custom_provider_helper.h"
OPCUA_BEGIN_EXTERN_C
OpcUa_UInt16 g_uCustomProvider_NamespaceIndex = OpcUa_UInt16_Max;
Machine *g_pMyCustomMachine = OpcUa_Null;
OpcUa_Timer g_hSimulationTimer;
OpcUa_Boolean g_bMyCustomMachineSwitch;
OpcUa_Double g_bMyCustomMachineTemperature;
IFMETHODIMP(CustomProvider_Cleanup)(OpcUa_Void);
OpcUa_StatusCode CustomProvider_Subscription_Initialize();
OpcUa_StatusCode CustomProvider_Subscription_Cleanup();
OpcUa_StatusCode CustomProvider_CreateTemperatureSensorType(OpcUa_NodeId *a_pStartingNodeId,
OpcUa_ObjectType **a_ppTemperatureSensorType)
{
OpcUa_ObjectType *pNewSensorType = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_BaseNode *pBaseNode = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateTemperatureSensorType");
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppTemperatureSensorType);
*a_ppTemperatureSensorType = OpcUa_Null;
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_BaseObjectType;
a_pStartingNodeId->Identifier.Numeric++;
&pNewSensorType,
pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"TemperatureSensorType");
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
&pVariable,
(OpcUa_BaseNode*)pNewSensorType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
OpcUa_GotoErrorIfBad(uStatus);
*a_ppTemperatureSensorType = pNewSensorType;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_CreateMachineType(OpcUa_NodeId *a_pStartingNodeId,
OpcUa_ObjectType **a_ppMachineType,
OpcUa_ObjectType **a_ppTemperatureSensorType)
{
OpcUa_ObjectType *pNewMachineType = OpcUa_Null;
OpcUa_Object *pTemperatureSensor = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_BaseNode *pBaseNode = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateMachineType");
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppMachineType);
OpcUa_ReturnErrorIfArgumentNull(a_ppTemperatureSensorType);
*a_ppMachineType = OpcUa_Null;
*a_ppTemperatureSensorType = OpcUa_Null;
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
uStatus = CustomProvider_CreateTemperatureSensorType(a_pStartingNodeId, a_ppTemperatureSensorType);
OpcUa_GotoErrorIfBad(uStatus);
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_BaseObjectType;
a_pStartingNodeId->Identifier.Numeric++;
&pNewMachineType,
pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"MachineType");
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
&pVariable,
(OpcUa_BaseNode*)pNewMachineType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"HeaterSwitch");
OpcUa_GotoErrorIfBad(uStatus);
pValue->Datatype = OpcUaType_Boolean;
pValue->Value.Boolean = OpcUa_False;
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
OpcUa_GotoErrorIfBad(uStatus);
referenceNodeId.Identifier.Numeric = OpcUaId_HasComponent;
a_pStartingNodeId->Identifier.Numeric++;
(OpcUa_BaseNode **)&pTemperatureSensor,
(OpcUa_BaseNode*)pNewMachineType,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
"TemperatureSensor",
"TemperatureSensor",
"TemperatureSensor");
OpcUa_GotoErrorIfBad(uStatus);
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
&pVariable,
(OpcUa_BaseNode*)pTemperatureSensor,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
OpcUa_GotoErrorIfBad(uStatus);
*a_ppMachineType = pNewMachineType;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_CreateTemperatureSensor(OpcUa_StringA a_sSensorName,
OpcUa_BaseNode *a_pOwner,
OpcUa_NodeId *a_pTemperatureSensorTypeId,
OpcUa_NodeId *a_pStartingNodeId,
TemperatureSensor **a_ppNewTemperatureSensor)
{
TemperatureSensor *pNewSensor = OpcUa_Null;
OpcUa_Object *pObject = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateTemperatureSensor");
OpcUa_ReturnErrorIfArgumentNull(a_sSensorName);
OpcUa_ReturnErrorIfArgumentNull(a_pOwner);
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppNewTemperatureSensor);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
pNewSensor = (TemperatureSensor*)OpcUa_Alloc(sizeof(TemperatureSensor));
OpcUa_ReturnErrorIfAllocFailed(pNewSensor);
OpcUa_MemSet(pNewSensor, 0, sizeof(TemperatureSensor));
pNewSensor->Type = UserDataTemperature;
referenceNodeId.Identifier.Numeric = OpcUaId_HasComponent;
a_pStartingNodeId->Identifier.Numeric++;
(OpcUa_BaseNode **)&pObject,
a_pOwner,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
a_pTemperatureSensorTypeId,
a_sSensorName,
a_sSensorName,
a_sSensorName);
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
&pVariable,
(OpcUa_BaseNode*)pObject,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
*a_ppNewTemperatureSensor = pNewSensor;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode CustomProvider_CreateMachine(OpcUa_StringA a_sMachineName,
OpcUa_StringA a_sTemperatureSensorName,
OpcUa_BaseNode *a_pOwner,
OpcUa_NodeId *a_pMachineTypeId,
OpcUa_NodeId *a_pTemperatureSensorTypeId,
OpcUa_NodeId *a_pStartingNodeId,
Machine **a_ppNewMachine)
{
Machine *pNewMachine = OpcUa_Null;
MachineSwitch *pNewHeaterSwitch = OpcUa_Null;
OpcUa_Object *pObject = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateMachine");
OpcUa_ReturnErrorIfArgumentNull(a_sMachineName);
OpcUa_ReturnErrorIfArgumentNull(a_sTemperatureSensorName);
OpcUa_ReturnErrorIfArgumentNull(a_pOwner);
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppNewMachine);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
pNewMachine = (Machine*)OpcUa_Alloc(sizeof(Machine));
OpcUa_ReturnErrorIfAllocFailed(pNewMachine);
OpcUa_MemSet(pNewMachine, 0, sizeof(Machine));
pNewMachine->Type = UserDataMachine;
referenceNodeId.Identifier.Numeric = OpcUaId_Organizes;
a_pStartingNodeId->Identifier.Numeric++;
(OpcUa_BaseNode **)&pObject,
a_pOwner,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
a_pMachineTypeId,
a_sMachineName,
a_sMachineName,
a_sMachineName);
OpcUa_GotoErrorIfBad(uStatus);
a_pStartingNodeId->Identifier.Numeric++;
&pVariable,
(OpcUa_BaseNode*)pObject,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"HeaterSwitch");
OpcUa_GotoErrorIfBad(uStatus);
pValue->Datatype = OpcUaType_Boolean;
pValue->Value.Boolean = OpcUa_False;
pNewHeaterSwitch = (MachineSwitch*)OpcUa_Alloc(sizeof(MachineSwitch));
OpcUa_ReturnErrorIfAllocFailed(pNewHeaterSwitch);
OpcUa_MemSet(pNewHeaterSwitch, 0, sizeof(MachineSwitch));
pNewHeaterSwitch->Type = UserDataMachineSwitch;
pNewMachine->pHeaterSwitch = pNewHeaterSwitch;
uStatus = CustomProvider_CreateTemperatureSensor(a_sTemperatureSensorName,
(OpcUa_BaseNode*)pObject,
a_pTemperatureSensorTypeId,
a_pStartingNodeId,
&pNewMachine->pTemperatureSensor);
OpcUa_GotoErrorIfBad(uStatus);
*a_ppNewMachine = pNewMachine;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OpcUa_Void CustomProvider_DeleteMachine(Machine **a_ppMachine)
{
if (a_ppMachine == OpcUa_Null ||
*a_ppMachine == OpcUa_Null)
{
return;
}
OpcUa_Free((*a_ppMachine)->pHeaterSwitch);
(*a_ppMachine)->pHeaterSwitch = OpcUa_Null;
OpcUa_Free((*a_ppMachine)->pTemperatureSensor);
(*a_ppMachine)->pTemperatureSensor = OpcUa_Null;
OpcUa_Free(*a_ppMachine);
*a_ppMachine = OpcUa_Null;
}
OpcUa_StatusCode CustomProvider_CreateAddressSpace()
{
OpcUa_UInt16 uNsIdx = g_uCustomProvider_NamespaceIndex;
OpcUa_Folder *pCustomProvider = OpcUa_Null;
OpcUa_Folder *pFolder = OpcUa_Null;
OpcUa_ObjectType *pMachineType = OpcUa_Null;
OpcUa_ObjectType *pTemperatureSensorType = OpcUa_Null;
OpcUa_NodeId nodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateAddressSpace");
OpcUa_NodeId_Initialize(&nodeId);
pBaseNode_DefaultValues->MinimumSamplingInterval = 50.0;
pBaseNode_DefaultValues->AccessLevel = OpcUa_AccessLevels_CurrentReadOrWrite;
#if UASERVER_SUPPORT_AUTHORIZATION == OPCUA_CONFIG_NO
pBaseNode_DefaultValues->UserAccessLevel = OpcUa_AccessLevels_CurrentReadOrWrite;
#endif
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ObjectsFolder;
nodeId.NamespaceIndex = uNsIdx;
nodeId.Identifier.Numeric = 1;
uStatus = CustomProvider_CreateMachineType(&nodeId, &pMachineType, &pTemperatureSensorType);
OpcUa_GotoErrorIfBad(uStatus);
nodeId.Identifier.Numeric++;
&pCustomProvider,
(OpcUa_BaseNode*)pFolder,
nodeId.Identifier.Numeric,
uNsIdx,
"Custom Provider");
OpcUa_GotoErrorIfBad(uStatus);
uStatus = CustomProvider_CreateMachine("MyCustomMachine",
"MyCustomTemperatureSensor",
(OpcUa_BaseNode*)pCustomProvider,
&nodeId,
&g_pMyCustomMachine);
OpcUa_GotoErrorIfBad(uStatus);
g_pMyCustomMachine->pHeaterSwitch->pValue = &g_bMyCustomMachineSwitch;
g_pMyCustomMachine->pTemperatureSensor->pValue = &g_bMyCustomMachineTemperature;
g_bMyCustomMachineSwitch = OpcUa_False;
g_bMyCustomMachineTemperature = 25.0;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
IFMETHODIMP(CustomProvider_SimulationTimerCallback)(OpcUa_Void *a_pvCallbackData,
OpcUa_Timer a_hTimer,
OpcUa_UInt32 a_msecElapsed)
{
OpcUa_ReferenceParameter(a_pvCallbackData);
OpcUa_ReferenceParameter(a_hTimer);
OpcUa_ReferenceParameter(a_msecElapsed);
if (g_bMyCustomMachineSwitch == OpcUa_False &&
g_bMyCustomMachineTemperature > -30.0)
{
g_bMyCustomMachineTemperature -= 0.5;
}
else if (g_bMyCustomMachineSwitch == OpcUa_True &&
g_bMyCustomMachineTemperature < 150.0)
{
g_bMyCustomMachineTemperature += 0.5;
}
return OpcUa_Good;
}
{
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_Initialize");
printf("Initialize CustomProvider ...\n");
g_pCustomProvider = a_pProvider;
g_pCustomProviderInterface = a_pProviderInterface;
a_pProviderInterface->Cleanup = CustomProvider_Cleanup;
a_pProviderInterface->ReadAsync = CustomProvider_ReadAsync;
a_pProviderInterface->WriteAsync = CustomProvider_WriteAsync;
a_pProviderInterface->BrowseAsync = CustomProvider_BrowseAsync;
a_pProviderInterface->TranslateAsync = CustomProvider_TranslateAsync;
a_pProviderInterface->AddItem = CustomProvider_AddItem;
a_pProviderInterface->RemoveItem = CustomProvider_RemoveItem;
a_pProviderInterface->Subscribe = CustomProvider_Subscribe;
&g_uCustomProvider_NamespaceIndex,
"http://www.unifiedautomation.com/customprovider/",
1009);
OpcUa_ReturnErrorIfBad(uStatus);
uStatus = CustomProvider_CreateAddressSpace();
OpcUa_ReturnErrorIfBad(uStatus);
uStatus = CustomProvider_Subscription_Initialize();
OpcUa_ReturnErrorIfBad(uStatus);
OpcUa_Timer_Create(&g_hSimulationTimer,
250,
CustomProvider_SimulationTimerCallback,
OpcUa_Null,
OpcUa_Null);
printf("Initialize CustomProvider DONE!\n");
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
IFMETHODIMP(CustomProvider_Cleanup)()
{
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_Cleanup");
printf("Cleanup CustomProvider ...\n");
OpcUa_Timer_Delete(&g_hSimulationTimer);
CustomProvider_Subscription_Cleanup();
CustomProvider_DeleteMachine(&g_pMyCustomMachine);
printf("Cleanup CustomProvider DONE!\n");
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
#if BUILD_SHARED_LIBS
CUSTOMPROVIDER_API(OpcUa_StatusCode) InitializeProvider(
UaServer_Provider* pProvider,
{
return CustomProvider_Initialize(pProvider, pProviderInterface);
}
#endif
OPCUA_END_EXTERN_C