jfk-solutions.TiaFileFormat.S7CommPlus
2025.10.22.1
dotnet add package jfk-solutions.TiaFileFormat.S7CommPlus --version 2025.10.22.1
NuGet\Install-Package jfk-solutions.TiaFileFormat.S7CommPlus -Version 2025.10.22.1
<PackageReference Include="jfk-solutions.TiaFileFormat.S7CommPlus" Version="2025.10.22.1" />
<PackageVersion Include="jfk-solutions.TiaFileFormat.S7CommPlus" Version="2025.10.22.1" />
<PackageReference Include="jfk-solutions.TiaFileFormat.S7CommPlus" />
paket add jfk-solutions.TiaFileFormat.S7CommPlus --version 2025.10.22.1
#r "nuget: jfk-solutions.TiaFileFormat.S7CommPlus, 2025.10.22.1"
#:package jfk-solutions.TiaFileFormat.S7CommPlus@2025.10.22.1
#addin nuget:?package=jfk-solutions.TiaFileFormat.S7CommPlus&version=2025.10.22.1
#tool nuget:?package=jfk-solutions.TiaFileFormat.S7CommPlus&version=2025.10.22.1
TiaFileFormat.S7CommPlus
Integration helpers for combining online S7CommPlusDriver metadata with
TiaFileFormat models.
This library is aimed at tooling that reads Siemens S7-1200/S7-1500 PLC data
over S7CommPlus and wants to reuse the same block, network, call-path, and
alarm-source concepts used by TiaFileFormat.
Features
- Convert online PLC block content into
TiaFileFormatCodeBlockmodels. - Build a catalog of online blocks, call sites, instance DB candidates, and calling paths.
- Resolve
S7CommPlusAlarmsource relation IDs back to source blocks and known calling paths. - Build TIS watch request and simple trigger blobs for online block-view experiments.
- Create, discover, activate, observe, and decode PLC-owned traces through a typed high-level API.
- Discover downloaded TIA watch-table definitions over S7CommPlus, including rows, multilingual comments, display formats and runtime addresses.
- Discover PROFINET devices on local network interfaces with DCP identify requests.
Package
The package is published as:
jfk-solutions.TiaFileFormat.S7CommPlus
NuGet: https://www.nuget.org/packages/jfk-solutions.TiaFileFormat.S7CommPlus/
Requirements
- .NET SDK 8.0 or newer
- Target frameworks:
net8.0andnet9.0 jfk-solutions.TiaFileFormat2026.8.27.3 or newerDotNetProjects.S7CommPlusDriver3.3.0 or newer- Network capture support for
ProfinetClientFinderthrough SharpPcap/Npcap
Build
dotnet restore .\TiaFileFormat.S7CommPlus.slnx
dotnet build .\TiaFileFormat.S7CommPlus.slnx
Building the project also creates a NuGet package because
GeneratePackageOnBuild is enabled in the project file.
Usage
Discover Downloaded Watch Tables
var catalog = await new S7CommPlusWatchTableClient(client).GetWatchTablesAsync();
foreach (var table in catalog.Tables)
Console.WriteLine($"{table.Name}: {table.Entries.Count} rows");
This reads native object 53, attribute 7579 (WebServer.VariableTables) over
the existing S7CommPlus session. It does not use HTTP, a web login, TIA Portal,
or a write-enabled connection. Driver 5.0.0 is sufficient. The raw-read bridge
adapts the driver's public GetValue and blob-entry fields because its protocol
value classes are internal.
Only tables selected under the CPU's Web server > Watch tables settings and
downloaded to the CPU are available. Tables kept solely in the engineering
project are not present in this attribute. Publication is needed to place the
definitions on the CPU; reading them does not depend on web-server login rights.
CanWrite describes the downloaded table's configuration and does not grant
permission to write signals. Definitions and CPU state are never changed by discovery.
The decoder handles formats 1–3, preserves blank/comment rows, and rejects unknown
versions, truncated records and invalid references. Native runtime addresses contain
little-endian RID/local-ID/CRC words inside the big-endian record format. Format 3
preserves comments by LCID. S7CommPlusWatchTableDecoder.Decode also accepts a saved
sparse-blob snapshot without a live connection.
Set S7COMMPLUS_WATCH_TABLE_TEST_ADDRESS to an authorized PLC to run the opt-in
WatchTableApiTests device test. Ordinary tests use synthetic protocol data.
Create and Activate a Trace
Wrap a connected S7CommPlusClient in S7CommPlusTraceClient. The wrapper
resolves symbols, compiles the definition, installs the trace, and activates it
before CreateTraceAsync returns.
using S7CommPlusDriver;
using TiaFileFormat.S7CommPlus;
var traces = new S7CommPlusTraceClient(client);
var definition = new S7CommPlusTraceDefinition("Valve transition")
{
RecordingDuration = S7CommPlusTraceDuration.FromSamples(10_000),
Trigger = S7CommPlusTraceTrigger.RisingEdge(
"ValveOpen",
S7CommPlusTracePretrigger.FromSamples(2_000)),
Storage = S7CommPlusTraceStorage.MemoryCard(
measurementLimit: 5,
S7CommPlusTraceStorageFullBehavior.OverwriteOldest),
ContinueAfterDisconnect = true
};
definition.Signals.Add(S7CommPlusTraceSignal.FromSymbol("ProcessByte"));
definition.Signals.Add(S7CommPlusTraceSignal.FromSymbol("ValveOpen"));
await using var trace = await traces.CreateTraceAsync(definition);
var measurement = await traces.WaitForTraceMeasurementAsync(trace);
var values = measurement.GetSeries("ProcessByte").GetValues<byte>();
ContinueAfterDisconnect defaults to true. The installed job therefore keeps
waiting, recording, or saving when the creating connection closes. Disposing
S7CommPlusTrace only detaches its temporary notification subscription.
Discover Existing Traces and Measurements
Discovery includes traces installed by other clients. Configuration metadata is decoded when its format is supported; the raw protocol blobs remain available for unknown versions.
var installed = await traces.GetInstalledTracesAsync();
var selected = installed.Single(item => item.Reference.Name == "Valve transition");
// Attach without reinstalling or activating the trace.
await using var attached = await traces.OpenTraceAsync(selected.Reference);
// Explicit lifecycle operations work with rediscovered references.
await traces.DeactivateTraceAsync(selected.Reference);
await traces.ActivateTraceAsync(selected.Reference); // re-arm
// Current results and memory-card measurements have content-stable references.
var available = await traces.GetTraceMeasurementsAsync(selected.Reference);
if (available.Count != 0)
var exactResult = await traces.ReadTraceMeasurementAsync(available[0].Reference);
var retained = await traces.GetStoredTraceMeasurementsAsync();
if (retained.Count != 0)
{
var stored = await traces.ReadStoredTraceMeasurementAsync(retained[0].Reference);
await traces.DeleteStoredTraceMeasurementAsync(retained[0].Reference);
}
await traces.DeleteTraceAsync(selected.Reference);
Creation, activation, deactivation, trace deletion, and stored-measurement
deletion require the underlying client to have WriteEnabled = true.
Discovery, result reading, and attachment are read-only. See
Documentation/s7commplus/traces.md for
all trigger modes, pretrigger behavior, storage, reconnect semantics, and the
low-level/high-level package boundary.
Build an Online Block Call-Path Catalog
OnlineBlockCallPathCatalogBuilder reads the online block list and selected
block metadata. The resulting catalog can be cached and reused by UIs or alarm
workflows. Online metadata extraction remains in this package, while call-graph
construction uses the protocol-neutral builder from TiaFileFormat that also
supports offline projects.
using TiaFileFormat.S7CommPlus;
var catalog = await OnlineBlockCallPathCatalogBuilder.BuildAsync(client);
foreach (var path in catalog.CallingPaths)
{
Console.WriteLine(path.DisplayName);
}
foreach (var warning in catalog.Warnings)
{
Console.WriteLine(warning);
}
If another workflow has already loaded block metadata, reuse it instead of reading it again from the PLC:
var catalog = OnlineBlockCallPathCatalogBuilder.BuildFromLoadedBlocks(
blocks,
loadedBlockContents);
Resolve Alarm Sources
S7CommPlusDriver exposes alarm source identifiers decoded from
CpuAlarmId. This package resolves those identifiers against an existing
catalog so a UI can jump from an alarm to the related block and calling paths.
using TiaFileFormat.S7CommPlus;
var catalog = await OnlineBlockCallPathCatalogBuilder.BuildAsync(client);
var alarms = await client.GetActiveAlarmsAsync(languageId: 1031, textLists);
var selectedAlarm = alarms[0];
var source = catalog.ResolveAlarmSource(selectedAlarm);
if (source.SourceBlock != null)
{
Console.WriteLine(
$"{source.SourceBlock.Name} ({source.SourceBlock.Type}{source.SourceBlock.Number})");
}
foreach (var path in source.CallingPaths)
{
Console.WriteLine(path.DisplayName);
}
ResolveAlarmSource does not read from the PLC. It only uses the supplied
catalog.
Convert Online Block Content
OnlineBlockConverter turns an online S7CommPlusClientBlockContent object
into a TiaFileFormat.Wrappers.CodeBlocks.CodeBlock.
using TiaFileFormat.S7CommPlus;
var content = await client.GetBlockContentAsync(block.RelationId);
var codeBlock = OnlineBlockConverter.GetOnlineCodeBlock(content);
foreach (var network in codeBlock.Networks)
{
Console.WriteLine($"{network.SourceRefId}: {network.Title}");
}
Create TIS Watch Requests
OnlineBlockViewTisWatchRequestBuilder contains low-level helpers for building
request and trigger blobs used by S7CommPlus TIS watch jobs.
using S7CommPlusDriver;
using TiaFileFormat.S7CommPlus;
var request = OnlineBlockViewTisWatchRequestBuilder.CreateForBlock(
S7CommPlusBlockType.FB,
blockNumber: 3001,
watchPoints);
This API is intentionally close to the protocol. See
Documentation/s7commplus/online-block-view.md for the reverse-engineering
notes, live PLC findings, and current limitations.
Repository Layout
.
|-- Documentation/
| `-- s7commplus/ Research notes and protocol references
|-- TiaFileFormat.S7CommPlus/
| |-- *.cs Library source
| |-- README.md Package-focused README content
| `-- *.csproj
`-- TiaFileFormat.S7CommPlus.slnx
Notes on Online Block View Support
The TIS online block-view code is based on packet captures, Siemens metadata, and live PLC experiments. Simple block triggers and request/result layout are implemented, but exact S7-1500 Plus call-path disambiguation for ambiguous FB instances still depends on MC7Plus trigger-expression generation.
For implementation details and open questions, start with:
Documentation/s7commplus/online-block-view.mdDocumentation/s7commplus/*.pdf
License
MIT. Visit http://jfk-solutions.de for more information.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Framework | net481 is compatible. |
-
.NETFramework 4.8.1
- DotNetProjects.S7CommPlusDriver (>= 5.0.0)
- jfk-solutions.TiaFileFormat (>= 2026.10.16.1)
- PacketDotNet (>= 1.4.8)
- SharpPcap (>= 6.3.1)
- zlib.net-mutliplatform (>= 1.1.0)
-
net8.0
- DotNetProjects.S7CommPlusDriver (>= 5.0.0)
- jfk-solutions.TiaFileFormat (>= 2026.10.16.1)
- PacketDotNet (>= 1.4.8)
- SharpPcap (>= 6.3.1)
- zlib.net-mutliplatform (>= 1.1.0)
-
net9.0
- DotNetProjects.S7CommPlusDriver (>= 5.0.0)
- jfk-solutions.TiaFileFormat (>= 2026.10.16.1)
- PacketDotNet (>= 1.4.8)
- SharpPcap (>= 6.3.1)
- zlib.net-mutliplatform (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2025.10.22.1 | 90 | 10/21/2026 |
| 2025.10.21.1 | 88 | 10/21/2026 |
| 2025.10.16.1 | 108 | 10/16/2026 |
| 2025.10.10.1 | 97 | 10/10/2026 |
| 2025.9.9.2 | 191 | 9/9/2026 |
| 2025.9.9.1 | 109 | 9/9/2026 |
| 2025.8.27.1 | 122 | 8/27/2026 |
| 2025.6.24.1 | 400 | 6/24/2025 |
| 1.25.6.17 | 261 | 6/17/2025 |