How to Setup DNP3 Device

Modbus devices have the nifty configuration utility to make connections pretty easy, but DNP3 is throwing me. I don’t see a space for client / server DNP addresses only the server’s IP port and IP address.

Any ideas? Or is there a template on how to create a connection string for DNP3?

I was able to find a examples of device strings in the openPDC documentation, but none for DNP3. Also found that the PMU connection tester dose not have a DNP3 option.

Are their any examples of a device connection string for DNP3 available?

To be honest, I’ve never actually set this up myself. I will say that it works a little differently than how we configure the synchrophasor protocols because the adapter was written by a third-party to interface with the opendnp3 library. The connection string should be defined as follows.

CommsFilePath=comms.xml; MappingFilePath=mapping.xml

You are going to need to configure comms and mappings via XML files. There exist a couple example files in the GSF source code.

Examples
comms.xml
mapping.xml

In order to create the mapping file, it will be necessary to create Measurements in the openHistorian database. For this, you will need to use the Manage > Measurements screen in the openHistorian Manager.

Thanks,
Stephen

I’m playing with it for giggles. I’ll report back if I make any progress or can share a functioning setup.

---- Stack Trace ----

[7/3/2018 10:47:46 AM] (Inner Exception)
Date and Time:         7/3/2018 10:47:46 AM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      mscorlib
Exception Type:        System.ArgumentNullException
Exception Message:     Value cannot be null.
Parameter name: type
Exception Target Site: CreateInstance

---- Stack Trace ----
   System.Activator.CreateInstance(type As Type, nonPublic As Boolean)
       openHistorian.exe: N 14715308
   System.Activator.CreateInstance(type As Type)
       openHistorian.exe: N 00012
   GSF.TimeSeries.Adapters.AdapterCollectionBase`1.TryCreateAdapter(adapterRow As DataRow, adapter As T&)
       openHistorian.exe: N 00441


(Outer Exception)
Date and Time:         7/3/2018 10:47:46 AM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      
Exception Type:        System.InvalidOperationException
Exception Message:     Failed to load adapter "RTAC-DNP" [Dnp3Adapters.Dnp3InputAdapter] from "C:\Program Files\openHistorian\Dnp3Adapters.dll": Value cannot be null.
Parameter name: type

That looks like a casing issue. If you execute this script, it should fix the casing in the database.

UPDATE Protocol SET TypeName = 'DNP3Adapters.DNP3InputAdapter' WHERE TypeName = 'Dnp3Adapters.Dnp3InputAdapter'

After running that query, I believe the system should pick up the change automatically if you initialize the device.

On to the next error!

(Inner Exception)
(Inner Exception)
(Inner Exception)
Date and Time:         7/3/2018 2:48:42 PM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1
Current User ID:       NT SERVICE\openHistorian
Current User Name:     
Current User Phone:    
Current User Email:    

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      Dnp3Adapters
Exception Type:        System.IO.FileNotFoundException
Exception Message:     Could not load file or assembly 'DNP3CLRAdapter.dll' or one of its dependencies. The specified module could not be found.
Exception Target Site: .cctor

---- Stack Trace ----
   DNP3Adapters.DNP3InputAdapter..cctor()
       openHistorian.exe: N 00000


(Outer Exception)
Date and Time:         7/3/2018 2:48:43 PM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1
Current User ID:       NT SERVICE\openHistorian
Current User Name:     
Current User Phone:    
Current User Email:    

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      Dnp3Adapters
Exception Type:        System.TypeInitializationException
Exception Message:     The type initializer for 'DNP3Adapters.DNP3InputAdapter' threw an exception.
Exception Target Site: .ctor

---- Stack Trace ----
   DNP3Adapters.DNP3InputAdapter..ctor()
       openHistorian.exe: N 00000


(Outer Exception)
Date and Time:         7/3/2018 2:48:43 PM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1
Current User ID:       NT SERVICE\openHistorian
Current User Name:     
Current User Phone:    
Current User Email:    

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      mscorlib
Exception Type:        System.Reflection.TargetInvocationException
Exception Message:     Exception has been thrown by the target of an invocation.
Exception Target Site: CreateInstance

---- Stack Trace ----
   System.RuntimeTypeHandle.CreateInstance(type As RuntimeType, publicOnly As Boolean, noCheck As Boolean, canBeCached As Boolean&, ctor As RuntimeMethodHandleInternal&, bNeedSecurityCheck As Boolean&)
       openHistorian.exe: N 00000
   System.RuntimeType.CreateInstanceSlow(publicOnly As Boolean, skipCheckThis As Boolean, fillCache As Boolean, stackMark As StackCrawlMark&)
       openHistorian.exe: N 00197
   System.Activator.CreateInstance(type As Type, nonPublic As Boolean)
       openHistorian.exe: N 00105
   System.Activator.CreateInstance(type As Type)
       openHistorian.exe: N 00012
   GSF.TimeSeries.Adapters.AdapterCollectionBase`1.TryCreateAdapter(adapterRow As DataRow, adapter As T&)
       openHistorian.exe: N 00441


