Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Ostwald committed Apr 7, 2021
1 parent b6e53b9 commit 2360c7a
Show file tree
Hide file tree
Showing 10 changed files with 711 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## **Step 1 - Generating the Application**

At the end of the tutorial, you will have created a Data Access Client with access to an item of the supplied demo server. For the created item DataChanged callbacks will be received whenever its value changes.

This section describes how to generate an application by using the [Project Wizard](c2dd4578-aa68-4ba7-bf5b-4da879baaa29.htm) of the Softing OPC Toolkit V4.4x.

First, you need to create a new project by selecting the "Project Wizard" from the start menu folder "Programs | Softing OPC Toolkit V4.4x". The Application Assistant shown in the figure below opens. On the first page of the wizard select the Microsoft Windows operating system.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_OS.png)

Then select the used programming language which is C++ in this case.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_PL.png)

In the next page select the development environment. In this tutorial Microsoft Visual Studio 2010 will be used.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_DE.png)

Type the name of the OPC client project and the location where it should be created. Note that the directory path must be a valid one. In case the directory path doesn't exist, a message error will block you from going further.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_L.png)

Next the OPC specification must be chosen. We want to create a Data Access client so please choose the OPC Data Access specification.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_ClientDA_Step5.png)

Choose the application type as being Console.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_ClientDA_Step6.png)

Choose the compiler settings.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_ClientDA_Step7.png)

For the tutorial, we do not want the wizard to generate a client that receives DataChanged callbacks. In the next step, we will see how to receive these callbacks for the already created item.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Client_AE_Step8.PNG)

Review all the settings using the last page and then press **Finish**.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Client_AE_Step9.PNG)

After the Project Wizard has generated the source code, you have a compilable, executable OPC Client. However, it does not do anything yet because this is what we are going to do in next step.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## **Step 2 - Customizing the Application**

The next steps will explain the structure of the supplied project and will tell you how to extend its functionality.

This part describes how to add application-specific implementations.

### Microsoft Visual Studio 2003, 2005, 2008 and 2010

In the installed tutorial, the paths for the Include and Library files have been set according to the directory structure of the installation. If you have changed this structure or want to generate the tutorial in a different directory, you have to change the settings.

You will find the corresponding forms in the figures below.

Please make sure that you choose "All configurations" when setting the directories for the header files. You will reach the forms via the menu item Project->Properties.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/SettingsVS2010_C%2B%2B.png)

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/SettingsVS2010_Linker.png)

### Brief explanation on the generated classes

The generated project contains 4 classes: **MyDaSession**, **MyDaSubscription**, **MyDaItem** and **OpcClient**. The first three classes are defined only using a header file and for the last one a header and a source file exists. The name of the header and source files coincide with the class name.

The first three classes represent OPC objects: session, subscription and item and can be extended to add extra functionality to the generated project.

The **OpcClient** class contains a small number of methods that are needed to create a functional OPC client. It has methods for initializing (**initialize**) and terminating (**terminate**) the application, tracing the application (**trace**), processing CommandLine (**processCommandLine**) and setting the service name (**setServiceName**) that is used when the project needs to be run as a service. The other methods are used for creating and initializing OPC objects (**initializeDaObjects**) and for reading the value of a previously created item.(**readItem**)

When running the project, an instance of the **OpcClient** class is created and then the application is initialized. You can see this below:

```
//create the OpcClient instance
createOpcClient();
OpcClient* pClient = getOpcClient();
if(!SUCCEEDED(pClient->initialize()))
{
pClient->terminate();
destroyOpcClient();
CloseHandle(g_endEvent);
return 1;
}
```

After the application was succesfully initialized its time to create the OPC objects. This is done by calling the **initializeDaObjects** method. It creates a session, a subscription and an item and then connects all these objects.

In this moment operations on the created objects can be performed. e.g reading the item's value, receiving DataChanged callbacks...

How to do this you can see in the next step.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
## **Step 3 - Extending the Application**

This step will explain how to implement extra functionality to the generated project.

First let's see how the **readItem** method can be used to read the item's value. Go to **Console.cpp** file and search the **_tmain** function. Here the OPC client is initialized using the methods from the OpcClient class. After initializing the OPC objects, the **readItem** method can be used to read an item's value.

Find the while cycle and replace the // TODO: place your cyclic code here line with the call of the **readItem** method. Also change the wait time from 100 to 1000 ms.

Before you make any change you should have this:

```
while (!end)
{
waitRet = WaitForSingleObject(g_endEvent, waitTime);
waitTime = 100;
if (waitRet == WAIT_OBJECT_0)
{
end = TRUE;
}
else
{
// TODO: place your cyclic code here
} // end if...else
} // end while
```

