### Get Help for Adding and Removing Ads Routes Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterWpfApp/ReadMe.md Provides instructions on how to get help for the Add-AdsRoute and Remove-AdsRoute cmdlets. This is useful for learning the syntax and available parameters for managing ADS routes. ```powershell PS> get-help Add-AdsRoute -examples PS> get-help Remove-AdsRoute -examples ``` -------------------------------- ### Start RouterConsole Sample with Docker Compose Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md This command starts the RouterConsole sample by deploying the necessary Docker images and containers defined in the docker-compose.routerconsole.yml file. It orchestrates the communication between client, server, and router containers, with output visible in the console. ```bash docker compose -f docker-compose.routerconsole.yml up ``` -------------------------------- ### Manage Docker Compose Services Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md Commands to start and stop the MQTT-based ADS container services. ```bash cd ./Sources/DockerSamples docker compose -f docker-compose.mqtt.yml up docker compose -f docker-compose.mqtt.yml down ``` -------------------------------- ### Install and Import TcXaeMgmt PowerShell Module Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterWpfApp/ReadMe.md Installs the TcXaeMgmt PowerShell module from the PowerShell Gallery and then imports it into the current session. This module is necessary for managing ADS routes and testing ADS servers. ```powershell PS> install-module TcXaeMgmt PS> import-module TcXaeMgmt ``` -------------------------------- ### Implement Custom ADS Server (C#) Source: https://context7.com/beckhoff/tf6000_ads_dotnet_v5_samples/llms.txt Provides a C# example of creating a custom ADS server by extending the `AdsServer` base class. This allows handling incoming ADS read, write, state read, and control requests. The server port must be in the customer range (25000-25999 or 26000-26999). ```csharp using TwinCAT.Ads; using TwinCAT.Ads.Server; public class CustomAdsServer : AdsServer { private byte[] _dataBuffer = { 1, 2, 3, 4 }; private AdsState _adsState = AdsState.Run; // Port must be in customer range: 25000-25999 or 26000-26999 public CustomAdsServer() : base(26000, "CustomServer") { base.serverVersion = new Version(1, 0, 0); } // Handle read requests protected override Task OnReadAsync( AmsAddress address, uint invokeId, uint indexGroup, uint indexOffset, int readLength, CancellationToken cancel) { Console.WriteLine($"Read request: IG=0x{indexGroup:X}, IO=0x{indexOffset:X}"); var result = ResultReadBytes.CreateSuccess(_dataBuffer.AsMemory()); return Task.FromResult(result); } // Handle write requests protected override Task OnWriteAsync( AmsAddress address, uint invokeId, uint indexGroup, uint indexOffset, ReadOnlyMemory writeData, CancellationToken cancel) { Console.WriteLine($"Write request: IG=0x{indexGroup:X}, IO=0x{indexOffset:X}, Len={writeData.Length}"); if (indexGroup == 0x10000 && writeData.Length == 4) { writeData.CopyTo(_dataBuffer); return Task.FromResult(ResultWrite.CreateSuccess()); } return Task.FromResult(ResultWrite.CreateError(AdsErrorCode.DeviceServiceNotSupported)); } // Handle state read requests protected override Task OnReadDeviceStateAsync( AmsAddress address, uint invokeId, CancellationToken cancel) { var state = new StateInfo(_adsState, 0); return Task.FromResult(ResultReadDeviceState.CreateSuccess(state)); } // Handle state write (control) requests protected override Task OnWriteControlAsync( AmsAddress sender, uint invokeId, AdsState adsState, ushort deviceState, ReadOnlyMemory data, CancellationToken cancel) { _adsState = adsState; Console.WriteLine($"State changed to: {adsState}"); return Task.FromResult(ResultAds.CreateSuccess()); } } // Usage: var server = new CustomAdsServer(); // Server automatically registers with local ADS router Console.WriteLine("Server running on port 26000"); // Expected: Server responds to ADS requests on port 26000 ``` -------------------------------- ### Install TcXaeMgmt PowerShell Module Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md Installs the TcXaeMgmt PowerShell module from the PowerShell Gallery. This module is required for interacting with TwinCAT ADS servers using PowerShell. It supports various PowerShell versions and TwinCAT versions. ```powershell PS> install-module TcXaeMgmt PS> get-module TcXaeMgmt -listAvailable ``` -------------------------------- ### Establish ADS Session and Get AdsState Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md Establishes a session with the ADS server and retrieves its current state. This is the initial step to interact with the TwinCAT ADS server. Requires the NetId and AmsPort of the target server. ```powershell $session = new-tcsession -NetId Local -port 25000 $session | Get-AdsState ``` -------------------------------- ### Orchestrate Docker Services via Compose Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md Example snippet showing how to reference an environment configuration file within a docker-compose service definition. This allows the containerized application to load ADS settings at runtime. ```yaml services: router: env_file: "settings-bridged-network.env" ``` -------------------------------- ### Establish ADS Route and Test Connection Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md This PowerShell snippet establishes a route to the TwinCAT ADS server and tests the connection. It requires the TwinCAT ADS module to be installed. The output shows the route details and connection status. ```powershell PS> test-adsroute -port 25000 Name Address Port Latency Result (ms) ---- ------- ----- ------- ------ CX_1234 172.17.60.167.1.1 25000 36 Ok ``` -------------------------------- ### Configure Router with appsettings.json Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/ReadMe.md Example of an appsettings.json file used to configure the TwinCAT ADS TCP Router. This file specifies local system details, remote connections, and logging levels. Ensure the 'AmsRouter' section contains the correct 'Name', 'NetId', 'TcpPort', and 'RemoteConnections'. ```json { "AmsRouter": { "Name": "MyLocalSystem", "NetId": "192.168.1.20.1.1", "TcpPort": 48898, "RemoteConnections": [ { "Name": "RemoteSystem1", "Address": "RemoteSystem1", "NetId": "192.168.1.21.1.1", "Type": "TCP_IP" }, { "Name": "RemoteSystem2", "Address": "192.168.1.22", "NetId": "192.168.1.22.1.1", "Type": "TCP_IP" }, ] }, "Logging": { "LogLevel": { "Default": "Information", "System": "Information", "Microsoft": "Information" }, "Console": { "IncludeScopes": true } } } ``` -------------------------------- ### Configure ADS Router Environment Variables Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/docs/run-as-docker-container.md Example configuration for the AdsRouterConsoleApp using environment variables. These variables define the router identity and remote TwinCAT host connections. ```bash # Basic ADS-Router config which has to match StaticRoutes on TwinCAT-Host systems ENV_AmsRouter__Name=AdsRouterConsole ENV_AmsRouter__NetId=55.123.98.42.1.1 # Indexed List of remote connections to TwinCAT Hosts # First TwinCAT-Host ENV_AmsRouter__RemoteConnections__0__Name=TwinCAT-Host ENV_AmsRouter__RemoteConnections__0__Address=192.168.178.72 ENV_AmsRouter__RemoteConnections__0__NetId=5.29.122.232.1.1 # Another sample TwinCAT-Host ENV_AmsRouter__RemoteConnections__1__Name=Another-TwinCAT-Host ENV_AmsRouter__RemoteConnections__1__Address=192.168.178.74 ENV_AmsRouter__RemoteConnections__1__NetId=19.58.12.202.1.1 # Verbose log output ENV_Logging__LogLevel__Default=Debug ``` -------------------------------- ### Create ADS Router Console Application (C#) Source: https://context7.com/beckhoff/tf6000_ads_dotnet_v5_samples/llms.txt This C# code snippet shows how to create a standalone ADS router application. It uses Microsoft.Extensions.Hosting for dependency injection and configuration. The router can be configured via appSettings.json to manage remote connections and listen on a specific TCP port. It's useful for scenarios where a full TwinCAT installation is not available. ```csharp using Microsoft.Extensions.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using TwinCAT.Ads.TcpRouter; class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService(); }) .ConfigureAppConfiguration((hostingContext, config) => { config.AddEnvironmentVariables("ENV_"); config.AddJsonFile("appSettings.json", optional: true); }); } // appSettings.json configuration: /* { "AmsRouter": { "Name": "MyRouterSystem", "NetId": "192.168.1.100.1.1", "TcpPort": 48898, "RemoteConnections": [ { "Name": "PLCSystem", "Address": "192.168.1.50", "NetId": "192.168.1.50.1.1", "Type": "TCP_IP" } ] }, "Logging": { "LogLevel": { "Default": "Information" } } } */ // Expected: Router starts and accepts ADS connections on port 48898 ``` -------------------------------- ### Configure Router with StaticRoutes.xml Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/ReadMe.md Example of a StaticRoutes.xml file for configuring the TwinCAT ADS TCP Router. This XML structure defines local system properties and remote connection routes. Remember to add the 'StaticRoutesXmlConfigurationProvider' to your host configuration during startup. ```xml MyLocalSystem 192.168.1.20.1.1 48898 RemoteSystem1
RemoteSytem
192.168.1.21.1.1 TCP_IP
RemoteSystem2
192.168.1.22
192.168.1.21.1.1 TCP_IP
``` -------------------------------- ### Navigate to Docker Samples Directory Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md Command line instruction to navigate to the source directory containing the Docker sample projects. ```bash cd ./Sources/DockerSamples ``` -------------------------------- ### Running AdsOverMqttApp Sample (.NET CLI) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ClientSamples/AdsOverMqttApp/README.md Command to run the AdsOverMqttApp sample using the .NET CLI. This command navigates to the 'src' directory and executes the project, assuming the configuration is correctly set up. ```cmd cd .\src dotnet run --project .\AdsOverMqttApp.csproj ``` -------------------------------- ### Connect and Perform Raw ADS Read/Write Source: https://context7.com/beckhoff/tf6000_ads_dotnet_v5_samples/llms.txt Demonstrates how to instantiate an AdsClient, establish a connection to a local or remote TwinCAT runtime, and perform basic read/write operations using IndexGroup and IndexOffset memory addressing. ```csharp using TwinCAT.Ads; // Create and connect to local PLC (port 851 is TwinCAT 3 Runtime 1) using (AdsClient client = new AdsClient()) { client.Connect(851); // Connect to local system // Or connect to remote system: // client.Connect(new AmsNetId("192.168.1.100.1.1"), 851); // Read using IndexGroup/IndexOffset uint iValue = (uint)client.ReadAny(0x4020, 0x0, typeof(UInt32)); Console.WriteLine($"Value: {iValue}"); // Write using IndexGroup/IndexOffset UInt32 newValue = 42; client.WriteAny(0x4020, 0x0, newValue); } ``` -------------------------------- ### Clone and Build AdsRouterConsoleApp (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/RouterConsoleAdsEventProxy.md This snippet demonstrates how to clone the sample project from GitHub, navigate to the AdsRouterConsoleApp source directory, and build the application using .NET CLI commands. ```powershell git clone https://github.com/Beckhoff/TF6000_ADS_DOTNET_V5_Samples.git cd .\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src dotnet build ``` -------------------------------- ### Get Remote Ads Routes using Get-AdsRoute Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterWpfApp/ReadMe.md Retrieves a list of configured remote ADS routes known to the local system. This helps in understanding the network topology and available ADS devices. ```powershell PS> Get-AdsRoute Name NetId Protocol TLS Address FingerPrint ---- ----- -------- --- ------- ----------- CodedRemote 3.3.3.3.1.1 TcpIP ``` -------------------------------- ### Run RouterConsole Containers Interactively Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md This set of commands runs the RouterConsole containers interactively, allowing for direct console output and immediate feedback. Each container is assigned a name, uses a specified network, and loads environment variables from a settings file. ```bash docker run -it --rm --name router --env-file="settings-bridged-network.env" --network bridge adsrouter docker run -it --rm --name server --env-file="settings-bridged-network.env" --network bridge adsserver docker run -it --rm --name client --env-file="settings-bridged-network.env" --network bridge adsclient docker run -it --rm --name adsClient --env-file="settings-bridged-network.env" --network bridge pwshClient ``` -------------------------------- ### Get Local TwinCAT ADS Route Information (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/README.md This PowerShell command retrieves information about the local TwinCAT ADS route configuration. It displays the name, NetId, protocol, address, and other details of the local ADS route. ```powershell PS> Get-AdsRoute -local Name NetId Protocol TLS Address FingerPrint ---- ----- -------- --- ------- ----------- MYSYSTEM 1.1.1.1.1.1 TcpIP 192.168.0.1 ``` -------------------------------- ### Configure Docker Build Credentials Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md Sets environment variables for private NuGet feed access and executes Docker build commands for the various ADS services. ```bash export NuGetPackageSourceCredentials_TcBase="Username=DevOpsBuild@beckhoff.com;Password=$AZDEVOPS_ACCESS_TOKEN;ValidAuthenticationTypes=Basic" docker build -t adsrouter --no-cache --target=final --file ./AdsRouterConsole/Dockerfile --build-arg NuGetPackageSourceCredentials_TcBase=$NuGetPackageSourceCredentials_TcBase . docker build -t adsserver --no-cache --target=final --file ./AdsServer/Dockerfile --build-arg NuGetPackageSourceCredentials_TcBase=$NuGetPackageSourceCredentials_TcBase . docker build -t adsclient --no-cache --target=final --file ./AdsClient/Dockerfile --build-arg NuGetPackageSourceCredentials_TcBase=$NuGetPackageSourceCredentials_TcBase . docker build -t pwshclient --no-cache --target=final --file ./PwshClient/Dockerfile --build-arg NuGetPackageSourceCredentials_TcBase=$NuGetPackageSourceCredentials_TcBase --progress=plain . ``` -------------------------------- ### Build RouterConsole Docker Images Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md These commands manually build the Docker images required for the RouterConsole sample. They use specific Dockerfile targets to create optimized images for the router, server, client, and PowerShell client components. ```bash docker build -t adsrouter --no-cache --target=final --file ./AdsRouterConsole/Dockerfile . docker build -t adsserver --no-cache --target=final --file ./AdsServer/Dockerfile . docker build -t adsclient --no-cache --target=final --file ./AdsClient/Dockerfile . docker build -t pwshclient --no-cache --target=final --file ./PwshClient/Dockerfile . ``` -------------------------------- ### Configure MQTT Environment Variables Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md Defines the ADS-over-MQTT protocol settings, including the router name, NetId, and MQTT broker connection details. ```env AmsRouter__ChannelProtocol=AdsOverMqtt AmsRouter__Name=MqttRouter AmsRouter__NetId=42.42.42.42.1.1 AmsRouter__Mqtt__0__Address=192.168.20.2 AmsRouter__Mqtt__0__Port=1883 AmsRouter__Mqtt__0__Topic=VirtualAmsNetwork1 ``` -------------------------------- ### Get Recursive TwinCAT Symbol Information Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md This PowerShell snippet retrieves all symbols and their properties from a TwinCAT system recursively. It uses the `Get-TcSymbol` cmdlet with the `-recurse` option. The output details the instance path, category, data type, size, and other attributes of each symbol. ```powershell PS> $session | Get-TcSymbol -recurse InstancePath Category DataType Size Static Persistant IG IO ------------ -------- -------- ---- ------ ---------- -- -- Globals Struct 0 False False 0 0 Globals.bool1 Primitive BOOL 1 False False 2 1000 Globals.int1 Primitive INT 2 False False 2 1001 Globals.dint1 Primitive DINT 4 False False 2 1003 Globals.string1 String WSTRING(80) 162 False False 2 1007 Globals.myStruct1 Struct MYSTRUCT 169 False False 2 10A9 Globals.myStruct1.name String WSTRING(80) 162 False False 2 10A9 Globals.myStruct1.a Primitive BOOL 1 False False 2 114B Globals.myStruct1.b Primitive INT 2 False False 2 114C Globals.myStruct1.c Primitive DINT 4 False False 2 114E Globals.myArray1 Array ARRAY [0..3][0..1] OF INT 16 False False 2 1152 Globals.myEnum1 Enum MYENUM 4 False False 2 1162 Globals.myAlias1 Alias MYALIAS 4 False False 2 1166 Globals.pointer1 Pointer POINTER TO INT 8 False False 2 116A Globals.pointer1^ Primitive INT 2 False False F014 0 Globals.reference1 Reference REFERENCE TO INT 8 False False 2 1172 Globals.rpcInvoke1 Struct MYRPCSTRUCT 169 False False 2 117A Globals.rpcInvoke1.name String WSTRING(80) 162 False False 2 117A Globals.rpcInvoke1.a Primitive BOOL 1 False False 2 121C Globals.rpcInvoke1.b Primitive INT 2 False False 2 121D Globals.rpcInvoke1.c Primitive DINT 4 False False 2 121F Main Struct 0 False False 0 0 Main.bool1 Primitive BOOL 1 False False 1 1000 Main.int1 Primitive INT 2 False False 1 1001 Main.dint1 Primitive DINT 4 False False 1 1003 Main.string1 String WSTRING(80) 162 False False 1 1007 Main.myStruct1 Struct MYSTRUCT 169 False False 1 10A9 Main.myStruct1.name String WSTRING(80) 162 False False 1 10A9 Main.myStruct1.a Primitive BOOL 1 False False 1 114B Main.myStruct1.b Primitive INT 2 False False 1 114C Main.myStruct1.c Primitive DINT 4 False False 1 114E Main.myArray1 Array ARRAY [0..3][0..1] OF INT 16 False False 1 1152 Main.myEnum1 Enum MYENUM 4 False False 1 1162 Main.myAlias1 Alias MYALIAS 4 False False 1 1166 Main.pointer1 Pointer POINTER TO INT 8 False False 1 116A Main.pointer1^ Primitive INT 2 False False F014 0 Main.reference1 Reference REFERENCE TO INT 8 False False 1 1172 Main.rpcInvoke1 Struct MYRPCSTRUCT 169 False False 1 117A ``` -------------------------------- ### Run TwinCAT ADS Router Console Application (Full Framework) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/README.md This command executes the TwinCAT ADS Router console application compiled for the .NET Full Framework. Ensure the 'TwinCAT.Ads.AdsRouterConsole.exe' is present in the current directory or provide the correct path. ```shell TwinCAT.Ads.AdsRouterConsole.exe ``` -------------------------------- ### AdsOverMqttApp Configuration (JSON) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ClientSamples/AdsOverMqttApp/README.md The appSettings.json file for the AdsOverMqttApp, defining the MQTT broker connection details, TLS security settings, and target NetId. This configuration is crucial for establishing communication between the .NET application and the TwinCAT device via MQTT. ```json { "TargetNetId": "3.79.104.236.1.1", "AmsRouter": { "Name": "MqttRouter", "NetId": "42.42.42.42.1.1", "ChannelProtocol": "All", "Mqtt": [ { "NoRetain": false, "Unidirectional": false, "Port": 8883, "Address": "ba-0f8cfe2680560cffb.eu-central-1.demo.beckhoff-cloud-instances.com", "Topic": "VirtualAmsNetwork1", "Tls": { "IgnoreCn": false, "CA": "C:\\Program Files (x86)\\Beckhoff\\TwinCAT\\3.1\\Target\\Certificates\\BA-0f8cfe2680560cffb\\intermediateCA.pem", "CERT": "C:\\Program Files (x86)\\Beckhoff\\TwinCAT\\3.1\\Target\\Certificates\\BA-0f8cfe2680560cffb\\MyDevice.pem", "KEY": "C:\\Program Files (x86)\\Beckhoff\\TwinCAT\\3.1\\Target\\Certificates\\BA-0f8cfe2680560cffb\\MyDevice.key", "Version": "tlsv1.2" } } ] } } ``` -------------------------------- ### Instantiate AmsTcpIpRouter in C# Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/docs/run-beneath-TwinCATRouter.md Demonstrates the programmatic instantiation of the AmsTcpIpRouter class using specific network parameters. This approach is used to initialize the router within a .NET application, providing the necessary AmsNetId, port mappings, and subnet constraints. ```csharp AmsNetId localNetId = new AmsNetId("2.2.2.2.1.1"); IPAddress loopbackIP = IPAddress.Parse("192.168.2.1"); int loopbackPort = 48900; int externalPort = 48901; IPNetwork loopbackExternalSubnet = new IPNetwork("192.168.2.0/24"); AmsTcpIpRouter _router = new AmsTcpIpRouter(localNetId, loopbackPort, loopbackIP, externalPort, loopbackExternalSubnet, _logger); ``` -------------------------------- ### Browse and Test Certificate (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/AdsSecureSamples/AdsSecureConsoleApp/README.md These PowerShell commands show how to retrieve a specific certificate from the local machine's certificate store and test its validity for SSL/TLS communication, allowing untrusted roots. ```powershell PS> $cert = Get-ChildItem -Path cert:\LocalMachine\My\ | where Subject -like *TwinCATTestCertificate PS> $cert | Test-Certificate -Policy SSL -AllowUntrustedRoot ``` -------------------------------- ### Run TwinCAT ADS Router Console Application (.NET Core / Standard) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/README.md This command executes the TwinCAT ADS Router console application using the .NET Core or .NET Standard runtime. Ensure the 'TwinCAT.Ads.AdsRouterConsole.dll' is present in the current directory or provide the correct path. ```shell dotnet run .\TwinCAT.Ads.AdsRouterConsole.dll ``` -------------------------------- ### Run AdsRouterConsoleApp and View Configuration (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/RouterConsoleAdsEventProxy.md This snippet shows how to execute the AdsRouterConsoleApp using 'dotnet run' and displays the application's runtime information, including directory paths, environment configuration, and ADS router settings. ```powershell PS> dotnet run Application Directories ======================= ApplicationPath: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src\bin\Debug\net8.0\AdsRouterConsoleApp.dll BaseDirectory: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src\bin\Debug\net8.0\ CurrentDirectory: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_S Configuration ============= ASPNETCORE_ENVIRONMENT: Production Press Ctrl + C to shutdown! [2025-10-17 16:50:19.003] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Allowed EXTERNAL LOOPBACK NETWORK: 0.0.0.0/0 [2025-10-17 16:50:19.223] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Local System Name: LocalSystem [2025-10-17 16:50:19.224] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Local AmsNetId: 1.1.1.1.1.1 [2025-10-17 16:50:19.224] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter IPAddresses: 169.254.253.168,192.168.56.1,172.17.60.232,172.30.224.1 [2025-10-17 16:50:19.224] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter External Port: bf02 [2025-10-17 16:50:19.224] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Loopback IP: 127.0.0.1 [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Loopback Port: bf02 [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter UDP Discovery Port:bf03 [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter LoopbackExternals: 0.0.0.0/0 [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter Configured routes: [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter ================== [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter RemoteSystem, 2.2.2.2.1.1, 192.168.0.2 [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.TcpRouter.AmsTcpIpRouter [2025-10-17 16:50:19.225] [Thread:1] Information: TwinCAT.Ads.AdsRouterService.RouterService ApplicationPath: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src\bin\Debug\net8.0\AdsRouterConsoleApp.dll BaseDirectory: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src\bin\Debug\net8.0\ CurrentDirectory: D:\tmp\githubtest\TF6000_ADS_DOTNET_V5_Samples\Sources\RouterSamples\AdsRouterConsoleApp\src ``` -------------------------------- ### Retrieve and Inspect RPC Symbols via PowerShell Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md Demonstrates how to fetch a specific symbol from the ADS path and inspect its dynamic structure. This allows developers to view available fields and RPC methods associated with a TwinCAT struct. ```powershell $rpcSymbol = $s | get-tcSymbol -path 'Main.RpcInvoke1' $rpcSymbol | get-member -MemberType dynamic ``` -------------------------------- ### Configure Docker Daemon Network Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md JSON configuration for /etc/docker/daemon.json to resolve IP address conflicts within a domain network. ```json { "dns":["172.17.0.3", "172.17.0.4"], "dns-search":["beckhoff.com"], "bip":"192.168.220.1/22", "default-address-pools":[ {"base":"192.168.224.0/20","size":26} ], "shutdown-timeout": 3600 } ``` -------------------------------- ### Stream ADS Notifications with Reactive Extensions (C#) Source: https://context7.com/beckhoff/tf6000_ads_dotnet_v5_samples/llms.txt Demonstrates how to use Reactive Extensions (Rx) with TwinCAT ADS to create observable streams for notifications, monitor ADS state changes, and poll values at intervals. Requires the System.Reactive NuGet package. ```csharp using TwinCAT.Ads; using TwinCAT.Ads.Reactive; using TwinCAT.Ads.TypeSystem; using TwinCAT.TypeSystem; using System.Reactive; using System.Reactive.Linq; using (AdsClient client = new AdsClient()) { client.Connect(new AmsAddress(AmsNetId.Local, 851)); // Create typed observable from notifications var valueObserver = Observer.Create(val => { Console.WriteLine($"CycleCount: {val}"); }); // Subscribe to notifications as observable stream, take 20 values IDisposable subscription = client .WhenNotification("TwinCAT_SystemInfoVarList._TaskInfo.CycleCount", NotificationSettings.Default) .Take(20) .Subscribe(valueObserver); Console.ReadKey(); subscription.Dispose(); } // Monitor ADS state changes using (AdsClient client = new AdsClient()) { client.Connect(new AmsAddress(AmsNetId.Local, 851)); var stateObserver = Observer.Create>(states => { Console.WriteLine($"State changed: {states[0]} -> {states[1]}"); }); // Buffer 2 values to show old/new state IDisposable subscription = client .WhenAdsStateChanges() .Buffer(2, 1) .Subscribe(stateObserver); Console.ReadKey(); subscription.Dispose(); } // Polling values at intervals using (AdsClient client = new AdsClient()) { client.Connect(new AmsAddress(AmsNetId.Local, 851)); var symbolLoader = SymbolLoaderFactory.Create(client, SymbolLoaderSettings.Default); IValueSymbol cycleCount = (IValueSymbol)symbolLoader.Symbols["TwinCAT_SystemInfoVarList._TaskInfo.CycleCount"]; // Poll value every 500ms, take 10 samples IDisposable subscription = cycleCount .PollValues(TimeSpan.FromMilliseconds(500)) .Take(10) .Subscribe(val => Console.WriteLine($"Polled: {val}")); Console.ReadKey(); subscription.Dispose(); } // Expected output: // CycleCount: 12345 // CycleCount: 12346 // ... ``` -------------------------------- ### Configure ADS Router via appsettings.json Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/README.md Defines the local system identity and remote ADS connection routes using a standard JSON configuration file. This file is loaded at startup to establish the router's network parameters. ```json { "AmsRouter": { "Name": "MyLocalSystem", "NetId": "192.168.1.20.1.1", "TcpPort": 48898, "RemoteConnections": [ { "Name": "RemoteSystem1", "Address": "RemoteSystem1", "NetId": "192.168.1.21.1.1", "Type": "TCP_IP" }, { "Name": "RemoteSystem2", "Address": "192.168.1.22", "NetId": "192.168.1.22.1.1", "Type": "TCP_IP" } ] }, "Logging": { "LogLevel": { "Default": "Warning" } } } ``` -------------------------------- ### Activate Self-Signed Mode in C# Sample Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/AdsSecureSamples/AdsSecureConsoleApp/README.md This C# code snippet demonstrates how to configure the .NET sample application to use self-signed certificates for secure ADS connections. The `selfSigned` boolean flag should be set to `true`. ```csharp static async Task Main(string[] args) { // Change this flag to change between SelfSigned and CA certificates! bool selfSigned = true; ... ``` -------------------------------- ### Generate Certificate for Target IPC using OpenSSL Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/AdsSecureSamples/AdsSecureConsoleApp/README.md This snippet demonstrates the command-line steps to generate a private key, a certificate signing request (CSR), and a self-signed X.509 certificate for a target IPC using OpenSSL. It requires a pre-existing RootCA certificate and key. ```bash openssl genrsa -out C:\certs\TargetIPC.key 2048 openssl req -out C:\certs\TargetIPC.csr -key C:\certs\TargetIPC.key -subj "/C=DE/ST=NRW/L=Verl/O=Bk/OU=TCPM/CN=TargetIPC" –new openssl x509 -req -in C:\certs\TargetIPC.csr -CA C:\certs\RootCA.pem -CAkey C:\certs\RootCA.key -CAcreateserial -out C:\certs\TargetIPC.crt -days 360 -sha256 ``` -------------------------------- ### Run AdsRouterConsoleApp in Host Network Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/docs/run-as-docker-container.md Command to execute the container using the host network mode, passing configuration via an environment file. ```sh docker run \ -it \ --rm \ --name adsrouter \ --env-file="src/settings-host-network.env" \ --network host \ ads-router-console ``` -------------------------------- ### Build AdsRouterConsoleApp Docker Image Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/docs/run-as-docker-container.md Command to build the Docker image from the project root. It uses the specified Dockerfile and tags the image for later use. ```sh docker build -t ads-router-console --target=final --file Dockerfile . ``` -------------------------------- ### Create Self-Signed Certificate (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/AdsSecureSamples/AdsSecureConsoleApp/README.md This code demonstrates how to create a self-signed certificate for testing purposes using PowerShell. The certificate is stored in the local machine's 'My' certificate store and includes client and server authentication enhanced key usages. ```powershell PS> $cert = New-SelfSignedCertificate -DnsName TwinCATTestCertificate -CertStoreLocation cert:\LocalMachine\My PS> $cert PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My Thumbprint Subject EnhancedKeyUsageList ---------- ------- -------------------- 9814BEADD027C50B5905DBD769D848D7EE777B78 CN=TwinCATTestCerti… {Client Authentication, Server Authentication} ``` -------------------------------- ### List ADS Routes (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/RouterConsoleAdsEventProxy.md This snippet demonstrates how to list the configured ADS routes on a local system using the `get-adsroute` PowerShell cmdlet. It displays the name, NetId, protocol, and address of each route. This is useful for verifying connectivity and understanding the network configuration of TwinCAT devices. ```powershell PS> get-adsroute Name NetId Protocol TLS Address FingerPrint ---- ----- -------- --- ------- ----------- RemoteSystem 2.2.2.2.1.1 TcpIP 192.168.0.2 RalfHW1064 172.19.241.154.1.1 TcpIP 172.30.226.23 226f1c4889b156f8b94b7d484877f25625ec38e… ``` -------------------------------- ### Invoke Dynamic RPC Methods Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/ServerSamples/AdsSymbolicServerSample/ReadMe.md Shows the syntax for calling a dynamic RPC method on a retrieved symbol instance. The method accepts parameters and returns the result directly to the PowerShell console. ```powershell $rpcSymbol.Method1(4,5) ``` -------------------------------- ### Configure AdsRouterConsoleApp Settings (Text) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/RouterConsoleAdsEventProxy.md This section outlines the essential configuration parameters for the AdsRouterConsoleApp, specifying network interfaces, ports, and loopback settings. These settings are typically found in the appsettings.json file and are crucial for replacing default TwinCAT Router network configurations. ```text IPAddresses: 169.254.253.168,192.168.56.1,172.17.60.232,172.30.224.1 External Port: bf02 Loopback IP: 127.0.0.1 Loopback Port: bf02 ``` -------------------------------- ### Inspect Docker Bridge Network Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/docs/run-as-docker-container.md Command to display network interface details for the default docker0 bridge. ```sh ip addr show dev docker0 ``` -------------------------------- ### Run RouterConsole Containers Non-interactively Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md These commands launch the RouterConsole containers in detached mode (background). This is suitable for running the sample without direct console interaction, with each container named and configured with network and environment settings. ```bash docker run -d --rm --name router --env-file="settings-bridged-network.env" --network bridge adsrouter docker run -d --rm --name server --env-file="settings-bridged-network.env" --network bridge adsserver docker run -d --rm --name client --env-file="settings-bridged-network.env" --network bridge adsclient docker run -d --rm --name pwshclient --env-file="settings-bridged-network.env" --network bridge pwshclient ``` -------------------------------- ### Configure TwinCAT ADS Router via Environment Variables (PowerShell) Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterConsoleApp/README.md This snippet demonstrates how to set various configuration parameters for the TwinCAT ADS Router using PowerShell environment variables. It covers local system settings, remote connections, and logging levels. These variables are typically used to customize the router's behavior without modifying configuration files directly. ```powershell PS> $env:AmsRouter:Name = 'MyLocalSystem' PS> $env:AmsRouter:NetId = '192.168.1.20.1.1' PS> $env:AmsRouter:TcpPort = 48898 PS> $env:AmsRouter:RemoteConnections:0:Name = 'RemoteSystem1' PS> $env:AmsRouter:RemoteConnections:0:Address = 'RemoteSystem1' PS> $env:AmsRouter:RemoteConnections:0:NetId = '192.168.1.21.1.1' PS> $env:AmsRouter:RemoteConnections:1:Name = 'RemoteSystem2' PS> $env:AmsRouter:RemoteConnections:1:Address = '192.168.1.22' PS> $env:AmsRouter:RemoteConnections:1:NetId = '192.168.1.22.1.1' PS> $env:AmsRouter:Logging:LogLevel:Default = 'Warning' ``` ```powershell PS> dir env: | where Name -like AmsRouter* | format-table -AutoSize Name Value ---- ----- AmsRouter:Name MyLocalSystem AmsRouter:NetId 192.168.1.20.1.1 AmsRouter:TcpPort 48898 AmsRouter:RemoteConnections:0:Name RemoteSystem1 AmsRouter:RemoteConnections:0:Address RemoteSystem1 AmsRouter:RemoteConnections:0:NetId 192.168.1.21.1.1 AmsRouter:RemoteConnections:1:Name RemoteSystem2 AmsRouter:RemoteConnections:1:Address 192.168.1.22 AmsRouter:RemoteConnections:1:NetId 192.168.1.22.1.1 AmsRouter:Logging:LogLevel:Default Warning ``` -------------------------------- ### Broadcast Search for All Ads Devices with Get-AdsRoute -all Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/RouterSamples/AdsRouterWpfApp/ReadMe.md Performs a broadcast search across the network to discover all available ADS devices. It returns detailed information including NetId, IP Address, TwinCAT version, and operating system. ```powershell PS> Get-AdsRoute -all Name NetId Protocol TLS Address FingerPrint TcVersion RTSystem ---- ----- -------- --- ------- ----------- --------- -------- MYSYSTEM 1.1.1.1.1.1 TcpIP 192.168.0.1 [UNKNOWN] [UNKNOWN] CX_11111 1.1.1.1.1.2 TcpIP X 192.168.0.2 478c762e... 3.1.4025 TcBSD 13.2 CX_11112 1.1.1.1.1.3 TcpIP X 192.168.0.3 3.1.4022 CE7.0 CX_11113 1.1.1.1.1.4 TcpIP X 192.168.0.4 ab35ff7f... 3.1.4024 Win10 (21H2) CX_11114 1.1.1.1.1.5 TcpIP X 192.168.0.5 4528dc85... 3.1.4024 Win10 (22H2) ``` -------------------------------- ### PowerShell Commands for ADS Interaction Source: https://github.com/beckhoff/tf6000_ads_dotnet_v5_samples/blob/main/Sources/DockerSamples/ReadMe.md These PowerShell commands are executed within the pwsh client container to establish a session with the ADS server and retrieve its state and symbol information. They demonstrate basic ADS communication and introspection capabilities. ```pwsh PS> $server = new-tcsession -port 25000 PS> $server | get-adsstate Target NetId Port State Latency (ms) ------ ----- ---- ----- ------- bb71e66573c7 42.42.42.42.1.1 25000 Run 1.4 PS> $server | Get-TcSymbol -recurse InstancePath Category DataType Size Static Persistant IG IO ------------ -------- -------- ---- ------ ---------- -- -- Globals Struct 0 False False 0 0 Globals.bool1 Primitive BOOL 1 False False 2 1000 Globals.int1 Primitive INT 2 False False 2 1001 Globals.dint1 Primitive DINT 4 False False 2 1003 Globals.real1 Primitive REAL 4 False False 2 1007 Globals.lreal1 Primitive LREAL 8 False False 2 100B Globals.string1 String WSTRING(80) 162 False False 2 1013 ```