Create a Hosting Application

Once you have compiled the custom Driver assembly, your next step will be to Create a Hosting Application that will load the assembly and run it. This application can be any .NET app, but for most deployments, you will be creating a .NET Windows Service or a Console Application. Services are perfect for deployment on a Windows platform, and Console Applications, when written using .NET Core, can be hosted on non-Windows operating systems like Linux and Mac. Additionally, you can create an Android or iOS app using the Xamarin development tools within Visual Studio.

In this example we will be creating a .NET Windows Service that will use the Driver Assembly created in the previous tutorial Creating a Universal Driver Interface.  If you have not reviewed this tutorial, please go back and review it before proceeding with the steps below.

The Hosting Application Architecture

The previous example results in a .NET assembly that uses the OAS Universal Driver Interface to read and write data and configurations within the OAS Platform. This assembly is designed to be hosted by an application that will load it in memory and communicate with a designated OAS Server.

Prerequisites

You will need to be running Open Automation Software Version 11 or greater to support Universal Drivers.  You can download the latest version at https://openautomationsoftware.com/download/

You will also need Microsoft Visual Studio to work with any of these examples and to compile your custom driver. If you do not currently have Visual Studio installed, you can try out Visual Studio Community which is a fully functional, free version of the IDE.


Step 1

Copy the C# or VB Hosting App Code from the OAS installation path, typically C:\Program Files (x86)\Open Automation Software\OPC Systems.NET\Universal Drivers\Framework4\Hosting App\. Locate the Windows Service directory and copy to a location of your choosing, then open the project in Visual Studio. We suggest copying to a directory near the Driver source code you created in the previous tutorial as you will be referencing it.

 


Step 2

Open up your choice of VB or C# example code, preferably matching the language chosen for your driver. It is not necessary for them to be written in the same language, but is easier to debug when they are consistent.

The main hosting code exists in the ExampleDriverHost file (.vb or .cs depending on the language).

Application configurations are located in the appsettings.js file.

The ProjectInstaller file is used for installation of the Windows service once the project has been compiled.

 


Step 3

Reference the Driver and ensure startup code is bound to it properly.

First, expand the project references and locate the ExampleDriver assembly. Right-click and remove this reference. This is the pre-compiled Driver that you will be replacing with your own.

Next right-click on the References and select Add Reference, navigating next to the location of your compiled Driver assembly. In the Reference Manager dialog, select Browse and then locate the compiled assembly. This will be below the bin directory in your Driver project. The assembly itself will be in the bin\Release folder or bin\Debug folder depending on the mode you used to compile the Driver. Either version will work. Select the assembly that matches the name of the assembly set in Step 2 of the Create a Universal Driver Interface tutorial. If you set this to ExampleDriver, locate and select ExampleDriver.dll.

The example Service assumes you have not changed the namespace or class names of the example Driver. If your Driver namespace was changed, you’ll see an error like the one below. Just change all reference to ExampleDriver to match your namespace.

 


Step 4

Edit the appsettings.json file to configure your deployment.

The appsettings file does not get compiled but it is distributed with the Windows service. This file holds configuration settings that can be altered based on how you wish the deployment to operate at runtime. The default settings are as follows:

  • ServiceNode
    This is the IP Address of the OAS Server that the Driver will connect to and transmit data
  • LiveDataCloudNode
    The optional name of the configured Live Data Cloud node if you are connecting to a remote host via another OAS Server
  • PortNumber
    The port on which to communicate with the OAS Server. This defaults to 58727, but may be configured on the remote OAS Server for TCP communications
  • MachineName
    This is the local identifier for the machine housing the Driver. This will be displayed in the Configure Drivers screen on the destination OAS Server’s Configuration application and useful for identifying Drivers if multiples of the same type are deployed on several devices
  • StoreAndForward
    A boolean indicating whether to cache data when a connection cannot be made to the OAS Server, forwarding when a connection is reestablished
  • UserName/Password
    The credential used to connect to the remote OAS Server if a credential is required

 


Step 5

Configure the ServiceInstaller to set up the Service runtime settings.

Within the Visual Studio Solution Explorer, click on the ProjectInstaller(.vb or .cs) and you should see a “Designer” that displays a reference to ServiceInstaller1. Click on ServiceInstaller1 and in the properties pane you should see the settings pictured here.

