Configuring S7-300 OPC UA Java Client with Simatic Net

David Krause14 min read
OPC / OPC UASiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview: S7-300 Data to a Java Application via OPC UA

The Siemens S7-300 CPU family has no native OPC UA server. To expose S7-300 tags to a Java client you must run a Windows-based PC with SIMATIC NET, which acts as the OPC UA server and bridges an S7 connection (Industrial Ethernet, PROFIBUS, or MPI) to a standards-based opc.tcp:// endpoint. A Java application then consumes that endpoint using the official OPC Foundation Java stack or a third-party Java SDK such as Eclipse Milo or Prosys OPC UA.

This reference covers the full integration for a process-data scenario (e.g., methane concentration logging) where the Java client must read measured values from the S7-300 and write them to a time-stamped archive. The configuration is identical whether the Java client is a desktop application, a Tomcat servlet, or a Spring Boot microservice, and the OPC UA protocol guarantees that the same client code runs unchanged when the controller is later upgraded to an S7-1200 or S7-1500 with its built-in OPC UA server.

OPC UA Data Flow and S7-300 Architecture

The end-to-end path of one measured value (e.g., methane concentration) is:

  1. S7-300 CPU — holds the process tag. Typical items: DB100.DBD0 (REAL, methane % LEL), DB100.DBW4 (INT, status), DB100.DBX6.0 (BOOL, alarm).
  2. CP 343-1 / CP 343-1 Advanced — communications processor that provides the Industrial Ethernet port on the S7-300 rack.
  3. SIMATIC NET PC software — on a Windows host, runs both the S7 connection (named "S7 connection" in STEP 7 / NCM PC) and the OPC UA Server.
  4. OPC UA endpoint — listens on opc.tcp://<simatic-net-host>:4840 with the configured SecurityPolicy and authentication mode.
  5. Java OPC UA client — opens a session, browses the AddressSpace, and subscribes to selected monitored items.
  6. The Java client applies an application-level time-stamp at the moment the notification is consumed, independent of the source controller.
Architectural note: Because the S7-300 cannot expose OPC UA natively, every Java client in this topology depends on the SIMATIC NET host. If you can change the controller family, the TIA Portal V20 OPC UA documentation shows that the S7-1200 and S7-1500 CPUs include a built-in OPC UA server, eliminating the PC software layer entirely.

Prerequisites: Hardware, Software, and Licensing

Component Requirement
S7-300 CPU CPU 31x with an Ethernet CP (CPU 315-2 PN/DP, CPU 317-2 PN/DP, etc.) and a CP 343-1 or onboard PROFINET port
STEP 7 / TIA Portal project DBs configured for the methane tag and control flags; tags must be reachable as absolute addresses
PC hardware Windows 10/11 or Windows Server 2016/2019/2022, x64, 4 GB RAM minimum, 100 Mbit/s Ethernet
SIMATIC NET Version with OPC UA Server for S7 connections. The OPC UA server for S7 connections is available as of the CD2800 release of SIMATIC NET, per Siemens support entry 31675909.
SIMATIC NET license OPC UA Server license key for the S7 connection count you are activating
Java JDK JDK 11 or newer (LTS); JDK 17 and JDK 21 are validated against Eclipse Milo 0.6.x
Java OPC UA SDK Eclipse Milo (open source), Prosys OPC UA Java SDK (commercial), or OPC Foundation Java stack (commercial / RCL)
Network TCP 4840 reachable from the Java host to the SIMATIC NET host; TCP 102 (ISO-on-TCP / RFC 1006) reachable from SIMATIC NET to the S7-300 CP
Firewall Allow inbound 4840/tcp to the SIMATIC NET service; allow inbound 102/tcp to the S7-300 CP

Install SIMATIC NET before plugging in the S7 connection; the S7-OPC server components and license plug-in only become visible in the PC station hardware catalog after the main install completes.

Configuring the SIMATIC NET OPC UA Server for S7 Connections

Configuration lives in the SIMATIC Manager (STEP 7 V5.x) or TIA Portal project that targets the PC station. The PC station must contain a virtual "OPC Server" application and an S7 connection to the S7-300.

  1. Open the PC station hardware configuration and insert an "OPC Server" application on the virtual PC.
  2. Configure an S7 connection from the OPC Server to the S7-300 CP. The connection partner is the S7-300 IP address and the S7 connection ID defined in the CP's STEP 7 configuration. The connection type "S7 connection" must match on both sides.
  3. Define the S7 symbols to expose. Each absolute address or symbolic name becomes a UA variable. For the methane application, expose at minimum:
    • DB100.DBD0 — REAL, methane concentration
    • DB100.DBW4 — INT, status word
    • DB100.DBX6.0 — BOOL, alarm flag
  4. Compile and load the PC station configuration to the runtime system. The S7 communication service and the OPC UA server start automatically under the local system account.
  5. Open the SIMATIC NET "Commissioning" tool, browse to the OPC UA Server settings, and set the SecurityPolicy of the endpoint. For an isolated plant network you can start with None + anonymous authentication; for production use Basic256Sha256 + user/password or certificate-based client auth.
  6. Confirm the endpoint answers a GetEndpoints request from any external OPC UA browser.

