After installing CSWorks, many of you are tempted to connect it to your OPC data source. Here is a quick step-by-step guide how you can do that in five minutes.

In this example, I will assume we are dealing with Matrikon OPC Simulation Server - you can download it for free from Matrikon website. After installing Matrikon components, you can start tweaking CSWorks Pipes and Tank Demo so it uses data from Matrikon OPC Server.

Add new data source to LiveData Service configuration

Add a few lines to C:\Program Files\CSWorks\Framework\Server\CSWorks.Server.LiveDataService.exe.config:

    <opcLiveDataSources type="CSWorks.Server.DataSource.Opc.OpcLiveDataSource, CSWorks.Server.OpcProvider">
      ...
      <opcLiveDataSource name="OpcMatrikon" sampleBufferLength="16" hostName="localhost" progId="Matrikon.OPC.Simulation.1" subscriptionUpdateRate="250">
        <templates>
          <template name="matrikonBoolTag" type="Boolean" readPath="Random.Boolean" canWrite="true"/>
        </templates>
      </opcLiveDataSource>

    </opcLiveDataSources>


Restart LiveData Service so your changes take effect and the service connects to the data source.

Add new data source to LiveData Server topology configuration

Add one line to C:\Program Files\CSWorks\Demo\Web\LiveDataWebService\web.config:

  <liveDataTopology>
    <liveDataPartitions>
      <liveDataPartition name="partition1" primaryLiveDataServer="liveDataServer_1_primary" secondaryLiveDataServer="">
        <dataSources>
          ...
          <dataSource name="OpcMatrikon"/>
        </dataSources>
      </liveDataPartition>
    </liveDataPartitions>
  </liveDataTopology>


Now LiveData Web Service knows where to get data for OpcMatrikon data source.

Modify demo application

Run Microsoft Visual Studio and open Pipes and Tanks Demo project at C:\Program Files\CSWorks\Demo\Src\PipesAndTanksDemo\PipesAndTanksDemo.Sample.csproj. Let's make several additions to the Page.xaml file.

Add a new data item that gets data from the boolean tag configured for Matrikon OPC Server:

    <UserControl.Resources>
        ...
        <d:BoolDataItem x:Key="TestValve" Id="type in new guid here" DataSource="OpcMatrikon" TemplateName="matrikonBoolTag" Parameters=""/>
    </UserControl.Resources>



Add a few visual elements to the upper left corner of the screen and bind them to the new data item:

        <controls:TabControl...>
            <controls:TabItem Header="HMI Controls View">
                <Canvas>
                    ...
                    <Grid ...>
                          ...
                      </Grid.ColumnDefinitions>
                        <pipes:RightValve Grid.Row="0" Grid.Column="3" IsOpen="{Binding Value, Mode=OneWay, Source={StaticResource TestValve}}" OpenColor="Black" ClosedColor="Black" IsEnabled="False" Margin="-16,0,16,0"/>
                        <PipesAndTanksDemo:Wireframe Grid.Row="0" Grid.Column="3" Status="{Binding Status, Mode=OneWay, Source={StaticResource TestValve}}" Margin="-16,0,16,0"/>
                        <pipes:RightTWay Grid.Row="0" Grid.Column="2" IsFilled="{Binding Value, Mode=OneWay, Source={StaticResource TestValve}}" FillColor="Coral" Margin="-16,0,16,0"/>
                        <PipesAndTanksDemo:Wireframe Grid.Row="0" Grid.Column="2" Status="{Binding Status, Mode=OneWay, Source={StaticResource TestValve}}" Margin="-16,0,16,0"/>

                        ...


Now we have a valve and a t-way joint that supply some coral-colored liquid to Tank 1. Also, we have added a couple of Wireframe elements that will tell us if something is wrong with Matrikon boolean tag.

Time to tell DataManager that we have a new data item. Add a command to the Page_Loaded() handler in Page.xaml.cs:

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
          ...
          dataManager.DataItems.Add(Resources["TestValve"] as DataItem);


Do not forget to update the id of the datamanager in the Page.xaml, otherwise LiveData Service will keep using cached list of required data items and Matrikon tag value will never be returned:

        <d:DataManager x:Key="DataManager" Id="type in new guid here" />

We are done. Build client application and run it at http://localhost/CSWorksDemo/PipesAndTanksDemo.html (or click Start menu and choose All Programs -> CSWorks ->  Client Samples -> Pipes and Tanks Demo). The left upper corner of the screen will have some new visual elements - see screenshot.