After making the changes you should have this:

```
while (!end)
{
waitRet = WaitForSingleObject(g_endEvent, waitTime);
waitTime = 1000; // was previously 100
if (waitRet == WAIT_OBJECT_0)
{
end = TRUE;
}
else
{
tstring value = pClient->readItem();
_tprintf("%s",value.c_str());
} // end if...else
} // end while
```

You can compile and link the files. If you install your project on a PC system be aware that the corresponding Toolkit libraries (OTB*.dll, TBCVS2010*.dll) are beside your application (installed in the same directory) or can be found by the system's PATH variable.

When running the program, you can see that a message is displayed on the console every 1000 ms containing the item value together with its quality and timestamp.

### Note
```
If you use the [Project Wizard](c2dd4578-aa68-4ba7-bf5b-4da879baaa29.htm) and you choose to add simulation values you will have the same functionality except
that another thread will be created with the purpose of calling the **readItem** method every second. The read value
will be written in a file instead of being displayed on the console.
```

You can go further and change the project so that DataChanged callbacks are received. For this, MyDaSubscription class must be changed by adding an extra method: **handleDataChanged**. Using this method, the client will receive DataChanged callbacks for the items added to the existing subscription if their value changes. The received items' values will be displayed on the console together with their quality and timestamp.

Add the following code in file where MyDaSubscription class is defined:

```
// MyDaSubscription.h
void handleDataChanged(
const std::vector<SoftingOPCToolboxClient::DaItem*>& items,
const std::vector<ValueQT*>& values,
const std::vector<long>& results)
{
unsigned long i;
size_t count = items.size();
_tprintf(_T("\n%s - Data changed\n"), _T("Subscription"));
for (i = 0; i < count; i++)
{
_tprintf(_T("%-23.23s - %s\n"), items[i]->getId().c_str(),values[i]->toString().c_str());
} // end for
}
```
Before running the project please insert the following line in the MyDaSubscription.h file:

#include "Da\ClientDaItem.h"

below the already existing line:

#include "Da\ClientDaSubscription.h"

Change the call of **m_daSession->connect(...)** in the long OpcClient::initializeDaObjects() function to use 2 times TRUE:

```
long OpcClient::initializeDaObjects(){
// ...
long connectResult = m_daSession->connect(TRUE, TRUE, &executionOptions);
// ...
} // end initializeDaObjects
```

You can compile and run the project. Now you will have 2 types of messages on the screen: one saying that the item read was succesful and one saying that a DataChanged callback was received. Each message contain the current value of the "math.sin" item.

To stop the client from running please press **CTRL + C** in the console window.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## **Step 1 - Generating the Application**

At the end of the tutorial, you will have created an Alarms and Events Server with an event in the event space and an event source which can initiate simple events.

This section describes how to generate an application by using the [Project Wizard](c2dd4578-aa68-4ba7-bf5b-4da879baaa29.htm) of the Softing OPC Toolkit V4.4x.

First, you need to create a new project by selecting the "Project Wizard" from the start menu folder "Programs | Softing OPC Toolkit V4.4x". The Application Assistant shown in the figure below opens. On the first page of the wizard select the Microsoft Windows operating system.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_OS.png)

Then select the used programming language which is C++ in this case.


![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_PL.png)

In the next page select the development environment. In this tutorial Microsoft Visual Studio 2010 will be used.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_DE.png)

Type the name of the OPC server project and the location where it should be created. Note that the directory path must be a valid one. In case the directory path doesn't exist, a message error will block you from going further.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_L.png)

Next the OPC specification must be chosen. We want to create an Alarms and Events Server so please choose the OPC Alarms & Events specification.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Server_AE_Step5.PNG)

Choose the application type as being Console.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Server_AE_Step6.PNG)

Choose the compiler settings.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Server_AE_Step7.PNG)

For the tutorial, we do not want the wizard to generate a server that simulates events. In the next steps, we will see how to generate these events.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Server_AE_Step8.PNG)

Review all the settings using the last page and then press **Finish**.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/OPCWizard_Server_AE_Step9.PNG)

After the Project Wizard has generated the source code, you have a compilable, executable OPC Server. In the next steps we are going to see how to create area and source spaces and how to generate events.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## **Step 2 - Customizing the Application**

The next steps will explain the structure of the supplied project and will tell you how to extend its functionality.

This part describes how to add application-specific implementations.

### Microsoft Visual Studio 2003, 2005, 2008 and 2010

