Unlock Your IIoT Today

Connect machines, Collect data, Combine manufacturing data and operational information. Compute previously unavailable information sets. Convey discovered information and make business decisions with confidence.

Achieve 5C

Kepware™ Proxy is a unique service that shims multiple Kepware communications servers and your enterprise systems. Data exchange between the two environments is accomplished through Kepware’s IoT Gateway agents. With Kepware Proxy, you choose what to connect, collect, combine, compute, and convey. index

Interop With Enterprise Systems

Leverage the Microsoft.NET framework and transform industrial data into information and knowledge through C# scripts.

Script Missing PLC Logic

Create custom representations of data from multiple PLC sources.

Generate Knowledge With Splunk

Combine manufacturing and operational data and convey it into Splunk with a single line of code.

Open Source

Approach IIOT with a pragmatic lens and a community driven framework.

Web Application / HTTP API

Created using the latest version of Microsoft ASP.NET MVC and Web API.

Connecting Machines

Kepware Technologies is the only player that satisfies our requirements of communicating with industrial programmable logic controllers on-premise. We have researched platforms from larger and smaller companies and arrived at the conclusion that only KEPServerEX™ fits into our IIOT strategy as a data broker.

  • Connector.

    Industrial Grade

    The focus of their communications platform remains on connecting machinery and industrial equipment.

  • Connector.

    Forward Thinking

    The IoT Gateway enables communication with industrial equipment out of the box using standards such as HTTP and MQTT.

  • Connector.

    Customer Oriented

    They strive to improve their product by listening to their customers’ needs. This is evident through new feature releases.

Terminology

Internal Feature

Device I/O point.

An internal feature is an OPC tag which identifies a specific I/O point on the connected device. Tags become available to Kepware Proxy once they are added to an IoT Gateway agent. An internal feature can have a virtual entity.

Click Me!

External Feature

Client supplied parameter.

An external feature is a key-value pair supplied by a Kepware Proxy client. It can also be the active key-value pair within Kepware Proxy's lookup data set.

Click Me!

Unlisted Feature

The missing PLC feature.

An unlisted feature is a combination of internal and external features to form a previously non-existing feature.

Click Me!

Lookup Data Set

A keyed value.

A lookup is a collection of key-value pairs of the same key. Only one of these key-value pairs is the active one.

Click Me!

Thing

A physical, connected entity with a virtual representation.

A thing is a representation of a KEPServerEX channel with a physical and connected device. A thing can also have internal and unlisted features, and a virtual entity. It also belongs to a particular type or kind of things.

Click Me!

Aggregated Thing

Combination of multiple things to form a larger system.

An aggregated thing is a combination of multiple things. Aggregated things are the primary way of constructing unlisted features that require data from multiple PLCs. Each part plays a specific role within the larger system.

Click Me!

Virtual Entity

The enterprise context of a thing or its internal features.

A virtual entity is a cross-reference between a thing or its internal features and the thing's representation in an enterprise context, such as a database.

Click Me!

Service Endpoint

IoT Gateway HTTP server agent locator.

A service endpoint contains the URI of an IoT Gateway HTTP server agent, along with an environment name and geographical location.

Click Me!

Feature Script

C# script of an unlisted feature triggered by external clients.

A feature script is a user created C# script to read and write the IoT Gateway on demand. A feature script also accepts external features and returns values that represent an unlisted feature.

Click Me!

Action Script

C# script triggered by ingestion of data from the IoT Gateway.

An action script is a user created C# script that is invoked when ingested IoT Gateway data matches specified regular expressions.

Click Me!

Stream Script

C# script triggered by ingestion of data from non-OPC clients.

A stream script is a user created C# script that is invoked when ingested non-OPC data matches the stream name.

Click Me!
 

Scripting Engines

Kepware Proxy has four scripting engines:

  • feature scripting engine
  • action scripting engine
  • stream scripting engine
  • database seeding script engine

All scripting engines utilize the Managed Extensibility Framework to load script libraries during engine initialization. This approach allows you to add, replace, and remove script libraries on the fly.

The feature scripting engine is triggered by an HTTP POST to the /api/feature endpoint from any HTTP client. The inbound payload must be JSON and in the correct format. Based on the requested thing’s identifier value and requested environment, the correct IoT Gateway HTTP server agent URI is retrieved from the service endpoints list. Then, a user script is located by matching the thing’s kind (or category type) and requested unlisted feature name. An instance of the matching script is created and invoked with the received external features and any defined lookups. Any reading and writing of internal features defined in the script occurs against the previously retrieved service endpoint URI.
The action scripting engine is triggered by an HTTP POST to the /api/action endpoint from the IoT Gateway. The inbound payload must be JSON and formatted using the default IoT Gateway HTTP client agent body format. The payload is then deconstructed into individual internal features (OPC tags) and matching user scripts are located using regular expressions defined within each user script. An instance of each matching script is created and invoked with the received collection of internal features and any defined lookups. Any reading and writing of internal features defined in the script occurs against the service endpoint that is able to resolve to the HTTP request’s user host IP address.
The stream scripting engine is triggered by an HTTP POST to the /api/stream endpoint from non-OPC clients. The inbound payload must be JSON and contain the stream name and a dictionary of client data as the body. An instance of each matching script by stream name is created and invoked with the received dictionary of data.
The database seeding script engine is an out of band engine used to initially seed the embedded BrightstarDB database with things, lookups, and default Kepware Proxy settings. This is not required since all of the items can be added manually, however, a sample script has been provided with the solution.

