4.1.3 Proto Client API Tutorial |
The Proto Client API tutorial implements the same behavior as 4.1.1 Standalone API Tutorial and 4.1.2 Client API Tutorial but in a more generic way. It relies directly on the GRPC proto interface and links these dependencies instead. The API is auto generated on build and handles a bit chunkier without some convenience implementations available in the .NET versions of above tutorials.
If you prefer another non-.NET programming language, you will most likely find your language in the list of supported GRPC convertible languages , which can be auto-generated the PDA API from proto files for you.
For an idea how this could look like, have a look at this tutorial, generating proto files to C#/.NET.
//----------------------------------------------------------------------------- // This example demonstrates how to acquire data, export to .csv and what // steps are needed to achieve this with the ProcessDataAnalyzer Proto // generated API. // In contrast to the StandaloneAPITutorial, the ProtoClientAPITutorial // requires the PDA API service to be already running. // The application will connect to the first available device, acquire // ten seconds worth of default configured data and save it to the // desktop from where the .csv file will be opened with the PCs current // default program for .csv. // The ProtoClientAPITutorial application is implemented using the async // interface. // The ProtoClientAPITutorial application and ClientAPITutorial application // demonstrate the same implementation with different dependencies. //----------------------------------------------------------------------------- using Google.Protobuf.WellKnownTypes; using Grpc.Core; using RAYLASE.PDA.API; using System.Diagnostics; public class Program { // Before running this example, please make sure that the PDA API service is running. // The default installation location of the ProcessDataAnalyzer.Service.exe is // %ProgramFiles%\RAYLASE\ProcessDataAnalyzer\bin\ProcessDataAnalyzer.Service.exe"; // // To install the PDA API service as Windows service and have it running in // the background: // - Open a command line as admin, navigate to the location and call: // > ProcessDataAnalyzer.Service.exe install // > ProcessDataAnalyzer.Service.exe start // Or you can start a single instance in a (non-admin) command line: // > ProcessDataAnalyzer.Service.exe server public static int Main( string[] args ) { Console.WriteLine( "\n\nProto Client API sample\n------------------\n\n" ); // Create a connection to the running PDA API service. var channel = new Channel( "127.0.0.1:30051", ChannelCredentials.Insecure ); // Create a new acquisition service instance which will represent the client acquisition API var acquisitionAPI = new Acquisition.AcquisitionClient( channel ); // The card could be set by IP or serial number var suggestedCardIP = args[0]; if ( !string.IsNullOrEmpty( suggestedCardIP ) ) { Console.WriteLine( $"Connecting to card {suggestedCardIP} given as argument" ); } else { // Discover all available cards Console.WriteLine( "Discovering available cards" ); // With the protos, we need to use the "raw" generated interface. var discoverTask = acquisitionAPI.DiscoverAsync( new DiscoverRequest() ).ResponseAsync; var discoveryDuration = 0; while ( !discoverTask.IsCompleted ) { Console.WriteLine( $"Discovering... {++discoveryDuration} s" ); Thread.Sleep( 1000 ); } // Get the card repeated field from the reply message. var cards = discoverTask.Result.CardInfos.CardInfos_; if ( cards.Count == 0 ) { Console.WriteLine( "No cards found, please check your card configuration and network setup." ); return -1; } else Console.WriteLine( $"Found {cards.Count} cards" ); suggestedCardIP = cards[0].SuggestedIp; Console.WriteLine( $"Connecting to first card with suggested IP {suggestedCardIP}" ); } // Here the proto interface call requires us to set the IP address. This can be a bit cumbersome at times. // Just traverse the messages as seen in acquisition.proto for the Connect() call. // Note that the .NET overload to parse the connection argument for IP and serial number // Is not available here. If a card should be connected by serial number, it must be set to SerialNumber. acquisitionAPI.Connect( new ConnectRequest { Cards = { new Card { CardIp = suggestedCardIP } } } ); Console.WriteLine( "Starting acquisition (non-blocking)" ); // The specified timeout will override the PDA's default timeout value. var acquisitionStartTask = acquisitionAPI.StartAsync( new AcquisitionStartRequest { AutoStopSeconds = 60 } ).ResponseAsync; // Do something else while the acquisition is running and stop after 10 seconds manually var processingDuration = 0; while ( processingDuration < 10 ) { Console.WriteLine( $"Doing some dummy processing while acquisition is running... completed task {++processingDuration} of 10" ); Thread.Sleep( 1000 ); } // After "processing", manually stop the acquisition. var stopwatch = new Stopwatch(); stopwatch.Start(); var acquisitionStopTask = acquisitionAPI.StopAsync( new() ).ResponseAsync; while ( !acquisitionStartTask.IsCompleted && !acquisitionStopTask.IsCompleted ) { Thread.Sleep( 10 ); } stopwatch.Stop(); Console.WriteLine( $"Manually stopped acquisition after processing finished, stopping took {stopwatch.ElapsedMilliseconds} ms" ); // Some commands return a status in their reply which can transport a "soft" error without throwing. // In case of the Acquisition, if ADC signals are configured and the license can not be found, // The ADC signals will be excluded from acquisition and a warning is returned. // It might be a good idea to check the status code if available: var acquisitionReply = acquisitionStartTask.Result; if ( acquisitionReply.Status.Code != RAYLASE.PDA.API.Error.StatusCode.Ok ) { Console.WriteLine( $"Acquisition encountered an error: {acquisitionReply.Status}" ); return -1; } // Export the acquired 10 seconds to a .csv file to load into an excel table. // Please note that this path is as seen from the service.exe. If you set a relative path, it will // be relative to where the PDA service is running! Console.WriteLine( "Exporting acquired data to .csv" ); var exportPath = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.Desktop ), "ProtoClientAPI_Export.csv" ); acquisitionAPI.Export( new ExportRequest { ExportPath = exportPath, UseDecimalPoint = true } ); //// Now you could open the file with Excel (or the default .csv reader on the system) //// Open the file with Excel (or the default .csv reader on the system) //using ( var fileopener = new Process() ) //{ // fileopener.StartInfo.FileName = "explorer"; // fileopener.StartInfo.Arguments = "\"" + exportPath + "\""; // fileopener.Start(); //} // Exiting this client application will keep the service running. // This means that you could start an acquisition here and immediately exit. The acquisition will // keep running until a stop condition is met (e.g. trigger off or auto-stop timeout). return 0; } }