libplctag 1.5.2

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package libplctag --version 1.5.2                
NuGet\Install-Package libplctag -Version 1.5.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="libplctag" Version="1.5.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add libplctag --version 1.5.2                
#r "nuget: libplctag, 1.5.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install libplctag as a Cake Addin
#addin nuget:?package=libplctag&version=1.5.2

// Install libplctag as a Cake Tool
#tool nuget:?package=libplctag&version=1.5.2                

libplctag.NET

libplctag is a C library for Linux, Android, Windows and macOS that uses EtherNet/IP or Modbus TCP to read and write tags in PLCs.

libplctag.NET provides wrapper packages for libplctag, with an API naturalised to .NET by adding the following features:

  • Values are strongly-typed (both Atomic types and User-Defined Types).
  • Errors are thrown as Exceptions
  • Async/Await
  • Native resource cleanup

How to use

// Example tag configuration for a global DINT tag in an Allen-Bradley CompactLogix/ControlLogix PLC
var myTag = new TagDint()
{
    Name = "SomeDINT",
    Gateway = "10.10.10.10",
    Path = "1,0",
    PlcType = PlcType.ControlLogix,
    Protocol = Protocol.ab_eip
};

// Read the value from the PLC and output to console
int output = myTag.Read();        
Console.WriteLine($"Original value: {output}");

// Write a new value to the PLC, then read it back, and output to console
myTag.Write(37);    
output = myTag.Read();
Console.WriteLine($"Updated value: {output}");

See the examples projects for further detail and usage:

Introduction

A tag is a local reference to a region of PLC memory. Depending on the PLC type and protocol the region may be named. For some protocols, the region is simply a type and register number (e.g. Modbus). For other protocols, it is a name, possible array element, field names etc. (e.g. a CIP-based PLC).

Your program directly controls the resources associated with the connection to the PLC. It initializes these resources through the Initialize() function and frees the resources used with the Dispose() function. The lowest level of access to a tag is via the Read() and Write() operations. In most cases you must explicitly call these functions to write to the PLC or read from the PLC. There are also attributes that can be passed when creating a Tag to make it either automatically write to the PLC when the local copy of the tag is updated or read from the PLC periodically, or both. Once initialized, the tag memory is exposed as a byte array, and can be manipulated using various data accessors.

Libplctag does not expose the concept of a PLC. Just tags.

Read more on the libplctag wiki.

Tag

libplctag.NET provides a wrapper for the C API naturalised for .NET. The Tag class is intended to be functionally equivalent to the C API.

For example:

Some methods are presented slightly differently due to the differences in languages and language idioms. For example, the counterpart to Initialize(..) is plc_tag_create(..) and the tag attributes are specified as properties (e.g. Tag.Path).

Tag<M,T> and Mappers

In your .NET application, you will usually need to convert the raw bytes into a .NET type. It is possible to use GetInt32() and SetInt32() (and others) provided by the Tag class to perform this conversion, and most of the time, there will only be one sensible way to interpret these bytes for a given tag.

For example, a DINT tag defined in a PLC is a 32bit signed integer, and this would be exposed as a little-endian encoded 4-byte array. The natural choice for a C# type would be int - it would be rare to want to work with this data as a float or a 4-byte ASCII string for example.

To this end, libplctag.NET offers a typed tag class Tag<M,T> that exposes the tag value as a C# type instead of the complete set of Getter/Setter functions. This class pairs with an IPlcMapper, which encapsulates the mapping between a .NET type (e.g. int, float) and the PLC type (e.g. DINT, REAL) by calling the appropriate functions on a Tag (as well as providing other information that libplctag needs for this mapping).

class DintPlcMapper : IPlcMapper<int>
{
    public PlcType PlcType { get; set; }
    public int? ElementSize => 4;
    public int[] ArrayDimensions { get; set; }
    public int? GetElementCount() => 1;
    public int Decode(Tag tag, int offset) => tag.GetInt32(offset);
    public void Encode(Tag tag, int offset, int value) => tag.SetInt32(offset, value);
}

var myTag = new Tag<DintPlcMapper, int>(){...configuration...};
myTag.Initialize();
myTag.Value = 1234;
myTag.Write();

In general, you will need prior knowedge of the structure of the tag data, and you may need to reverse-engineer it. An example for reverse engineering a UDT can be found here.

Because the structure of the data depends on many factors (PLC Make/model, Protocol, and even the tag Name), libplctag.NET does not provide built-in Mappers for all types. The manuals provided by your device manufacturer are the best source of information on these details.

Types

libplctag namepsace

  • Tag - A wrapper around the core libplctag library tag with an interface naturalised to .NET.
  • Tag<M,T> - A wrapper that exposes a .NET type (generic parameter T) instead of Data Accessors. The data access logic is delegated to an IPlcMapper (generic parameter M).
  • ITag - an interface that is implemented by Tag<M,T>.
  • Libplctag - A static class used to access some additional features of the libplctag base library such as global debug levels and logging.
  • Enum types such as DebugLevel.
  • Supporting types such as TagEventArgs.