Feature Scripts

Feature scripts provide a way to unlock valuable information that can be conveyed to multiple roles within an organization.

While internal features of PLCs provide data about a specific device I/O point, they provide little value, by themselves, to the business. To transform the internal feature data into information it must be combined and calculated with other internal features of the the same or other PLCs. Even then, what you get is information isolated to the manufacturing context, disjointed from the operational or business contexts. Therefore, the meaningfulness and value of the information can only be conveyed to and understood by limited groups within an organization. More valuable information is realized by combining manufacturing and operational data through the use of both internal features and external features.

Let’s look at an anatomy of a feature script. Below is a script which calculates the quantity of pieces from a set of PLC enabled weighing scales. A small sample scale is used to weigh a predetermined number of pieces and arrive at an average piece weight. A larger scale provides the gross weight of a large container of pieces. It is important to mention that this weighing system is controlled by a single PLC.

Feature Declaration

The UnlistedFeature and Usefulness attributes declare this script as providing the “quantity” feature to things with a particular type of “contained weighing system“. Feature scripts must inherit from UnlistedFeatureScriptBase and implement both Get (retrieve feature) and Set (assign feature) methods.

Reading and Writing Internal Features

There are several variations of reading and writing internal features from and to the IoT Gateway. When reading or writing part of an aggregated thing, use the Role parameter to refer to the correct internal feature.

Read. Request an internal feature using by performing an HTTP GET or POST with a list of internal features to the IoT Gateway HTTP server agent.


Read. Request an internal feature by pausing script execution and waiting a predefined time for an IoT Gateway HTTP client agent to push the data to Kepware Proxy /api/httpServer endpoint.


Write. Write an internal feature performing an HTTP POST with the internal feature path and a predefined value. By default writes are performed before method execution.


Write. Write an internal feature performing an HTTP POST with the internal feature path. The value of the internal feature will be set to the external feature value keyed “kv-pair-key”.


Write. Write an internal feature performing an HTTP POST with the internal feature path. The write will be performed after method execution and the value of the internal feature will be set to the script result value keyed “kv-pair-key”.


Order. Be default writing internal features occurs before reading internal features. This order can be inversed by declaring the attribute below.


Feature Retrieval

IoT Gateway HTTP Server

Since the task of weighing product is operator initiated, we have configured the PLC as a demand poll device within KEPServerEX. If this device was set with a scan rate then the IoT Gateway, acting as a client, would generate unnecessary network noise. To retrieve the weight values from the device, we are required to write a bit to the device’s “_System._DemandPoll” internal feature, which resets itself back to zero after all transaction sets have completed within KEPServerEX. This also means that the weight values will not be available immediately after we demand a poll, therefore, we can not just write one internal feature and request a polled internal feature. Instead, we will add internal features of interest to an IoT Gateway HTTP client agent and point it to our Kepware Proxy /api/httpServer endpoint. By enabling “Send Every Scan” on each internal feature we are ensuring that both items will be transmitted even if only one of them changes.

IoT Gateway HTTP Client Agent

The above transaction is represented with RequiresInternalFeature and WritesInternalFeature attributes. We are instructing the script to write a value of “1” to “_System._DemandPoll” before the Get method is invoked, since it is also possible to write internal features to the IoT Gateway HTTP server agent after the method completes. By setting the parameter How = EnumHow.PUSHED and PushTimeoutMs = 5000 we are instructing the read operations to pause script execution and wait for data to be pushed from KEPServerEX to Kepware Proxy. If both features are not received within 5 seconds, script execution is aborted and an exception is thrown. The other operating mode of RequiresInternalFeature is for the script engine to request internal features from IoT Gateway HTTP server agent.

{$thingId} parametrizes the internal feature path and is expanded during script execution.

If the IoT Gateway reads and writes succeed, the Get method is invoked and the internal features are passed into the method along with any external features. External features are a collection of key-value pairs either provided by the calling client or retrieved from Kepware Proxy’s internal lookup data set.

Inside the method simple calculations are performed to arrive at the number of pieces we have placed on both weighing scales. Another collection of key-value pairs is returned to the calling client.

Below is an example request to your KepwareProxy /api/feature endpoint along with the response.

JSON Request

JSON Response

Splunking

The above request and response payloads contain a lot of valuable information. We can forward this information to Splunk by declaring the SplunkIt attribute on our script. This will inform our internal logger, NLog, to send a message to a Splunk instance over UDP. See the NLog configuration file for more details.

