CSWorks: web-based industrial automation

Of CSWorks and software development

About resource hierarchy in web.config files

clock November 12, 2010 17:55 by author Sergey Sorokin


CSWorks stores resource hierarchy in web.config files, so:

  • LiveData Web Service can find LiveData Service instance that collects data from some specific data source;
  • Alarm Web Service can find Alarm Service that handles some specific alarm group;
  • History Reader Web Service can find database that holds historical data for a specific data point.


Let’s take History Reader Web Service for example. The following piece of web.config tells web service that data history for data point “7cc32718-0da0-42b3-ae55-0acbb3593671" (also known as "Tank1") is stored in the database “partition1”:

<historyTopology>
  <historyPartitions>

    <historyPartition name="partition1" primaryDbTarget="…" secondaryDbTarget="…">

      <areas>

        <area id="…" name="By Equipment/Location">

          <areas>

            <area id="…" name="Tanks">

              <areas>

                <area id="…" name="West Side">

                  <dataPoints>

                    <dataPoint id="{7cc32718-0da0-42b3-ae55-0acbb3593671}" description="Tank1"/>


One potential problem is that some solutions can record thousands of historical data points, and all of them must be referenced in a single web.config file, and by default, ASP.NET limits the size of web.config file by 256kb. Consider the following setup.


Run a script that generates 10,000 historical datapoint references (you can download it here) and insert them into <historyPartition name="partition1"…> node of the web.config of History Reader Web Service. Web.config now has size around 1mb (see screenshot below). Run any client application that uses this web service (CSWorks TrendDemo for example) and get a web service error that doesn’t leave any trace: no exceptions in ASP.Net worker process, no error in the Event Log.


Now tell ASP.NET that it should accept bigger web.config files. Create DWORD registry value HKLM\Software\Microsoft\InetStp\Configuration\MaxWebConfigFileSizeInKB and set its value to, say 1024kb (see screenshot below).


Now restart the client application and start accessing those 10,000 historical data points. The screenshot below shows:

  • registry editor with MaxWebConfigFileSizeInKB value;
  • web.config file size;
  • a fragment of web.config that references historical data points that belong to area “#0199”;
  • a fragment of CSWorks Trend Control that allows to choose any historical data point from area “#0199” and add it to the chart.


Click to enlarge


There are few other potential problems with large amount of data in web.config files. First, Silverlight Tree Control has problems with displaying more than a few thousand nodes simultaneously. Second, CSWorks History Reader Web Service handles data point hierarchy more efficiently if every area doesn’t contain more than a few hundred data points.


The recommendation is obvious: when planning historical data point areas hierarchy, do not put more than a few hundred data points in a single area, avoid “plain” hierarchies with thousands of data points in the same area. The script used in this demo (you can download it here) generates 200 areas each containing 50 historical data points.


This discussion also applies to LiveData and Alarm web services, although the problem of large web.config files is not that relevant for live data and alarming: only extremely large CSWorks solutions use more than thousand data sources and more than thousand alarm groups.



Error: LiveData Web Service is not available

clock July 22, 2010 02:41 by author Sergey Sorokin

The remote server returned an error: NotFound.

In some rare cases, after installing CSWorks and running Pipes and Tanks Demo, you can see the following error:



This means one simple thing: ASP.NET cannot run LiveData Web Service code. There can be different reasons for this. The first thing you should do in this case is to get as much additional error information as possible. Check application event log - it may give you some clues. Also, try to get LiveData Web Service definition from your browser at http://localhost/CSWorksDemo/LiveDataWebService/Service.asmx.

The browser will probably give you some more details about the error. Consider the following example.
 


The problem in this particular case is that ASP.NET cannot write temporary binary it compiles for a specific page or web service. There can be several root causes for that, for example: error in the ASP.NET installation, changing ASP.NET  worker process account without modifying temp folder privileges etc. There is a lot of information about this issue in the net, here are some good sources:

http://forums.asp.net/p/1060279/1520411.aspx
http://weblogs.asp.net/rchartier/archive/2006/01/05/434626.aspx

The idea is to give the account ASP.NET runs under, say NETWORK SERVICE, or LocalSystem, or "ASP.NET v4.0 Classic" account (depends on which account you are using, see your IIS Manager settings, Application Pools, "ASP.NET v4.0 Classic" pool properties) full access to all temporary folder it may use while compiling ASP.NET page or service. Those folders include:

c:\WINDOWS\Microsoft.NET\...\Temporary ASP.NET Files
c:\windows\temp

