### Install L5Sharp.Gateway NuGet Package Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Install the L5Sharp.Gateway NuGet package using the Package Manager Console. ```powershell Install-Package L5Sharp.Gateway ``` -------------------------------- ### Install L5Sharp.Catalog via NuGet Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Use this command to install the L5Sharp.Catalog package using the NuGet Package Manager Console. ```powershell Install-Package L5Sharp.Catalog ``` -------------------------------- ### Install L5Sharp.Core via NuGet Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the dotnet CLI to add the L5Sharp.Core package to your project. ```bash dotnet add package L5Sharp.Core ``` -------------------------------- ### Install L5Sharp Package Source: https://github.com/tnunnink/l5sharp/wiki/Home Add the L5Sharp package to your project using NuGet to begin using the library. ```powershell Install-Package L5Sharp ``` -------------------------------- ### Fast Component Lookups in L5Sharp Source: https://context7.com/tnunnink/l5sharp/llms.txt Demonstrates how to perform O(1) lookups for various components like DataTypes, Modules, Tags, and Rungs using the L5Sharp library. Includes examples for retrieving components by name, full path, and checking for their existence. ```csharp var project = L5X.Load("MyController.L5X"); // Get a component by name with generic type var dataType = project.Get("MyCustomType"); // Get a module by name if (project.TryGet("LocalModuleName", out var module)) { Console.WriteLine($"Module found: {module.Name}"); } // Get a program-scoped tag with full path var programTag = project.Get("Program:MainProgram.MyTagName"); // Get a nested tag member with array indexing var nestedMember = project.Get("Program:SomeProgram.MyTagName.Member[2].Value"); // Get a rung by number, program, and routine if (project.TryGet(12, "MainProgram", "MainRoutine", out var rung)) { Console.WriteLine($"Rung text: {rung.Text}"); } // Check if a reference exists var reference = Reference.To("MyTag", Scope.Controller); bool exists = project.Contains(reference); // Find all references to a component name var references = project.References("MyTagName"); foreach (var r in references) { Console.WriteLine($"Referenced at: {r.Path}"); } ``` -------------------------------- ### Lookup Component Using Reference String Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the Get method with a reference string to retrieve a component from the indexed L5X project. ```csharp var component = project.Get("tag://MyProgram/MyTagName.SomeMember.Array[9].Element.12"); ``` -------------------------------- ### Add L5Sharp.Generators Package Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Generators/README.md Install the L5Sharp.Generators package as an analyzer/development dependency in your project. ```xml ``` -------------------------------- ### Fast Component Lookup by Name Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the Get method for O(1) time lookups of components by their name. The L5X is indexed on the first call. ```csharp // Gets a component by name. var component = project.Get("MyCustomType"); ``` -------------------------------- ### Creating User-Defined Data Types (UDTs) in L5Sharp Source: https://context7.com/tnunnink/l5sharp/llms.txt Provides examples of defining custom data type structures with typed members, dimensions, and descriptions using the L5Sharp library. Demonstrates adding, updating, and removing members, adding UDTs to a project, and converting them to tags or LogixData. ```csharp // Create a new data type with constructor var myType = new DataType("ProcessData"); // Add members using fluent API myType.AddMember("Speed", "REAL", m => { m.Description = "Process speed in RPM"; m.Radix = Radix.Float; }) .AddMember("Temperature", "REAL", m => m.Description = "Current temperature") .AddMember("Status", "DINT", m => m.Radix = Radix.Binary) .AddMember("AlarmCode", "INT") .AddMember("DataBuffer", "DINT", m => m.Dimension = 10); // Update an existing member myType.UpdateMember("Speed", m => m.Description = "Updated speed description"); // Remove a member myType.RemoveMember("AlarmCode"); // Add to the project project.DataTypes.Add(myType); // Convert data type definition to a tag var processTag = myType.ToTag("MyProcessTag"); // Convert to LogixData for use elsewhere var data = myType.ToData(); ``` -------------------------------- ### Access Controller and Program Components Source: https://context7.com/tnunnink/l5sharp/llms.txt Access controller-scoped and program-scoped components through intuitive collection properties. Get, try to get, remove, and add components by name. ```csharp var project = L5X.Load("MyController.L5X"); // Access controller-scoped components var controllerTags = project.Tags; var userDefinedTypes = project.DataTypes; var aois = project.AddOnInstructions; var modules = project.Modules; var programs = project.Programs; var tasks = project.Tasks; var trends = project.Trends; var watchLists = project.WatchLists; ``` ```csharp // Access program-scoped components var mainProgram = project.Programs.First(); var programTags = mainProgram.Tags; var routines = mainProgram.Routines; ``` ```csharp // Get a specific component by name var myTag = project.Tags.Get("MyTagName"); ``` ```csharp // Try to get a component safely if (project.Tags.TryGet("MyTagName", out var tag)) { Console.WriteLine($"Found tag: {tag.Name}, Type: {tag.DataType}"); } ``` ```csharp // Remove a component by name var removed = project.Tags.Remove("OldTag"); ``` ```csharp // Add a new component project.Tags.Add(new Tag { Name = "NewTag", Value = 100 }); ``` -------------------------------- ### Create and Get Tag Reference Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Create a new in-memory tag and access its Reference property, which provides a URI-like path to the element. ```csharp // Create a new in memory program tag. var component = Tag.New("Program:SomeProgram.MyTagName"); // Get the Reference property. var reference = component.Reference; // Write the results of the reference Console.WriteLine(reference.Path); // Output: tag://SomeProgram/MyTagName Console.WriteLine(reference.Type); // Output: tag Console.WriteLine(reference.Container); // Output: SomeProgram Console.WriteLine(reference.Id); // Output: MyTagName ``` -------------------------------- ### Try Get Component by Name Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Attempt to retrieve a component by name from a LogixContainer, returning a boolean indicating success and the component instance if found. ```csharp // Try to get component in the collection and return the instance if found. var result = project.Tags.TryGet("MyTagName", out var tag); ``` -------------------------------- ### Get Component by Name Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Retrieve a specific component (e.g., a tag) from a LogixContainer by its name. ```csharp // Get a component in the collection with the specified name. var tag = project.Tags.Get("MyTagname"); ``` -------------------------------- ### Fast Lookup for Scoped and Nested Tags Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md The Get API supports looking up controller-scoped, program-scoped, and nested tag members efficiently. ```csharp // This API supports controller scoped, program scoped, and nested tag member. var tag = project.Get("Program:SomeProgram.MyTagName.Member[2].Value"); ``` -------------------------------- ### Create and Configure a Program with Tags and Routines Source: https://context7.com/tnunnink/l5sharp/llms.txt Demonstrates creating a new program, adding tags, defining RLL routines using a builder, and adding routines to the program. Use this to set up the basic structure of a PLC program. ```csharp // Create a new program var program = new Program("MainProgram", ProgramType.Normal) { MainRoutineName = "Main", FaultRoutineName = "FaultHandler", Disabled = false }; // Add tags to the program program.Tags.Add(new Tag("LocalCounter", new DINT(0))); program.Tags.Add(new Tag("CycleTimer", new TIMER())); // Create an RLL routine with the builder var mainRoutine = Routine.Rll("Main") .Rung("XIC(StartButton)OTE(MotorRunning);", "Start motor when button pressed") .Rung("TON(CycleTimer,1000,0);", "Cycle timing") .Rung("XIC(CycleTimer.DN)RES(CycleTimer);", "Reset timer on done") .Build(); // Add routines to the program program.Routines.Add(mainRoutine); program.Routines.Add(new Routine("FaultHandler", RoutineType.RLL)); // Add program to the project project.Programs.Add(program); // Access routine content var routine = project.Programs.Get("MainProgram").Routines.Get("Main"); var rungs = routine.Rungs; foreach (var rung in rungs) { Console.WriteLine($"Rung {rung.Number}: {rung.Text}"); Console.WriteLine($"Comment: {rung.Comment}"); } // Add a new rung routine.Rungs.Add(new Rung("XIC(StopButton)OTU(MotorRunning);", "Stop motor")); ``` -------------------------------- ### Load and Create L5X Files Source: https://context7.com/tnunnink/l5sharp/llms.txt Load existing L5X files from disk, parse from XML string, or create new projects in memory with configurable controller settings. Save projects to disk. ```csharp // Load an existing L5X file synchronously var project = L5X.Load("MyController.L5X"); ``` ```csharp // Load an existing L5X file asynchronously var projectAsync = await L5X.LoadAsync("MyController.L5X", CancellationToken.None); ``` ```csharp // Parse L5X content from a string var projectFromXml = L5X.Parse(""); ``` ```csharp // Create a new L5X project with specified controller name, processor, and revision var newProject = L5X.New("MyProjectName", "1756-L84E", new Revision(36, 1)); ``` ```csharp // Create an empty L5X project var emptyProject = L5X.Empty(); ``` ```csharp // Save the project to a file project.Save("UpdatedController.L5X"); ``` -------------------------------- ### Create New L5X Project Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Create a new L5X project in memory, specifying the project name, processor type, and firmware version. ```csharp // Create new L5X in memory. This will seed the project with the specified processor. var project = L5X.New("MyProjectName", "1756-L84E", 36.1); ``` -------------------------------- ### Create L5Sharp Components with Constructors Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Utilize constructors for L5Sharp components like Tag, DataType, and Task to initialize them with essential parameters. ```csharp var tag = new Tag("MyTag", 123); var dataType = new DataType("MyCustomType"); var task = new Task("PeriodicTask", TaskType.Periodic) ``` -------------------------------- ### Create L5Sharp Components with Default Constructor Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Initialize L5Sharp components like Tag, DataType, and Task using their default constructors and setting properties directly. ```csharp var tag = new Tag { Name = "MyTag", Value = 123}; var dataType = new DataType { Name = "MyCustomType", Description = "This is a custom type." }; var task = new Task { Name = "PeriodicTask", Type = TaskType.Periodic, Rate = 100 }; ``` -------------------------------- ### Fast Component Lookup with TryGet Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the TryGet method to safely attempt to retrieve a component by name, outputting the result if found. This operates in O(1) time. ```csharp // Try to get a component by name and output the result if found. var result = project.TryGet("LocalModuleName", out var component); ``` -------------------------------- ### Creating and Configuring Tags in L5Sharp Source: https://context7.com/tnunnink/l5sharp/llms.txt Shows various methods for creating tags, including constructors, factory methods, and a fluent builder API. Supports atomic, complex, and array data types, as well as producer/consumer tag configurations. ```csharp // Create tags using constructors var simpleTag = new Tag { Name = "MyTag", Value = 123 }; var typedTag = new Tag("MyDint", new DINT(100)); var tagWithDesc = new Tag("Counter", "COUNTER", "Main production counter"); // Create tags with factory methods var timerTag = Tag.New("Program:MainProgram.CycleTimer"); var arrayTag = Tag.New("DataArray", new Dimensions(10)); // Create tags using the fluent builder API var configuredTag = Tag.Named("Program:MainProgram.ProcessTimer") .WithValue(t => { t.PRE = 5000; t.DN = true; }) .WithDescription("Main process cycle timer") .ReadOnly() .Build(); // Create a producer tag var producerTag = Tag.Named("ProducedData") .WithValue() .Produces(p => p.WithRemoteTag("ConsumedData")) .Build(); // Create a consumer tag var consumerTag = Tag.Named("ConsumedData") .WithValue() .Consumes(c => c.FromProducer("RemoteController", "ProducedData")) .Build(); ``` -------------------------------- ### Create Empty L5X Project Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Create an empty L5X project in memory, which can then be populated with components. ```csharp // Create an empty L5X in memory. var project = L5X.Empty(); ``` -------------------------------- ### Create a Configured I/O Module Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Create a specific revision of an I/O module with custom configuration, including description, parent module, port, and slot. ```csharp // Create a specific revision of an I/O module with custom configuration var inputModule = catalog.Create("Input_Slot1", "1756-IB16", new Revision(2, 1), m => { m.Description = "Main Intake Sensors"; m.ParentModule = "Local"; m.ParentPortId = 1; m.Slot = 1; }); ``` -------------------------------- ### Create and Analyze Ladder Logic Rungs Source: https://context7.com/tnunnink/l5sharp/llms.txt Shows how to create a rung with text and comments, access its properties, and extract instructions, tag names, and dependencies. Use this to parse and understand existing ladder logic. ```csharp // Create a rung with text and comment var rung = new Rung("XIC(Input1)XIC(Input2)OTE(Output1);", "AND logic for output control"); // Access rung properties Console.WriteLine($"Type: {rung.Type}"); Console.WriteLine($"Text: {rung.Text}"); Console.WriteLine($"Comment: {rung.Comment}"); // Get all instructions in the rung var instructions = rung.Instructions(); foreach (var instruction in instructions) { Console.WriteLine($"Instruction: {instruction.Key}"); foreach (var arg in instruction.Arguments) { Console.WriteLine($" Argument: {arg}"); } } // Get all tag names referenced in the rung var tagNames = rung.Tags(); foreach (var tagName in tagNames) { Console.WriteLine($"Referenced tag: {tagName}"); } // Get dependencies (tags and AOIs used) var dependencies = rung.Dependencies(); foreach (var dep in dependencies) { Console.WriteLine($"Dependency: {dep.Reference}"); } // Modify rung content rung.Text = "XIC(NewInput)OTE(NewOutput);"; rung.Comment = "Updated rung logic"; // Query rungs across the project var jsrRungs = project.Query(r => r.Text.Contains("JSR")); ``` -------------------------------- ### Create PlcClient Instance Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Create a new PlcClient instance to connect to a Logix PLC. This client implements IDisposable and should be disposed of to release resources. ```csharp using var client = new PlcClient("10.10.10.10", 1); ``` -------------------------------- ### Import Content from L5X Files Source: https://context7.com/tnunnink/l5sharp/llms.txt Import components from other L5X files with configurable operations like Overwrite or Discard. Use Where clauses to filter components before import. ```csharp var project = L5X.Load("TargetProject.L5X"); // Import from another L5X file project.Import(import => import .FromFile("SourceComponents.L5X") .DataTypes(config => config.Overwrite()) // Replace existing types .Tags(config => config.Overwrite()) .Programs(config => config.Overwrite()) ); // Import specific components with modification project.Import(import => import .FromFile("Templates.L5X") .Programs(config => config .Where(p => p.Name.StartsWith("Template_")) .Modify(p => p.Name = p.Name.Replace("Template_", "Instance_")) ) ); // Import with discard option (skip certain items) project.Import(import => import .FromFile("Library.L5X") .DataTypes(config => config .Where(dt => !dt.Name.StartsWith("OBSOLETE_")) .Overwrite() ) ); project.Save("UpdatedProject.L5X"); ``` -------------------------------- ### Create a Controller Module Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Instantiate a ControlLogix processor module using the catalog, specifying its name and catalog number. ```csharp // Create the latest revision of a ControlLogix processor var controller = catalog.Create("MainController", "1756-L83E"); ``` -------------------------------- ### Create Virtual Tag Service with L5X Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Creates a virtual tag service by loading an L5X file and configuring fake latency. This service can be injected into the PlcClient for testing. ```csharp // This creates a new virtual tag service by loading the specified L5X and confiuring a fake latency duration. var tagService = VirtualTagService.Upload(@"C:\Path\To\MyFile.L5X", TimeSpan.FromMilliseconds(10)); // You can inject this or any other mock service into the client constructor. using var client = new PlcClient(options, tagService); ``` -------------------------------- ### Load L5X Project Asynchronously Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the asynchronous overload of L5X.LoadAsync for loading L5X files, providing a CancellationToken for managing the operation. ```csharp // Use async overload for loading. var project = await L5X.LoadAsync("MyProject.L5X", CancellationToken.None); ``` -------------------------------- ### Configure PLC Client Options Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Configures the PLC client with specific options like IP, slot, timeout, poll rate, and exceptions to throw. Create the client with these options. ```csharp var options = new PlcOptions { IP = "10.10.10.10", Slot = 2, // Duration in milliseconds before timeout error occurs. Default is 5000 Timeout = 30000, // Rate in milliseconds at which to poll for tag updates (only applies to MonitorTag and PollTag methods). Default is 1000. PollRate = 100, // Which result statuses to throw exceptions for. Default is none. ThrowOn = { TagStatus.BadData, TagStatus.BadConnection, TagStatus.Timeout } }; // Create the client with the configured options. using var client = new PlcClient(options); ``` -------------------------------- ### Clone and Duplicate L5Sharp Components Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Create a direct clone of a component or a duplicate with updated configuration. The Duplicate method can also add the new instance to an L5X and perform find/replace operations. ```csharp // Create a direct clone of the current object with no changes. var clone = tag.Clone(); // Create a duplicate with updated config. This method will also add the duplicate to the L5X. var duplicate = program.Duplicate(p => { p.Name = "Program_02"; p.Description = "This is a different instance"; p.Replace("Tag_01", "Tag_02"); //This method will perform find/replace of text in the new object. }); ``` -------------------------------- ### Bulk Write Tags Queried and Updated from an L5X File Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Load an L5X file, query tags using LINQ, update their values, and then perform a bulk write of the modified tags. This allows for seamless bulk updates. ```csharp var content = L5X.Load(@"C:\Path\To\MyFile.L5X"); var tags = content.Query() .Where(t => t.DataType == "ALARM_ANALOG" && t.Dimensions == Dimensions.Empty && t.Scope.IsController ) .Update(t => { t.Value.As().HHEnabled = true; t.Value.As().HHLimit = 100; }); var result = await client.WriteTags(tags); ``` -------------------------------- ### Build a Module Catalog Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Aggregate module definitions from various sources using the ModuleCatalogBuilder. This includes loading default modules, seeding from L5X files, and loading from the Rockwell database. ```csharp var catalog = new ModuleCatalogBuilder() .WithDefaultModules() // Load built-in common modules .WithModulesFromL5X("StandardTemplates.L5X") // Seed from a project file .WithModulesFromRAD() // Load from local Rockwell database .Build(); ``` -------------------------------- ### Checking for Partial Export Files Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Demonstrates how to determine if an L5X file is a partial export and retrieve the target component's name and type. ```csharp var isPartial = project.Content.ContainsContext; ``` ```csharp var targetName = file.Content.TargetName; var targetType = file.Content.TargetType; ``` -------------------------------- ### Add L5Sharp.Generators.Data Package Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Generators.Data/README.md Add the L5Sharp.Generators.Data package as an analyzer/development dependency. Include L5Sharp.Core for core functionality. ```xml ``` -------------------------------- ### Create and Update Atomic Tags Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Demonstrates creating a new tag with a specific data type and value, or using implicit conversions. Also shows how to update an existing tag's value. ```csharp var tag = new Tag("MyTag", new DINT(123)); ``` ```csharp var tag = new Tag("MyTag", 123); ``` ```csharp tag.Value = 456; ``` -------------------------------- ### Create Reference to Rung with Fragment Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Create a reference to a specific rung, including an optional fragment to identify instruction details. ```csharp // Create reference to rung with instruction fragment "XIC(LocalTag)" var reference = Reference.To("rung://MyProgram/MyRoutine/1#XIC(LocalTag)"); ``` -------------------------------- ### Save L5X Project Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Save the modified L5X project to a specified file path. ```csharp project.Save("Updated.L5X"); ``` -------------------------------- ### Manipulate Components using Self-Referencing Methods Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use methods like AddAfter, AddBefore, Remove, and Replace to manage components relative to their current instance within a parent container or L5X. ```csharp // Add a new object after current instance in the document. rung.AddAfter(new Rung("XIC(SomeTag.12)OTE(AnotherTag)")); // Replace current instance with new one. tag.Replace(new Tag { Name = "UpdatedTag", Value = 123, Description = "Completely new instance"}); // Removes this instance from the L5X or parent container. routine.Remove() ``` -------------------------------- ### Include L5X Files as AdditionalFiles Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Generators.Data/README.md Add your L5X file containing type definitions to your project as an AdditionalFiles item. This allows the generator to process it. ```xml ``` -------------------------------- ### Create a Tag Monitor Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Use the `MonitorTag` method to create a tag monitor for periodic reads. This method requires the tag name and returns a `TagMonitor` object. ```csharp using var monitor = await client.MonitorTag("MyDintTag"); ``` -------------------------------- ### Write a Tag Constructed with the Tag Builder API Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Construct a tag instance in memory using the tag builder API and then write it to the PLC. Use the 'Program' prefix for program tags. ```csharp // Use the "Program" prefix to specify this as a program tag. var tag = Tag.Named("Program:SomeProgram.SomeTag") .WithValue(123) .Build(); var response = await client.WriteTag(tag); ``` -------------------------------- ### Query and Update Tag Values Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Load an L5X project, query for specific tag types, update a member value, and save the changes. Ensure the TIMER data type and its members are correctly defined in your L5X file. ```csharp var project = L5X.Load("MyController.L5X"); var timers = project.Query() .Where(t => t.DataType == "TIMER" && t.Dimensions == Dimensions.Empty) .Select(t => t.Value.As()) .Where(t => t.PRE < 1000); timers.ToList().ForEach(t => t.PRE = 5000); project.Save("MyController.L5X"); ``` -------------------------------- ### Query L5X Components with LINQ Source: https://context7.com/tnunnink/l5sharp/llms.txt Use the Query API with LINQ expressions to search across all scopes for elements matching specific criteria. Supports complex queries and updating matching components. ```csharp var project = L5X.Load("MyController.L5X"); // Find all tags in the project var allTags = project.Query(); ``` ```csharp // Find all TIMER tags var timerTags = project.Query(t => t.DataType == "TIMER"); ``` ```csharp // Find tags in a specific program var programTags = project.Query(t => t.Scope.Container == "MainProgram"); ``` ```csharp // Find I/O tags (tags with colon in name) var ioTags = project.Query(t => t.TagName.Base.Contains(":")); ``` ```csharp // Find all rungs in the project var allRungs = project.Query(); ``` ```csharp // Find rungs containing specific instruction text var alarmRungs = project.Query(r => r.Text.Contains("ALARM")); ``` ```csharp // Complex query: Find all non-array TIMER tags with PRE value under 1000 var lowPresetTimers = project.Query() .Where(t => t.DataType == "TIMER" && t.Dimensions == Dimensions.Empty) .Select(t => t.Value.As()) .Where(t => t.PRE < 1000); ``` ```csharp // Update all matching timers lowPresetTimers.ToList().ForEach(t => t.PRE = 5000); ``` -------------------------------- ### FBD Routine - Sheet 1 Connections and Blocks Source: https://github.com/tnunnink/l5sharp/blob/main/tests/L5Sharp.Tests.Core/Components/ProgramTests.Duplicate_ValidConfig_ShouldBeVerified.verified.txt Illustrates connections and blocks within a Function Block Diagram (FBD) routine, including ADD, LPF, BNOT__F, BAND__F, and SQRT__F functions. ```XML ``` -------------------------------- ### Query Module Definitions by Catalog Number Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Retrieve all available revisions for a specific module catalog number from the catalog. ```csharp // Get all definitions for a specific catalog number var revisions = catalog.Definitions("1756-IB16"); ``` -------------------------------- ### Modify, Clone, and Duplicate L5X Components Source: https://context7.com/tnunnink/l5sharp/llms.txt Illustrates direct modification of tag properties, cloning components, duplicating programs with text replacement, and bulk updating components based on criteria. Use for managing and transforming L5X data. ```csharp var project = L5X.Load("MyController.L5X"); // Modify tag properties directly var tag = project.Tags.Get("MyTag"); tag.Value = 50; tag.Description = "Updated tag description"; tag.ExternalAccess = Access.ReadOnly; // Clone a component (creates an exact copy) var clonedTag = tag.Clone(); clonedTag.Name = "ClonedTag"; project.Tags.Add(clonedTag); // Duplicate a program with modifications and text replacement var originalProgram = project.Programs.Get("Template"); var duplicatedProgram = originalProgram.Duplicate(p => { p.Name = "Program_02"; p.Description = "Instance 2 of template program"; p.Replace("Template", "Program_02"); // Find/replace in all content }); // Bulk update components matching criteria project.Tags.Update( t => t.DataType == "TIMER", // Filter condition t => t.Description = "Updated TIMER" // Update action ); // Self-referencing operations (requires attached component) var firstRung = project.Programs.First().Routines.First().Rungs.First(); firstRung.AddAfter(new Rung("XIC(NewTag)OTE(Output);", "")); firstRung.AddBefore(new Rung("", "Placeholder rung")); // Replace a component in place tag.Replace(new Tag { Name = "ReplacementTag", Value = 999 }); // Remove a component from its container var obsoleteRoutine = project.Programs.Get("OldProgram").Routines.Get("Unused"); obsoleteRoutine.Remove(); ``` -------------------------------- ### Module Catalog Management Source: https://context7.com/tnunnink/l5sharp/llms.txt Manage and query Rockwell Automation module definitions for creating hardware configurations. Build catalogs from default modules, L5X files, or local databases. ```csharp // Build a module catalog from multiple sources var catalog = new ModuleCatalogBuilder() .WithDefaultModules() // Built-in common modules .WithModulesFromL5X("StandardTemplates.L5X") // From existing project .WithModulesFromRAD() // From local Rockwell database .Build(); // Create modules from the catalog var controller = catalog.Create("MainController", "1756-L83E"); // Create with specific revision and configuration var inputModule = catalog.Create("Input_Slot1", "1756-IB16", new Revision(2, 1), m => { m.Description = "Main Intake Sensors"; m.ParentModule = "Local"; m.ParentPortId = 1; m.Slot = 1; }); // Query available module definitions var digitalInputs = catalog.Definitions("1756-IB16"); foreach (var def in digitalInputs) { Console.WriteLine($"Revision: {def.Revision}, Ports: {def.Ports.Count()}"); } // Find specific definition if (catalog.TryGetDefinition("1756-EN2T", out var definition)) { Console.WriteLine($"Found {definition.CatalogNumber}"); } // Add modules to project project.Modules.Add(controller); project.Modules.Add(inputModule); ``` -------------------------------- ### RLL: Examine Input and Output Source: https://github.com/tnunnink/l5sharp/blob/main/tests/L5Sharp.Tests.Core/Components/ProgramTests.Duplicate_ValidConfig_ShouldBeVerified.verified.txt Examines the state of an input point and outputs a value to a buffer tag. Useful for I/O monitoring. ```RLL XIC(FlexIO:3:I.Pt01.Data)OTE(BufferTag); ``` -------------------------------- ### Working with Array Data Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Illustrates how to access and modify elements of an array tag using the ArrayData class and indexer. Includes iteration over array elements. ```csharp var arrayTag = project.Tags.Get("MyArray"); var array = arrayTag.Value.As>(); ``` ```csharp var first = array[0]; array[1] = 123; ``` ```csharp foreach (var element in array) { // ... } ``` -------------------------------- ### Working with Tag Data Types in L5Sharp Source: https://context7.com/tnunnink/l5sharp/llms.txt Illustrates how to access and manipulate tag values using strongly-typed data classes for atomic types, predefined structures, arrays, and custom UDTs. Covers accessing and modifying atomic values, working with TIMER/COUNTER types, and handling arrays and structures. ```csharp var project = L5X.Load("MyController.L5X"); // Working with atomic data types var dintTag = new Tag("MyDint", 123); // Implicit conversion var realTag = new Tag("MyReal", new REAL(3.14f)); var boolTag = new Tag("MyBool", new BOOL(true)); // Access and modify atomic values int value = dintTag.Value.As(); // Implicit conversion to int dintTag.Value = 456; // Working with predefined types (TIMER, COUNTER, etc.) var timerTag = project.Tags.Get("CycleTimer"); var timer = timerTag.Value.As(); timer.PRE = 2000; timer.ACC = 500; timer.DN = true; // Working with arrays var arrayTag = project.Tags.Get("DataBuffer"); var array = arrayTag.Value.As>(); array[0] = 100; array[1] = 200; foreach (var element in array) { Console.WriteLine(element); } // Working with custom structures (UDTs) var udtTag = project.Tags.Get("ProcessData"); var udt = udtTag.Value.As(); // Access members by name var memberValue = udt["Speed"]; var nestedValue = udt["Header"]["Status"]["ErrorCode"]; // Navigate tag hierarchy var rootTag = project.Tags.Get("ComplexTag"); var member = rootTag.Member("SubStructure.Array[2].Value"); var allMembers = rootTag.Members(); // Get all tag names in the structure var tagNames = rootTag.TagNames(); ``` -------------------------------- ### Create Tag Component using Fluent Builder API Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the fluent builder API provided by the Tag class to create and configure tag values with specific properties and actions. ```csharp var tag = Tag.Create("SomeTimer") .WithValue(t => { t.PRE = 5000; t.DN = true; }) .WithDescription("This is a fluent builder...") .ReadOnly() .Build(); ``` -------------------------------- ### Strongly Typed Data Access Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Shows how to access Logix data types with strong typing using the .As() method. Implicit conversion to C# types is also demonstrated. ```csharp var timer = tag.Value.As(); timer.PRE = 2000; timer.DN = true; ``` ```csharp var count = project.Tags.Get("MyCounter").Value.As(); int val = count; ``` -------------------------------- ### RLL Routine - Basic Logic with OTE/OTU Source: https://github.com/tnunnink/l5sharp/blob/main/tests/L5Sharp.Tests.Core/Components/ProgramTests.Duplicate_ValidConfig_ShouldBeVerified.verified.txt A rung in a Relay Ladder Logic (RLL) routine demonstrating basic logic using XIC (Examine If Closed) and OTE (Output Energize) / OTU (Output Unlatch) instructions. ```Ladder Logic [XIC(SimpleBool) ,XIC(SimpleBool) ][OTE(SimpleBool) ,OTU(SimpleBool) ]; ``` -------------------------------- ### Query for a Specific Module Definition Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Catalog/README.md Attempt to retrieve a specific module definition by catalog number and print its details if found. This method returns a boolean indicating success. ```csharp // Find a specific definition if (catalog.TryGetDefinition("1756-EN2T", out var definition)) { Console.WriteLine($"Found {definition.CatalogNumber} with {definition.Ports.Count()} ports."); } ``` -------------------------------- ### Read Collections of Tags Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Read collections of tags, such as all tags in a specific program, by querying an L5X using LINQ and passing the collection to the client. Tag names or types do not need to be known beforehand. ```csharp var tags = content.Query(t => t.Scope.Container == "MyProgram"); var results = await client.ReadTags(tags); ``` -------------------------------- ### Fast Lookup for Code Elements Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md The TryGet API can also be used to retrieve 'code' type elements, such as Rungs, by their identifier and scope. ```csharp // This API supports getting "code" type elements as well. var result = project.TryGet(12, "SomeProgram", "MainRoutine", out var rung); ``` -------------------------------- ### Cast Component Using As() Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md After retrieving a component using its reference, use the As() method to cast it to the desired type. ```csharp // Since you know this is a tag, you can cast it as needed. As() is a build in cast method available on all types. var tag = component.As(); ``` -------------------------------- ### Write a Simple Tag Value Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Use the client object to write a simple value to a known tag. Ensure the tag exists before writing. ```csharp var result = await client.WriteTag("MyRealTag", 1.34); ``` -------------------------------- ### Implicit String Conversion for Reference Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md The Reference class supports implicit string conversion, allowing it to be used directly where a string is expected. ```csharp // Reference also has implicit string conversion. Reference reference = "program://MyProgramName" ``` -------------------------------- ### Parse XML Rung with Comment Source: https://github.com/tnunnink/l5sharp/blob/main/tests/L5Sharp.Tests.Core/Serialization/RungSerializerTests.Serialize_Bool_ShouldBeApproved.verified.txt This snippet demonstrates parsing an XML-defined rung with a comment using L5Sharp. It's useful for understanding how L5Sharp interprets structured PLC code. ```xml ``` -------------------------------- ### Accessing Controller Properties Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Shows how to access the top-level Controller object and its properties like Name, ProcessorType, Revision, CommPath, and Tags. ```csharp var controller = porject.Controller; var name = controller.Name; var processor = controller.ProcessorType; var revision = controller.Revision; var commPath = controller.CommPath; var tags = controller.Tags; ``` -------------------------------- ### Read Tag Using In-Memory Tag Instance Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Create an in-memory Tag instance and pass it to the client to read its value. The tag type is specified during creation. ```csharp var tag = Tag.New("Program:SomeProgram.SomeTimer"); var result = await client.ReadTag(tag); ``` -------------------------------- ### PLC Communication with L5Sharp.Gateway Source: https://context7.com/tnunnink/l5sharp/llms.txt Communicate with live Allen-Bradley PLCs for reading and writing tag values. Supports atomic and complex tags, program-scoped tags, and nested members. ```csharp // Create a PLC client connection using var client = new PlcClient("10.10.10.10", 1); // Read atomic tags var dintResult = await client.ReadTag("MyDintTag"); Console.WriteLine($"Value: {dintResult.Tag.Value}, Status: {dintResult.Status}"); // Read complex tags var timerResult = await client.ReadTag("ProcessTimer"); var timer = timerResult.Tag.Value.As(); Console.WriteLine($"PRE: {timer.PRE}, ACC: {timer.ACC}, DN: {timer.DN}"); // Read program-scoped tags var programTag = await client.ReadTag("Program:MainProgram.SetPoint"); // Read nested members var preValue = await client.ReadTag("ProcessTimer.PRE"); // Write tag values await client.WriteTag("OutputValue", 1.5f); await client.WriteTag("ProcessTimer", new TIMER { PRE = 5000, DN = true }); // Write with update action await client.WriteTag("CycleTimer", t => { t.PRE = 12345; t.ACC = 0; t.EN = true; }); // Update specific members only (partial write) await client.UpdateTag("ProcessTimer", [ ("PRE", 5000), ("DN", 1) ]); // Bulk read from L5X query var content = L5X.Load("MyProject.L5X"); var tags = content.Query(t => t.Scope.Container == "MainProgram"); var results = await client.ReadTags(tags); // Monitor tag changes using var monitor = await client.MonitorTag("ProductCount"); monitor.OnChange(result => { Console.WriteLine($"Tag: {result.Tag.TagName} changed to {result.Tag.Value}"); }); // Poll until condition is met var pollResult = await client.PollTag("ProcessStep", step => step > 5, TimeSpan.FromSeconds(30)); ``` -------------------------------- ### Read Tag Using Existing Tag Instance Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Pass an existing Tag instance obtained from an L5X file to the client to read its value. The tag type is inferred from the tag element. ```csharp var content = L5X.Load(@"C:\Path\To\MyFile.L5X"); var tag = content.Tags.Get("SomeTag"); var result = await client.ReadTag(tag); ``` -------------------------------- ### Accessing Custom Structure Members Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Demonstrates how to work with User Defined Types (UDTs) or custom structures using StructureData, including accessing members by name and navigating nested structures. ```csharp var udtTag = project.Tags.Get("MyUdtTag"); var udt = udtTag.Value.As(); ``` ```csharp var memberValue = udt["SomeMember"]; ``` ```csharp var nestedValue = udt["Header"]["Status"]["ErrorCode"]; ``` -------------------------------- ### Create Reference to Tag with Scope Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the Reference.To method to create a reference to a tag, specifying its name and scope. ```csharp // Create reference to tag with provided name and scope. var reference = Reference.To("MyTag", Scope.Program("MyProgram")); // tag://MyProgram/MyTag ``` -------------------------------- ### RLL: Jump to Subroutine Source: https://github.com/tnunnink/l5sharp/blob/main/tests/L5Sharp.Tests.Core/Components/ProgramTests.Duplicate_ValidConfig_ShouldBeVerified.verified.txt Jumps to a subroutine for modular programming. Requires specifying the subroutine and parameters. ```RLL JSR(FBD,1,InputParameter,OutputParameter); ``` -------------------------------- ### Manage Components in LogixContainer Collections Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Add, remove, or bulk update components within LogixContainer collections like Tags. ```csharp // Add a new component to a container project.Tags.Add(new Tag { Name = "MyTag", Value = 100 }); // Remove a component from a container project.Tags.Remove("OldTag"); // Bulk update components project.Tags.Update( t => t.DataType == "TIMER", //update condition t => t.Description = "Updated TIMER description" //update action ); ``` -------------------------------- ### Perform Bulk Tag Writes Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Write multiple tags simultaneously using the `WriteTags` method. This method accepts a collection of tag objects. ```csharp var results = await client.WriteTags( [ Tag.New("First"), Tag.New("Second"), Tag.New("Third"), ]); ``` -------------------------------- ### Parse L5X String in Memory Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Parse an L5X content string directly in memory without loading from a file. ```csharp // Parse L5X string in memory. var project = L5X.Parse(""); ``` -------------------------------- ### Read Program Scoped Tag Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md To read a program scoped tag, prepend the `Program:{ProgramName}` specifier to the tag name. ```csharp var result = await client.ReadTag("Program:MainProgram.SomeTag"); ``` -------------------------------- ### Access Globally Scoped Components Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Access collections of globally scoped components within an L5X project, such as tags, data types, AOIs, modules, programs, and tasks. ```csharp // Access globally scoped components. var controllerTags = project.Tags; var userDefinedTypes = project.DataTypes; var aois = project.AddOnInstructions; var modules = project.Modules; var programs = project.Programs; var tasks = project.Tasks; ``` -------------------------------- ### Query Tags by Type and Criteria Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the Query method to find all tags matching specific criteria, such as data type or scope. This API searches across all scopes. ```csharp // Tag query examples var allTags = project.Query(); var allTimerTags = project.Query(t => t.DataType == "TIMER"); var tagsInProgram = project.Query(t => t.Scope.Container == "SomeProgram"); var ioTags = project.Query(t => t.TagName.Base.Contains(":")); ``` -------------------------------- ### Subscribe to Tag Updates Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Register callback functions to receive updates for monitored tags. The `OnUpdate` event is called for every read, regardless of value change. Callbacks receive a `TagResult` object. ```csharp // Subscribe to all reads regarless of value change. monitor.OnUpdate(result => { Console.WriteLine($"Tag: {result.Tag.TagName} | Value: {result.Tag.Value} | Status: {result.Statue}"); }); ``` -------------------------------- ### Write a Complex Tag Structure Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Write a complex tag structure by providing an instance of the corresponding C# class. The entire tag data structure will be overwritten. ```csharp var result = await client.WriteTag("MyTimer", new TIMER { PRE = 5000, DN = true }); ``` -------------------------------- ### Read Atomic Tag by Name and Type Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Gateway/README.md Use the client object to read a known atomic tag by its name and data type. ```csharp var result = await client.ReadTag("MyDintTag"); ``` -------------------------------- ### Query Rungs by Text Content Source: https://github.com/tnunnink/l5sharp/blob/main/src/L5Sharp.Core/README.md Use the Query method to find all rungs that contain specific text. This API searches across all scopes. ```csharp // Rung query examples var allRungs = project.Query(); var rungsWithInstruction = project.Query(r => r.Text.Contains("ALARM")); ```