All types are shipped with XML documentation, so the full API is discoverable in your IDE.

libplctag.DataTypes namespace

Of note are TagInfoPlcMapper and UdtInfoMapper, which can be used to list the tags in a ControlLogix PLC.

libplctag.DataTypes.Simple namespace

In simple cases such as atomic tags (e.g.DINT) or arrays of atomic tags (e.g. LREAL[x,y]), we provide classes that pair a built-in IPlcMapper with the natural .NET type:

libplctag.NativeImport

The libplctag package depends on the core libplctag libraries which are written in C and are released as native binaries. The delivery of these files, and the interop to the .NET environment is provided by the libplctag.NativeImport package.

Information on this package can be found here.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on libplctag:

Package Downloads
clxx.libplctag.NET

A high level API for reading/writing tags to Rockwell CLX PLCs. ControlLogix and CompactLogix.

MgSoftDev.IndustrialController.AllenBradley.LibPlcTagNetCore

Package Description

Acuit.Pinpoint.IO.PlcCommunication

Provides types for communicating with PLCs. These types provide a thin layer over libplctag.NET to facilitate unit testing abstractions.

MRIIOT.DIME

Data In Motion Enterprise

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on libplctag:

Repository Stars
Open-Industry-Project/Open-Industry-Project
Free and Open-source warehouse/manufacturing development framework and simulator
libplctag/libplctag.NET
A .NET wrapper for libplctag.
Version Downloads Last updated
1.6.0-alpha.0 623 7/26/2024
1.5.2 8,757 7/13/2024
1.5.1 529 7/12/2024
1.5.0 109 7/12/2024
1.4.1 1,447 6/22/2024
1.4.0 422 6/15/2024
1.3.1 115 6/15/2024
1.3.0 112 6/15/2024
1.2.1 4,231 5/29/2024
1.2.0 21,590 11/6/2023
1.2.0-alpha.2 91 10/29/2023
1.2.0-alpha.1 970 10/22/2023
1.2.0-alpha.0 2,455 7/4/2023
1.1.1 42,640 12/14/2022
1.1.1-beta.0 142 12/1/2022
1.1.1-alpha.1 146 11/25/2022
1.1.1-alpha.0 133 11/24/2022
1.1.0 6,929 10/9/2022
1.1.0-alpha.2 192 10/1/2022
1.1.0-alpha.1 2,306 12/27/2021
1.0.14-beta.6 1,395 12/21/2021
1.0.14-beta.5 619 11/5/2021
1.0.14-beta.4 197 10/28/2021
1.0.14-beta.3 189 10/27/2021
1.0.14-beta.2 304 10/23/2021
1.0.14-beta.1 307 10/23/2021
1.0.13 11,647 10/14/2021
1.0.12 458 10/14/2021
1.0.11 2,200 9/24/2021
1.0.10 520 9/22/2021
1.0.9 506 9/18/2021
1.0.8 605 8/30/2021
1.0.7 1,139 8/16/2021
1.0.7-alpha.3 199 8/13/2021
1.0.7-alpha.2 352 7/20/2021
1.0.7-alpha 126 7/20/2021
1.0.6 786 7/18/2021
1.0.5 1,846 5/29/2021
1.0.4 3,616 3/7/2021
1.0.4-beta.1 176 2/16/2021
1.0.3 1,164 1/11/2021
1.0.2 497 1/6/2021
1.0.1 1,351 11/15/2020
1.0.0 859 9/16/2020
0.0.29-alpha01 432 9/10/2020
0.0.28-alpha02 361 9/9/2020
0.0.28-alpha01 344 9/9/2020
0.0.27-alpha13 392 8/4/2020
0.0.27-alpha12 435 7/29/2020
0.0.27-alpha11 373 7/27/2020
0.0.27-alpha10 359 7/24/2020
0.0.27-alpha09 412 7/21/2020
0.0.27-alpha08 403 7/19/2020
0.0.27-alpha07 358 7/14/2020
0.0.27-alpha06 345 7/14/2020
0.0.27-alpha05 349 7/14/2020
0.0.27-alpha04 413 7/9/2020
0.0.27-alpha03 427 7/9/2020
0.0.27-alpha02 366 7/9/2020
0.0.27-alpha01 414 7/3/2020
0.0.26-alpha01 350 7/1/2020
0.0.25-alpha01 369 6/30/2020
0.0.24 920 4/4/2020
0.0.22 687 1/10/2020
0.0.21 649 1/4/2020
0.0.20-alpha 410 1/4/2020
0.0.19-alpha 412 1/4/2020
0.0.18-alpha 403 1/4/2020
0.0.17-alpha 419 1/4/2020
0.0.16-alpha 423 1/4/2020
0.0.15-alpha 453 1/4/2020
0.0.14-alpha 436 1/3/2020
0.0.13-alpha 408 1/3/2020
0.0.12-alpha 441 1/3/2020
0.0.11-alpha 406 1/3/2020