One would assume that ASP.NET setup (or aspnet_regiis command executed manually) should do that, but it looks like there is no 100% guarantee. Fixing folder access manually seems to be the best option. Unfortunately, there is nothing CSWorks installer can do here - it's ASP.NET setup problem.

The remote server returned an error: NotFound. (again)

Another scenario, same symptoms: LiveData Web Service is not available. The remote server returned an error: NotFound.

Navigating to http://localhost/CSWorksDemo/LiveDataWebService/Service.asmx gives the following error on a 64-bit system:

It sounds like ASP.NET worker process did not expect 64-bit code in the "bin" folder, so it cannot execute web service code. Let's open server manager and check Classic 4.0 Application pool settings:

Set "Enable 32-Bit Applications" to "False" and it solves the problem.


[HttpWebRequest_WebException_RemoteServer]

Another kind of error is common: LiveData Web Service is not available. [HttpWebRequest_WebException_RemoteServer]



This is usually caused by CSWorksDemo virtual directory ASP.NET version mismatch: CSWorks binaries require version 4.0, but the virtual directory uses another version. If you are using XP or 2003, right-click CSWorksDemo in IIS management console, select "Properties" and select ASP.NET 4.0 in the "ASP.NET" tab. If you are using 2008 or Windows 7, make sure you have selected "ASP.NET v4.0 Classic" application pool in CSWorksDemo virtual directory basic settings.

Another possible reason for this problem is: ASP.NET 4.0 web service extension (Windows 2003) or ASP.NET 4.0 ISAPI extension (2008,Vista, W7) is disabled. Please follow the instructions at
http://www.controlsystemworks.com/iis.html and enable correspondent extension manually.



CSWorks Tracing

clock March 17, 2010 18:46 by author Sergey Sorokin

When CSWorks is not working as expected the first thing to do is to see trace messages using a tool of your choice. This can be either some third-party tracing tool or a .NET trace listener.

Using tracing tools

I use DebugView by www.systeminternals.com. You can download the tool for free as part of their SysInternals Suite or as a standalone tool here.

No installation needed, just run dbgview.exe. Please keep in mind that Vista, Server 2008 and Windows 7 users should run this tool with elevated privileges, otherwise it won't be able to catch trace messages. When prompted for a filter, enter "CSWorks":



Make sure you have checked "Capture Global Win32" and "Capture Events" items of "Capture" menu:



Now you are ready to capture CSWorks trace messages. In most cases, this is all you have to do in order to find a problem and take action. The following screenshot shows the case when LiveData Service is denied access to an OPC server:



- when you see this, you may want to run dcomcnfg utility and adjust OPC server permission or run service manager and change the account LiveData Service runs under.

Using .NET trace listeners

You can avoid using third-party software - just turn on .NET TextWriterTraceListener, it is a part of the .NET framework. The only thing you have to do is to modify config file of the service or web service you are troubleshooting as follows:

<system.diagnostics>
  <trace autoflush="true" indentsize="2">
    <listeners>
      <remove name="Default" />
      <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\ProgramData\CSWorks\LiveDataServerLog.txt" />
    </listeners>
  </trace>
  <switches>
    <!-- Valid values are Error, Warning, Info, Verbose -->
    <add name="GeneralTraceSwitch" value="Warning" />
  </switches>
</system.diagnostics>

You can read more about .NET trace listeners at Microsoft web site.

Trace level

By default, all CSWorks server components send only error and warning messages, as displayed on the screenshot above. Sometimes this is not enough and you may want to see more details. Then you should increase tracing verbosity level of specific component(s).

For instance, if you need detailed tracing for LiveData Service, edit CSWorks.Server.LiveDataService.exe.config - set tracing level to "Info" or "Verbose":

  <system.diagnostics>
    <switches>
      <add name="GeneralTraceSwitch" value="Verbose"/>
    </switches>
  </system.diagnostics>


After you restart LiveData Service, you will start getting much more output in DebugView window.

If you change tracing level for a web service, edit "GeneralTraceSwitch" value in correspondent web.config file. After you save updated web.config, changes will take effect immediately.



Setup error: Failed while processing WebVirtualDirs. (-2147024894 )

clock March 10, 2010 04:02 by author Sergey Sorokin

Symptoms

A few customers were getting the following message when running CSWorks installation:

Failed while processing WebVirtualDirs. (-2147024894 ) (see screenshot)

Setup log file contains the following entry:

ConfigureIIsExec:  Error 0x80070002: Failed to find Web base