Below are some examples of Splunk dashboards created from collected information.

Aggregated Thing

Each Thing Plays a Role

Aggregated things are a combination of features from multiple PLC. Below is an example of a Mettler Toledo weighing system where each scale is controlled by an individual PLC.

There is only a slight difference in the declaration of required internal parameters. Notice the Role parameter.


Compilation

There are only a couple requirements for creating, compiling, and using your custom feature scripts library.

  • Feature scripts must inherit from UnlistedFeatureScriptBase.
  • Library project must reference KepwareProxy.Data.dll which is included with the project.
  • Compiled library must reside in the location configured in Settings > DotNetScriptsPath which is set by default to ~/App_Data/scripts/dotNet/.

Script libraries are discovered every time an instance of a scripting engine is initialized, or when a request is made by a client. This means that you can add, replace, or remove script libraries on the fly.

Action Scripts

Action scripts ingest data from the IoT Gateway as it becomes available. Their execution is triggered when an internal feature matches a specific regular expression declared within the script.

Let’s look at an anatomy of an action script. Below is a script which sends an email when a set of sensors is triggered on a machine.

Triggering and Evaluation

The TriggerActionExpression attribute declare that this script will be invoked when internal features from the IoT Gateway match the regular expression defined in the Path parameter. Action scripts must inherit from ActionScriptBase and implement both Continue and Execute methods.

The invocation begins with the action scripting engine generating a list of internal features that triggered this script to execute and this list is passed into the script’s methods as the triggers parameter. The opcItems parameters include all of the internal features received from the IoT Gateway, which may include more data points than those which triggered the script. The Continue method is invoked first. Returning true will allow the script to continue and invoke the Execute method. Returning false will abort script execution. Therefore, the Continue method may be used to validate that the internal features received satisfy conditions for the logic to be executed in the Execute method.

Reading and Writing Internal Features

Unlike feature scripts, action scripts do not support design time RequiresInternalFeature or WritesExternalFeature method decoration because multiple items may trigger script execution. Instead, Write() and Read() extension methods are used on IOpcItemValued lists and IOpcItemIdentified lists respectively within the method body to transact items to and from the IoT Gateway. This is illustrated in the machine simulation example below.

Machine Simulation

Action scripts are also great for simulating machinery when developing external applications that have to interface with a machine. Below is an example of such simulation which enables SCADA developers to test their solutions without affecting production.

Compilation

There are only a couple requirements for creating, compiling, and using your custom action scripts library.

  • Action scripts must inherit from ActionScriptBase.
  • Library project must reference KepwareProxy.Data.dll which is included with the project.
  • Compiled library must reside in the location configured in Settings > DotNetScriptsPath which is set by default to ~/App_Data/scripts/dotNet/.

Script libraries are discovered every time an instance of a scripting engine is initialized, or when a request is made by a client. This means that you can add, replace, or remove script libraries on the fly.

Stream Scripts

Stream scripts ingest data from non-OPC clients. Their execution is triggered when the stream name matches the script declared stream name. Just because feature scripts and action scripts are executed, they do not necessarily signify an enterprise transaction. Among other uses, stream scripting allows you to mark the completion of previous feature script or action script executions.

Let’s look at an anatomy of a stream script. Below is a script which forwards a transaction identifier to Splunk for correlation of events.

Triggering and Evaluation

The DataStream attribute declare that this script will be invoked when a data stream name matches stream name defined in the Name parameter. Stream scripts must inherit from DataStreamScriptBase and implement the Execute method.

Compilation

There are only a couple requirements for creating, compiling, and using your custom stream scripts library.

  • Stream scripts must inherit from DataStreamScriptBase.
  • Library project must reference KepwareProxy.Data.dll which is included with the project.
  • Compiled library must reside in the location configured in Settings > DotNetScriptsPath which is set by default to ~/App_Data/scripts/dotNet/.

Script libraries are discovered every time an instance of a scripting engine is initialized, or when a request is made by a client. This means that you can add, replace, or remove script libraries on the fly.

Database Seeding Scripts

Database seeding scripts allow you populate your initial dataset with data. Below is an example of a db seeding script that creates the data store and inserts default Kepware Proxy configuration values.

Compilation

There are only a couple requirements for creating, compiling, and using your custom db seeding scripts library.

  • Db seeding scripts must inherit from IDatabaseSeedScript.
  • Library project must reference KepwareProxy.Data.dll and KepwareProxy.Exceptions which are included with the project.
  • Library project must also reference BrightstarDb libraries available from NuGet.
  • Compiled library must reside in the location configured in Web.config > b*-seedScripts-virtualPath which is set by default to ~/App_Data/scripts/dotNet/seeds/.

Db seeding script libraries are discovered every time Kepware Proxy application is started.

Technical Reference

This section contains design and implementation details.

BrightstarDb Embedded Database

BrightstarDb is a native RDF embeddable database for the .NET platform.

Below are various configuration elements stored in Web.config.

Class and Database Structure