In the installed tutorial, the paths for the Include and Library files have been set according to the directory structure of the installation. If you have changed this structure or want to generate the tutorial in a different directory, you have to change the settings.

You will find the corresponding forms in the figures below.

Please make sure that you choose "All configurations" when setting the directories for the header files. You will reach the forms via the menu item **Project->Properties**.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/SettingsVS2010_C%2B%2B.png)

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/SettingsVS2010_Linker.png)


### Brief explanation on the generated classes

The generated project contains 3 classes: **MyCreator**, **MyAeAddressSpaceElement** and **OpcServer**. The first two classes are defined only using a header file and for the last one a header and a source file exists. The name of the header and source files coincide with the class name.

**MyCreator** class is used to create OPC server specific objects and **MyAeAddressSpaceElement** class is used for creating the objects that will form the server's area space.

The **OpcServer** class contains a small number of methods that are needed to create a functional OPC server. It has methods for initializing (**initialize**), preparing (**prepare**), starting (**start**), stopping (**stop**) and terminating (**terminate**) the server application. The other methods are for tracing the server application (**trace**), processing CommandLine (**processCommandLine**) and setting the service name (**setServiceName**) that is used when the project needs to be run as a service. Three other methods exist: one for building the area space (**buildNameSpace**), one for building the event space (**buildEventCategories**) and one that fires generated events (**fireSimulationEvents**).

When running the project, an instance of the **OpcServer** class is created and then the application is initialized. You can see this below:

```
// create and initialize the OpcServer instance
createOpcServer();
OpcServer* pServer = getOpcServer();
pServer->initialize();
```
After the application was succesfully initialized its time to prepare the application and then register the current server:

```
// provide the server with the proper custom creator
MyCreator creator;
if (!SUCCEEDED(pServer->prepare(&creator)))
{
pServer->terminate();
destroyOpcServer();
CloseHandle(g_endEvent);
return 1;
}
// handle the command line arguments (register/unregister, etc)
tstring commandLine(GetCommandLine());
result = pServer->processCommandLine(commandLine);
```
If everything is successful then the server application is started. In this step building the area space and event space is skipped. The next step will show how to build them.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## **Step 3 - Structure of the Event Space and Area Space**

This section describes the structure of the object trees which are used by the OPC Toolkit to process the OPC Client queries.

The OPC Server supports the event category "SimulationCategory" with one attribute called "SimulationAttribute". Events of this category are initiated by the event source "SimulationElement" of the event space. The following methods generated by the wizard create the two object trees.

```
// Creates the Area Space
long OpcServer::buildAddressSpace(void)
{
MyCreator* creator = (MyCreator*)getApp()->getCreator();
tstring aName; // AE
AeAddressSpaceRoot* aeRoot = getApp()->getAeAddressSpaceRoot();
AeAddressSpaceElement* aeElement = creator->createAeAddressSpaceElement();
aName = tstring(_T("SimulationElement")); aeElement->setName(aName);
aeElement->setHasChildren(FALSE); aeRoot->addChild(aeElement);
return S_OK;
} // end buildAddressSpace
```
```
// Creates the Event Space
long OpcServer::buildEventCategories(void)
{
tstring categoryName(_T("SimulationCategory"));
m_simulationCategory = new AeCategory(EnumEventType_SIMPLE, CATEGORY_ID_SIMULATION, categoryName);
getApp()->addAeCategory(m_simulationCategory);
tstring attributeName(_T("SimulationAttribute"));
m_simulationCategory->addAttribute(ATTRIBUTE_ID_SIMULATION, attributeName, VT_UI2);
return S_OK;
} // end buildEventCategories
```

The methods that create the server's area space and source space exist and must be used. For this, go to the **_tmain** function and replace the following code:
```
// Start the OPC server's I/O internal mechanism
if (SUCCEEDED(pServer->start()))
{
// declare the namespaces built and the server ready for clients to connect
pServer->ready();
}
```

with this one:

```
// Start the OPC server's I/O internal mechanism
if (SUCCEEDED(pServer->start()))
{
// build the namespace
pServer->buildAddressSpace();
pServer->buildEventCategories();
// declare the namespaces built and the server ready for clients to connect
pServer->ready();
}
```
After you have compiled the server, you can access the server with an OPC Alarms and Events Client.

You can now browse the event space and area space of the OPC Server and receive the names of the created objects. The figure below shows the two object trees of the server in the Softing OPC Demo Client.

![OPC-Classic-SDK](https://github.com/SoftingIndustrial/OPC-Classic-SDK/raw/main/documentation_pics/Area_Event_Space.png)
Loading

0 comments on commit 2360c7a

Please sign in to comment.