(Outer Exception)
Date and Time:         7/3/2018 2:48:43 PM
Machine Name:          SCADA-NUC
Machine IP:            ::1
Machine OS:            Microsoft Windows NT 6.1.7601 Service Pack 1
Current User ID:       NT SERVICE\openHistorian
Current User Name:     
Current User Phone:    
Current User Email:    

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.5.6.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.5.6.0
Assembly Build Date:   6/1/2018 12:22:34 AM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      
Exception Type:        System.InvalidOperationException
Exception Message:     Failed to load adapter "RTAC-DNP" [DNP3Adapters.DNP3InputAdapter] from "C:\Program Files\openHistorian\Dnp3Adapters.dll": Exception has been thrown by the target of an invocation.

---- Stack Trace ----

Make sure the DNP3adapters DLL is not missing from the installation.

If it is, you can try downloading and extracting the file from the openHistorian binaries:

https://www.gridprotectionalliance.org/NightlyBuilds/openHistorian/Beta/openHistorian.Binaries.zip

Also, the DNP3 adapters depend on the following Microsoft DLL (Visual C++ Redistributable for Visual Studio 2015):

Thanks,
Ritchie

PS) What little docs we have are little more developer focused:

See also:

FYI, I recently set up a test environment to validate the DNP3 functionality in openPDC.

General observations:

  • The Dnp3InputAdapter configuration only allows for the openPDC to initiate connections as the TCP client and communicate as the DNP3 Master to a DNP3 Outstation.

  • I initially encountered an issue with the version of the OpenDNP3 library being used by the Dnp3InputAdapter where the openPDC would poll the device and collect the measurements, but would not publish the measurements to the routing engine. This issue was resolved by updating the version of the OpenDNP3 library. The update required changes to the Dnp3InputAdapter, so I would not expect the Dnp3InputAdapter provided by the latest release build to work properly.

  • The latest version allows for you to adjust the polling interval through an additional connection string parameter. The parameter defines the number of seconds between each poll. PollingInterval=2

  • The latest build requires the latest version of the Visual C++ Redistributable, which we will be including in future releases of the openPDC.

For my test, I used the Automatak DNP3 Simulator to fill the role of the TCP server and DNP3 Outstation. The openPDC and the Simulator were hosted on the same system so the connection was made locally. After fixing a minor bug in the Dnp3InputAdapter, all data types supported by the openPDC were being properly updated on the openPDC Manager displays as the values changed in the Simulator. The latest nightly build version of the openPDC includes the working version of the Dnp3InputAdapter that I used in my test setup.

Excellent! I appreciate the help. I’ll end up getting back to this project here in a week or so and keep at it myself.

Can you expand on what the XML tags want in the configuration file?

For example, what exactly is <tsfid>, <dnpIndex>, <localaddr>, and <remoteaddr> asking for? I could not find definitions of what exactly these fields wanted.

Basically, TSF stands for Time-Series Framework, which is the library that underpins all of GPA’s synchrophasor products. <tsfid> is the Point ID of the measurement in openHistorian. <tsfSource> is going to be either the acronym of the historian or the device that the measurement is associated with. These two values make up the measurement key (example: PPA:14), which you have probably seen before. The measurement key is used to identify the measurement in openHistorian’s internal processes.

The rest of the fields you asked about are specific to the DNP3 protocol. I have next to no experience with DNP3 so I lack conceptual understanding and familiarity with terminology. Take the rest of this information with the disclaimer that it was entirely derived through speculation based on my experience with the tools to set up this test system.