These settings determine the way your service will behave when you install it. The properties to consider are:

  • DisplayName
    This is what you will see in the list of services when you open your Service Control Panel.
  • Service Name
    The unique name for the service which is used behind the scenes
  • StartType
    How the service is configured to start. Manual means the service must be started by a user and it will not start when the server reboots. Automatic will attempt to start the service when the server reboots. This is preferable for infrastructure components such as a Driver.

Fee free to alter any of these and then Build the service project.

 


Step 6

Install your service using the InstallUtil. Using a command-line window, navigate to the location of the compiled service. This will be within the /bin directory within the directory holding the project source code. As with the driver, the compiled code will be within either a Debug or Release director depending on what mode you selected when building the project.

From within this directory, execute the following command:

  installutil ExampleHostService.exe

If you changed the name of your service’s assembly name, your .exe may have a different name. Just use that name instead. Be sure to include the .exe or the installation will not proceed.

If the service installs correctly, you should see the message below:

If you see any error messages, be sure to close and start your Command Prompt “As Administrator” to ensure you have the permissions to install a service on your machine.

Check that the service installed properly in the Services Control Panel and you should see it listed.

NOTE:
To uninstall the service, make sure the service is stopped and follow the same steps for installation, but instead execute:

  installutil -u ExampleHostService.exe

 


Step 7

Start the service by selecting it from the Service Control Panel and select Start. If the service functions properly and starts with no issues, you should see “Running” under the Status column.

 

 


Step 8

Open OAS Configuration to Configure Drivers and Tags. Within the OAS installation directory, you can find the OAS Configuration.exe application. Execute this application and when the window opens select Configure > Drivers. Then click Select next to the field containing “Localhost“. You should see your new ExampleDriver listed to the left. Select it and you should see the following screen:

Driver Properties as defined in the code can be seen on the right.

Select Configure > Tags and click Select for Localhost as you did above. In this case you will now see the list of Tags configured on the server. Scroll the Tag list and you will see the tags that were configured automatically by the Driver listed under Example Driver.

Select any of these Tags and you can see how they are set up to use the custom Driver to feed dynamic data.

 


 

 

FAQs – Universal Driver Interface

Do I need to split up my projects between a Hosting App and a Driver? Can I combine them?
Creating a separate Driver and Hosting App is not required, but doing so gives you the greatest deployment flexibility. By developing a separate Driver assembly, you can reference it from different project types on different platforms, especially if you target either .NET Standard 2.0. Then you can just create a specific simple Hosting App for each deployment scenario without recompiling your driver. If you only have a single deployment target in mind, you can collapse these two projects into a single Hosting App that contains both the Driver code and the runtime host functionality, whether that be a Console Application, Windows Service, etc.
Which version of .NET should my Driver Library target? .NET Framework? .NET Core? .NET Standard?
Choosing the target framework depends on your chosen deployment platform and other required assembly references.
  • If your platform is Windows and you're required to support the full .NET Framework 4.0 or 4.5, your Driver assembly must target the full .NET Framework. Typically this will be .NET 4.0 for wider compatibility.
  • If you choose to deploy the Driver to Linux or other platforms, or if you want to create a Driver assembly that can be used on all platforms including Windows with .NET Framework 4.6.1+, then target the .NET Standard 2.0.
  • However, if you are required to use a 3rd party assembly for interaction with a data source or API, the target framework will be dependent upon the framework that this assembly supports, and may determine other limitations in deployment.
Which Operating Systems or platforms does the Universal Driver Interface support?
Using the .NET Standard 2.0 specification, and .NET Core, you can build communications drivers for OAS that run on Windows, Linux, Mac, Android, and iOS. You can even deploy a driver to run on a Raspberry Pi running the Raspbian OS. Read more about UDI Platform Support for specific OS versions and requirements.

Do I need to split up my projects between a Hosting App and a Driver? Can I combine them?

Creating a separate Driver and Hosting App is not required, but doing so gives you the greatest deployment flexibility. By developing a separate Driver assembly, you can reference it from different project types on different platforms, especially if you target either .NET Standard 2.0. Then you can just create a specific simple Hosting App for each deployment scenario without recompiling your driver. If you only have a single deployment target in mind, you can collapse these two projects into a single Hosting App that contains both the Driver code and the runtime host functionality, whether that be a Console Application, Windows Service, etc.

Which version of .NET should my Driver Library target? .NET Framework? .NET Core? .NET Standard?