Troubleshooting

Check names

Invalid configuration settings may prevent CSWorks LiveData Service from connecting to OPC servers. Make sure you have specified proper OPC data source attributes (opcLiveDataSource element in the config file):

  • hostName: must contain the name or the IP address of the computer running OPC server instance; if you specify host IP address, this will eliminate the need for the host name resolution, leaving less space for potential errors;
  • progId: must contain program id or guid of the OPC server; if you specify OPC server guid, this will eliminate the need to perform progid-to-guid mapping, leaving less space for potential errors.

Make sure you have specified correct read/write path(s) in template descriptions (see template elements in the data source definition) and template parameters (check your client application that supplies template parameters). If something is wrong, you will probably get an error from LiveData Service saying “Cannot add to OPC group”.

COM/DCOM security issues

In some cases, especially if you run OPC server on a separate computer, you may get security-related errors. Here is one of them: Data source <data source name>, cannot retrieve OPC server guid by program id <program id> on host <OPC server host name or IP address>.

When CSWorks LiveData service is trying to instantiate an OPC server, it calls .NET method Type.GetTypeFromProgID() method to get type information for this COM object. This method may fail for a number of reasons: improperly registered COM component, incorrect hostname or progId settings (see above), COM/DCOM security restrictions (see below) etc. Unfortunately, this piece of .NET/COM interop does not provide too much diagnostics info.

Another kind of message you may get is: Cannot create instance of OPC server <OPC server progid or guid> on machine <OPC server host name or IP address>, error Retrieving the COM class factory for remote component with CLSID <OPC server guid> from machine <OPC server host name or IP address> failed due to the following error: 80070005.

The error code 80070005 explicitly tells the reason for the failure: access to OPC server instance is denied. The following are the steps to troubleshoot COM/DCOM security issues.

Step one. Try connecting to the OPC server in question from the machine where LiveData Service is running using some simple OPC client software (Matrikon OPC Explorer is a good choice). If you fail to do that, investigate this issue using your usual DCOM troubleshooting routine. Here is a piece of advise though.

Checking “Launch and Activation” and “Access” permissions would probably be the first thing to check. In the case with Matrikon Simulation OPC Server, we did not have any issues with COM/DCOM security, mostly because Matrikon installer lets everyone access this OPC Server. You can verify it by running dcomcnfg tool on the OPC server machine and looking at Matrikon Simulation OPC Server configuration - it explicitly says that "Everyone" has "Launch and Activation" and "Access" permissions for this component, see screenshot. This cannot be considered safe practice, but makes casual user's life a bit easier.

Step two. After you have connected to the OPC server using OPC client software, try starting CSWorks LiveData Service again. You may keep getting the “access denied” error, regardless of the fact that OPC server may be already configured to be accessed by “Everyone”: “Everyone” may not include accounts based on remote machines. In our case, the problem is in the specific account CSWorks LiveData Service runs under – by default, it runs under “Network Service” Windows built-in account. Try running CSWorks LiveData Service under the account you were using on step one to run the OPC client, you probably did it using your personal account – local or domain-based. This should help in 99% of cases. After making sure that LiveData Service works, you will have to:

  • decide which account you want to use in the production environment (you probably don’t want to use your personal account for that);
  • give this account "Launch and Activation" and "Access" permissions for the OPC server;
  • configure CSWorks LiveData Service to run under this account.

64-bit implications

Please don’t expect 32-bit version of CSWorks LiveData Service to work with a 64-bit OPC server.

Desktop interaction issues

Some OPC servers may be implemented in a way they interact with the user: they may display some windows and/or add notification icons to the taskbar. Those OPC servers require special attention.

First, try to minimize OPC server desktop interaction. For example, Omron CX OPC Server software (that interacts with Windows desktop) has setting called “Start in Silent Mode” – turn it on.

Second, using dcomcnfg tool, make sure that the account CSWorks LiveData Service runs under (“Network Service”, “System”, or some non-built-in account) has ALL Launch and Access permissions for this OPC server component (do not trust the default settings, select "Customize" and check all permissions checkboxes for the given account explicitly).

Third, using dcomcnfg tool’s “Identity” tab, tell DCOM that "Launching" user should be used to run OPC server instance.

Remember: everytime you have issues connecting to OPC server, check CSWorks LiveData configuration settings spelling and COM/DCOM security as these two are by far the most common issues.