<dnpIndex> seems to be a way of identifying an individual signal based on its position in a collection of signals with the same data type. In other words, if you think of each of the map sections as representing a collection for an individual data type (binary, analog, counter, etc.) then the <dnpIndex> would be a zero-based index in that collection. For a real DNP3 device, I imagine that these indexes and their meanings would be defined in the documentation from the vendor.

<localaddr> and <remoteaddr> appear to be sort of like a DNP3 port number, though I really only just set them up to match the link’s source and destination that I configured in the simulated outstation and have not done any experimentation at all with changing them to see what happens. Wikipedia indicates that DNP3 defines an OSI model layer 2 protocol so maybe you could think of them as similar in function to a MAC address.

I have read through this thread and am still having trouble getting data to show up in openHistorian. I verified with a network monitor that the system is polling for DNP3 events (data change) and the outstation is replying. I am new to openHistorian, but very familiar with DNP3 and other protocols. I started with version 2.5.6. I updated to the nightly build on Monday.
I don’t understand the instruction:
“In order to create the mapping file, it will be necessary to create Measurements in the openHistorian database. For this, you will need to use the Manage > Measurements screen in the openHistorian Manager.”
I just modified the mapping.xml file to suit my outstation. Is there a step to “subscribe”?

I don’t notice anything in the error log.

Also, Must <tsfSource>:<tsfid> be unique?

In the openHistorian, the DNP3 input adapter will read data from the outstation, convert that data into measurements, and then provide those measurements to other adapters hosted by the openHistorian. Apart from modifying the database directly, the only way to define the output measurements that will be provided to other adapters is to use the openHistorian Manager desktop application (installed alongside the openHistorian Windows service by default). Once you have defined the measurements, they will be given an ID which matches the <tsfSource>:<tsfid> syntax you mentioned in your post. You will need to enter those values into the mapping file as appropriate in order to do the conversion from the DNP3 input data to a measurement in openHistorian.

I realize this thread is over a year old, but it’s the only one I’ve found covering DNP3 setup. I’ve read through this and attempted to set up per the methods described, but I haven’t been able to get successful polling of my remote outstation from OpenHistorian.

I’m hoping to get some clarification on a few steps to ensure I’m not implementing incorrectly.

  • Should the DNP3 connection be set up as a “Device based input”, or as a “Custom Input”? I’ve tried both without success, but trying to narrow down my potential issues. When I used the custom input, I couldn’t figure out how to associate measurements to the custom input.
  • Does the outstation IP address go under the <client> section of the comms.xml file? I didn’t see anywhere else to assign an IP, but I’m used to “client” and “master” being used synonymously (in SEL literature).

Any other additional insight into why my polling may not be working would be appreciated. I’ve successfully polled the outstation by configuring a different master on the same network, but haven’t had any success yet with this. I suspect I may be misunderstanding some of the steps.

Can you share a copy of your configuration files you are using - specifically the communications XML and mappings XML files, will certainly take a look. Make sure to obfuscate any IP addresses before posting.

Thanks,
Ritchie

If you have any error messages from the openHistorian Console or ErrorLog.txt that might be related to your DNP3 connection, please share those as well. To answer your questions…

  • When I ran my test, I set mine up as a “Device based input,” so setup as a custom input adapter is untested. That said, devices are essentially just input adapters so it should work fine either way. Measurements are associated with the device or custom input via the mapping.xml file. Custom inputs don’t show up in openHistorian Manager displays, so you’d also need to create a virtual device to associate with the measurements in the database for visualization purposes.
  • The <clilent> section is, indeed, where you enter the IP address of the outstation. Your understanding that client and master are basically synonymous likely still applies here, but rather than interpreting that section as requiring information about the client, it’s more like it represents the configuration on how the client should operate.

For the comms.xml file, I essentially took the example file linked above and changed only the IP address to the address of my outstation device. I configured the outstation server to use DNP address 1024 to match what’s assigned here and to look for a master of address 1. Here is comms file:

<?xml version="1.0" encoding="utf-8"?>
<MasterConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <client>
    <address>192.xxx.xxx.xxx</address>
    <port>20000</port>
    <minRetryMs>5000</minRetryMs>
    <maxRetryMs>60000</maxRetryMs>
    <level>15</level>
  </client>
  <master>
    <master>
      <fragSize>2048</fragSize>
      <allowTimeSync>true</allowTimeSync>
      <doUnsolOnStartup>false</doUnsolOnStartup>
      <enableUnsol>true</enableUnsol>
      <unsolClassMask>14</unsolClassMask>
      <integrityPeriodMs>5000</integrityPeriodMs>
      <taskRetryPeriodMs>5000</taskRetryPeriodMs>
    </master>
    <app>
      <isMaster>true</isMaster>
      <rspTimeoutMs>5000</rspTimeoutMs>
      <numRetry>0</numRetry>
      <fragSize>2048</fragSize>
    </app>
    <link>
      <isMaster>true</isMaster>
      <useConfirms>false</useConfirms>
      <numRetry>0</numRetry>
      <localAddr>1</localAddr>
      <remoteAddr>1024</remoteAddr>
      <timeoutMs>1000</timeoutMs>
    </link>
  </master>
</MasterConfiguration>

For the purposes of testing, I’m only attempting to poll 2 analog points. So for the mapping file, I removed everything from the example file but the analog section:

<?xml version="1.0" encoding="Windows-1252"?>

<MeasurementMap xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <analogMap>

    <Mapping>

      <tsfId>135</tsfId>

      <tsfSource>PPA</tsfSource>

      <dnpIndex>0</dnpIndex>

    </Mapping>
	
	<Mapping>

      <tsfId>136</tsfId>

      <tsfSource>PPA</tsfSource>

      <dnpIndex>1</dnpIndex>

    </Mapping>

  </analogMap>

</MeasurementMap>

If I’m understanding the mapping file correctly, it should map the following:

  • DNP AI0000 --> PPA:135
  • DNP AI0001 --> PPA:136

PPA:135 & 136 are measurements I created as Current Magnitude & Current Phase Angle types

There was an error generated yesterday afternoon, but I can’t seem to duplicate it anymore, and I’m not certain exactly what generated it, as I was trying a lot of different configurations throughout the afternoon:

[5/21/2020 2:22:10 PM] Date and Time:         5/21/2020 2:22:10 PM
Machine Name:          SEL
Machine IP:            xx::xxx:xxx:xxx:xxx
Machine OS:            Microsoft Windows NT 6.2.9200.0

Application Domain:    openHistorian.exe
Assembly Codebase:     C:/Program Files/openHistorian/openHistorian.exe
Assembly Full Name:    openHistorian, Version=2.7.195.0, Culture=neutral, PublicKeyToken=null
Assembly Version:      2.7.195.0
Assembly Build Date:   5/5/2020 6:22:56 PM
.Net Runtime Version:  4.0.30319.42000

Exception Source:      System
Exception Type:        System.Net.HttpListenerException
Exception Message:     An operation was attempted on a nonexistent network connection
Exception Target Site: WriteAsyncFast

---- Stack Trace ----
   System.Net.WebSockets.WebSocketHttpListenerDuplexStream.WriteAsyncFast(eventArgs As HttpListenerAsyncEventArgs)
       openHistorian.exe: N 00689
   System.Net.WebSockets.<WriteAsyncCore>d__41.MoveNext()
       openHistorian.exe: N 01323
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       openHistorian.exe: N 00032
   System.Net.WebSockets.<SendFrameAsync>d__48.MoveNext()
       openHistorian.exe: N 01218
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       openHistorian.exe: N 00032
   System.Net.WebSockets.<Process>d__19.MoveNext()
       openHistorian.exe: N 03862
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       openHistorian.exe: N 00032
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(task As Task)
       openHistorian.exe: N 00062
   System.Net.WebSockets.<CloseOutputAsyncCore>d__51.MoveNext()
       openHistorian.exe: N 02191

There are a number of items on the “Add New Device Configuration” screen on the manager that I’m not sure how to interpret or how they should be set (i.e. Connect on Demand, Allow use of cached configuration, frames per second, etc) If you have descriptions of the options on that screen, or an example of how you configured that screen for DNP that may be helpful.

Thanks for taking a look at this!

I don’t see anything wrong obviously wrong with the configuration you’ve provided. How did you configure the device? And what happens in the openHistorian Console when you initialize it?

Here is the device configuration I used:

This is what the console reports when I try to initialize it:

[RTAC-DNP3] Connecting to: xxx.xxx.xxx.xxx (INFO) @ c:\projects\dnp3\cpp\libs\src\asiodnp3\tcpclientiohandler.cpp(70)

[RTAC-DNP3] WARNING: Error Connecting: A connection attempt failed because the connected party did not properly respond after a period of ti (WARN) @ c:\projects\dnp3\cpp\libs\src\asiodnp3\tcpclientiohandler.cpp(76)