Why does this happen?

CSWorks installer installs demo application to IIS (Internet Information Services) website with following properties:

  • IP address: all unassigned;
  • Port: 80;
  • Header: <empty>

These are the default settings for “Default Web Site” created by IIS installer, and they usually remain unchanged unless system administrator edits them manually. CSWorks installer assumes there is a web site with those properties running on this machine, otherwise it throws the error above.

A similar issue is discussed with WiX installer developers at http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg30278.html, here is an excerpt:

“Make sure the IP, Port and Header all exactly match the website on the machine. These are the 3 things we use to determine if we've found the right website or not.”

Is it possible to improve CSWorks installer so it can handle more complex scenarios? We probably can do that, but:

  • it will increase installer complexity and decrease its reliability;
  • installer will have to make some changes in demo applications’ settings on-the-fly which is a risky thing.

We may consider adding support for those complex scenarios, but this is not a top priority at the moment. We are sorry about the inconvenience caused and we appreciate your understanding in this regard.

Workaround

Before installing CSWorks, make sure that “Default Web Site” is configured to run on port 80 for all unassigned IP addresses, and host header name for this configuration is empty, as shown at this screenshot (Windows XP). When done, run CSWorks installer and make sure CSWorks demo applications work properly. All demo applications are configured to run from http://localhost/CSWorksDemo, and they won’t run if you change port or header for the web site that hosts CSWorksDemo virtual folder.



CSWorks demo and your OPC data source

clock March 8, 2010 17:48 by author Sergey Sorokin

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.



Installing IIS and ASP.NET

clock February 22, 2010 15:33 by author Sergey Sorokin

Users who are new to .NET web development keep asking asking questions about CSWorks installation errors related to IIS and ASP.NET, here are some of them:

Cannot connect to Internet Information Server. (-2147221164)

IIS (Internet Information Services) version 5 or higher must be installed

IIS (Internet Information Services) version 7 or higher and IIS 6 Management Compatibility (appcmd.exe) must be installed

Also, you may experience ASP.NET-related problems even after CSWorks installation: Pipes and Tanks Demo is not running and shows The remote server returned an error: NotFound (click to see troubleshooting guide).

All these messages signal about the same thing: IIS/ASP.NET is not working properly on this machine. Please follow the steps below to install IIS/ASP.NET on your machine

Windows 7, Windows Server 2008, Vista

I will describe the process for Windows Server 2008. Windows 7 interface is very similar, Vista interface is slightly different, but names and descriptions are pretty much the same.

In "Programs and Features", click on "Turn Windows features on or off". See screenshot.

Add Web Server Role if needed, and click on it to configure. See screenshot.

Select all Web Server role service required for ASP.NET application hosting as on the screenshot below. Please pay special attention to the "Application Development" and "Management Tools" sections. See W2K8 screenshot , or Windows 7 screenshot.

You may need to enable ASP.NET ISAPI extension manually. Find "ISAPI and CGI Restrictions" under IIS properties (see screenshot), and enable ASP.NET extensions (see screenshot).

Windows XP

Go to Settings -> Control Panel ->Add or Remove Programs -> Add/Remove Windows Components. Select "Internet Information Services", and select required components - see screenshot.

Navigate to your Microsoft .NET windows directory which is usually C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319 and run aspnet_regiis -i and aspnet_regiis -c.

Go to My Computer -> Manage -> Services and Applications -> Internet Information Services, Select "Default Web Site", right-click on it and modify ASP.NET tab of site properties so it uses ASP.NET 4.0. See screenshot.

Windows Server 2003

Go to Settings -> Control Panel ->Add or Remove Programs -> Add/Remove Windows Components. Select "Internet Information Services", and select required components - see screenshot.

Navigate to your Microsoft .NET windows directory which is usually C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319 and run aspnet_regiis -i and aspnet_regiis -c.

Go to My Computer -> Manage -> Services and Applications -> Internet Information Services, Select "Default Web Site", right-click on it and modify ASP.NET tab of site properties so it uses ASP.NET 4.0. See screenshot.

Select "Web Service Extensions" node of local IIS server and enable ASP.NET v4.0 extension.See screenshot.


Update (August 2010):

On XP or 2003, use DefaultAppPool for all CSWorks virtual directories. On Vista, 2008 and Windows 7 platforms, use "ASP.NET v4.0 Classic" for CSWorksDemo virtual directory, and "ASP.NET v4.0" for CSWorksM2MDemo virtual directory.