L5Sharp 0.9.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package L5Sharp --version 0.9.1                
NuGet\Install-Package L5Sharp -Version 0.9.1                
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="L5Sharp" Version="0.9.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add L5Sharp --version 0.9.1                
#r "nuget: L5Sharp, 0.9.1"                
#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 L5Sharp as a Cake Addin
#addin nuget:?package=L5Sharp&version=0.9.1

// Install L5Sharp as a Cake Tool
#tool nuget:?package=L5Sharp&version=0.9.1                

L5Sharp

A C# library for interacting with Rockwell's L5X import/export files. The goal of this project was to provide a simple and reusable library for querying and manipulating L5X files to aid in the creation of tools that automate tasks related RSLogix 5000 PLC development.

Getting started

This project is still under development and in a preview phase, but you can start using it by adding the package from Nuget.

Install-Package L5Sharp

If you would like to contribute, have feedback or questions, please reach out! If you are using or like the progress being made, please leave a star. Thanks!

Overview

The following is a basic walk through of some of the high level features ofr the library. I plan to create a more in depth wiki at some point, but for now please refer to the following information to understand how to use the library.

Entry Point

The main entry point to the L5X is the LogixContent class. Use the factory methods Load to load a file or Parse to parse a string, exactly how you would with XDocument.

var content = LogixContent.Load("C:\PathToMyFile\FileName.L5X");

LogixContent has a L5X property, which is essentially the root content element of the document. So if you ever need access the XML directly, use that property. It also contains the root content attributes, such as target type, target component, software version, and others.

var content = LogixContent.Load(Known.Test);

content.L5X.Should().NotBeNull();
content.L5X.SchemaRevision.Should().Be(new Revision());
content.L5X.SoftwareRevision.Should().Be(new Revision(32, 02));
content.L5X.TargetName.Should().Be("TestController");
content.L5X.TargetType.Should().Be("Controller");
content.L5X.ContainsContext.Should().Be(false);
content.L5X.Owner.Should().Be("tnunnink, EN Engineering");
content.L5X.ExportDate.Should().NotBeNull();

Querying Content

Once the LogixContent is created, you can use the component collection methods to get access to most of the primary L5X components, such as Tag, DataType, Module, Program, and more. The following shows some simple querying via the tags component collection interface.

//Get all controller tags. 
var controllerTags = content.Tags();

//Get all tags in a program by providing a scope name.
var programTags = content.Tags("MainProgram");

//Get a tag by name.
var myTag = content.Tags().Find("MyTag");

//Use LINQ to query further.
var timersInMaingProgram = content.Tags("MainProgram").Where(t => t.DataType == "TIMER");

Modifying Content

Modifying components is simple as well. The same component collection interface offers methods for adding, removing, and replacing components.

//Add a new component.
var tag = new Tag
{
    Name= "NewTag";
    Data = new DINT();
};

content.Tags().Add(tag);

//Remove an existing component.
var result = content.Tags().Remove("MyTag");

//Repalce an existing component.
var result = content.Tags().Replace(tag);

//Save changes when done.
content.Save("C:\PathToMyOutputFile\FileName.L5X");

More On Querying

Tags are unique components in that they have different scopes. We have to specify a scope to know where to modify the existing collection. For example, if you call Tags().Add(tag), where do we add the tag? This is why you have to specify a scope name for the tags collection when interacting with it. The same applies to Routine.

But what if I just want to query across the entire file, how do I do that? The answer is use the Query<T>() method and specify the type to query as the generic argument.

var allTagsInFile = content.Query<Tag>();

NOTE: Query<T>() just returns an IEnumerable<T>, so it is essentially read only, but still allows you to form more complex queries using LINQ and the strongly typed components in the library.

Tag Data

Tag components also contain simple or complex data structures. This library includes prebuilt Atomic and Predefined data structures that allow in memory creation of tag data.

When creating a Tag component, initialize the Data property to get a new instance of instantiated tag data for the type.

The following creates a tag with the predefined TIMER tag structure.

var tag = new Tag
{
    Name = "TimerTag"
    Data = new TIMER()
};

You can then get members of the tag using the Member() or Members() methods.

//Get the preset member of the timer tag.
var pre = tag.Member("PRE");