Choosing the target framework depends on your chosen deployment platform and other required assembly references.
  • If your platform is Windows and you’re required to support the full .NET Framework 4.0 or 4.5, your Driver assembly must target the full .NET Framework. Typically this will be .NET 4.0 for wider compatibility.
  • If you choose to deploy the Driver to Linux or other platforms, or if you want to create a Driver assembly that can be used on all platforms including Windows with .NET Framework 4.6.1+, then target the .NET Standard 2.0.
  • However, if you are required to use a 3rd party assembly for interaction with a data source or API, the target framework will be dependent upon the framework that this assembly supports, and may determine other limitations in deployment.

UDI – Getting Started

  • Create a Driver

    • Overview – choosing a framework
    • .NET 4.0 Assembly
    • .NET Standard 2.0 Assembly
    • Debugging and Testing
  • Create a Hosting App

    • Windows Service
    • .NET Core 2.0 Console App
    • Xamarin App
  • Deployment

UDI Technical Overview

The Universal Driver Interface is built upon the .NET Standard 2.0 Framework, allowing it to be deployed and run on Windows, Mac, Linux, Android, iOS, and even Raspberry Pi* platforms. This opens up unlimited integration scenarios for the OAS Platform, allowing for new edge computing solutions and device connectivity.

OAS Platform Native Drivers

The OAS Platform ships with built-in native drivers for many devices such as Allen Bradley, Siemens, and Modbus PLCs. Connectivity can be configured using the OAS Configuration tool, exposing real time data and control to the Platform. Once connected, each device’s data can be shared over any network between other installations of the OAS Platform, providing a great deal of flexibility in deployment and data aggregation.

OAS Universal Driver (UDI)

The UDI SDK allows developers create new and customized integrations that may not be possible with the built-in device drivers. Using the SDK, a developer writes custom code to read and write data against any external API or protocol, exposing these data points to an OAS Server. The UDI implementation is written in either C# or VB.NET against the .NET Core 2.0 Framework, and depending on the desired deployment target, can be deployed as a Windows Service or application to be run on any other supported platform.

Additionally, the UDI implementation can be deployed either on the same machine as the OAS Server if written as a Windows Service, or it can be deployed remotely on another Windows PC or server. If the UDI implementation is written as a .NET Core application, it can be deployed as a Mac or Linux application and installed as a persistent background process. If desired, a UDI implementation can also be written using Xamarin and deployed as an Android or iOS application.

UDI Application Architecture

The .NET Standard is a cross-platform, baseline version of the .NET libraries. The UDI is built to support the .NET Standard 2.0, allowing for device drivers to be written for any platform supported by the .NET Standard.

Developing Your Driver as a .NET Core or .NET Standard Assembly will allow for the interface to be reused on multiple platforms without the core code being recompiled. A “wrapper” application or service can use the assembly with each deployment target and use case having it’s own custom wrapper. This can be a Windows Service, a console application, or even mobile app.

*While Raspbery Pi is not technically supported as a deployment platform by MS, the Raspbian OS is a variant of Debian, which is a supported target.

UDI Platform Support

The Universal Driver Interface can be deployed on any platform supported by .NET Standard, .NET Core, and .NET Framework. This includes Windows, Mac OS X, many variants of Linux, and even mobile platforms such as Android and iOS. Below are the details on each platform and minimum compatibility requirements.

 Windows

OS Versions Architectures
Windows Client 7 SP1+, 8.1 X64, x86
Windows 10 Client Version 1607+ X64, x86
Windows Server 2008 R2 SP1+ X64, x86

 

 Mac OS

OS Versions Architectures
Mac OS X 10.12+ X64

 

 Linux

OS Versions Architectures
Red Hat Enterprise 7, 6 x64
CentOS 7 x64
Oracle Linux 7 x64
Fedora 27 x64
Debian 9, 8.7+ x64
Ubuntu 18.04, 16.04, 14.04 x64
Linux Mint 18, 17 x64
openSUSE 42.3+ x64
SUSE Enterprise Linux (SLES) 12 SP2+ x64

 

 Android, iOS, Mac through Xamarin

Xamarin Target Minimum Version
Xamarin.iOS 10.14
Xamarin.Mac 3.8
Xamarin.Android 8.0

 

 Unofficially Supported

OS Versions Hardware
Raspbian
(Debian-based Linux)
Kernel 3.18+ Raspberry Pi 3, 3+ recommended for minimum performance