The warning indicates a timeout when establishing the connection. Timeouts typically occur when packets get blocked by a firewall. If you can, verify that the device is actually listening for DNP3 connections on TCP port 20000. Then ensure that there are no firewalls blocking connections to that port.

So far as I can tell there are no firewalls enabled on the computer (windows firewall reminds me that it’s not enabled every time I log in). However, for reasons unknown to me, the console is now generating different output when I try to initialize it:

initialize RTAC-DNP3

Adapter "RTAC-DNP3" (14) was successfully initialized...



Database connection opened.

Attempting to augment existing configuration data set...

Executing startup data operation "Time Series Startup Operations".

Executing startup data operation "Phasor Data Source Validation".

Establishing default measurement key cache...

Validating signal types...

Validating output stream device ID codes...

Verifying statistics archive exists...

Validating device protocols...

Executing startup data operation "Optimize Local Historian Settings".

Optimizing settings for local historians...

Loaded 0 rows from "FilterAdapters" in 0 seconds...

FilterAdapters configuration pre-cache completed in 0 seconds.

Loaded 1 row from "InputAdapters" in 0 seconds...

InputAdapters configuration pre-cache completed in 0 seconds.

Loaded 9 rows from "ActionAdapters" in 1 milliseconds...

ActionAdapters configuration pre-cache completed in 0 seconds.

Loaded 2 rows from "OutputAdapters" in 0 seconds...

OutputAdapters configuration pre-cache completed in 1 milliseconds.

Loaded 0 rows from "InputStreamDevices" in 0 seconds...

InputStreamDevices configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "OutputStreamDevices" in 0 seconds...

OutputStreamDevices configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "OutputStreamMeasurements" in 0 seconds...

OutputStreamMeasurements configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "OutputStreamDevicePhasors" in 0 seconds...

OutputStreamDevicePhasors configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "OutputStreamDeviceAnalogs" in 1 milliseconds...

OutputStreamDeviceAnalogs configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "OutputStreamDeviceDigitals" in 0 seconds...

OutputStreamDeviceDigitals configuration pre-cache completed in 0 seconds.

Loaded 108 rows from "Statistics" in 2 milliseconds...

Statistics configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "Subscribers" in 0 seconds...

Subscribers configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "SubscriberMeasurements" in 0 seconds...

SubscriberMeasurements configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "SubscriberMeasurementGroups" in 1 milliseconds...

SubscriberMeasurementGroups configuration pre-cache completed in 0 seconds.

Loaded 1 row from "MeasurementGroups" in 0 seconds...

MeasurementGroups configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "MeasurementGroupMeasurements" in 0 seconds...

MeasurementGroupMeasurements configuration pre-cache completed in 1 milliseconds.

Loaded 0 rows from "Alarms" in 0 seconds...

Alarms configuration pre-cache completed in 0 seconds.

Loaded 1 row from "NodeInfo" in 0 seconds...

NodeInfo configuration pre-cache completed in 0 seconds.

Loaded 0 rows from "CompressionSettings" in 1 milliseconds...

CompressionSettings configuration pre-cache completed in 0 seconds.

Starting measurement route calculation...

Calculated 85 routes for 11 destinations in 0 seconds.

Starting measurement route calculation...

Calculated 85 routes for 11 destinations in 0 seconds.

Starting measurement route calculation...

[STAT] Pausing measurement processing...

[STAT] AdoMetadataProvider has started metadata refresh...

Calculated 85 routes for 11 destinations in 0 seconds.

Database connection closed.

[RTAC-DNP3] Disposed.

Starting measurement route calculation...

Calculated 85 routes for 11 destinations in 1 milliseconds.

Starting measurement route calculation...

Calculated 85 routes for 11 destinations in 1 milliseconds.

[STAT] AdoMetadataProvider has finished metadata refresh.

Successfully cached current configuration to binary.

[STAT] Resuming measurement processing...

Successfully cached current configuration to XML.

[STATISTIC!SERVICES] Loaded 108 statistic calculation definitions and 83 statistic measurement definitions.

It says it initializes successfully, but then shortly after initializing, it says Disposed.

I used a comms capture on the RTAC that I’m trying to connect to, and there is no record of packets to TCP port 20000 over the time period when I initialized the device in OpenHistorian. So it seems OpenHistorian isn’t actually getting anything out to the destination IP.