Full procedural and parameter documentation is in the SIMATIC NET programming manual referenced by Siemens support entry 42783968 (page 116 of the cited edition lists the language bindings for the UA interface) and the SIMATIC NET OPC UA Server for S7 connections entry at 31675909.

Choosing a Java OPC UA Client SDK

The OPC Foundation defines language-agnostic bindings for OPC UA in C, .NET (C#, VB.NET), Java, and C++, and the corresponding communication stacks are distributed by the Foundation. The Java stack is one of the four official bindings and is the path of least resistance for a Java application.

SDK License Java version Strengths Limits
OPC Foundation Java Stack (reference implementation) OPC Foundation commercial / RCL JDK 8+ Authoritative, used by OPC Foundation tools and test harnesses Commercial license for production deployment; heavier API
Eclipse Milo EPL-2.0 (open source) JDK 11+ Active community, idiomatic async API, Spring Boot samples Not OPC Foundation compliance certified
Prosys OPC UA Java SDK Commercial, free for development JDK 8+ Long-term support, certified, has SIMATIC NET sample code Paid for production runtime

For a lab or pilot deployment Eclipse Milo is the lowest-friction option. For a regulated plant deployment (GAMP, 21 CFR Part 11, IEC 62443) select Prosys or the OPC Foundation commercial stack, both of which hold OPC Foundation compliance certification.

Java Client Implementation with Eclipse Milo

Add the Milo dependencies to a Maven project:

<dependency>
  <groupId>org.eclipse.milo</groupId>
  <artifactId>sdk-client</artifactId>
  <version>0.6.9</version>
</dependency>
<dependency>
  <groupId>org.eclipse.milo</groupId>
  <artifactId>binaryserver</artifactId>
  <version>0.6.9</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>2.0.13</version>
</dependency>

Minimum code to discover the endpoints, open a session, read a value, and close cleanly:

import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;

public class S7OpcUaReader {
  public static void main(String[] args) throws Exception {
    String endpointUrl = "opc.tcp://10.0.0.50:4840";

    OpcUaClient client = OpcUaClient.create(
        endpointUrl,
        endpoints -> endpoints.stream()
            .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
            .findFirst(),
        configBuilder -> configBuilder
            .setApplicationName(LocalizedText.english("Java UA Client"))
            .setApplicationUri("urn:java:opcua:client")
            .setRequestTimeout(uint(5000))
    );

    client.connect().get();

    // SIMATIC NET exposes S7 tags under its own numeric namespace, typically ns=2 or ns=4.
    NodeId methaneConcentration = new NodeId(2, "DB100.DBD0");

    DataValue dv = client
        .readValue(0.0, TimestampsToReturn.Both, methaneConcentration)
        .get();

    System.out.println("Value       : " + dv.getValue().getValue());
    System.out.println("Source time : " + dv.getSourceTime().getJavaDate());
    System.out.println("Server time : " + dv.getServerTime().getJavaDate());

    client.disconnect().get();
  }
}

The same logic in the OPC Foundation Java stack uses the UaClient SDK and an SessionActivationHelper:

import org.opcfoundation.ua.client.UaClient;
import org.opcfoundation.ua.core.ReadParameters;

UaClient client = new UaClient("opc.tcp://10.0.0.50:4840");
client.connect();

ReadParameters rp = new ReadParameters();
rp.getNodesToRead().add(new ReadValueId(
    new NodeId(2, "DB100.DBD0"), AttributeId.Value, null, QualifiedName.NULL));

DataValue[] results = client.Read(rp);
System.out.println("CH4: " + results[0].getValue().getValue());

Building a Time-Stamped Data Logger with Subscriptions

For continuous logging, use a UA Subscription with monitored items instead of polling readValue. The server pushes changed values; the client records its own time-stamp the moment a notification arrives. This decouples the logging rate from the polling rate and survives temporary network outages with the server's PublishingInterval and KeepAliveCount acting as a buffer.

import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.time.Instant;
import java.util.List;

ManagedSubscription sub = client
    .getSubscriptionManager()
    .createSubscription(250.0)            // publishingInterval ms
    .get();

NodeId ch4   = new NodeId(2, "DB100.DBD0");
NodeId alarm = new NodeId(2, "DB100.DBX6.0";)

sub.addDataItems(List.of(ch4, alarm)).get();

sub.addDataItemsListener((items, values) -> {
    Instant tClient = Instant.now();
    try (BufferedWriter w = new BufferedWriter(
            new FileWriter("methane.csv", true))) {
        for (int i = 0; i < items.size(); i++) {
            String tag = items.get(i).getNodeId().getIdentifier().toString();
            Object val = values.get(i).getValue().getValue();
            w.write(tClient + "," + tag + "," + val + "\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
});

Recommended parameters when calling createSubscription(double publishingInterval):

Parameter Typical value Effect
publishingInterval 250 ms How often the server checks monitored items for change
samplingInterval 0 (server decides) or 100 ms Source sampling on the SIMATIC NET server side
queueSize 10 How many samples are buffered if the client is slow
discardOldest true When the queue is full, drop oldest to keep latency low
KeepAliveCount 10 Number of empty publish cycles before the server sends a keep-alive
LifeTimeCount 3 × KeepAliveCount Server terminates the subscription if no publish is acknowledged

Security Policies, Certificates, and Authentication

SIMATIC NET's OPC UA server supports the SecurityPolicies defined by the OPC UA specification. The choice of policy is made in the SIMATIC NET Commissioning tool and must match on the client.

SecurityPolicy MessageSecurityMode Use case
None Invalid / None Lab, isolated VLAN, commissioning only
Basic128Rsa15 Sign / SignAndEncrypt Legacy systems; considered weak by modern standards
Basic256Sha256 Sign / SignAndEncrypt Production deployments with SHA-2 trust chain
Aes128Sha256RsaOaep Sign / SignAndEncrypt Highest available in SIMATIC NET, preferred for new plants

To enable a non-None policy on the Java side, install the SIMATIC NET server certificate into the Java truststore:

keytool -importcert -alias simatic-net \
  -file simatic-net-server.der \
  -keystore $JAVA_HOME/lib/security/cacerts \
  -storepass changeit

For two-way authentication, export the Java client's certificate and import it into the SIMATIC NET trusted clients list. The OPC Foundation Java stack stores its client certificate in PKI/own/certs inside the application folder; Eclipse Milo defaults to ~/.milo/client.pfx.

Time-stamp note: With SecurityPolicy None + no source time-stamps configured, the DataValue source time is null and only the application time-stamp is meaningful. Switch on the TimestampsToReturn.Both flag in the read or the subscription to retrieve the source time-stamp from the SIMATIC NET server.

Java vs VB.NET OPC UA Client Comparison

The Java and .NET bindings of OPC UA expose the same concepts (Session, Subscription, MonitoredItem, DataValue) and the same binary protocol on the wire. The differences are at the language-idiom level, not in the protocol.

Aspect VB.NET (.NET) Java
SDK OPC Foundation .NET Standard stack, also wrapped by SIMATIC NET examples OPC Foundation Java stack, Eclipse Milo, Prosys
Async model async/await on Task<T> CompletableFuture, Reactive Streams, or callbacks
Project setup NuGet packages, Visual Studio project file Maven or Gradle; any IDE
Deployment OS Windows-centric for .NET Framework 4.x; .NET 6+ is cross-platform OS-neutral; runs on Linux servers, edge gateways, Android
Containerization Possible with .NET 6+; larger image footprint Native fit for Docker, slim JRE base images (alpine)
IDE / debugging Step into UA stack from Visual Studio Step into UA stack from IntelliJ, Eclipse, or VS Code
Typical use case Windows-only HMI extension, WPF / WinForms front-end Linux service, REST gateway, Kafka producer, time-series pipeline

If your application must run on a Linux server, an Android tablet, or inside a Docker container, the Java binding is the better fit. If the application is a Windows-only HMI extension written in WPF or WinForms and you need to bind the UA events into UI components, the .NET stack has tighter tooling. The two bindings can also be mixed: a Java back-end reads from SIMATIC NET and a VB.NET front-end consumes the back-end over REST, MQTT, or WebSocket.

Verification, Acceptance Test, and Troubleshooting

Use the following acceptance procedure before handing the integration over to operations:

  1. From the Java host, open any OPC UA browser (for example, the free Prosys OPC UA Browser) and call GetEndpoints on opc.tcp://<simatic-net-host>:4840. Confirm at least one None or Basic256Sha256 endpoint is returned.
  2. Browse the UA AddressSpace. The S7 tags should appear under the SIMATIC NET default namespace (typically ns=2 or ns=4 depending on the project version).
  3. Read a known static value stored in DB100.DBD0 from the S7-300 program and verify it matches what STEP 7 online shows for the same DB.
  4. Force a value change in the S7-300 with a watch table and confirm the Java subscription receives a notification within the configured publishingInterval.
  5. Inspect the source and server time-stamps of the received DataValue. The server time must be monotonically increasing; large gaps indicate the SIMATIC NET host is overloaded or the S7 connection is being throttled.
  6. Disconnect and reconnect the Java client to verify session recovery and automatic re-subscription of monitored items.
Symptom Likely cause Fix
Java client cannot reach opc.tcp://host:4840 Windows Firewall on the SIMATIC NET host blocking inbound 4840 Add an inbound rule for 4840/tcp to scsas.exe / SIMATIC NET service; on Linux clients open the Java host outbound 4840/tcp
Endpoints visible but session returns Bad_SecurityChecksFailed Mismatched SecurityPolicy or MessageSecurityMode Match SecurityPolicy (None, Basic256Sha256, etc.) and MessageSecurityMode.Sign or SignAndEncrypt on both sides
Bad_NodeIdUnknown on a tag The S7 symbol was not added to the OPC Server's symbol table or DB number is wrong Re-export the S7 symbols in the SIMATIC NET configuration; verify the absolute address in the S7-300 program
Values update slowly (multi-second) Sampling interval on SIMATIC NET set too high, or S7 connection is being throttled by the CP Reduce the samplingInterval on the monitored item; check CP 343-1 connection resources; reduce publishingInterval
Connection drops every few minutes KeepAliveCount exceeded; the SIMATIC NET service is being stopped by a Windows service manager or a domain policy Verify the SIMATIC NET service is set to Automatic and not killed by a watchdog; raise KeepAliveCount and LifeTimeCount
Java client works in Eclipse / IntelliJ but fails from a packaged JAR Bouncy Castle or Milo native dependencies missing from the classpath; SPI service files not merged Build a fat-jar with the Maven Shade plugin; verify META-INF/services files for Milo, Bouncy Castle, and Netty are included
Bad_CommunicationError after working for hours SIMATIC NET PC lost the S7 connection to the S7-300 CP Check CP 343-1 link LEDs, the S7 connection status in the SIMATIC NET Commissioning tool, and any switch port errors between the PC and the CP

Field-Proven Caveats

  • The OPC UA server in SIMATIC NET only becomes available from the CD2800 build onwards for S7 connections, per Siemens support entry 31675909. Older installations must be upgraded before they can serve UA to a Java client.
  • The S7-300 cannot be replaced by an S7-1200 / S7-1500 in the same SIMATIC NET project — the PC station is still required for older CPUs even when the rest of the plant is on newer controllers. The cleanest path is a separate PC station for each controller family.
  • Eclipse Milo is a community project, not OPC Foundation certified. For SIL / safety-related or audit-controlled deployments select a certified SDK (Prosys or OPC Foundation commercial stack).
  • The OPC Foundation Java stack is in long-term maintenance, so Eclipse Milo and Prosys are the realistic long-term Java options.
  • Always time-stamp the application value with Instant.now() at the notification handler, not just at the file write. Notifications can queue inside the server and arrive in bursts; the application time-stamp at the moment of consumption is what regulatory archives expect.
  • For long-running logging, log a session ID and subscription ID so a restart can re-attach to existing monitored items rather than recreating the entire AddressSpace browse.

Frequently Asked Questions

Can an S7-300 expose OPC UA directly without a PC?

No. The S7-300 CPU family has no built-in OPC UA server. You need a Windows PC running SIMATIC NET as the OPC UA server and an S7 connection to the controller. Only the S7-1200 and S7-1500 families have a native OPC UA server, as documented in the TIA Portal V20 OPC UA guide.

Which Java library should I use for an OPC UA client?

For a non-regulated application Eclipse Milo is the most widely deployed open-source Java SDK (EPL-2.0 license). For a regulated or audit-controlled environment use the Prosys OPC UA Java SDK or the commercial OPC Foundation Java stack, both of which hold OPC Foundation compliance certification.

Does the Java client need a SIMATIC NET license?

No. The SIMATIC NET license is on the server side (the PC running the OPC UA Server). The Java client only needs the OPC UA Java SDK, which is either open source (Eclipse Milo) or commercially licensed to the application vendor, not to the customer deploying it.

How do I time-stamp the measured value in Java?

Either use the source time-stamp on the DataValue returned by a subscription notification, or stamp the value with Instant.now() the moment the notification handler fires. The latter is the application time-stamp and is what most process-data archives require for compliance.

Does the Java code change when I migrate from S7-300 to S7-1500?

The Java client code does not change at all. Only the server endpoint URL and (optionally) the SecurityPolicy change. The S7-1500 with a built-in OPC UA server replaces the SIMATIC NET PC entirely, so you repoint the client to opc.tcp://<s7-1500-cpu-ip>:4840 and the same Milo / OPC Foundation client code reads the same NodeIds.

Is the Java code different from the VB.NET sample in the SIMATIC NET manual?

No — the OPC UA protocol is identical. The Java and VB.NET bindings differ only in async style (CompletableFuture vs async/await) and project tooling (Maven vs NuGet). The session, subscription, monitored item, and DataValue objects map one-to-one between the two stacks.

Back to blog