//Set the value of the DINT preset member.
pre.Data = 5000;

//Get all tag members.
var members = tag.Members();

When serialized back to the L5X, this component will include all the tag data you have set on the component. Nice!

Custom Data Types

The goal is to continue adding all predefined data structures, but if one you require is missing, or if you have a user defined type that you want to create, you can add them yourself.

Just inherit from StructureType and start creating type members like so.

/// <summary>
/// A test type used to test nested complex data structure code
/// </summary>
public class MyNestedType : StructureType
{
    public MyNestedType() : base(nameof(MyNestedType))
    {
    }

    public override DataTypeClass Class => DataTypeClass.User;

    /// <summary>
    /// A simple boolean member
    /// </summary>
    public BOOL Indy { get; set; } = new();

    /// <summary>
    /// A string member
    /// </summary>
    public STRING Str { get; set; } = new();

    /// <summary>
    /// A nested timer member
    /// </summary>
    public TIMER Tmr { get; set; } = new();

    /// <summary>
    /// A nested user defined type
    /// </summary>
    public MySimpleType Simple { get; set; } = new();

    /// <summary>
    /// A nested array of atomic values. 
    /// Using this Logix.Array will create array filled with instantiated types.
    /// This will aviod issues with the structure type members collection containing
    /// null data for you members.
    /// </summary>
    public BOOL[] Flags { get; set; } = Logix.Array<BOOL>(10).ToArray();

    /// <summary>
    /// A nested array of structure types.
    /// </summary>
    public MESSAGE[] Messages { get; set; } = Logix.Array<MESSAGE>(10).ToArray();
}

IMPORTANT: When creating custom types, it is important to make them properties, and initialize them straight away. Internally, StructureType will generate the Members collection using reflection and adding all ILogixType members. If not initialized, Members will contain null instances of the data types, which may cause you some runtime exceptions when trying to access their members.

Documentation

For further reading on Rockwell's import/export features, see the following published document. Logix 5000 Controllers Import/Export

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 netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen 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.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on L5Sharp:

Package Downloads
L5Sharp.Extensions

A library for intuitively interacting with Rockwell's L5X import/export files.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
4.7.1 78 11/15/2024
4.7.0 69 11/15/2024
4.6.0 84 11/14/2024
4.5.0 85 11/11/2024
4.4.0 87 10/31/2024
4.3.0 81 10/30/2024
4.2.0 126 10/8/2024
4.1.0 87 10/7/2024
4.0.0 89 10/5/2024
3.3.1 105 9/24/2024
3.3.0 130 7/29/2024
3.2.0 121 7/7/2024
3.1.0 94 7/5/2024
3.0.0 114 6/3/2024
2.3.2 90 5/9/2024
2.3.1 344 5/6/2024
2.3.0 123 5/4/2024
2.2.1 111 4/29/2024
2.2.0 117 4/23/2024
2.1.0 110 4/18/2024
2.0.0 174 4/4/2024
0.19.7 135 3/27/2024
0.19.6 232 3/22/2024
0.19.5 128 3/9/2024
0.19.4 123 2/5/2024
0.19.3 104 2/3/2024
0.19.1 116 1/16/2024
0.19.0 95 1/16/2024
0.18.3 127 1/8/2024
0.18.2 113 1/4/2024
0.18.1 111 12/29/2023
0.18.0 157 12/9/2023
0.17.0 145 12/8/2023
0.16.1 128 11/28/2023
0.16.0 124 11/28/2023
0.15.2 186 8/18/2023
0.15.1 151 8/17/2023
0.15.0 196 8/16/2023
0.14.0 195 8/9/2023
0.13.0 201 8/6/2023
0.12.0 180 8/1/2023
0.11.0 171 7/12/2023
0.10.1 235 3/31/2023
0.10.0 202 3/31/2023
0.9.2 208 3/24/2023
0.9.1 222 3/15/2023
0.9.0 226 3/15/2023
0.8.0 227 3/15/2023
0.7.0 211 3/14/2023
0.6.0 217 3/14/2023
0.5.3 221 3/13/2023
0.5.2 218 3/13/2023
0.5.0 222 3/13/2023
0.4.0 230 3/12/2023
0.3.0 233 3/5/2023
0.2.0 283 3/1/2023

Initial release.